public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aldyh/heads/ranger-staging)] Merge remote-tracking branch 'origin/master' into me/ranger-staging
@ 2020-09-10 16:24 Aldy Hernandez
  0 siblings, 0 replies; only message in thread
From: Aldy Hernandez @ 2020-09-10 16:24 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:c6d77a304ffe9188ccd14cfe15821008e1aaa941

commit c6d77a304ffe9188ccd14cfe15821008e1aaa941
Merge: 10d9fe7633c f40866967d6
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Thu Sep 10 16:18:00 2020 +0200

    Merge remote-tracking branch 'origin/master' into me/ranger-staging

Diff:

 ChangeLog                                          |   11 +
 MAINTAINERS                                        |    1 +
 config/ChangeLog                                   |   17 +
 config/ax_cxx_compile_stdcxx.m4                    |   39 +-
 config/largefile.m4                                |   45 +-
 configure                                          | 1007 +++++++++
 configure.ac                                       |    4 +
 contrib/ChangeLog                                  |    5 +
 contrib/config-list.mk                             |    3 +-
 gcc/ChangeLog                                      | 1499 +++++++++++++
 gcc/DATESTAMP                                      |    2 +-
 gcc/ada/ChangeLog                                  |   18 +
 gcc/ada/exp_unst.adb                               |   30 +-
 gcc/ada/fe.h                                       |    1 +
 gcc/ada/gcc-interface/trans.c                      |    4 +-
 gcc/ada/opt.ads                                    |    7 +
 gcc/ada/sem_util.adb                               |   73 +
 gcc/ada/sem_util.ads                               |    6 +
 gcc/ada/stand.ads                                  |    4 +
 gcc/alias.c                                        |    5 +-
 gcc/analyzer/ChangeLog                             |  440 ++++
 gcc/analyzer/analyzer.opt                          |    4 +
 gcc/analyzer/checker-path.cc                       |   25 +-
 gcc/analyzer/diagnostic-manager.cc                 |   56 +-
 gcc/analyzer/engine.cc                             |   83 +-
 gcc/analyzer/program-state.cc                      |   72 +-
 gcc/analyzer/region-model-impl-calls.cc            |   35 +
 gcc/analyzer/region-model-manager.cc               |   46 +-
 gcc/analyzer/region-model.cc                       |  276 ++-
 gcc/analyzer/region-model.h                        |   19 +-
 gcc/analyzer/region.cc                             |   63 +-
 gcc/analyzer/sm-file.cc                            |   15 +-
 gcc/analyzer/sm-malloc.cc                          |  633 ++++--
 gcc/analyzer/sm-pattern-test.cc                    |    6 +-
 gcc/analyzer/sm-sensitive.cc                       |    9 +-
 gcc/analyzer/sm-signal.cc                          |   11 +-
 gcc/analyzer/sm-taint.cc                           |   53 +-
 gcc/analyzer/sm.cc                                 |   62 +-
 gcc/analyzer/sm.h                                  |   89 +-
 gcc/analyzer/store.cc                              |  209 +-
 gcc/analyzer/store.h                               |   16 +-
 gcc/analyzer/svalue.cc                             |   50 +-
 gcc/attribs.c                                      |    8 +-
 gcc/attribs.h                                      |    1 -
 gcc/bb-reorder.c                                   |   10 +-
 gcc/builtins.c                                     |  987 +++++----
 gcc/builtins.h                                     |   44 +-
 gcc/c-family/ChangeLog                             |    4 +
 gcc/c-family/c.opt                                 |    4 +
 gcc/c/ChangeLog                                    |   30 +
 gcc/c/c-decl.c                                     |    5 +-
 gcc/c/c-typeck.c                                   |    9 +-
 gcc/c/gimple-parser.c                              |    4 +-
 gcc/calls.c                                        |   81 +-
 gcc/calls.h                                        |    2 +-
 gcc/cfgbuild.c                                     |    2 +-
 gcc/cfgexpand.c                                    |   12 +-
 gcc/cfgrtl.c                                       |   68 +-
 gcc/cfgrtl.h                                       |    3 +-
 gcc/cgraphunit.c                                   |  146 +-
 gcc/combine.c                                      |    4 +-
 gcc/common.opt                                     |    4 +-
 gcc/common/config/i386/cpuinfo.h                   |   10 +
 gcc/common/config/i386/i386-common.c               |    4 +-
 gcc/common/config/msp430/msp430-common.c           |   26 +-
 gcc/config.gcc                                     |    1 +
 gcc/config.host                                    |    6 +-
 gcc/config/aarch64/aarch64-c.c                     |    2 +-
 gcc/config/aarch64/aarch64-simd-builtins.def       |  308 +--
 gcc/config/aarch64/aarch64-sve-builtins.cc         |  142 +-
 gcc/config/aarch64/aarch64-sve.md                  |   42 +-
 gcc/config/aarch64/aarch64.c                       |    1 -
 gcc/config/aarch64/aarch64.md                      |  295 +--
 gcc/config/aarch64/predicates.md                   |   15 -
 gcc/config/arm/mve.md                              |    4 +-
 gcc/config/arm/thumb1.md                           |   94 +-
 gcc/config/bpf/bpf.c                               |   26 +-
 gcc/config/bpf/bpf.h                               |   48 +-
 gcc/config/c6x/c6x.c                               |    5 +-
 gcc/config/darwin.c                                |    3 +-
 gcc/config/gcn/gcn-tree.c                          |    2 +-
 gcc/config/gcn/gcn-valu.md                         |    2 +-
 gcc/config/gcn/gcn.md                              |    8 +-
 gcc/config/gcn/mkoffload.c                         |   40 +-
 gcc/config/i386/avx512fintrin.h                    |   27 +-
 gcc/config/i386/i386-expand.c                      |   48 +-
 gcc/config/i386/i386-features.c                    |  157 +-
 gcc/config/i386/i386-options.c                     |   51 +-
 gcc/config/i386/i386-passes.def                    |    1 +
 gcc/config/i386/i386-protos.h                      |    1 +
 gcc/config/i386/i386.c                             |   75 +-
 gcc/config/i386/i386.h                             |   14 +-
 gcc/config/i386/i386.md                            |  223 +-
 gcc/config/i386/predicates.md                      |    5 +
 gcc/config/i386/sse.md                             |  118 +-
 gcc/config/i386/x86-tune-costs.h                   |  144 ++
 gcc/config/mips/mips.md                            |   12 +-
 gcc/config/msp430/constraints.md                   |   10 +-
 gcc/config/msp430/msp430-opts.h                    |   12 +
 gcc/config/msp430/msp430-protos.h                  |    6 +-
 gcc/config/msp430/msp430.c                         |  308 ++-
 gcc/config/msp430/msp430.md                        |  381 +---
 gcc/config/msp430/msp430.opt                       |   29 +-
 gcc/config/msp430/predicates.md                    |   13 +-
 gcc/config/nvptx/nvptx.c                           |    4 +-
 gcc/config/pa/pa.c                                 |  193 +-
 gcc/config/pa/pa.md                                |   34 +-
 gcc/config/rs6000/altivec.h                        |    4 -
 gcc/config/rs6000/rs6000-builtin.def               |  304 +--
 gcc/config/rs6000/rs6000-c.c                       |    6 +-
 gcc/config/rs6000/rs6000-call.c                    |  386 ++--
 gcc/config/rs6000/rs6000-logue.c                   |   30 +-
 gcc/config/rs6000/rs6000-string.c                  |  103 +-
 gcc/config/rs6000/rs6000.c                         |   35 +-
 gcc/config/rs6000/rs6000.opt                       |    4 +
 gcc/config/rs6000/vsx.md                           |    6 +-
 gcc/config/tilepro/gen-mul-tables.cc               |    2 +
 gcc/config/vxworks.h                               |   16 +-
 gcc/configure                                      |    2 +-
 gcc/configure.ac                                   |    2 +-
 gcc/cp/ChangeLog                                   |  182 ++
 gcc/cp/call.c                                      |   15 +-
 gcc/cp/class.c                                     |   18 +-
 gcc/cp/constexpr.c                                 |    4 +-
 gcc/cp/constraint.cc                               |   16 +-
 gcc/cp/cp-tree.h                                   |   45 +-
 gcc/cp/decl.c                                      |  113 +-
 gcc/cp/decl2.c                                     |    3 +-
 gcc/cp/expr.c                                      |    4 +-
 gcc/cp/init.c                                      |   79 +-
 gcc/cp/name-lookup.c                               |  136 +-
 gcc/cp/optimize.c                                  |   10 +-
 gcc/cp/parser.c                                    |   40 +-
 gcc/cp/pt.c                                        |  129 +-
 gcc/cp/ptree.c                                     |   16 +
 gcc/cp/rtti.c                                      |    2 +-
 gcc/cp/semantics.c                                 |   13 +-
 gcc/d/ChangeLog                                    |   95 +
 gcc/d/Make-lang.in                                 |    1 +
 gcc/d/d-builtins.cc                                |    2 +-
 gcc/d/d-codegen.cc                                 |   35 +-
 gcc/d/d-frontend.cc                                |   12 +-
 gcc/d/d-gimplify.cc                                |  215 ++
 gcc/d/d-lang.cc                                    |  203 +-
 gcc/d/d-target.cc                                  |   18 +-
 gcc/d/d-tree.h                                     |    5 +-
 gcc/d/decl.cc                                      |   61 +-
 gcc/d/dmd/MERGE                                    |    2 +-
 gcc/d/dmd/ctfeexpr.c                               |    2 +-
 gcc/d/dmd/declaration.h                            |    1 +
 gcc/d/dmd/dinterpret.c                             |    9 -
 gcc/d/dmd/dmacro.c                                 |    7 +-
 gcc/d/dmd/dtemplate.c                              |   19 +-
 gcc/d/dmd/expressionsem.c                          |    2 +-
 gcc/d/dmd/func.c                                   |  139 +-
 gcc/d/dmd/globals.h                                |    2 +
 gcc/d/dmd/mtype.c                                  |    4 +-
 gcc/d/dmd/optimize.c                               |   11 +-
 gcc/d/dmd/statementsem.c                           |   37 +-
 gcc/d/expr.cc                                      |   17 +-
 gcc/d/intrinsics.cc                                |    7 +-
 gcc/d/toir.cc                                      |   56 +-
 gcc/d/typeinfo.cc                                  |   36 +
 gcc/d/types.cc                                     |    7 +-
 gcc/df-core.c                                      |    4 +-
 gcc/doc/extend.texi                                |   28 +-
 gcc/doc/install.texi                               |    2 +-
 gcc/doc/invoke.texi                                |   84 +-
 gcc/doc/rtl.texi                                   |   32 +-
 gcc/doc/sourcebuild.texi                           |   35 +
 gcc/dwarf2cfi.c                                    |    2 +-
 gcc/dwarf2out.c                                    |   53 +-
 gcc/early-remat.c                                  |    4 +-
 gcc/emit-rtl.c                                     |   19 +-
 gcc/except.c                                       |    2 +-
 gcc/expr.c                                         |    8 +-
 gcc/final.c                                        |    4 +-
 gcc/fold-const.c                                   |   88 +-
 gcc/fortran/ChangeLog                              |  172 ++
 gcc/fortran/check.c                                |   13 +-
 gcc/fortran/decl.c                                 |    3 +
 gcc/fortran/expr.c                                 |    8 +-
 gcc/fortran/gfortran.h                             |   10 +
 gcc/fortran/interface.c                            |    5 +-
 gcc/fortran/intrinsic.texi                         |    3 +-
 gcc/fortran/module.c                               |   75 +-
 gcc/fortran/openmp.c                               |   81 +-
 gcc/fortran/resolve.c                              |   16 +-
 gcc/fortran/simplify.c                             |   20 +-
 gcc/fortran/trans-array.c                          |   33 +-
 gcc/fortran/trans-common.c                         |   25 +-
 gcc/fortran/trans-decl.c                           |   22 +-
 gcc/fortran/trans-intrinsic.c                      |   45 +-
 gcc/fortran/trans-openmp.c                         |   10 +-
 gcc/fortran/trans-stmt.c                           |    3 +-
 gcc/fortran/trans-types.c                          |   12 +-
 gcc/function.c                                     |    2 +-
 gcc/fwprop.c                                       |    6 +-
 gcc/gcc.c                                          |   62 +-
 gcc/genautomata.c                                  |    6 +-
 gcc/genmatch.c                                     |    4 +-
 gcc/genrecog.c                                     |   12 +-
 gcc/ggc-common.c                                   |    2 +-
 gcc/gimple-fold.c                                  |   12 +-
 gcc/gimple-loop-versioning.cc                      |    4 +-
 gcc/gimple-range-cache.cc                          |   18 +-
 gcc/gimple-range-edge.cc                           |    6 +-
 gcc/gimple-range-gori.cc                           |   32 +-
 gcc/gimple-range.cc                                |   24 +-
 gcc/gimple-ssa-evrp.c                              |    2 +-
 gcc/gimple-streamer-in.c                           |   19 +-
 gcc/gimple-streamer-out.c                          |   12 +-
 gcc/gimple.c                                       |   14 +-
 gcc/gimple.h                                       |   16 +
 gcc/ginclude/stdbool.h                             |    7 -
 gcc/go/gofrontend/MERGE                            |    2 +-
 gcc/graphite-isl-ast-to-gimple.c                   |    2 +-
 gcc/haifa-sched.c                                  |    4 +-
 gcc/insn-addr.h                                    |    4 +-
 gcc/ipa-cp.c                                       |   17 +-
 gcc/ipa-devirt.c                                   |    4 +-
 gcc/ipa-fnsummary.c                                |   26 +-
 gcc/ipa-icf.c                                      |    2 +-
 gcc/ipa-prop.c                                     |   26 +-
 gcc/ipa-reference.c                                |    2 +-
 gcc/ipa-split.c                                    |    2 +-
 gcc/ira.c                                          |    2 +-
 gcc/jit/ChangeLog                                  |   14 +
 gcc/jit/jit-recording.c                            |    2 +-
 gcc/jit/libgccjit.c                                |   14 +-
 gcc/lower-subreg.c                                 |    2 +-
 gcc/lra-constraints.c                              |   97 +-
 gcc/lto-streamer-in.c                              |  451 +++-
 gcc/lto-streamer-out.c                             |  128 +-
 gcc/lto-streamer.c                                 |    1 +
 gcc/lto-streamer.h                                 |   20 +-
 gcc/lto/ChangeLog                                  |    5 +
 gcc/lto/lto-common.c                               |    2 +-
 gcc/match.pd                                       |    8 +
 gcc/modulo-sched.c                                 |   16 +-
 gcc/omp-general.c                                  |    2 +-
 gcc/opts-global.c                                  |   10 +-
 gcc/passes.c                                       |    4 +-
 gcc/predict.c                                      |    2 +-
 gcc/profile.c                                      |    2 +-
 gcc/range-op.cc                                    |  132 +-
 gcc/read-rtl-function.c                            |    2 +-
 gcc/read-rtl.c                                     |    2 +-
 gcc/recog.c                                        |  134 +-
 gcc/recog.h                                        |    2 +
 gcc/reg-stack.c                                    |    2 +-
 gcc/regrename.c                                    |    2 +-
 gcc/reorg.c                                        |   37 +-
 gcc/rtl.def                                        |    2 +-
 gcc/rtlanal.c                                      |    2 +-
 gcc/sched-deps.c                                   |    2 +-
 gcc/sel-sched-ir.c                                 |    6 +-
 gcc/streamer-hooks.h                               |   14 +-
 gcc/symbol-summary.h                               |   13 +-
 gcc/symtab.c                                       |    3 +-
 gcc/targhooks.c                                    |    5 +-
 gcc/testsuite/ChangeLog                            | 1163 ++++++++++
 gcc/testsuite/c-c++-common/Warray-bounds-7.c       |   77 +-
 gcc/testsuite/c-c++-common/Wrestrict.c             |    4 +-
 gcc/testsuite/c-c++-common/attr-nonstring-3.c      |    4 +-
 gcc/testsuite/c-c++-common/attr-nonstring-6.c      |   82 +-
 gcc/testsuite/c-c++-common/attr-nonstring-8.c      |    2 +-
 gcc/testsuite/c-c++-common/gomp/depend-1.c         |    2 +-
 gcc/testsuite/c-c++-common/gomp/map-1.c            |    2 +-
 gcc/testsuite/c-c++-common/gomp/map-4.c            |   29 +
 gcc/testsuite/c-c++-common/gomp/pr96867.c          |    9 +
 gcc/testsuite/c-c++-common/gomp/reduction-1.c      |    2 +-
 gcc/testsuite/g++.dg/analyzer/new-1.C              |   52 +
 gcc/testsuite/g++.dg/analyzer/new-vs-malloc.C      |   21 +
 gcc/testsuite/g++.dg/analyzer/pr96643.C            |   26 +
 gcc/testsuite/g++.dg/analyzer/pr96723.C            |   10 +
 gcc/testsuite/g++.dg/analyzer/pr96763.C            |   13 +
 gcc/testsuite/g++.dg/concepts/diagnostic10.C       |    2 +-
 gcc/testsuite/g++.dg/concepts/diagnostic13.C       |    2 +-
 gcc/testsuite/g++.dg/concepts/diagnostic2.C        |    2 +-
 gcc/testsuite/g++.dg/concepts/diagnostic3.C        |    4 +-
 gcc/testsuite/g++.dg/concepts/diagnostic4.C        |    2 +-
 gcc/testsuite/g++.dg/concepts/diagnostic5.C        |    2 +-
 gcc/testsuite/g++.dg/concepts/diagnostic9.C        |    3 +-
 gcc/testsuite/g++.dg/concepts/expression2.C        |    2 +-
 gcc/testsuite/g++.dg/concepts/fn5.C                |    4 +-
 gcc/testsuite/g++.dg/concepts/placeholder5.C       |    4 +-
 gcc/testsuite/g++.dg/concepts/pr67595.C            |    2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-array23.C     |    6 +-
 gcc/testsuite/g++.dg/cpp0x/error9.C                |    6 +
 gcc/testsuite/g++.dg/cpp0x/initlist-new4.C         |    6 +
 gcc/testsuite/g++.dg/cpp0x/initlist123.C           |   39 +
 gcc/testsuite/g++.dg/cpp0x/initlist69.C            |    4 +-
 gcc/testsuite/g++.dg/cpp0x/sfinae4.C               |    8 +-
 gcc/testsuite/g++.dg/cpp1y/auto-96647.C            |   10 +
 gcc/testsuite/g++.dg/cpp1z/class-deduction-spec1.C |   38 +
 gcc/testsuite/g++.dg/cpp1z/constexpr-96862.C       |   20 +
 .../g++.dg/cpp2a/class-deduction-alias4.C          |   44 +
 gcc/testsuite/g++.dg/cpp2a/concepts-fn6.C          |   10 +
 gcc/testsuite/g++.dg/cpp2a/concepts-nondep1.C      |   19 +
 gcc/testsuite/g++.dg/cpp2a/concepts-nondep1a.C     |   20 +
 gcc/testsuite/g++.dg/cpp2a/concepts-pr78752-2.C    |    2 +-
 gcc/testsuite/g++.dg/cpp2a/concepts-pr84140.C      |    1 -
 .../g++.dg/cpp2a/concepts-recursive-sat3.C         |    2 +-
 gcc/testsuite/g++.dg/cpp2a/concepts-requires18.C   |    4 +-
 gcc/testsuite/g++.dg/cpp2a/concepts-requires19.C   |   12 +-
 gcc/testsuite/g++.dg/cpp2a/concepts3.C             |    6 +-
 gcc/testsuite/g++.dg/cpp2a/new-array1.C            |   70 +
 gcc/testsuite/g++.dg/cpp2a/new-array2.C            |   22 +
 gcc/testsuite/g++.dg/cpp2a/new-array3.C            |   17 +
 gcc/testsuite/g++.dg/cpp2a/new-array4.C            |   10 +
 gcc/testsuite/g++.dg/cpp2a/new-array5.C            |   15 +
 gcc/testsuite/g++.dg/cpp2a/paren-init33.C          |  128 ++
 gcc/testsuite/g++.dg/cpp2a/paren-init34.C          |   25 +
 gcc/testsuite/g++.dg/cpp2a/paren-init35.C          |   21 +
 gcc/testsuite/g++.dg/cpp2a/paren-init36.C          |   14 +
 gcc/testsuite/g++.dg/cpp2a/paren-init37.C          |   14 +
 gcc/testsuite/g++.dg/diagnostic/mem-init1.C        |    4 +-
 gcc/testsuite/g++.dg/gomp/depend-1.C               |    2 +-
 gcc/testsuite/g++.dg/gomp/depend-2.C               |    2 +-
 gcc/testsuite/g++.dg/init/array28.C                |    2 +-
 gcc/testsuite/g++.dg/ipa/pr96806.C                 |   53 +
 gcc/testsuite/g++.dg/lookup/operator-1.C           |   20 +
 gcc/testsuite/g++.dg/lookup/operator-2.C           |   23 +
 gcc/testsuite/g++.dg/lto/pr96690_0.C               |   17 +
 gcc/testsuite/g++.dg/opt/flifetime-dse8.C          |   12 +
 gcc/testsuite/g++.dg/opt/pr96722.C                 |   20 +
 gcc/testsuite/g++.dg/other/final8.C                |    8 +-
 gcc/testsuite/g++.dg/pr84729.C                     |    2 +-
 gcc/testsuite/g++.dg/pr96818.C                     |   28 +
 .../g++.dg/torture/Wsizeof-pointer-memaccess1.C    |    2 +-
 .../g++.dg/torture/Wsizeof-pointer-memaccess2.C    |    2 +-
 gcc/testsuite/g++.dg/warn/Wconversion-null-5.C     |    6 +
 gcc/testsuite/g++.dg/warn/Wnonnull6.C              |    4 +-
 gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C       |    1 +
 gcc/testsuite/g++.old-deja/g++.brendan/crash60.C   |    2 +-
 gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C       |    2 +-
 gcc/testsuite/g++.old-deja/g++.law/init10.C        |    2 +-
 gcc/testsuite/g++.old-deja/g++.other/array3.C      |    3 +-
 gcc/testsuite/g++.old-deja/g++.robertl/eb58.C      |    2 +-
 gcc/testsuite/g++.old-deja/g++.robertl/eb63.C      |    2 +-
 .../aarch64/sve/acle/general-c++/attributes_2.C    |   66 +
 .../aarch64/sve/acle/general-c++/mangle_1.C        |   26 +-
 .../aarch64/sve/acle/general-c++/mangle_10.C       |   19 +
 .../aarch64/sve/acle/general-c++/mangle_2.C        |   26 +-
 .../aarch64/sve/acle/general-c++/mangle_3.C        |    4 +-
 .../aarch64/sve/acle/general-c++/mangle_5.C        |    4 +-
 .../aarch64/sve/acle/general-c++/mangle_6.C        |   36 +
 .../aarch64/sve/acle/general-c++/mangle_7.C        |   19 +
 .../aarch64/sve/acle/general-c++/mangle_8.C        |   19 +
 .../aarch64/sve/acle/general-c++/mangle_9.C        |   19 +
 .../i386/avx512bw-pr96246-1.C}                     |   12 +-
 .../i386/avx512bw-pr96246-2.C}                     |   19 +-
 gcc/testsuite/g++.target/i386/avx512f-helper.h     |    1 +
 .../i386/avx512vl-pr96246-1.C}                     |   12 +-
 .../i386/avx512vl-pr96246-2.C}                     |   31 +-
 gcc/testsuite/gcc.c-torture/compile/pr96796.c      |   55 +
 gcc/testsuite/gcc.dg/Warray-bounds-39.c            |   46 +-
 gcc/testsuite/gcc.dg/Warray-bounds-40.c            |    2 +-
 gcc/testsuite/gcc.dg/Warray-bounds-58.c            |   24 +-
 .../gcc.dg/Wbuiltin-declaration-mismatch-16.c      |   12 +
 gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c  |    2 +-
 gcc/testsuite/gcc.dg/Wstringop-overflow-22.c       |   54 +-
 gcc/testsuite/gcc.dg/Wstringop-overflow-33.c       |    8 +-
 gcc/testsuite/gcc.dg/Wstringop-overflow-42.c       |   58 +
 gcc/testsuite/gcc.dg/Wstringop-overflow-9.c        |    4 +-
 gcc/testsuite/gcc.dg/Wstringop-overflow.c          |   12 +-
 gcc/testsuite/gcc.dg/Wstringop-overread-2.c        |  117 +
 gcc/testsuite/gcc.dg/Wstringop-overread-3.c        |  188 ++
 gcc/testsuite/gcc.dg/Wstringop-overread-4.c        |   58 +
 gcc/testsuite/gcc.dg/Wstringop-overread.c          |  716 +++++++
 .../gcc.dg/analyzer/loop-start-up-to-end-by-1.c    |    2 -
 .../gcc.dg/analyzer/malloc-ipa-8-double-free.c     |   10 +-
 gcc/testsuite/gcc.dg/analyzer/memset-1.c           |   14 +
 gcc/testsuite/gcc.dg/analyzer/pr94851-1.c          |   46 +
 gcc/testsuite/gcc.dg/analyzer/pr94851-3.c          |   20 +
 gcc/testsuite/gcc.dg/analyzer/pr94851-4.c          |   24 +
 gcc/testsuite/gcc.dg/analyzer/pr94858-1.c          |   42 +
 gcc/testsuite/gcc.dg/analyzer/pr94858-2.c          |   25 +
 gcc/testsuite/gcc.dg/analyzer/pr95152-4.c          |   11 +
 gcc/testsuite/gcc.dg/analyzer/pr95152-5.c          |    6 +
 gcc/testsuite/gcc.dg/analyzer/pr96648.c            |   36 +
 gcc/testsuite/gcc.dg/analyzer/pr96651-1.c          |   22 +
 gcc/testsuite/gcc.dg/analyzer/pr96651-2.c          |   72 +
 gcc/testsuite/gcc.dg/analyzer/pr96699.c            |   13 +
 gcc/testsuite/gcc.dg/analyzer/pr96705.c            |    9 +
 gcc/testsuite/gcc.dg/analyzer/pr96713.c            |    8 +
 gcc/testsuite/gcc.dg/analyzer/pr96764.c            |    6 +
 gcc/testsuite/gcc.dg/analyzer/pr96777.c            |   12 +
 gcc/testsuite/gcc.dg/analyzer/pr96792.c            |   39 +
 gcc/testsuite/gcc.dg/analyzer/pr96860-1.c          |    9 +
 gcc/testsuite/gcc.dg/analyzer/pr96860-2.c          |    8 +
 .../gcc.dg/analyzer/torture/loop-inc-ptr-2.c       |    2 +-
 .../gcc.dg/analyzer/torture/loop-inc-ptr-3.c       |    2 +-
 gcc/testsuite/gcc.dg/analyzer/vla-1.c              |    1 +
 gcc/testsuite/gcc.dg/attr-nonstring-2.c            |   22 +-
 gcc/testsuite/gcc.dg/attr-nonstring-3.c            |   18 +-
 gcc/testsuite/gcc.dg/attr-nonstring-4.c            |    6 +-
 gcc/testsuite/gcc.dg/attr-nonstring.c              |   32 +-
 gcc/testsuite/gcc.dg/builtin-object-size-4.c       |    3 +
 gcc/testsuite/gcc.dg/builtin-stringop-chk-5.c      |    2 +-
 gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c      |   30 +-
 gcc/testsuite/gcc.dg/ipa/symver1.c                 |   11 +
 gcc/testsuite/gcc.dg/pr21137.c                     |   20 +
 gcc/testsuite/gcc.dg/pr55940.c                     |    1 +
 gcc/testsuite/gcc.dg/pr78902.c                     |    1 +
 gcc/testsuite/gcc.dg/pr79214.c                     |    2 +-
 gcc/testsuite/gcc.dg/pr86314.c                     |    2 +-
 gcc/testsuite/gcc.dg/pr94234-1.c                   |   15 +
 gcc/testsuite/gcc.dg/pr96579.c                     |    4 +
 gcc/testsuite/gcc.dg/pr96818.c                     |   14 +
 gcc/testsuite/gcc.dg/pr96931.c                     |   19 +
 gcc/testsuite/gcc.dg/pubtypes-2.c                  |    2 +-
 gcc/testsuite/gcc.dg/pubtypes-3.c                  |    2 +-
 gcc/testsuite/gcc.dg/pubtypes-4.c                  |    2 +-
 gcc/testsuite/gcc.dg/sinatan-2.c                   |    1 +
 gcc/testsuite/gcc.dg/sinhovercosh-1.c              |    1 +
 gcc/testsuite/gcc.dg/strcmpopt_10.c                |    2 +-
 gcc/testsuite/gcc.dg/strcmpopt_12.c                |   17 +
 gcc/testsuite/gcc.dg/strlenopt-57.c                |    6 +-
 gcc/testsuite/gcc.dg/tanhbysinh.c                  |    3 +-
 .../gcc.dg/torture/Wsizeof-pointer-memaccess1.c    |    2 +-
 gcc/testsuite/gcc.dg/torture/pr96522.c             |   36 +
 gcc/testsuite/gcc.dg/torture/pr96548.c             |   20 +
 gcc/testsuite/gcc.dg/torture/pr96760.c             |   22 +
 .../gcc.dg/tree-ssa/builtins-folding-gimple-ub.c   |    4 +-
 gcc/testsuite/gcc.dg/tree-ssa/copy-sign-3.c        |   23 +
 gcc/testsuite/gcc.dg/tree-ssa/loop-19.c            |    4 +-
 gcc/testsuite/gcc.dg/tree-ssa/loop-2.c             |    1 -
 gcc/testsuite/gcc.dg/tree-ssa/loop-3.c             |    3 +-
 gcc/testsuite/gcc.dg/tree-ssa/pr96730.c            |   13 +
 gcc/testsuite/gcc.dg/tree-ssa/pr96820.c            |   12 +
 gcc/testsuite/gcc.dg/tree-ssa/pr96967.c            |   36 +
 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-40.c         |   16 +
 gcc/testsuite/gcc.dg/uninit-33.c                   |    2 +-
 gcc/testsuite/gcc.dg/vect/bb-slp-32.c              |    7 +-
 gcc/testsuite/gcc.dg/vect/bb-slp-38.c              |    2 +-
 gcc/testsuite/gcc.dg/vect/bb-slp-45.c              |   36 +
 gcc/testsuite/gcc.dg/vect/bb-slp-46.c              |   28 +
 gcc/testsuite/gcc.dg/vect/bb-slp-47.c              |   14 +
 gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c         |    4 +-
 .../vect/costmodel/x86_64/costmodel-pr69297.c      |   20 +-
 gcc/testsuite/gcc.dg/vect/pr96698.c                |   19 +
 gcc/testsuite/gcc.dg/vect/pr96783-1.c              |   38 +
 gcc/testsuite/gcc.dg/vect/pr96783-2.c              |   29 +
 gcc/testsuite/gcc.dg/vect/pr96854.c                |   20 +
 gcc/testsuite/gcc.dg/vect/pr96920.c                |   20 +
 gcc/testsuite/gcc.dg/vect/slp-3.c                  |    8 +-
 gcc/testsuite/gcc.dg/vect/slp-46.c                 |    1 +
 gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c      |    4 +-
 gcc/testsuite/gcc.dg/vect/slp-perm-1.c             |    4 +-
 gcc/testsuite/gcc.dg/vect/slp-perm-5.c             |    4 +-
 gcc/testsuite/gcc.dg/vect/slp-perm-6.c             |    4 +-
 gcc/testsuite/gcc.dg/vect/slp-perm-7.c             |    4 +-
 gcc/testsuite/gcc.dg/vect/slp-perm-8.c             |    4 +-
 gcc/testsuite/gcc.dg/vect/slp-perm-9.c             |    4 +-
 gcc/testsuite/gcc.dg/vect/vect-cond-13.c           |   38 +
 gcc/testsuite/gcc.dg/vect/vect-live-6.c            |   31 +
 gcc/testsuite/gcc.dg/vect/vect-version-2.c         |    6 +-
 gcc/testsuite/gcc.dg/warn-strnlen-no-nul-2.c       |    8 +-
 gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c         |   18 +-
 gcc/testsuite/gcc.target/aarch64/adds3.c           |    2 +-
 gcc/testsuite/gcc.target/aarch64/cmp.c             |    3 +-
 gcc/testsuite/gcc.target/aarch64/extend-syntax.c   |  120 ++
 gcc/testsuite/gcc.target/aarch64/insv_1.c          |    2 +-
 .../gcc.target/aarch64/mem-shift-canonical.c       |   28 +
 gcc/testsuite/gcc.target/aarch64/mgeneral-regs_7.c |   11 +
 gcc/testsuite/gcc.target/aarch64/strcmpopt_6.c     |    2 +-
 gcc/testsuite/gcc.target/aarch64/subs3.c           |    2 +-
 gcc/testsuite/gcc.target/aarch64/subsp.c           |    2 +-
 .../aarch64/sve/acle/general/attributes_1.c        |    4 +-
 .../aarch64/sve/acle/general/attributes_7.c        |    4 +
 gcc/testsuite/gcc.target/aarch64/sve/pr96357.c     |   25 +
 .../gcc.target/arm/mve/intrinsics/vst1q_f16.c      |   10 +-
 .../gcc.target/arm/mve/intrinsics/vst1q_s16.c      |   10 +-
 .../gcc.target/arm/mve/intrinsics/vst1q_s8.c       |   10 +-
 .../gcc.target/arm/mve/intrinsics/vst1q_u16.c      |   10 +-
 .../gcc.target/arm/mve/intrinsics/vst1q_u8.c       |   10 +-
 gcc/testsuite/gcc.target/arm/pure-code/pr94538-1.c |   13 +
 gcc/testsuite/gcc.target/arm/pure-code/pr94538-2.c |   12 +
 gcc/testsuite/gcc.target/arm/pure-code/pr96769.c   |   20 +
 .../gcc.target/arm/pure-code/pure-code.exp         |    8 +-
 .../gcc.target/bpf/xbpf-indirect-call-1.c          |   21 +
 gcc/testsuite/gcc.target/cris/pr93372-47.c         |   49 +
 gcc/testsuite/gcc.target/hppa/shadd-2.c            |    2 +-
 gcc/testsuite/gcc.target/i386/387-7.c              |    1 +
 gcc/testsuite/gcc.target/i386/387-9.c              |    1 +
 .../gcc.target/i386/avx2-broadcast-pr87767-1.c     |   40 +
 .../gcc.target/i386/avx512bw-kunpckwd-1.c          |    2 +-
 .../gcc.target/i386/avx512bw-kunpckwd-3.c          |    2 +-
 gcc/testsuite/gcc.target/i386/avx512bw-pr88465.c   |   23 +
 gcc/testsuite/gcc.target/i386/avx512bw-pr95488-1.c |    2 +-
 gcc/testsuite/gcc.target/i386/avx512dq-kmovb-5.c   |    2 +-
 .../gcc.target/i386/avx512f-broadcast-pr87767-1.c  |   30 +
 .../gcc.target/i386/avx512f-broadcast-pr87767-2.c  |   42 +
 .../gcc.target/i386/avx512f-broadcast-pr87767-3.c  |   30 +
 .../gcc.target/i386/avx512f-broadcast-pr87767-4.c  |   42 +
 .../gcc.target/i386/avx512f-broadcast-pr87767-5.c  |   26 +
 .../gcc.target/i386/avx512f-broadcast-pr87767-6.c  |   41 +
 .../gcc.target/i386/avx512f-broadcast-pr87767-7.c  |  121 ++
 gcc/testsuite/gcc.target/i386/avx512f-kmovw-5.c    |    2 +-
 gcc/testsuite/gcc.target/i386/avx512f-pr96551-1.c  |   18 +
 gcc/testsuite/gcc.target/i386/avx512f-pr96551-2.c  |   33 +
 .../gcc.target/i386/avx512f-rint-sfix-vec-2.c      |    1 +
 .../gcc.target/i386/avx512f-rintf-sfix-vec-2.c     |    1 +
 .../gcc.target/i386/avx512vl-broadcast-pr87767-1.c |   45 +
 .../gcc.target/i386/avx512vl-broadcast-pr87767-2.c |   59 +
 .../gcc.target/i386/avx512vl-broadcast-pr87767-3.c |   37 +
 .../gcc.target/i386/avx512vl-broadcast-pr87767-4.c |   56 +
 .../gcc.target/i386/avx512vl-broadcast-pr87767-5.c |   37 +
 .../gcc.target/i386/avx512vl-broadcast-pr87767-6.c |   55 +
 gcc/testsuite/gcc.target/i386/bitwise_mask_op-1.c  |  178 ++
 gcc/testsuite/gcc.target/i386/bitwise_mask_op-2.c  |    8 +
 gcc/testsuite/gcc.target/i386/bitwise_mask_op-3.c  |   44 +
 .../gcc.target/i386/builtin_thread_pointer.c       |   30 +
 gcc/testsuite/gcc.target/i386/double_mask_reg-1.c  |   19 +
 gcc/testsuite/gcc.target/i386/pr55342.c            |    2 +-
 gcc/testsuite/gcc.target/i386/pr61403.c            |    1 +
 gcc/testsuite/gcc.target/i386/pr65146.c            |   12 +
 gcc/testsuite/gcc.target/i386/pr87007-4.c          |    2 +-
 gcc/testsuite/gcc.target/i386/pr87007-5.c          |    2 +-
 gcc/testsuite/gcc.target/i386/pr92645-4.c          |    2 +-
 .../gcc.target/i386/pr92658-avx512bw-trunc.c       |    2 +-
 gcc/testsuite/gcc.target/i386/pr92658-avx512f.c    |    2 +-
 gcc/testsuite/gcc.target/i386/pr95863-1.c          |   47 +
 gcc/testsuite/gcc.target/i386/pr95863-2.c          |   27 +
 gcc/testsuite/gcc.target/i386/pr96262-1.c          |   11 +
 gcc/testsuite/gcc.target/i386/pr96744-1.c          |   10 +
 gcc/testsuite/gcc.target/i386/pr96744-2.c          |   11 +
 gcc/testsuite/gcc.target/i386/pr96744-3a.c         |   12 +
 gcc/testsuite/gcc.target/i386/pr96744-3b.c         |   16 +
 gcc/testsuite/gcc.target/i386/pr96744-4.c          |   11 +
 gcc/testsuite/gcc.target/i386/pr96744-5.c          |   17 +
 gcc/testsuite/gcc.target/i386/pr96744-6.c          |   11 +
 gcc/testsuite/gcc.target/i386/pr96744-7.c          |   14 +
 gcc/testsuite/gcc.target/i386/pr96744-8a.c         |   33 +
 gcc/testsuite/gcc.target/i386/pr96744-8b.c         |   35 +
 gcc/testsuite/gcc.target/i386/pr96744-9.c          |   25 +
 gcc/testsuite/gcc.target/i386/pr96755.c            |   16 +
 gcc/testsuite/gcc.target/i386/pr96802-1.c          |   12 +
 gcc/testsuite/gcc.target/i386/pr96802-2.c          |   16 +
 gcc/testsuite/gcc.target/i386/spill_to_mask-1.c    |   92 +
 gcc/testsuite/gcc.target/i386/spill_to_mask-2.c    |   10 +
 gcc/testsuite/gcc.target/i386/spill_to_mask-3.c    |   10 +
 gcc/testsuite/gcc.target/i386/spill_to_mask-4.c    |   10 +
 .../gcc.target/i386/sse4_1-ceil-sfix-vec.c         |    1 +
 .../gcc.target/i386/sse4_1-ceilf-sfix-vec.c        |    1 +
 .../gcc.target/i386/sse4_1-floor-sfix-vec.c        |    1 +
 .../gcc.target/i386/sse4_1-floorf-sfix-vec.c       |    1 +
 .../gcc.target/i386/sse4_1-rint-sfix-vec.c         |    1 +
 .../gcc.target/i386/sse4_1-rintf-sfix-vec.c        |    1 +
 .../gcc.target/i386/sse4_1-round-sfix-vec.c        |    1 +
 .../gcc.target/i386/sse4_1-roundf-sfix-vec.c       |    1 +
 gcc/testsuite/gcc.target/i386/strcmpopt_6.c        |    8 +-
 gcc/testsuite/gcc.target/msp430/430x-default-isa.c |   10 +
 gcc/testsuite/gcc.target/msp430/emulate-srli.c     |    2 +-
 .../msp430/max-inline-shift-430-no-opt.c           |   52 +
 .../gcc.target/msp430/max-inline-shift-430.c       |   50 +
 .../gcc.target/msp430/max-inline-shift-430x.c      |   48 +
 gcc/testsuite/gcc.target/msp430/mcpu-is-430.c      |   10 +
 gcc/testsuite/gcc.target/msp430/mcpu-is-430x.c     |   12 +
 gcc/testsuite/gcc.target/msp430/mcpu-is-430xv2.c   |   13 +
 gcc/testsuite/gcc.target/powerpc/mma-builtin-3.c   |    4 +-
 gcc/testsuite/gcc.target/powerpc/pcrel-sibcall-1.c |   19 +-
 gcc/testsuite/gcc.target/powerpc/pr92398.p9+.c     |    2 +-
 gcc/testsuite/gcc.target/powerpc/pr92398.p9-.c     |    4 +-
 gcc/testsuite/gcc.target/powerpc/pr95450.c         |   29 +
 gcc/testsuite/gcc.target/powerpc/pr96139-a.c       |   32 +
 gcc/testsuite/gcc.target/powerpc/pr96139-b.c       |   32 +
 gcc/testsuite/gcc.target/powerpc/pr96139-c.c       |   26 +
 gcc/testsuite/gcc.target/powerpc/pr96787-1.c       |   38 +
 gcc/testsuite/gcc.target/powerpc/pr96787-2.c       |   35 +
 gcc/testsuite/gcc.target/powerpc/pr96808.c         |   59 +
 gcc/testsuite/gdc.dg/cast1.d                       |    7 +
 gcc/testsuite/gdc.dg/dg.exp                        |   24 +-
 gcc/testsuite/gdc.dg/gdc213.d                      |    4 +-
 gcc/testsuite/gdc.dg/gdc284.d                      |    4 +-
 gcc/testsuite/gdc.dg/gdc67.d                       |    3 +-
 gcc/testsuite/gdc.dg/pr96157b.d                    |   46 +
 gcc/testsuite/gdc.dg/pr96869.d                     |   32 +
 gcc/testsuite/gdc.dg/pr96924.d                     |   14 +
 gcc/testsuite/gdc.dg/simd.d                        | 1947 -----------------
 gcc/testsuite/gdc.dg/simd1.d                       |   71 +
 gcc/testsuite/gdc.dg/simd10447.d                   |   11 +
 gcc/testsuite/gdc.dg/simd12776.d                   |   25 +
 gcc/testsuite/gdc.dg/simd13841.d                   |   29 +
 gcc/testsuite/gdc.dg/simd13927.d                   |   10 +
 gcc/testsuite/gdc.dg/simd15123.d                   |   17 +
 gcc/testsuite/gdc.dg/simd15144.d                   |   11 +
 gcc/testsuite/gdc.dg/simd16087.d                   |   98 +
 gcc/testsuite/gdc.dg/simd16697.d                   |   12 +
 gcc/testsuite/gdc.dg/simd17237.d                   |   18 +
 gcc/testsuite/gdc.dg/simd17695.d                   |    8 +
 gcc/testsuite/gdc.dg/simd17720a.d                  |   43 +
 gcc/testsuite/gdc.dg/simd17720b.d                  |   43 +
 gcc/testsuite/gdc.dg/simd19224.d                   |   17 +
 gcc/testsuite/gdc.dg/simd19627.d                   |    6 +
 gcc/testsuite/gdc.dg/simd19628.d                   |   41 +
 gcc/testsuite/gdc.dg/simd19629.d                   |   41 +
 gcc/testsuite/gdc.dg/simd19630.d                   |   77 +
 gcc/testsuite/gdc.dg/simd2a.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2b.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2c.d                      |   70 +
 gcc/testsuite/gdc.dg/simd2d.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2e.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2f.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2g.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2h.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2i.d                      |   69 +
 gcc/testsuite/gdc.dg/simd2j.d                      |   69 +
 gcc/testsuite/gdc.dg/simd7951.d                    |   22 +
 gcc/testsuite/gdc.dg/torture/array2.d              |   25 +
 gcc/testsuite/gdc.dg/torture/array3.d              |   15 +
 gcc/testsuite/gdc.dg/{ => torture}/gdc115.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc131.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc141.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc17.d         |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc171.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc179.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc186.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc187.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc191.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc198.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc200.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc210.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc240.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc242b.d       |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc248.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc250.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc273.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc283.d        |    3 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc285.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc286.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc309.d        |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc35.d         |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc36.d         |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc51.d         |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc57.d         |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/gdc66.d         |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/imports/gdc36.d |    0
 gcc/testsuite/gdc.dg/{ => torture}/init1.d         |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/pr92309.d       |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/pr94424.d       |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/pr94777b.d      |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/pr96152.d       |    2 +-
 gcc/testsuite/gdc.dg/{ => torture}/pr96153.d       |   20 +-
 gcc/testsuite/gdc.dg/torture/pr96156.d             |   33 +
 gcc/testsuite/gdc.dg/torture/pr96157a.d            |   24 +
 gcc/testsuite/gdc.dg/torture/simd16488a.d          |  106 +
 gcc/testsuite/gdc.dg/torture/simd16488b.d          |  103 +
 gcc/testsuite/gdc.dg/torture/simd16703.d           |   36 +
 gcc/testsuite/gdc.dg/torture/simd19223.d           |   19 +
 gcc/testsuite/gdc.dg/torture/simd19607.d           |   19 +
 gcc/testsuite/gdc.dg/torture/simd3.d               |   34 +
 gcc/testsuite/gdc.dg/torture/simd4.d               |   14 +
 gcc/testsuite/gdc.dg/torture/simd7411.d            |   16 +
 gcc/testsuite/gdc.dg/torture/simd7413a.d           |   95 +
 gcc/testsuite/gdc.dg/torture/simd7413b.d           |   95 +
 gcc/testsuite/gdc.dg/torture/simd7414.d            |   54 +
 gcc/testsuite/gdc.dg/torture/simd9200.d            |   25 +
 gcc/testsuite/gdc.dg/torture/simd9304.d            |   17 +
 gcc/testsuite/gdc.dg/torture/simd9449.d            |   31 +
 gcc/testsuite/gdc.dg/torture/simd9910.d            |   15 +
 gcc/testsuite/gdc.dg/torture/torture.exp           |   50 +
 gcc/testsuite/gdc.test/compilable/ice20092.d       |   10 +
 gcc/testsuite/gdc.test/compilable/interpret3.d     |   38 +
 gcc/testsuite/gdc.test/fail_compilation/reg6769.d  |   29 +
 gcc/testsuite/gdc.test/runnable/sdtor.d            |    5 +-
 gcc/testsuite/gdc.test/runnable/test8.d            |    8 +-
 gcc/testsuite/gfortran.dg/PR94110.f90              |   88 +
 gcc/testsuite/gfortran.dg/PR95352.f90              |   27 +
 gcc/testsuite/gfortran.dg/PR96726.f90              |   72 +
 gcc/testsuite/gfortran.dg/PR96727.f90              |   34 +
 gcc/testsuite/gfortran.dg/PR96728.f90              |   49 +
 gcc/testsuite/gfortran.dg/analyzer/pr96949.f90     |   20 +
 gcc/testsuite/gfortran.dg/char_length_23.f90       |   25 +
 gcc/testsuite/gfortran.dg/coarray_fail_st.f90      |    2 +-
 gcc/testsuite/gfortran.dg/gomp/combined-if.f90     |    4 +-
 .../gfortran.dg/gomp/declare-target-4.f90          |   81 +
 .../gfortran.dg/gomp/declare-target-5.f90          |   63 +
 gcc/testsuite/gfortran.dg/gomp/openmp-simd-5.f90   |   24 +
 gcc/testsuite/gfortran.dg/gomp/pr67500.f90         |   57 +
 gcc/testsuite/gfortran.dg/iall_masked.f90          |   22 +
 gcc/testsuite/gfortran.dg/min_max_kind.f90         |   15 +
 gcc/testsuite/gfortran.dg/minmax_char_3.f90        |   10 +
 .../gfortran.dg/optional_assumed_charlen_2.f90     |   48 +
 gcc/testsuite/gfortran.dg/pr95398.f90              |   53 +
 gcc/testsuite/gfortran.dg/pr95882_1.f90            |    8 +
 gcc/testsuite/gfortran.dg/pr95882_2.f90            |    6 +
 gcc/testsuite/gfortran.dg/pr95882_3.f90            |    6 +
 gcc/testsuite/gfortran.dg/pr95882_4.f90            |    7 +
 gcc/testsuite/gfortran.dg/pr95882_5.f90            |    6 +
 gcc/testsuite/gfortran.dg/pr96436_1.f90            |   10 +
 gcc/testsuite/gfortran.dg/pr96436_10.f90           |   10 +
 gcc/testsuite/gfortran.dg/pr96436_2.f90            |   10 +
 gcc/testsuite/gfortran.dg/pr96436_3.f90            |   13 +
 gcc/testsuite/gfortran.dg/pr96436_4.f90            |   25 +
 gcc/testsuite/gfortran.dg/pr96436_5.f90            |   25 +
 gcc/testsuite/gfortran.dg/pr96436_6.f90            |   10 +
 gcc/testsuite/gfortran.dg/pr96436_7.f90            |   10 +
 gcc/testsuite/gfortran.dg/pr96436_8.f90            |   10 +
 gcc/testsuite/gfortran.dg/pr96436_9.f90            |   10 +
 gcc/testsuite/gfortran.dg/pr96486.f90              |    9 +
 gcc/testsuite/gfortran.dg/pr96613.f90              |   15 +
 gcc/testsuite/gfortran.dg/pr96711.f90              |   28 +
 gcc/testsuite/gfortran.dg/pr96737.f90              |  103 +
 gcc/testsuite/gfortran.dg/pr96859.f90              |   25 +
 gcc/testsuite/gfortran.dg/ptr-func-3.f90           |   56 +
 gcc/testsuite/gfortran.dg/ptr_func_assign_4.f08    |    4 +-
 gcc/testsuite/gfortran.dg/reshape_8.f90            |   14 +
 .../gfortran.dg/unlimited_polymorphic_31.f03       |    2 +-
 gcc/testsuite/gfortran.dg/vect/pr96920.f90         |   37 +
 gcc/testsuite/lib/gdc-utils.exp                    |   24 +-
 gcc/testsuite/lib/target-supports-dg.exp           |   10 +
 gcc/testsuite/lib/target-supports.exp              |  117 +-
 gcc/tracer.c                                       |    2 +-
 gcc/trans-mem.c                                    |    4 +-
 gcc/tree-cfg.c                                     |   46 +-
 gcc/tree-cfgcleanup.c                              |   28 +-
 gcc/tree-complex.c                                 |    4 +-
 gcc/tree-if-conv.c                                 |    2 +-
 gcc/tree-inline.c                                  |    2 +-
 gcc/tree-into-ssa.c                                |    4 +-
 gcc/tree-object-size.c                             |    4 +-
 gcc/tree-predcom.c                                 |    8 +-
 gcc/tree-pretty-print.c                            |   89 +-
 gcc/tree-sra.c                                     |   15 +-
 gcc/tree-ssa-address.c                             |   62 +-
 gcc/tree-ssa-coalesce.c                            |    2 +-
 gcc/tree-ssa-dom.c                                 |   56 +-
 gcc/tree-ssa-dse.c                                 |   11 +
 gcc/tree-ssa-forwprop.c                            |    2 +-
 gcc/tree-ssa-loop-im.c                             |    4 +
 gcc/tree-ssa-loop-ivopts.c                         |    4 +-
 gcc/tree-ssa-loop-niter.c                          |    2 +-
 gcc/tree-ssa-pre.c                                 |   13 +-
 gcc/tree-ssa-propagate.c                           |    4 +-
 gcc/tree-ssa-reassoc.c                             |   17 +-
 gcc/tree-ssa-sccvn.c                               |   16 +-
 gcc/tree-ssa-strlen.c                              |   22 +-
 gcc/tree-ssa-threadedge.c                          |    2 +-
 gcc/tree-ssa-uninit.c                              |    8 +-
 gcc/tree-ssanames.c                                |    2 +-
 gcc/tree-streamer-in.c                             |    2 +-
 gcc/tree-vect-data-refs.c                          |   66 +-
 gcc/tree-vect-generic.c                            |   14 +-
 gcc/tree-vect-loop.c                               |  331 ++-
 gcc/tree-vect-patterns.c                           |    2 +-
 gcc/tree-vect-slp.c                                |  467 +++-
 gcc/tree-vect-stmts.c                              |  100 +-
 gcc/tree-vectorizer.h                              |   15 +-
 gcc/tree-vrp.c                                     |  121 +-
 gcc/tree-vrp.h                                     |    1 +
 gcc/tree.c                                         |   15 +
 gcc/tree.h                                         |   15 +
 gcc/value-query.cc                                 |    8 +-
 gcc/value-range.cc                                 |    4 +-
 gcc/value-range.h                                  |    2 +-
 gcc/varasm.c                                       |  181 +-
 gcc/vec.c                                          |    2 +-
 gcc/vec.h                                          |   27 +-
 include/ChangeLog                                  |   15 +
 include/dwarf2.h                                   |   41 +-
 include/floatformat.h                              |    3 +
 libatomic/ChangeLog                                |    4 +
 libatomic/testsuite/libatomic.c/atomic-generic.c   |    1 +
 libbacktrace/ChangeLog                             |   51 +
 libbacktrace/dwarf.c                               |  180 +-
 libbacktrace/fileline.c                            |   38 +-
 libbacktrace/filetype.awk                          |   24 +-
 libbacktrace/macho.c                               |   90 +-
 libbacktrace/pecoff.c                              |   20 +-
 libbacktrace/simple.c                              |    2 +-
 libcc1/libcp1plugin.cc                             |    2 +-
 libcpp/ChangeLog                                   |    5 +
 libcpp/files.c                                     |    2 +-
 libgcc/ChangeLog                                   |   11 +
 libgcc/config/msp430/slli.S                        |   15 +
 libgcc/config/msp430/srai.S                        |   15 +
 libgcc/config/msp430/srli.S                        |   16 +
 libgcc/config/nvptx/atomic.c                       |   12 +-
 libgfortran/ChangeLog                              |   23 +
 libgfortran/generated/iall_i1.c                    |    2 +-
 libgfortran/generated/iall_i16.c                   |    2 +-
 libgfortran/generated/iall_i2.c                    |    2 +-
 libgfortran/generated/iall_i4.c                    |    2 +-
 libgfortran/generated/iall_i8.c                    |    2 +-
 libgfortran/intrinsics/env.c                       |    7 +-
 libgfortran/io/format.c                            |   10 +-
 libgfortran/m4/iall.m4                             |    2 +-
 libgo/Makefile.am                                  |    4 +
 libgo/Makefile.in                                  |    4 +
 libgo/go/cmd/cgo/gcc.go                            |    5 +-
 libgo/go/cmd/go/internal/work/exec.go              |    4 +
 libgo/testsuite/gotest                             |    4 +-
 libgomp/ChangeLog                                  |   21 +
 libgomp/plugin/plugin-nvptx.c                      |   22 +-
 .../libgomp.fortran/lastprivate-conditional-10.f90 |   63 +
 .../libgomp.oacc-c-c++-common/atomic_capture-2.c   |   92 +-
 .../testsuite/libgomp.oacc-fortran/collapse-1.f90  |    3 +
 .../testsuite/libgomp.oacc-fortran/collapse-2.f90  |    3 +
 libiberty/ChangeLog                                |   38 +
 libiberty/d-demangle.c                             |  116 +-
 libiberty/floatformat.c                            |   19 +-
 libiberty/testsuite/d-demangle-expected            |   24 +-
 libphobos/ChangeLog                                |   20 +
 libphobos/Makefile.in                              |    3 +
 libphobos/configure                                |   13 +-
 libphobos/configure.ac                             |    3 +
 libphobos/libdruntime/Makefile.in                  |    4 +
 libphobos/libdruntime/config/x86/switchcontext.S   |    9 +-
 libphobos/libdruntime/core/thread.d                |   52 +-
 libphobos/libdruntime/gcc/config.d.in              |    3 +
 libphobos/src/Makefile.in                          |    4 +
 libphobos/testsuite/Makefile.in                    |    4 +
 libstdc++-v3/ChangeLog                             |  816 +++++++
 libstdc++-v3/config/os/aix/t-aix                   |    3 +
 libstdc++-v3/include/Makefile.am                   |    1 +
 libstdc++-v3/include/Makefile.in                   |    1 +
 libstdc++-v3/include/backward/auto_ptr.h           |    6 +-
 libstdc++-v3/include/backward/binders.h            |    4 +-
 libstdc++-v3/include/bits/c++config                |   57 +-
 libstdc++-v3/include/bits/cpp_type_traits.h        |   60 +
 libstdc++-v3/include/bits/deque.tcc                |    8 +-
 libstdc++-v3/include/bits/hashtable.h              |  692 +++---
 libstdc++-v3/include/bits/hashtable_policy.h       |  468 ++--
 libstdc++-v3/include/bits/ios_base.h               |   17 +-
 libstdc++-v3/include/bits/iterator_concepts.h      |   65 +-
 libstdc++-v3/include/bits/max_size_type.h          |  753 +++++++
 libstdc++-v3/include/bits/node_handle.h            |    4 +-
 libstdc++-v3/include/bits/range_access.h           |   39 +-
 libstdc++-v3/include/bits/ranges_algo.h            |    5 +-
 libstdc++-v3/include/bits/stl_algobase.h           |    7 +-
 libstdc++-v3/include/bits/stl_iterator.h           |    3 +-
 libstdc++-v3/include/bits/stl_tree.h               |   16 -
 libstdc++-v3/include/experimental/numeric          |   38 +-
 libstdc++-v3/include/experimental/string_view      |    9 +-
 libstdc++-v3/include/ext/numeric_traits.h          |   18 +-
 libstdc++-v3/include/parallel/base.h               |    5 +-
 libstdc++-v3/include/std/array                     |   22 +-
 libstdc++-v3/include/std/chrono                    | 2252 +++++++++++++++++++-
 libstdc++-v3/include/std/future                    |   18 +-
 libstdc++-v3/include/std/limits                    |   10 +-
 libstdc++-v3/include/std/numeric                   |  107 +-
 libstdc++-v3/include/std/ranges                    |  133 +-
 libstdc++-v3/include/std/streambuf                 |    4 +-
 libstdc++-v3/include/std/string_view               |    9 +-
 libstdc++-v3/include/std/tuple                     |  174 +-
 libstdc++-v3/include/std/type_traits               |   26 +-
 libstdc++-v3/include/std/variant                   |   26 +-
 libstdc++-v3/libsupc++/new                         |    4 +-
 libstdc++-v3/libsupc++/new_opvnt.cc                |    3 +-
 .../17_intro/headers/c++1998/all_attributes.cc     |    2 +-
 .../17_intro/headers/c++2011/all_attributes.cc     |    2 +-
 .../17_intro/headers/c++2014/all_attributes.cc     |    2 +-
 .../17_intro/headers/c++2017/all_attributes.cc     |    2 +-
 .../17_intro/headers/c++2020/all_attributes.cc     |    2 +-
 .../testsuite/18_support/destroying_delete.cc      |    1 +
 .../testsuite/20_util/duration/cons/dr2094.cc      |   64 +
 .../duration/requirements/reduced_period.cc        |  183 ++
 .../20_util/duration/requirements/typedefs_neg2.cc |    4 +-
 .../invoke_result/incomplete_neg.cc}               |   27 +-
 .../20_util/is_nothrow_invocable/incomplete_neg.cc |   33 +
 .../is_nothrow_swappable/incomplete_neg.cc}        |   26 +-
 .../is_nothrow_swappable_with/incomplete_neg.cc    |   31 +
 .../is_swappable_with/incomplete_neg.cc}           |   29 +-
 .../testsuite/20_util/shared_ptr/atomic/3.cc       |    3 +-
 .../shared_ptr/thread/default_weaktoshared.cc      |    4 +-
 .../shared_ptr/thread/mutex_weaktoshared.cc        |    4 +-
 libstdc++-v3/testsuite/20_util/time_point/4.cc     |   42 +
 libstdc++-v3/testsuite/20_util/tuple/cons/96592.cc |   58 +
 libstdc++-v3/testsuite/20_util/tuple/cons/96803.cc |   41 +
 .../testsuite/20_util/variant/index_type.cc        |    2 +-
 .../array/comparison_operators/96851.cc            |  119 ++
 .../23_containers/array/tuple_interface/get_neg.cc |    6 +-
 .../debug/iterator_self_move_assign_neg.cc         |   34 -
 .../forward_list/debug/self_move_assign_neg.cc     |   33 -
 .../list/debug/iterator_self_move_assign_neg.cc    |   34 -
 .../map/debug/iterator_self_move_assign_neg.cc     |   34 -
 .../map/debug/self_move_assign_neg.cc              |   33 -
 .../debug/iterator_self_move_assign_neg.cc         |   34 -
 .../multimap/debug/self_move_assign_neg.cc         |   33 -
 .../debug/iterator_self_move_assign_neg.cc         |   34 -
 .../multiset/debug/self_move_assign_neg.cc         |   33 -
 .../set/debug/iterator_self_move_assign_neg.cc     |   34 -
 .../debug/iterator_self_move_assign_neg.cc         |   34 -
 .../self_move_assign_neg.cc => dup_types.cc}       |   24 +-
 .../debug/iterator_self_move_assign_neg.cc         |   34 -
 .../debug/self_move_assign_neg.cc                  |   33 -
 .../debug/iterator_self_move_assign_neg.cc         |   34 -
 .../debug/self_move_assign_neg.cc                  |   33 -
 .../debug/iterator_self_move_assign_neg.cc         |   34 -
 .../unordered_set/debug/self_move_assign_neg.cc    |   33 -
 .../vector/debug/self_move_assign_neg.cc           |   33 -
 .../associated_types/readable.traits.cc            |   26 +
 .../testsuite/25_algorithms/pstl/feature_test-2.cc |    1 +
 .../testsuite/25_algorithms/pstl/feature_test-3.cc |    1 +
 .../testsuite/25_algorithms/pstl/feature_test-5.cc |    1 +
 .../testsuite/25_algorithms/pstl/feature_test.cc   |    1 +
 libstdc++-v3/testsuite/26_numerics/gcd/1.cc        |   17 +-
 libstdc++-v3/testsuite/26_numerics/gcd/2.cc        |  133 ++
 libstdc++-v3/testsuite/26_numerics/gcd/92978.cc    |   40 +
 libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc  |   10 +-
 .../lcm/92978.cc}                                  |   24 +-
 libstdc++-v3/testsuite/26_numerics/lcm/lcm_neg.cc  |   10 +-
 libstdc++-v3/testsuite/27_io/types/1.cc            |   13 +-
 libstdc++-v3/testsuite/30_threads/async/42819.cc   |    3 +-
 libstdc++-v3/testsuite/30_threads/async/49668.cc   |    3 +-
 libstdc++-v3/testsuite/30_threads/async/54297.cc   |    3 +-
 libstdc++-v3/testsuite/30_threads/async/any.cc     |    3 +-
 libstdc++-v3/testsuite/30_threads/async/async.cc   |    3 +-
 libstdc++-v3/testsuite/30_threads/async/except.cc  |    3 +-
 libstdc++-v3/testsuite/30_threads/async/launch.cc  |    3 +-
 libstdc++-v3/testsuite/30_threads/async/lwg2021.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/async/sync.cc    |    3 +-
 .../testsuite/30_threads/call_once/39909.cc        |    3 +-
 .../testsuite/30_threads/call_once/49668.cc        |    3 +-
 .../testsuite/30_threads/call_once/60497.cc        |    3 +-
 .../testsuite/30_threads/call_once/call_once1.cc   |    3 +-
 .../testsuite/30_threads/call_once/dr2442.cc       |    3 +-
 .../30_threads/condition_variable/54185.cc         |    3 +-
 .../30_threads/condition_variable/cons/1.cc        |    3 +-
 .../30_threads/condition_variable/members/1.cc     |    3 +-
 .../30_threads/condition_variable/members/2.cc     |    3 +-
 .../30_threads/condition_variable/members/3.cc     |    3 +-
 .../30_threads/condition_variable/members/53841.cc |    3 +-
 .../30_threads/condition_variable/members/68519.cc |    3 +-
 .../condition_variable/native_handle/typesizes.cc  |    3 +-
 .../30_threads/condition_variable_any/50862.cc     |    3 +-
 .../30_threads/condition_variable_any/53830.cc     |    3 +-
 .../30_threads/condition_variable_any/cond.cc      |    3 +-
 .../30_threads/condition_variable_any/cons/1.cc    |    3 +-
 .../30_threads/condition_variable_any/members/1.cc |    3 +-
 .../30_threads/condition_variable_any/members/2.cc |    3 +-
 .../testsuite/30_threads/future/cons/move.cc       |    3 +-
 .../testsuite/30_threads/future/members/45133.cc   |    3 +-
 .../testsuite/30_threads/future/members/get.cc     |    3 +-
 .../testsuite/30_threads/future/members/get2.cc    |    3 +-
 .../testsuite/30_threads/future/members/share.cc   |    3 +-
 .../testsuite/30_threads/future/members/valid.cc   |    3 +-
 .../testsuite/30_threads/future/members/wait.cc    |    3 +-
 .../30_threads/future/members/wait_for.cc          |    3 +-
 .../30_threads/future/members/wait_until.cc        |    3 +-
 .../30_threads/future/requirements/lwg3458.cc      |   13 +-
 libstdc++-v3/testsuite/30_threads/lock/1.cc        |    3 +-
 libstdc++-v3/testsuite/30_threads/lock/2.cc        |    3 +-
 libstdc++-v3/testsuite/30_threads/lock/3.cc        |    3 +-
 libstdc++-v3/testsuite/30_threads/lock/4.cc        |    3 +-
 libstdc++-v3/testsuite/30_threads/mutex/cons/1.cc  |    3 +-
 .../30_threads/mutex/dest/destructor_locked.cc     |    3 +-
 libstdc++-v3/testsuite/30_threads/mutex/lock/1.cc  |    3 +-
 .../testsuite/30_threads/mutex/native_handle/1.cc  |    3 +-
 .../30_threads/mutex/native_handle/typesizes.cc    |    3 +-
 .../testsuite/30_threads/mutex/try_lock/1.cc       |    3 +-
 .../testsuite/30_threads/mutex/try_lock/2.cc       |    3 +-
 .../testsuite/30_threads/mutex/unlock/1.cc         |    3 +-
 .../testsuite/30_threads/mutex/unlock/2.cc         |    3 +-
 .../testsuite/30_threads/packaged_task/49668.cc    |    3 +-
 .../testsuite/30_threads/packaged_task/60564.cc    |    3 +-
 .../testsuite/30_threads/packaged_task/cons/1.cc   |    3 +-
 .../testsuite/30_threads/packaged_task/cons/2.cc   |    3 +-
 .../testsuite/30_threads/packaged_task/cons/3.cc   |    3 +-
 .../30_threads/packaged_task/cons/56492.cc         |    3 +-
 .../30_threads/packaged_task/cons/alloc.cc         |    4 +-
 .../30_threads/packaged_task/cons/move.cc          |    3 +-
 .../30_threads/packaged_task/cons/move_assign.cc   |    3 +-
 .../packaged_task/members/at_thread_exit.cc        |    3 +-
 .../30_threads/packaged_task/members/get_future.cc |    3 +-
 .../packaged_task/members/get_future2.cc           |    3 +-
 .../30_threads/packaged_task/members/invoke.cc     |    3 +-
 .../30_threads/packaged_task/members/invoke2.cc    |    3 +-
 .../30_threads/packaged_task/members/invoke3.cc    |    3 +-
 .../30_threads/packaged_task/members/invoke4.cc    |    3 +-
 .../30_threads/packaged_task/members/invoke5.cc    |    3 +-
 .../30_threads/packaged_task/members/reset.cc      |    3 +-
 .../30_threads/packaged_task/members/reset2.cc     |    3 +-
 .../30_threads/packaged_task/members/swap.cc       |    3 +-
 .../30_threads/packaged_task/members/valid.cc      |    3 +-
 libstdc++-v3/testsuite/30_threads/promise/60966.cc |    3 +-
 .../testsuite/30_threads/promise/cons/1.cc         |    3 +-
 .../testsuite/30_threads/promise/cons/alloc.cc     |    3 +-
 .../testsuite/30_threads/promise/cons/move.cc      |    3 +-
 .../30_threads/promise/cons/move_assign.cc         |    3 +-
 .../30_threads/promise/members/at_thread_exit.cc   |    3 +-
 .../30_threads/promise/members/at_thread_exit2.cc  |    3 +-
 .../30_threads/promise/members/get_future.cc       |    3 +-
 .../30_threads/promise/members/get_future2.cc      |    3 +-
 .../30_threads/promise/members/set_exception.cc    |    3 +-
 .../30_threads/promise/members/set_exception2.cc   |    3 +-
 .../30_threads/promise/members/set_value.cc        |    3 +-
 .../30_threads/promise/members/set_value2.cc       |    3 +-
 .../30_threads/promise/members/set_value3.cc       |    3 +-
 .../testsuite/30_threads/promise/members/swap.cc   |    3 +-
 .../30_threads/promise/requirements/lwg3466.cc     |   13 +-
 .../testsuite/30_threads/recursive_mutex/cons/1.cc |    3 +-
 .../recursive_mutex/dest/destructor_locked.cc      |    3 +-
 .../testsuite/30_threads/recursive_mutex/lock/1.cc |    3 +-
 .../30_threads/recursive_mutex/native_handle/1.cc  |    3 +-
 .../recursive_mutex/native_handle/typesizes.cc     |    3 +-
 .../30_threads/recursive_mutex/try_lock/1.cc       |    3 +-
 .../30_threads/recursive_mutex/try_lock/2.cc       |    3 +-
 .../30_threads/recursive_mutex/unlock/1.cc         |    3 +-
 .../30_threads/recursive_mutex/unlock/2.cc         |    3 +-
 .../30_threads/recursive_timed_mutex/cons/1.cc     |    4 +-
 .../dest/destructor_locked.cc                      |    4 +-
 .../30_threads/recursive_timed_mutex/lock/1.cc     |    4 +-
 .../30_threads/recursive_timed_mutex/lock/2.cc     |    4 +-
 .../recursive_timed_mutex/native_handle/1.cc       |    3 +-
 .../native_handle/typesizes.cc                     |    3 +-
 .../30_threads/recursive_timed_mutex/try_lock/1.cc |    4 +-
 .../30_threads/recursive_timed_mutex/try_lock/2.cc |    4 +-
 .../recursive_timed_mutex/try_lock_for/1.cc        |    4 +-
 .../recursive_timed_mutex/try_lock_for/2.cc        |    4 +-
 .../recursive_timed_mutex/try_lock_for/3.cc        |    4 +-
 .../recursive_timed_mutex/try_lock_until/1.cc      |    4 +-
 .../recursive_timed_mutex/try_lock_until/2.cc      |    4 +-
 .../30_threads/recursive_timed_mutex/unlock/1.cc   |    4 +-
 .../30_threads/recursive_timed_mutex/unlock/2.cc   |    3 +-
 .../30_threads/shared_future/cons/move.cc          |    3 +-
 .../30_threads/shared_future/members/45133.cc      |    3 +-
 .../30_threads/shared_future/members/get.cc        |    3 +-
 .../30_threads/shared_future/members/get2.cc       |    3 +-
 .../30_threads/shared_future/members/valid.cc      |    3 +-
 .../30_threads/shared_future/members/wait.cc       |    3 +-
 .../30_threads/shared_future/members/wait_for.cc   |    3 +-
 .../30_threads/shared_future/members/wait_until.cc |    3 +-
 .../shared_future/requirements/lwg3458.cc          |   13 +-
 .../testsuite/30_threads/shared_lock/cons/1.cc     |    3 +-
 .../testsuite/30_threads/shared_lock/cons/2.cc     |    3 +-
 .../testsuite/30_threads/shared_lock/cons/3.cc     |    3 +-
 .../testsuite/30_threads/shared_lock/cons/4.cc     |    3 +-
 .../testsuite/30_threads/shared_lock/cons/5.cc     |    4 +-
 .../testsuite/30_threads/shared_lock/cons/6.cc     |    4 +-
 .../testsuite/30_threads/shared_lock/locking/1.cc  |    3 +-
 .../testsuite/30_threads/shared_lock/locking/2.cc  |    3 +-
 .../testsuite/30_threads/shared_lock/locking/3.cc  |    4 +-
 .../testsuite/30_threads/shared_lock/locking/4.cc  |    4 +-
 .../30_threads/shared_lock/modifiers/1.cc          |    3 +-
 .../testsuite/30_threads/shared_mutex/cons/1.cc    |    4 +-
 .../30_threads/shared_mutex/try_lock/1.cc          |    4 +-
 .../30_threads/shared_mutex/try_lock/2.cc          |    4 +-
 .../testsuite/30_threads/shared_mutex/unlock/1.cc  |    4 +-
 .../30_threads/shared_timed_mutex/cons/1.cc        |    3 +-
 .../30_threads/shared_timed_mutex/try_lock/1.cc    |    3 +-
 .../30_threads/shared_timed_mutex/try_lock/2.cc    |    3 +-
 .../30_threads/shared_timed_mutex/try_lock/3.cc    |    3 +-
 .../30_threads/shared_timed_mutex/unlock/1.cc      |    3 +-
 libstdc++-v3/testsuite/30_threads/this_thread/1.cc |    3 +-
 .../30_threads/this_thread/sleep_for-mt.cc         |    3 +-
 .../30_threads/this_thread/sleep_until-mt.cc       |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/1.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/2.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/3.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/4.cc |    3 +-
 .../testsuite/30_threads/thread/cons/49668.cc      |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/5.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/6.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/7.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/8.cc |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/cons/9.cc |    3 +-
 .../testsuite/30_threads/thread/cons/moveable.cc   |    3 +-
 .../testsuite/30_threads/thread/cons/terminate.cc  |    3 +-
 .../testsuite/30_threads/thread/members/1.cc       |    3 +-
 .../testsuite/30_threads/thread/members/2.cc       |    3 +-
 .../testsuite/30_threads/thread/members/3.cc       |    3 +-
 .../testsuite/30_threads/thread/members/4.cc       |    3 +-
 .../testsuite/30_threads/thread/members/5.cc       |    3 +-
 .../thread/members/hardware_concurrency.cc         |    3 +-
 .../30_threads/thread/native_handle/typesizes.cc   |    3 +-
 libstdc++-v3/testsuite/30_threads/thread/swap/1.cc |    3 +-
 .../testsuite/30_threads/timed_mutex/cons/1.cc     |    4 +-
 .../timed_mutex/dest/destructor_locked.cc          |    4 +-
 .../testsuite/30_threads/timed_mutex/lock/1.cc     |    4 +-
 .../30_threads/timed_mutex/native_handle/1.cc      |    3 +-
 .../timed_mutex/native_handle/typesizes.cc         |    3 +-
 .../testsuite/30_threads/timed_mutex/try_lock/1.cc |    4 +-
 .../testsuite/30_threads/timed_mutex/try_lock/2.cc |    4 +-
 .../30_threads/timed_mutex/try_lock_for/1.cc       |    4 +-
 .../30_threads/timed_mutex/try_lock_for/2.cc       |    4 +-
 .../30_threads/timed_mutex/try_lock_for/3.cc       |    4 +-
 .../30_threads/timed_mutex/try_lock_until/1.cc     |    4 +-
 .../30_threads/timed_mutex/try_lock_until/2.cc     |    4 +-
 .../30_threads/timed_mutex/try_lock_until/57641.cc |    4 +-
 .../testsuite/30_threads/timed_mutex/unlock/1.cc   |    4 +-
 .../testsuite/30_threads/timed_mutex/unlock/2.cc   |    3 +-
 libstdc++-v3/testsuite/30_threads/try_lock/1.cc    |    3 +-
 libstdc++-v3/testsuite/30_threads/try_lock/2.cc    |    3 +-
 libstdc++-v3/testsuite/30_threads/try_lock/3.cc    |    3 +-
 libstdc++-v3/testsuite/30_threads/try_lock/4.cc    |    3 +-
 .../testsuite/30_threads/unique_lock/cons/1.cc     |    3 +-
 .../testsuite/30_threads/unique_lock/cons/2.cc     |    3 +-
 .../testsuite/30_threads/unique_lock/cons/3.cc     |    3 +-
 .../testsuite/30_threads/unique_lock/cons/4.cc     |    3 +-
 .../testsuite/30_threads/unique_lock/cons/5.cc     |    4 +-
 .../testsuite/30_threads/unique_lock/cons/6.cc     |    4 +-
 .../testsuite/30_threads/unique_lock/locking/1.cc  |    3 +-
 .../testsuite/30_threads/unique_lock/locking/2.cc  |    3 +-
 .../testsuite/30_threads/unique_lock/locking/3.cc  |    4 +-
 .../testsuite/30_threads/unique_lock/locking/4.cc  |    4 +-
 .../30_threads/unique_lock/modifiers/1.cc          |    3 +-
 .../testsuite/experimental/numeric/92978.cc        |   48 +
 libstdc++-v3/testsuite/experimental/numeric/gcd.cc |  136 +-
 .../testsuite/std/ranges/adaptors/95322.cc         |    2 +-
 .../testsuite/std/ranges/adaptors/elements.cc      |   22 +
 .../ranges/adaptors/join_lwg3474.cc}               |   33 +-
 .../testsuite/std/ranges/adaptors/lwg3406.cc       |   40 +
 libstdc++-v3/testsuite/std/ranges/iota/96042.cc    |   65 +
 .../testsuite/std/ranges/iota/difference_type.cc   |   57 +
 .../testsuite/std/ranges/iota/max_size_type.cc     |  376 ++++
 libstdc++-v3/testsuite/std/ranges/iota/size.cc     |  110 +
 .../testsuite/std/ranges/subrange/96042.cc         |   34 +
 libstdc++-v3/testsuite/std/time/day/1.cc           |   67 +
 libstdc++-v3/testsuite/std/time/hh_mm_ss/1.cc      |   63 +
 .../time/is_am/1.cc}                               |   33 +-
 .../time/is_pm/1.cc}                               |   34 +-
 libstdc++-v3/testsuite/std/time/make12/1.cc        |   36 +
 libstdc++-v3/testsuite/std/time/make24/1.cc        |   41 +
 libstdc++-v3/testsuite/std/time/month/1.cc         |   75 +
 libstdc++-v3/testsuite/std/time/month_day/1.cc     |   73 +
 .../testsuite/std/time/month_day_last/1.cc         |   65 +
 libstdc++-v3/testsuite/std/time/month_weekday/1.cc |   48 +
 .../testsuite/std/time/month_weekday_last/1.cc     |   48 +
 libstdc++-v3/testsuite/std/time/weekday/1.cc       |  102 +
 .../testsuite/std/time/weekday_indexed/1.cc        |   53 +
 libstdc++-v3/testsuite/std/time/weekday_last/1.cc  |   48 +
 libstdc++-v3/testsuite/std/time/year/1.cc          |   85 +
 libstdc++-v3/testsuite/std/time/year_month/1.cc    |   98 +
 libstdc++-v3/testsuite/std/time/year_month/2.cc    |   40 +
 .../testsuite/std/time/year_month_day/1.cc         |   91 +
 .../testsuite/std/time/year_month_day/2.cc         |   40 +
 .../testsuite/std/time/year_month_day_last/1.cc    |   82 +
 .../testsuite/std/time/year_month_day_last/2.cc    |   40 +
 .../testsuite/std/time/year_month_weekday/1.cc     |   79 +
 .../testsuite/std/time/year_month_weekday/2.cc     |   40 +
 .../std/time/year_month_weekday_last/1.cc          |   61 +
 .../std/time/year_month_weekday_last/2.cc          |   40 +
 lto-plugin/ChangeLog                               |    7 +
 lto-plugin/Makefile.am                             |    2 +-
 lto-plugin/Makefile.in                             |    2 +-
 lto-plugin/lto-plugin.c                            |   31 +-
 1140 files changed, 31986 insertions(+), 9407 deletions(-)

diff --cc gcc/builtins.c
index c9057fd9b79,97f1a184dc6..fb94c8e0ac0
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@@ -183,6 -183,9 +183,10 @@@ static void maybe_emit_chk_warning (tre
  static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
  static void maybe_emit_free_warning (tree);
  static tree fold_builtin_object_size (tree, tree);
 -static tree compute_objsize (tree, int, access_ref *, const vr_values * = NULL);
 -static bool get_range (tree, signop, offset_int[2], const vr_values * = NULL);
++static tree compute_objsize (tree, int, access_ref *, range_query * = NULL);
++static bool get_range (tree, gimple *, signop, offset_int[2],
++		       range_query * = NULL);
+ static bool check_read_access (tree, tree, tree = NULL_TREE, int = 1);
  
  unsigned HOST_WIDE_INT target_newline;
  unsigned HOST_WIDE_INT target_percent;
@@@ -4181,8 -4367,7 +4368,7 @@@ compute_objsize (tree ptr, int ostype, 
  	     offset to the maximum.  */
  	  offset_int orng[2];
  	  tree off = gimple_assign_rhs2 (stmt);
- 	  if (!get_range (off, stmt, SIGNED, orng, rvals)
- 	      || !wi::les_p (orng[0], orng[1]))
 -	  if (!get_range (off, SIGNED, orng, rvals))
++	  if (!get_range (off, stmt, SIGNED, orng, rvals))
  	    {
  	      orng[0] = wi::to_offset (TYPE_MIN_VALUE (ptrdiff_type_node));
  	      orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
@@@ -4216,7 -4407,7 +4408,7 @@@
  
  static tree
  compute_objsize (tree ptr, int ostype, access_ref *pref,
- 		 range_query *rvals = NULL)
 -		 const vr_values *rvals /* = NULL */)
++		 range_query *rvals /* = NULL */)
  {
    bitmap visited = NULL;
  
diff --cc gcc/calls.h
index cbb4d21c145,dfb951ca45b..0784fb28430
--- a/gcc/calls.h
+++ b/gcc/calls.h
@@@ -132,9 -132,8 +132,9 @@@ extern bool reference_callee_copied (CU
  				     const function_arg_info &);
  extern void maybe_warn_alloc_args_overflow (tree, tree, tree[2], int[2]);
  extern tree get_attr_nonstring_decl (tree, tree * = NULL);
- extern void maybe_warn_nonstring_arg (tree, tree);
+ extern bool maybe_warn_nonstring_arg (tree, tree);
  extern bool get_size_range (tree, tree[2], bool = false);
 +extern bool get_size_range (tree, gimple *, tree[2], bool = false);
  extern rtx rtx_for_static_chain (const_tree, bool);
  extern bool cxx17_empty_base_field_p (const_tree);
  
diff --cc gcc/gimple-range-cache.cc
index d7fd5e84585,00000000000..777ab564727
mode 100644,000000..100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@@ -1,665 -1,0 +1,665 @@@
 +/* Gimple ranger SSA cache implementation.
 +   Copyright (C) 2017-2020 Free Software Foundation, Inc.
 +   Contributed by Andrew MacLeod <amacleod@redhat.com>.
 +
 +This file is part of GCC.
 +
 +GCC is free software; you can redistribute it and/or modify
 +it under the terms of the GNU General Public License as published by
 +the Free Software Foundation; either version 3, or (at your option)
 +any later version.
 +
 +GCC is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with GCC; see the file COPYING3.  If not see
 +<http://www.gnu.org/licenses/>.  */
 +
 +#include "config.h"
 +#include "system.h"
 +#include "coretypes.h"
 +#include "backend.h"
 +#include "insn-codes.h"
 +#include "tree.h"
 +#include "gimple.h"
 +#include "ssa.h"
 +#include "gimple-pretty-print.h"
 +#include "gimple-range.h"
 +
 +// During contructor, allocate the vector of ssa_names.
 +
 +non_null_ref::non_null_ref ()
 +{
 +  m_nn.create (0);
 +  m_nn.safe_grow_cleared (num_ssa_names);
 +}
 +
 +// Free any bitmaps which were allocated,a swell as the vector itself.
 +
 +non_null_ref::~non_null_ref ()
 +{
 +  unsigned x;
 +  for (x = 0; x< m_nn.length (); x++)
 +    if (m_nn[x])
 +      BITMAP_FREE (m_nn[x]);
 +}
 +
 +// Return true if NAME has a non-null dereference in block bb.  If this is the
 +// first query for NAME, calculate the summary first.
 +
 +bool
 +non_null_ref::non_null_deref_p (tree name, basic_block bb)
 +{
 +  if (!POINTER_TYPE_P (TREE_TYPE (name)))
 +    return false;
 +
 +  unsigned v = SSA_NAME_VERSION (name);
 +  if (!m_nn[v])
 +    process_name (name);
 +
 +  return bitmap_bit_p (m_nn[v], bb->index);
 +}
 +
 +// Allocate an populate the bitmap for NAME.  An ON bit for a block
 +// index indicates there is a non-null reference in that block.  In
 +// order to populate the bitmap, a quick run of all the immediate uses
 +// are made and the statement checked to see if a non-null dereference
 +// is made on that statement.
 +
 +void
 +non_null_ref::process_name (tree name)
 +{
 +  unsigned v = SSA_NAME_VERSION (name);
 +  use_operand_p use_p;
 +  imm_use_iterator iter;
 +  bitmap b;
 +
 +  // Only tracked for pointers.
 +  if (!POINTER_TYPE_P (TREE_TYPE (name)))
 +    return;
 +
 +  // Already processed if a bitmap has been allocated.
 +  if (m_nn[v])
 +    return;
 +
 +  b = BITMAP_ALLOC (NULL);
 +
 +  // Loop over each immediate use and see if it implies a non-null value.
 +  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
 +    {
 +      gimple *s = USE_STMT (use_p);
 +      unsigned index = gimple_bb (s)->index;
 +      tree value;
 +      enum tree_code comp_code;
 +
 +      // If bit is already set for this block, dont bother looking again.
 +      if (bitmap_bit_p (b, index))
 +	continue;
 +
 +      // If we can infer a != 0 range, then set the bit for this BB
 +      if (infer_value_range (s, name, &comp_code, &value))
 +	{
 +	  if (comp_code == NE_EXPR && integer_zerop (value))
 +	    bitmap_set_bit (b, index);
 +	}
 +    }
 +
 +  m_nn[v] = b;
 +}
 +
 +// This class implements a cache of ranges indexed by basic block.  It
 +// represents all that is known about an SSA_NAME on entry to each
 +// block.  It caches a range-for-type varying range so it doesn't need
 +// to be reformed all the time.  If a range is ever always associated
 +// with a type, we can use that instead.  Whenever varying is being
 +// set for a block, the cache simply points to this cached one rather
 +// than create a new one each time.
 +
 +class ssa_block_ranges
 +{
 +public:
 +  ssa_block_ranges (tree t);
 +  ~ssa_block_ranges ();
 +
 +  void set_bb_range (const basic_block bb, const irange &r);
 +  void set_bb_varying (const basic_block bb);
 +  bool get_bb_range (irange &r, const basic_block bb);
 +  bool bb_range_p (const basic_block bb);
 +
 +  void dump(FILE *f);
 +private:
 +  vec<irange *> m_tab;
 +  irange *m_type_range;
 +  tree m_type;
 +  irange_pool m_irange_pool;
 +};
 +
 +
 +// Initialize a block cache for an ssa_name of type T
 +
 +ssa_block_ranges::ssa_block_ranges (tree t)
 +{
 +  gcc_assert (TYPE_P (t));
 +  m_type = t;
 +
 +  m_tab.create (0);
 +  m_tab.safe_grow_cleared (last_basic_block_for_fn (cfun));
 +
 +  // Create the cached type range.
 +  m_type_range = m_irange_pool.allocate (2);
 +  m_type_range->set_varying (t);
 +
 +  m_tab[ENTRY_BLOCK_PTR_FOR_FN (cfun)->index] = m_type_range;
 +}
 +
 +// Destruct block range.
 +
 +ssa_block_ranges::~ssa_block_ranges ()
 +{
 +  m_tab.release ();
 +}
 +
 +// Set the range for block BB to be R.
 +
 +void
 +ssa_block_ranges::set_bb_range (const basic_block bb, const irange &r)
 +{
 +  irange *m = m_irange_pool.allocate (r);
 +  m_tab[bb->index] = m;
 +}
 +
 +// Set the range for block BB to the range for the type.
 +
 +void
 +ssa_block_ranges::set_bb_varying (const basic_block bb)
 +{
 +  m_tab[bb->index] = m_type_range;
 +}
 +
 +// Return the range associated with block BB in R. Return false if
 +// there is no range.
 +
 +bool
 +ssa_block_ranges::get_bb_range (irange &r, const basic_block bb)
 +{
 +  irange *m = m_tab[bb->index];
 +  if (m)
 +    {
 +      r = *m;
 +      return true;
 +    }
 +  return false;
 +}
 +
 +// Returns true if a range is present
 +
 +bool
 +ssa_block_ranges::bb_range_p (const basic_block bb)
 +{
 +  return m_tab[bb->index] != NULL;
 +}
 +
 +
 +// Print the list of known ranges for file F in a nice format.
 +
 +void
 +ssa_block_ranges::dump (FILE *f)
 +{
 +  basic_block bb;
-   widest_irange r;
++  int_range_max r;
 +
 +  FOR_EACH_BB_FN (bb, cfun)
 +    if (get_bb_range (r, bb))
 +      {
 +	fprintf (f, "BB%d  -> ", bb->index);
 +	r.dump (f);
 +	fprintf (f, "\n");
 +      }
 +}
 +
 +// -------------------------------------------------------------------------
 +
 +// Initialize the block cache.
 +
 +block_range_cache::block_range_cache ()
 +{
 +  m_ssa_ranges.create (0);
 +  m_ssa_ranges.safe_grow_cleared (num_ssa_names);
 +}
 +
 +// Remove any m_block_caches which have been created.
 +
 +block_range_cache::~block_range_cache ()
 +{
 +  unsigned x;
 +  for (x = 0; x < m_ssa_ranges.length (); ++x)
 +    {
 +      if (m_ssa_ranges[x])
 +	delete m_ssa_ranges[x];
 +    }
 +  // Release the vector itself.
 +  m_ssa_ranges.release ();
 +}
 +
 +// Return a reference to the m_block_cache for NAME. If it has not been
 +// accessed yet, allocate it.
 +
 +ssa_block_ranges &
 +block_range_cache::get_block_ranges (tree name)
 +{
 +  unsigned v = SSA_NAME_VERSION (name);
 +  if (v >= m_ssa_ranges.length ())
 +    m_ssa_ranges.safe_grow_cleared (num_ssa_names + 1);
 +
 +  if (!m_ssa_ranges[v])
 +    m_ssa_ranges[v] = new ssa_block_ranges (TREE_TYPE (name));
 +
 +  return *(m_ssa_ranges[v]);
 +}
 +
 +// Set the range for NAME on entry to block BB to R.
 +
 +void
 +block_range_cache::set_bb_range (tree name, const basic_block bb,
 +				 const irange &r)
 +{
 +  return get_block_ranges (name).set_bb_range (bb, r);
 +}
 +
 +// Set the range for NAME on entry to block BB to varying..
 +
 +void
 +block_range_cache::set_bb_varying (tree name, const basic_block bb)
 +{
 +  return get_block_ranges (name).set_bb_varying (bb);
 +}
 +
 +// Return the range for NAME on entry to BB in R.  Return true if here
 +// is one.
 +
 +bool
 +block_range_cache::get_bb_range (irange &r, tree name, const basic_block bb)
 +{
 +  return get_block_ranges (name).get_bb_range (r, bb);
 +}
 +
 +// Return true if NAME has a range set in block BB.
 +
 +bool
 +block_range_cache::bb_range_p (tree name, const basic_block bb)
 +{
 +  return get_block_ranges (name).bb_range_p (bb);
 +}
 +
 +// Print all known block caches to file F.
 +void
 +block_range_cache::dump (FILE *f)
 +{
 +  unsigned x;
 +  for (x = 0; x < m_ssa_ranges.length (); ++x)
 +    {
 +      if (m_ssa_ranges[x])
 +	{
 +	  fprintf (f, " Ranges for ");
 +	  print_generic_expr (f, ssa_name (x), TDF_NONE);
 +	  fprintf (f, ":\n");
 +	  m_ssa_ranges[x]->dump (f);
 +	  fprintf (f, "\n");
 +	}
 +    }
 +}
 +
 +// Print all known ranges on entry to blobk BB to file F.
 +void
 +block_range_cache::dump (FILE *f, basic_block bb, bool print_varying)
 +{
 +  unsigned x;
-   widest_irange r;
++  int_range_max r;
 +  bool summarize_varying = false;
 +  for (x = 1; x < m_ssa_ranges.length (); ++x)
 +    {
 +      if (!gimple_range_ssa_p (ssa_name (x)))
 +	continue;
 +      if (m_ssa_ranges[x] && m_ssa_ranges[x]->get_bb_range (r, bb))
 +	{
 +	  if (!print_varying && r.varying_p ())
 +	    {
 +	      summarize_varying = true;
 +	      continue;
 +	    }
 +	  print_generic_expr (f, ssa_name (x), TDF_NONE);
 +	  fprintf (f, "\t");
 +	  r.dump(f);
 +	  fprintf (f, "\n");
 +	}
 +    }
 +  // If there were any varying entries, lump them all together.
 +  if (summarize_varying)
 +    {
 +      fprintf (f, "VARYING_P on entry : ");
 +      for (x = 1; x < num_ssa_names; ++x)
 +	{
 +	  if (!gimple_range_ssa_p (ssa_name (x)))
 +	    continue;
 +	  if (m_ssa_ranges[x] && m_ssa_ranges[x]->get_bb_range (r, bb))
 +	    {
 +	      if (r.varying_p ())
 +		{
 +		  print_generic_expr (f, ssa_name (x), TDF_NONE);
 +		  fprintf (f, "  ");
 +		}
 +	    }
 +	}
 +      fprintf (f, "\n");
 +    }
 +}
 +// -------------------------------------------------------------------------
 +
 +// Initialize a global cache.
 +
 +ssa_global_cache::ssa_global_cache ()
 +{
 +  m_tab.create (0);
 +  m_tab.safe_grow_cleared (num_ssa_names);
 +  m_irange_pool = new irange_pool;
 +}
 +
 +// Deconstruct a global cache.
 +
 +ssa_global_cache::~ssa_global_cache ()
 +{
 +  m_tab.release ();
 +  delete m_irange_pool;
 +}
 +
 +// Retrieve the global range of NAME from cache memory if it exists. 
 +// Return the value in R.
 +
 +bool
 +ssa_global_cache::get_global_range (irange &r, tree name) const
 +{
 +  unsigned v = SSA_NAME_VERSION (name);
 +  if (v >= m_tab.length ())
 +    return false;
 +
 +  irange *stow = m_tab[v];
 +  if (!stow)
 +    return false;
 +  r = *stow;
 +  return true;
 +}
 +
 +// Set the range for NAME to R in the global cache.
 +
 +void
 +ssa_global_cache::set_global_range (tree name, const irange &r)
 +{
 +  unsigned v = SSA_NAME_VERSION (name);
 +  if (v >= m_tab.length ())
 +    m_tab.safe_grow_cleared (num_ssa_names + 1);
 +
 +  irange *m = m_tab[v];
 +  if (m && m->fits_p (r))
 +    *m = r;
 +  else
 +    m_tab[v] = m_irange_pool->allocate (r);
 +}
 +
 +// Set the range for NAME to R in the glonbal cache.
 +
 +void
 +ssa_global_cache::clear_global_range (tree name)
 +{
 +  unsigned v = SSA_NAME_VERSION (name);
 +  if (v >= m_tab.length ())
 +    m_tab.safe_grow_cleared (num_ssa_names + 1);
 +  m_tab[v] = NULL;
 +}
 +
 +// Clear the global cache.
 +
 +void
 +ssa_global_cache::clear ()
 +{
 +  memset (m_tab.address(), 0, m_tab.length () * sizeof (irange *));
 +}
 +
 +// Dump the contents of the global cache to F.
 +
 +void
 +ssa_global_cache::dump (FILE *f)
 +{
 +  unsigned x;
-   widest_irange r;
++  int_range_max r;
 +  fprintf (f, "Non-varying global ranges:\n");
 +  fprintf (f, "=========================:\n");
 +  for ( x = 1; x < num_ssa_names; x++)
 +    if (gimple_range_ssa_p (ssa_name (x)) &&
 +	get_global_range (r, ssa_name (x))  && !r.varying_p ())
 +      {
 +	print_generic_expr (f, ssa_name (x), TDF_NONE);
 +	fprintf (f, "  : ");
 +	r.dump (f);
 +	fprintf (f, "\n");
 +      }
 +  fputc ('\n', f);
 +}
 +
 +// --------------------------------------------------------------------------
 +
 +ranger_cache::ranger_cache ()
 +{
 +  m_workback.create (0);
 +  m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun));
 +  m_update_list.create (0);
 +  m_update_list.safe_grow_cleared (last_basic_block_for_fn (cfun));
 +  m_update_list.truncate (0);
 +}
 +
 +ranger_cache::~ranger_cache ()
 +{
 +  m_workback.release ();
 +  m_update_list.release ();
 +}
 +
 +
 +//  Provide lookup for the gori-computes class to access the best known range
 +//  of an ssa_name in any given basic block.  NOte this does no additonal
 +//  lookups, just accesses the data that is already known.
 +
 +void
 +ranger_cache::ssa_range_in_bb (irange &r, tree name, basic_block bb)
 +{
 +  gimple *s = SSA_NAME_DEF_STMT (name);
 +  basic_block def_bb = ((s && gimple_bb (s)) ? gimple_bb (s) :
 +					       ENTRY_BLOCK_PTR_FOR_FN (cfun));
 +  if (bb == def_bb || !m_on_entry.get_bb_range (r, name, bb))
 +    {
 +      // Try to pick up any known value first.
 +      if (!m_globals.get_global_range (r, name))
 +	r = gimple_range_global (name);
 +    }
 +
 +  // Check if pointers have any non-null dereferences.  Non-call
 +  // exceptions mean we could throw in the middle of he block, so just
 +  // punt for now on those.
 +  if (r.varying_p () && m_non_null.non_null_deref_p (name, bb) &&
 +      !cfun->can_throw_non_call_exceptions)
 +    r = range_nonzero (TREE_TYPE (name));
 +}
 +
 +
 +// Return a static range for NAME on entry to basic block BB in R.  If
 +// calc is true, fill any cache entries required between BB and the
 +// def block for NAME.  Otherwise, return false if the cache is empty.
 +
 +bool
 +ranger_cache::block_range (irange &r, basic_block bb, tree name, bool calc)
 +{
 +  gcc_checking_assert (gimple_range_ssa_p (name));
 +
 +  if (calc)
 +    {
 +      gimple *def_stmt = SSA_NAME_DEF_STMT (name);
 +      basic_block def_bb = NULL;
 +      if (def_stmt)
 +	def_bb = gimple_bb (def_stmt);;
 +      if (!def_bb)
 +	{
 +	  // If we get to the entry block, this better be a default def
 +	  // or range_on_entry was called for a block not dominated by
 +	  // the def.  This would be a bug.
 +	  gcc_checking_assert (SSA_NAME_IS_DEFAULT_DEF (name));
 +	  def_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
 +	}
 +
 +      // There is no range on entry for the definition block.
 +      if (def_bb == bb)
 +	return false;
 +
 +      // Otherwise, go figure out what is known in predecessor blocks.
 +      fill_block_cache (name, bb, def_bb);
 +      gcc_checking_assert (m_on_entry.bb_range_p (name, bb));
 +    }
 +  return m_on_entry.get_bb_range (r, name, bb);
 +}
 +
 +
 +void
 +ranger_cache::add_to_update (basic_block bb)
 +{
 +  if (!m_update_list.contains (bb))
 +    m_update_list.quick_push (bb);
 +}
 +
 +#define DEBUG_CACHE (dump_file && flag_evrp_mode == EVRP_MODE_RVRP_DEBUG)
 +
 +// If there is anything in the iterative update_list, continue
 +// processing NAME until the list of blocks is empty.
 +
 +void
 +ranger_cache::iterative_cache_update (tree name)
 +{
 +  basic_block bb;
 +  edge_iterator ei;
 +  edge e;
-   widest_irange new_range;
-   widest_irange current_range;
-   widest_irange e_range;
++  int_range_max new_range;
++  int_range_max current_range;
++  int_range_max e_range;
 +
 +  // Process each block by seeing if it's calculated range on entry is
 +  // the same as it's cached value. IF there is a difference, update
 +  // the cache to reflect the new value, and check to see if any
 +  // successors have cache entries which may need to be checked for
 +  // updates.
 +
 +  while (m_update_list.length () > 0)
 +    {
 +      bb = m_update_list.pop ();
 +if (DEBUG_CACHE) fprintf (dump_file, "FWD visiting block %d\n", bb->index);
 +
 +      gcc_assert (m_on_entry.get_bb_range (current_range, name, bb));
 +      // Calculate the "new" range on entry by unioning the pred edges..
 +      new_range.set_undefined ();
 +      FOR_EACH_EDGE (e, ei, bb->preds)
 +	{
 +	  // Get whatever range we can for this edge
 +	  if (!outgoing_edge_range_p (e_range, e, name))
 +	    ssa_range_in_bb (e_range, name, e->src);
 +	  new_range.union_ (e_range);
 +	  if (new_range.varying_p ())
 +	    break;
 +	}
 +      // If the range on entry has changed, update it.
 +      if (new_range != current_range)
 +	{
 +if (DEBUG_CACHE) { fprintf (dump_file, "  updating range from "); current_range.dump (dump_file); fprintf (dump_file, " to");  new_range.dump (dump_file); fprintf (dump_file, "\n"); }
 +	  m_on_entry.set_bb_range (name, bb, new_range);
 +	  // Mark each successor that has a range to re-check it's range
 +	  FOR_EACH_EDGE (e, ei, bb->succs)
 +	    if (m_on_entry.bb_range_p (name, e->dest))
 +	      add_to_update (e->dest);
 +	}
 +    }
 +if (DEBUG_CACHE) fprintf (dump_file, "DONE visiting blocks \n\n");
 +}
 +
 +// Make sure that the range-on-entry cache for NAME is set for block BB.
 +// Work back thourgh the CFG to DEF_BB ensuring the range is calculated
 +// on the block/edges leading back to that point.
 +
 +void
 +ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
 +{
 +  edge_iterator ei;
 +  edge e;
-   widest_irange block_result;
-   widest_irange undefined;
++  int_range_max block_result;
++  int_range_max undefined;
 +
 +  // At this point we shouldnt be looking at the def, entry or exit block.
 +  gcc_checking_assert (bb != def_bb && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
 +		       bb != EXIT_BLOCK_PTR_FOR_FN (cfun));
 +
 +  // If the block cache is set, then we've already visited this block.
 +  if (m_on_entry.bb_range_p (name, bb))
 +    return;
 +
 +  // Visit each block back to the DEF.  Initialize each one to UNDEFINED.
 +  // m_visited at the end will contain all the blocks that we needed to set
 +  // the range_on_entry cache for.
 +  m_workback.truncate (0);
 +  m_workback.quick_push (bb);
 +  undefined.set_undefined ();
 +  m_on_entry.set_bb_range (name, bb, undefined);
 +  gcc_checking_assert (m_update_list.length () == 0);
 +
 +if (DEBUG_CACHE) { fprintf (dump_file, "\n"); print_generic_expr (dump_file, name, TDF_SLIM); fprintf (dump_file, " : "); }
 +
 +  while (m_workback.length () > 0)
 +    {
 +      basic_block node = m_workback.pop ();
 +if (DEBUG_CACHE)  fprintf (dump_file, "BACK visiting block %d\n", node->index);
 +
 +      FOR_EACH_EDGE (e, ei, node->preds)
 +        {
 +	  basic_block pred = e->src;
- 	  widest_irange r;
++	  int_range_max r;
 +	  // If the pred block is the def block add this BB to update list.
 +	  if (pred == def_bb)
 +	    {
 +	      add_to_update (node);
 +	      continue;
 +	    }
 +
 +	  // If the pred is entry but NOT def, then it is used before
 +	  // defined, it'll get set to []. and no need to update it.
 +	  if (pred == ENTRY_BLOCK_PTR_FOR_FN (cfun))
 +	    continue;
 +
 +	  // Regardless of whther we have visited pred or not, if the pred has
 +	  // a non-null reference, revisit this block.
 +	  if (m_non_null.non_null_deref_p (name, pred))
 +	    add_to_update (node);
 +
 +	  // If the pred block already has a range, or if it can contribute
 +	  // something new. Ie, the edge generates a range of some sort.
 +	  if (m_on_entry.get_bb_range (r, name, pred))
 +	    {
 +	      if (!r.undefined_p () || has_edge_range_p (e, name))
 +		add_to_update (node);
 +	      continue;
 +	    }
 +
 +	  // If the pred hasn't been visited (has no range), add it to
 +	  // the list.
 +	  gcc_checking_assert (!m_on_entry.bb_range_p (name, pred));
 +	  m_on_entry.set_bb_range (name, pred, undefined);
 +	  m_workback.quick_push (pred);
 +	}
 +    }
 +
 +  iterative_cache_update (name);
 +}
diff --cc gcc/gimple-range-edge.cc
index 567fe575dd9,00000000000..4a4878722e8
mode 100644,000000..100644
--- a/gcc/gimple-range-edge.cc
+++ b/gcc/gimple-range-edge.cc
@@@ -1,191 -1,0 +1,191 @@@
 +/* Gimple range edge functionaluity.
 +   Copyright (C) 2020 Free Software Foundation, Inc.
 +   Contributed by Andrew MacLeod <amacleod@redhat.com>
 +   and Aldy Hernandez <aldyh@redhat.com>.
 +
 +This file is part of GCC.
 +
 +GCC is free software; you can redistribute it and/or modify
 +it under the terms of the GNU General Public License as published by
 +the Free Software Foundation; either version 3, or (at your option)
 +any later version.
 +
 +GCC is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with GCC; see the file COPYING3.  If not see
 +<http://www.gnu.org/licenses/>.  */
 +
 +
 +#include "config.h"
 +#include "system.h"
 +#include "coretypes.h"
 +#include "backend.h"
 +#include "tree.h"
 +#include "gimple.h"
 +#include "ssa.h"
 +#include "gimple-pretty-print.h"
 +#include "gimple-iterator.h"
 +#include "tree-cfg.h"
 +#include "gimple-range.h"
 +
 +
 +outgoing_range::outgoing_range ()
 +{
 +  m_edge_table = NULL;
 +}
 +
 +outgoing_range::~outgoing_range ()
 +{
 +  if (m_edge_table)
 +    delete m_edge_table;
 +}
 +
 +bool
 +outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
 +{
 +  gcc_checking_assert (is_a<gswitch *> (s));
 +  gswitch *sw = as_a<gswitch *> (s);
 +
 +  // ADA currently has cases where the index is 64 bits and the case
 +  // arguments are  32 bit, causing a trap when we create a case_range.
 +  // Until this is resolved (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87798)
 +  // punt on these switches.
 +  if (gimple_switch_num_labels (sw) > 1 && 
 +      TYPE_PRECISION (TREE_TYPE (CASE_LOW (gimple_switch_label (sw, 1)))) !=
 +      TYPE_PRECISION (TREE_TYPE (gimple_switch_index (sw))))
 +    return false;
 +
 +   if (!m_edge_table)
 +     m_edge_table = new hash_map<edge, irange *> (n_edges_for_fn (cfun));
 +
 +   irange **val = m_edge_table->get (e);
 +   if (!val)
 +     {
 +       calc_switch_ranges (sw);
 +       val = m_edge_table->get (e);
 +       gcc_checking_assert (val);
 +     }
 +    r = **val;
 +  return true;
 +}
 +
 +void
 +outgoing_range::calc_switch_ranges (gswitch *sw)
 +{
 +  bool existed;
 +  unsigned x, lim;
 +  lim = gimple_switch_num_labels (sw);
 +  tree type = TREE_TYPE (gimple_switch_index (sw));
 +  
 +  edge default_edge = gimple_switch_default_edge (cfun, sw);
 +  irange *&default_slot = m_edge_table->get_or_insert (default_edge, &existed);
 +  // This should be the first call into this switch.
 +  // For the default range case, start with varying and intersect each other 
 +  // case from it. 
 +  gcc_assert (!existed);
-   // Allocatea widest_irange for default case.
++  // Allocatea int_range_max for default case.
 +  default_slot = range_pool.allocate (255);
 +  default_slot->set_varying (type);
 +
 +  for (x = 1; x < lim; x++)
 +    {
 +      edge e = gimple_switch_edge (cfun, sw, x);
 +
 +      // If this edge is the same as the default edge, do nothing else.
 +      if (e == default_edge)
 +        continue;
 +
 +      tree low = CASE_LOW (gimple_switch_label (sw, x));
 +      tree high = CASE_HIGH (gimple_switch_label (sw, x));
 +      if (!high)
 +	high = low;
 +
 +      // intersect the case from the default case.
-       widest_irange def_range (low, high);
++      int_range_max def_range (low, high);
 +      range_cast (def_range, type);
 +      def_range.invert ();
 +      default_slot->intersect (def_range);
 +
 +      // Create/union this case with anything on else on the edge.
-       widest_irange case_range (low, high);
++      int_range_max case_range (low, high);
 +      range_cast (case_range, type);
 +      irange *&slot = m_edge_table->get_or_insert (e, &existed);
 +      if (existed)
 +	case_range.union_ (*slot);
 +      // If there was an existing range, we lose the memory, but it'll get
 +      // reclaimed when the obstack is freed.  This seems less intrusive than
 +      // allocating max ranges for each case.
 +      slot = range_pool.allocate (case_range);
 +    }
 +}
 +
 +
 +// If there is a range control statment at the end of block BB, return it.
 +
 +static inline gimple_stmt_iterator
 +gsi_outgoing_range_stmt (basic_block bb)
 +{
 +  gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
 +  if (!gsi_end_p (gsi))
 +    {
 +      gimple *s = gsi_stmt (gsi);
 +      if (is_a<gcond *> (s) && gimple_range_handler (s))
 +	return gsi;
 +      gswitch *sw = dyn_cast<gswitch *> (s);
 +      if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw))))
 +	return gsi;
 +    }
 +  return gsi_none ();
 +}
 +
 +// If there is a range control statment at the end of block BB, return it.
 +gimple *
 +gimple_outgoing_range_stmt_p (basic_block bb)
 +{
 +  // This will return NULL if there is not a branch statement.
 +  gimple *stmt = gsi_stmt (gsi_outgoing_range_stmt (bb));
 +  return stmt;
 +}
 +
 +// Calculate the range forced on on edge E by control flow, return it
 +// in R.  Return the statment which defines the range, otherwise
 +// return NULL
 +
 +gimple *
 +outgoing_range::edge_range_p (irange &r, edge e)
 +{
 +  // Determine if there is an outgoing edge.
 +  gimple *s = gimple_outgoing_range_stmt_p (e->src);
 +  if (!s)
 +    return NULL;
 +
 +  if (is_a<gcond *> (s))
 +    {
 +      if (e->flags & EDGE_TRUE_VALUE)
 +	r = int_range<2> (boolean_true_node, boolean_true_node);
 +      else if (e->flags & EDGE_FALSE_VALUE)
 +	r = int_range<2> (boolean_false_node, boolean_false_node);
 +      else
 +	gcc_unreachable ();
 +      return s;
 +    }
 +
 +  gcc_checking_assert (is_a<gswitch *> (s));
 +  gswitch *sw = as_a<gswitch *> (s);
 +  tree type = TREE_TYPE (gimple_switch_index (sw));
 +
 +  if (!irange::supports_type_p (type))
 +    return NULL;
 +
 +  if (get_edge_range (r, sw, e))
 +    return s;
 +
 +  return NULL;
 +}
 +
 +
 +
diff --cc gcc/gimple-range-gori.cc
index 914e033ca73,00000000000..3f3dcfc7adc
mode 100644,000000..100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@@ -1,1456 -1,0 +1,1456 @@@
 +/* Gimple range GORI functions.
 +   Copyright (C) 2017-2020 Free Software Foundation, Inc.
 +   Contributed by Andrew MacLeod <amacleod@redhat.com>
 +   and Aldy Hernandez <aldyh@redhat.com>.
 +
 +This file is part of GCC.
 +
 +GCC is free software; you can redistribute it and/or modify
 +it under the terms of the GNU General Public License as published by
 +the Free Software Foundation; either version 3, or (at your option)
 +any later version.
 +
 +GCC is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with GCC; see the file COPYING3.  If not see
 +<http://www.gnu.org/licenses/>.  */
 +
 +#define DEBUG_CACHE (1 && getenv("DEBUG_CACHE"))
 +
 +#include "config.h"
 +#include "system.h"
 +#include "coretypes.h"
 +#include "backend.h"
 +#include "tree.h"
 +#include "gimple.h"
 +#include "ssa.h"
 +#include "gimple-pretty-print.h"
 +#include "gimple-range.h"
 +
 +
 +/* RANGE_DEF_CHAIN is used to determine what SSA names in a block can
 +   have range information calculated for them, and what the
 +   dependencies on each other are.
 +
 +   Information for a basic block is calculated once and stored.  It is
 +   only calculated the first time a query is made, so if no queries
 +   are made, there is little overhead.
 +
 +   The def_chain bitmap is indexed by SSA_NAME_VERSION.  Bits are set
 +   within this bitmap to indicate SSA names that are defined in the
 +   SAME block and used to calculate this SSA name.
 +
 +   One import is maintained per def-chain.  An IMPORT is defined as an
 +   SSA name in the def chain which occurs outside the basic block. A
 +   change in the value of this SSA name can change the value of any
 +   name in the chain.
 +
 +   If there is more than one import, or an ssa_name originates WITHIN
 +   the same basic block, but is defined by a statement that the range
 +   engine does not know how to calculate, then there is no import for
 +   the entire chain.
 +
 +    <bb 2> :
 +      _1 = x_4(D) + -2;
 +      _2 = _1 * 4;
 +      j_7 = foo ();
 +      q_5 = _2 + 3;
 +      if (q_5 <= 13)
 +
 +    _1  : (import : x_4(D))  :x_4(D)
 +    _2  : (import : x_4(D))  :_1  x_4(D)
 +    q_5  : (import : x_4(D))  :_1  _2  x_4(D)
 +
 +    This dump indicates the bits set in the def_chain vector and their
 +    import, as well as demonstrates the def_chain bits for the related
 +    ssa_names.
 +
 +    Checking the chain for _2 indicates that _1 and x_4 are used in
 +    its evaluation, and with x_4 being an import.
 +
 +    For the purpose of defining an import, PHI node defintions are
 +    considered imports as they don't really reside in the block, but
 +    are accumulators of values from incoming edges.
 +
 +    Def chains also only include statements which are valid gimple
 +    so a def chain will only span statements for which the range
 +    engine implements operations for.  */
 +
 +
 +class range_def_chain
 +{
 +public:
 +  range_def_chain ();
 +  ~range_def_chain ();
 +  tree terminal_name (tree name);
 +  bool has_def_chain (tree name);
 +  bitmap get_def_chain (tree name);
 +  bool in_chain_p (tree name, tree def);
 +private:
 +  vec<bitmap> m_def_chain;	// SSA_NAME : def chain components.
 +  vec<tree> m_terminal;	        // SSA_NAME : chain terminal name.
 +  tree build_def_chain (tree name, bitmap result, basic_block bb);
 +};
 +
 +
 +
 +// Construct a range_def_chain
 +
 +range_def_chain::range_def_chain ()
 +{
 +  m_def_chain.create (0);
 +  m_def_chain.safe_grow_cleared (num_ssa_names);
 +  m_terminal.create (0);
 +  m_terminal.safe_grow_cleared (num_ssa_names);
 +}
 +
 +// Destruct a range_def_chain
 +
 +range_def_chain::~range_def_chain ()
 +{
 +  unsigned x;
 +  for (x = 0; x < m_def_chain.length (); ++x)
 +    if (m_def_chain[x])
 +      BITMAP_FREE (m_def_chain[x]);
 +  m_def_chain.release ();
 +  m_terminal.release ();
 +}
 +
 +// Return true if NAME is in the def chain of DEF.  If BB is provided,
 +// only return true if the defining statement of DEF is in BB.
 +
 +bool
 +range_def_chain::in_chain_p (tree name, tree def)
 +{
 +  gcc_checking_assert (gimple_range_ssa_p (def));
 +  gcc_checking_assert (gimple_range_ssa_p (name));
 +
 +  // Get the defintion chain for DEF
 +  bitmap chain = get_def_chain (def);
 +
 +  if (chain == NULL)
 +    return false;
 +  return bitmap_bit_p (chain, SSA_NAME_VERSION (name));
 +}
 +
 +// If NAME has a definition chain, and the chain has a single import
 +// into the block, return the name of that import.
 +
 +tree
 +range_def_chain::terminal_name (tree name)
 +{
 +  // Ensure the def chain has been calculated.
 +  get_def_chain (name);
 +  return m_terminal[SSA_NAME_VERSION (name)];
 +}
 +
 +// Given up to 3 ssa names, return the common name or NULL_TREE.
 +// NULL_TREE's passed in can be ignored, but all specified ssa-names
 +// must be the same name.
 +
 +static inline tree
 +pick_import (tree ssa1, tree ssa2, tree ssa3)
 +{
 +  if (ssa1)
 +    {
 +      if (ssa2 && ssa1 != ssa2)
 +        return NULL_TREE;	// No match.
 +      // Either ssa2 is NULL, or it is the same as ssa1.
 +      if (!ssa3 || ssa1 == ssa3)
 +        return ssa1;	// ssa1 is the import.
 +      return NULL_TREE;
 +    }
 +  if (ssa2)
 +    {
 +      // If there is no ssa3 or ssa3 is the same as ssa2, thats the import.
 +      if (!ssa3 || ssa2 == ssa3)
 +        return ssa2;
 +      // They must both be different, so no import.
 +      return NULL_TREE;
 +    }
 +  return ssa3;
 +}
 +
 +// Build def_chains for NAME if it is in BB.. copy the def chain into
 +// RESULT.  Return the import for name, or NAME if it is an import.
 +
 +tree
 +range_def_chain::build_def_chain (tree name, bitmap result, basic_block bb)
 +{
 +  bitmap b;
 +  gimple *def_stmt = SSA_NAME_DEF_STMT (name);
 +  // Add this operand into the result.
 +  bitmap_set_bit (result, SSA_NAME_VERSION (name));
 +
 +  if (gimple_bb (def_stmt) == bb && !is_a<gphi *>(def_stmt))
 +    {
 +      // Get the def chain for the operand
 +      b = get_def_chain (name);
 +      // If there was one, copy it into result and return the terminal name.
 +      if (b)
 +        {
 +	  bitmap_ior_into (result, b);
 +	  return m_terminal [SSA_NAME_VERSION (name)];
 +	}
 +      // If there is no def chain, this terminal is within the same BB.
 +    }
 +  return name;	// This is an import.
 +}
 +
 +// Return TRUE if NAME has been processed for a def_chain.
 +
 +inline bool
 +range_def_chain::has_def_chain (tree name)
 +{
 +  unsigned v = SSA_NAME_VERSION (name);
 +  if (v >= m_def_chain.length ())
 +    {
 +      m_def_chain.safe_grow_cleared (num_ssa_names + 1);
 +      m_terminal.safe_grow_cleared (num_ssa_names + 1);
 +    }
 +  return (m_def_chain[v] != NULL);
 +}
 +
 +// Calculate the def chain for NAME and all of its dependent
 +// operands. Only using names in the same BB.  Return the bitmap of
 +// all names in the m_def_chain.  This only works for supported range
 +// statements.
 +
 +bitmap
 +range_def_chain::get_def_chain (tree name)
 +{
 +  tree ssa1, ssa2, ssa3;
 +  unsigned v = SSA_NAME_VERSION (name);
 +
 +  // If it has already been processed, just return the cached value.
 +  if (has_def_chain (name))
 +    return m_def_chain[v];
 +
 +  // No definition chain for default defs.
 +  if (SSA_NAME_IS_DEFAULT_DEF (name))
 +    return NULL;
 +
 +  gimple *stmt = SSA_NAME_DEF_STMT (name);
 +  if (gimple_range_handler (stmt))
 +    {
 +      ssa1 = gimple_range_ssa_p (gimple_range_operand1 (stmt));
 +      ssa2 = gimple_range_ssa_p (gimple_range_operand2 (stmt));
 +      ssa3 = NULL_TREE;
 +    }
 +  else if (is_a<gassign *> (stmt)
 +	   && gimple_assign_rhs_code (stmt) == COND_EXPR)
 +    {
 +      gassign *st = as_a<gassign *> (stmt);
 +      ssa1 = gimple_range_ssa_p (gimple_assign_rhs1 (st));
 +      ssa2 = gimple_range_ssa_p (gimple_assign_rhs2 (st));
 +      ssa3 = gimple_range_ssa_p (gimple_assign_rhs3 (st));
 +    }
 +  else
 +    return NULL;
 +
 +  basic_block bb = gimple_bb (stmt);
 +
 +  // Allocate a new bitmap and initialize it.
 +  m_def_chain[v] = BITMAP_ALLOC (NULL);
 +
 +  // build_def_chain returns the terminal name. If we have more than
 +  // one unique terminal name, then this statement will have no
 +  // terminal.
 +  bool has_term = true;
 +  m_terminal[v] = NULL_TREE;
 +  if (ssa1)
 +    {
 +      ssa1 = build_def_chain (ssa1, m_def_chain[v], bb);
 +      // if this chain has no terminal, root cannot either.
 +      if (!ssa1)
 +        has_term = false;
 +    }
 +  if (ssa2)
 +    {
 +      ssa2 = build_def_chain (ssa2, m_def_chain[v], bb);
 +      if (!ssa2)
 +        has_term = false;
 +    }
 +  if (ssa3)
 +    {
 +      ssa3 = build_def_chain (ssa3, m_def_chain[v], bb);
 +      if (!ssa3)
 +        has_term = false;
 +    }
 +
 +  if (has_term)
 +    m_terminal[v] = pick_import (ssa1, ssa2, ssa3);
 +  else
 +    m_terminal[v] = NULL_TREE;
 +
 +  // If we run into pathological cases where the defintion chains are
 +  // huge (I'm thinking fppp for instance.. huge basic block fully
 +  // unrolled) we might be able to limit this by deciding here that if
 +  // there is no import AND 2 or more ssa names, we change the
 +  // def_chain back to be just the ssa-names.  that should prevent a_2
 +  // = b_6 + a_8 from creating a pathological case yet allow us to
 +  // still handle it when b_6 and a_8 are derived from the same base
 +  // name.  thoughts?
 +  return m_def_chain[v];
 +}
 +
 +// -------------------------------------------------------------------
 +
 +/* GORI_MAP is used to accumulate what SSA names in a block can
 +   generate range information, and provides tools for the block ranger
 +   to enable it to efficiently calculate these ranges.
 +
 +   GORI stands for "Generates Outgoing Range Information."
 +
 +   It utilizes the range_def_chain class to contruct def_chains.
 +   Information for a basic block is calculated once and stored.  It is
 +   only calculated the first time a query is made.  If no queries are
 +   made, there is little overhead.
 +
 +   2 bitmaps are maintained for each basic block:
 +
 +   m_outgoing  : a set bit indicates a range can be generated for a name.
 +   m_incoming  : a set bit means a this name come from outside the
 +	         block and is used in the calculation of some outgoing
 +	         range.
 +
 +   Generally speaking, the m_outgoing vector is the union of the
 +   entire def_chain of all SSA names used in the last statement of the
 +   block which generate ranges.  The m_incoming vector is the union of
 +   all the terminal names of those def chains.  They act as a one-stop
 +   summary for the block.  */
 +
 +class gori_map : public range_def_chain
 +{
 +public:
 +  gori_map ();
 +  ~gori_map ();
 +
 +  bool is_export_p (tree name, basic_block bb);
 +  bool def_chain_in_export_p (tree name, basic_block bb);
 +  bool is_import_p (tree name, basic_block bb);
 +
 +  void dump (FILE *f);
 +  void dump (FILE *f, basic_block bb);
 +private:
 +  bitmap_obstack m_bitmaps;
 +  vec<bitmap> m_outgoing;	// BB: Outgoing ranges calculatable on edges
 +  vec<bitmap> m_incoming;	// BB: block imports
 +  void maybe_add_gori (tree name, basic_block bb);
 +  void calculate_gori (basic_block bb);
 +  bitmap imports (basic_block bb);
 +  bitmap exports (basic_block bb);
 +};
 +
 +
 +// Initialize a gori-map structure.
 +
 +gori_map::gori_map ()
 +{
 +  m_outgoing.create (0);
 +  m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
 +  m_incoming.create (0);
 +  m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
 +  bitmap_obstack_initialize (&m_bitmaps);
 +}
 +
 +// Free any memory the GORI map allocated.
 +
 +gori_map::~gori_map ()
 +{
 +  bitmap_obstack_release (&m_bitmaps);
 +  m_incoming.release ();
 +  m_outgoing.release ();
 +}
 +
 +// Return the bitmap vector of all imports to BB. Calculate if necessary.
 +
 +bitmap
 +gori_map::imports (basic_block bb)
 +{
 +  if (!m_incoming[bb->index])
 +    calculate_gori (bb);
 +  return m_incoming[bb->index];
 +}
 +
 +// Return true if NAME is an import to basic block BB
 +
 +bool
 +gori_map::is_import_p (tree name, basic_block bb)
 +{
 +  return bitmap_bit_p (imports (bb), SSA_NAME_VERSION (name));
 +}
 +
 +// Return the bitmap vector of all export from BB. Calculate if necessary.
 +
 +bitmap
 +gori_map::exports (basic_block bb)
 +{
 +  if (!m_outgoing[bb->index])
 +    calculate_gori (bb);
 +  return m_outgoing[bb->index];
 +}
 +
 +// Return true if NAME is can have ranges generated for it from basic
 +// block BB.
 +
 +bool
 +gori_map::is_export_p (tree name, basic_block bb)
 +{
 +  return bitmap_bit_p (exports (bb), SSA_NAME_VERSION (name));
 +}
 +
 +// Return true if any element in the def chain of NAME is in the
 +// export list for BB.
 +
 +bool
 +gori_map::def_chain_in_export_p (tree name, basic_block bb)
 +{
 +  bitmap a = exports (bb);
 +  bitmap b = get_def_chain (name);
 +  if (a && b)
 +    return bitmap_intersect_p (a, b);
 +  return false;
 +}
 +
 +// If NAME is non-NULL and defined in block BB, calculate the def
 +// chain and add it to m_outgoing, and any imports to m_incoming.
 +
 +void
 +gori_map::maybe_add_gori (tree name, basic_block bb)
 +{
 +  if (name)
 +    {
 +      gimple *s = SSA_NAME_DEF_STMT (name);
 +      bitmap r = get_def_chain (name);
 +      // Check if there is a def chain, and it is in this block.
 +      if (r && gimple_bb (s) == bb)
 +        {
 +	  bitmap_copy (m_outgoing[bb->index], r);
 +	  tree im = terminal_name (name);
 +	  if (im)
 +	    bitmap_set_bit (m_incoming[bb->index], SSA_NAME_VERSION (im));
 +	}
 +      else
 +        {
 +	  // If there is no def chain, and name originates outside
 +	  // this block then this name is also an import.
 +	  if (!s || gimple_bb (s) != bb)
 +	    bitmap_set_bit (m_incoming[bb->index], SSA_NAME_VERSION (name));
 +	}
 +      // Def chain doesn't include itself, and even if there isn't a
 +      // def chain, this name should be added to exports.
 +      bitmap_set_bit (m_outgoing[bb->index], SSA_NAME_VERSION (name));
 +    }
 +}
 +
 +// Calculate all the required information for BB.
 +
 +void
 +gori_map::calculate_gori (basic_block bb)
 +{
 +  tree name;
 +  if (bb->index >= (signed int)m_outgoing.length ())
 +    {
 +      m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
 +      m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
 +    }
 +  gcc_assert (m_outgoing[bb->index] == NULL);
 +  m_outgoing[bb->index] = BITMAP_ALLOC (&m_bitmaps);
 +  m_incoming[bb->index] = BITMAP_ALLOC (&m_bitmaps);
 +
 +  // If this block's last statement may generate range informaiton, go
 +  // calculate it.
 +  gimple *stmt = gimple_outgoing_range_stmt_p (bb);
 +  if (!stmt)
 +    return;
 +  if (is_a<gcond *> (stmt))
 +    {
 +      gcond *gc = as_a<gcond *>(stmt);
 +      name = gimple_range_ssa_p (gimple_cond_lhs (gc));
 +      maybe_add_gori (name, gimple_bb (stmt));
 +
 +      name = gimple_range_ssa_p (gimple_cond_rhs (gc));
 +      maybe_add_gori (name, gimple_bb (stmt));
 +    }
 +  else
 +    {
 +      gswitch *gs = as_a<gswitch *>(stmt);
 +      name = gimple_range_ssa_p (gimple_switch_index (gs));
 +      maybe_add_gori (name, gimple_bb (stmt));
 +    }
 +}
 +
 +// Dump the table information for BB to file F.
 +
 +void
 +gori_map::dump(FILE *f, basic_block bb)
 +{
 +  tree t;
 +  bool header = false;
 +  const char *header_string = "bb%-4d ";
 +  const char *header2 = "       ";
 +  bool printed_something = false;;
 +  unsigned x, y;
 +  bitmap_iterator bi;
 +
 +  // BB was not processed.
 +  if (!m_outgoing[bb->index])
 +    return;
 +
 +  // Dump the def chain for each SSA_NAME defined in BB.
 +  for (x = 1; x < num_ssa_names; x++)
 +    {
 +      tree name = ssa_name (x);
 +      if (!name)
 +	continue;
 +      gimple *stmt = SSA_NAME_DEF_STMT (name);
 +      bitmap chain = (has_def_chain (name) ? get_def_chain (name) : NULL);
 +      if (stmt && gimple_bb (stmt) == bb && chain && !bitmap_empty_p (chain))
 +        {
 +	  fprintf (f, header_string, bb->index);
 +	  header_string = header2;
 +	  header = true;
 +	  print_generic_expr (f, name, TDF_SLIM);
 +	  if ((t = terminal_name (name)))
 +	    {
 +	      fprintf (f, "  : (terminal ");
 +	      print_generic_expr (f, t, TDF_SLIM);
 +	      fprintf (f, ")");
 +	    }
 +	  fprintf (f, " : ");
 +	  EXECUTE_IF_SET_IN_BITMAP (chain, 0, y, bi)
 +	    {
 +	      print_generic_expr (f, ssa_name (y), TDF_SLIM);
 +	      fprintf (f, "  ");
 +	    }
 +	  fprintf (f, "\n");
 +	}
 +    }
 +
 +  printed_something |= header;
 +  // Now dump the incoming vector.
 +  header = false;
 +  EXECUTE_IF_SET_IN_BITMAP (m_incoming[bb->index], 0, y, bi)
 +    {
 +      if (!header)
 +        {
 +	  fprintf (f, header_string, bb->index);
 +	  fprintf (f, "imports: ");
 +	  header_string = header2;
 +	  header = true;
 +	}
 +      print_generic_expr (f, ssa_name (y), TDF_SLIM);
 +      fprintf (f, "  ");
 +    }
 +
 +  if (header)
 +    fputc ('\n', f);
 +
 +  // Now dump the export vector.
 +  printed_something |= header;
 +  header = false;
 +  EXECUTE_IF_SET_IN_BITMAP (m_outgoing[bb->index], 0, y, bi)
 +    {
 +      if (!header)
 +        {
 +	  fprintf (f, header_string, bb->index);
 +	  fprintf (f, "exports: ");
 +	  header_string = header2;
 +	  header = true;
 +	}
 +      print_generic_expr (f, ssa_name (y), TDF_SLIM);
 +      fprintf (f, "  ");
 +    }
 +  if (header)
 +    fputc ('\n', f);
 +
 +  printed_something |= header;
 +  if (printed_something)
 +    fprintf (f, "\n");
 +}
 +
 +// Dump the entire GORI map structure to file F.
 +//
 +void
 +gori_map::dump(FILE *f)
 +{
 +  basic_block bb;
 +  FOR_EACH_BB_FN (bb, cfun)
 +    {
 +      dump (f, bb);
 +      if (m_outgoing[bb->index])
 +	fprintf (f, "\n");
 +    }
 +}
 +
 +DEBUG_FUNCTION void
 +debug (gori_map &g)
 +{
 +  g.dump (stderr);
 +}
 +
 +// -------------------------------------------------------------------
 +
 +
 +void
 +gori_compute::expr_range_in_bb (irange &r, tree expr, basic_block bb)
 +{
 +  if (gimple_range_ssa_p (expr))
 +    ssa_range_in_bb (r, expr, bb);
 +  else
 +    get_tree_range (r, expr);
 +}
 +
 +// Calculate the range for NAME if the lhs of statement S has the
 +// range LHS.  If present, NAME_RANGE is any known range for NAME
 +// coming into this stmt.  Return the result in R. Return false if no
 +// range can be calculated.
 +
 +bool
 +gori_compute::compute_name_range_op (irange &r, gimple *stmt,
 +				     const irange &lhs, tree name)
 +{
-   widest_irange op1_range, op2_range;
++  int_range_max op1_range, op2_range;
 +
 +  tree op1 = gimple_range_operand1 (stmt);
 +  tree op2 = gimple_range_operand2 (stmt);
 +
 +  // Operand 1 is the name being looked for, evaluate it.
 +  if (op1 == name)
 +    {
 +      expr_range_in_bb (op1_range, op1, gimple_bb (stmt));
 +      if (!op2)
 +	{
 +	  // The second parameter to a unary operation is the range
 +	  // for the type of operand1, but if it can be reduced
 +	  // further, the results will be better.  Start with what we
 +	  // know of the range of OP1 instead of the full type.
 +	  return gimple_range_calc_op1 (r, stmt, lhs, op1_range);
 +	}
 +      // If we need the second operand, get a value and evaluate.
 +      expr_range_in_bb (op2_range, op2, gimple_bb (stmt));
 +      if (gimple_range_calc_op1 (r, stmt, lhs, op2_range))
 +	r.intersect (op1_range);
 +      else
 +        r = op1_range;
 +      return true;
 +    }
 +
 +  if (op2 == name)
 +    {
 +      expr_range_in_bb (op1_range, op1, gimple_bb (stmt));
 +      expr_range_in_bb (r, op2, gimple_bb (stmt));
 +      if (gimple_range_calc_op2 (op2_range, stmt, lhs, op1_range))
 +        r.intersect (op2_range);
 +      return true;
 +    }
 +  return false;
 +}
 +
 +
 +
 +// Construct a gori_compute object.
 +
 +gori_compute::gori_compute ()
 +{
 +  // Create a boolean_type true and false range.
 +  m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node);
 +  m_bool_one = int_range<2> (boolean_true_node, boolean_true_node);
 +  m_gori_map = new gori_map;
 +}
 +
 +// Destruct a gori_compute_object
 +
 +gori_compute::~gori_compute ()
 +{
 +  delete m_gori_map;
 +}
 +
 +// Given the switch S, return an evaluation in R for NAME when the lhs
 +// evaluates to LHS.  Returning false means the name being looked for
 +// was not resolvable.  If present, NAME_RANGE is any known range for
 +// NAME coming into S.
 +
 +bool
 +gori_compute::compute_operand_range_switch (irange &r, gswitch *s,
 +					    const irange &lhs,
 +					    tree name)
 +{
 +  tree op1 = gimple_switch_index (s);
 +
 +  // If name matches, the range is simply the range from the edge.
 +  // Empty ranges are viral as they are on a path which isn't
 +  // executable.
 +  if (op1 == name || lhs.undefined_p ())
 +    {
 +      r = lhs;
 +      return true;
 +    }
 +
 +  // If op1 is in the defintion chain, pass lhs back.
 +  if (gimple_range_ssa_p (op1) && m_gori_map->in_chain_p (name, op1))
 +    return compute_operand_range (r, SSA_NAME_DEF_STMT (op1), lhs, name);
 +
 +  return false;
 +}
 +
 +// Return TRUE if GS is a logical && or || expression.
 +
 +static inline bool
 +is_gimple_logical_p (const gimple *gs)
 +{
 +  /* Look for boolean and/or condition.  */
 +  if (gimple_code (gs) == GIMPLE_ASSIGN)
 +    switch (gimple_expr_code (gs))
 +      {
 +	case TRUTH_AND_EXPR:
 +	case TRUTH_OR_EXPR:
 +	  return true;
 +
 +	case BIT_AND_EXPR:
 +	case BIT_IOR_EXPR:
 +	  // Bitwise operations on single bits are logical too.
 +	  if (types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (gs)),
 +				  boolean_type_node))
 +	    return true;
 +	  break;
 +
 +	default:
 +	  break;
 +      }
 +  return false;
 +}
 +
 +// Return an evaluation for NAME as it would appear in STMT when the
 +// statement's lhs evaluates to LHS.  If successful, return TRUE and
 +// store the evaluation in R, otherwise return FALSE.
 +//
 +// If present, NAME_RANGE is any known range for NAME coming into STMT.
 +
 +bool
 +gori_compute::compute_operand_range (irange &r, gimple *stmt,
 +				     const irange &lhs, tree name)
 +{
 +  // Empty ranges are viral as they are on an unexecutable path.
 +  if (lhs.undefined_p ())
 +    {
 +      r.set_undefined ();
 +      return true;
 +    }
 +  if (is_a<gswitch *> (stmt))
 +    return compute_operand_range_switch (r, as_a<gswitch *> (stmt), lhs, name);
 +  if (!gimple_range_handler (stmt))
 +    return false;
 +
 +  tree op1 = gimple_range_ssa_p (gimple_range_operand1 (stmt));
 +  tree op2 = gimple_range_ssa_p (gimple_range_operand2 (stmt));
 +
 +  // The base ranger handles NAME on this statement.
 +  if (op1 == name || op2 == name)
 +    return compute_name_range_op (r, stmt, lhs, name);
 +
 +  if (is_gimple_logical_p (stmt))
 +    return compute_logical_operands (r, stmt, lhs, name);
 +
 +  // NAME is not in this stmt, but one of the names in it ought to be
 +  // derived from it.
 +  bool op1_in_chain = op1 && m_gori_map->in_chain_p (name, op1);
 +  bool op2_in_chain = op2 && m_gori_map->in_chain_p (name, op2);
 +  if (op1_in_chain && op2_in_chain)
 +    return compute_operand1_and_operand2_range (r, stmt, lhs, name);
 +  if (op1_in_chain)
 +    return compute_operand1_range (r, stmt, lhs, name);
 +  if (op2_in_chain)
 +    return compute_operand2_range (r, stmt, lhs, name);
 +
 +  // If neither operand is derived, this statement tells us nothing.
 +  return false;
 +}
 +
 +static bool
 +range_is_either_true_or_false (const irange &r)
 +{
 +  if (r.undefined_p ())
 +    return false;
 +
 +  // This is complicated by the fact that Ada has multi-bit booleans,
 +  // so true can be ~[0, 0] (i.e. [1,MAX]).
 +  tree type = r.type ();
 +  gcc_checking_assert (types_compatible_p (type, boolean_type_node));
 +  return (r.singleton_p () || !r.contains_p (build_zero_cst (type)));
 +}
 +
 +struct tf_range
 +{
 +  tf_range () { }
 +  tf_range (const irange &t_range, const irange &f_range)
 +    : true_range (t_range), false_range (f_range) { }
-   widest_irange true_range, false_range;
++  int_range_max true_range, false_range;
 +};
 +
 +// Evaluate a binary logical expression by combining the true and
 +// false ranges for each of the operands based on the result value in
 +// the LHS.
 +
 +bool
 +gori_compute::logical_combine (irange &r, enum tree_code code,
 +			       const irange &lhs,
 +			       const tf_range &op1, const tf_range &op2)
 +{
 +  if (op1.true_range.varying_p ()
 +      && op1.false_range.varying_p ()
 +      && op2.true_range.varying_p ()
 +      && op2.false_range.varying_p ())
 +    return false;
 +
 +  // This is not a simple fold of a logical expression, rather it
 +  // determines ranges which flow through the logical expression.
 +  //
 +  // Assuming x_8 is an unsigned char, and relational statements:
 +  //	      b_1 = x_8 < 20
 +  //	      b_2 = x_8 > 5
 +  // consider the logical expression and branch:
 +  //          c_2 = b_1 && b_2
 +  //          if (c_2)
 +  //
 +  // To determine the range of x_8 on either edge of the branch, one
 +  // must first determine what the range of x_8 is when the boolean
 +  // values of b_1 and b_2 are both true and false.
 +  //    b_1 TRUE      x_8 = [0, 19]
 +  //    b_1 FALSE     x_8 = [20, 255]
 +  //    b_2 TRUE      x_8 = [6, 255]
 +  //    b_2 FALSE     x_8 = [0,5].
 +  //
 +  // These ranges are then combined based on the expected outcome of
 +  // the branch.  The range on the TRUE side of the branch must satisfy
 +  //     b_1 == true && b_2 == true
 +  //
 +  // In terms of x_8, that means both x_8 == [0, 19] and x_8 = [6, 255]
 +  // must be true.  The range of x_8 on the true side must be the
 +  // intersection of both ranges since both must be true.  Thus the
 +  // range of x_8 on the true side is [6, 19].
 +  //
 +  // To determine the ranges on the FALSE side, all 3 combinations of
 +  // failing ranges must be considered, and combined as any of them
 +  // can cause the false result.
 +  //
 +  // If the LHS can be TRUE or FALSE, then evaluate both a TRUE and
 +  // FALSE results and combine them.  If we fell back to VARYING any
 +  // range restrictions that have been discovered up to this point
 +  // would be lost.
 +  if (!range_is_either_true_or_false (lhs))
 +    {
-       widest_irange r1;
++      int_range_max r1;
 +      if (logical_combine (r1, code, m_bool_zero, op1, op2)
 +	  && logical_combine (r, code, m_bool_one, op1, op2))
 +	{
 +	  r.union_ (r1);
 +	  return true;
 +	}
 +      return false;
 +    }
 +
 +  switch (code)
 +    {
 +      //  A logical AND combines ranges from 2 boolean conditions.
 +      //       c_2 = b_1 && b_2
 +      case TRUTH_AND_EXPR:
 +      case BIT_AND_EXPR:
 +        if (!lhs.zero_p ())
 +	  {
 +	    // The TRUE side is the intersection of the the 2 true ranges.
 +	    r = op1.true_range;
 +	    r.intersect (op2.true_range);
 +	  }
 +	else
 +	  {
 +	    // The FALSE side is the union of the other 3 cases.
- 	    widest_irange ff (op1.false_range);
++	    int_range_max ff (op1.false_range);
 +	    ff.intersect (op2.false_range);
- 	    widest_irange tf (op1.true_range);
++	    int_range_max tf (op1.true_range);
 +	    tf.intersect (op2.false_range);
- 	    widest_irange ft (op1.false_range);
++	    int_range_max ft (op1.false_range);
 +	    ft.intersect (op2.true_range);
 +	    r = ff;
 +	    r.union_ (tf);
 +	    r.union_ (ft);
 +	  }
 +        break;
 +      //  A logical OR combines ranges from 2 boolean conditons.
 +      // 	c_2 = b_1 || b_2
 +      case TRUTH_OR_EXPR:
 +      case BIT_IOR_EXPR:
 +        if (lhs.zero_p ())
 +	  {
 +	    // An OR operation will only take the FALSE path if both
 +	    // operands are false, so [20, 255] intersect [0, 5] is the
 +	    // union: [0,5][20,255].
 +	    r = op1.false_range;
 +	    r.intersect (op2.false_range);
 +	  }
 +	else
 +	  {
 +	    // The TRUE side of an OR operation will be the union of
 +	    // the other three combinations.
- 	    widest_irange tt (op1.true_range);
++	    int_range_max tt (op1.true_range);
 +	    tt.intersect (op2.true_range);
- 	    widest_irange tf (op1.true_range);
++	    int_range_max tf (op1.true_range);
 +	    tf.intersect (op2.false_range);
- 	    widest_irange ft (op1.false_range);
++	    int_range_max ft (op1.false_range);
 +	    ft.intersect (op2.true_range);
 +	    r = tt;
 +	    r.union_ (tf);
 +	    r.union_ (ft);
 +	  }
 +	break;
 +      default:
 +        gcc_unreachable ();
 +    }
 +
 +  return true;
 +}
 +
 +bool
 +gori_compute::optimize_logical_operands (tf_range &range,
 +					 gimple *stmt,
 +					 const irange &lhs,
 +					 tree name,
 +					 tree op)
 +{
 +  enum tree_code code = gimple_expr_code (stmt);
 +
 +  // Optimize [0 = x | y], since neither operand can ever be non-zero.
 +  if ((code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) && lhs.zero_p ())
 +    {
 +      if (!compute_operand_range (range.false_range, SSA_NAME_DEF_STMT (op),
 +				  m_bool_zero, name))
 +	expr_range_in_bb (range.false_range, name, gimple_bb (stmt));
 +      range.true_range = range.false_range;
 +      return true;
 +    }
 +  // Optimize [1 = x & y], since neither operand can ever be zero.
 +  if ((code == BIT_AND_EXPR || code == TRUTH_AND_EXPR) && lhs == m_bool_one)
 +    {
 +      if (!compute_operand_range (range.true_range, SSA_NAME_DEF_STMT (op),
 +				  m_bool_one, name))
 +	expr_range_in_bb (range.true_range, name, gimple_bb (stmt));
 +      range.false_range = range.true_range;
 +      return true;
 +    }
 +  return false;
 +}
 +
 +// Given a logical STMT, calculate TRUE_RANGE and FALSE_RANGE for each
 +// potential path of NAME, assuming NAME came through the OP chain if
 +// OP_IN_CHAIN is true.  If present, NAME_RANGE is any known range for
 +// NAME coming into STMT.
 +
 +void
 +gori_compute::compute_logical_operands_in_chain (tf_range &range,
 +						 gimple *stmt,
 +						 const irange &lhs,
 +						 tree name,
 +						 tree op, bool op_in_chain)
 +{
 +  if (!op_in_chain)
 +    {
 +      // If op is not in chain, use its known value.
 +      expr_range_in_bb (range.true_range, name, gimple_bb (stmt));
 +      range.false_range = range.true_range;
 +      return;
 +    }
 +  if (optimize_logical_operands (range, stmt, lhs, name, op))
 +    return;
 +
 +  // Calulate ranges for true and false on both sides, since the false
 +  // path is not always a simple inversion of the true side.
 +  if (!compute_operand_range (range.true_range, SSA_NAME_DEF_STMT (op),
 +			      m_bool_one, name))
 +    expr_range_in_bb (range.true_range, name, gimple_bb (stmt));
 +  if (!compute_operand_range (range.false_range, SSA_NAME_DEF_STMT (op),
 +			      m_bool_zero, name))
 +    expr_range_in_bb (range.false_range, name, gimple_bb (stmt));
 +}
 +
 +// Given a logical STMT, calculate true and false for each potential
 +// path using NAME, and resolve the outcome based on the logical
 +// operator.  If present, NAME_RANGE is any known range for NAME
 +// coming into STMT.
 +
 +bool
 +gori_compute::compute_logical_operands (irange &r, gimple *stmt,
 +					const irange &lhs,
 +					tree name)
 +{
 +  // Reaching this point means NAME is not in this stmt, but one of
 +  // the names in it ought to be derived from it.  */
 +  tree op1 = gimple_range_operand1 (stmt);
 +  tree op2 = gimple_range_operand2 (stmt);
 +  gcc_checking_assert (op1 != name && op2 != name);
 +
 +  bool op1_in_chain = (gimple_range_ssa_p (op1)
 +		       && m_gori_map->in_chain_p (name, op1));
 +  bool op2_in_chain = (gimple_range_ssa_p (op2)
 +		       && m_gori_map->in_chain_p (name, op2));
 +
 +  // If neither operand is derived, then this stmt tells us nothing.
 +  if (!op1_in_chain && !op2_in_chain)
 +    return false;
 +
 +  tf_range op1_range, op2_range;
 +  compute_logical_operands_in_chain (op1_range, stmt, lhs,
 +				     name, op1, op1_in_chain);
 +  compute_logical_operands_in_chain (op2_range, stmt, lhs,
 +				     name, op2, op2_in_chain);
 +  return logical_combine (r, gimple_expr_code (stmt), lhs,
 +			  op1_range, op2_range);
 +}
 +
 +// Calculate a range for NAME from the operand 1 position of STMT
 +// assuming the result of the statement is LHS.  Return the range in
 +// R, or false if no range could be calculated.  If present,
 +// NAME_RANGE is any known range for NAME coming into STMT.
 +
 +bool
 +gori_compute::compute_operand1_range (irange &r, gimple *stmt,
 +				      const irange &lhs, tree name)
 +{
-   widest_irange op1_range, op2_range;
++  int_range_max op1_range, op2_range;
 +  tree op1 = gimple_range_operand1 (stmt);
 +  tree op2 = gimple_range_operand2 (stmt);
 +
 +  expr_range_in_bb (op1_range, op1, gimple_bb (stmt));
 +
 +  // Now calcuated the operand and put that result in r.
 +  if (op2)
 +    {
 +      expr_range_in_bb (op2_range, op2, gimple_bb (stmt));
 +      if (!gimple_range_calc_op1 (r, stmt, lhs, op2_range))
 +	return false;
 +    }
 +  else
 +    {
 +      // We pass op1_range to the unary operation.  Nomally it's a
 +      // hidden range_for_type parameter, but sometimes having the
 +      // actual range can result in better information.
 +      if (!gimple_range_calc_op1 (r, stmt, lhs, op1_range))
 +	return false;
 +    }
 +
 +  // Intersect the calculated result with the known result.
 +  op1_range.intersect (r);
 +
 +  gimple *src_stmt = SSA_NAME_DEF_STMT (op1);
 +  // If defstmt is outside of this BB, then name must be an import.
 +  if (!src_stmt || (gimple_bb (src_stmt) != gimple_bb (stmt)))
 +    {
 +      // IF this isn't the right import statement, then abort calculation
 +      if (!src_stmt || gimple_get_lhs (src_stmt) != name)
 +        return false;
 +      return compute_name_range_op (r, src_stmt, op1_range, name);
 +    }
 +  else
 +  // Then feed this range back as the LHS of the defining statement.
 +    return compute_operand_range (r, src_stmt, op1_range, name);
 +}
 +
 +
 +// Calculate a range for NAME from the operand 2 position of S
 +// assuming the result of the statement is LHS.  Return the range in
 +// R, or false if no range could be calculated.  If present,
 +// NAME_RANGE is any known range for NAME coming into S.
 +
 +bool
 +gori_compute::compute_operand2_range (irange &r, gimple *stmt,
 +				      const irange &lhs, tree name)
 +{
-   widest_irange op1_range, op2_range;
++  int_range_max op1_range, op2_range;
 +  tree op1 = gimple_range_operand1 (stmt);
 +  tree op2 = gimple_range_operand2 (stmt);
 +
 +  expr_range_in_bb (op1_range, op1, gimple_bb (stmt));
 +  expr_range_in_bb (op2_range, op2, gimple_bb (stmt));
 +
 +  // INtersect with range for op2 based on lhs and op1.
 +  if (gimple_range_calc_op2 (r, stmt, lhs, op1_range))
 +    op2_range.intersect (r);
 +
 +  gimple *src_stmt = SSA_NAME_DEF_STMT (op2);
 +  // If defstmt is outside of this BB, then name must be an import.
 +  if (!src_stmt || (gimple_bb (src_stmt) != gimple_bb (stmt)))
 +    {
 +      // IF this isn't the right src statement, then abort calculation
 +      if (!src_stmt || gimple_get_lhs (src_stmt) != name)
 +        return false;
 +      return compute_name_range_op (r, src_stmt, op2_range, name);
 +    }
 +  else
 +  // Then feed this range back as the LHS of the defining statement.
 +    return compute_operand_range (r, src_stmt, op2_range, name);
 +}
 +
 +// Calculate a range for NAME from both operand positions of S
 +// assuming the result of the statement is LHS.  Return the range in
 +// R, or false if no range could be calculated.  If present,
 +// NAME_RANGE is any known range for NAME coming into S.
 +
 +bool
 +gori_compute::compute_operand1_and_operand2_range
 +					(irange &r,
 +					 gimple *stmt,
 +					 const irange &lhs,
 +					 tree name)
 +{
-   widest_irange op_range;
++  int_range_max op_range;
 +
 +  // Calculate a good a range for op2.  Since op1 == op2, this will
 +  // have already included whatever the actual range of name is.
 +  if (!compute_operand2_range (op_range, stmt, lhs, name))
 +    return false;
 +
 +  // Now get the range thru op1...
 +  if (!compute_operand1_range (r, stmt, lhs, name))
 +    return false;
 +
 +  // Whichever range is the most permissive is the one we need to
 +  // use. (?)  OR is that true?  Maybe this should be intersection?
 +  r.union_ (op_range);
 +  return true;
 +}
 +
 +bool
 +gori_compute::has_edge_range_p (edge e, tree name)
 +{
 +  return (m_gori_map->is_export_p (name, e->src)
 +	  || m_gori_map->def_chain_in_export_p (name, e->src));
 +}
 +
 +
 +void
 +gori_compute::dump (FILE *f)
 +{
 +  m_gori_map->dump (f);
 +}
 +
 +
 +// Calculate a range on edge E and return it in R.  Try to evaluate a
 +// range for NAME on this edge.  Return FALSE if this is either not a
 +// control edge or NAME is not defined by this edge.
 +
 +bool
 +gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name)
 +{
-   widest_irange lhs;
++  int_range_max lhs;
 +
 +  gcc_checking_assert (gimple_range_ssa_p (name));
 +  // Determine if there is an outgoing edge.
 +  gimple *stmt = outgoing.edge_range_p (lhs, e);
 +  if (!stmt)
 +    return false;
 +
 +  // If NAME can be calculated on the edge, use that.
 +  if (m_gori_map->is_export_p (name, e->src))
 +    return compute_operand_range (r, stmt, lhs, name);
 +
 +  // Otherwise see if NAME is derived from something that can be
 +  // calculated.  This performs no dynamic lookups whatsover, so it is
 +  // low cost.
 +  return false;
 +}
 +
 +
 +
 +
 +class logical_stmt_cache
 +{
 +public:
 +  logical_stmt_cache ();
 +  ~logical_stmt_cache ();
 +  void set_range (tree carrier, tree name, const tf_range &);
 +  bool get_range (tf_range &r, tree carrier, tree name) const;
 +  bool cacheable_p (gimple *, const irange *lhs_range = NULL) const;
 +  void dump (FILE *, gimple *stmt) const;
 +  tree same_cached_name (tree op1, tree op2) const;
 +private:
 +  tree cached_name (tree carrier) const;
 +  void slot_diagnostics (tree carrier, const tf_range &range) const;
 +  struct cache_entry
 +  {
 +    cache_entry (tree name, const irange &t_range, const irange &f_range);
 +    void dump (FILE *out) const;
 +    tree name;
 +    tf_range range;
 +  };
 +  vec<cache_entry *> m_ssa_cache;
 +};
 +
 +logical_stmt_cache::cache_entry::cache_entry (tree name,
 +					      const irange &t_range,
 +					      const irange &f_range)
 +  : name (name), range (t_range, f_range)
 +{
 +}
 +
 +logical_stmt_cache::logical_stmt_cache ()
 +{
 +  m_ssa_cache.create (num_ssa_names + num_ssa_names / 10);
 +  m_ssa_cache.safe_grow_cleared (num_ssa_names);
 +}
 +
 +logical_stmt_cache::~logical_stmt_cache ()
 +{
 +  for (unsigned i = 0; i < m_ssa_cache.length (); ++i)
 +    if (m_ssa_cache[i])
 +      delete m_ssa_cache[i];
 +  m_ssa_cache.release ();
 +}
 +
 +void
 +logical_stmt_cache::cache_entry::dump (FILE *out) const
 +{
 +  fprintf (out, "name=");
 +  print_generic_expr (out, name, TDF_SLIM);
 +  fprintf (out, " ");
 +  range.true_range.dump (out);
 +  fprintf (out, ", ");
 +  range.false_range.dump (out);
 +  fprintf (out, "\n");
 +}
 +
 +void
 +logical_stmt_cache::set_range (tree carrier, tree name, const tf_range &range)
 +{
 +  unsigned version = SSA_NAME_VERSION (carrier);
 +  if (version >= m_ssa_cache.length ())
 +    m_ssa_cache.safe_grow_cleared (num_ssa_names + num_ssa_names / 10);
 +
 +  cache_entry *slot = m_ssa_cache[version];
 +  slot_diagnostics (carrier, range);
 +  if (slot)
 +    {
 +      // The IL must have changed.  Update the carried SSA name for
 +      // consistency.  Testcase is libgomp.fortran/doacross1.f90.
 +      if (slot->name != name)
 +	slot->name = name;
 +      return;
 +    }
 +  m_ssa_cache[version]
 +    = new cache_entry (name, range.true_range, range.false_range);
 +}
 +
 +void
 +logical_stmt_cache::slot_diagnostics (tree carrier,
 +				      const tf_range &range) const
 +{
 +  gimple *stmt = SSA_NAME_DEF_STMT (carrier);
 +  unsigned version = SSA_NAME_VERSION (carrier);
 +  cache_entry *slot = m_ssa_cache[version];
 +
 +  if (!slot)
 +    {
 +      if (DEBUG_CACHE)
 +	{
 +	  fprintf (dump_file ? dump_file : stderr, "registering range for: ");
 +	  dump (dump_file ? dump_file : stderr, stmt);
 +	}
 +      return;
 +    }
 +  if (DEBUG_CACHE)
 +    fprintf (dump_file ? dump_file : stderr,
 +	     "reusing range for SSA #%d\n", version);
 +  if (CHECKING_P && (slot->range.true_range != range.true_range
 +		     || slot->range.false_range != range.false_range))
 +    {
 +      fprintf (stderr, "FATAL: range altered for cached: ");
 +      dump (stderr, stmt);
 +      fprintf (stderr, "Attempt to change to:\n");
 +      fprintf (stderr, "TRUE=");
 +      range.true_range.dump (stderr);
 +      fprintf (stderr, ", FALSE=");
 +      range.false_range.dump (stderr);
 +      fprintf (stderr, "\n");
 +      gcc_unreachable ();
 +    }
 +}
 +
 +bool
 +logical_stmt_cache::get_range (tf_range &r, tree carrier, tree name) const
 +{
 +  gcc_checking_assert (cacheable_p (SSA_NAME_DEF_STMT (carrier)));
 +  if (cached_name (carrier) == name)
 +    {
 +      unsigned version = SSA_NAME_VERSION (carrier);
 +      if (m_ssa_cache[version])
 +	{
 +	  r = m_ssa_cache[version]->range;
 +	  return true;
 +	}
 +    }
 +  return false;
 +}
 +
 +tree
 +logical_stmt_cache::cached_name (tree carrier) const
 +{
 +  unsigned version = SSA_NAME_VERSION (carrier);
 +
 +  if (version >= m_ssa_cache.length ())
 +    return NULL;
 +
 +  if (m_ssa_cache[version])
 +    return m_ssa_cache[version]->name;
 +  return NULL;
 +}
 +
 +tree
 +logical_stmt_cache::same_cached_name (tree op1, tree op2) const
 +{
 +  tree name = cached_name (op1);
 +  if (name && name == cached_name (op2))
 +    return name;
 +  return NULL;
 +}
 +
 +bool
 +logical_stmt_cache::cacheable_p (gimple *stmt, const irange *lhs_range) const
 +{
 +  if (gimple_code (stmt) == GIMPLE_ASSIGN
 +      && types_compatible_p (TREE_TYPE (gimple_assign_lhs (stmt)),
 +			     boolean_type_node)
 +      && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
 +    {
 +      switch (gimple_expr_code (stmt))
 +	{
 +	case LT_EXPR:
 +	case LE_EXPR:
 +	case GT_EXPR:
 +	case GE_EXPR:
 +	case EQ_EXPR:
 +	case NE_EXPR:
 +	case TRUTH_AND_EXPR:
 +	case BIT_AND_EXPR:
 +	case TRUTH_OR_EXPR:
 +	case BIT_IOR_EXPR:
 +	  return !lhs_range || range_is_either_true_or_false (*lhs_range);
 +	default:
 +	  return false;
 +	}
 +    }
 +  return false;
 +}
 +
 +void
 +logical_stmt_cache::dump (FILE *out, gimple *stmt) const
 +{
 +  tree carrier = gimple_assign_lhs (stmt);
 +  cache_entry *entry = m_ssa_cache[SSA_NAME_VERSION (carrier)];
 +
 +  print_gimple_stmt (out, stmt, 0, TDF_SLIM);
 +  if (entry)
 +    {
 +      fprintf (out, "\tname = ");
 +      print_generic_expr (out, entry->name);
 +      fprintf (out, " carrier(%d)= ", SSA_NAME_VERSION (carrier));
 +      print_generic_expr (out, carrier);
 +      fprintf (out, "\n\tTRUE=");
 +      entry->range.true_range.dump (out);
 +      fprintf (out, ", FALSE=");
 +      entry->range.false_range.dump (out);
 +      fprintf (out, "\n");
 +    }
 +  else
 +    fprintf (out, "[EMPTY]\n");
 +}
 +
 +gori_compute_cache::gori_compute_cache ()
 +{
 +  m_cache = new logical_stmt_cache;
 +}
 +
 +gori_compute_cache::~gori_compute_cache ()
 +{
 +  delete m_cache;
 +}
 +
 +bool
 +gori_compute_cache::compute_operand_range (irange &r, gimple *stmt,
 +					   const irange &lhs,
 +					   tree name)
 +{
 +  bool cacheable = m_cache->cacheable_p (stmt, &lhs);
 +  if (cacheable)
 +    {
 +      tree carrier = gimple_assign_lhs (stmt);
 +      tf_range range;
 +      if (m_cache->get_range (range, carrier, name))
 +	{
 +	  if (lhs.zero_p ())
 +	    r = range.false_range;
 +	  else
 +	    r = range.true_range;
 +	  return true;
 +	}
 +    }
 +  if (super::compute_operand_range (r, stmt, lhs, name))
 +    {
 +      if (cacheable)
 +	cache_comparison (stmt);
 +      return true;
 +    }
 +  return false;
 +}
 +
 +void
 +gori_compute_cache::cache_comparison (gimple *stmt)
 +{
 +  gcc_checking_assert (m_cache->cacheable_p (stmt));
 +
 +  enum tree_code code = gimple_expr_code (stmt);
 +  tree op1 = gimple_range_operand1 (stmt);
 +  tree op2 = gimple_range_operand2 (stmt);
 +
 +  if (TREE_CODE (op2) == INTEGER_CST)
 +    cache_comparison_with_int (stmt, code, op1, op2);
 +  else if (m_cache->same_cached_name (op1, op2))
 +    cache_comparison_with_ssa (stmt, code, op1, op2);
 +}
 +
 +void
 +gori_compute_cache::cache_comparison_with_int (gimple *stmt,
 +					       enum tree_code code,
 +					       tree op1, tree op2)
 +{
-   widest_irange r_true_side, r_false_side;
++  int_range_max r_true_side, r_false_side;
 +  tree lhs = gimple_assign_lhs (stmt);
 +  range_operator *handler = range_op_handler (code, TREE_TYPE (lhs));
-   widest_irange op2_range;
++  int_range_max op2_range;
 +  expr_range_in_bb (op2_range, op2, gimple_bb (stmt));
 +  tree type = TREE_TYPE (op1);
 +  handler->op1_range (r_true_side, type, m_bool_one, op2_range);
 +  handler->op1_range (r_false_side, type, m_bool_zero, op2_range);
 +  m_cache->set_range (lhs, op1, tf_range (r_true_side, r_false_side));
 +}
 +
 +void
 +gori_compute_cache::cache_comparison_with_ssa (gimple *stmt,
 +					       enum tree_code code,
 +					       tree op1, tree op2)
 +{
 +  tree cached_name = m_cache->same_cached_name (op1, op2);
-   widest_irange r_true_side, r_false_side;
++  int_range_max r_true_side, r_false_side;
 +  tf_range op1_range, op2_range;
 +  gcc_assert (m_cache->get_range (op1_range, op1, cached_name));
 +  gcc_assert (m_cache->get_range (op2_range, op2, cached_name));
 +  gcc_checking_assert (logical_combine (r_true_side, code, m_bool_one,
 +					op1_range, op2_range));
 +  gcc_checking_assert (logical_combine (r_false_side, code, m_bool_zero,
 +					op1_range, op2_range));
 +  tree carrier = gimple_assign_lhs (stmt);
 +  m_cache->set_range (carrier, cached_name,
 +		      tf_range (r_true_side, r_false_side));
 +}
diff --cc gcc/gimple-range.cc
index bd1e4a438c2,00000000000..032b039ffa5
mode 100644,000000..100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@@ -1,1169 -1,0 +1,1169 @@@
 +/* Code for GIMPLE range related routines.
 +   Copyright (C) 2019-2020 Free Software Foundation, Inc.
 +   Contributed by Andrew MacLeod <amacleod@redhat.com>
 +   and Aldy Hernandez <aldyh@redhat.com>.
 +
 +This file is part of GCC.
 +
 +GCC is free software; you can redistribute it and/or modify
 +it under the terms of the GNU General Public License as published by
 +the Free Software Foundation; either version 3, or (at your option)
 +any later version.
 +
 +GCC is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with GCC; see the file COPYING3.  If not see
 +<http://www.gnu.org/licenses/>.  */
 +
 +#include "config.h"
 +#include "system.h"
 +#include "coretypes.h"
 +#include "backend.h"
 +#include "insn-codes.h"
 +#include "rtl.h"
 +#include "tree.h"
 +#include "gimple.h"
 +#include "ssa.h"
 +#include "gimple-pretty-print.h"
 +#include "gimple-iterator.h"
 +#include "optabs-tree.h"
 +#include "gimple-fold.h"
 +#include "tree-cfg.h"
 +#include "fold-const.h"
 +#include "tree-cfg.h"
 +#include "wide-int.h"
 +#include "fold-const.h"
 +#include "case-cfn-macros.h"
 +#include "omp-general.h"
 +#include "cfgloop.h"
 +#include "tree-ssa-loop.h"
 +#include "tree-scalar-evolution.h"
 +#include "dbgcnt.h"
 +#include "alloc-pool.h"
 +#include "vr-values.h"
 +#include "gimple-range.h"
 +
 +
 +// Adjust the range for a pointer difference where the operands came
 +// from a memchr.
 +//
 +// This notices the following sequence:
 +//
 +//	def = __builtin_memchr (arg, 0, sz)
 +//	n = def - arg
 +//
 +// The range for N can be narrowed to [0, PTRDIFF_MAX - 1].
 +
 +static void
 +adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt)
 +{
 +  tree op0 = gimple_assign_rhs1 (diff_stmt);
 +  tree op1 = gimple_assign_rhs2 (diff_stmt);
 +  tree op0_ptype = TREE_TYPE (TREE_TYPE (op0));
 +  tree op1_ptype = TREE_TYPE (TREE_TYPE (op1));
 +  gimple *call;
 +
 +  if (TREE_CODE (op0) == SSA_NAME
 +      && TREE_CODE (op1) == SSA_NAME
 +      && (call = SSA_NAME_DEF_STMT (op0))
 +      && is_gimple_call (call)
 +      && gimple_call_builtin_p (call, BUILT_IN_MEMCHR)
 +      && TYPE_MODE (op0_ptype) == TYPE_MODE (char_type_node)
 +      && TYPE_PRECISION (op0_ptype) == TYPE_PRECISION (char_type_node)
 +      && TYPE_MODE (op1_ptype) == TYPE_MODE (char_type_node)
 +      && TYPE_PRECISION (op1_ptype) == TYPE_PRECISION (char_type_node)
 +      && gimple_call_builtin_p (call, BUILT_IN_MEMCHR)
 +      && vrp_operand_equal_p (op1, gimple_call_arg (call, 0))
 +      && integer_zerop (gimple_call_arg (call, 1)))
 +    {
 +      tree max = vrp_val_max (ptrdiff_type_node);
 +      wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
 +      tree expr_type = gimple_expr_type (diff_stmt);
 +      tree range_min = build_zero_cst (expr_type);
 +      tree range_max = wide_int_to_tree (expr_type, wmax - 1);
 +      int_range<2> r (range_min, range_max);
 +      res.intersect (r);
 +    }
 +}
 +
 +// This function looks for situations when walking the use/def chains
 +// may provide additonal contextual range information not exposed on
 +// this statement.  Like knowing the IMAGPART return value from a
 +// builtin function is a boolean result.
 +
 +// We should rework how we're called, as we have an op_unknown entry
 +// for IMAGPART_EXPR and POINTER_DIFF_EXPR in range-ops just so this
 +// function gets called.
 +
 +static void
 +gimple_range_adjustment (irange &res, const gimple *stmt)
 +{
 +  switch (gimple_expr_code (stmt))
 +    {
 +    case POINTER_DIFF_EXPR:
 +      adjust_pointer_diff_expr (res, stmt);
 +      return;
 +
 +    case IMAGPART_EXPR:
 +      {
 +	tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
 +	if (TREE_CODE (name) == SSA_NAME)
 +	  {
 +	    gimple *def_stmt = SSA_NAME_DEF_STMT (name);
 +	    if (def_stmt && is_gimple_call (def_stmt)
 +		&& gimple_call_internal_p (def_stmt))
 +	      {
 +		switch (gimple_call_internal_fn (def_stmt))
 +		  {
 +		  case IFN_ADD_OVERFLOW:
 +		  case IFN_SUB_OVERFLOW:
 +		  case IFN_MUL_OVERFLOW:
 +		  case IFN_ATOMIC_COMPARE_EXCHANGE:
 +		    {
 +		      int_range<2> r;
 +		      r.set_varying (boolean_type_node);
 +		      tree type = TREE_TYPE (gimple_assign_lhs (stmt));
 +		      range_cast (r, type);
 +		      res.intersect (r);
 +		    }
 +		  default:
 +		    break;
 +		  }
 +	      }
 +	  }
 +	break;
 +      }
 +
 +    default:
 +      break;
 +    }
 +}
 +
 +
 +// Return a range in R for the tree EXPR.  Return true if a range is
 +// representable.
 +
 +bool
 +get_tree_range (irange &r, tree expr)
 +{
 +  tree type;
 +  if (TYPE_P (expr))
 +    type = expr;
 +  else
 +    type = TREE_TYPE (expr);
 +
 +  // Return false if the type isn't suported.
 +  if (!irange::supports_type_p (type))
 +    return false;
 +
 +  switch (TREE_CODE (expr))
 +    {
 +      case INTEGER_CST:
 +	r.set (expr, expr);
 +	return true;
 +
 +      case SSA_NAME:
 +	r = gimple_range_global (expr);
 +	return true;
 +
 +      case ADDR_EXPR:
 +        {
 +	  // Handle &var which can show up in phi arguments.
 +	  bool ov;
 +	  if (tree_single_nonzero_warnv_p (expr, &ov))
 +	    {
 +	      r = range_nonzero (type);
 +	      return true;
 +	    }
 +	  break;
 +	}
 +
 +      default:
 +        break;
 +    }
 +  r.set_varying (type);
 +  return true;
 +}
 +
 +// Fold this unary statement using R1 as operand1's range, returning
 +// the result in RES.  Return false if the operation fails.
 +
 +bool
 +gimple_range_fold (irange &res, const gimple *stmt, const irange &r1)
 +{
 +  gcc_checking_assert (gimple_range_handler (stmt));
 +
 +  tree type = gimple_expr_type (stmt);
 +  // Unary SSA operations require the LHS type as the second range.
 +  int_range<2> r2 (type);
 +
 +  return gimple_range_fold (res, stmt, r1, r2);
 +}
 +
 +
 +// Fold this binary statement using R1 and R2 as the operands ranges,
 +// returning the result in RES.  Return false if the operation fails.
 +
 +bool
 +gimple_range_fold (irange &res, const gimple *stmt,
 +		   const irange &r1, const irange &r2)
 +{
 +  gcc_checking_assert (gimple_range_handler (stmt));
 +
 +  gimple_range_handler (stmt)->fold_range (res, gimple_expr_type (stmt),
 +					   r1, r2);
 +
 +  // If there are any gimple lookups, do those now.
 +  gimple_range_adjustment (res, stmt);
 +  return true;
 +}
 +
 +// Return the base of the RHS of an assignment.
 +
 +tree
 +gimple_range_base_of_assignment (const gimple *stmt)
 +{
 +  gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
 +  tree op1 = gimple_assign_rhs1 (stmt);
 +  if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
 +    return get_base_address (TREE_OPERAND (op1, 0));
 +  return op1;
 +}
 +
 +// Return the first operand of this statement if it is a valid operand
 +// supported by ranges, otherwise return NULL_TREE.  Special case is
 +// &(SSA_NAME expr), return the SSA_NAME instead of the ADDR expr.
 +
 +tree
 +gimple_range_operand1 (const gimple *stmt)
 +{
 +  gcc_checking_assert (gimple_range_handler (stmt));
 +
 +  switch (gimple_code (stmt))
 +    {
 +      case GIMPLE_COND:
 +	return gimple_cond_lhs (stmt);
 +      case GIMPLE_ASSIGN:
 +	{
 +	  tree base = gimple_range_base_of_assignment (stmt);
 +	  if (base && TREE_CODE (base) == MEM_REF)
 +	    {
 +	      // If the base address is an SSA_NAME, we return it
 +	      // here.  This allows processing of the range of that
 +	      // name, while the rest of the expression is simply
 +	      // ignored.  The code in range_ops will see the
 +	      // ADDR_EXPR and do the right thing.
 +	      tree ssa = TREE_OPERAND (base, 0);
 +	      if (TREE_CODE (ssa) == SSA_NAME)
 +		return ssa;
 +	    }
 +	  return base;
 +	}
 +      default:
 +	break;
 +    }
 +  return NULL;
 +}
 +
 +
 +// Return the second operand of statement STMT, otherwise return NULL_TREE.
 +
 +tree
 +gimple_range_operand2 (const gimple *stmt)
 +{
 +  gcc_checking_assert (gimple_range_handler (stmt));
 +
 +  switch (gimple_code (stmt))
 +    {
 +    case GIMPLE_COND:
 +      return gimple_cond_rhs (stmt);
 +    case GIMPLE_ASSIGN:
 +      if (gimple_num_ops (stmt) >= 3)
 +	return gimple_assign_rhs2 (stmt);
 +    default:
 +      break;
 +    }
 +  return NULL_TREE;
 +}
 +
 +
 +
 +// Calculate what we can determine of the range of this unary
 +// statement's operand if the lhs of the expression has the range
 +// LHS_RANGE.  Return false if nothing can be determined.
 +
 +bool
 +gimple_range_calc_op1 (irange &r, const gimple *stmt, const irange &lhs_range)
 +{
 +  gcc_checking_assert (gimple_num_ops (stmt) < 3);
 +  // An empty range is viral, so return an empty range.
 +
 +  tree type = TREE_TYPE (gimple_range_operand1 (stmt));
 +  if (lhs_range.undefined_p ())
 +    {
 +      r.set_undefined ();
 +      return true;
 +    }
 +  // Unary operations require the type of the first operand in the
 +  // second range position.
 +  int_range<2> type_range (type);
 +  return gimple_range_handler (stmt)->op1_range (r, type, lhs_range,
 +						 type_range);
 +}
 +
 +
 +// Calculate what we can determine of the range of this statement's
 +// first operand if the lhs of the expression has the range LHS_RANGE
 +// and the second operand has the range OP2_RANGE.  Return false if
 +// nothing can be determined.
 +
 +bool
 +gimple_range_calc_op1 (irange &r, const gimple *stmt,
 +		       const irange &lhs_range, const irange &op2_range)
 +{
 +  // Unary operation are allowed to pass a range in for second operand
 +  // as there are often additional restrictions beyond the type which
 +  // can be imposed.  See operator_cast::op1_range.()
 +  tree type = TREE_TYPE (gimple_range_operand1 (stmt));
 +  // An empty range is viral, so return an empty range.
 +  if (op2_range.undefined_p () || lhs_range.undefined_p ())
 +    {
 +      r.set_undefined ();
 +      return true;
 +    }
 +  return gimple_range_handler (stmt)->op1_range (r, type, lhs_range,
 +						 op2_range);
 +}
 +
 +
 +// Calculate what we can determine of the range of this statement's
 +// second operand if the lhs of the expression has the range LHS_RANGE
 +// and the first operand has the range OP1_RANGE.  Return false if
 +// nothing can be determined.
 +
 +bool
 +gimple_range_calc_op2 (irange &r, const gimple *stmt,
 +		       const irange &lhs_range, const irange &op1_range)
 +{
 +  tree type = TREE_TYPE (gimple_range_operand2 (stmt));
 +  // An empty range is viral, so return an empty range.
 +  if (op1_range.undefined_p () || lhs_range.undefined_p ())
 +    {
 +      r.set_undefined ();
 +      return true;
 +    }
 +  return gimple_range_handler (stmt)->op2_range (r, type, lhs_range,
 +						 op1_range);
 +}
 +
 +
 +// Calculate a range for statement S and return it in R. If NAME is provided it
 +// represents the SSA_NAME on the LHS of the statement. It is only required
 +// if there is more than one lhs/output.  If a range cannot
 +// be calculated, return false.
 +
 +bool
 +gimple_ranger::calc_stmt (irange &r, gimple *s, tree name)
 +{
 +  bool res = false;
 +  // If name is specified, make sure it is a LHS of S.
 +  gcc_checking_assert (name ? SSA_NAME_DEF_STMT (name) == s : true);
 +
 +  if (gimple_range_handler (s))
 +    res = range_of_range_op (r, s);
 +  else if (is_a<gphi *>(s))
 +    res = range_of_phi (r, as_a<gphi *> (s));
 +  else if (is_a<gcall *>(s))
 +    res = range_of_call (r, as_a<gcall *> (s));
 +  else if (is_a<gassign *> (s) && gimple_assign_rhs_code (s) == COND_EXPR)
 +    res = range_of_cond_expr (r, as_a<gassign *> (s));
 +  else
 +    {
 +      // If no name is specified, try the expression kind.
 +      if (!name)
 +	{
 +	  tree t = gimple_expr_type (s);
 +	  if (!irange::supports_type_p (t))
 +	    return false;
 +	  r.set_varying (t);
 +	  return true;
 +	}
 +      // We don't understand the stmt, so return the global range.
 +      r = gimple_range_global (name);
 +      return true;
 +    }
 +  if (res)
 +    {
 +      if (r.undefined_p ())
 +	return true;
 +      if (name && TREE_TYPE (name) != r.type ())
 +	range_cast (r, TREE_TYPE (name));
 +      return true;
 +    }
 +  return false;
 +}
 +
 +// Calculate a range for range_op statement S and return it in R.  If any
 +// If a range cannot be calculated, return false.
 +
 +bool
 +gimple_ranger::range_of_range_op (irange &r, gimple *s)
 +{
-   widest_irange range1, range2;
++  int_range_max range1, range2;
 +  tree type = gimple_expr_type (s);
 +  gcc_checking_assert (irange::supports_type_p (type));
 +
 +  tree op1 = gimple_range_operand1 (s);
 +  tree op2 = gimple_range_operand2 (s);
 +
 +  if (range_of_non_trivial_assignment (r, s))
 +    return true;
 +
 +  if (range_of_expr (range1, op1, s))
 +    {
 +      if (!op2)
 +	return gimple_range_fold (r, s, range1);
 +
 +      if (range_of_expr (range2, op2, s))
 +	return gimple_range_fold (r, s, range1, range2);
 +    }
 +  r.set_varying (type);
 +  return true;
 +}
 +
 +
 +// Calculate the range of a non-trivial assignment.  That is, is one
 +// inolving arithmetic on an SSA name (for example, an ADDR_EXPR).
 +// Return the range in R.
 +//
 +// If a range cannot be calculated, return false.
 +
 +bool
 +gimple_ranger::range_of_non_trivial_assignment (irange &r, gimple *stmt)
 +{
 +  if (gimple_code (stmt) != GIMPLE_ASSIGN)
 +    return false;
 +
 +  tree base = gimple_range_base_of_assignment (stmt);
 +  if (base && TREE_CODE (base) == MEM_REF
 +      && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
 +    {
-       widest_irange range1;
++      int_range_max range1;
 +      tree ssa = TREE_OPERAND (base, 0);
 +      if (range_of_expr (range1, ssa, stmt))
 +	{
 +	  tree type = TREE_TYPE (ssa);
 +	  range_operator *op = range_op_handler (POINTER_PLUS_EXPR, type);
 +	  int_range<2> offset (TREE_OPERAND (base, 1), TREE_OPERAND (base, 1));
 +	  op->fold_range (r, type, range1, offset);
 +	  return true;
 +	}
 +    }
 +  return false;
 +}
 +
 +
 +// Calculate a range for phi statement S and return it in R.
 +// If a range cannot be calculated, return false.
 +
 +bool
 +gimple_ranger::range_of_phi (irange &r, gphi *phi)
 +{
 +  tree phi_def = gimple_phi_result (phi);
 +  tree type = TREE_TYPE (phi_def);
-   widest_irange phi_range;
++  int_range_max phi_range;
 +  unsigned x;
 +
 +  if (!irange::supports_type_p (type))
 +    return false;
 +
 +  if (loop_aware_p ())
 +    {
 +      // If there is no global range for a PHI, start the party with
 +      // whatever information SCEV may have.
 +      tree phi_result = PHI_RESULT (phi);
 +      if (!POINTER_TYPE_P (TREE_TYPE (phi_result))
 +	  && !m_cache.m_globals.get_global_range (r, phi_result)
 +	  && range_with_loop_info (r, phi_result))
 +	{
 +	  value_range loop_range;
 +	  get_range_info (phi_result, loop_range);
 +	  r.intersect (loop_range);
 +	  if (!r.varying_p ())
 +	    set_range_info (phi_result, r);
 +	}
 +    }
 +
 +  // And start with an empty range, unioning in each argument's range.
 +  r.set_undefined ();
 +  for (x = 0; x < gimple_phi_num_args (phi); x++)
 +    {
-       widest_irange arg_range;
++      int_range_max arg_range;
 +      tree arg = gimple_phi_arg_def (phi, x);
 +      edge e = gimple_phi_arg_edge (phi, x);
 +
 +      range_on_edge (arg_range, e, arg);
 +      r.union_ (arg_range);
 +      // Once the value reaches varying, stop looking.
 +      if (r.varying_p ())
 +	break;
 +    }
 +
 +  return true;
 +}
 +
 +
 +// Calculate a range for call statement S and return it in R.
 +// If a range cannot be calculated, return false.
 +
 +bool
 +gimple_ranger::range_of_call (irange &r, gcall *call)
 +{
 +  tree type = gimple_call_return_type (call);
 +  tree lhs = gimple_call_lhs (call);
 +  bool strict_overflow_p;
 +
 +  if (!irange::supports_type_p (type))
 +    return false;
 +
 +  if (range_of_builtin_call (r, call))
 +    ;
 +  else if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p))
 +    r.set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
 +  else if (gimple_call_nonnull_result_p (call)
 +	   || gimple_call_nonnull_arg (call))
 +    r = range_nonzero (type);
 +  else
 +    r.set_varying (type);
 +
 +  // If there is a lHS, intersect that with what is known.
 +  if (lhs)
 +    {
 +      value_range def;
 +      def = gimple_range_global (lhs);
 +      r.intersect (def);
 +    }
 +  return true;
 +}
 +
 +
 +void
 +gimple_ranger::range_of_builtin_ubsan_call (irange &r, gcall *call,
 +					    tree_code code)
 +{
 +  gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR
 +		       || code == MULT_EXPR);
 +  tree type = gimple_call_return_type (call);
 +  range_operator *op = range_op_handler (code, type);
 +  gcc_checking_assert (op);
-   widest_irange ir0, ir1;
++  int_range_max ir0, ir1;
 +  tree arg0 = gimple_call_arg (call, 0);
 +  tree arg1 = gimple_call_arg (call, 1);
 +  gcc_assert (range_of_expr (ir0, arg0, call));
 +  gcc_assert (range_of_expr (ir1, arg1, call));
 +
 +  bool saved_flag_wrapv = flag_wrapv;
 +  /* Pretend the arithmetics is wrapping.  If there is
 +     any overflow, we'll complain, but will actually do
 +     wrapping operation.  */
 +  flag_wrapv = 1;
 +  op->fold_range (r, type, ir0, ir1);
 +  flag_wrapv = saved_flag_wrapv;
 +
 +  /* If for both arguments vrp_valueize returned non-NULL,
 +     this should have been already folded and if not, it
 +     wasn't folded because of overflow.  Avoid removing the
 +     UBSAN_CHECK_* calls in that case.  */
 +  if (r.singleton_p ())
 +    r.set_varying (type);
 +}
 +
 +
 +bool
 +gimple_ranger::range_of_builtin_call (irange &r, gcall *call)
 +{
 +  combined_fn func = gimple_call_combined_fn (call);
 +  if (func == CFN_LAST)
 +    return false;
 +
 +  tree type = gimple_call_return_type (call);
 +  tree arg;
 +  int mini, maxi, zerov, prec;
 +  scalar_int_mode mode;
 +
 +  switch (func)
 +    {
 +    case CFN_BUILT_IN_CONSTANT_P:
 +      if (cfun->after_inlining)
 +	{
 +	  r.set_zero (type);
 +	  // r.equiv_clear ();
 +	  return true;
 +	}
 +      arg = gimple_call_arg (call, 0);
 +      if (range_of_expr (r, arg, call) && r.singleton_p ())
 +	{
 +	  r.set (build_one_cst (type), build_one_cst (type));
 +	  return true;
 +	}
 +      break;
 +
 +    CASE_CFN_FFS:
 +    CASE_CFN_POPCOUNT:
 +      // __builtin_ffs* and __builtin_popcount* return [0, prec].
 +      arg = gimple_call_arg (call, 0);
 +      prec = TYPE_PRECISION (TREE_TYPE (arg));
 +      mini = 0;
 +      maxi = prec;
 +      gcc_assert (range_of_expr (r, arg, call));
 +      // If arg is non-zero, then ffs or popcount are non-zero.
 +      if (!range_includes_zero_p (&r))
 +	mini = 1;
 +      // If some high bits are known to be zero, decrease the maximum.
 +      if (!r.undefined_p ())
 +	{
 +	  wide_int max = r.upper_bound ();
 +	  maxi = wi::floor_log2 (max) + 1;
 +	}
 +      r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
 +      return true;
 +
 +    CASE_CFN_PARITY:
 +      r.set (build_zero_cst (type), build_one_cst (type));
 +      return true;
 +
 +    CASE_CFN_CLZ:
 +      // __builtin_c[lt]z* return [0, prec-1], except when the
 +      // argument is 0, but that is undefined behavior.
 +      //
 +      // On many targets where the CLZ RTL or optab value is defined
 +      // for 0, the value is prec, so include that in the range by
 +      // default.
 +      arg = gimple_call_arg (call, 0);
 +      prec = TYPE_PRECISION (TREE_TYPE (arg));
 +      mini = 0;
 +      maxi = prec;
 +      mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
 +      if (optab_handler (clz_optab, mode) != CODE_FOR_nothing
 +	  && CLZ_DEFINED_VALUE_AT_ZERO (mode, zerov)
 +	  // Only handle the single common value.
 +	  && zerov != prec)
 +	// Magic value to give up, unless we can prove arg is non-zero.
 +	mini = -2;
 +
 +      gcc_assert (range_of_expr (r, arg, call));
 +      // From clz of minimum we can compute result maximum.
 +      if (r.constant_p ())
 +	{
 +	  maxi = prec - 1 - wi::floor_log2 (r.lower_bound ());
 +	  if (maxi != prec)
 +	    mini = 0;
 +	}
 +      else if (!range_includes_zero_p (&r))
 +	{
 +	  maxi = prec - 1;
 +	  mini = 0;
 +	}
 +      if (mini == -2)
 +	break;
 +      // From clz of maximum we can compute result minimum.
 +      if (r.constant_p ())
 +	{
 +	  mini = prec - 1 - wi::floor_log2 (r.upper_bound ());
 +	  if (mini == prec)
 +	    break;
 +	}
 +      if (mini == -2)
 +	break;
 +      r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
 +      return true;
 +
 +    CASE_CFN_CTZ:
 +      // __builtin_ctz* return [0, prec-1], except for when the
 +      // argument is 0, but that is undefined behavior.
 +      //
 +      // If there is a ctz optab for this mode and
 +      // CTZ_DEFINED_VALUE_AT_ZERO, include that in the range,
 +      // otherwise just assume 0 won't be seen.
 +      arg = gimple_call_arg (call, 0);
 +      prec = TYPE_PRECISION (TREE_TYPE (arg));
 +      mini = 0;
 +      maxi = prec - 1;
 +      mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
 +      if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing
 +	  && CTZ_DEFINED_VALUE_AT_ZERO (mode, zerov))
 +	{
 +	  // Handle only the two common values.
 +	  if (zerov == -1)
 +	    mini = -1;
 +	  else if (zerov == prec)
 +	    maxi = prec;
 +	  else
 +	    // Magic value to give up, unless we can prove arg is non-zero.
 +	    mini = -2;
 +	}
 +      gcc_assert (range_of_expr (r, arg, call));
 +      if (!r.undefined_p ())
 +	{
 +	  if (r.lower_bound () != 0)
 +	    {
 +	      mini = 0;
 +	      maxi = prec - 1;
 +	    }
 +	  // If some high bits are known to be zero, we can decrease
 +	  // the maximum.
 +	  wide_int max = r.upper_bound ();
 +	  if (max == 0)
 +	    break;
 +	  maxi = wi::floor_log2 (max);
 +	}
 +      if (mini == -2)
 +	break;
 +      r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
 +      return true;
 +
 +    CASE_CFN_CLRSB:
 +      arg = gimple_call_arg (call, 0);
 +      prec = TYPE_PRECISION (TREE_TYPE (arg));
 +      r.set (build_int_cst (type, 0), build_int_cst (type, prec - 1));
 +      return true;
 +    case CFN_UBSAN_CHECK_ADD:
 +      range_of_builtin_ubsan_call (r, call, PLUS_EXPR);
 +      return true;
 +    case CFN_UBSAN_CHECK_SUB:
 +      range_of_builtin_ubsan_call (r, call, MINUS_EXPR);
 +      return true;
 +    case CFN_UBSAN_CHECK_MUL:
 +      range_of_builtin_ubsan_call (r, call, MULT_EXPR);
 +      return true;
 +
 +    case CFN_GOACC_DIM_SIZE:
 +    case CFN_GOACC_DIM_POS:
 +      // Optimizing these two internal functions helps the loop
 +      // optimizer eliminate outer comparisons.  Size is [1,N]
 +      // and pos is [0,N-1].
 +      {
 +	bool is_pos = func == CFN_GOACC_DIM_POS;
 +	int axis = oacc_get_ifn_dim_arg (call);
 +	int size = oacc_get_fn_dim_size (current_function_decl, axis);
 +	if (!size)
 +	  // If it's dynamic, the backend might know a hardware limitation.
 +	  size = targetm.goacc.dim_limit (axis);
 +
 +	r.set (build_int_cst (type, is_pos ? 0 : 1),
 +	       size
 +	       ? build_int_cst (type, size - is_pos) : vrp_val_max (type));
 +	return true;
 +      }
 +
 +    case CFN_BUILT_IN_STRLEN:
 +      if (tree lhs = gimple_call_lhs (call))
 +	if (ptrdiff_type_node
 +	    && (TYPE_PRECISION (ptrdiff_type_node)
 +		== TYPE_PRECISION (TREE_TYPE (lhs))))
 +	  {
 +	    tree type = TREE_TYPE (lhs);
 +	    tree max = vrp_val_max (ptrdiff_type_node);
 +	    wide_int wmax
 +	      = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
 +	    tree range_min = build_zero_cst (type);
 +	    // To account for the terminating NULL, the maximum length
 +	    // is one less than the maximum array size, which in turn
 +	    // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
 +	    // smaller than the former type).
 +	    // FIXME: Use max_object_size() - 1 here.
 +	    tree range_max = wide_int_to_tree (type, wmax - 2);
 +	    r.set (range_min, range_max);
 +	    return true;
 +	  }
 +      break;
 +    default:
 +      break;
 +    }
 +  return false;
 +}
 +
 +
 +
 +
 +// Calculate a range for COND_EXPR statement S and return it in R.
 +// If a range cannot be calculated, return false.
 +
 +bool
 +gimple_ranger::range_of_cond_expr  (irange &r, gassign *s)
 +{
-   widest_irange cond_range, range1, range2;
++  int_range_max cond_range, range1, range2;
 +  tree cond = gimple_assign_rhs1 (s);
 +  tree op1 = gimple_assign_rhs2 (s);
 +  tree op2 = gimple_assign_rhs3 (s);
 +
 +  gcc_checking_assert (gimple_assign_rhs_code (s) == COND_EXPR);
 +  gcc_checking_assert (useless_type_conversion_p  (TREE_TYPE (op1),
 +						   TREE_TYPE (op2)));
 +  if (!irange::supports_type_p (TREE_TYPE (op1)))
 +    return false;
 +
 +  gcc_assert (range_of_expr (cond_range, cond, s));
 +  gcc_assert (range_of_expr (range1, op1, s));
 +  gcc_assert (range_of_expr (range2, op2, s));
 +
 +  // If the condition is known, choose the appropriate expression.
 +  if (cond_range.singleton_p ())
 +    {
 +      // False, pick second operand
 +      if (cond_range.zero_p ())
 +	r = range2;
 +      else
 +	r = range1;
 +    }
 +  else
 +    {
 +      r = range1;
 +      r.union_ (range2);
 +    }
 +  return true;
 +}
 +
 +
 +
 +bool
 +gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
 +{
 +  if (!gimple_range_ssa_p (expr))
 +    return get_tree_range (r, expr);
 +
 +  // If there is no statement, just get the global value.
 +  if (!stmt)
 +    {
 +      if (!m_cache.m_globals.get_global_range (r, expr))
 +        r = gimple_range_global (expr);
 +      return true;
 +    }
 +
 +  basic_block bb = gimple_bb (stmt);
 +  gimple *def_stmt = SSA_NAME_DEF_STMT (expr);
 +
 +  // If name is defined in this block, try to get an range from S.
 +  if (def_stmt && gimple_bb (def_stmt) == bb)
 +    gcc_assert (range_of_stmt (r, def_stmt, expr));
 +  else
 +    // Otherwise OP comes from outside this block, use range on entry.
 +    range_on_entry (r, bb, expr);
 +
 +  // No range yet, see if there is a dereference in the block.
 +  // We don't care if it's between the def and a use within a block
 +  // because the entire block must be executed anyway.
 +  // FIXME:?? For non-call exceptions we could have a statement throw
 +  // which causes an early block exit.
 +  // in which case we may need to walk from S back to the def/top of block
 +  // to make sure the deref happens between S and there before claiming
 +  // there is a deref.   Punt for now.
 +  if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
 +      m_cache.m_non_null.non_null_deref_p (expr, bb))
 +    r = range_nonzero (TREE_TYPE (expr));
 +
 +  return true;
 +}
 +
 +
 +// Return the range of NAME on entry to block BB in R.
 +
 +void
 +gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name)
 +{
-   widest_irange entry_range;
++  int_range_max entry_range;
 +  gcc_checking_assert (gimple_range_ssa_p (name));
 +
 +  // Start with any known range
 +  gcc_assert (range_of_stmt (r, SSA_NAME_DEF_STMT (name), name));
 +
 +  // Now see if there is any on_entry value which may refine it.
 +  if (m_cache.block_range (entry_range, bb, name))
 +    r.intersect (entry_range);
 +}
 +
 +
 +// Calculate the range for NAME at the end of block BB and return it in R.
 +// Return false if no range can be calculated.
 +
 +void
 +gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name)
 +{
 +  // on-exit from the exit block?
 +  gcc_checking_assert (bb != EXIT_BLOCK_PTR_FOR_FN (cfun));
 +
 +  gimple *s = last_stmt (bb);
 +  // If there is no statement in the block and this isn't the entry
 +  // block, go get the range_on_entry for this block.  For the entry
 +  // block, a NULL stmt will return the global value for NAME.
 +  if (!s && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun))
 +    range_on_entry (r, bb, name);
 +  else
 +    gcc_assert (range_of_expr (r, name, s));
 +  gcc_checking_assert (r.undefined_p ()
 +		       || types_compatible_p (r.type(), TREE_TYPE (name)));
 +}
 +
 +// Calculate a range for NAME on edge E and return it in R.
 +
 +bool
 +gimple_ranger::range_on_edge (irange &r, edge e, tree name)
 +{
-   widest_irange edge_range;
++  int_range_max edge_range;
 +  gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
 +
 +  // PHI arguments can be constants, catch these here.
 +  if (!gimple_range_ssa_p (name))
 +    {
 +      gcc_assert (range_of_expr (r, name));
 +      return true;
 +    }
 +
 +  range_on_exit (r, e->src, name);
 +  gcc_checking_assert  (r.undefined_p ()
 +			|| types_compatible_p (r.type(), TREE_TYPE (name)));
 +
 +  // Check to see if NAME is defined on edge e.
 +  if (m_cache.outgoing_edge_range_p (edge_range, e, name))
 +    r.intersect (edge_range);
 +
 +  if (loop_aware_p ())
 +    {
 +      int_range<2> loop_range;
 +      if (range_with_loop_info (loop_range, name))
 +	r.intersect (loop_range);
 +    }
 +  return true;
 +}
 +
 +// Calculate a range for statement S and return it in R.  If NAME is
 +// provided it represents the SSA_NAME on the LHS of the statement.
 +// It is only required if there is more than one lhs/output.  Check
 +// the global cache for NAME first to see if the evaluation can be
 +// avoided.  If a range cannot be calculated, return false.
 +
 +bool
 +gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
 +{
 +  // If no name, simply call the base routine.
 +  if (!name)
 +    name = gimple_get_lhs (s);
 +
 +  if (!name)
 +    return calc_stmt (r, s, NULL_TREE);
 +
 +  gcc_checking_assert (TREE_CODE (name) == SSA_NAME &&
 +		       irange::supports_type_p (TREE_TYPE (name)));
 +
 +  // If this STMT has already been processed, return that value.
 +  if (m_cache.m_globals.get_global_range (r, name))
 +    return true;
 +  // Avoid infinite recursion by initializing global cache
-   widest_irange tmp = gimple_range_global (name);
++  int_range_max tmp = gimple_range_global (name);
 +  m_cache.m_globals.set_global_range (name, tmp);
 +
 +  gcc_assert (calc_stmt (r, s, name));
 +
 +  if (is_a<gphi *> (s))
 +    r.intersect (tmp);
 +  m_cache.m_globals.set_global_range (name, r);
 +  return true;
 +}
 +
 +
 +// This routine will export whatever global ranges are known to GCC
 +// SSA_RANGE_NAME_INFO fields.
 +
 +void
 +gimple_ranger::export_global_ranges ()
 +{
 +  unsigned x;
-   widest_irange r;
++  int_range_max r;
 +  if (dump_file)
 +    {
 +      fprintf (dump_file, "Exported global range table\n");
 +      fprintf (dump_file, "===========================\n");
 +    }
 +
 +  for ( x = 1; x < num_ssa_names; x++)
 +    {
 +      tree name = ssa_name (x);
 +      if (name && !SSA_NAME_IN_FREE_LIST (name)
 +	  && gimple_range_ssa_p (name)
 +	  && m_cache.m_globals.get_global_range (r, name)
 +	  && !r.varying_p())
 +	{
 +	  // Make sure the new range is a subset of the old range.
- 	  widest_irange old_range;
++	  int_range_max old_range;
 +	  old_range = gimple_range_global (name);
 +	  old_range.intersect (r);
 +	  /* Disable this while we fix tree-ssa/pr61743-2.c.  */
 +	  //gcc_checking_assert (old_range == r);
 +
 +	  // WTF? Can't write non-null pointer ranges?? stupid set_range_info!
 +	  if (!POINTER_TYPE_P (TREE_TYPE (name)) && !r.undefined_p ())
 +	    {
 +	      value_range vr = r;
 +	      set_range_info (name, vr);
 +	      if (dump_file)
 +		{
 +		  print_generic_expr (dump_file, name , TDF_SLIM);
 +		  fprintf (dump_file, " --> ");
 +		  vr.dump (dump_file);
 +		  fprintf (dump_file, "\n");
 +		  fprintf (dump_file, "         irange : ");
 +		  r.dump (dump_file);
 +		  fprintf (dump_file, "\n");
 +		}
 +	    }
 +	}
 +    }
 +}
 +
 +
 +// Print the known table values to file F.
 +
 +void
 +gimple_ranger::dump (FILE *f)
 +{
 +  basic_block bb;
 +
 +  FOR_EACH_BB_FN (bb, cfun)
 +    {
 +      unsigned x;
 +      edge_iterator ei;
 +      edge e;
-       widest_irange range;
++      int_range_max range;
 +      fprintf (f, "\n=========== BB %d ============\n", bb->index);
 +      m_cache.m_on_entry.dump (f, bb);
 +
 +      dump_bb (f, bb, 4, TDF_NONE);
 +
 +      // Now find any globals defined in this block
 +      for (x = 1; x < num_ssa_names; x++)
 +	{
 +	  tree name = ssa_name (x);
 +	  if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) &&
 +	      gimple_bb (SSA_NAME_DEF_STMT (name)) == bb &&
 +	      m_cache.m_globals.get_global_range (range, name))
 +	    {
 +	      if (!range.varying_p ())
 +	       {
 +		 print_generic_expr (f, name, TDF_SLIM);
 +		 fprintf (f, " : ");
 +		 range.dump (f);
 +		 fprintf (f, "\n");
 +	       }
 +
 +	    }
 +	}
 +
 +      // And now outgoing edges, if they define anything.
 +      FOR_EACH_EDGE (e, ei, bb->succs)
 +	{
 +	  for (x = 1; x < num_ssa_names; x++)
 +	    {
 +	      tree name = gimple_range_ssa_p (ssa_name (x));
 +	      if (name && m_cache.outgoing_edge_range_p (range, e, name))
 +		{
 +		  gimple *s = SSA_NAME_DEF_STMT (name);
 +		  // Only print the range if this is the def block, or
 +		  // the on entry cache for either end of the edge is
 +		  // set.
 +		  if ((s && bb == gimple_bb (s)) ||
 +		      m_cache.block_range (range, bb, name, false) ||
 +		      m_cache.block_range (range, e->dest, name, false))
 +		    {
 +		      range_on_edge (range, e, name);
 +		      if (!range.varying_p ())
 +			{
 +			  fprintf (f, "%d->%d ", e->src->index,
 +				   e->dest->index);
 +			  char c = ' ';
 +			  if (e->flags & EDGE_TRUE_VALUE)
 +			    fprintf (f, " (T)%c", c);
 +			  else if (e->flags & EDGE_FALSE_VALUE)
 +			    fprintf (f, " (F)%c", c);
 +			  else
 +			    fprintf (f, "     ");
 +			  print_generic_expr (f, name, TDF_SLIM);
 +			  fprintf(f, " : \t");
 +			  range.dump(f);
 +			  fprintf (f, "\n");
 +			}
 +		    }
 +		}
 +	    }
 +	}
 +    }
 +
 +  m_cache.m_globals.dump (dump_file);
 +  fprintf (f, "\n");
 +
 +  if (dump_flags & TDF_DETAILS)
 +    {
 +      fprintf (f, "\nDUMPING GORI MAP\n");
 +      m_cache.dump (f);
 +      fprintf (f, "\n");
 +    }
 +}
 +
 +void
 +gimple_ranger::range_of_ssa_name_with_loop_info (irange &r, tree name,
 +						 class loop *l, gphi *phi)
 +{
 +  gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
 +  tree min, max, type = TREE_TYPE (name);
 +  if (bounds_of_var_in_loop (&min, &max, this, l, phi, name))
 +    {
 +      // ?? We could do better here.  Since MIN/MAX can only be an
 +      // SSA, SSA +- INTEGER_CST, or INTEGER_CST, we could easily call
 +      // the ranger and solve anything not an integer.
 +      if (TREE_CODE (min) != INTEGER_CST)
 +	min = vrp_val_min (type);
 +      if (TREE_CODE (max) != INTEGER_CST)
 +	max = vrp_val_max (type);
 +      r.set (min, max);
 +    }
 +  else
 +    r.set_varying (type);
 +}
 +
 +// If NAME is either a PHI result or a PHI argument, see if we can
 +// determine range information by querying loop info.  If so, return
 +// TRUE and set the range in R.
 +
 +bool
 +gimple_ranger::range_with_loop_info (irange &r, tree name)
 +{
 +  if (!scev_initialized_p ())
 +    return false;
 +
 +  gimple *def = SSA_NAME_DEF_STMT (name);
 +  class loop *l = loop_containing_stmt (def);
 +  if (!l)
 +    return false;
 +
 +  basic_block header = l->header;
 +  for (gphi_iterator iter = gsi_start_phis (header);
 +       !gsi_end_p (iter); gsi_next (&iter))
 +    {
 +      gphi *phi = iter.phi ();
 +      if (PHI_RESULT (phi) == name)
 +	{
 +	  range_of_ssa_name_with_loop_info (r, name, l, phi);
 +	  return true;
 +	}
 +      for (size_t i = 0; i < gimple_phi_num_args (phi); ++i)
 +	if (PHI_ARG_DEF (phi, i) == name)
 +	  {
 +	    range_of_ssa_name_with_loop_info (r, name, l, phi);
 +	    return true;
 +	  }
 +    }
 +  return false;
 +}
diff --cc gcc/gimple-ssa-evrp.c
index cfebeb3bce8,e8fde63aa34..9367ef976d1
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@@ -106,204 -106,6 +106,204 @@@ protected
    simplify_using_ranges simplifier;
  };
  
 +// -------------------------------------------------------------------------
 +
 +
 +// Until the simplifier is adjusted to use range_of_stmt for folding conditons,
 +// we'll have to do it manually here.
 +
 +static bool
 +fold_cond (gimple_ranger *ranger, gcond *cond)
 +{
 +  if (!irange::supports_type_p (gimple_expr_type (cond)))
 +    return false;
 +
-   widest_irange r;
++  int_range_max r;
 +  if (ranger->range_of_stmt (r, cond) && r.singleton_p ())
 +    {
 +      if (r.zero_p ())
 +	{
 +	  if (dump_file && (dump_flags & TDF_DETAILS))
 +	    fprintf (dump_file, "\nPredicate evaluates to: 0\n");
 +	  gimple_cond_make_false (cond);
 +	}
 +      else
 +	{
 +	  if (dump_file && (dump_flags & TDF_DETAILS))
 +	    fprintf (dump_file, "\nPredicate evaluates to: 1\n");
 +	  gimple_cond_make_true (cond);
 +	}
 +      return true;
 +    }
 +  return false;
 +}
 +
 +
 +class rvrp_folder : public substitute_and_fold_engine
 +{
 +public:
 +
 +  rvrp_folder () : substitute_and_fold_engine (), m_simplifier ()
 +  { 
 +    if (flag_evrp_mode == EVRP_MODE_RVRP_TRACE
 +	|| flag_evrp_mode == EVRP_MODE_RVRP_DEBUG)
 +      m_ranger = new trace_ranger (true);
 +    else
 +      m_ranger = new gimple_ranger (true);
 +    substitute_and_fold_engine::set_value_query (m_ranger);
 +    m_simplifier.set_range_query (m_ranger);
 +  }
 +      
 +
 +  ~rvrp_folder ()
 +  {
 +    if (dump_file && (dump_flags & TDF_DETAILS))
 +      m_ranger->dump (dump_file);
 +    delete m_ranger;
 +  }
 +
 +  bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE
 +  {
 +    gcond *cond = dyn_cast <gcond *> (gsi_stmt (*gsi));
 +    if (cond && fold_cond (m_ranger, cond))
 +      return true;
 +
 +    return m_simplifier.simplify (gsi);
 +  }
 +
 +private:
 +  gimple_ranger *m_ranger;
 +  simplify_using_ranges m_simplifier;
 +};
 +
 +// -----------------------------------------------------------------------
 +
 +
 +// Override value_of_expr in a ranger to compare results with the EVRp
 +// evaluator
 +class hybrid_ranger : public gimple_ranger
 +{
 +public:
 +  hybrid_ranger (vr_values *v) : gimple_ranger (true), m_vr_values (v) { }
 +
 +  bool value_of_expr (tree &t, tree op, gimple *stmt) OVERRIDE
 +  {
 +    tree evrp_ret = m_vr_values->op_with_constant_singleton_value_range (op);
 +    bool ret = gimple_ranger::value_of_expr (t, op, stmt);
 +
 +    if (!ret)
 +      {
 +	// If neither returned a value, return false.
 +	if (!evrp_ret)
 +	  return false;
 +
 +	// Otherwise EVRP found something.
 +	if (dump_file)
 +	  {
 +	    fprintf (dump_file, "EVRP:hybrid: EVRP found singleton ");
 +	    print_generic_expr (dump_file, evrp_ret);
 +	    fprintf (dump_file, "\n");
 +	  }
 +	t = evrp_ret;
 +	return true;
 +      }
 +
 +
 +    // Otherwise ranger found a value, if they match we're good.
 +    if (evrp_ret && !compare_values (evrp_ret, t))
 +      return true;
 +
 +    // We should never get different singletons.
 +    gcc_checking_assert (!evrp_ret);
 +
 +    // Now ranger has found a value, but EVRP did not.
 +    if (dump_file)
 +      {
 +	fprintf (dump_file, "EVRP:hybrid: RVRP found singleton ");
 +	print_generic_expr (dump_file, t);
 +	fprintf (dump_file, "\n");
 +      }
 +    return true;
 +  }
 +private:
 +  vr_values *m_vr_values;
 +};
 +
 +
 +// In a hybrid folder, start with an EVRP folder, and add the required fold_stmt
 +// bits do either try the ranger first or second.
 +
 +class hybrid_folder : public evrp_folder
 +{
 +public:
 +  hybrid_folder () :
 +    evrp_folder (),
 +    m_ranger (m_vr_values),
 +    m_evrp_try_first (flag_evrp_mode == EVRP_MODE_EVRP_FIRST)
 +  {
 +    // Default to the hybrid evaluator if we should try it first
 +    if (!m_evrp_try_first)
 +      {
 +	simplifier.set_range_query (&m_ranger);
 +	substitute_and_fold_engine::set_value_query (&m_ranger);
 +      }
 +  }
 +
 +  ~hybrid_folder ()
 +  {
 +    if (dump_file && (dump_flags & TDF_DETAILS))
 +      m_ranger.dump (dump_file);
 +  }
 +
 +  bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE
 +  {
 +    gcond *cond = dyn_cast <gcond *> (gsi_stmt (*gsi));
 +    if (m_evrp_try_first)
 +      {
 +	simplifier.set_range_query (m_vr_values);
 +	if (simplifier.simplify (gsi))
 +	  return true;
 +
 +	simplifier.set_range_query (&m_ranger);
 +	if (cond && fold_cond (&m_ranger, cond))
 +	  {
 +	    if (dump_file)
 +	      fprintf (dump_file, "EVRP:hybrid: RVRP folded conditional\n");
 +	    return true;
 +	  }
 +	if (simplifier.simplify (gsi))
 +	  {
 +	    if (dump_file)
 +	      fprintf (dump_file, "EVRP:hybrid: RVRP simplifed stmt\n");
 +	    return true;
 +	  }
 +	return false;
 +      }
 +
 +    simplifier.set_range_query (&m_ranger);
 +    if (cond && fold_cond (&m_ranger, cond))
 +      return true;
 +    if (simplifier.simplify (gsi))
 +      return true;
 +
 +    simplifier.set_range_query (m_vr_values);
 +    if (simplifier.simplify (gsi))
 +      {
 +	if (dump_file)
 +	  fprintf (dump_file, "EVRP:hybrid: EVRP simplifed stmt\n");
 +	return true;
 +      }
 +    return false;
 +  }
 +
 +private:
 +  DISABLE_COPY_AND_ASSIGN (hybrid_folder);
 +  hybrid_ranger m_ranger;
 +  bool m_evrp_try_first;
 +};
 +
 +
 +
  /* Main entry point for the early vrp pass which is a simplified non-iterative
     version of vrp where basic blocks are visited in dominance order.  Value
     ranges discovered in early vrp will also be used by ipa-vrp.  */
diff --cc gcc/value-query.cc
index fe30dffcafc,00000000000..89a7d641d3d
mode 100644,000000..100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@@ -1,121 -1,0 +1,121 @@@
 +/* Support routines for value queries.
 +   Copyright (C) 2020 Free Software Foundation, Inc.
 +   Contributed by Aldy Hernandez <aldyh@redhat.com> and
 +   Andrew MacLeod <amacleod@redhat.com>.
 +
 +This file is part of GCC.
 +
 +GCC is free software; you can redistribute it and/or modify
 +it under the terms of the GNU General Public License as published by
 +the Free Software Foundation; either version 3, or (at your option)
 +any later version.
 +
 +GCC is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with GCC; see the file COPYING3.  If not see
 +<http://www.gnu.org/licenses/>.  */
 +
 +#include "config.h"
 +#include "system.h"
 +#include "coretypes.h"
 +#include "backend.h"
 +#include "tree.h"
 +#include "gimple.h"
 +#include "ssa.h"
 +#include "tree-pretty-print.h"
 +#include "fold-const.h"
 +#include "value-range-equiv.h"
 +#include "value-query.h"
 +#include "alloc-pool.h"
 +
 +
 +bool
 +value_query::value_on_edge (tree &t, edge, tree name)
 +{
 +  return value_of_expr (t, name);
 +}
 +
 +bool
 +value_query::value_of_stmt (tree &t, gimple *, tree name)
 +{
 +  if (name)
 +    return value_of_expr (t, name);
 +  return false;
 +}
 +
 +
 +// -----------------------------------------------------------
 +
 +bool
 +range_query::range_on_edge (irange &r, edge, tree name)
 +{
 +  return range_of_expr (r, name);
 +}
 +
 +bool
 +range_query::range_of_stmt (irange &r, gimple *, tree name)
 +{
 +  if (name)
 +    return range_of_expr (r, name);
 +  return false;
 +}
 +
 +bool
 +range_query::value_of_expr (tree &t, tree name, gimple *stmt)
 +{
-   widest_irange r;
++  int_range_max r;
 +  if (!irange::supports_type_p (TREE_TYPE (name)))
 +    return false;
 +  return (range_of_expr (r, name, stmt) && r.singleton_p (&t));
 +}
 +
 +bool
 +range_query::value_on_edge (tree &t, edge e, tree name)
 +{
-   widest_irange r;
++  int_range_max r;
 +  if (!irange::supports_type_p (TREE_TYPE (name)))
 +    return false;
 +  return (range_on_edge (r, e, name) && r.singleton_p (&t));
 +}
 +
 +bool
 +range_query::value_of_stmt (tree &t, gimple *stmt, tree name)
 +{
-   widest_irange r;
++  int_range_max r;
 +  if (!irange::supports_type_p (TREE_TYPE (name)))
 +    return false;
 +  return (range_of_stmt (r, stmt, name) && r.singleton_p (&t));
 +}
 +
 +
 +// valuation_query support routines for value_range_equiv's.
 +
 +class equiv_allocator : public object_allocator<value_range_equiv>
 +{
 +public:
 +  equiv_allocator ()
 +    : object_allocator<value_range_equiv> ("equiv_allocator pool") { }
 +};
 +
 +const class value_range_equiv *
 +range_query::get_value_range (const_tree expr, gimple *stmt)
 +{
-   widest_irange r;
++  int_range_max r;
 +  if (range_of_expr (r, const_cast<tree> (expr), stmt))
 +    return new (equiv_pool->allocate ()) value_range_equiv (r);
 +  return new (equiv_pool->allocate ()) value_range_equiv (TREE_TYPE (expr));
 +}
 +
 +range_query::range_query ()
 +{
 +  equiv_pool = new equiv_allocator;
 +}
 +
 +range_query::~range_query ()
 +{
 +  equiv_pool->release ();
 +}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-10 16:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-10 16:24 [gcc(refs/users/aldyh/heads/ranger-staging)] Merge remote-tracking branch 'origin/master' into me/ranger-staging Aldy Hernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).