aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@baylibre.com>2024-03-10 23:42:46 +0100
committerThomas Schwinge <tschwinge@baylibre.com>2024-03-10 23:42:46 +0100
commit6915bdb8fcdaeee585bbc9aaa52311e8c695da01 (patch)
treefb2227327879ffdd1d6a3d652a70043afb7db58e /gcc
parentffba2ab00fb01d77dfc4103bfffabebfc2568d9a (diff)
parent5f5e37dcbc19cbbaec58789fc532cb9940413258 (diff)
downloadgcc-6915bdb8fcdaeee585bbc9aaa52311e8c695da01.zip
gcc-6915bdb8fcdaeee585bbc9aaa52311e8c695da01.tar.gz
gcc-6915bdb8fcdaeee585bbc9aaa52311e8c695da01.tar.bz2
Merge commit 'f4a2ae2338962208b8039f154f5912402e94c378^' into HEAD
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog1605
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog147
-rw-r--r--gcc/ada/debug.adb6
-rw-r--r--gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst14
-rw-r--r--gcc/ada/exp_aggr.adb1
-rw-r--r--gcc/ada/exp_ch3.adb98
-rw-r--r--gcc/ada/exp_ch3.ads4
-rw-r--r--gcc/ada/exp_ch4.adb770
-rw-r--r--gcc/ada/exp_ch4.ads4
-rw-r--r--gcc/ada/exp_ch5.adb8
-rw-r--r--gcc/ada/exp_ch6.adb61
-rw-r--r--gcc/ada/exp_ch8.adb3
-rw-r--r--gcc/ada/exp_util.adb33
-rw-r--r--gcc/ada/exp_util.ads17
-rw-r--r--gcc/ada/gcc-interface/Makefile.in9
-rw-r--r--gcc/ada/gcc-interface/decl.cc11
-rw-r--r--gcc/ada/gcc-interface/trans.cc17
-rw-r--r--gcc/ada/gnat1drv.adb21
-rw-r--r--gcc/ada/gnat_rm.texi774
-rw-r--r--gcc/ada/gnat_ugn.texi4
-rw-r--r--gcc/ada/libgnat/a-textio.ads22
-rw-r--r--gcc/ada/opt.ads10
-rw-r--r--gcc/ada/sem_ch12.adb81
-rw-r--r--gcc/ada/sem_ch5.adb19
-rw-r--r--gcc/ada/sem_disp.adb30
-rw-r--r--gcc/ada/sem_disp.ads5
-rw-r--r--gcc/ada/sem_util.adb35
-rw-r--r--gcc/ada/sprint.adb6
-rw-r--r--gcc/analyzer/ChangeLog160
-rw-r--r--gcc/analyzer/access-diagram.cc1
-rw-r--r--gcc/analyzer/bounds-checking.cc1
-rw-r--r--gcc/analyzer/region-model-manager.cc5
-rw-r--r--gcc/analyzer/region-model-manager.h3
-rw-r--r--gcc/analyzer/region-model.cc15
-rw-r--r--gcc/c-family/ChangeLog27
-rw-r--r--gcc/c-family/c-common.cc4
-rw-r--r--gcc/c-family/c-common.h4
-rw-r--r--gcc/c-family/c-cppbuiltin.cc8
-rw-r--r--gcc/c-family/c-opts.cc28
-rw-r--r--gcc/c-family/c.opt29
-rw-r--r--gcc/c/ChangeLog21
-rw-r--r--gcc/c/Make-lang.in4
-rw-r--r--gcc/c/c-decl.cc20
-rw-r--r--gcc/c/c-typeck.cc5
-rw-r--r--gcc/cfg.cc7
-rw-r--r--gcc/common/config/i386/cpuinfo.h3
-rw-r--r--gcc/common/config/riscv/riscv-common.cc55
-rw-r--r--gcc/config/aarch64/aarch64-protos.h2
-rw-r--r--gcc/config/aarch64/aarch64-simd.md102
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins-base.cc48
-rw-r--r--gcc/config/aarch64/aarch64.cc10
-rw-r--r--gcc/config/aarch64/iterators.md3
-rw-r--r--gcc/config/aarch64/predicates.md12
-rw-r--r--gcc/config/cris/cris.cc2
-rw-r--r--gcc/config/cris/cris.md9
-rw-r--r--gcc/config/darwin.h5
-rw-r--r--gcc/config/darwin.opt4
-rw-r--r--gcc/config/i386/i386-expand.cc3
-rw-r--r--gcc/config/i386/i386-features.cc145
-rw-r--r--gcc/config/i386/i386-features.h1
-rw-r--r--gcc/config/i386/i386-options.cc10
-rw-r--r--gcc/config/i386/i386.cc97
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/i386/i386.md76
-rw-r--r--gcc/config/i386/predicates.md12
-rw-r--r--gcc/config/i386/sse.md280
-rw-r--r--gcc/config/mips/constraints.md4
-rw-r--r--gcc/config/mips/mips-protos.h4
-rw-r--r--gcc/config/mips/mips.cc219
-rw-r--r--gcc/config/mips/mips.h33
-rw-r--r--gcc/config/mips/mips.md200
-rw-r--r--gcc/config/mips/mips.opt4
-rw-r--r--gcc/config/mips/predicates.md21
-rw-r--r--gcc/config/nvptx/nvptx.cc3
-rwxr-xr-xgcc/config/riscv/arch-canonicalize7
-rw-r--r--gcc/config/riscv/autovec-opt.md279
-rw-r--r--gcc/config/riscv/autovec.md552
-rw-r--r--gcc/config/riscv/predicates.md7
-rw-r--r--gcc/config/riscv/riscv-opts.h34
-rw-r--r--gcc/config/riscv/riscv-protos.h6
-rw-r--r--gcc/config/riscv/riscv-v.cc163
-rw-r--r--gcc/config/riscv/riscv-vector-builtins-bases.cc53
-rw-r--r--gcc/config/riscv/riscv-vector-builtins-bases.h6
-rw-r--r--gcc/config/riscv/riscv-vector-builtins-functions.def2
-rw-r--r--gcc/config/riscv/riscv-vector-builtins-shapes.cc68
-rw-r--r--gcc/config/riscv/riscv-vector-builtins-shapes.h1
-rw-r--r--gcc/config/riscv/riscv-vector-builtins.cc42
-rw-r--r--gcc/config/riscv/riscv-vector-builtins.h4
-rw-r--r--gcc/config/riscv/riscv-vsetvl.cc70
-rw-r--r--gcc/config/riscv/riscv-vsetvl.h2
-rw-r--r--gcc/config/riscv/riscv.cc52
-rw-r--r--gcc/config/riscv/riscv.h4
-rw-r--r--gcc/config/riscv/riscv.md4
-rw-r--r--gcc/config/riscv/riscv.opt6
-rw-r--r--gcc/config/riscv/vector-iterators.md97
-rw-r--r--gcc/config/riscv/vector.md225
-rw-r--r--gcc/config/rs6000/altivec.md2
-rw-r--r--gcc/config/rs6000/fusion.md27
-rwxr-xr-xgcc/config/rs6000/genfusion.pl37
-rw-r--r--gcc/config/rs6000/predicates.md25
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.cc30
-rw-r--r--gcc/config/rs6000/rs6000.md43
-rw-r--r--gcc/config/rs6000/vsx.md24
-rw-r--r--gcc/config/s390/s390.cc6
-rw-r--r--gcc/config/xtensa/xtensa.cc16
-rw-r--r--gcc/config/xtensa/xtensa.md19
-rw-r--r--gcc/cp/ChangeLog106
-rw-r--r--gcc/cp/Make-lang.in4
-rw-r--r--gcc/cp/constexpr.cc11
-rw-r--r--gcc/cp/cp-gimplify.cc2
-rw-r--r--gcc/cp/cp-name-hint.h1
-rw-r--r--gcc/cp/cp-tree.h24
-rw-r--r--gcc/cp/decl.cc10
-rw-r--r--gcc/cp/init.cc4
-rw-r--r--gcc/cp/method.cc2
-rw-r--r--gcc/cp/module.cc2
-rw-r--r--gcc/cp/name-lookup.cc2
-rw-r--r--gcc/cp/optimize.cc26
-rw-r--r--gcc/cp/parser.cc8
-rw-r--r--gcc/cp/pt.cc132
-rw-r--r--gcc/cp/ptree.cc3
-rw-r--r--gcc/cp/typeck.cc5
-rw-r--r--gcc/cselib.cc60
-rw-r--r--gcc/cselib.h10
-rw-r--r--gcc/d/ChangeLog49
-rw-r--r--gcc/d/d-builtins.cc9
-rw-r--r--gcc/d/d-convert.cc31
-rw-r--r--gcc/d/decl.cc14
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/aggregate.h10
-rw-r--r--gcc/d/dmd/attrib.h12
-rw-r--r--gcc/d/dmd/common/outbuffer.h6
-rw-r--r--gcc/d/dmd/cond.d3
-rw-r--r--gcc/d/dmd/cond.h2
-rw-r--r--gcc/d/dmd/cppmangle.d11
-rw-r--r--gcc/d/dmd/declaration.h12
-rw-r--r--gcc/d/dmd/dsymbol.h4
-rw-r--r--gcc/d/dmd/dsymbolsem.d13
-rw-r--r--gcc/d/dmd/expression.h50
-rw-r--r--gcc/d/dmd/expressionsem.d22
-rw-r--r--gcc/d/dmd/globals.h112
-rw-r--r--gcc/d/dmd/hdrgen.d5
-rw-r--r--gcc/d/dmd/identifier.h2
-rw-r--r--gcc/d/dmd/init.h8
-rw-r--r--gcc/d/dmd/lexer.d26
-rw-r--r--gcc/d/dmd/module.h8
-rw-r--r--gcc/d/dmd/mtype.h4
-rw-r--r--gcc/d/dmd/objc.h6
-rw-r--r--gcc/d/dmd/root/array.d2
-rw-r--r--gcc/d/dmd/root/dcompat.h10
-rw-r--r--gcc/d/dmd/root/optional.h4
-rw-r--r--gcc/d/dmd/scope.h4
-rw-r--r--gcc/d/dmd/semantic2.d3
-rw-r--r--gcc/d/dmd/semantic3.d2
-rw-r--r--gcc/d/dmd/statement.h24
-rw-r--r--gcc/d/dmd/statementsem.d8
-rw-r--r--gcc/d/dmd/target.h20
-rw-r--r--gcc/d/dmd/template.h14
-rw-r--r--gcc/d/dmd/visitor.h3
-rw-r--r--gcc/d/expr.cc4
-rw-r--r--gcc/d/intrinsics.cc2
-rw-r--r--gcc/d/lang.opt4
-rw-r--r--gcc/d/types.cc43
-rw-r--r--gcc/diagnostic-format-sarif.cc1
-rw-r--r--gcc/diagnostic.cc1
-rw-r--r--gcc/doc/cpp.texi7
-rw-r--r--gcc/doc/extend.texi79
-rw-r--r--gcc/doc/gm2.texi126
-rw-r--r--gcc/doc/invoke.texi53
-rw-r--r--gcc/doc/md.texi50
-rw-r--r--gcc/doc/optinfo.texi2
-rw-r--r--gcc/dwarf2out.cc6
-rw-r--r--gcc/except.h2
-rw-r--r--gcc/expr.cc117
-rw-r--r--gcc/expr.h16
-rw-r--r--gcc/final.cc50
-rw-r--r--gcc/flag-types.h5
-rw-r--r--gcc/fold-const.cc75
-rw-r--r--gcc/fold-const.h2
-rw-r--r--gcc/fortran/ChangeLog32
-rw-r--r--gcc/fortran/expr.cc4
-rw-r--r--gcc/fortran/resolve.cc5
-rw-r--r--gcc/fortran/trans-decl.cc1
-rw-r--r--gcc/fortran/trans-expr.cc88
-rw-r--r--gcc/function.cc3
-rw-r--r--gcc/gengtype-parse.cc6
-rw-r--r--gcc/ggc-page.cc10
-rw-r--r--gcc/ggc.h8
-rw-r--r--gcc/gimple-fold.cc92
-rw-r--r--gcc/gimple-predicate-analysis.cc4
-rw-r--r--gcc/gimple-range-gori.cc21
-rw-r--r--gcc/gimple-ssa-store-merging.cc5
-rw-r--r--gcc/gimplify.cc7
-rw-r--r--gcc/go/ChangeLog14
-rw-r--r--gcc/go/gccgo.texi8
-rw-r--r--gcc/go/go-c.h1
-rw-r--r--gcc/go/go-lang.cc6
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/embed.cc11
-rw-r--r--gcc/go/gofrontend/expressions.cc3
-rw-r--r--gcc/go/gofrontend/go.cc2
-rw-r--r--gcc/go/gofrontend/gogo.cc50
-rw-r--r--gcc/go/gofrontend/gogo.h12
-rw-r--r--gcc/go/gofrontend/import.cc124
-rw-r--r--gcc/go/lang.opt4
-rw-r--r--gcc/internal-fn.cc205
-rw-r--r--gcc/internal-fn.def13
-rw-r--r--gcc/internal-fn.h1
-rw-r--r--gcc/ipa-cp.cc18
-rw-r--r--gcc/ipa-devirt.cc2
-rw-r--r--gcc/ipa-fnsummary.cc38
-rw-r--r--gcc/ipa-fnsummary.h6
-rw-r--r--gcc/ipa-icf.cc2
-rw-r--r--gcc/ipa-inline.cc101
-rw-r--r--gcc/ipa-modref.cc2
-rw-r--r--gcc/ipa-prop.cc157
-rw-r--r--gcc/ipa-prop.h5
-rw-r--r--gcc/ipa-sra.cc2
-rw-r--r--gcc/ipa-utils.cc7
-rw-r--r--gcc/lto-cgraph.cc2
-rw-r--r--gcc/lto-section-in.cc2
-rw-r--r--gcc/lto-streamer-in.cc18
-rw-r--r--gcc/lto-streamer-out.cc13
-rw-r--r--gcc/lto-streamer.h12
-rw-r--r--gcc/lto/ChangeLog25
-rw-r--r--gcc/lto/Make-lang.in2
-rw-r--r--gcc/lto/lto-common.cc10
-rw-r--r--gcc/m2/ChangeLog71
-rw-r--r--gcc/m2/Make-lang.in6
-rw-r--r--gcc/m2/gm2-compiler/M2BasicBlock.mod2
-rw-r--r--gcc/m2/gm2-compiler/M2Code.mod4
-rw-r--r--gcc/m2/gm2-compiler/M2GCCDeclare.mod21
-rw-r--r--gcc/m2/gm2-compiler/M2GenGCC.mod30
-rw-r--r--gcc/m2/gm2-compiler/M2Optimize.mod97
-rw-r--r--gcc/m2/gm2-compiler/M2Options.def10
-rw-r--r--gcc/m2/gm2-compiler/M2Options.mod14
-rw-r--r--gcc/m2/gm2-compiler/M2Quads.def28
-rw-r--r--gcc/m2/gm2-compiler/M2Quads.mod238
-rw-r--r--gcc/m2/gm2-compiler/M2SymInit.def59
-rw-r--r--gcc/m2/gm2-compiler/M2SymInit.mod1307
-rw-r--r--gcc/m2/gm2-compiler/SymbolTable.def52
-rw-r--r--gcc/m2/gm2-compiler/SymbolTable.mod173
-rw-r--r--gcc/m2/gm2-gcc/m2options.h2
-rw-r--r--gcc/m2/gm2-lang.cc3
-rw-r--r--gcc/m2/gm2-libs/RTint.mod70
-rw-r--r--gcc/m2/lang.opt4
-rw-r--r--gcc/match.pd102
-rw-r--r--gcc/optabs-tree.cc86
-rw-r--r--gcc/optabs-tree.h6
-rw-r--r--gcc/optabs.cc90
-rw-r--r--gcc/optabs.def12
-rw-r--r--gcc/optabs.h16
-rw-r--r--gcc/opts.cc4
-rw-r--r--gcc/output.h14
-rw-r--r--gcc/predict.cc56
-rw-r--r--gcc/predict.def18
-rw-r--r--gcc/predict.h1
-rw-r--r--gcc/print-tree.cc5
-rw-r--r--gcc/regcprop.cc52
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/rust/ChangeLog5
-rw-r--r--gcc/sbitmap.cc2
-rw-r--r--gcc/sbitmap.h2
-rw-r--r--gcc/simplify-rtx.cc32
-rw-r--r--gcc/statistics.cc21
-rw-r--r--gcc/testsuite/ChangeLog916
-rw-r--r--gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c15
-rw-r--r--gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c21
-rw-r--r--gcc/testsuite/g++.dg/cpp/pr64127.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-mutable6.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype-110175.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept79.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr72759.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/var-templ82.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/noexcept-type21.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp23/cplusplus.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C35
-rw-r--r--gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp26/cplusplus.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp26/feat-cxx26.C597
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/missing-header-pr110164.C10
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C2
-rw-r--r--gcc/testsuite/g++.dg/opt/pr66119.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/error56.C1
-rw-r--r--gcc/testsuite/g++.dg/parse/template30.C3
-rw-r--r--gcc/testsuite/g++.dg/template/nontype12.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr110308.C29
-rw-r--r--gcc/testsuite/g++.target/powerpc/pr105325.C28
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c26
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr110334.c20
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr110444-1.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20230630-1.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20230630-2.c29
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20230630-3.c27
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20230630-4.c33
-rw-r--r--gcc/testsuite/gcc.dg/Wtraditional-conversion-3.c9
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c134
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr109849.c27
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr110377.c16
-rw-r--r--gcc/testsuite/gcc.dg/plugin/crash-test-ice-sarif.c3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/crash-test-ice-stderr.c1
-rw-r--r--gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-sarif.c3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-stderr.c1
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr110436.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr110461.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr110496.c26
-rw-r--r--gcc/testsuite/gcc.dg/pr110506-2.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr110506.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr110508.c9
-rw-r--r--gcc/testsuite/gcc.dg/predict-18.c10
-rw-r--r--gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c60
-rw-r--r--gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c60
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr110228.c34
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr110376.c39
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr110443.c21
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr110491.c29
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ifc-20040816-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr103680.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr110334.c17
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pr101912.c2
-rw-r--r--gcc/testsuite/gcc.dg/variable-sized-type-flex-array.c31
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c16
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr110381.c45
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-46.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-12.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-9.c4
-rw-r--r--gcc/testsuite/gcc.misc-tests/outputs.exp10
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_2.c45
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_3.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_4.c34
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_none_2.c73
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_none_3.c73
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_none_4.c84
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_run_1.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_widen_2.c50
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_widen_3.c50
-rw-r--r--gcc/testsuite/gcc.target/aarch64/abd_widen_4.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr110371.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/abd_1.c57
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/abd_2.c47
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/abd_none_1.c73
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/abd_none_2.c80
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_11.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/pr110280.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/general-c/nomve_fp_1.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu1.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/ashldi3-1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/ashlti3-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-30.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512-binop-not-1.h13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512-binop-not-2.h13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-andn-di-zmm-2.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-andn-si-zmm-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-copysign.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-2.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/bf16_short_warn.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/mvc17.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/pieces-memcmp-2.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100711-3.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100711-4.c42
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100711-5.c40
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100711-6.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/pr104610.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr110018-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr110018-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr110309.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr110310.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr110452.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr69482-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/rotate-6.c195
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-stv-1.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c16
-rw-r--r--gcc/testsuite/gcc.target/mips/align-1-n64.c20
-rw-r--r--gcc/testsuite/gcc.target/mips/align-1-o32.c20
-rw-r--r--gcc/testsuite/gcc.target/mips/expand-block-move-r6-no-unaligned.c15
-rw-r--r--gcc/testsuite/gcc.target/mips/expand-block-move-r6.c20
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp10
-rw-r--r--gcc/testsuite/gcc.target/mips/mips16e2-cache.c34
-rw-r--r--gcc/testsuite/gcc.target/mips/mips16e2-cmov.c68
-rw-r--r--gcc/testsuite/gcc.target/mips/mips16e2-gp.c101
-rw-r--r--gcc/testsuite/gcc.target/mips/mips16e2.c240
-rw-r--r--gcc/testsuite/gcc.target/mips/movcc-3.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/fusion-p10-ldcmpi.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr104124.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c89
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h78
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c83
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-run.c96
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv32gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv64gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-template.h20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-zvfh-run.c64
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c44
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-zvfh-run.c64
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-run.c96
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv32gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv64gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-template.h19
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-zvfh-run.c42
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-run.c52
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv32gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv64gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-template.h18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-zvfh-run.c64
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h16
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c34
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-run.c64
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv32gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv64gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-template.h17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-zvfh-run.c64
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-run.c96
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv32gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv64gcv.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-template.h20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-zvfh-run.c45
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h16
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c34
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vncvt-template.h2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vsext-template.h2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vzext-template.h2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c43
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-1.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.h44
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.h149
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-2.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-3.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c34
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-17.c84
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-18.c69
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-19.c69
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c23
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c9
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c9
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c23
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c40
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c60
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c60
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c40
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c60
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c60
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c35
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c35
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c35
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c35
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c55
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-10.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-11.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-12.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-3.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-7.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-8.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-10.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-11.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-12.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-3.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-7.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-8.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/zvfhmin-1.c48
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-10.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-11.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-12.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-15.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-17.c229
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-18.c229
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-8.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-9.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c15
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c31
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c23
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c23
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-1.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvbb.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvbc.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkg.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkn-1.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkn.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvknc-1.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvknc-2.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvknc.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkned.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkng-1.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkng-2.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkng.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvknha.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvknhb.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvks-1.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvks.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksc-1.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksc-2.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksc.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksed.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksg-1.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksg-2.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksg.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvksh.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zvkt.c13
-rw-r--r--gcc/testsuite/gcc.target/s390/larl-1.c32
-rw-r--r--gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d44
-rw-r--r--gcc/testsuite/gdc.dg/pr108962.d13
-rw-r--r--gcc/testsuite/gdc.dg/pr110359.d22
-rw-r--r--gcc/testsuite/gdc.dg/pr110471a.d5
-rw-r--r--gcc/testsuite/gdc.dg/pr110471b.d5
-rw-r--r--gcc/testsuite/gdc.dg/pr110471c.d5
-rw-r--r--gcc/testsuite/gdc.dg/pr110514a.d9
-rw-r--r--gcc/testsuite/gdc.dg/pr110514b.d8
-rw-r--r--gcc/testsuite/gdc.dg/pr110514c.d8
-rw-r--r--gcc/testsuite/gdc.dg/pr110514d.d8
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr110406.d25
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr110516a.d12
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr110516b.d12
-rw-r--r--gcc/testsuite/gdc.test/compilable/shared.d66
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22739.d10
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23799.d37
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/bug9631.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/cerrors.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail17646.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19948.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22857.d18
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail23816.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/shared.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21164.d3
-rw-r--r--gcc/testsuite/gdc.test/runnable/complex3.d31
-rw-r--r--gcc/testsuite/gfortran.dg/pr25623.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/pr49213.f90109
-rw-r--r--gcc/testsuite/gfortran.dg/value_9.f90101
-rw-r--r--gcc/testsuite/gfortran.dg/vect/pr110451.f51
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/switches-uninit-variable-checking-fail.exp37
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testinit.mod17
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge.mod27
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge2.mod24
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit.mod31
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit2.mod25
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit5.mod25
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec.mod22
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec2.mod24
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallvec.mod20
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testvarinit.mod17
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithnoptr.mod29
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr.mod34
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr2.mod30
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr3.mod21
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/switches-uninit-variable-checking-pass.exp37
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit3.mod30
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit5.mod25
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec.mod22
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec2.mod24
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testvarinit.mod17
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr.mod34
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr2.mod31
-rw-r--r--gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr3.mod31
-rw-r--r--gcc/testsuite/jit.dg/jit.exp4
-rw-r--r--gcc/testsuite/jit.dg/test-expressions.c22
-rw-r--r--gcc/testsuite/lib/g++-dg.exp10
-rw-r--r--gcc/testsuite/lib/g++.exp4
-rw-r--r--gcc/testsuite/lib/obj-c++.exp4
-rw-r--r--gcc/testsuite/lib/options.exp2
-rw-r--r--gcc/testsuite/lib/target-supports.exp32
-rw-r--r--gcc/testsuite/objc-obj-c++-shared/GNUStep/Foundation/NSObjCRuntime.h3
-rw-r--r--gcc/text-art/box-drawing.cc1
-rw-r--r--gcc/text-art/canvas.cc1
-rw-r--r--gcc/text-art/ruler.cc1
-rw-r--r--gcc/text-art/selftests.cc1
-rw-r--r--gcc/text-art/selftests.h4
-rw-r--r--gcc/text-art/style.cc1
-rw-r--r--gcc/text-art/styled-string.cc1
-rw-r--r--gcc/text-art/table.cc1
-rw-r--r--gcc/text-art/table.h1
-rw-r--r--gcc/text-art/theme.cc1
-rw-r--r--gcc/text-art/types.h10
-rw-r--r--gcc/text-art/widget.cc1
-rw-r--r--gcc/text-art/widget.h1
-rw-r--r--gcc/tree-cfg.cc103
-rw-r--r--gcc/tree-cfg.h2
-rw-r--r--gcc/tree-core.h2
-rw-r--r--gcc/tree-nrv.cc12
-rw-r--r--gcc/tree-object-size.cc23
-rw-r--r--gcc/tree-ssa-alias.cc3
-rw-r--r--gcc/tree-ssa-ccp.cc1
-rw-r--r--gcc/tree-ssa-dce.cc3
-rw-r--r--gcc/tree-ssa-dom.cc65
-rw-r--r--gcc/tree-ssa-dse.cc48
-rw-r--r--gcc/tree-ssa-ifcombine.cc8
-rw-r--r--gcc/tree-ssa-loop-ch.cc53
-rw-r--r--gcc/tree-ssa-loop-im.cc11
-rw-r--r--gcc/tree-ssa-loop-ivopts.cc16
-rw-r--r--gcc/tree-ssa-math-opts.cc17
-rw-r--r--gcc/tree-ssa-phiopt.cc15
-rw-r--r--gcc/tree-ssa-phiprop.cc8
-rw-r--r--gcc/tree-ssa-reassoc.cc241
-rw-r--r--gcc/tree-ssa-sccvn.cc14
-rw-r--r--gcc/tree-ssa-scopedtables.cc2
-rw-r--r--gcc/tree-ssa.cc17
-rw-r--r--gcc/tree-ssa.h1
-rw-r--r--gcc/tree-streamer-in.cc7
-rw-r--r--gcc/tree-streamer-out.cc7
-rw-r--r--gcc/tree-streamer.cc2
-rw-r--r--gcc/tree-streamer.h12
-rw-r--r--gcc/tree-vect-loop-manip.cc104
-rw-r--r--gcc/tree-vect-loop.cc93
-rw-r--r--gcc/tree-vect-patterns.cc202
-rw-r--r--gcc/tree-vect-slp.cc70
-rw-r--r--gcc/tree-vect-stmts.cc454
-rw-r--r--gcc/tree-vrp.cc65
-rw-r--r--gcc/tree-vrp.h1
-rw-r--r--gcc/tree.cc126
-rw-r--r--gcc/tree.def17
-rw-r--r--gcc/tree.h19
-rw-r--r--gcc/value-range.cc114
-rw-r--r--gcc/value-range.h2
-rw-r--r--gcc/varasm.cc101
-rw-r--r--gcc/varasm.h2
-rw-r--r--gcc/vec.h22
696 files changed, 22793 insertions, 3705 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a82f00f..9e0bdab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,1608 @@
+2023-07-04 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/110487
+ * match.pd (a !=/== CST1 ? CST2 : CST3): Always
+ build a nonstandard integer and use that.
+
+2023-07-04 Andrew Pinski <apinski@marvell.com>
+
+ * match.pd (a?-1:0): Cast type an integer type
+ rather the type before the negative.
+ (a?0:-1): Likewise.
+
+2023-07-04 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
+
+ * config/xtensa/xtensa.cc (machine_function, xtensa_expand_prologue):
+ Change to use HARD_REG_BIT and its macros.
+ * config/xtensa/xtensa.md
+ (peephole2: regmove elimination during DFmode input reload):
+ Likewise.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110491
+ * tree-ssa-phiopt.cc (match_simplify_replacement): Check
+ whether the PHI args are possibly undefined before folding
+ the COND_EXPR.
+
+2023-07-04 Pan Li <pan2.li@intel.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * lto-streamer-in.cc (lto_input_mode_table): Stream in the mode
+ bits for machine mode table.
+ * lto-streamer-out.cc (lto_write_mode_table): Stream out the
+ HOST machine mode bits.
+ * lto-streamer.h (struct lto_file_decl_data): New fields mode_bits.
+ * tree-streamer.cc (streamer_mode_table): Take MAX_MACHINE_MODE
+ as the table size.
+ * tree-streamer.h (streamer_mode_table): Ditto.
+ (bp_pack_machine_mode): Take 1 << ceil_log2 (MAX_MACHINE_MODE)
+ as the packing limit.
+ (bp_unpack_machine_mode): Ditto with 'file_data->mode_bits'.
+
+2023-07-04 Thomas Schwinge <thomas@codesourcery.com>
+
+ * lto-streamer.h (class lto_input_block): Capture
+ 'lto_file_decl_data *file_data' instead of just
+ 'unsigned char *mode_table'.
+ * ipa-devirt.cc (ipa_odr_read_section): Adjust.
+ * ipa-fnsummary.cc (inline_read_section): Likewise.
+ * ipa-icf.cc (sem_item_optimizer::read_section): Likewise.
+ * ipa-modref.cc (read_section): Likewise.
+ * ipa-prop.cc (ipa_prop_read_section, read_replacements_section):
+ Likewise.
+ * ipa-sra.cc (isra_read_summary_section): Likewise.
+ * lto-cgraph.cc (input_cgraph_opt_section): Likewise.
+ * lto-section-in.cc (lto_create_simple_input_block): Likewise.
+ * lto-streamer-in.cc (lto_read_body_or_constructor)
+ (lto_input_toplevel_asms): Likewise.
+ * tree-streamer.h (bp_unpack_machine_mode): Likewise.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-phiopt.cc (pass_phiopt::execute): Mark SSA undefs.
+ (empty_bb_or_one_feeding_into_p): Check for them.
+ * tree-ssa.h (gimple_uses_undefined_value_p): Remove.
+ * tree-ssa.cc (gimple_uses_undefined_value_p): Likewise.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-loop.cc (vect_analyze_loop_costing): Remove
+ check guarding scalar_niter underflow.
+
+2023-07-04 Hao Liu <hliu@os.amperecomputing.com>
+
+ PR tree-optimization/110531
+ * tree-vect-loop.cc (vect_analyze_loop_1): initialize
+ slp_done_for_suggested_uf to false.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110228
+ * tree-ssa-ifcombine.cc (pass_tree_ifcombine::execute):
+ Mark SSA may-undefs.
+ (bb_no_side_effects_p): Check stmt uses for undefs.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110436
+ * tree-vect-stmts.cc (vect_mark_relevant): Expand dumping,
+ force live but not relevant pattern stmts relevant.
+
+2023-07-04 Lili Cui <lili.cui@intel.com>
+
+ * config/i386/i386.h: Add PTA_ENQCMD and PTA_UINTR to PTA_SIERRAFOREST.
+ * doc/invoke.texi: Update new isa to march=sierraforest and grandridge.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/110495
+ * tree.h (TREE_OVERFLOW): Do not mention VECTOR_CSTs
+ since we do not set TREE_OVERFLOW on those since the
+ introduction of VL vectors.
+ * match.pd (x +- CST +- CST): For VECTOR_CST do not look
+ at TREE_OVERFLOW to determine validity of association.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110310
+ * tree-vect-loop.cc (vect_determine_partial_vectors_and_peeling):
+ Move costing part ...
+ (vect_analyze_loop_costing): ... here. Integrate better
+ estimate for epilogues from ...
+ (vect_analyze_loop_2): Call vect_determine_partial_vectors_and_peeling
+ with actual epilogue status.
+ * tree-vect-loop-manip.cc (vect_do_peeling): ... here and
+ avoid cancelling epilogue vectorization.
+ (vect_update_epilogue_niters): Remove. No longer update
+ epilogue LOOP_VINFO_NITERS.
+
+2023-07-04 Pan Li <pan2.li@intel.com>
+
+ Revert:
+ 2023-07-03 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/vector.md: Fix typo.
+
+2023-07-04 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * doc/md.texi: Add len_mask_gather_load/len_mask_scatter_store.
+ * internal-fn.cc (expand_scatter_store_optab_fn): Ditto.
+ (expand_gather_load_optab_fn): Ditto.
+ (internal_load_fn_p): Ditto.
+ (internal_store_fn_p): Ditto.
+ (internal_gather_scatter_fn_p): Ditto.
+ (internal_fn_len_index): Ditto.
+ (internal_fn_mask_index): Ditto.
+ (internal_fn_stored_value_index): Ditto.
+ * internal-fn.def (LEN_MASK_GATHER_LOAD): Ditto.
+ (LEN_MASK_SCATTER_STORE): Ditto.
+ * optabs.def (OPTAB_CD): Ditto.
+
+2023-07-04 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-vsetvl.cc
+ (vector_insn_info::parse_insn): Add early break.
+
+2023-07-04 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/cris/cris.md (CRIS_UNSPEC_SWAP_BITS): Remove.
+ ("cris_swap_bits", "ctzsi2"): Use bitreverse instead.
+
+2023-07-04 Hans-Peter Nilsson <hp@axis.com>
+
+ * dwarf2out.cc (mem_loc_descriptor): Handle BITREVERSE.
+
+2023-07-03 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * common/config/riscv/riscv-common.cc: Add support for zvbb,
+ zvbc, zvkg, zvkned, zvknha, zvknhb, zvksed, zvksh, zvkn,
+ zvknc, zvkng, zvks, zvksc, zvksg, zvkt and the implied subsets.
+ * config/riscv/arch-canonicalize: Add canonicalization info for
+ zvkn, zvknc, zvkng, zvks, zvksc, zvksg.
+ * config/riscv/riscv-opts.h (MASK_ZVBB): New macro.
+ (MASK_ZVBC): Likewise.
+ (TARGET_ZVBB): Likewise.
+ (TARGET_ZVBC): Likewise.
+ (MASK_ZVKG): Likewise.
+ (MASK_ZVKNED): Likewise.
+ (MASK_ZVKNHA): Likewise.
+ (MASK_ZVKNHB): Likewise.
+ (MASK_ZVKSED): Likewise.
+ (MASK_ZVKSH): Likewise.
+ (MASK_ZVKN): Likewise.
+ (MASK_ZVKNC): Likewise.
+ (MASK_ZVKNG): Likewise.
+ (MASK_ZVKS): Likewise.
+ (MASK_ZVKSC): Likewise.
+ (MASK_ZVKSG): Likewise.
+ (MASK_ZVKT): Likewise.
+ (TARGET_ZVKG): Likewise.
+ (TARGET_ZVKNED): Likewise.
+ (TARGET_ZVKNHA): Likewise.
+ (TARGET_ZVKNHB): Likewise.
+ (TARGET_ZVKSED): Likewise.
+ (TARGET_ZVKSH): Likewise.
+ (TARGET_ZVKN): Likewise.
+ (TARGET_ZVKNC): Likewise.
+ (TARGET_ZVKNG): Likewise.
+ (TARGET_ZVKS): Likewise.
+ (TARGET_ZVKSC): Likewise.
+ (TARGET_ZVKSG): Likewise.
+ (TARGET_ZVKT): Likewise.
+ * config/riscv/riscv.opt: Introduction of riscv_zv{b,k}_subext.
+
+2023-07-03 Andrew Pinski <apinski@marvell.com>
+
+ PR middle-end/110510
+ * except.h (struct eh_landing_pad_d): Add chain_next GTY.
+
+2023-07-03 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.h: Avoid duplicate multiply_defined specs on
+ earlier Darwin versions with shared libgcc.
+
+2023-07-03 Uros Bizjak <ubizjak@gmail.com>
+
+ * tree.h (tree_int_cst_equal): Change return type from int to bool.
+ (operand_equal_for_phi_arg_p): Ditto.
+ (tree_map_base_marked_p): Ditto.
+ * tree.cc (contains_placeholder_p): Update function body
+ for bool return type.
+ (type_cache_hasher::equal): Ditto.
+ (tree_map_base_hash): Change return type
+ from int to void and adjust function body accordingly.
+ (tree_int_cst_equal): Ditto.
+ (operand_equal_for_phi_arg_p): Ditto.
+ (get_narrower): Change "first" variable to bool.
+ (cl_option_hasher::equal): Update function body for bool return type.
+ * ggc.h (ggc_set_mark): Change return type from int to bool.
+ (ggc_marked_p): Ditto.
+ * ggc-page.cc (gt_ggc_mx): Change return type
+ from int to void and adjust function body accordingly.
+ (ggc_set_mark): Ditto.
+
+2023-07-03 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec.md: Change order of
+ LEN_MASK_LOAD/LEN_MASK_STORE/LEN_LOAD/LEN_STORE arguments.
+ * config/riscv/riscv-v.cc (expand_load_store): Ditto.
+ * doc/md.texi: Ditto.
+ * gimple-fold.cc (gimple_fold_partial_load_store_mem_ref): Ditto.
+ * internal-fn.cc (len_maskload_direct): Ditto.
+ (len_maskstore_direct): Ditto.
+ (add_len_and_mask_args): New function.
+ (expand_partial_load_optab_fn): Change order of
+ LEN_MASK_LOAD/LEN_MASK_STORE/LEN_LOAD/LEN_STORE arguments.
+ (expand_partial_store_optab_fn): Ditto.
+ (internal_fn_len_index): New function.
+ (internal_fn_mask_index): Change order of
+ LEN_MASK_LOAD/LEN_MASK_STORE/LEN_LOAD/LEN_STORE arguments.
+ (internal_fn_stored_value_index): Ditto.
+ (internal_len_load_store_bias): Ditto.
+ * internal-fn.h (internal_fn_len_index): New function.
+ * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Change order of
+ LEN_MASK_LOAD/LEN_MASK_STORE/LEN_LOAD/LEN_STORE arguments.
+ * tree-vect-stmts.cc (vectorizable_store): Ditto.
+ (vectorizable_load): Ditto.
+
+2023-07-03 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/110125
+ * doc/gm2.texi (Semantic checking): Include examples using
+ -Wuninit-variable-checking.
+
+2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec-opt.md (*double_widen_fnma<mode>): New pattern.
+ (*single_widen_fnma<mode>): Ditto.
+ (*double_widen_fms<mode>): Ditto.
+ (*single_widen_fms<mode>): Ditto.
+ (*double_widen_fnms<mode>): Ditto.
+ (*single_widen_fnms<mode>): Ditto.
+
+2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec-opt.md (@pred_single_widen_mul<any_extend:su><mode>): Change "@"
+ into "*" in pattern name which simplifies build files.
+ (*pred_single_widen_mul<any_extend:su><mode>): Ditto.
+ (*pred_single_widen_mul<mode>): New pattern.
+
+2023-07-03 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-simd.md (vec_extract<mode><Vhalf>): Expect
+ the index to be 0 or 1.
+
+2023-07-03 Lehua Ding <lehua.ding@rivai.ai>
+
+ Revert:
+ 2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec-opt.md (*double_widen_fnma<mode>): New pattern.
+ (*single_widen_fnma<mode>): Ditto.
+ (*double_widen_fms<mode>): Ditto.
+ (*single_widen_fms<mode>): Ditto.
+ (*double_widen_fnms<mode>): Ditto.
+ (*single_widen_fnms<mode>): Ditto.
+
+2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec-opt.md (*double_widen_fnma<mode>): New pattern.
+ (*single_widen_fnma<mode>): Ditto.
+ (*double_widen_fms<mode>): Ditto.
+ (*single_widen_fms<mode>): Ditto.
+ (*double_widen_fnms<mode>): Ditto.
+ (*single_widen_fnms<mode>): Ditto.
+
+2023-07-03 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/vector.md: Fix typo.
+
+2023-07-03 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110506
+ * tree-vect-patterns.cc (vect_recog_rotate_pattern): Re-order
+ TYPE_PRECISION access with INTEGRAL_TYPE_P check.
+
+2023-07-03 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110506
+ * tree-ssa-ccp.cc (get_value_for_expr): Check for integral
+ type before relying on TYPE_PRECISION to produce a nonzero mask.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.md(*and<mode>3_mips16): Generates
+ ZEB/ZEH instructions.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.cc(mips_9bit_offset_address_p): Restrict the
+ address register to M16_REGS for MIPS16.
+ (BUILTIN_AVAIL_MIPS16E2): Defined a new macro.
+ (AVAIL_MIPS16E2_OR_NON_MIPS16): Same as above.
+ (AVAIL_NON_MIPS16 (cache..)): Update to
+ AVAIL_MIPS16E2_OR_NON_MIPS16.
+ * config/mips/mips.h (ISA_HAS_CACHE): Add clause for ISA_HAS_MIPS16E2.
+ * config/mips/mips.md (mips_cache): Mark as extended MIPS16.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.h(ISA_HAS_9BIT_DISPLACEMENT): Add clause
+ for ISA_HAS_MIPS16E2.
+ (ISA_HAS_SYNC): Same as above.
+ (ISA_HAS_LL_SC): Same as above.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.cc(mips_expand_ins_as_unaligned_store):
+ Add logics for generating instruction.
+ * config/mips/mips.h(ISA_HAS_LWL_LWR): Add clause for ISA_HAS_MIPS16E2.
+ * config/mips/mips.md(mov_<load>l): Generates instructions.
+ (mov_<load>r): Same as above.
+ (mov_<store>l): Adjusted for the conditions above.
+ (mov_<store>r): Same as above.
+ (mov_<store>l_mips16e2): Add machine description for `define_insn mov_<store>l_mips16e2`.
+ (mov_<store>r_mips16e2): Add machine description for `define_insn mov_<store>r_mips16e2`.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.cc(mips_symbol_insns_1): Generates LUI instruction.
+ (mips_const_insns): Same as above.
+ (mips_output_move): Same as above.
+ (mips_output_function_prologue): Same as above.
+ * config/mips/mips.md: Same as above
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/constraints.md(Yz): New constraints for mips16e2.
+ * config/mips/mips-protos.h(mips_bit_clear_p): Declared new function.
+ (mips_bit_clear_info): Same as above.
+ * config/mips/mips.cc(mips_bit_clear_info): New function for
+ generating instructions.
+ (mips_bit_clear_p): Same as above.
+ * config/mips/mips.h(ISA_HAS_EXT_INS): Add clause for ISA_HAS_MIPS16E2.
+ * config/mips/mips.md(extended_mips16): Generates EXT and INS instructions.
+ (*and<mode>3): Generates INS instruction.
+ (*and<mode>3_mips16): Generates EXT, INS and ANDI instructions.
+ (ior<mode>3): Add logics for ORI instruction.
+ (*ior<mode>3_mips16_asmacro): Generates ORI instrucion.
+ (*ior<mode>3_mips16): Add logics for XORI instruction.
+ (*xor<mode>3_mips16): Generates XORI instrucion.
+ (*extzv<mode>): Add logics for EXT instruction.
+ (*insv<mode>): Add logics for INS instruction.
+ * config/mips/predicates.md(bit_clear_operand): New predicate for
+ generating bitwise instructions.
+ (and_reg_operand): Add logics for generating bitwise instructions.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.cc(mips_regno_mode_ok_for_base_p): Generate instructions
+ that uses global pointer register.
+ (mips16_unextended_reference_p): Same as above.
+ (mips_pic_base_register): Same as above.
+ (mips_init_relocs): Same as above.
+ * config/mips/mips.h(MIPS16_GP_LOADS): Defined a new macro.
+ (GLOBAL_POINTER_REGNUM): Moved to machine description `mips.md`.
+ * config/mips/mips.md(GLOBAL_POINTER_REGNUM): Moved to here from above.
+ (*lowsi_mips16_gp):New `define_insn *low<mode>_mips16`.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.h(ISA_HAS_CONDMOVE): Add condition for ISA_HAS_MIPS16E2.
+ * config/mips/mips.md(*mov<GPR:mode>_on_<MOVECC:mode>): Add logics for MOVx insts.
+ (*mov<GPR:mode>_on_<MOVECC:mode>_mips16e2): Generate MOVx instruction.
+ (*mov<GPR:mode>_on_<GPR2:mode>_ne): Add logics for MOVx insts.
+ (*mov<GPR:mode>_on_<GPR2:mode>_ne_mips16e2): Generate MOVx instruction.
+ * config/mips/predicates.md(reg_or_0_operand_mips16e2): New predicate for MOVx insts.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * config/mips/mips.cc(mips_file_start): Add mips16e2 info
+ for output file.
+ * config/mips/mips.h(__mips_mips16e2): Defined a new
+ predefine macro.
+ (ISA_HAS_MIPS16E2): Defined a new macro.
+ (ASM_SPEC): Pass mmips16e2 to the assembler.
+ * config/mips/mips.opt: Add -m(no-)mips16e2 option.
+ * config/mips/predicates.md: Add clause for TARGET_MIPS16E2.
+ * doc/invoke.texi: Add -m(no-)mips16e2 option..
+
+2023-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/110508
+ * tree-ssa-math-opts.cc (match_uaddc_usubc): Only replace re2 with
+ REALPART_EXPR opf nlhs if re2 is non-NULL.
+
+2023-07-02 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
+
+ * config/xtensa/xtensa.cc (xtensa_match_CLAMPS_imms_p):
+ Simplify.
+ * config/xtensa/xtensa.md (*xtensa_clamps):
+ Add TARGET_MINMAX to the condition.
+
+2023-07-02 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
+
+ * config/xtensa/xtensa.md (*eqne_INT_MIN):
+ Add missing ":SI" to the match_operator.
+
+2023-07-02 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR target/108743
+ * config/darwin.opt: Add fconstant-cfstrings alias to
+ mconstant-cfstrings.
+ * doc/invoke.texi: Amend invocation descriptions to reflect
+ that the fconstant-cfstrings is a target-option alias and to
+ add the missing mconstant-cfstrings option description to the
+ Darwin section.
+
+2023-07-01 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.cc (gimple_duplicate_sese_region): Add elliminated_edge
+ parmaeter; update profile.
+ * tree-cfg.h (gimple_duplicate_sese_region): Update prototype.
+ * tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Rename to ...
+ (static_loop_exit): ... this; return the edge to be elliminated.
+ (ch_base::copy_headers): Handle profile updating for eliminated exits.
+
+2023-07-01 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/i386/i386-features.cc (compute_convert_gain): Provide
+ gains/costs for ROTATE and ROTATERT (by an integer constant).
+ (general_scalar_chain::convert_rotate): New helper function to
+ convert a DImode or SImode rotation by an integer constant into
+ SSE vector form.
+ (general_scalar_chain::convert_insn): Call the new convert_rotate
+ for ROTATE and ROTATERT.
+ (general_scalar_to_vector_candidate_p): Consider ROTATE and
+ ROTATERT to be candidates if the second operand is an integer
+ constant, valid for a rotation (or shift) in the given mode.
+ * config/i386/i386-features.h (general_scalar_chain): Add new
+ helper method convert_rotate.
+
+2023-07-01 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/103680
+ * cfg.cc (update_bb_profile_for_threading): Fix profile update;
+ make message clearer.
+
+2023-06-30 Qing Zhao <qing.zhao@oracle.com>
+
+ PR tree-optimization/101832
+ * tree-object-size.cc (addr_object_size): Handle structure/union type
+ when it has flexible size.
+
+2023-06-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gimple-fold.cc (fold_array_ctor_reference): Fix head comment.
+ (fold_nonarray_ctor_reference): Likewise. Specifically deal
+ with integral bit-fields.
+ (fold_ctor_reference): Make sure that the constructor uses the
+ native storage order.
+
+2023-06-30 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/109849
+ * predict.cc (estimate_bb_frequencies): Turn to static function.
+ (expr_expected_value_1): Fix handling of binary expressions with
+ predicted values.
+ * predict.def (PRED_MALLOC_NONNULL): Move later in the priority queue.
+ (PRED_BUILTIN_EXPECT_WITH_PROBABILITY): Move to almost top of the priority
+ queue.
+ * predict.h (estimate_bb_frequencies): No longer declare it.
+
+2023-06-30 Uros Bizjak <ubizjak@gmail.com>
+
+ * fold-const.h (multiple_of_p): Change return type from int to bool.
+ * fold-const.cc (split_tree): Change negl_p, neg_litp_p,
+ neg_conp_p and neg_var_p variables to bool.
+ (const_binop): Change sat_p variable to bool.
+ (merge_ranges): Change no_overlap variable to bool.
+ (extract_muldiv_1): Change same_p variable to bool.
+ (tree_swap_operands_p): Update function body for bool return type.
+ (fold_truth_andor): Change commutative variable to bool.
+ (multiple_of_p): Change return type
+ from int to void and adjust function body accordingly.
+ * optabs.h (expand_twoval_unop): Change return type from int to bool.
+ (expand_twoval_binop): Ditto.
+ (can_compare_p): Ditto.
+ (have_add2_insn): Ditto.
+ (have_addptr3_insn): Ditto.
+ (have_sub2_insn): Ditto.
+ (have_insn_for): Ditto.
+ * optabs.cc (add_equal_note): Ditto.
+ (widen_operand): Change no_extend argument from int to bool.
+ (expand_binop): Ditto.
+ (expand_twoval_unop): Change return type
+ from int to void and adjust function body accordingly.
+ (expand_twoval_binop): Ditto.
+ (can_compare_p): Ditto.
+ (have_add2_insn): Ditto.
+ (have_addptr3_insn): Ditto.
+ (have_sub2_insn): Ditto.
+ (have_insn_for): Ditto.
+
+2023-06-30 Oluwatamilore Adebayo <oluwatamilore.adebayo@arm.com>
+
+ * config/aarch64/aarch64-simd.md
+ (vec_widen_<su>abdl_lo_<mode>, vec_widen_<su>abdl_hi_<mode>):
+ Expansions for abd vec widen optabs.
+ (aarch64_<su>abdl<mode>_insn): VQW based abdl RTL.
+ * config/aarch64/iterators.md (USMAX_EXT): Code attributes
+ that give the appropriate extend RTL for the max RTL.
+
+2023-06-30 Oluwatamilore Adebayo <oluwatamilore.adebayo@arm.com>
+
+ * internal-fn.def (VEC_WIDEN_ABD): New internal hilo optab.
+ * optabs.def (vec_widen_sabd_optab,
+ vec_widen_sabd_hi_optab, vec_widen_sabd_lo_optab,
+ vec_widen_sabd_odd_even, vec_widen_sabd_even_optab,
+ vec_widen_uabd_optab,
+ vec_widen_uabd_hi_optab, vec_widen_uabd_lo_optab,
+ vec_widen_uabd_odd_even, vec_widen_uabd_even_optab):
+ New optabs.
+ * doc/md.texi: Document them.
+ * tree-vect-patterns.cc (vect_recog_abd_pattern): Update to
+ to build a VEC_WIDEN_ABD call if the input precision is smaller
+ than the precision of the output.
+ (vect_recog_widen_abd_pattern): Should an ABD expression be
+ found preceeding an extension, replace the two with a
+ VEC_WIDEN_ABD.
+
+2023-06-30 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/vector.md: Refactor the common condition.
+
+2023-06-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110496
+ * gimple-ssa-store-merging.cc (find_bswap_or_nop_1): Re-order
+ verifying and TYPE_PRECISION query for the BIT_FIELD_REF case.
+
+2023-06-30 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/110489
+ * statistics.cc (curr_statistics_hash): Add argument
+ indicating whether we should allocate the hash.
+ (statistics_fini_pass): If the hash isn't allocated
+ only print the summary header.
+
+2023-06-30 Segher Boessenkool <segher@kernel.crashing.org>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * config/nvptx/nvptx.cc (TARGET_LRA_P): Remove.
+
+2023-06-30 Jovan Dmitrović <jovan.dmitrovic@syrmia.com>
+
+ PR target/109435
+ * config/mips/mips.cc (mips_function_arg_alignment): Returns
+ the alignment of function argument. In case of typedef type,
+ it returns the aligment of the aliased type.
+ (mips_function_arg_boundary): Relocated calculation of the
+ aligment of function arguments.
+
+2023-06-29 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/109849
+ * ipa-fnsummary.cc (decompose_param_expr): Skip
+ functions returning its parameter.
+ (set_cond_stmt_execution_predicate): Return early
+ if predicate was constructed.
+
+2023-06-29 Qing Zhao <qing.zhao@oracle.com>
+
+ PR c/77650
+ * doc/extend.texi: Document GCC extension on a structure containing
+ a flexible array member to be a member of another structure.
+
+2023-06-29 Qing Zhao <qing.zhao@oracle.com>
+
+ * print-tree.cc (print_node): Print new bit type_include_flexarray.
+ * tree-core.h (struct tree_type_common): Use bit no_named_args_stdarg_p
+ as type_include_flexarray for RECORD_TYPE or UNION_TYPE.
+ * tree-streamer-in.cc (unpack_ts_type_common_value_fields): Stream
+ in bit no_named_args_stdarg_p properly for its corresponding type.
+ * tree-streamer-out.cc (pack_ts_type_common_value_fields): Stream
+ out bit no_named_args_stdarg_p properly for its corresponding type.
+ * tree.h (TYPE_INCLUDES_FLEXARRAY): New macro TYPE_INCLUDES_FLEXARRAY.
+
+2023-06-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.cc (maybe_set_nonzero_bits): Move from here...
+ * tree-ssa-dom.cc (maybe_set_nonzero_bits): ...to here.
+ * tree-vrp.h (maybe_set_nonzero_bits): Remove.
+
+2023-06-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (frange::set): Do not call verify_range.
+ (frange::normalize_kind): Verify range.
+ (frange::union_nans): Do not call verify_range.
+ (frange::union_): Same.
+ (frange::intersect): Same.
+ (irange::irange_single_pair_union): Call normalize_kind if
+ necessary.
+ (irange::union_): Same.
+ (irange::intersect): Same.
+ (irange::set_range_from_nonzero_bits): Verify range.
+ (irange::set_nonzero_bits): Call normalize_kind if necessary.
+ (irange::get_nonzero_bits): Tweak comment.
+ (irange::intersect_nonzero_bits): Call normalize_kind if
+ necessary.
+ (irange::union_nonzero_bits): Same.
+ * value-range.h (irange::normalize_kind): Verify range.
+
+2023-06-29 Uros Bizjak <ubizjak@gmail.com>
+
+ * cselib.h (rtx_equal_for_cselib_1):
+ Change return type from int to bool.
+ (references_value_p): Ditto.
+ (rtx_equal_for_cselib_p): Ditto.
+ * expr.h (can_store_by_pieces): Ditto.
+ (try_casesi): Ditto.
+ (try_tablejump): Ditto.
+ (safe_from_p): Ditto.
+ * sbitmap.h (bitmap_equal_p): Ditto.
+ * cselib.cc (references_value_p): Change return type
+ from int to void and adjust function body accordingly.
+ (rtx_equal_for_cselib_1): Ditto.
+ * expr.cc (is_aligning_offset): Ditto.
+ (can_store_by_pieces): Ditto.
+ (mostly_zeros_p): Ditto.
+ (all_zeros_p): Ditto.
+ (safe_from_p): Ditto.
+ (is_aligning_offset): Ditto.
+ (try_casesi): Ditto.
+ (try_tablejump): Ditto.
+ (store_constructor): Change "need_to_clear" and
+ "const_bounds_p" variables to bool.
+ * sbitmap.cc (bitmap_equal_p): Change return type from int to bool.
+
+2023-06-29 Robin Dapp <rdapp@ventanamicro.com>
+
+ * tree-ssa-math-opts.cc (divmod_candidate_p): Use
+ element_precision.
+
+2023-06-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110460
+ * tree-vect-stmts.cc (get_related_vectype_for_scalar_type):
+ Only allow integral, pointer and scalar float type scalar_type.
+
+2023-06-29 Lili Cui <lili.cui@intel.com>
+
+ PR tree-optimization/110148
+ * tree-ssa-reassoc.cc (rewrite_expr_tree_parallel): Handle loop-carried
+ ops in this function.
+
+2023-06-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/110452
+ * expr.cc (store_constructor): Handle uniform boolean
+ vectors with integer mode specially.
+
+2023-06-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/110461
+ * match.pd (bitop (convert@2 @0) (convert?@3 @1)): Disable
+ for VECTOR_TYPE_P.
+
+2023-06-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * vec.h (gt_pch_nx): Add overloads for va_gc_atomic.
+ (array_slice): Relax va_gc constructor to handle all vectors
+ with a vl_embed layout.
+
+2023-06-29 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/riscv.cc (riscv_emit_mode_set): Add emit for FRM.
+ (riscv_mode_needed): Likewise.
+ (riscv_entity_mode_after): Likewise.
+ (riscv_mode_after): Likewise.
+ (riscv_mode_entry): Likewise.
+ (riscv_mode_exit): Likewise.
+ * config/riscv/riscv.h (NUM_MODES_FOR_MODE_SWITCHING): Add number
+ for FRM.
+ * config/riscv/riscv.md: Add FRM register.
+ * config/riscv/vector-iterators.md: Add FRM type.
+ * config/riscv/vector.md (frm_mode): Define new attr for FRM mode.
+ (fsrm): Define new insn for fsrm instruction.
+
+2023-06-29 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/riscv-protos.h (enum floating_point_rounding_mode):
+ Add macro for static frm min and max.
+ * config/riscv/riscv-vector-builtins-bases.cc
+ (class binop_frm): New class for floating-point with frm.
+ (BASE): Add vfadd for frm.
+ * config/riscv/riscv-vector-builtins-bases.h: Likewise.
+ * config/riscv/riscv-vector-builtins-functions.def
+ (vfadd_frm): Likewise.
+ * config/riscv/riscv-vector-builtins-shapes.cc
+ (struct alu_frm_def): New struct for alu with frm.
+ (SHAPE): Add alu with frm.
+ * config/riscv/riscv-vector-builtins-shapes.h: Likewise.
+ * config/riscv/riscv-vector-builtins.cc
+ (function_checker::report_out_of_range_and_not): New function
+ for report out of range and not val.
+ (function_checker::require_immediate_range_or): New function
+ for checking in range or one val.
+ * config/riscv/riscv-vector-builtins.h: Add function decl.
+
+2023-06-29 Cui, Lili <lili.cui@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_intel_cpu): Remove model value 0xa8
+ from Rocketlake, move model value 0xbf from Alderlake to Raptorlake.
+
+2023-06-28 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/110144
+ * config/cris/cris.cc (cris_postdbr_cmpelim): Don't apply PATTERN
+ to insn before validating it.
+
+2023-06-28 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/110334
+ * ipa-fnsummary.h (ipa_fn_summary): Add
+ safe_to_inline_to_always_inline.
+ * ipa-inline.cc (can_early_inline_edge_p): ICE
+ if SSA is not built; do cycle checking for
+ always_inline functions.
+ (inline_always_inline_functions): Be recrusive;
+ watch for cycles; do not updat overall summary.
+ (early_inliner): Do not give up on always_inlines.
+ * ipa-utils.cc (ipa_reverse_postorder): Do not skip
+ always inlines.
+
+2023-06-28 Uros Bizjak <ubizjak@gmail.com>
+
+ * output.h (leaf_function_p): Change return type from int to bool.
+ (final_forward_branch_p): Ditto.
+ (only_leaf_regs_used): Ditto.
+ (maybe_assemble_visibility): Ditto.
+ * varasm.h (supports_one_only): Ditto.
+ * rtl.h (compute_alignments): Change return type from int to void.
+ * final.cc (app_on): Change return type from int to bool.
+ (compute_alignments): Change return type from int to void
+ and adjust function body accordingly.
+ (shorten_branches): Change "something_changed" variable
+ type from int to bool.
+ (leaf_function_p): Change return type from int to bool
+ and adjust function body accordingly.
+ (final_forward_branch_p): Ditto.
+ (only_leaf_regs_used): Ditto.
+ * varasm.cc (contains_pointers_p): Change return type from
+ int to bool and adjust function body accordingly.
+ (compare_constant): Ditto.
+ (maybe_assemble_visibility): Ditto.
+ (supports_one_only): Ditto.
+
+2023-06-28 Manolis Tsamis <manolis.tsamis@vrull.eu>
+
+ PR debug/110308
+ * regcprop.cc (maybe_mode_change): Check stack_pointer_rtx mode.
+ (maybe_copy_reg_attrs): New function.
+ (find_oldest_value_reg): Use maybe_copy_reg_attrs.
+ (copyprop_hardreg_forward_1): Ditto.
+
+2023-06-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110434
+ * tree-nrv.cc (pass_nrv::execute): Remove CLOBBERs of
+ VAR we replace with <retval>.
+
+2023-06-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110451
+ * tree-ssa-loop-im.cc (stmt_cost): [VEC_]COND_EXPR and
+ tcc_comparison are expensive.
+
+2023-06-28 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/i386/i386-expand.cc (ix86_expand_branch): Also use ptest
+ for TImode comparisons on 32-bit architectures.
+ * config/i386/i386.md (cbranch<mode>4): Change from SDWIM to
+ SWIM1248x to exclude/avoid TImode being conditional on -m64.
+ (cbranchti4): New define_expand for TImode on both TARGET_64BIT
+ and/or with TARGET_SSE4_1.
+ * config/i386/predicates.md (ix86_timode_comparison_operator):
+ New predicate that depends upon TARGET_64BIT.
+ (ix86_timode_comparison_operand): Likewise.
+
+2023-06-28 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR target/78794
+ * config/i386/i386-features.cc (compute_convert_gain): Provide
+ more accurate gains for conversion of scalar comparisons to
+ PTEST.
+
+2023-06-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110443
+ * tree-vect-slp.cc (vect_build_slp_tree_1): Reject non-grouped
+ gather loads.
+
+2023-06-28 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * config/rs6000/rs6000.md (peephole2 for compare_and_move): New.
+ (peephole2 for move_and_compare): New.
+ (mode_iterator WORD): New. Set the mode to SI/DImode by
+ TARGET_POWERPC64.
+ (*mov<mode>_internal2): Change the mode iterator from P to WORD.
+ (split pattern for compare_and_move): Likewise.
+
+2023-06-28 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec-opt.md (*double_widen_fma<mode>): New pattern.
+ (*single_widen_fma<mode>): Ditto.
+
+2023-06-28 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ PR target/104124
+ * config/rs6000/altivec.md (*altivec_vupkhs<VU_char>_direct): Rename
+ to...
+ (altivec_vupkhs<VU_char>_direct): ...this.
+ * config/rs6000/predicates.md (vspltisw_vupkhsw_constant_split): New
+ predicate to test if a constant can be loaded with vspltisw and
+ vupkhsw.
+ (easy_vector_constant): Call vspltisw_vupkhsw_constant_p to Check if
+ a vector constant can be synthesized with a vspltisw and a vupkhsw.
+ * config/rs6000/rs6000-protos.h (vspltisw_vupkhsw_constant_p):
+ Declare.
+ * config/rs6000/rs6000.cc (vspltisw_vupkhsw_constant_p): New
+ function to return true if OP mode is V2DI and can be synthesized
+ with vupkhsw and vspltisw.
+ * config/rs6000/vsx.md (*vspltisw_v2di_split): New insn to load up
+ constants with vspltisw and vupkhsw.
+
+2023-06-28 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/110377
+ * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Pass statement to
+ the ranger query.
+ (ipa_analyze_node): Enable ranger.
+
+2023-06-28 Richard Biener <rguenther@suse.de>
+
+ * tree.h (TYPE_PRECISION): Check for non-VECTOR_TYPE.
+ (TYPE_PRECISION_RAW): Provide raw access to the precision
+ field.
+ * tree.cc (verify_type_variant): Compare TYPE_PRECISION_RAW.
+ (gimple_canonical_types_compatible_p): Likewise.
+ * tree-streamer-out.cc (pack_ts_type_common_value_fields):
+ Stream TYPE_PRECISION_RAW.
+ * tree-streamer-in.cc (unpack_ts_type_common_value_fields):
+ Likewise.
+ * lto-streamer-out.cc (hash_tree): Hash TYPE_PRECISION_RAW.
+
+2023-06-28 Alexandre Oliva <oliva@adacore.com>
+
+ * doc/extend.texi (zero-call-used-regs): Document leafy and
+ variants thereof.
+ * flag-types.h (zero_regs_flags): Add LEAFY_MODE, as well as
+ LEAFY and variants.
+ * function.cc (gen_call_ued_regs_seq): Set only_used for leaf
+ functions in leafy mode.
+ * opts.cc (zero_call_used_regs_opts): Add leafy and variants.
+
+2023-06-28 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-vector-builtins-bases.cc: Adapt expand.
+ * config/riscv/vector.md (@pred_single_widen_<plus_minus:optab><mode>):
+ Remove.
+ (@pred_single_widen_add<mode>): New pattern.
+ (@pred_single_widen_sub<mode>): New pattern.
+
+2023-06-28 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/i386.cc (ix86_invalid_conversion): New function.
+ (TARGET_INVALID_CONVERSION): Define as
+ ix86_invalid_conversion.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md (<optab><vnconvert><mode>2): New
+ expander.
+ (<float_cvt><vnconvert><mode>2): Ditto.
+ (<optab><mode><vnconvert>2): Ditto.
+ (<float_cvt><mode><vnconvert>2): Ditto.
+ * config/riscv/vector-iterators.md: Add vnconvert.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md (extend<v_double_trunc><mode>2): New
+ expander.
+ (extend<v_quad_trunc><mode>2): Ditto.
+ (trunc<mode><v_double_trunc>2): Ditto.
+ (trunc<mode><v_quad_trunc>2): Ditto.
+ * config/riscv/vector-iterators.md: Add VQEXTF and HF to
+ V_QUAD_TRUNC and v_quad_trunc.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md (<float_cvt><vconvert><mode>2): New
+ expander.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md (copysign<mode>3): Add expander.
+ (xorsign<mode>3): Ditto.
+ * config/riscv/riscv-vector-builtins-bases.cc (class vfsgnjn):
+ New class.
+ * config/riscv/vector-iterators.md (copysign): Remove ncopysign.
+ (xorsign): Ditto.
+ (n): Ditto.
+ (x): Ditto.
+ * config/riscv/vector.md (@pred_ncopysign<mode>): Split off.
+ (@pred_ncopysign<mode>_scalar): Ditto.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md: VF_AUTO -> VF.
+ * config/riscv/vector-iterators.md: Introduce VF_ZVFHMIN,
+ VWEXTF_ZVFHMIN and use TARGET_ZVFH in VWCONVERTI, VHF and
+ VHF_LMUL1.
+ * config/riscv/vector.md: Use new iterators.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * match.pd: Use element_mode and check if target supports
+ operation with new type.
+
+2023-06-27 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svdupq_impl::fold_nonconst_dupq): New method.
+ (svdupq_impl::fold): Call fold_nonconst_dupq.
+
+2023-06-27 Andrew Pinski <apinski@marvell.com>
+
+ PR middle-end/110420
+ PR middle-end/103979
+ PR middle-end/98619
+ * gimplify.cc (gimplify_asm_expr): Mark asm with labels as volatile.
+
+2023-06-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * ipa-cp.cc (decide_whether_version_node): Adjust comment.
+ * ipa-fnsummary.cc (evaluate_conditions_for_known_args): Adjust
+ for Value_Range.
+ (set_switch_stmt_execution_predicate): Same.
+ * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Same.
+
+2023-06-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * ipa-prop.cc (struct ipa_vr_ggc_hash_traits): Adjust for use with
+ ipa_vr instead of value_range.
+ (gt_pch_nx): Same.
+ (gt_ggc_mx): Same.
+ (ipa_get_value_range): Same.
+ * value-range.cc (gt_pch_nx): Move to ipa-prop.cc and adjust for
+ ipa_vr.
+ (gt_ggc_mx): Same.
+
+2023-06-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * ipa-cp.cc (ipa_vr_operation_and_type_effects): New.
+ * ipa-prop.cc (ipa_get_value_range): Adjust for ipa_vr.
+ (ipa_set_jfunc_vr): Take a range.
+ (ipa_compute_jump_functions_for_edge): Pass range to
+ ipa_set_jfunc_vr.
+ (ipa_write_jump_function): Call streamer write helper.
+ (ipa_read_jump_function): Call streamer read helper.
+ * ipa-prop.h (class ipa_vr): Change m_vr to an ipa_vr.
+
+2023-06-27 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gengtype-parse.cc (consume_until_comma_or_eos): Parse "= { ... }"
+ as a probable initializer rather than a probable complete statement.
+
+2023-06-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/96208
+ * tree-vect-slp.cc (vect_build_slp_tree_1): Allow
+ a non-grouped load if it is the same for all lanes.
+ (vect_build_slp_tree_2): Handle not grouped loads.
+ (vect_optimize_slp_pass::remove_redundant_permutations):
+ Likewise.
+ (vect_transform_slp_perm_load_1): Likewise.
+ * tree-vect-stmts.cc (vect_model_load_cost): Likewise.
+ (get_group_load_store_type): Likewise. Handle
+ invariant accesses.
+ (vectorizable_load): Likewise.
+
+2023-06-27 liuhongt <hongtao.liu@intel.com>
+
+ PR rtl-optimization/110237
+ * config/i386/sse.md (<avx512>_store<mode>_mask): Refine with
+ UNSPEC_MASKMOV.
+ (maskstore<mode><avx512fmaskmodelower): Ditto.
+ (*<avx512>_store<mode>_mask): New define_insn, it's renamed
+ from original <avx512>_store<mode>_mask.
+
+2023-06-27 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/i386-features.cc (pass_insert_vzeroupper:gate):
+ Move flag_expensive_optimizations && !optimize_size to ..
+ * config/i386/i386-options.cc (ix86_option_override_internal):
+ .. this, it makes -mvzeroupper independent of optimization
+ level, but still keeps the behavior of architecture
+ tuning(emit_vzeroupper) unchanged.
+
+2023-06-27 liuhongt <hongtao.liu@intel.com>
+
+ PR target/82735
+ * config/i386/i386.cc (ix86_avx_u127_mode_needed): Don't emit
+ vzeroupper for vzeroupper call_insn.
+
+2023-06-27 Andrew Pinski <apinski@marvell.com>
+
+ * doc/extend.texi (__builtin_alloca_with_align_and_max): Fix
+ defbuiltin usage.
+
+2023-06-27 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-v.cc (expand_const_vector): Fix stepped vector
+ with base != 0.
+
+2023-06-26 Andrew Pinski <apinski@marvell.com>
+
+ * doc/extend.texi (access attribute): Add
+ cindex for it.
+ (interrupt/interrupt_handler attribute):
+ Likewise.
+
+2023-06-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-simd.md (aarch64_sqrshrun_n<mode>_insn):
+ Use <DWI> instead of <V2XWIDE>.
+ (aarch64_sqrshrun_n<mode>): Likewise.
+
+2023-06-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_const_vec_rsra_rnd_imm_p):
+ Rename to...
+ (aarch64_rnd_imm_p): ... This.
+ * config/aarch64/predicates.md (aarch64_simd_rsra_rnd_imm_vec):
+ Rename to...
+ (aarch64_int_rnd_operand): ... This.
+ (aarch64_simd_rshrn_imm_vec): Delete.
+ * config/aarch64/aarch64-simd.md (aarch64_<sra_op>rsra_n<mode>_insn):
+ Adjust for the above.
+ (aarch64_<sra_op>rshr_n<mode><vczle><vczbe>_insn): Likewise.
+ (*aarch64_<shrn_op>rshrn_n<mode>_insn): Likewise.
+ (*aarch64_sqrshrun_n<mode>_insn<vczle><vczbe>): Likewise.
+ (aarch64_sqrshrun_n<mode>_insn): Likewise.
+ (aarch64_<shrn_op>rshrn2_n<mode>_insn_le): Likewise.
+ (aarch64_<shrn_op>rshrn2_n<mode>_insn_be): Likewise.
+ (aarch64_sqrshrun2_n<mode>_insn_le): Likewise.
+ (aarch64_sqrshrun2_n<mode>_insn_be): Likewise.
+ * config/aarch64/aarch64.cc (aarch64_const_vec_rsra_rnd_imm_p):
+ Rename to...
+ (aarch64_rnd_imm_p): ... This.
+
+2023-06-26 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * config/s390/s390.cc (s390_encode_section_info): Set
+ SYMBOL_FLAG_SET_NOTALIGN2 only if the symbol has explicitely been
+ misaligned.
+
+2023-06-26 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/109849
+ * tree-ssa-dce.cc (make_forwarders_with_degenerate_phis): Fix profile
+ count of newly constructed forwarder block.
+
+2023-06-26 Andrew Carlotti <andrew.carlotti@arm.com>
+
+ * doc/optinfo.texi: Fix "steam" -> "stream".
+
+2023-06-26 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Add LEN_MASK_STORE and
+ fix LEN_STORE.
+ (dse_optimize_stmt): Add LEN_MASK_STORE.
+
+2023-06-26 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * gimple-fold.cc (gimple_fold_partial_load_store_mem_ref): Fix gimple
+ fold of LOAD/STORE with length.
+
+2023-06-26 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-gori.cc (compute_operand1_and_operand2_range):
+ Check for interdependence between operands 1 and 2.
+
+2023-06-26 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-vect-stmts.cc (vectorizable_conversion): Take multi_step_cvt
+ into account when costing non-widening/truncating conversions.
+
+2023-06-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110381
+ * tree-vect-slp.cc (vect_optimize_slp_pass::start_choosing_layouts):
+ Materialize permutes before fold-left reductions.
+
+2023-06-26 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/riscv-vector-builtins-bases.h: Remove duplicated decl.
+
+2023-06-26 Richard Biener <rguenther@suse.de>
+
+ * varasm.cc (initializer_constant_valid_p_1): Also
+ constrain the type of value to be scalar integral
+ before dispatching to narrowing_initializer_constant_valid_p.
+
+2023-06-26 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-scopedtables.cc (hashable_expr_equal_p):
+ Use element_precision.
+
+2023-06-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec.md (vcond<V:mode><VI:mode>): Remove redundant
+ vcond patterns.
+ (vcondu<V:mode><VI:mode>): Ditto.
+ * config/riscv/riscv-protos.h (expand_vcond): Ditto.
+ * config/riscv/riscv-v.cc (expand_vcond): Ditto.
+
+2023-06-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110392
+ * gimple-predicate-analysis.cc (uninit_analysis::is_use_guarded):
+ Do early exits on true/false predicate only after normalization.
+
+2023-06-26 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * tree-ssa-sccvn.cc (vn_reference_lookup_3): Change name "len" into
+ "length".
+
+2023-06-26 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/i386/i386.md (peephole2): Simplify zeroing a register
+ followed by an IOR, XOR or PLUS operation on it, into a move.
+ (*ashl<dwi>3_doubleword_highpart): New define_insn_and_split to
+ eliminate (and hide from reload) unnecessary word to doubleword
+ extensions that are followed by left shifts by sufficiently large,
+ but valid, bit counts.
+
+2023-06-26 liuhongt <hongtao.liu@intel.com>
+
+ PR tree-optimization/110371
+ PR tree-optimization/110018
+ * tree-vect-stmts.cc (vectorizable_conversion): Use cvt_op to
+ save intermediate type operand instead of "subtle" vec_dest
+ for case NONE.
+
+2023-06-26 liuhongt <hongtao.liu@intel.com>
+
+ PR tree-optimization/110371
+ PR tree-optimization/110018
+ * tree-vect-stmts.cc (vectorizable_conversion): Don't use
+ intermiediate type for FIX_TRUNC_EXPR when ftrapping-math.
+
+2023-06-26 Hongyu Wang <hongyu.wang@intel.com>
+
+ * config/i386/i386-options.cc (ix86_valid_target_attribute_tree):
+ Override tune_string with arch_string if tune_string is not
+ explicitly specified.
+
+2023-06-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-vsetvl.cc (vector_insn_info::parse_insn): Ehance
+ AVL propagation.
+ * config/riscv/riscv-vsetvl.h: New function.
+
+2023-06-25 Li Xu <xuli1@eswincomputing.com>
+
+ * config/riscv/riscv-vector-builtins-bases.cc: change emit_insn to
+ emit_move_insn
+
+2023-06-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec.md (len_load_<mode>): Remove.
+ (len_maskload<mode><vm>): Remove.
+ (len_store_<mode>): New pattern.
+ (len_maskstore<mode><vm>): New pattern.
+ * config/riscv/predicates.md (autovec_length_operand): New predicate.
+ * config/riscv/riscv-protos.h (enum insn_type): New enum.
+ (expand_load_store): New function.
+ * config/riscv/riscv-v.cc (emit_vlmax_masked_insn): Ditto.
+ (emit_nonvlmax_masked_insn): Ditto.
+ (expand_load_store): Ditto.
+ * config/riscv/riscv-vector-builtins.cc
+ (function_expander::use_contiguous_store_insn): Add avl_type operand
+ into pred_store.
+ * config/riscv/vector.md: Ditto.
+
+2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * internal-fn.cc (expand_partial_store_optab_fn): Fix bug of BIAS
+ argument index.
+
+2023-06-25 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/vector.md: Revert.
+
+2023-06-25 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/genrvv-type-indexer.cc (valid_type): Revert changes.
+ * config/riscv/riscv-modes.def (RVV_TUPLE_MODES): Ditto.
+ (ADJUST_ALIGNMENT): Ditto.
+ (RVV_TUPLE_PARTIAL_MODES): Ditto.
+ (ADJUST_NUNITS): Ditto.
+ * config/riscv/riscv-vector-builtins-types.def (vfloat16mf4x2_t): Ditto.
+ (vfloat16mf4x3_t): Ditto.
+ (vfloat16mf4x4_t): Ditto.
+ (vfloat16mf4x5_t): Ditto.
+ (vfloat16mf4x6_t): Ditto.
+ (vfloat16mf4x7_t): Ditto.
+ (vfloat16mf4x8_t): Ditto.
+ (vfloat16mf2x2_t): Ditto.
+ (vfloat16mf2x3_t): Ditto.
+ (vfloat16mf2x4_t): Ditto.
+ (vfloat16mf2x5_t): Ditto.
+ (vfloat16mf2x6_t): Ditto.
+ (vfloat16mf2x7_t): Ditto.
+ (vfloat16mf2x8_t): Ditto.
+ (vfloat16m1x2_t): Ditto.
+ (vfloat16m1x3_t): Ditto.
+ (vfloat16m1x4_t): Ditto.
+ (vfloat16m1x5_t): Ditto.
+ (vfloat16m1x6_t): Ditto.
+ (vfloat16m1x7_t): Ditto.
+ (vfloat16m1x8_t): Ditto.
+ (vfloat16m2x2_t): Ditto.
+ (vfloat16m2x3_t): Diito.
+ (vfloat16m2x4_t): Diito.
+ (vfloat16m4x2_t): Diito.
+ * config/riscv/riscv-vector-builtins.def (vfloat16mf4x2_t): Ditto.
+ (vfloat16mf4x3_t): Ditto.
+ (vfloat16mf4x4_t): Ditto.
+ (vfloat16mf4x5_t): Ditto.
+ (vfloat16mf4x6_t): Ditto.
+ (vfloat16mf4x7_t): Ditto.
+ (vfloat16mf4x8_t): Ditto.
+ (vfloat16mf2x2_t): Ditto.
+ (vfloat16mf2x3_t): Ditto.
+ (vfloat16mf2x4_t): Ditto.
+ (vfloat16mf2x5_t): Ditto.
+ (vfloat16mf2x6_t): Ditto.
+ (vfloat16mf2x7_t): Ditto.
+ (vfloat16mf2x8_t): Ditto.
+ (vfloat16m1x2_t): Ditto.
+ (vfloat16m1x3_t): Ditto.
+ (vfloat16m1x4_t): Ditto.
+ (vfloat16m1x5_t): Ditto.
+ (vfloat16m1x6_t): Ditto.
+ (vfloat16m1x7_t): Ditto.
+ (vfloat16m1x8_t): Ditto.
+ (vfloat16m2x2_t): Ditto.
+ (vfloat16m2x3_t): Ditto.
+ (vfloat16m2x4_t): Ditto.
+ (vfloat16m4x2_t): Ditto.
+ * config/riscv/riscv-vector-switch.def (TUPLE_ENTRY): Ditto.
+ * config/riscv/riscv.md: Ditto.
+ * config/riscv/vector-iterators.md: Ditto.
+
+2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * gimple-fold.cc (arith_overflowed_p): Apply LEN_MASK_{LOAD,STORE}.
+ (gimple_fold_partial_load_store_mem_ref): Ditto.
+ (gimple_fold_partial_store): Ditto.
+ (gimple_fold_call): Ditto.
+
+2023-06-25 liuhongt <hongtao.liu@intel.com>
+
+ PR target/110309
+ * config/i386/sse.md (maskload<mode><avx512fmaskmodelower>):
+ Refine pattern with UNSPEC_MASKLOAD.
+ (maskload<mode><avx512fmaskmodelower>): Ditto.
+ (*<avx512>_load<mode>_mask): Extend mode iterator to
+ VI12HFBF_AVX512VL.
+ (*<avx512>_load<mode>): Ditto.
+
+2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * tree-ssa-alias.cc (call_may_clobber_ref_p_1): Add LEN_MASK_STORE.
+
+2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * tree-ssa-alias.cc (ref_maybe_used_by_call_p_1): Apply
+ LEN_MASK_{LOAD,STORE}
+
+2023-06-25 yulong <shiyulong@iscas.ac.cn>
+
+ * config/riscv/vector.md: Add float16 attr at sew、vlmul and ratio.
+
+2023-06-24 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/i386/i386.md (*<code>qi_ext<mode>_3): New define_insn.
+
+2023-06-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec.md (*fma<mode>): set clobber to Pmode in expand stage.
+ (*fma<VI:mode><P:mode>): Ditto.
+ (*fnma<mode>): Ditto.
+ (*fnma<VI:mode><P:mode>): Ditto.
+
+2023-06-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/autovec.md (fma<mode>4): New pattern.
+ (*fma<mode>): Ditto.
+ (fnma<mode>4): Ditto.
+ (*fnma<mode>): Ditto.
+ (fms<mode>4): Ditto.
+ (*fms<mode>): Ditto.
+ (fnms<mode>4): Ditto.
+ (*fnms<mode>): Ditto.
+ * config/riscv/riscv-protos.h (emit_vlmax_fp_ternary_insn):
+ New function.
+ * config/riscv/riscv-v.cc (emit_vlmax_fp_ternary_insn): Ditto.
+ * config/riscv/vector.md: Fix attribute bug.
+
+2023-06-24 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * tree-ssa-loop-ivopts.cc (get_mem_type_for_internal_fn):
+ Apply LEN_MASK_{LOAD,STORE}.
+
+2023-06-24 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * tree-ssa-loop-ivopts.cc (get_alias_ptr_type_for_ptr_address):
+ Add LEN_MASK_{LOAD,STORE}.
+
+2023-06-24 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic-format-sarif.cc: Add #define INCLUDE_VECTOR.
+ * diagnostic.cc: Likewise.
+ * text-art/box-drawing.cc: Likewise.
+ * text-art/canvas.cc: Likewise.
+ * text-art/ruler.cc: Likewise.
+ * text-art/selftests.cc: Likewise.
+ * text-art/selftests.h (text_art::canvas): New forward decl.
+ * text-art/style.cc: Add #define INCLUDE_VECTOR.
+ * text-art/styled-string.cc: Likewise.
+ * text-art/table.cc: Likewise.
+ * text-art/table.h: Remove #include <vector>.
+ * text-art/theme.cc: Add #define INCLUDE_VECTOR.
+ * text-art/types.h: Check that INCLUDE_VECTOR is defined.
+ Remove #include of <vector> and <string>.
+ * text-art/widget.cc: Add #define INCLUDE_VECTOR.
+ * text-art/widget.h: Remove #include <vector>.
+
+2023-06-24 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * internal-fn.cc (expand_partial_store_optab_fn): Adapt for LEN_MASK_STORE.
+ (internal_load_fn_p): Add LEN_MASK_LOAD.
+ (internal_store_fn_p): Add LEN_MASK_STORE.
+ (internal_fn_mask_index): Add LEN_MASK_{LOAD,STORE}.
+ (internal_fn_stored_value_index): Add LEN_MASK_STORE.
+ (internal_len_load_store_bias): Add LEN_MASK_{LOAD,STORE}.
+ * optabs-tree.cc (can_vec_mask_load_store_p): Adapt for LEN_MASK_{LOAD,STORE}.
+ (get_len_load_store_mode): Ditto.
+ * optabs-tree.h (can_vec_mask_load_store_p): Ditto.
+ (get_len_load_store_mode): Ditto.
+ * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Ditto.
+ (get_all_ones_mask): New function.
+ (vectorizable_store): Apply LEN_MASK_{LOAD,STORE} into vectorizer.
+ (vectorizable_load): Ditto.
+
+2023-06-23 Marek Polacek <polacek@redhat.com>
+
+ * doc/cpp.texi (__cplusplus): Document value for -std=c++26 and
+ -std=gnu++26. Document that for C++23, its value is 202302L.
+ * doc/invoke.texi: Document -std=c++26 and -std=gnu++26.
+ * dwarf2out.cc (highest_c_language): Handle GNU C++26.
+ (gen_compile_unit_die): Likewise.
+
+2023-06-23 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-phiprop.cc (propagate_with_phi): Compute post dominators on
+ demand.
+ (pass_phiprop::execute): Do not compute it here; return
+ update_ssa_only_virtuals if something changed.
+ (pass_data_phiprop): Remove TODO_update_ssa from todos.
+
+2023-06-23 Michael Meissner <meissner@linux.ibm.com>
+ Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ PR target/105325
+ * config/rs6000/genfusion.pl (gen_ld_cmpi_p10_one): Fix problems that
+ allowed prefixed lwa to be generated.
+ * config/rs6000/fusion.md: Regenerate.
+ * config/rs6000/predicates.md (ds_form_mem_operand): Delete.
+ * config/rs6000/rs6000.md (prefixed attribute): Add support for load
+ plus compare immediate fused insns.
+ (maybe_prefixed): Likewise.
+
+2023-06-23 Roger Sayle <roger@nextmovesoftware.com>
+
+ * simplify-rtx.cc (simplify_subreg): Optimize lowpart SUBREGs
+ of ASHIFT to const0_rtx with sufficiently large shift count.
+ Optimize highpart SUBREGs of ASHIFT as the shift operand when
+ the shift count is the correct offset. Optimize SUBREGs of
+ multi-word logic operations if the SUBREGs of both operands
+ can be simplified.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * varasm.cc (initializer_constant_valid_p_1): Only
+ allow conversions between scalar floating point types.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-stmts.cc (vectorizable_assignment):
+ Properly handle non-integral operands when analyzing
+ conversions.
+
+2023-06-23 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR tree-optimization/110280
+ * match.pd (vec_perm_expr(v, v, mask) -> v): Explicitly build vector
+ using build_vector_from_val with the element of input operand, and
+ mask's type if operand and mask's types don't match.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * fold-const.cc (tree_simple_nonnegative_warnv_p): Guard
+ the truth_value_p case with !VECTOR_TYPE_P.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-patterns.cc (vect_look_through_possible_promotion):
+ Exit early when the type isn't scalar integral.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * match.pd ((outertype)((innertype0)a+(innertype1)b)
+ -> ((newtype)a+(newtype)b)): Use element_precision
+ where appropriate.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * fold-const.cc (fold_binary_loc): Use element_precision
+ when trying (double)float1 CMP (double)float2 to
+ float1 CMP float2 simplification.
+ * match.pd: Likewise.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-stmts.cc (vectorizable_load): Avoid useless
+ copies of VMAT_INVARIANT vectorized stmts, fix SLP support.
+
+2023-06-23 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-stmts.cc (vector_vector_composition_type):
+ Handle composition of a vector from a number of elements that
+ happens to match its number of lanes.
+
+2023-06-22 Marek Polacek <polacek@redhat.com>
+
+ * configure.ac (--enable-host-bind-now): New check. Add
+ -Wl,-z,now to LD_PICFLAG if --enable-host-bind-now.
+ * configure: Regenerate.
+ * doc/install.texi: Document --enable-host-bind-now.
+
+2023-06-22 Di Zhao OS <dizhao@os.amperecomputing.com>
+
+ * config/aarch64/aarch64.cc: Change fma_reassoc_width for ampere1.
+
+2023-06-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110332
+ * tree-ssa-phiprop.cc (propagate_with_phi): Always
+ check aliasing with edge inserted loads.
+
+2023-06-22 Roger Sayle <roger@nextmovesoftware.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386-expand.cc (ix86_expand_sse_ptest): Recognize
+ expansion of ptestc with equal operands as producing const1_rtx.
+ * config/i386/i386.cc (ix86_rtx_costs): Provide accurate cost
+ estimates of UNSPEC_PTEST, where the ptest performs the PAND
+ or PAND of its operands.
+ * config/i386/sse.md (define_split): Transform CCCmode UNSPEC_PTEST
+ of reg_equal_p operands into an x86_stc instruction.
+ (define_split): Split pandn/ptestz/set{n?}e into ptestc/set{n?}c.
+ (define_split): Similar to above for strict_low_part destinations.
+ (define_split): Split pandn/ptestz/j{n?}e into ptestc/j{n?}c.
+
+2023-06-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * Makefile.in (ANALYZER_OBJS): Add analyzer/access-diagram.o.
+ * doc/invoke.texi (Wanalyzer-out-of-bounds): Add description of
+ text art.
+ (fanalyzer-debug-text-art): New.
+
+2023-06-22 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (OBJS-libcommon): Add text-art/box-drawing.o,
+ text-art/canvas.o, text-art/ruler.o, text-art/selftests.o,
+ text-art/style.o, text-art/styled-string.o, text-art/table.o,
+ text-art/theme.o, and text-art/widget.o.
+ * color-macros.h (COLOR_FG_BRIGHT_BLACK): New.
+ (COLOR_FG_BRIGHT_RED): New.
+ (COLOR_FG_BRIGHT_GREEN): New.
+ (COLOR_FG_BRIGHT_YELLOW): New.
+ (COLOR_FG_BRIGHT_BLUE): New.
+ (COLOR_FG_BRIGHT_MAGENTA): New.
+ (COLOR_FG_BRIGHT_CYAN): New.
+ (COLOR_FG_BRIGHT_WHITE): New.
+ (COLOR_BG_BRIGHT_BLACK): New.
+ (COLOR_BG_BRIGHT_RED): New.
+ (COLOR_BG_BRIGHT_GREEN): New.
+ (COLOR_BG_BRIGHT_YELLOW): New.
+ (COLOR_BG_BRIGHT_BLUE): New.
+ (COLOR_BG_BRIGHT_MAGENTA): New.
+ (COLOR_BG_BRIGHT_CYAN): New.
+ (COLOR_BG_BRIGHT_WHITE): New.
+ * common.opt (fdiagnostics-text-art-charset=): New option.
+ (diagnostic-text-art.h): New SourceInclude.
+ (diagnostic_text_art_charset) New Enum and EnumValues.
+ * configure: Regenerate.
+ * configure.ac (gccdepdir): Add text-art to loop.
+ * diagnostic-diagram.h: New file.
+ * diagnostic-format-json.cc (json_emit_diagram): New.
+ (diagnostic_output_format_init_json): Wire it up to
+ context->m_diagrams.m_emission_cb.
+ * diagnostic-format-sarif.cc: Include "diagnostic-diagram.h" and
+ "text-art/canvas.h".
+ (sarif_result::on_nested_diagnostic): Move code to...
+ (sarif_result::add_related_location): ...this new function.
+ (sarif_result::on_diagram): New.
+ (sarif_builder::emit_diagram): New.
+ (sarif_builder::make_message_object_for_diagram): New.
+ (sarif_emit_diagram): New.
+ (diagnostic_output_format_init_sarif): Set
+ context->m_diagrams.m_emission_cb to sarif_emit_diagram.
+ * diagnostic-text-art.h: New file.
+ * diagnostic.cc: Include "diagnostic-text-art.h",
+ "diagnostic-diagram.h", and "text-art/theme.h".
+ (diagnostic_initialize): Initialize context->m_diagrams and
+ call diagnostics_text_art_charset_init.
+ (diagnostic_finish): Clean up context->m_diagrams.m_theme.
+ (diagnostic_emit_diagram): New.
+ (diagnostics_text_art_charset_init): New.
+ * diagnostic.h (text_art::theme): New forward decl.
+ (class diagnostic_diagram): Likewise.
+ (diagnostic_context::m_diagrams): New field.
+ (diagnostic_emit_diagram): New decl.
+ * doc/invoke.texi (Diagnostic Message Formatting Options): Add
+ -fdiagnostics-text-art-charset=.
+ (-fdiagnostics-plain-output): Add
+ -fdiagnostics-text-art-charset=none.
+ * gcc.cc: Include "diagnostic-text-art.h".
+ (driver_handle_option): Handle OPT_fdiagnostics_text_art_charset_.
+ * opts-common.cc (decode_cmdline_options_to_array): Add
+ "-fdiagnostics-text-art-charset=none" to expanded_args for
+ -fdiagnostics-plain-output.
+ * opts.cc: Include "diagnostic-text-art.h".
+ (common_handle_option): Handle OPT_fdiagnostics_text_art_charset_.
+ * pretty-print.cc (pp_unicode_character): New.
+ * pretty-print.h (pp_unicode_character): New decl.
+ * selftest-run-tests.cc: Include "text-art/selftests.h".
+ (selftest::run_tests): Call text_art_tests.
+ * text-art/box-drawing-chars.inc: New file, generated by
+ contrib/unicode/gen-box-drawing-chars.py.
+ * text-art/box-drawing.cc: New file.
+ * text-art/box-drawing.h: New file.
+ * text-art/canvas.cc: New file.
+ * text-art/canvas.h: New file.
+ * text-art/ruler.cc: New file.
+ * text-art/ruler.h: New file.
+ * text-art/selftests.cc: New file.
+ * text-art/selftests.h: New file.
+ * text-art/style.cc: New file.
+ * text-art/styled-string.cc: New file.
+ * text-art/table.cc: New file.
+ * text-art/table.h: New file.
+ * text-art/theme.cc: New file.
+ * text-art/theme.h: New file.
+ * text-art/types.h: New file.
+ * text-art/widget.cc: New file.
+ * text-art/widget.h: New file.
+
2023-06-21 Uros Bizjak <ubizjak@gmail.com>
* function.h (emit_initial_value_sets):
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 2fa3911..31e1a2e 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20230622
+20230705
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 5110f3d..c3f5906 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,150 @@
+2023-07-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch5.adb (Expand_Assign_Array): Adjust comment above the
+ calls to Possible_Bit_Aligned_Component on the LHS and RHS. Do not
+ call Is_Possibly_Unaligned_Slice in the slice case.
+ * exp_util.ads (Component_May_Be_Bit_Aligned): Add For_Slice
+ boolean parameter.
+ (Possible_Bit_Aligned_Component): Likewise.
+ * exp_util.adb (Component_May_Be_Bit_Aligned): Do not return False
+ for the slice of a small record or bit-packed array component.
+ (Possible_Bit_Aligned_Component): Pass For_Slice in recursive
+ calls, except in the slice case where True is passed, as well as
+ in call to Component_May_Be_Bit_Aligned.
+
+2023-07-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.ads (Expand_Unchecked_Union_Equality): Only take a
+ single parameter.
+ * exp_ch4.adb (Expand_Unchecked_Union_Equality): Add guard against
+ repeated invocation on the same node.
+ * exp_ch6.adb (Expand_Call): Only pass a single actual parameter
+ in the call to Expand_Unchecked_Union_Equality.
+
+2023-07-04 Viljar Indus <indus@adacore.com>
+
+ * doc/gnat_rm/standard_and_implementation_defined_restrictions.rst:
+ add No_Use_Of_Attribute & No_Use_Of_Pragma restrictions.
+ * gnat_rm.texi: Regenerate.
+ * gnat_ugn.texi: Regenerate.
+
+2023-07-04 Yannick Moy <moy@adacore.com>
+
+ * sem_disp.adb (Inherited_Subprograms): Add parameter to filter
+ out results.
+ * sem_disp.ads: Likewise.
+
+2023-07-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch3.ads (Build_Variant_Record_Equality): Add Spec_Id as second
+ parameter.
+ * exp_ch3.adb (Build_Variant_Record_Equality): For unchecked union
+ types, build the additional parameters as extra formal parameters.
+ (Expand_Freeze_Record_Type.Build_Variant_Record_Equality): Pass
+ Empty as Spec_Id in call to Build_Variant_Record_Equality.
+ * exp_ch4.ads (Expand_Unchecked_Union_Equality): New procedure.
+ * exp_ch4.adb (Expand_Composite_Equality): In the presence of a
+ function implementing composite equality, do not special case the
+ unchecked union types, and only convert the operands if the base
+ types are not the same like in Build_Equality_Call.
+ (Build_Equality_Call): Do not special case the unchecked union types
+ and relocate the operands only once.
+ (Expand_N_Op_Eq): Do not special case the unchecked union types.
+ (Expand_Unchecked_Union_Equality): New procedure implementing the
+ specific expansion of calls to the predefined equality function.
+ * exp_ch6.adb (Is_Unchecked_Union_Equality): New predicate.
+ (Expand_Call): Call Is_Unchecked_Union_Equality to determine whether
+ to call Expand_Unchecked_Union_Equality or Expand_Call_Helper.
+ * exp_ch8.adb (Build_Body_For_Renaming): Set Has_Delayed_Freeze flag
+ earlier on Id and pass Id in call to Build_Variant_Record_Equality.
+
+2023-07-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch3.adb (Build_Untagged_Equality): Rename into...
+ (Build_Untagged_Record_Equality): ...this.
+ (Expand_Freeze_Record_Type): Adjust to above renaming and invoke
+ the procedure also for discriminated types without a variant part.
+
+2023-07-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_util.adb (Has_Inferable_Discriminants): In the case of a
+ component with a per-object constraint, also return true if the
+ enclosing object is not of an unchecked union type.
+ In the default case, remove a useless call to Base_Type.
+
+2023-06-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc-interface/decl.cc (gt_pch_nx): Remove overloads for Entity_Id.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/Makefile.in (LIBIBERTY): Fix condition.
+ (TOOLS_LIBS): Add @LD_PICFLAG@.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.cc (Subprogram_Body_to_gnu): Add guard to the
+ code turning the type of the RESULT_DECL into a reference type.
+ (maybe_make_gnu_thunk): Use a more precise guard in the same case.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.cc (Case_Statement_to_gnu): Rename boolean
+ constant and use From_Conditional_Expression flag for its value.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * debug.adb (d.L): Remove documentation.
+ * exp_ch4.adb (Expand_N_Case_Expression): In the not-by-copy case,
+ do not wrap the case statement in an Expression_With_Actions node.
+ (Expand_N_If_Expression): Do not test
+ Back_End_Handles_Limited_Types
+ * gnat1drv.adb (Adjust_Global_Switches): Do not set it.
+ * opt.ads (Back_End_Handles_Limited_Types): Delete.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Check_Generic_Actuals): Check the component type
+ of constants and variables of an array type.
+ (Copy_Generic_Node): Fix bogus handling of iterator
+ specifications.
+
+2023-06-27 Claire Dross <dross@adacore.com>
+
+ * libgnat/a-textio.ads (Get_Line): Use Relaxed_Initialization on
+ the Item parameter of Get_Line.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Quantified_Expression): Revert the latest
+ change as it is subsumed by the machinery in Sem_Ch5.
+ * sem_ch5.adb (Prepare_Iterator_Loop): Also wrap the loop
+ statement in a block in the name contains a function call that
+ returns on the secondary stack.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Scope_Within_Body_Or_Same): New predicate.
+ (Check_Actual_Type): Take into account packages nested in bodies
+ to compute the enclosing scope by means of
+ Scope_Within_Body_Or_Same.
+
+2023-06-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Check_Private_View): Also check the type of
+ visible discriminants in record and concurrent types.
+
+2023-06-27 Viljar Indus <indus@adacore.com>
+
+ * sprint.adb (Print_Node_Actual): Print homogeneous N_Aggregate
+ nodes with brackets.
+
+2023-06-27 Viljar Indus <indus@adacore.com>
+
+ * exp_aggr.adb (Expand_N_Aggregate): Ensure that container
+ aggregate expressions do not get expanded as records but instead
+ as container aggregates.
+
2023-06-20 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Variable>: Pass
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index fd94203..9c2a2b0 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -123,7 +123,6 @@ package body Debug is
-- d.I Do not ignore enum representation clauses in CodePeer mode
-- d.J Relaxed rules for pragma No_Return
-- d.K Do not reject components in extensions overlapping with parent
- -- d.L Depend on back end for limited types in if and case expressions
-- d.M Relaxed RM semantics
-- d.N Use rounding when converting from floating point to fixed point
-- d.O Dump internal SCO tables
@@ -898,11 +897,6 @@ package body Debug is
-- clause but they cannot be fully supported by the GCC type system.
-- This switch nevertheless allows them for the sake of compatibility.
- -- d.L Normally the front end generates special expansion for conditional
- -- expressions of a limited type. This debug flag removes this special
- -- case expansion, leaving it up to the back end to handle conditional
- -- expressions correctly.
-
-- d.M Relaxed RM semantics. This flag sets Opt.Relaxed_RM_Semantics
-- See Opt.Relaxed_RM_Semantics for more details.
diff --git a/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst b/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst
index 275b46c..5c023239 100644
--- a/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst
+++ b/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst
@@ -767,6 +767,13 @@ No_Unchecked_Deallocation
[RM J.13] This restriction ensures at compile time that there are no semantic
dependences on the predefined generic procedure Unchecked_Deallocation.
+No_Use_Of_Attribute
+-------------------
+.. index:: No_Use_Of_Attribute
+
+[RM 13.12.1] This is a standard Ada 2012 restriction that is GNAT defined in
+earlier versions of Ada.
+
No_Use_Of_Entity
----------------
.. index:: No_Use_Of_Entity
@@ -780,6 +787,13 @@ where ``Name`` is the fully qualified entity, for example ::
No_Use_Of_Entity => Ada.Text_IO.Put_Line
+No_Use_Of_Pragma
+----------------
+.. index:: No_Use_Of_Pragma
+
+[RM 13.12.1] This is a standard Ada 2012 restriction that is GNAT defined in
+earlier versions of Ada.
+
Pure_Barriers
-------------
.. index:: Pure_Barriers
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 5e22fef..d922c3b 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -6463,6 +6463,7 @@ package body Exp_Aggr is
if Is_Record_Type (T)
and then not Is_Private_Type (T)
+ and then not Is_Homogeneous_Aggregate (N)
then
Expand_Record_Aggregate (N);
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 7ac4680..daf27fb 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -139,7 +139,7 @@ package body Exp_Ch3 is
-- the code expansion for controlled components (when control actions
-- are active) can lead to very large blocks that GCC handles poorly.
- procedure Build_Untagged_Equality (Typ : Entity_Id);
+ procedure Build_Untagged_Record_Equality (Typ : Entity_Id);
-- AI05-0123: Equality on untagged records composes. This procedure
-- builds the equality routine for an untagged record that has components
-- of a record type that has user-defined primitive equality operations.
@@ -4450,11 +4450,11 @@ package body Exp_Ch3 is
Set_Is_Pure (Proc_Name);
end Build_Slice_Assignment;
- -----------------------------
- -- Build_Untagged_Equality --
- -----------------------------
+ ------------------------------------
+ -- Build_Untagged_Record_Equality --
+ ------------------------------------
- procedure Build_Untagged_Equality (Typ : Entity_Id) is
+ procedure Build_Untagged_Record_Equality (Typ : Entity_Id) is
Build_Eq : Boolean;
Comp : Entity_Id;
Decl : Node_Id;
@@ -4481,7 +4481,7 @@ package body Exp_Ch3 is
end if;
end User_Defined_Eq;
- -- Start of processing for Build_Untagged_Equality
+ -- Start of processing for Build_Untagged_Record_Equality
begin
-- If a record component has a primitive equality operation, we must
@@ -4558,7 +4558,7 @@ package body Exp_Ch3 is
Set_Is_Public (Op);
end if;
end if;
- end Build_Untagged_Equality;
+ end Build_Untagged_Record_Equality;
-----------------------------------
-- Build_Variant_Record_Equality --
@@ -4606,6 +4606,7 @@ package body Exp_Ch3 is
function Build_Variant_Record_Equality
(Typ : Entity_Id;
+ Spec_Id : Entity_Id;
Body_Id : Entity_Id;
Param_Specs : List_Id) return Node_Id
is
@@ -4652,42 +4653,66 @@ package body Exp_Ch3 is
if Is_Unchecked_Union (Typ) then
declare
+ Right_Formal : constant Entity_Id :=
+ (if Present (Spec_Id) then Last_Formal (Spec_Id) else Right);
+ Scop : constant Entity_Id :=
+ (if Present (Spec_Id) then Spec_Id else Body_Id);
+
+ procedure Decorate_Extra_Formal (F, F_Typ : Entity_Id);
+ -- Decorate extra formal F with type F_Typ
+
+ ---------------------------
+ -- Decorate_Extra_Formal --
+ ---------------------------
+
+ procedure Decorate_Extra_Formal (F, F_Typ : Entity_Id) is
+ begin
+ Mutate_Ekind (F, E_In_Parameter);
+ Set_Etype (F, F_Typ);
+ Set_Scope (F, Scop);
+ Set_Mechanism (F, By_Copy);
+ end Decorate_Extra_Formal;
+
A : Entity_Id;
B : Entity_Id;
Discr : Entity_Id;
Discr_Type : Entity_Id;
+ Last_Extra : Entity_Id := Empty;
New_Discrs : Elist_Id;
begin
+ Mutate_Ekind (Body_Id, E_Subprogram_Body);
New_Discrs := New_Elmt_List;
Discr := First_Discriminant (Typ);
while Present (Discr) loop
Discr_Type := Etype (Discr);
+ -- Add the new parameters as extra formals
+
A :=
Make_Defining_Identifier (Loc,
Chars => New_External_Name (Chars (Discr), 'A'));
+ Decorate_Extra_Formal (A, Discr_Type);
+
+ if Present (Last_Extra) then
+ Set_Extra_Formal (Last_Extra, A);
+ else
+ Set_Extra_Formal (Right_Formal, A);
+ Set_Extra_Formals (Scop, A);
+ end if;
+
+ Append_Elmt (A, New_Discrs);
+
B :=
Make_Defining_Identifier (Loc,
Chars => New_External_Name (Chars (Discr), 'B'));
- -- Add new parameters to the parameter list
+ Decorate_Extra_Formal (B, Discr_Type);
- Append_To (Param_Specs,
- Make_Parameter_Specification (Loc,
- Defining_Identifier => A,
- Parameter_Type =>
- New_Occurrence_Of (Discr_Type, Loc)));
-
- Append_To (Param_Specs,
- Make_Parameter_Specification (Loc,
- Defining_Identifier => B,
- Parameter_Type =>
- New_Occurrence_Of (Discr_Type, Loc)));
-
- Append_Elmt (A, New_Discrs);
+ Set_Extra_Formal (A, B);
+ Last_Extra := B;
-- Generate the following code to compare each of the inferred
-- discriminants:
@@ -4706,6 +4731,7 @@ package body Exp_Ch3 is
Make_Simple_Return_Statement (Loc,
Expression =>
New_Occurrence_Of (Standard_False, Loc)))));
+
Next_Discriminant (Discr);
end loop;
@@ -5319,7 +5345,7 @@ package body Exp_Ch3 is
-- evaluate the conditions.
procedure Build_Variant_Record_Equality (Typ : Entity_Id);
- -- Create An Equality function for the untagged variant record Typ and
+ -- Create an equality function for the untagged variant record Typ and
-- attach it to the TSS list.
procedure Register_Dispatch_Table_Wrappers (Typ : Entity_Id);
@@ -5417,6 +5443,7 @@ package body Exp_Ch3 is
Discard_Node (
Build_Variant_Record_Equality
(Typ => Typ,
+ Spec_Id => Empty,
Body_Id => F,
Param_Specs => New_List (
Make_Parameter_Specification (Loc,
@@ -5803,25 +5830,18 @@ package body Exp_Ch3 is
end if;
-- In the untagged case, ever since Ada 83 an equality function must
- -- be provided for variant records that are not unchecked unions.
- -- In Ada 2012 the equality function composes, and thus must be built
- -- explicitly just as for tagged records.
+ -- be provided for variant records that are not unchecked unions.
elsif Has_Discriminants (Typ)
and then not Is_Limited_Type (Typ)
+ and then Present (Component_List (Type_Definition (Typ_Decl)))
+ and then
+ Present (Variant_Part (Component_List (Type_Definition (Typ_Decl))))
then
- declare
- Comps : constant Node_Id :=
- Component_List (Type_Definition (Typ_Decl));
- begin
- if Present (Comps)
- and then Present (Variant_Part (Comps))
- then
- Build_Variant_Record_Equality (Typ);
- end if;
- end;
+ Build_Variant_Record_Equality (Typ);
- -- Otherwise create primitive equality operation (AI05-0123)
+ -- In Ada 2012 the equality function composes, and thus must be built
+ -- explicitly just as for tagged records.
-- This is done unconditionally to ensure that tools can be linked
-- properly with user programs compiled with older language versions.
@@ -5832,7 +5852,7 @@ package body Exp_Ch3 is
and then Convention (Typ) = Convention_Ada
and then not Is_Limited_Type (Typ)
then
- Build_Untagged_Equality (Typ);
+ Build_Untagged_Record_Equality (Typ);
end if;
-- Before building the record initialization procedure, if we are
@@ -5841,9 +5861,7 @@ package body Exp_Ch3 is
-- type and the concurrent record value type. See the section "Handling
-- of Discriminants" in the Einfo spec for details.
- if Is_Concurrent_Record_Type (Typ)
- and then Has_Discriminants (Typ)
- then
+ if Is_Concurrent_Record_Type (Typ) and then Has_Discriminants (Typ) then
declare
Ctyp : constant Entity_Id :=
Corresponding_Concurrent_Type (Typ);
diff --git a/gcc/ada/exp_ch3.ads b/gcc/ada/exp_ch3.ads
index d2f8534..64ccdeb 100644
--- a/gcc/ada/exp_ch3.ads
+++ b/gcc/ada/exp_ch3.ads
@@ -109,10 +109,12 @@ package Exp_Ch3 is
function Build_Variant_Record_Equality
(Typ : Entity_Id;
+ Spec_Id : Entity_Id;
Body_Id : Entity_Id;
Param_Specs : List_Id) return Node_Id;
-- Build the body of the equality function Body_Id for the untagged variant
- -- record Typ with the given parameters specification list.
+ -- record Typ with the given parameters specification list. If Spec_Id is
+ -- present, the body is built for a renaming of the equality function.
function Freeze_Type (N : Node_Id) return Boolean;
-- This function executes the freezing actions associated with the given
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 7b6e997..ec95d8b 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -2274,148 +2274,28 @@ package body Exp_Ch4 is
Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
if Present (Eq_Op) then
- if Etype (First_Formal (Eq_Op)) /= Full_Type then
-
- -- Inherited equality from parent type. Convert the actuals to
- -- match signature of operation.
-
- declare
- T : constant Entity_Id := Etype (First_Formal (Eq_Op));
-
- begin
- return
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Eq_Op, Loc),
- Parameter_Associations => New_List (
- OK_Convert_To (T, Lhs),
- OK_Convert_To (T, Rhs)));
- end;
-
- else
- -- Comparison between Unchecked_Union components
-
- if Is_Unchecked_Union (Full_Type) then
- declare
- Lhs_Type : Node_Id := Full_Type;
- Rhs_Type : Node_Id := Full_Type;
- Lhs_Discr_Val : Node_Id;
- Rhs_Discr_Val : Node_Id;
-
- begin
- -- Lhs subtype
-
- if Nkind (Lhs) = N_Selected_Component then
- Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
- end if;
-
- -- Rhs subtype
-
- if Nkind (Rhs) = N_Selected_Component then
- Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
- end if;
-
- -- Lhs of the composite equality
-
- if Is_Constrained (Lhs_Type) then
-
- -- Since the enclosing record type can never be an
- -- Unchecked_Union (this code is executed for records
- -- that do not have variants), we may reference its
- -- discriminant(s).
-
- if Nkind (Lhs) = N_Selected_Component
- and then Has_Per_Object_Constraint
- (Entity (Selector_Name (Lhs)))
- then
- Lhs_Discr_Val :=
- Make_Selected_Component (Loc,
- Prefix => Prefix (Lhs),
- Selector_Name =>
- New_Copy
- (Get_Discriminant_Value
- (First_Discriminant (Lhs_Type),
- Lhs_Type,
- Stored_Constraint (Lhs_Type))));
-
- else
- Lhs_Discr_Val :=
- New_Copy
- (Get_Discriminant_Value
- (First_Discriminant (Lhs_Type),
- Lhs_Type,
- Stored_Constraint (Lhs_Type)));
-
- end if;
- else
- -- It is not possible to infer the discriminant since
- -- the subtype is not constrained.
-
- return
- Make_Raise_Program_Error (Loc,
- Reason => PE_Unchecked_Union_Restriction);
- end if;
-
- -- Rhs of the composite equality
-
- if Is_Constrained (Rhs_Type) then
- if Nkind (Rhs) = N_Selected_Component
- and then Has_Per_Object_Constraint
- (Entity (Selector_Name (Rhs)))
- then
- Rhs_Discr_Val :=
- Make_Selected_Component (Loc,
- Prefix => Prefix (Rhs),
- Selector_Name =>
- New_Copy
- (Get_Discriminant_Value
- (First_Discriminant (Rhs_Type),
- Rhs_Type,
- Stored_Constraint (Rhs_Type))));
-
- else
- Rhs_Discr_Val :=
- New_Copy
- (Get_Discriminant_Value
- (First_Discriminant (Rhs_Type),
- Rhs_Type,
- Stored_Constraint (Rhs_Type)));
-
- end if;
- else
- return
- Make_Raise_Program_Error (Loc,
- Reason => PE_Unchecked_Union_Restriction);
- end if;
+ declare
+ Op_Typ : constant Entity_Id := Etype (First_Formal (Eq_Op));
- -- Call the TSS equality function with the inferred
- -- discriminant values.
+ L_Exp, R_Exp : Node_Id;
- return
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Eq_Op, Loc),
- Parameter_Associations => New_List (
- Lhs,
- Rhs,
- Lhs_Discr_Val,
- Rhs_Discr_Val));
- end;
+ begin
+ -- Adjust operands if necessary to comparison type
- -- All cases other than comparing Unchecked_Union types
+ if Base_Type (Full_Type) /= Base_Type (Op_Typ) then
+ L_Exp := OK_Convert_To (Op_Typ, Lhs);
+ R_Exp := OK_Convert_To (Op_Typ, Rhs);
else
- declare
- T : constant Entity_Id := Etype (First_Formal (Eq_Op));
- begin
- return
- Make_Function_Call (Loc,
- Name =>
- New_Occurrence_Of (Eq_Op, Loc),
- Parameter_Associations => New_List (
- OK_Convert_To (T, Lhs),
- OK_Convert_To (T, Rhs)));
- end;
+ L_Exp := Relocate_Node (Lhs);
+ R_Exp := Relocate_Node (Rhs);
end if;
- end if;
+
+ return
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Eq_Op, Loc),
+ Parameter_Associations => New_List (L_Exp, R_Exp));
+ end;
-- Equality composes in Ada 2012 for untagged record types. It also
-- composes for bounded strings, because they are part of the
@@ -5306,7 +5186,6 @@ package body Exp_Ch4 is
Alt : Node_Id;
Case_Stmt : Node_Id;
Decl : Node_Id;
- Expr : Node_Id;
Target : Entity_Id := Empty;
Target_Typ : Entity_Id;
@@ -5361,7 +5240,6 @@ package body Exp_Ch4 is
-- In all other cases expand into
- -- do
-- type Ptr_Typ is access all Typ;
-- Target : Ptr_Typ;
-- case X is
@@ -5371,7 +5249,8 @@ package body Exp_Ch4 is
-- Target := BX'Unrestricted_Access;
-- ...
-- end case;
- -- in Target.all end;
+
+ -- and replace the case expression by a reference to Target.all.
-- This approach avoids extra copies of potentially large objects. It
-- also allows handling of values of limited or unconstrained types.
@@ -5514,20 +5393,21 @@ package body Exp_Ch4 is
Prepend_List (Actions (Alt), Stmts);
end if;
- -- Finalize any transient objects on exit from the alternative.
- -- This is done only in the return optimization case because
- -- otherwise the case expression is converted into an expression
- -- with actions which already contains this form of processing.
-
- if Optimize_Return_Stmt then
- Process_If_Case_Statements (N, Stmts);
- end if;
-
Append_To
(Alternatives (Case_Stmt),
Make_Case_Statement_Alternative (Sloc (Alt),
Discrete_Choices => Discrete_Choices (Alt),
Statements => Stmts));
+
+ -- Finalize any transient objects on exit from the alternative.
+ -- This needs to be done only when the case expression is _not_
+ -- later converted into an expression with actions, which already
+ -- contains this form of processing, and after Stmts is attached
+ -- to the Alternatives list above (for Safe_To_Capture_Value).
+
+ if Optimize_Return_Stmt or else not Is_Copy_Type (Typ) then
+ Process_If_Case_Statements (N, Stmts);
+ end if;
end;
Next (Alt);
@@ -5539,30 +5419,24 @@ package body Exp_Ch4 is
Rewrite (Par, Case_Stmt);
Analyze (Par);
- -- Otherwise convert the case expression into an expression with actions
+ -- Otherwise rewrite the case expression itself
else
Append_To (Acts, Case_Stmt);
if Is_Copy_Type (Typ) then
- Expr := New_Occurrence_Of (Target, Loc);
+ Rewrite (N,
+ Make_Expression_With_Actions (Loc,
+ Expression => New_Occurrence_Of (Target, Loc),
+ Actions => Acts));
else
- Expr :=
+ Insert_Actions (N, Acts);
+ Rewrite (N,
Make_Explicit_Dereference (Loc,
- Prefix => New_Occurrence_Of (Target, Loc));
+ Prefix => New_Occurrence_Of (Target, Loc)));
end if;
- -- Generate:
- -- do
- -- ...
- -- in Target[.all] end;
-
- Rewrite (N,
- Make_Expression_With_Actions (Loc,
- Expression => Expr,
- Actions => Acts));
-
Analyze_And_Resolve (N, Typ);
end if;
end Expand_N_Case_Expression;
@@ -5937,9 +5811,8 @@ package body Exp_Ch4 is
Set_From_Conditional_Expression (New_If);
- -- If the type is limited, and the back end does not handle limited
- -- types, then we expand as follows to avoid the possibility of
- -- improper copying.
+ -- If the type is by reference, then we expand as follows to avoid the
+ -- possibility of improper copying.
-- type Ptr is access all Typ;
-- Cnn : Ptr;
@@ -5953,12 +5826,7 @@ package body Exp_Ch4 is
-- and replace the if expression by a reference to Cnn.all.
- -- This special case can be skipped if the back end handles limited
- -- types properly and ensures that no incorrect copies are made.
-
- elsif Is_By_Reference_Type (Typ)
- and then not Back_End_Handles_Limited_Types
- then
+ elsif Is_By_Reference_Type (Typ) then
-- When the "then" or "else" expressions involve controlled function
-- calls, generated temporaries are chained on the corresponding list
-- of actions. These temporaries need to be finalized after the if
@@ -8124,242 +7992,29 @@ package body Exp_Ch4 is
-------------------------
procedure Build_Equality_Call (Eq : Entity_Id) is
- Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
- L_Exp : Node_Id := Relocate_Node (Lhs);
- R_Exp : Node_Id := Relocate_Node (Rhs);
+ Op_Typ : constant Entity_Id := Etype (First_Formal (Eq));
+
+ L_Exp, R_Exp : Node_Id;
begin
-- Adjust operands if necessary to comparison type
- if Base_Type (Op_Type) /= Base_Type (A_Typ)
+ if Base_Type (A_Typ) /= Base_Type (Op_Typ)
and then not Is_Class_Wide_Type (A_Typ)
then
- L_Exp := OK_Convert_To (Op_Type, L_Exp);
- R_Exp := OK_Convert_To (Op_Type, R_Exp);
- end if;
-
- -- If we have an Unchecked_Union, we need to add the inferred
- -- discriminant values as actuals in the function call. At this
- -- point, the expansion has determined that both operands have
- -- inferable discriminants.
-
- if Is_Unchecked_Union (Op_Type) then
- declare
- Lhs_Type : constant Entity_Id := Etype (L_Exp);
- Rhs_Type : constant Entity_Id := Etype (R_Exp);
-
- Lhs_Discr_Vals : Elist_Id;
- -- List of inferred discriminant values for left operand.
-
- Rhs_Discr_Vals : Elist_Id;
- -- List of inferred discriminant values for right operand.
-
- Discr : Entity_Id;
-
- begin
- Lhs_Discr_Vals := New_Elmt_List;
- Rhs_Discr_Vals := New_Elmt_List;
-
- -- Per-object constrained selected components require special
- -- attention. If the enclosing scope of the component is an
- -- Unchecked_Union, we cannot reference its discriminants
- -- directly. This is why we use the extra parameters of the
- -- equality function of the enclosing Unchecked_Union.
-
- -- type UU_Type (Discr : Integer := 0) is
- -- . . .
- -- end record;
- -- pragma Unchecked_Union (UU_Type);
-
- -- 1. Unchecked_Union enclosing record:
-
- -- type Enclosing_UU_Type (Discr : Integer := 0) is record
- -- . . .
- -- Comp : UU_Type (Discr);
- -- . . .
- -- end Enclosing_UU_Type;
- -- pragma Unchecked_Union (Enclosing_UU_Type);
-
- -- Obj1 : Enclosing_UU_Type;
- -- Obj2 : Enclosing_UU_Type (1);
-
- -- [. . .] Obj1 = Obj2 [. . .]
-
- -- Generated code:
-
- -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
-
- -- A and B are the formal parameters of the equality function
- -- of Enclosing_UU_Type. The function always has two extra
- -- formals to capture the inferred discriminant values for
- -- each discriminant of the type.
-
- -- 2. Non-Unchecked_Union enclosing record:
-
- -- type
- -- Enclosing_Non_UU_Type (Discr : Integer := 0)
- -- is record
- -- . . .
- -- Comp : UU_Type (Discr);
- -- . . .
- -- end Enclosing_Non_UU_Type;
-
- -- Obj1 : Enclosing_Non_UU_Type;
- -- Obj2 : Enclosing_Non_UU_Type (1);
-
- -- ... Obj1 = Obj2 ...
-
- -- Generated code:
-
- -- if not (uu_typeEQ (obj1.comp, obj2.comp,
- -- obj1.discr, obj2.discr)) then
-
- -- In this case we can directly reference the discriminants of
- -- the enclosing record.
-
- -- Process left operand of equality
-
- if Nkind (Lhs) = N_Selected_Component
- and then
- Has_Per_Object_Constraint (Entity (Selector_Name (Lhs)))
- then
- -- If enclosing record is an Unchecked_Union, use formals
- -- corresponding to each discriminant. The name of the
- -- formal is that of the discriminant, with added suffix,
- -- see Exp_Ch3.Build_Record_Equality for details.
-
- if Is_Unchecked_Union (Scope (Entity (Selector_Name (Lhs))))
- then
- Discr :=
- First_Discriminant
- (Scope (Entity (Selector_Name (Lhs))));
- while Present (Discr) loop
- Append_Elmt
- (Make_Identifier (Loc,
- Chars => New_External_Name (Chars (Discr), 'A')),
- To => Lhs_Discr_Vals);
- Next_Discriminant (Discr);
- end loop;
-
- -- If enclosing record is of a non-Unchecked_Union type, it
- -- is possible to reference its discriminants directly.
-
- else
- Discr := First_Discriminant (Lhs_Type);
- while Present (Discr) loop
- Append_Elmt
- (Make_Selected_Component (Loc,
- Prefix => Prefix (Lhs),
- Selector_Name =>
- New_Copy
- (Get_Discriminant_Value (Discr,
- Lhs_Type,
- Stored_Constraint (Lhs_Type)))),
- To => Lhs_Discr_Vals);
- Next_Discriminant (Discr);
- end loop;
- end if;
-
- -- Otherwise operand is on object with a constrained type.
- -- Infer the discriminant values from the constraint.
-
- else
- Discr := First_Discriminant (Lhs_Type);
- while Present (Discr) loop
- Append_Elmt
- (New_Copy
- (Get_Discriminant_Value (Discr,
- Lhs_Type,
- Stored_Constraint (Lhs_Type))),
- To => Lhs_Discr_Vals);
- Next_Discriminant (Discr);
- end loop;
- end if;
-
- -- Similar processing for right operand of equality
-
- if Nkind (Rhs) = N_Selected_Component
- and then
- Has_Per_Object_Constraint (Entity (Selector_Name (Rhs)))
- then
- if Is_Unchecked_Union
- (Scope (Entity (Selector_Name (Rhs))))
- then
- Discr :=
- First_Discriminant
- (Scope (Entity (Selector_Name (Rhs))));
- while Present (Discr) loop
- Append_Elmt
- (Make_Identifier (Loc,
- Chars => New_External_Name (Chars (Discr), 'B')),
- To => Rhs_Discr_Vals);
- Next_Discriminant (Discr);
- end loop;
-
- else
- Discr := First_Discriminant (Rhs_Type);
- while Present (Discr) loop
- Append_Elmt
- (Make_Selected_Component (Loc,
- Prefix => Prefix (Rhs),
- Selector_Name =>
- New_Copy (Get_Discriminant_Value
- (Discr,
- Rhs_Type,
- Stored_Constraint (Rhs_Type)))),
- To => Rhs_Discr_Vals);
- Next_Discriminant (Discr);
- end loop;
- end if;
-
- else
- Discr := First_Discriminant (Rhs_Type);
- while Present (Discr) loop
- Append_Elmt
- (New_Copy (Get_Discriminant_Value
- (Discr,
- Rhs_Type,
- Stored_Constraint (Rhs_Type))),
- To => Rhs_Discr_Vals);
- Next_Discriminant (Discr);
- end loop;
- end if;
-
- -- Now merge the list of discriminant values so that values
- -- of corresponding discriminants are adjacent.
-
- declare
- Params : List_Id;
- L_Elmt : Elmt_Id;
- R_Elmt : Elmt_Id;
-
- begin
- Params := New_List (L_Exp, R_Exp);
- L_Elmt := First_Elmt (Lhs_Discr_Vals);
- R_Elmt := First_Elmt (Rhs_Discr_Vals);
- while Present (L_Elmt) loop
- Append_To (Params, Node (L_Elmt));
- Append_To (Params, Node (R_Elmt));
- Next_Elmt (L_Elmt);
- Next_Elmt (R_Elmt);
- end loop;
-
- Rewrite (N,
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Eq, Loc),
- Parameter_Associations => Params));
- end;
- end;
-
- -- Normal case, not an unchecked union
+ L_Exp := OK_Convert_To (Op_Typ, Lhs);
+ R_Exp := OK_Convert_To (Op_Typ, Rhs);
else
- Rewrite (N,
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Eq, Loc),
- Parameter_Associations => New_List (L_Exp, R_Exp)));
+ L_Exp := Relocate_Node (Lhs);
+ R_Exp := Relocate_Node (Rhs);
end if;
+ Rewrite (N,
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Eq, Loc),
+ Parameter_Associations => New_List (L_Exp, R_Exp)));
+
Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
end Build_Equality_Call;
@@ -8733,62 +8388,18 @@ package body Exp_Ch4 is
-- Ada 2005 (AI-216): Program_Error is raised when evaluating the
-- predefined equality operator for a type which has a subcomponent
- -- of an Unchecked_Union type whose nominal subtype is unconstrained.
+ -- of an unchecked union type whose nominal subtype is unconstrained.
elsif Has_Unconstrained_UU_Component (Typl) then
Insert_Action (N,
Make_Raise_Program_Error (Loc,
Reason => PE_Unchecked_Union_Restriction));
- -- Prevent Gigi from generating incorrect code by rewriting the
- -- equality as a standard False. (is this documented somewhere???)
-
Rewrite (N,
New_Occurrence_Of (Standard_False, Loc));
- elsif Is_Unchecked_Union (Typl) then
-
- -- If we can infer the discriminants of the operands, we make a
- -- call to the TSS equality function.
-
- if Has_Inferable_Discriminants (Lhs)
- and then
- Has_Inferable_Discriminants (Rhs)
- then
- Build_Equality_Call
- (TSS (Root_Type (Typl), TSS_Composite_Equality));
-
- else
- -- Ada 2005 (AI-216): Program_Error is raised when evaluating
- -- the predefined equality operator for an Unchecked_Union type
- -- if either of the operands lack inferable discriminants.
-
- Insert_Action (N,
- Make_Raise_Program_Error (Loc,
- Reason => PE_Unchecked_Union_Restriction));
-
- -- Emit a warning on source equalities only, otherwise the
- -- message may appear out of place due to internal use. The
- -- warning is unconditional because it is required by the
- -- language.
-
- if Comes_From_Source (N) then
- Error_Msg_N
- ("Unchecked_Union discriminants cannot be determined??",
- N);
- Error_Msg_N
- ("\Program_Error will be raised for equality operation??",
- N);
- end if;
-
- -- Prevent Gigi from generating incorrect code by rewriting
- -- the equality as a standard False (documented where???).
-
- Rewrite (N,
- New_Occurrence_Of (Standard_False, Loc));
- end if;
-
- -- If a type support function is present (for complex cases), use it
+ -- If a type support function is present, e.g. if there is a variant
+ -- part, including an unchecked union type, use it.
elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
Build_Equality_Call
@@ -11116,32 +10727,6 @@ package body Exp_Ch4 is
Freeze_Before (P, Etype (Var));
end;
- -- For an expression of the form "for all/some X of F(...) => ...",
- -- where F(...) is a function call that returns on the secondary stack,
- -- we need to mark an enclosing scope as Uses_Sec_Stack. We must do
- -- this before expansion, which can obscure the tree. Note that we
- -- might be inside another quantified expression. Skip blocks and
- -- loops that were generated by expansion.
-
- if Present (Iterator_Specification (N))
- and then Nkind (Name (Iterator_Specification (N))) = N_Function_Call
- and then Needs_Secondary_Stack
- (Etype (Name (Iterator_Specification (N))))
- then
- declare
- Source_Scope : Entity_Id := Current_Scope;
- begin
- while Ekind (Source_Scope) in E_Block | E_Loop
- and then not Comes_From_Source (Source_Scope)
- loop
- Source_Scope := Scope (Source_Scope);
- end loop;
-
- Set_Uses_Sec_Stack (Source_Scope);
- Check_Restriction (No_Secondary_Stack, N);
- end;
- end if;
-
-- Create the declaration of the flag which tracks the status of the
-- quantified expression. Generate:
@@ -13569,6 +13154,251 @@ package body Exp_Ch4 is
Adjust_Result_Type (N, Typ);
end Expand_Short_Circuit_Operator;
+ -------------------------------------
+ -- Expand_Unchecked_Union_Equality --
+ -------------------------------------
+
+ procedure Expand_Unchecked_Union_Equality (N : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+ Eq : constant Entity_Id := Entity (Name (N));
+ Lhs : constant Node_Id := First_Actual (N);
+ Rhs : constant Node_Id := Next_Actual (Lhs);
+
+ function Get_Discr_Values (Op : Node_Id; Lhs : Boolean) return Elist_Id;
+ -- Return the list of inferred discriminant values for Op
+
+ ----------------------
+ -- Get_Discr_Values --
+ ----------------------
+
+ function Get_Discr_Values (Op : Node_Id; Lhs : Boolean) return Elist_Id
+ is
+ Typ : constant Entity_Id := Etype (Op);
+ Values : constant Elist_Id := New_Elmt_List;
+
+ function Get_Extra_Formal (Nam : Name_Id) return Entity_Id;
+ -- Return the extra formal Nam from the current scope, which must be
+ -- an equality function for an unchecked union type.
+
+ ----------------------
+ -- Get_Extra_Formal --
+ ----------------------
+
+ function Get_Extra_Formal (Nam : Name_Id) return Entity_Id is
+ Func : constant Entity_Id := Current_Scope;
+
+ Formal : Entity_Id;
+
+ begin
+ pragma Assert (Ekind (Func) = E_Function);
+
+ Formal := Extra_Formals (Func);
+ while Present (Formal) loop
+ if Chars (Formal) = Nam then
+ return Formal;
+ end if;
+
+ Formal := Extra_Formal (Formal);
+ end loop;
+
+ -- An extra formal of the proper name must be found
+
+ raise Program_Error;
+ end Get_Extra_Formal;
+
+ -- Local variables
+
+ Discr : Entity_Id;
+
+ -- Start of processing for Get_Discr_Values
+
+ begin
+ -- Per-object constrained selected components require special
+ -- attention. If the enclosing scope of the component is an
+ -- Unchecked_Union, we cannot reference its discriminants
+ -- directly. This is why we use the extra parameters of the
+ -- equality function of the enclosing Unchecked_Union.
+
+ -- type UU_Type (Discr : Integer := 0) is
+ -- . . .
+ -- end record;
+ -- pragma Unchecked_Union (UU_Type);
+
+ -- 1. Unchecked_Union enclosing record:
+
+ -- type Enclosing_UU_Type (Discr : Integer := 0) is record
+ -- . . .
+ -- Comp : UU_Type (Discr);
+ -- . . .
+ -- end Enclosing_UU_Type;
+ -- pragma Unchecked_Union (Enclosing_UU_Type);
+
+ -- Obj1 : Enclosing_UU_Type;
+ -- Obj2 : Enclosing_UU_Type (1);
+
+ -- [. . .] Obj1 = Obj2 [. . .]
+
+ -- Generated code:
+
+ -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
+
+ -- A and B are the formal parameters of the equality function
+ -- of Enclosing_UU_Type. The function always has two extra
+ -- formals to capture the inferred discriminant values for
+ -- each discriminant of the type.
+
+ -- 2. Non-Unchecked_Union enclosing record:
+
+ -- type
+ -- Enclosing_Non_UU_Type (Discr : Integer := 0)
+ -- is record
+ -- . . .
+ -- Comp : UU_Type (Discr);
+ -- . . .
+ -- end Enclosing_Non_UU_Type;
+
+ -- Obj1 : Enclosing_Non_UU_Type;
+ -- Obj2 : Enclosing_Non_UU_Type (1);
+
+ -- ... Obj1 = Obj2 ...
+
+ -- Generated code:
+
+ -- if not (uu_typeEQ (obj1.comp, obj2.comp,
+ -- obj1.discr, obj2.discr)) then
+
+ -- In this case we can directly reference the discriminants of
+ -- the enclosing record.
+
+ if Nkind (Op) = N_Selected_Component
+ and then Has_Per_Object_Constraint (Entity (Selector_Name (Op)))
+ then
+ -- If enclosing record is an Unchecked_Union, use formals
+ -- corresponding to each discriminant. The name of the
+ -- formal is that of the discriminant, with added suffix,
+ -- see Exp_Ch3.Build_Variant_Record_Equality for details.
+
+ if Is_Unchecked_Union (Scope (Entity (Selector_Name (Op)))) then
+ Discr :=
+ First_Discriminant
+ (Scope (Entity (Selector_Name (Op))));
+ while Present (Discr) loop
+ Append_Elmt
+ (New_Occurrence_Of
+ (Get_Extra_Formal
+ (New_External_Name
+ (Chars (Discr), (if Lhs then 'A' else 'B'))), Loc),
+ To => Values);
+ Next_Discriminant (Discr);
+ end loop;
+
+ -- If enclosing record is of a non-Unchecked_Union type, it
+ -- is possible to reference its discriminants directly.
+
+ else
+ Discr := First_Discriminant (Typ);
+ while Present (Discr) loop
+ Append_Elmt
+ (Make_Selected_Component (Loc,
+ Prefix => Prefix (Op),
+ Selector_Name =>
+ New_Copy
+ (Get_Discriminant_Value (Discr,
+ Typ,
+ Stored_Constraint (Typ)))),
+ To => Values);
+ Next_Discriminant (Discr);
+ end loop;
+ end if;
+
+ -- Otherwise operand is on object with a constrained type.
+ -- Infer the discriminant values from the constraint.
+
+ else
+ Discr := First_Discriminant (Typ);
+ while Present (Discr) loop
+ Append_Elmt
+ (New_Copy
+ (Get_Discriminant_Value (Discr,
+ Typ,
+ Stored_Constraint (Typ))),
+ To => Values);
+ Next_Discriminant (Discr);
+ end loop;
+ end if;
+
+ return Values;
+ end Get_Discr_Values;
+
+ -- Start of processing for Expand_Unchecked_Union_Equality
+
+ begin
+ -- Guard against repeated invocation on the same node
+
+ if Present (Next_Actual (Rhs)) then
+ return;
+ end if;
+
+ -- If we can infer the discriminants of the operands, make a call to Eq
+
+ if Has_Inferable_Discriminants (Lhs)
+ and then
+ Has_Inferable_Discriminants (Rhs)
+ then
+ declare
+ Lhs_Values : constant Elist_Id := Get_Discr_Values (Lhs, True);
+ Rhs_Values : constant Elist_Id := Get_Discr_Values (Rhs, False);
+
+ Formal : Entity_Id;
+ L_Elmt : Elmt_Id;
+ R_Elmt : Elmt_Id;
+
+ begin
+ -- Add the inferred discriminant values as extra actuals
+
+ Formal := Extra_Formals (Eq);
+ L_Elmt := First_Elmt (Lhs_Values);
+ R_Elmt := First_Elmt (Rhs_Values);
+
+ while Present (L_Elmt) loop
+ Analyze_And_Resolve (Node (L_Elmt), Etype (Formal));
+ Add_Extra_Actual_To_Call (N, Formal, Node (L_Elmt));
+
+ Formal := Extra_Formal (Formal);
+
+ Analyze_And_Resolve (Node (R_Elmt), Etype (Formal));
+ Add_Extra_Actual_To_Call (N, Formal, Node (R_Elmt));
+
+ Formal := Extra_Formal (Formal);
+ Next_Elmt (L_Elmt);
+ Next_Elmt (R_Elmt);
+ end loop;
+ end;
+
+ -- Ada 2005 (AI-216): Program_Error is raised when evaluating
+ -- the predefined equality operator for an Unchecked_Union type
+ -- if either of the operands lack inferable discriminants.
+
+ else
+ Insert_Action (N,
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Unchecked_Union_Restriction));
+
+ -- Give a warning on source equalities only, otherwise the message
+ -- may appear out of place due to internal use. It is unconditional
+ -- because it is required by the language.
+
+ if Comes_From_Source (Original_Node (N)) then
+ Error_Msg_N
+ ("Unchecked_Union discriminants cannot be determined??", N);
+ Error_Msg_N
+ ("\Program_Error will be raised for equality operation??", N);
+ end if;
+
+ Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
+ end if;
+ end Expand_Unchecked_Union_Equality;
+
------------------------------------
-- Fixup_Universal_Fixed_Operation --
-------------------------------------
diff --git a/gcc/ada/exp_ch4.ads b/gcc/ada/exp_ch4.ads
index 1891e2e..39177cd 100644
--- a/gcc/ada/exp_ch4.ads
+++ b/gcc/ada/exp_ch4.ads
@@ -105,6 +105,10 @@ package Exp_Ch4 is
-- membership test. The whole membership is rewritten connecting these
-- with OR ELSE.
+ procedure Expand_Unchecked_Union_Equality (N : Node_Id);
+ -- Expand a call to the predefined equality operator of an unchecked union
+ -- type, possibly rewriting it as a raise statement.
+
function Integer_Promotion_Possible (N : Node_Id) return Boolean;
-- Returns true if the node is a type conversion whose operand is an
-- arithmetic operation on signed integers, and the base type of the
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 258459b..d55fdb3 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -524,7 +524,7 @@ package body Exp_Ch5 is
R_Type := Get_Actual_Subtype (Act_Rhs);
Loop_Required := True;
- -- We require a loop if the left side is possibly bit unaligned
+ -- We require a loop if either side is possibly bit aligned
elsif Possible_Bit_Aligned_Component (Lhs)
or else
@@ -682,14 +682,10 @@ package body Exp_Ch5 is
return;
-- If either operand is bit packed, then we need a loop, since we can't
- -- be sure that the slice is byte aligned. Similarly, if either operand
- -- is a possibly unaligned slice, then we need a loop (since the back
- -- end cannot handle unaligned slices).
+ -- be sure that the slice is byte aligned.
elsif Is_Bit_Packed_Array (L_Type)
or else Is_Bit_Packed_Array (R_Type)
- or else Is_Possibly_Unaligned_Slice (Lhs)
- or else Is_Possibly_Unaligned_Slice (Rhs)
then
Loop_Required := True;
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 28d563f..2e3a2b3 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -37,6 +37,7 @@ with Expander; use Expander;
with Exp_Aggr; use Exp_Aggr;
with Exp_Atag; use Exp_Atag;
with Exp_Ch3; use Exp_Ch3;
+with Exp_Ch4; use Exp_Ch4;
with Exp_Ch7; use Exp_Ch7;
with Exp_Ch9; use Exp_Ch9;
with Exp_Dbug; use Exp_Dbug;
@@ -2800,7 +2801,40 @@ package body Exp_Ch6 is
-----------------
procedure Expand_Call (N : Node_Id) is
- Post_Call : List_Id;
+ function Is_Unchecked_Union_Equality (N : Node_Id) return Boolean;
+ -- Return True if N is a call to the predefined equality operator of an
+ -- unchecked union type, or a renaming thereof.
+
+ ---------------------------------
+ -- Is_Unchecked_Union_Equality --
+ ---------------------------------
+
+ function Is_Unchecked_Union_Equality (N : Node_Id) return Boolean is
+ begin
+ if Is_Entity_Name (Name (N))
+ and then Ekind (Entity (Name (N))) = E_Function
+ and then Present (First_Formal (Entity (Name (N))))
+ and then
+ Is_Unchecked_Union (Etype (First_Formal (Entity (Name (N)))))
+ then
+ declare
+ Func : constant Entity_Id := Entity (Name (N));
+ Typ : constant Entity_Id := Etype (First_Formal (Func));
+ Decl : constant Node_Id :=
+ Original_Node (Parent (Declaration_Node (Func)));
+
+ begin
+ return Func = TSS (Typ, TSS_Composite_Equality)
+ or else (Nkind (Decl) = N_Subprogram_Renaming_Declaration
+ and then Nkind (Name (Decl)) = N_Operator_Symbol
+ and then Chars (Name (Decl)) = Name_Op_Eq
+ and then Ekind (Entity (Name (Decl))) = E_Operator);
+ end;
+
+ else
+ return False;
+ end if;
+ end Is_Unchecked_Union_Equality;
-- If this is an indirect call through an Access_To_Subprogram
-- with contract specifications, it is rewritten as a call to
@@ -2815,6 +2849,10 @@ package body Exp_Ch6 is
and then Present
(Access_Subprogram_Wrapper (Etype (Name (N))));
+ Post_Call : List_Id;
+
+ -- Start of processing for Expand_Call
+
begin
pragma Assert (Nkind (N) in N_Entry_Call_Statement
| N_Function_Call
@@ -2890,6 +2928,27 @@ package body Exp_Ch6 is
Analyze_And_Resolve (N, Typ);
end;
+ -- Case of a call to the predefined equality operator of an unchecked
+ -- union type, which requires specific processing.
+
+ elsif Is_Unchecked_Union_Equality (N) then
+ declare
+ Eq : constant Entity_Id := Entity (Name (N));
+
+ begin
+ Expand_Unchecked_Union_Equality (N);
+
+ -- If the call was not rewritten as a raise, expand the actuals
+
+ if Nkind (N) = N_Function_Call then
+ pragma Assert (Check_Number_Of_Actuals (N, Eq));
+ Expand_Actuals (N, Eq, Post_Call);
+ pragma Assert (Is_Empty_List (Post_Call));
+ end if;
+ end;
+
+ -- Normal case
+
else
Expand_Call_Helper (N, Post_Call);
Insert_Post_Call_Actions (N, Post_Call);
diff --git a/gcc/ada/exp_ch8.adb b/gcc/ada/exp_ch8.adb
index 09c364c..411e5db 100644
--- a/gcc/ada/exp_ch8.adb
+++ b/gcc/ada/exp_ch8.adb
@@ -294,10 +294,10 @@ package body Exp_Ch8 is
begin
Set_Alias (Id, Empty);
Set_Has_Completion (Id, False);
+ Set_Has_Delayed_Freeze (Id);
Rewrite (N,
Make_Subprogram_Declaration (Loc,
Specification => Specification (N)));
- Set_Has_Delayed_Freeze (Id);
Body_Id := Make_Defining_Identifier (Loc, Chars (Id));
Set_Debug_Info_Needed (Body_Id);
@@ -306,6 +306,7 @@ package body Exp_Ch8 is
Decl :=
Build_Variant_Record_Equality
(Typ => Typ,
+ Spec_Id => Id,
Body_Id => Body_Id,
Param_Specs => Copy_Parameter_List (Id));
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 0d0ad8a..c74921e 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -4959,7 +4959,10 @@ package body Exp_Util is
-- Component_May_Be_Bit_Aligned --
----------------------------------
- function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
+ function Component_May_Be_Bit_Aligned
+ (Comp : Entity_Id;
+ For_Slice : Boolean := False) return Boolean
+ is
UT : Entity_Id;
begin
@@ -4980,11 +4983,12 @@ package body Exp_Util is
-- If we know that we have a small (at most the maximum integer size)
-- record or bit-packed array, then everything is fine, since the back
- -- end can handle these cases correctly.
+ -- end can handle these cases correctly, except if a slice is involved.
elsif Known_Esize (Comp)
and then Esize (Comp) <= System_Max_Integer_Size
and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
+ and then not For_Slice
then
return False;
@@ -11318,7 +11322,10 @@ package body Exp_Util is
-- Possible_Bit_Aligned_Component --
------------------------------------
- function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
+ function Possible_Bit_Aligned_Component
+ (N : Node_Id;
+ For_Slice : Boolean := False) return Boolean
+ is
begin
-- Do not process an unanalyzed node because it is not yet decorated and
-- most checks performed below will fail.
@@ -11356,7 +11363,7 @@ package body Exp_Util is
-- indexing from a possibly unaligned component.
else
- return Possible_Bit_Aligned_Component (P);
+ return Possible_Bit_Aligned_Component (P, For_Slice);
end if;
end;
@@ -11371,14 +11378,14 @@ package body Exp_Util is
-- This is the crucial test: if the component itself causes
-- trouble, then we can stop and return True.
- if Component_May_Be_Bit_Aligned (Comp) then
+ if Component_May_Be_Bit_Aligned (Comp, For_Slice) then
return True;
-- Otherwise, we need to test the prefix, to see if we are
-- selecting from a possibly unaligned component.
else
- return Possible_Bit_Aligned_Component (P);
+ return Possible_Bit_Aligned_Component (P, For_Slice);
end if;
end;
@@ -11386,13 +11393,13 @@ package body Exp_Util is
-- then for sure the slice is.
when N_Slice =>
- return Possible_Bit_Aligned_Component (Prefix (N));
+ return Possible_Bit_Aligned_Component (Prefix (N), True);
-- For an unchecked conversion, check whether the expression may
-- be bit aligned.
when N_Unchecked_Type_Conversion =>
- return Possible_Bit_Aligned_Component (Expression (N));
+ return Possible_Bit_Aligned_Component (Expression (N), For_Slice);
-- If we have none of the above, it means that we have fallen off the
-- top testing prefixes recursively, and we now have a stand alone
@@ -11400,15 +11407,11 @@ package body Exp_Util is
-- in which case we need to look into the renamed object.
when others =>
- if Is_Entity_Name (N)
+ return Is_Entity_Name (N)
and then Is_Object (Entity (N))
and then Present (Renamed_Object (Entity (N)))
- then
- return
- Possible_Bit_Aligned_Component (Renamed_Object (Entity (N)));
- else
- return False;
- end if;
+ and then Possible_Bit_Aligned_Component
+ (Renamed_Object (Entity (N)), For_Slice);
end case;
end Possible_Bit_Aligned_Component;
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 02324d23..65bb920 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -399,16 +399,19 @@ package Exp_Util is
-- since for floating-point, abs, unary "-", and unary "+" can never
-- case overflow.
- function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean;
+ function Component_May_Be_Bit_Aligned
+ (Comp : Entity_Id;
+ For_Slice : Boolean := False) return Boolean;
-- This function is in charge of detecting record components that may cause
- -- trouble for the back end if an attempt is made to access the component
- -- as a whole. The back end can handle such accesses with no problem if the
- -- components involved are small (64 bits or less) records or scalar items
+ -- trouble for the back end if an attempt is made to access the component,
+ -- either as a whole if For_Slice is False, or through an array slice if
+ -- For_Slice is True. The back end can handle such accesses only if the
+ -- components involved are small (64/128 bits or less) records or scalars
-- (including bit-packed arrays represented with a modular type), or else
-- if they are aligned on byte boundaries (i.e. starting on a byte boundary
-- and occupying an integral number of bytes).
--
- -- However, problems arise for records larger than 64 bits, or for arrays
+ -- However problems arise for records larger than 64/128 bits or for arrays
-- (other than bit-packed arrays represented with a modular type) if the
-- component either does not start on a byte boundary or does not occupy an
-- integral number of bytes (i.e. there are some bits possibly shared with
@@ -998,7 +1001,9 @@ package Exp_Util is
-- address might be captured in a way we do not detect. A value of True is
-- returned only if the replacement is safe.
- function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean;
+ function Possible_Bit_Aligned_Component
+ (N : Node_Id;
+ For_Slice : Boolean := False) return Boolean;
-- This function is used during processing the assignment of a record or an
-- array, or the construction of an aggregate. The argument N is either the
-- left or the right hand side of an assignment and the function determines
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index dc0e54f..b5243a2 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -240,10 +240,10 @@ ALL_CPPFLAGS = $(CPPFLAGS)
ALL_COMPILERFLAGS = $(ALL_CFLAGS)
# This is where we get libiberty.a from.
-ifeq ($(PICFLAG),)
-LIBIBERTY = ../../libiberty/libiberty.a
-else
+ifneq ($(findstring $(PICFLAG),-fPIC -fPIE),)
LIBIBERTY = ../../libiberty/pic/libiberty.a
+else
+LIBIBERTY = ../../libiberty/libiberty.a
endif
# We need to link against libbacktrace because diagnostic.c in
@@ -261,6 +261,9 @@ TOOLS_LIBS = ../version.o ../link.o ../targext.o ../../ggc-none.o \
$(LIBGNAT) $(LIBINTL) $(LIBICONV) ../$(LIBBACKTRACE) ../$(LIBIBERTY) \
$(SYSLIBS) $(TGT_LIB)
+# Add -no-pie to TOOLS_LIBS since some of them are compiled with -fno-PIE.
+TOOLS_LIBS += @LD_PICFLAG@
+
# Specify the directories to be searched for header files.
# Both . and srcdir are used, in that order,
# so that tm.h and config.h will be found in the compilation
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 494b24e..ee913a0 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -163,17 +163,6 @@ struct GTY((for_user)) tree_entity_vec_map
vec<Entity_Id, va_gc_atomic> *to;
};
-void
-gt_pch_nx (Entity_Id &)
-{
-}
-
-void
-gt_pch_nx (Entity_Id *x, gt_pointer_operator op, void *cookie)
-{
- op (x, NULL, cookie);
-}
-
struct dummy_type_hasher : ggc_cache_ptr_hash<tree_entity_vec_map>
{
static inline hashval_t
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index ddc7b6d..f5eadbb 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -2700,11 +2700,9 @@ Case_Statement_to_gnu (Node_Id gnat_node)
never been problematic, but not for case expressions in Ada 2012. */
if (choices_added_p)
{
- const bool is_case_expression
- = (Nkind (Parent (gnat_node)) == N_Expression_With_Actions);
- tree group
- = build_stmt_group (Statements (gnat_when), !is_case_expression);
- bool group_may_fallthru = block_may_fallthru (group);
+ const bool case_expr_p = From_Conditional_Expression (gnat_node);
+ tree group = build_stmt_group (Statements (gnat_when), !case_expr_p);
+ const bool group_may_fallthru = block_may_fallthru (group);
add_stmt (group);
if (group_may_fallthru)
{
@@ -3904,8 +3902,11 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
gnu_return_var_elmt = NULL_TREE;
/* If the function returns by invisible reference, make it explicit in the
- function body. See gnat_to_gnu_subprog_type for more details. */
- if (TREE_ADDRESSABLE (gnu_subprog_type))
+ function body, but beware that maybe_make_gnu_thunk may already have done
+ it if the function is inlined across units. See gnat_to_gnu_subprog_type
+ for more details. */
+ if (TREE_ADDRESSABLE (gnu_subprog_type)
+ && TREE_CODE (TREE_TYPE (gnu_result_decl)) != REFERENCE_TYPE)
{
TREE_TYPE (gnu_result_decl)
= build_reference_type (TREE_TYPE (gnu_result_decl));
@@ -11017,7 +11018,7 @@ maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk)
same transformation as Subprogram_Body_to_gnu here. */
if (TREE_ADDRESSABLE (TREE_TYPE (gnu_target))
&& DECL_EXTERNAL (gnu_target)
- && !POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (gnu_target))))
+ && TREE_CODE (TREE_TYPE (DECL_RESULT (gnu_target))) != REFERENCE_TYPE)
{
TREE_TYPE (DECL_RESULT (gnu_target))
= build_reference_type (TREE_TYPE (DECL_RESULT (gnu_target)));
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index e74036e..78c4968 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -712,27 +712,6 @@ procedure Gnat1drv is
Suppress_Options.Suppress (Alignment_Check) := True;
end if;
- -- Set switch indicating if back end can handle limited types, and
- -- guarantee that no incorrect copies are made (e.g. in the context
- -- of an if or case expression).
-
- -- Debug flag -gnatd.L decisively sets usage on
-
- if Debug_Flag_Dot_LL then
- Back_End_Handles_Limited_Types := True;
-
- -- If no debug flag, usage off for SCIL cases
-
- elsif Generate_SCIL then
- Back_End_Handles_Limited_Types := False;
-
- -- Otherwise normal gcc back end, for now still turn flag off by
- -- default, since there are unresolved problems in the front end.
-
- else
- Back_End_Handles_Limited_Types := False;
- end if;
-
-- Return slot support is disabled if -gnatd_r is specified
if Debug_Flag_Underscore_R then
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index a5ee992..b28e6eb 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT Reference Manual , Jun 01, 2023
+GNAT Reference Manual , Jul 04, 2023
AdaCore
@@ -521,7 +521,9 @@ Partition-Wide Restrictions
* No_Unchecked_Access::
* No_Unchecked_Conversion::
* No_Unchecked_Deallocation::
+* No_Use_Of_Attribute::
* No_Use_Of_Entity::
+* No_Use_Of_Pragma::
* Pure_Barriers::
* Simple_Barriers::
* Static_Priorities::
@@ -12121,7 +12123,9 @@ then all compilation units in the partition must obey the restriction).
* No_Unchecked_Access::
* No_Unchecked_Conversion::
* No_Unchecked_Deallocation::
+* No_Use_Of_Attribute::
* No_Use_Of_Entity::
+* No_Use_Of_Pragma::
* Pure_Barriers::
* Simple_Barriers::
* Static_Priorities::
@@ -13106,7 +13110,7 @@ occurrences of the Unchecked_Access attribute.
[RM J.13] This restriction ensures at compile time that there are no semantic
dependences on the predefined generic function Unchecked_Conversion.
-@node No_Unchecked_Deallocation,No_Use_Of_Entity,No_Unchecked_Conversion,Partition-Wide Restrictions
+@node No_Unchecked_Deallocation,No_Use_Of_Attribute,No_Unchecked_Conversion,Partition-Wide Restrictions
@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{202}
@subsection No_Unchecked_Deallocation
@@ -13116,8 +13120,18 @@ dependences on the predefined generic function Unchecked_Conversion.
[RM J.13] This restriction ensures at compile time that there are no semantic
dependences on the predefined generic procedure Unchecked_Deallocation.
-@node No_Use_Of_Entity,Pure_Barriers,No_Unchecked_Deallocation,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{203}
+@node No_Use_Of_Attribute,No_Use_Of_Entity,No_Unchecked_Deallocation,Partition-Wide Restrictions
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-attribute}@anchor{203}
+@subsection No_Use_Of_Attribute
+
+
+@geindex No_Use_Of_Attribute
+
+[RM 13.12.1] This is a standard Ada 2012 restriction that is GNAT defined in
+earlier versions of Ada.
+
+@node No_Use_Of_Entity,No_Use_Of_Pragma,No_Use_Of_Attribute,Partition-Wide Restrictions
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{204}
@subsection No_Use_Of_Entity
@@ -13136,8 +13150,18 @@ where @code{Name} is the fully qualified entity, for example
No_Use_Of_Entity => Ada.Text_IO.Put_Line
@end example
-@node Pure_Barriers,Simple_Barriers,No_Use_Of_Entity,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{204}
+@node No_Use_Of_Pragma,Pure_Barriers,No_Use_Of_Entity,Partition-Wide Restrictions
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-pragma}@anchor{205}
+@subsection No_Use_Of_Pragma
+
+
+@geindex No_Use_Of_Pragma
+
+[RM 13.12.1] This is a standard Ada 2012 restriction that is GNAT defined in
+earlier versions of Ada.
+
+@node Pure_Barriers,Simple_Barriers,No_Use_Of_Pragma,Partition-Wide Restrictions
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{206}
@subsection Pure_Barriers
@@ -13188,7 +13212,7 @@ but still ensures absence of side effects, exceptions, and recursion
during the evaluation of the barriers.
@node Simple_Barriers,Static_Priorities,Pure_Barriers,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{205}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{207}
@subsection Simple_Barriers
@@ -13207,7 +13231,7 @@ compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
@node Static_Priorities,Static_Storage_Size,Simple_Barriers,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{206}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{208}
@subsection Static_Priorities
@@ -13218,7 +13242,7 @@ are static, and that there are no dependences on the package
@code{Ada.Dynamic_Priorities}.
@node Static_Storage_Size,,Static_Priorities,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{207}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{209}
@subsection Static_Storage_Size
@@ -13228,7 +13252,7 @@ are static, and that there are no dependences on the package
in a Storage_Size pragma or attribute definition clause is static.
@node Program Unit Level Restrictions,,Partition-Wide Restrictions,Standard and Implementation Defined Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{208}@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{209}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{20a}@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{20b}
@section Program Unit Level Restrictions
@@ -13259,7 +13283,7 @@ other compilation units in the partition.
@end menu
@node No_Elaboration_Code,No_Dynamic_Accessibility_Checks,,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{20a}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{20c}
@subsection No_Elaboration_Code
@@ -13315,7 +13339,7 @@ associated with the unit. This counter is typically used to check for access
before elaboration and to control multiple elaboration attempts.
@node No_Dynamic_Accessibility_Checks,No_Dynamic_Sized_Objects,No_Elaboration_Code,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-accessibility-checks}@anchor{20b}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-accessibility-checks}@anchor{20d}
@subsection No_Dynamic_Accessibility_Checks
@@ -13364,7 +13388,7 @@ In all other cases, the level of T is as defined by the existing rules of Ada.
@end itemize
@node No_Dynamic_Sized_Objects,No_Entry_Queue,No_Dynamic_Accessibility_Checks,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{20c}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{20e}
@subsection No_Dynamic_Sized_Objects
@@ -13382,7 +13406,7 @@ access discriminants. It is often a good idea to combine this restriction
with No_Secondary_Stack.
@node No_Entry_Queue,No_Implementation_Aspect_Specifications,No_Dynamic_Sized_Objects,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{20d}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{20f}
@subsection No_Entry_Queue
@@ -13395,7 +13419,7 @@ checked at compile time. A program execution is erroneous if an attempt
is made to queue a second task on such an entry.
@node No_Implementation_Aspect_Specifications,No_Implementation_Attributes,No_Entry_Queue,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{20e}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{210}
@subsection No_Implementation_Aspect_Specifications
@@ -13406,7 +13430,7 @@ GNAT-defined aspects are present. With this restriction, the only
aspects that can be used are those defined in the Ada Reference Manual.
@node No_Implementation_Attributes,No_Implementation_Identifiers,No_Implementation_Aspect_Specifications,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{20f}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{211}
@subsection No_Implementation_Attributes
@@ -13418,7 +13442,7 @@ attributes that can be used are those defined in the Ada Reference
Manual.
@node No_Implementation_Identifiers,No_Implementation_Pragmas,No_Implementation_Attributes,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{210}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{212}
@subsection No_Implementation_Identifiers
@@ -13429,7 +13453,7 @@ implementation-defined identifiers (marked with pragma Implementation_Defined)
occur within language-defined packages.
@node No_Implementation_Pragmas,No_Implementation_Restrictions,No_Implementation_Identifiers,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{211}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{213}
@subsection No_Implementation_Pragmas
@@ -13440,7 +13464,7 @@ GNAT-defined pragmas are present. With this restriction, the only
pragmas that can be used are those defined in the Ada Reference Manual.
@node No_Implementation_Restrictions,No_Implementation_Units,No_Implementation_Pragmas,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{212}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{214}
@subsection No_Implementation_Restrictions
@@ -13452,7 +13476,7 @@ are present. With this restriction, the only other restriction identifiers
that can be used are those defined in the Ada Reference Manual.
@node No_Implementation_Units,No_Implicit_Aliasing,No_Implementation_Restrictions,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{213}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{215}
@subsection No_Implementation_Units
@@ -13463,7 +13487,7 @@ mention in the context clause of any implementation-defined descendants
of packages Ada, Interfaces, or System.
@node No_Implicit_Aliasing,No_Implicit_Loops,No_Implementation_Units,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{214}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{216}
@subsection No_Implicit_Aliasing
@@ -13478,7 +13502,7 @@ to be aliased, and in such cases, it can always be replaced by
the standard attribute Unchecked_Access which is preferable.
@node No_Implicit_Loops,No_Obsolescent_Features,No_Implicit_Aliasing,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{215}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{217}
@subsection No_Implicit_Loops
@@ -13495,7 +13519,7 @@ arrays larger than about 5000 scalar components. Note that if this restriction
is set in the spec of a package, it will not apply to its body.
@node No_Obsolescent_Features,No_Wide_Characters,No_Implicit_Loops,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{216}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{218}
@subsection No_Obsolescent_Features
@@ -13505,7 +13529,7 @@ is set in the spec of a package, it will not apply to its body.
features are used, as defined in Annex J of the Ada Reference Manual.
@node No_Wide_Characters,Static_Dispatch_Tables,No_Obsolescent_Features,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{217}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{219}
@subsection No_Wide_Characters
@@ -13519,7 +13543,7 @@ appear in the program (that is literals representing characters not in
type @code{Character}).
@node Static_Dispatch_Tables,SPARK_05,No_Wide_Characters,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{218}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{21a}
@subsection Static_Dispatch_Tables
@@ -13529,7 +13553,7 @@ type @code{Character}).
associated with dispatch tables can be placed in read-only memory.
@node SPARK_05,,Static_Dispatch_Tables,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{219}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{21b}
@subsection SPARK_05
@@ -13552,7 +13576,7 @@ gnatprove -P project.gpr --mode=check_all
@end example
@node Implementation Advice,Implementation Defined Characteristics,Standard and Implementation Defined Restrictions,Top
-@anchor{gnat_rm/implementation_advice doc}@anchor{21a}@anchor{gnat_rm/implementation_advice id1}@anchor{21b}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}
+@anchor{gnat_rm/implementation_advice doc}@anchor{21c}@anchor{gnat_rm/implementation_advice id1}@anchor{21d}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}
@chapter Implementation Advice
@@ -13650,7 +13674,7 @@ case the text describes what GNAT does and why.
@end menu
@node RM 1 1 3 20 Error Detection,RM 1 1 3 31 Child Units,,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{21c}
+@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{21e}
@section RM 1.1.3(20): Error Detection
@@ -13667,7 +13691,7 @@ or diagnosed at compile time.
@geindex Child Units
@node RM 1 1 3 31 Child Units,RM 1 1 5 12 Bounded Errors,RM 1 1 3 20 Error Detection,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{21d}
+@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{21f}
@section RM 1.1.3(31): Child Units
@@ -13683,7 +13707,7 @@ Followed.
@geindex Bounded errors
@node RM 1 1 5 12 Bounded Errors,RM 2 8 16 Pragmas,RM 1 1 3 31 Child Units,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{21e}
+@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{220}
@section RM 1.1.5(12): Bounded Errors
@@ -13700,7 +13724,7 @@ runtime.
@geindex Pragmas
@node RM 2 8 16 Pragmas,RM 2 8 17-19 Pragmas,RM 1 1 5 12 Bounded Errors,Implementation Advice
-@anchor{gnat_rm/implementation_advice id2}@anchor{21f}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{220}
+@anchor{gnat_rm/implementation_advice id2}@anchor{221}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{222}
@section RM 2.8(16): Pragmas
@@ -13813,7 +13837,7 @@ that this advice not be followed. For details see
@ref{7,,Implementation Defined Pragmas}.
@node RM 2 8 17-19 Pragmas,RM 3 5 2 5 Alternative Character Sets,RM 2 8 16 Pragmas,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{221}
+@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{223}
@section RM 2.8(17-19): Pragmas
@@ -13834,14 +13858,14 @@ replacing @code{library_items}.”
@end itemize
@end quotation
-See @ref{220,,RM 2.8(16); Pragmas}.
+See @ref{222,,RM 2.8(16); Pragmas}.
@geindex Character Sets
@geindex Alternative Character Sets
@node RM 3 5 2 5 Alternative Character Sets,RM 3 5 4 28 Integer Types,RM 2 8 17-19 Pragmas,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{222}
+@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{224}
@section RM 3.5.2(5): Alternative Character Sets
@@ -13869,7 +13893,7 @@ there is no such restriction.
@geindex Integer types
@node RM 3 5 4 28 Integer Types,RM 3 5 4 29 Integer Types,RM 3 5 2 5 Alternative Character Sets,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{223}
+@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{225}
@section RM 3.5.4(28): Integer Types
@@ -13888,7 +13912,7 @@ are supported for convenient interface to C, and so that all hardware
types of the machine are easily available.
@node RM 3 5 4 29 Integer Types,RM 3 5 5 8 Enumeration Values,RM 3 5 4 28 Integer Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{224}
+@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{226}
@section RM 3.5.4(29): Integer Types
@@ -13904,7 +13928,7 @@ Followed.
@geindex Enumeration values
@node RM 3 5 5 8 Enumeration Values,RM 3 5 7 17 Float Types,RM 3 5 4 29 Integer Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{225}
+@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{227}
@section RM 3.5.5(8): Enumeration Values
@@ -13924,7 +13948,7 @@ Followed.
@geindex Float types
@node RM 3 5 7 17 Float Types,RM 3 6 2 11 Multidimensional Arrays,RM 3 5 5 8 Enumeration Values,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{226}
+@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{228}
@section RM 3.5.7(17): Float Types
@@ -13954,7 +13978,7 @@ is a software rather than a hardware format.
@geindex multidimensional
@node RM 3 6 2 11 Multidimensional Arrays,RM 9 6 30-31 Duration’Small,RM 3 5 7 17 Float Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{227}
+@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{229}
@section RM 3.6.2(11): Multidimensional Arrays
@@ -13972,7 +13996,7 @@ Followed.
@geindex Duration'Small
@node RM 9 6 30-31 Duration’Small,RM 10 2 1 12 Consistent Representation,RM 3 6 2 11 Multidimensional Arrays,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{228}
+@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{22a}
@section RM 9.6(30-31): Duration’Small
@@ -13993,7 +14017,7 @@ it need not be the same time base as used for @code{Calendar.Clock}.”
Followed.
@node RM 10 2 1 12 Consistent Representation,RM 11 4 1 19 Exception Information,RM 9 6 30-31 Duration’Small,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{229}
+@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{22b}
@section RM 10.2.1(12): Consistent Representation
@@ -14015,7 +14039,7 @@ advice without severely impacting efficiency of execution.
@geindex Exception information
@node RM 11 4 1 19 Exception Information,RM 11 5 28 Suppression of Checks,RM 10 2 1 12 Consistent Representation,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{22a}
+@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{22c}
@section RM 11.4.1(19): Exception Information
@@ -14046,7 +14070,7 @@ Pragma @code{Discard_Names}.
@geindex suppression of
@node RM 11 5 28 Suppression of Checks,RM 13 1 21-24 Representation Clauses,RM 11 4 1 19 Exception Information,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{22b}
+@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{22d}
@section RM 11.5(28): Suppression of Checks
@@ -14061,7 +14085,7 @@ Followed.
@geindex Representation clauses
@node RM 13 1 21-24 Representation Clauses,RM 13 2 6-8 Packed Types,RM 11 5 28 Suppression of Checks,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{22c}
+@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{22e}
@section RM 13.1 (21-24): Representation Clauses
@@ -14110,7 +14134,7 @@ Followed.
@geindex Packed types
@node RM 13 2 6-8 Packed Types,RM 13 3 14-19 Address Clauses,RM 13 1 21-24 Representation Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{22d}
+@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{22f}
@section RM 13.2(6-8): Packed Types
@@ -14141,7 +14165,7 @@ subcomponent of the packed type.
@geindex Address clauses
@node RM 13 3 14-19 Address Clauses,RM 13 3 29-35 Alignment Clauses,RM 13 2 6-8 Packed Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{22e}
+@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{230}
@section RM 13.3(14-19): Address Clauses
@@ -14194,7 +14218,7 @@ Followed.
@geindex Alignment clauses
@node RM 13 3 29-35 Alignment Clauses,RM 13 3 42-43 Size Clauses,RM 13 3 14-19 Address Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{22f}
+@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{231}
@section RM 13.3(29-35): Alignment Clauses
@@ -14251,7 +14275,7 @@ Followed.
@geindex Size clauses
@node RM 13 3 42-43 Size Clauses,RM 13 3 50-56 Size Clauses,RM 13 3 29-35 Alignment Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{230}
+@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{232}
@section RM 13.3(42-43): Size Clauses
@@ -14269,7 +14293,7 @@ object’s @code{Alignment} (if the @code{Alignment} is nonzero).”
Followed.
@node RM 13 3 50-56 Size Clauses,RM 13 3 71-73 Component Size Clauses,RM 13 3 42-43 Size Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{231}
+@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{233}
@section RM 13.3(50-56): Size Clauses
@@ -14320,7 +14344,7 @@ Followed.
@geindex Component_Size clauses
@node RM 13 3 71-73 Component Size Clauses,RM 13 4 9-10 Enumeration Representation Clauses,RM 13 3 50-56 Size Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{232}
+@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{234}
@section RM 13.3(71-73): Component Size Clauses
@@ -14354,7 +14378,7 @@ Followed.
@geindex enumeration
@node RM 13 4 9-10 Enumeration Representation Clauses,RM 13 5 1 17-22 Record Representation Clauses,RM 13 3 71-73 Component Size Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{233}
+@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{235}
@section RM 13.4(9-10): Enumeration Representation Clauses
@@ -14376,7 +14400,7 @@ Followed.
@geindex records
@node RM 13 5 1 17-22 Record Representation Clauses,RM 13 5 2 5 Storage Place Attributes,RM 13 4 9-10 Enumeration Representation Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{234}
+@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{236}
@section RM 13.5.1(17-22): Record Representation Clauses
@@ -14436,7 +14460,7 @@ and all mentioned features are implemented.
@geindex Storage place attributes
@node RM 13 5 2 5 Storage Place Attributes,RM 13 5 3 7-8 Bit Ordering,RM 13 5 1 17-22 Record Representation Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{235}
+@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{237}
@section RM 13.5.2(5): Storage Place Attributes
@@ -14456,7 +14480,7 @@ Followed. There are no such components in GNAT.
@geindex Bit ordering
@node RM 13 5 3 7-8 Bit Ordering,RM 13 7 37 Address as Private,RM 13 5 2 5 Storage Place Attributes,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{236}
+@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{238}
@section RM 13.5.3(7-8): Bit Ordering
@@ -14476,7 +14500,7 @@ Thus non-default bit ordering is not supported.
@geindex as private type
@node RM 13 7 37 Address as Private,RM 13 7 1 16 Address Operations,RM 13 5 3 7-8 Bit Ordering,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{237}
+@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{239}
@section RM 13.7(37): Address as Private
@@ -14494,7 +14518,7 @@ Followed.
@geindex operations of
@node RM 13 7 1 16 Address Operations,RM 13 9 14-17 Unchecked Conversion,RM 13 7 37 Address as Private,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{238}
+@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{23a}
@section RM 13.7.1(16): Address Operations
@@ -14512,7 +14536,7 @@ operation raises @code{Program_Error}, since all operations make sense.
@geindex Unchecked conversion
@node RM 13 9 14-17 Unchecked Conversion,RM 13 11 23-25 Implicit Heap Usage,RM 13 7 1 16 Address Operations,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{239}
+@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{23b}
@section RM 13.9(14-17): Unchecked Conversion
@@ -14556,7 +14580,7 @@ Followed.
@geindex implicit
@node RM 13 11 23-25 Implicit Heap Usage,RM 13 11 2 17 Unchecked Deallocation,RM 13 9 14-17 Unchecked Conversion,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{23a}
+@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{23c}
@section RM 13.11(23-25): Implicit Heap Usage
@@ -14607,7 +14631,7 @@ Followed.
@geindex Unchecked deallocation
@node RM 13 11 2 17 Unchecked Deallocation,RM 13 13 2 1 6 Stream Oriented Attributes,RM 13 11 23-25 Implicit Heap Usage,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{23b}
+@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{23d}
@section RM 13.11.2(17): Unchecked Deallocation
@@ -14622,7 +14646,7 @@ Followed.
@geindex Stream oriented attributes
@node RM 13 13 2 1 6 Stream Oriented Attributes,RM A 1 52 Names of Predefined Numeric Types,RM 13 11 2 17 Unchecked Deallocation,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{23c}
+@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{23e}
@section RM 13.13.2(1.6): Stream Oriented Attributes
@@ -14653,7 +14677,7 @@ scalar types. This XDR alternative can be enabled via the binder switch -xdr.
@geindex Stream oriented attributes
@node RM A 1 52 Names of Predefined Numeric Types,RM A 3 2 49 Ada Characters Handling,RM 13 13 2 1 6 Stream Oriented Attributes,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{23d}
+@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{23f}
@section RM A.1(52): Names of Predefined Numeric Types
@@ -14671,7 +14695,7 @@ Followed.
@geindex Ada.Characters.Handling
@node RM A 3 2 49 Ada Characters Handling,RM A 4 4 106 Bounded-Length String Handling,RM A 1 52 Names of Predefined Numeric Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{23e}
+@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{240}
@section RM A.3.2(49): @code{Ada.Characters.Handling}
@@ -14688,7 +14712,7 @@ Followed. GNAT provides no such localized definitions.
@geindex Bounded-length strings
@node RM A 4 4 106 Bounded-Length String Handling,RM A 5 2 46-47 Random Number Generation,RM A 3 2 49 Ada Characters Handling,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{23f}
+@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{241}
@section RM A.4.4(106): Bounded-Length String Handling
@@ -14703,7 +14727,7 @@ Followed. No implicit pointers or dynamic allocation are used.
@geindex Random number generation
@node RM A 5 2 46-47 Random Number Generation,RM A 10 7 23 Get_Immediate,RM A 4 4 106 Bounded-Length String Handling,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{240}
+@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{242}
@section RM A.5.2(46-47): Random Number Generation
@@ -14732,7 +14756,7 @@ condition here to hold true.
@geindex Get_Immediate
@node RM A 10 7 23 Get_Immediate,RM A 18 Containers,RM A 5 2 46-47 Random Number Generation,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{241}
+@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{243}
@section RM A.10.7(23): @code{Get_Immediate}
@@ -14756,7 +14780,7 @@ this functionality.
@geindex Containers
@node RM A 18 Containers,RM B 1 39-41 Pragma Export,RM A 10 7 23 Get_Immediate,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-18-containers}@anchor{242}
+@anchor{gnat_rm/implementation_advice rm-a-18-containers}@anchor{244}
@section RM A.18: @code{Containers}
@@ -14777,7 +14801,7 @@ follow the implementation advice.
@geindex Export
@node RM B 1 39-41 Pragma Export,RM B 2 12-13 Package Interfaces,RM A 18 Containers,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{243}
+@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{245}
@section RM B.1(39-41): Pragma @code{Export}
@@ -14825,7 +14849,7 @@ Followed.
@geindex Interfaces
@node RM B 2 12-13 Package Interfaces,RM B 3 63-71 Interfacing with C,RM B 1 39-41 Pragma Export,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{244}
+@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{246}
@section RM B.2(12-13): Package @code{Interfaces}
@@ -14855,7 +14879,7 @@ Followed. GNAT provides all the packages described in this section.
@geindex interfacing with
@node RM B 3 63-71 Interfacing with C,RM B 4 95-98 Interfacing with COBOL,RM B 2 12-13 Package Interfaces,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{245}
+@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{247}
@section RM B.3(63-71): Interfacing with C
@@ -14943,7 +14967,7 @@ Followed.
@geindex interfacing with
@node RM B 4 95-98 Interfacing with COBOL,RM B 5 22-26 Interfacing with Fortran,RM B 3 63-71 Interfacing with C,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{246}
+@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{248}
@section RM B.4(95-98): Interfacing with COBOL
@@ -14984,7 +15008,7 @@ Followed.
@geindex interfacing with
@node RM B 5 22-26 Interfacing with Fortran,RM C 1 3-5 Access to Machine Operations,RM B 4 95-98 Interfacing with COBOL,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{247}
+@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{249}
@section RM B.5(22-26): Interfacing with Fortran
@@ -15035,7 +15059,7 @@ Followed.
@geindex Machine operations
@node RM C 1 3-5 Access to Machine Operations,RM C 1 10-16 Access to Machine Operations,RM B 5 22-26 Interfacing with Fortran,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{248}
+@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{24a}
@section RM C.1(3-5): Access to Machine Operations
@@ -15070,7 +15094,7 @@ object that is specified as exported.”
Followed.
@node RM C 1 10-16 Access to Machine Operations,RM C 3 28 Interrupt Support,RM C 1 3-5 Access to Machine Operations,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{249}
+@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{24b}
@section RM C.1(10-16): Access to Machine Operations
@@ -15131,7 +15155,7 @@ Followed on any target supporting such operations.
@geindex Interrupt support
@node RM C 3 28 Interrupt Support,RM C 3 1 20-21 Protected Procedure Handlers,RM C 1 10-16 Access to Machine Operations,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{24a}
+@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{24c}
@section RM C.3(28): Interrupt Support
@@ -15149,7 +15173,7 @@ of interrupt blocking.
@geindex Protected procedure handlers
@node RM C 3 1 20-21 Protected Procedure Handlers,RM C 3 2 25 Package Interrupts,RM C 3 28 Interrupt Support,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{24b}
+@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{24d}
@section RM C.3.1(20-21): Protected Procedure Handlers
@@ -15175,7 +15199,7 @@ Followed. Compile time warnings are given when possible.
@geindex Interrupts
@node RM C 3 2 25 Package Interrupts,RM C 4 14 Pre-elaboration Requirements,RM C 3 1 20-21 Protected Procedure Handlers,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{24c}
+@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{24e}
@section RM C.3.2(25): Package @code{Interrupts}
@@ -15193,7 +15217,7 @@ Followed.
@geindex Pre-elaboration requirements
@node RM C 4 14 Pre-elaboration Requirements,RM C 5 8 Pragma Discard_Names,RM C 3 2 25 Package Interrupts,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{24d}
+@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{24f}
@section RM C.4(14): Pre-elaboration Requirements
@@ -15209,7 +15233,7 @@ Followed. Executable code is generated in some cases, e.g., loops
to initialize large arrays.
@node RM C 5 8 Pragma Discard_Names,RM C 7 2 30 The Package Task_Attributes,RM C 4 14 Pre-elaboration Requirements,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{24e}
+@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{250}
@section RM C.5(8): Pragma @code{Discard_Names}
@@ -15227,7 +15251,7 @@ Followed.
@geindex Task_Attributes
@node RM C 7 2 30 The Package Task_Attributes,RM D 3 17 Locking Policies,RM C 5 8 Pragma Discard_Names,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{24f}
+@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{251}
@section RM C.7.2(30): The Package Task_Attributes
@@ -15248,7 +15272,7 @@ Not followed. This implementation is not targeted to such a domain.
@geindex Locking Policies
@node RM D 3 17 Locking Policies,RM D 4 16 Entry Queuing Policies,RM C 7 2 30 The Package Task_Attributes,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{250}
+@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{252}
@section RM D.3(17): Locking Policies
@@ -15265,7 +15289,7 @@ whose names (@code{Inheritance_Locking} and
@geindex Entry queuing policies
@node RM D 4 16 Entry Queuing Policies,RM D 6 9-10 Preemptive Abort,RM D 3 17 Locking Policies,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{251}
+@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{253}
@section RM D.4(16): Entry Queuing Policies
@@ -15280,7 +15304,7 @@ Followed. No such implementation-defined queuing policies exist.
@geindex Preemptive abort
@node RM D 6 9-10 Preemptive Abort,RM D 7 21 Tasking Restrictions,RM D 4 16 Entry Queuing Policies,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{252}
+@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{254}
@section RM D.6(9-10): Preemptive Abort
@@ -15306,7 +15330,7 @@ Followed.
@geindex Tasking restrictions
@node RM D 7 21 Tasking Restrictions,RM D 8 47-49 Monotonic Time,RM D 6 9-10 Preemptive Abort,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{253}
+@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{255}
@section RM D.7(21): Tasking Restrictions
@@ -15325,7 +15349,7 @@ pragma @code{Profile (Restricted)} for more details.
@geindex monotonic
@node RM D 8 47-49 Monotonic Time,RM E 5 28-29 Partition Communication Subsystem,RM D 7 21 Tasking Restrictions,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{254}
+@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{256}
@section RM D.8(47-49): Monotonic Time
@@ -15360,7 +15384,7 @@ Followed.
@geindex PCS
@node RM E 5 28-29 Partition Communication Subsystem,RM F 7 COBOL Support,RM D 8 47-49 Monotonic Time,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{255}
+@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{257}
@section RM E.5(28-29): Partition Communication Subsystem
@@ -15388,7 +15412,7 @@ GNAT.
@geindex COBOL support
@node RM F 7 COBOL Support,RM F 1 2 Decimal Radix Support,RM E 5 28-29 Partition Communication Subsystem,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{256}
+@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{258}
@section RM F(7): COBOL Support
@@ -15408,7 +15432,7 @@ Followed.
@geindex Decimal radix support
@node RM F 1 2 Decimal Radix Support,RM G Numerics,RM F 7 COBOL Support,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{257}
+@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{259}
@section RM F.1(2): Decimal Radix Support
@@ -15424,7 +15448,7 @@ representations.
@geindex Numerics
@node RM G Numerics,RM G 1 1 56-58 Complex Types,RM F 1 2 Decimal Radix Support,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{258}
+@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{25a}
@section RM G: Numerics
@@ -15444,7 +15468,7 @@ Followed.
@geindex Complex types
@node RM G 1 1 56-58 Complex Types,RM G 1 2 49 Complex Elementary Functions,RM G Numerics,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{259}
+@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{25b}
@section RM G.1.1(56-58): Complex Types
@@ -15506,7 +15530,7 @@ Followed.
@geindex Complex elementary functions
@node RM G 1 2 49 Complex Elementary Functions,RM G 2 4 19 Accuracy Requirements,RM G 1 1 56-58 Complex Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{25a}
+@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{25c}
@section RM G.1.2(49): Complex Elementary Functions
@@ -15528,7 +15552,7 @@ Followed.
@geindex Accuracy requirements
@node RM G 2 4 19 Accuracy Requirements,RM G 2 6 15 Complex Arithmetic Accuracy,RM G 1 2 49 Complex Elementary Functions,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{25b}
+@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{25d}
@section RM G.2.4(19): Accuracy Requirements
@@ -15552,7 +15576,7 @@ Followed.
@geindex complex arithmetic
@node RM G 2 6 15 Complex Arithmetic Accuracy,RM H 6 15/2 Pragma Partition_Elaboration_Policy,RM G 2 4 19 Accuracy Requirements,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{25c}
+@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{25e}
@section RM G.2.6(15): Complex Arithmetic Accuracy
@@ -15570,7 +15594,7 @@ Followed.
@geindex Sequential elaboration policy
@node RM H 6 15/2 Pragma Partition_Elaboration_Policy,,RM G 2 6 15 Complex Arithmetic Accuracy,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{25d}
+@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{25f}
@section RM H.6(15/2): Pragma Partition_Elaboration_Policy
@@ -15585,7 +15609,7 @@ immediately terminated.”
Not followed.
@node Implementation Defined Characteristics,Intrinsic Subprograms,Implementation Advice,Top
-@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{25e}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{25f}@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}
+@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{260}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{261}@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}
@chapter Implementation Defined Characteristics
@@ -16880,7 +16904,7 @@ When the @code{Pattern} parameter is not the null string, it is interpreted
according to the syntax of regular expressions as defined in the
@code{GNAT.Regexp} package.
-See @ref{260,,GNAT.Regexp (g-regexp.ads)}.
+See @ref{262,,GNAT.Regexp (g-regexp.ads)}.
@itemize *
@@ -17978,7 +18002,7 @@ Information on those subjects is not yet available.
Execution is erroneous in that case.
@node Intrinsic Subprograms,Representation Clauses and Pragmas,Implementation Defined Characteristics,Top
-@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{261}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{262}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}
+@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{263}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{264}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}
@chapter Intrinsic Subprograms
@@ -18016,7 +18040,7 @@ Ada standard does not require Ada compilers to implement this feature.
@end menu
@node Intrinsic Operators,Compilation_ISO_Date,,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{263}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{264}
+@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{265}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{266}
@section Intrinsic Operators
@@ -18047,7 +18071,7 @@ It is also possible to specify such operators for private types, if the
full views are appropriate arithmetic types.
@node Compilation_ISO_Date,Compilation_Date,Intrinsic Operators,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{265}@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{266}
+@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{267}@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{268}
@section Compilation_ISO_Date
@@ -18061,7 +18085,7 @@ application program should simply call the function
the current compilation (in local time format YYYY-MM-DD).
@node Compilation_Date,Compilation_Time,Compilation_ISO_Date,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{267}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{268}
+@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{269}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{26a}
@section Compilation_Date
@@ -18071,7 +18095,7 @@ Same as Compilation_ISO_Date, except the string is in the form
MMM DD YYYY.
@node Compilation_Time,Enclosing_Entity,Compilation_Date,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{269}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{26a}
+@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{26b}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{26c}
@section Compilation_Time
@@ -18085,7 +18109,7 @@ application program should simply call the function
the current compilation (in local time format HH:MM:SS).
@node Enclosing_Entity,Exception_Information,Compilation_Time,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{26b}@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{26c}
+@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{26d}@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{26e}
@section Enclosing_Entity
@@ -18099,7 +18123,7 @@ application program should simply call the function
the current subprogram, package, task, entry, or protected subprogram.
@node Exception_Information,Exception_Message,Enclosing_Entity,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{26d}@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{26e}
+@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{26f}@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{270}
@section Exception_Information
@@ -18113,7 +18137,7 @@ so an application program should simply call the function
the exception information associated with the current exception.
@node Exception_Message,Exception_Name,Exception_Information,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{26f}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{270}
+@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{271}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{272}
@section Exception_Message
@@ -18127,7 +18151,7 @@ so an application program should simply call the function
the message associated with the current exception.
@node Exception_Name,File,Exception_Message,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{271}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{272}
+@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{273}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{274}
@section Exception_Name
@@ -18141,7 +18165,7 @@ so an application program should simply call the function
the name of the current exception.
@node File,Line,Exception_Name,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms file}@anchor{273}@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{274}
+@anchor{gnat_rm/intrinsic_subprograms file}@anchor{275}@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{276}
@section File
@@ -18155,7 +18179,7 @@ application program should simply call the function
file.
@node Line,Shifts and Rotates,File,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{275}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{276}
+@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{277}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{278}
@section Line
@@ -18169,7 +18193,7 @@ application program should simply call the function
source line.
@node Shifts and Rotates,Source_Location,Line,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{277}@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{278}
+@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{279}@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{27a}
@section Shifts and Rotates
@@ -18212,7 +18236,7 @@ corresponding operator for modular type. In particular, shifting a negative
number may change its sign bit to positive.
@node Source_Location,,Shifts and Rotates,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{279}@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{27a}
+@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{27b}@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{27c}
@section Source_Location
@@ -18226,7 +18250,7 @@ application program should simply call the function
source file location.
@node Representation Clauses and Pragmas,Standard Library Routines,Intrinsic Subprograms,Top
-@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{27b}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{27c}@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}
+@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{27d}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{27e}@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}
@chapter Representation Clauses and Pragmas
@@ -18272,7 +18296,7 @@ and this section describes the additional capabilities provided.
@end menu
@node Alignment Clauses,Size Clauses,,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{27d}@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{27e}
+@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{27f}@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{280}
@section Alignment Clauses
@@ -18403,7 +18427,7 @@ assumption is non-portable, and other compilers may choose different
alignments for the subtype @code{RS}.
@node Size Clauses,Storage_Size Clauses,Alignment Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{27f}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{280}
+@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{281}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{282}
@section Size Clauses
@@ -18480,7 +18504,7 @@ if it is known that a Size value can be accommodated in an object of
type Integer.
@node Storage_Size Clauses,Size of Variant Record Objects,Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{281}@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{282}
+@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{283}@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{284}
@section Storage_Size Clauses
@@ -18553,7 +18577,7 @@ Of course in practice, there will not be any explicit allocators in the
case of such an access declaration.
@node Size of Variant Record Objects,Biased Representation,Storage_Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{283}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{284}
+@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{285}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{286}
@section Size of Variant Record Objects
@@ -18663,7 +18687,7 @@ the maximum size, regardless of the current variant value, the
variant value.
@node Biased Representation,Value_Size and Object_Size Clauses,Size of Variant Record Objects,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{285}@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{286}
+@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{287}@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{288}
@section Biased Representation
@@ -18701,7 +18725,7 @@ biased representation can be used for all discrete types except for
enumeration types for which a representation clause is given.
@node Value_Size and Object_Size Clauses,Component_Size Clauses,Biased Representation,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{287}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{288}
+@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{289}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{28a}
@section Value_Size and Object_Size Clauses
@@ -19017,7 +19041,7 @@ definition clause forces biased representation. This
warning can be turned off using @code{-gnatw.B}.
@node Component_Size Clauses,Bit_Order Clauses,Value_Size and Object_Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{289}@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{28a}
+@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{28b}@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{28c}
@section Component_Size Clauses
@@ -19065,7 +19089,7 @@ and a pragma Pack for the same array type. if such duplicate
clauses are given, the pragma Pack will be ignored.
@node Bit_Order Clauses,Effect of Bit_Order on Byte Ordering,Component_Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{28b}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{28c}
+@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{28d}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{28e}
@section Bit_Order Clauses
@@ -19171,7 +19195,7 @@ if desired. The following section contains additional
details regarding the issue of byte ordering.
@node Effect of Bit_Order on Byte Ordering,Pragma Pack for Arrays,Bit_Order Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{28d}@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{28e}
+@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{28f}@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{290}
@section Effect of Bit_Order on Byte Ordering
@@ -19428,7 +19452,7 @@ to set the boolean constant @code{Master_Byte_First} in
an appropriate manner.
@node Pragma Pack for Arrays,Pragma Pack for Records,Effect of Bit_Order on Byte Ordering,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{28f}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{290}
+@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{291}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{292}
@section Pragma Pack for Arrays
@@ -19548,7 +19572,7 @@ Here 31-bit packing is achieved as required, and no warning is generated,
since in this case the programmer intention is clear.
@node Pragma Pack for Records,Record Representation Clauses,Pragma Pack for Arrays,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{291}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{292}
+@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{293}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{294}
@section Pragma Pack for Records
@@ -19632,7 +19656,7 @@ array that is longer than 64 bits, so it is itself non-packable on
boundary, and takes an integral number of bytes, i.e., 72 bits.
@node Record Representation Clauses,Handling of Records with Holes,Pragma Pack for Records,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{293}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{294}
+@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{295}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{296}
@section Record Representation Clauses
@@ -19711,7 +19735,7 @@ end record;
@end example
@node Handling of Records with Holes,Enumeration Clauses,Record Representation Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{295}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{296}
+@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{297}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{298}
@section Handling of Records with Holes
@@ -19787,7 +19811,7 @@ for Hrec'Size use 64;
@end example
@node Enumeration Clauses,Address Clauses,Handling of Records with Holes,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{297}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{298}
+@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{299}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{29a}
@section Enumeration Clauses
@@ -19830,7 +19854,7 @@ the overhead of converting representation values to the corresponding
positional values, (i.e., the value delivered by the @code{Pos} attribute).
@node Address Clauses,Use of Address Clauses for Memory-Mapped I/O,Enumeration Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{299}@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{29a}
+@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{29b}@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{29c}
@section Address Clauses
@@ -20170,7 +20194,7 @@ then the program compiles without the warning and when run will generate
the output @code{X was not clobbered}.
@node Use of Address Clauses for Memory-Mapped I/O,Effect of Convention on Representation,Address Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{29b}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{29c}
+@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{29d}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{29e}
@section Use of Address Clauses for Memory-Mapped I/O
@@ -20228,7 +20252,7 @@ provides the pragma @code{Volatile_Full_Access} which can be used in lieu of
pragma @code{Atomic} and will give the additional guarantee.
@node Effect of Convention on Representation,Conventions and Anonymous Access Types,Use of Address Clauses for Memory-Mapped I/O,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{29d}@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{29e}
+@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{29f}@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{2a0}
@section Effect of Convention on Representation
@@ -20306,7 +20330,7 @@ when one of these values is read, any nonzero value is treated as True.
@end itemize
@node Conventions and Anonymous Access Types,Determining the Representations chosen by GNAT,Effect of Convention on Representation,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{29f}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{2a0}
+@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{2a1}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{2a2}
@section Conventions and Anonymous Access Types
@@ -20382,7 +20406,7 @@ package ConvComp is
@end example
@node Determining the Representations chosen by GNAT,,Conventions and Anonymous Access Types,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{2a1}@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{2a2}
+@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{2a3}@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{2a4}
@section Determining the Representations chosen by GNAT
@@ -20534,7 +20558,7 @@ generated by the compiler into the original source to fix and guarantee
the actual representation to be used.
@node Standard Library Routines,The Implementation of Standard I/O,Representation Clauses and Pragmas,Top
-@anchor{gnat_rm/standard_library_routines doc}@anchor{2a3}@anchor{gnat_rm/standard_library_routines id1}@anchor{2a4}@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}
+@anchor{gnat_rm/standard_library_routines doc}@anchor{2a5}@anchor{gnat_rm/standard_library_routines id1}@anchor{2a6}@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}
@chapter Standard Library Routines
@@ -21358,7 +21382,7 @@ For packages in Interfaces and System, all the RM defined packages are
available in GNAT, see the Ada 2012 RM for full details.
@node The Implementation of Standard I/O,The GNAT Library,Standard Library Routines,Top
-@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{2a5}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2a6}@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f}
+@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{2a7}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2a8}@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f}
@chapter The Implementation of Standard I/O
@@ -21410,7 +21434,7 @@ these additional facilities are also described in this chapter.
@end menu
@node Standard I/O Packages,FORM Strings,,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a7}@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2a8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a9}@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2aa}
@section Standard I/O Packages
@@ -21481,7 +21505,7 @@ flush the common I/O streams and in particular Standard_Output before
elaborating the Ada code.
@node FORM Strings,Direct_IO,Standard I/O Packages,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2a9}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2aa}
+@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2ab}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2ac}
@section FORM Strings
@@ -21507,7 +21531,7 @@ unrecognized keyword appears in a form string, it is silently ignored
and not considered invalid.
@node Direct_IO,Sequential_IO,FORM Strings,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2ab}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2ac}
+@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2ad}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2ae}
@section Direct_IO
@@ -21527,7 +21551,7 @@ There is no limit on the size of Direct_IO files, they are expanded as
necessary to accommodate whatever records are written to the file.
@node Sequential_IO,Text_IO,Direct_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2ad}@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2ae}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2af}@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2b0}
@section Sequential_IO
@@ -21574,7 +21598,7 @@ using Stream_IO, and this is the preferred mechanism. In particular, the
above program fragment rewritten to use Stream_IO will work correctly.
@node Text_IO,Wide_Text_IO,Sequential_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2af}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2b0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2b1}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2b2}
@section Text_IO
@@ -21657,7 +21681,7 @@ the file.
@end menu
@node Stream Pointer Positioning,Reading and Writing Non-Regular Files,,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2b1}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2b2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2b3}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2b4}
@subsection Stream Pointer Positioning
@@ -21693,7 +21717,7 @@ between two Ada files, then the difference may be observable in some
situations.
@node Reading and Writing Non-Regular Files,Get_Immediate,Stream Pointer Positioning,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2b3}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2b4}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2b5}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2b6}
@subsection Reading and Writing Non-Regular Files
@@ -21744,7 +21768,7 @@ to read data past that end of
file indication, until another end of file indication is entered.
@node Get_Immediate,Treating Text_IO Files as Streams,Reading and Writing Non-Regular Files,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2b5}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2b6}
+@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2b7}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2b8}
@subsection Get_Immediate
@@ -21762,7 +21786,7 @@ possible), it is undefined whether the FF character will be treated as a
page mark.
@node Treating Text_IO Files as Streams,Text_IO Extensions,Get_Immediate,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2b7}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2b8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2b9}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2ba}
@subsection Treating Text_IO Files as Streams
@@ -21778,7 +21802,7 @@ skipped and the effect is similar to that described above for
@code{Get_Immediate}.
@node Text_IO Extensions,Text_IO Facilities for Unbounded Strings,Treating Text_IO Files as Streams,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2b9}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2ba}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2bb}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2bc}
@subsection Text_IO Extensions
@@ -21806,7 +21830,7 @@ the string is to be read.
@end itemize
@node Text_IO Facilities for Unbounded Strings,,Text_IO Extensions,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2bb}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2bc}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2bd}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2be}
@subsection Text_IO Facilities for Unbounded Strings
@@ -21854,7 +21878,7 @@ files @code{a-szuzti.ads} and @code{a-szuzti.adb} provides similar extended
@code{Wide_Wide_Text_IO} functionality for unbounded wide wide strings.
@node Wide_Text_IO,Wide_Wide_Text_IO,Text_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2bd}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2be}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2bf}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2c0}
@section Wide_Text_IO
@@ -22101,12 +22125,12 @@ input also causes Constraint_Error to be raised.
@end menu
@node Stream Pointer Positioning<2>,Reading and Writing Non-Regular Files<2>,,Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2bf}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2c0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2c1}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2c2}
@subsection Stream Pointer Positioning
@code{Ada.Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling
-of stream pointer positioning (@ref{2b0,,Text_IO}). There is one additional
+of stream pointer positioning (@ref{2b2,,Text_IO}). There is one additional
case:
If @code{Ada.Wide_Text_IO.Look_Ahead} reads a character outside the
@@ -22125,7 +22149,7 @@ to a normal program using @code{Wide_Text_IO}. However, this discrepancy
can be observed if the wide text file shares a stream with another file.
@node Reading and Writing Non-Regular Files<2>,,Stream Pointer Positioning<2>,Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2c1}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2c2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2c3}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2c4}
@subsection Reading and Writing Non-Regular Files
@@ -22136,7 +22160,7 @@ treated as data characters), and @code{End_Of_Page} always returns
it is possible to read beyond an end of file.
@node Wide_Wide_Text_IO,Stream_IO,Wide_Text_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2c3}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2c4}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2c5}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2c6}
@section Wide_Wide_Text_IO
@@ -22305,12 +22329,12 @@ input also causes Constraint_Error to be raised.
@end menu
@node Stream Pointer Positioning<3>,Reading and Writing Non-Regular Files<3>,,Wide_Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2c5}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2c6}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2c7}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2c8}
@subsection Stream Pointer Positioning
@code{Ada.Wide_Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling
-of stream pointer positioning (@ref{2b0,,Text_IO}). There is one additional
+of stream pointer positioning (@ref{2b2,,Text_IO}). There is one additional
case:
If @code{Ada.Wide_Wide_Text_IO.Look_Ahead} reads a character outside the
@@ -22329,7 +22353,7 @@ to a normal program using @code{Wide_Wide_Text_IO}. However, this discrepancy
can be observed if the wide text file shares a stream with another file.
@node Reading and Writing Non-Regular Files<3>,,Stream Pointer Positioning<3>,Wide_Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2c7}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2c8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2c9}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2ca}
@subsection Reading and Writing Non-Regular Files
@@ -22340,7 +22364,7 @@ treated as data characters), and @code{End_Of_Page} always returns
it is possible to read beyond an end of file.
@node Stream_IO,Text Translation,Wide_Wide_Text_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2c9}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2ca}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2cb}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2cc}
@section Stream_IO
@@ -22362,7 +22386,7 @@ manner described for stream attributes.
@end itemize
@node Text Translation,Shared Files,Stream_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2cb}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2cc}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2cd}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2ce}
@section Text Translation
@@ -22396,7 +22420,7 @@ mode. (corresponds to_O_U16TEXT).
@end itemize
@node Shared Files,Filenames encoding,Text Translation,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2cd}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2ce}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2cf}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2d0}
@section Shared Files
@@ -22459,7 +22483,7 @@ heterogeneous input-output. Although this approach will work in GNAT if
for this purpose (using the stream attributes)
@node Filenames encoding,File content encoding,Shared Files,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2cf}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2d0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2d1}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2d2}
@section Filenames encoding
@@ -22499,7 +22523,7 @@ platform. On the other Operating Systems the run-time is supporting
UTF-8 natively.
@node File content encoding,Open Modes,Filenames encoding,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2d1}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2d2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2d3}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2d4}
@section File content encoding
@@ -22532,7 +22556,7 @@ Unicode 8-bit encoding
This encoding is only supported on the Windows platform.
@node Open Modes,Operations on C Streams,File content encoding,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2d3}@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2d4}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2d5}@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2d6}
@section Open Modes
@@ -22635,7 +22659,7 @@ subsequently requires switching from reading to writing or vice-versa,
then the file is reopened in @code{r+} mode to permit the required operation.
@node Operations on C Streams,Interfacing to C Streams,Open Modes,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2d5}@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2d6}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2d7}@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2d8}
@section Operations on C Streams
@@ -22795,7 +22819,7 @@ end Interfaces.C_Streams;
@end example
@node Interfacing to C Streams,,Operations on C Streams,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d7}@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2d8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d9}@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2da}
@section Interfacing to C Streams
@@ -22888,7 +22912,7 @@ imported from a C program, allowing an Ada file to operate on an
existing C file.
@node The GNAT Library,Interfacing to Other Languages,The Implementation of Standard I/O,Top
-@anchor{gnat_rm/the_gnat_library doc}@anchor{2d9}@anchor{gnat_rm/the_gnat_library id1}@anchor{2da}@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}
+@anchor{gnat_rm/the_gnat_library doc}@anchor{2db}@anchor{gnat_rm/the_gnat_library id1}@anchor{2dc}@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}
@chapter The GNAT Library
@@ -23074,7 +23098,7 @@ of GNAT, and will generate a warning message.
@end menu
@node Ada Characters Latin_9 a-chlat9 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2db}@anchor{gnat_rm/the_gnat_library id2}@anchor{2dc}
+@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2dd}@anchor{gnat_rm/the_gnat_library id2}@anchor{2de}
@section @code{Ada.Characters.Latin_9} (@code{a-chlat9.ads})
@@ -23091,7 +23115,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Latin_1 a-cwila1 ads,Ada Characters Wide_Latin_9 a-cwila9 ads,Ada Characters Latin_9 a-chlat9 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2dd}@anchor{gnat_rm/the_gnat_library id3}@anchor{2de}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2df}@anchor{gnat_rm/the_gnat_library id3}@anchor{2e0}
@section @code{Ada.Characters.Wide_Latin_1} (@code{a-cwila1.ads})
@@ -23108,7 +23132,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Latin_9 a-cwila9 ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila9-ads}@anchor{2df}@anchor{gnat_rm/the_gnat_library id4}@anchor{2e0}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila9-ads}@anchor{2e1}@anchor{gnat_rm/the_gnat_library id4}@anchor{2e2}
@section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila9.ads})
@@ -23125,7 +23149,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Characters Wide_Latin_9 a-cwila9 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2e1}@anchor{gnat_rm/the_gnat_library id5}@anchor{2e2}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2e3}@anchor{gnat_rm/the_gnat_library id5}@anchor{2e4}
@section @code{Ada.Characters.Wide_Wide_Latin_1} (@code{a-chzla1.ads})
@@ -23142,7 +23166,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Containers Bounded_Holders a-coboho ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2e3}@anchor{gnat_rm/the_gnat_library id6}@anchor{2e4}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2e5}@anchor{gnat_rm/the_gnat_library id6}@anchor{2e6}
@section @code{Ada.Characters.Wide_Wide_Latin_9} (@code{a-chzla9.ads})
@@ -23159,7 +23183,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Containers Bounded_Holders a-coboho ads,Ada Command_Line Environment a-colien ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2e5}@anchor{gnat_rm/the_gnat_library id7}@anchor{2e6}
+@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2e7}@anchor{gnat_rm/the_gnat_library id7}@anchor{2e8}
@section @code{Ada.Containers.Bounded_Holders} (@code{a-coboho.ads})
@@ -23171,7 +23195,7 @@ This child of @code{Ada.Containers} defines a modified version of
Indefinite_Holders that avoids heap allocation.
@node Ada Command_Line Environment a-colien ads,Ada Command_Line Remove a-colire ads,Ada Containers Bounded_Holders a-coboho ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2e7}@anchor{gnat_rm/the_gnat_library id8}@anchor{2e8}
+@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2e9}@anchor{gnat_rm/the_gnat_library id8}@anchor{2ea}
@section @code{Ada.Command_Line.Environment} (@code{a-colien.ads})
@@ -23184,7 +23208,7 @@ provides a mechanism for obtaining environment values on systems
where this concept makes sense.
@node Ada Command_Line Remove a-colire ads,Ada Command_Line Response_File a-clrefi ads,Ada Command_Line Environment a-colien ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2e9}@anchor{gnat_rm/the_gnat_library id9}@anchor{2ea}
+@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2eb}@anchor{gnat_rm/the_gnat_library id9}@anchor{2ec}
@section @code{Ada.Command_Line.Remove} (@code{a-colire.ads})
@@ -23202,7 +23226,7 @@ to further calls to the subprograms in @code{Ada.Command_Line}. These calls
will not see the removed argument.
@node Ada Command_Line Response_File a-clrefi ads,Ada Direct_IO C_Streams a-diocst ads,Ada Command_Line Remove a-colire ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2eb}@anchor{gnat_rm/the_gnat_library id10}@anchor{2ec}
+@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2ed}@anchor{gnat_rm/the_gnat_library id10}@anchor{2ee}
@section @code{Ada.Command_Line.Response_File} (@code{a-clrefi.ads})
@@ -23222,7 +23246,7 @@ Using a response file allow passing a set of arguments to an executable longer
than the maximum allowed by the system on the command line.
@node Ada Direct_IO C_Streams a-diocst ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Command_Line Response_File a-clrefi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2ed}@anchor{gnat_rm/the_gnat_library id11}@anchor{2ee}
+@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2ef}@anchor{gnat_rm/the_gnat_library id11}@anchor{2f0}
@section @code{Ada.Direct_IO.C_Streams} (@code{a-diocst.ads})
@@ -23237,7 +23261,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Direct_IO C_Streams a-diocst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2ef}@anchor{gnat_rm/the_gnat_library id12}@anchor{2f0}
+@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2f1}@anchor{gnat_rm/the_gnat_library id12}@anchor{2f2}
@section @code{Ada.Exceptions.Is_Null_Occurrence} (@code{a-einuoc.ads})
@@ -23251,7 +23275,7 @@ exception occurrence (@code{Null_Occurrence}) without raising
an exception.
@node Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Exceptions Traceback a-exctra ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{2f1}@anchor{gnat_rm/the_gnat_library id13}@anchor{2f2}
+@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{2f3}@anchor{gnat_rm/the_gnat_library id13}@anchor{2f4}
@section @code{Ada.Exceptions.Last_Chance_Handler} (@code{a-elchha.ads})
@@ -23265,7 +23289,7 @@ exceptions (hence the name last chance), and perform clean ups before
terminating the program. Note that this subprogram never returns.
@node Ada Exceptions Traceback a-exctra ads,Ada Sequential_IO C_Streams a-siocst ads,Ada Exceptions Last_Chance_Handler a-elchha ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{2f3}@anchor{gnat_rm/the_gnat_library id14}@anchor{2f4}
+@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{2f5}@anchor{gnat_rm/the_gnat_library id14}@anchor{2f6}
@section @code{Ada.Exceptions.Traceback} (@code{a-exctra.ads})
@@ -23278,7 +23302,7 @@ give a traceback array of addresses based on an exception
occurrence.
@node Ada Sequential_IO C_Streams a-siocst ads,Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Exceptions Traceback a-exctra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{2f5}@anchor{gnat_rm/the_gnat_library id15}@anchor{2f6}
+@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{2f7}@anchor{gnat_rm/the_gnat_library id15}@anchor{2f8}
@section @code{Ada.Sequential_IO.C_Streams} (@code{a-siocst.ads})
@@ -23293,7 +23317,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Strings Unbounded Text_IO a-suteio ads,Ada Sequential_IO C_Streams a-siocst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{2f7}@anchor{gnat_rm/the_gnat_library id16}@anchor{2f8}
+@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{2f9}@anchor{gnat_rm/the_gnat_library id16}@anchor{2fa}
@section @code{Ada.Streams.Stream_IO.C_Streams} (@code{a-ssicst.ads})
@@ -23308,7 +23332,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Strings Unbounded Text_IO a-suteio ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Streams Stream_IO C_Streams a-ssicst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{2f9}@anchor{gnat_rm/the_gnat_library id17}@anchor{2fa}
+@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{2fb}@anchor{gnat_rm/the_gnat_library id17}@anchor{2fc}
@section @code{Ada.Strings.Unbounded.Text_IO} (@code{a-suteio.ads})
@@ -23325,7 +23349,7 @@ strings, avoiding the necessity for an intermediate operation
with ordinary strings.
@node Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Strings Unbounded Text_IO a-suteio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{2fb}@anchor{gnat_rm/the_gnat_library id18}@anchor{2fc}
+@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{2fd}@anchor{gnat_rm/the_gnat_library id18}@anchor{2fe}
@section @code{Ada.Strings.Wide_Unbounded.Wide_Text_IO} (@code{a-swuwti.ads})
@@ -23342,7 +23366,7 @@ wide strings, avoiding the necessity for an intermediate operation
with ordinary wide strings.
@node Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Task_Initialization a-tasini ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{2fd}@anchor{gnat_rm/the_gnat_library id19}@anchor{2fe}
+@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{2ff}@anchor{gnat_rm/the_gnat_library id19}@anchor{300}
@section @code{Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO} (@code{a-szuzti.ads})
@@ -23359,7 +23383,7 @@ wide wide strings, avoiding the necessity for an intermediate operation
with ordinary wide wide strings.
@node Ada Task_Initialization a-tasini ads,Ada Text_IO C_Streams a-tiocst ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-task-initialization-a-tasini-ads}@anchor{2ff}@anchor{gnat_rm/the_gnat_library id20}@anchor{300}
+@anchor{gnat_rm/the_gnat_library ada-task-initialization-a-tasini-ads}@anchor{301}@anchor{gnat_rm/the_gnat_library id20}@anchor{302}
@section @code{Ada.Task_Initialization} (@code{a-tasini.ads})
@@ -23371,7 +23395,7 @@ parameterless procedures. Note that such a handler is only invoked for
those tasks activated after the handler is set.
@node Ada Text_IO C_Streams a-tiocst ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Task_Initialization a-tasini ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{301}@anchor{gnat_rm/the_gnat_library id21}@anchor{302}
+@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{303}@anchor{gnat_rm/the_gnat_library id21}@anchor{304}
@section @code{Ada.Text_IO.C_Streams} (@code{a-tiocst.ads})
@@ -23386,7 +23410,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Wide_Characters Unicode a-wichun ads,Ada Text_IO C_Streams a-tiocst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{303}@anchor{gnat_rm/the_gnat_library id22}@anchor{304}
+@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{305}@anchor{gnat_rm/the_gnat_library id22}@anchor{306}
@section @code{Ada.Text_IO.Reset_Standard_Files} (@code{a-tirsfi.ads})
@@ -23401,7 +23425,7 @@ execution (for example a standard input file may be redefined to be
interactive).
@node Ada Wide_Characters Unicode a-wichun ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{305}@anchor{gnat_rm/the_gnat_library id23}@anchor{306}
+@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{307}@anchor{gnat_rm/the_gnat_library id23}@anchor{308}
@section @code{Ada.Wide_Characters.Unicode} (@code{a-wichun.ads})
@@ -23414,7 +23438,7 @@ This package provides subprograms that allow categorization of
Wide_Character values according to Unicode categories.
@node Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Characters Unicode a-wichun ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{307}@anchor{gnat_rm/the_gnat_library id24}@anchor{308}
+@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{309}@anchor{gnat_rm/the_gnat_library id24}@anchor{30a}
@section @code{Ada.Wide_Text_IO.C_Streams} (@code{a-wtcstr.ads})
@@ -23429,7 +23453,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{309}@anchor{gnat_rm/the_gnat_library id25}@anchor{30a}
+@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{30b}@anchor{gnat_rm/the_gnat_library id25}@anchor{30c}
@section @code{Ada.Wide_Text_IO.Reset_Standard_Files} (@code{a-wrstfi.ads})
@@ -23444,7 +23468,7 @@ execution (for example a standard input file may be redefined to be
interactive).
@node Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{30b}@anchor{gnat_rm/the_gnat_library id26}@anchor{30c}
+@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{30d}@anchor{gnat_rm/the_gnat_library id26}@anchor{30e}
@section @code{Ada.Wide_Wide_Characters.Unicode} (@code{a-zchuni.ads})
@@ -23457,7 +23481,7 @@ This package provides subprograms that allow categorization of
Wide_Wide_Character values according to Unicode categories.
@node Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{30d}@anchor{gnat_rm/the_gnat_library id27}@anchor{30e}
+@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{30f}@anchor{gnat_rm/the_gnat_library id27}@anchor{310}
@section @code{Ada.Wide_Wide_Text_IO.C_Streams} (@code{a-ztcstr.ads})
@@ -23472,7 +23496,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,GNAT Altivec g-altive ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{30f}@anchor{gnat_rm/the_gnat_library id28}@anchor{310}
+@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{311}@anchor{gnat_rm/the_gnat_library id28}@anchor{312}
@section @code{Ada.Wide_Wide_Text_IO.Reset_Standard_Files} (@code{a-zrstfi.ads})
@@ -23487,7 +23511,7 @@ change during execution (for example a standard input file may be
redefined to be interactive).
@node GNAT Altivec g-altive ads,GNAT Altivec Conversions g-altcon ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{311}@anchor{gnat_rm/the_gnat_library id29}@anchor{312}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{313}@anchor{gnat_rm/the_gnat_library id29}@anchor{314}
@section @code{GNAT.Altivec} (@code{g-altive.ads})
@@ -23500,7 +23524,7 @@ definitions of constants and types common to all the versions of the
binding.
@node GNAT Altivec Conversions g-altcon ads,GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec g-altive ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{313}@anchor{gnat_rm/the_gnat_library id30}@anchor{314}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{315}@anchor{gnat_rm/the_gnat_library id30}@anchor{316}
@section @code{GNAT.Altivec.Conversions} (@code{g-altcon.ads})
@@ -23511,7 +23535,7 @@ binding.
This package provides the Vector/View conversion routines.
@node GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Conversions g-altcon ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{315}@anchor{gnat_rm/the_gnat_library id31}@anchor{316}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{317}@anchor{gnat_rm/the_gnat_library id31}@anchor{318}
@section @code{GNAT.Altivec.Vector_Operations} (@code{g-alveop.ads})
@@ -23525,7 +23549,7 @@ library. The hard binding is provided as a separate package. This unit
is common to both bindings.
@node GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Vector_Views g-alvevi ads,GNAT Altivec Vector_Operations g-alveop ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{317}@anchor{gnat_rm/the_gnat_library id32}@anchor{318}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{319}@anchor{gnat_rm/the_gnat_library id32}@anchor{31a}
@section @code{GNAT.Altivec.Vector_Types} (@code{g-alvety.ads})
@@ -23537,7 +23561,7 @@ This package exposes the various vector types part of the Ada binding
to AltiVec facilities.
@node GNAT Altivec Vector_Views g-alvevi ads,GNAT Array_Split g-arrspl ads,GNAT Altivec Vector_Types g-alvety ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{319}@anchor{gnat_rm/the_gnat_library id33}@anchor{31a}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{31b}@anchor{gnat_rm/the_gnat_library id33}@anchor{31c}
@section @code{GNAT.Altivec.Vector_Views} (@code{g-alvevi.ads})
@@ -23552,7 +23576,7 @@ vector elements and provides a simple way to initialize vector
objects.
@node GNAT Array_Split g-arrspl ads,GNAT AWK g-awk ads,GNAT Altivec Vector_Views g-alvevi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{31b}@anchor{gnat_rm/the_gnat_library id34}@anchor{31c}
+@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{31d}@anchor{gnat_rm/the_gnat_library id34}@anchor{31e}
@section @code{GNAT.Array_Split} (@code{g-arrspl.ads})
@@ -23565,7 +23589,7 @@ an array wherever the separators appear, and provide direct access
to the resulting slices.
@node GNAT AWK g-awk ads,GNAT Binary_Search g-binsea ads,GNAT Array_Split g-arrspl ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{31d}@anchor{gnat_rm/the_gnat_library id35}@anchor{31e}
+@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{31f}@anchor{gnat_rm/the_gnat_library id35}@anchor{320}
@section @code{GNAT.AWK} (@code{g-awk.ads})
@@ -23580,7 +23604,7 @@ or more files containing formatted data. The file is viewed as a database
where each record is a line and a field is a data element in this line.
@node GNAT Binary_Search g-binsea ads,GNAT Bind_Environment g-binenv ads,GNAT AWK g-awk ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-binary-search-g-binsea-ads}@anchor{31f}@anchor{gnat_rm/the_gnat_library id36}@anchor{320}
+@anchor{gnat_rm/the_gnat_library gnat-binary-search-g-binsea-ads}@anchor{321}@anchor{gnat_rm/the_gnat_library id36}@anchor{322}
@section @code{GNAT.Binary_Search} (@code{g-binsea.ads})
@@ -23592,7 +23616,7 @@ Allow binary search of a sorted array (or of an array-like container;
the generic does not reference the array directly).
@node GNAT Bind_Environment g-binenv ads,GNAT Branch_Prediction g-brapre ads,GNAT Binary_Search g-binsea ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{321}@anchor{gnat_rm/the_gnat_library id37}@anchor{322}
+@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{323}@anchor{gnat_rm/the_gnat_library id37}@anchor{324}
@section @code{GNAT.Bind_Environment} (@code{g-binenv.ads})
@@ -23605,7 +23629,7 @@ These associations can be specified using the @code{-V} binder command
line switch.
@node GNAT Branch_Prediction g-brapre ads,GNAT Bounded_Buffers g-boubuf ads,GNAT Bind_Environment g-binenv ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{323}@anchor{gnat_rm/the_gnat_library id38}@anchor{324}
+@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{325}@anchor{gnat_rm/the_gnat_library id38}@anchor{326}
@section @code{GNAT.Branch_Prediction} (@code{g-brapre.ads})
@@ -23616,7 +23640,7 @@ line switch.
Provides routines giving hints to the branch predictor of the code generator.
@node GNAT Bounded_Buffers g-boubuf ads,GNAT Bounded_Mailboxes g-boumai ads,GNAT Branch_Prediction g-brapre ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{325}@anchor{gnat_rm/the_gnat_library id39}@anchor{326}
+@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{327}@anchor{gnat_rm/the_gnat_library id39}@anchor{328}
@section @code{GNAT.Bounded_Buffers} (@code{g-boubuf.ads})
@@ -23631,7 +23655,7 @@ useful directly or as parts of the implementations of other abstractions,
such as mailboxes.
@node GNAT Bounded_Mailboxes g-boumai ads,GNAT Bubble_Sort g-bubsor ads,GNAT Bounded_Buffers g-boubuf ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{327}@anchor{gnat_rm/the_gnat_library id40}@anchor{328}
+@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{329}@anchor{gnat_rm/the_gnat_library id40}@anchor{32a}
@section @code{GNAT.Bounded_Mailboxes} (@code{g-boumai.ads})
@@ -23644,7 +23668,7 @@ such as mailboxes.
Provides a thread-safe asynchronous intertask mailbox communication facility.
@node GNAT Bubble_Sort g-bubsor ads,GNAT Bubble_Sort_A g-busora ads,GNAT Bounded_Mailboxes g-boumai ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{329}@anchor{gnat_rm/the_gnat_library id41}@anchor{32a}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{32b}@anchor{gnat_rm/the_gnat_library id41}@anchor{32c}
@section @code{GNAT.Bubble_Sort} (@code{g-bubsor.ads})
@@ -23659,7 +23683,7 @@ data items. Exchange and comparison procedures are provided by passing
access-to-procedure values.
@node GNAT Bubble_Sort_A g-busora ads,GNAT Bubble_Sort_G g-busorg ads,GNAT Bubble_Sort g-bubsor ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{32b}@anchor{gnat_rm/the_gnat_library id42}@anchor{32c}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{32d}@anchor{gnat_rm/the_gnat_library id42}@anchor{32e}
@section @code{GNAT.Bubble_Sort_A} (@code{g-busora.ads})
@@ -23675,7 +23699,7 @@ access-to-procedure values. This is an older version, retained for
compatibility. Usually @code{GNAT.Bubble_Sort} will be preferable.
@node GNAT Bubble_Sort_G g-busorg ads,GNAT Byte_Order_Mark g-byorma ads,GNAT Bubble_Sort_A g-busora ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{32d}@anchor{gnat_rm/the_gnat_library id43}@anchor{32e}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{32f}@anchor{gnat_rm/the_gnat_library id43}@anchor{330}
@section @code{GNAT.Bubble_Sort_G} (@code{g-busorg.ads})
@@ -23691,7 +23715,7 @@ if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
@node GNAT Byte_Order_Mark g-byorma ads,GNAT Byte_Swapping g-bytswa ads,GNAT Bubble_Sort_G g-busorg ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{32f}@anchor{gnat_rm/the_gnat_library id44}@anchor{330}
+@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{331}@anchor{gnat_rm/the_gnat_library id44}@anchor{332}
@section @code{GNAT.Byte_Order_Mark} (@code{g-byorma.ads})
@@ -23707,7 +23731,7 @@ the encoding of the string. The routine includes detection of special XML
sequences for various UCS input formats.
@node GNAT Byte_Swapping g-bytswa ads,GNAT Calendar g-calend ads,GNAT Byte_Order_Mark g-byorma ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{331}@anchor{gnat_rm/the_gnat_library id45}@anchor{332}
+@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{333}@anchor{gnat_rm/the_gnat_library id45}@anchor{334}
@section @code{GNAT.Byte_Swapping} (@code{g-bytswa.ads})
@@ -23721,7 +23745,7 @@ General routines for swapping the bytes in 2-, 4-, and 8-byte quantities.
Machine-specific implementations are available in some cases.
@node GNAT Calendar g-calend ads,GNAT Calendar Time_IO g-catiio ads,GNAT Byte_Swapping g-bytswa ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{333}@anchor{gnat_rm/the_gnat_library id46}@anchor{334}
+@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{335}@anchor{gnat_rm/the_gnat_library id46}@anchor{336}
@section @code{GNAT.Calendar} (@code{g-calend.ads})
@@ -23735,7 +23759,7 @@ Also provides conversion of @code{Ada.Calendar.Time} values to and from the
C @code{timeval} format.
@node GNAT Calendar Time_IO g-catiio ads,GNAT CRC32 g-crc32 ads,GNAT Calendar g-calend ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{335}@anchor{gnat_rm/the_gnat_library id47}@anchor{336}
+@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{337}@anchor{gnat_rm/the_gnat_library id47}@anchor{338}
@section @code{GNAT.Calendar.Time_IO} (@code{g-catiio.ads})
@@ -23746,7 +23770,7 @@ C @code{timeval} format.
@geindex GNAT.Calendar.Time_IO (g-catiio.ads)
@node GNAT CRC32 g-crc32 ads,GNAT Case_Util g-casuti ads,GNAT Calendar Time_IO g-catiio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{337}@anchor{gnat_rm/the_gnat_library id48}@anchor{338}
+@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{339}@anchor{gnat_rm/the_gnat_library id48}@anchor{33a}
@section @code{GNAT.CRC32} (@code{g-crc32.ads})
@@ -23763,7 +23787,7 @@ of this algorithm see
Aug. 1988. Sarwate, D.V.
@node GNAT Case_Util g-casuti ads,GNAT CGI g-cgi ads,GNAT CRC32 g-crc32 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{339}@anchor{gnat_rm/the_gnat_library id49}@anchor{33a}
+@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{33b}@anchor{gnat_rm/the_gnat_library id49}@anchor{33c}
@section @code{GNAT.Case_Util} (@code{g-casuti.ads})
@@ -23778,7 +23802,7 @@ without the overhead of the full casing tables
in @code{Ada.Characters.Handling}.
@node GNAT CGI g-cgi ads,GNAT CGI Cookie g-cgicoo ads,GNAT Case_Util g-casuti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{33b}@anchor{gnat_rm/the_gnat_library id50}@anchor{33c}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{33d}@anchor{gnat_rm/the_gnat_library id50}@anchor{33e}
@section @code{GNAT.CGI} (@code{g-cgi.ads})
@@ -23793,7 +23817,7 @@ builds a table whose index is the key and provides some services to deal
with this table.
@node GNAT CGI Cookie g-cgicoo ads,GNAT CGI Debug g-cgideb ads,GNAT CGI g-cgi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{33d}@anchor{gnat_rm/the_gnat_library id51}@anchor{33e}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{33f}@anchor{gnat_rm/the_gnat_library id51}@anchor{340}
@section @code{GNAT.CGI.Cookie} (@code{g-cgicoo.ads})
@@ -23808,7 +23832,7 @@ Common Gateway Interface (CGI). It exports services to deal with Web
cookies (piece of information kept in the Web client software).
@node GNAT CGI Debug g-cgideb ads,GNAT Command_Line g-comlin ads,GNAT CGI Cookie g-cgicoo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{33f}@anchor{gnat_rm/the_gnat_library id52}@anchor{340}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{341}@anchor{gnat_rm/the_gnat_library id52}@anchor{342}
@section @code{GNAT.CGI.Debug} (@code{g-cgideb.ads})
@@ -23820,7 +23844,7 @@ This is a package to help debugging CGI (Common Gateway Interface)
programs written in Ada.
@node GNAT Command_Line g-comlin ads,GNAT Compiler_Version g-comver ads,GNAT CGI Debug g-cgideb ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{341}@anchor{gnat_rm/the_gnat_library id53}@anchor{342}
+@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{343}@anchor{gnat_rm/the_gnat_library id53}@anchor{344}
@section @code{GNAT.Command_Line} (@code{g-comlin.ads})
@@ -23833,7 +23857,7 @@ including the ability to scan for named switches with optional parameters
and expand file names using wildcard notations.
@node GNAT Compiler_Version g-comver ads,GNAT Ctrl_C g-ctrl_c ads,GNAT Command_Line g-comlin ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{343}@anchor{gnat_rm/the_gnat_library id54}@anchor{344}
+@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{345}@anchor{gnat_rm/the_gnat_library id54}@anchor{346}
@section @code{GNAT.Compiler_Version} (@code{g-comver.ads})
@@ -23851,7 +23875,7 @@ of the compiler if a consistent tool set is used to compile all units
of a partition).
@node GNAT Ctrl_C g-ctrl_c ads,GNAT Current_Exception g-curexc ads,GNAT Compiler_Version g-comver ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{345}@anchor{gnat_rm/the_gnat_library id55}@anchor{346}
+@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{347}@anchor{gnat_rm/the_gnat_library id55}@anchor{348}
@section @code{GNAT.Ctrl_C} (@code{g-ctrl_c.ads})
@@ -23862,7 +23886,7 @@ of a partition).
Provides a simple interface to handle Ctrl-C keyboard events.
@node GNAT Current_Exception g-curexc ads,GNAT Debug_Pools g-debpoo ads,GNAT Ctrl_C g-ctrl_c ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{347}@anchor{gnat_rm/the_gnat_library id56}@anchor{348}
+@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{349}@anchor{gnat_rm/the_gnat_library id56}@anchor{34a}
@section @code{GNAT.Current_Exception} (@code{g-curexc.ads})
@@ -23879,7 +23903,7 @@ This is particularly useful in simulating typical facilities for
obtaining information about exceptions provided by Ada 83 compilers.
@node GNAT Debug_Pools g-debpoo ads,GNAT Debug_Utilities g-debuti ads,GNAT Current_Exception g-curexc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{349}@anchor{gnat_rm/the_gnat_library id57}@anchor{34a}
+@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{34b}@anchor{gnat_rm/the_gnat_library id57}@anchor{34c}
@section @code{GNAT.Debug_Pools} (@code{g-debpoo.ads})
@@ -23896,7 +23920,7 @@ problems.
See @code{The GNAT Debug_Pool Facility} section in the @cite{GNAT User’s Guide}.
@node GNAT Debug_Utilities g-debuti ads,GNAT Decode_String g-decstr ads,GNAT Debug_Pools g-debpoo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{34b}@anchor{gnat_rm/the_gnat_library id58}@anchor{34c}
+@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{34d}@anchor{gnat_rm/the_gnat_library id58}@anchor{34e}
@section @code{GNAT.Debug_Utilities} (@code{g-debuti.ads})
@@ -23909,7 +23933,7 @@ to and from string images of address values. Supports both C and Ada formats
for hexadecimal literals.
@node GNAT Decode_String g-decstr ads,GNAT Decode_UTF8_String g-deutst ads,GNAT Debug_Utilities g-debuti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{34d}@anchor{gnat_rm/the_gnat_library id59}@anchor{34e}
+@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{34f}@anchor{gnat_rm/the_gnat_library id59}@anchor{350}
@section @code{GNAT.Decode_String} (@code{g-decstr.ads})
@@ -23933,7 +23957,7 @@ Useful in conjunction with Unicode character coding. Note there is a
preinstantiation for UTF-8. See next entry.
@node GNAT Decode_UTF8_String g-deutst ads,GNAT Directory_Operations g-dirope ads,GNAT Decode_String g-decstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{34f}@anchor{gnat_rm/the_gnat_library id60}@anchor{350}
+@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{351}@anchor{gnat_rm/the_gnat_library id60}@anchor{352}
@section @code{GNAT.Decode_UTF8_String} (@code{g-deutst.ads})
@@ -23954,7 +23978,7 @@ preinstantiation for UTF-8. See next entry.
A preinstantiation of GNAT.Decode_Strings for UTF-8 encoding.
@node GNAT Directory_Operations g-dirope ads,GNAT Directory_Operations Iteration g-diopit ads,GNAT Decode_UTF8_String g-deutst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{351}@anchor{gnat_rm/the_gnat_library id61}@anchor{352}
+@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{353}@anchor{gnat_rm/the_gnat_library id61}@anchor{354}
@section @code{GNAT.Directory_Operations} (@code{g-dirope.ads})
@@ -23967,7 +23991,7 @@ the current directory, making new directories, and scanning the files in a
directory.
@node GNAT Directory_Operations Iteration g-diopit ads,GNAT Dynamic_HTables g-dynhta ads,GNAT Directory_Operations g-dirope ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{353}@anchor{gnat_rm/the_gnat_library id62}@anchor{354}
+@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{355}@anchor{gnat_rm/the_gnat_library id62}@anchor{356}
@section @code{GNAT.Directory_Operations.Iteration} (@code{g-diopit.ads})
@@ -23979,7 +24003,7 @@ A child unit of GNAT.Directory_Operations providing additional operations
for iterating through directories.
@node GNAT Dynamic_HTables g-dynhta ads,GNAT Dynamic_Tables g-dyntab ads,GNAT Directory_Operations Iteration g-diopit ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{355}@anchor{gnat_rm/the_gnat_library id63}@anchor{356}
+@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{357}@anchor{gnat_rm/the_gnat_library id63}@anchor{358}
@section @code{GNAT.Dynamic_HTables} (@code{g-dynhta.ads})
@@ -23997,7 +24021,7 @@ dynamic instances of the hash table, while an instantiation of
@code{GNAT.HTable} creates a single instance of the hash table.
@node GNAT Dynamic_Tables g-dyntab ads,GNAT Encode_String g-encstr ads,GNAT Dynamic_HTables g-dynhta ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{357}@anchor{gnat_rm/the_gnat_library id64}@anchor{358}
+@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{359}@anchor{gnat_rm/the_gnat_library id64}@anchor{35a}
@section @code{GNAT.Dynamic_Tables} (@code{g-dyntab.ads})
@@ -24017,7 +24041,7 @@ dynamic instances of the table, while an instantiation of
@code{GNAT.Table} creates a single instance of the table type.
@node GNAT Encode_String g-encstr ads,GNAT Encode_UTF8_String g-enutst ads,GNAT Dynamic_Tables g-dyntab ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{359}@anchor{gnat_rm/the_gnat_library id65}@anchor{35a}
+@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{35b}@anchor{gnat_rm/the_gnat_library id65}@anchor{35c}
@section @code{GNAT.Encode_String} (@code{g-encstr.ads})
@@ -24039,7 +24063,7 @@ encoding method. Useful in conjunction with Unicode character coding.
Note there is a preinstantiation for UTF-8. See next entry.
@node GNAT Encode_UTF8_String g-enutst ads,GNAT Exception_Actions g-excact ads,GNAT Encode_String g-encstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{35b}@anchor{gnat_rm/the_gnat_library id66}@anchor{35c}
+@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{35d}@anchor{gnat_rm/the_gnat_library id66}@anchor{35e}
@section @code{GNAT.Encode_UTF8_String} (@code{g-enutst.ads})
@@ -24060,7 +24084,7 @@ Note there is a preinstantiation for UTF-8. See next entry.
A preinstantiation of GNAT.Encode_Strings for UTF-8 encoding.
@node GNAT Exception_Actions g-excact ads,GNAT Exception_Traces g-exctra ads,GNAT Encode_UTF8_String g-enutst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{35d}@anchor{gnat_rm/the_gnat_library id67}@anchor{35e}
+@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{35f}@anchor{gnat_rm/the_gnat_library id67}@anchor{360}
@section @code{GNAT.Exception_Actions} (@code{g-excact.ads})
@@ -24073,7 +24097,7 @@ for specific exceptions, or when any exception is raised. This
can be used for instance to force a core dump to ease debugging.
@node GNAT Exception_Traces g-exctra ads,GNAT Exceptions g-except ads,GNAT Exception_Actions g-excact ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{35f}@anchor{gnat_rm/the_gnat_library id68}@anchor{360}
+@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{361}@anchor{gnat_rm/the_gnat_library id68}@anchor{362}
@section @code{GNAT.Exception_Traces} (@code{g-exctra.ads})
@@ -24087,7 +24111,7 @@ Provides an interface allowing to control automatic output upon exception
occurrences.
@node GNAT Exceptions g-except ads,GNAT Expect g-expect ads,GNAT Exception_Traces g-exctra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{361}@anchor{gnat_rm/the_gnat_library id69}@anchor{362}
+@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{363}@anchor{gnat_rm/the_gnat_library id69}@anchor{364}
@section @code{GNAT.Exceptions} (@code{g-except.ads})
@@ -24108,7 +24132,7 @@ predefined exceptions, and for example allows raising
@code{Constraint_Error} with a message from a pure subprogram.
@node GNAT Expect g-expect ads,GNAT Expect TTY g-exptty ads,GNAT Exceptions g-except ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{363}@anchor{gnat_rm/the_gnat_library id70}@anchor{364}
+@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{365}@anchor{gnat_rm/the_gnat_library id70}@anchor{366}
@section @code{GNAT.Expect} (@code{g-expect.ads})
@@ -24124,7 +24148,7 @@ It is not implemented for cross ports, and in particular is not
implemented for VxWorks or LynxOS.
@node GNAT Expect TTY g-exptty ads,GNAT Float_Control g-flocon ads,GNAT Expect g-expect ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{365}@anchor{gnat_rm/the_gnat_library id71}@anchor{366}
+@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{367}@anchor{gnat_rm/the_gnat_library id71}@anchor{368}
@section @code{GNAT.Expect.TTY} (@code{g-exptty.ads})
@@ -24136,7 +24160,7 @@ ports. It is not implemented for cross ports, and
in particular is not implemented for VxWorks or LynxOS.
@node GNAT Float_Control g-flocon ads,GNAT Formatted_String g-forstr ads,GNAT Expect TTY g-exptty ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{367}@anchor{gnat_rm/the_gnat_library id72}@anchor{368}
+@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{369}@anchor{gnat_rm/the_gnat_library id72}@anchor{36a}
@section @code{GNAT.Float_Control} (@code{g-flocon.ads})
@@ -24150,7 +24174,7 @@ library calls may cause this mode to be modified, and the Reset procedure
in this package can be used to reestablish the required mode.
@node GNAT Formatted_String g-forstr ads,GNAT Generic_Fast_Math_Functions g-gfmafu ads,GNAT Float_Control g-flocon ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{369}@anchor{gnat_rm/the_gnat_library id73}@anchor{36a}
+@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{36b}@anchor{gnat_rm/the_gnat_library id73}@anchor{36c}
@section @code{GNAT.Formatted_String} (@code{g-forstr.ads})
@@ -24165,7 +24189,7 @@ derived from Integer, Float or enumerations as values for the
formatted string.
@node GNAT Generic_Fast_Math_Functions g-gfmafu ads,GNAT Heap_Sort g-heasor ads,GNAT Formatted_String g-forstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-generic-fast-math-functions-g-gfmafu-ads}@anchor{36b}@anchor{gnat_rm/the_gnat_library id74}@anchor{36c}
+@anchor{gnat_rm/the_gnat_library gnat-generic-fast-math-functions-g-gfmafu-ads}@anchor{36d}@anchor{gnat_rm/the_gnat_library id74}@anchor{36e}
@section @code{GNAT.Generic_Fast_Math_Functions} (@code{g-gfmafu.ads})
@@ -24183,7 +24207,7 @@ have a vector implementation that can be automatically used by the
compiler when auto-vectorization is enabled.
@node GNAT Heap_Sort g-heasor ads,GNAT Heap_Sort_A g-hesora ads,GNAT Generic_Fast_Math_Functions g-gfmafu ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{36d}@anchor{gnat_rm/the_gnat_library id75}@anchor{36e}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{36f}@anchor{gnat_rm/the_gnat_library id75}@anchor{370}
@section @code{GNAT.Heap_Sort} (@code{g-heasor.ads})
@@ -24197,7 +24221,7 @@ access-to-procedure values. The algorithm used is a modified heap sort
that performs approximately N*log(N) comparisons in the worst case.
@node GNAT Heap_Sort_A g-hesora ads,GNAT Heap_Sort_G g-hesorg ads,GNAT Heap_Sort g-heasor ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{36f}@anchor{gnat_rm/the_gnat_library id76}@anchor{370}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{371}@anchor{gnat_rm/the_gnat_library id76}@anchor{372}
@section @code{GNAT.Heap_Sort_A} (@code{g-hesora.ads})
@@ -24213,7 +24237,7 @@ This differs from @code{GNAT.Heap_Sort} in having a less convenient
interface, but may be slightly more efficient.
@node GNAT Heap_Sort_G g-hesorg ads,GNAT HTable g-htable ads,GNAT Heap_Sort_A g-hesora ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{371}@anchor{gnat_rm/the_gnat_library id77}@anchor{372}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{373}@anchor{gnat_rm/the_gnat_library id77}@anchor{374}
@section @code{GNAT.Heap_Sort_G} (@code{g-hesorg.ads})
@@ -24227,7 +24251,7 @@ if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
@node GNAT HTable g-htable ads,GNAT IO g-io ads,GNAT Heap_Sort_G g-hesorg ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{373}@anchor{gnat_rm/the_gnat_library id78}@anchor{374}
+@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{375}@anchor{gnat_rm/the_gnat_library id78}@anchor{376}
@section @code{GNAT.HTable} (@code{g-htable.ads})
@@ -24240,7 +24264,7 @@ data. Provides two approaches, one a simple static approach, and the other
allowing arbitrary dynamic hash tables.
@node GNAT IO g-io ads,GNAT IO_Aux g-io_aux ads,GNAT HTable g-htable ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{375}@anchor{gnat_rm/the_gnat_library id79}@anchor{376}
+@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{377}@anchor{gnat_rm/the_gnat_library id79}@anchor{378}
@section @code{GNAT.IO} (@code{g-io.ads})
@@ -24256,7 +24280,7 @@ Standard_Input, and writing characters, strings and integers to either
Standard_Output or Standard_Error.
@node GNAT IO_Aux g-io_aux ads,GNAT Lock_Files g-locfil ads,GNAT IO g-io ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{377}@anchor{gnat_rm/the_gnat_library id80}@anchor{378}
+@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{379}@anchor{gnat_rm/the_gnat_library id80}@anchor{37a}
@section @code{GNAT.IO_Aux} (@code{g-io_aux.ads})
@@ -24270,7 +24294,7 @@ Provides some auxiliary functions for use with Text_IO, including a test
for whether a file exists, and functions for reading a line of text.
@node GNAT Lock_Files g-locfil ads,GNAT MBBS_Discrete_Random g-mbdira ads,GNAT IO_Aux g-io_aux ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{379}@anchor{gnat_rm/the_gnat_library id81}@anchor{37a}
+@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{37b}@anchor{gnat_rm/the_gnat_library id81}@anchor{37c}
@section @code{GNAT.Lock_Files} (@code{g-locfil.ads})
@@ -24284,7 +24308,7 @@ Provides a general interface for using files as locks. Can be used for
providing program level synchronization.
@node GNAT MBBS_Discrete_Random g-mbdira ads,GNAT MBBS_Float_Random g-mbflra ads,GNAT Lock_Files g-locfil ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{37b}@anchor{gnat_rm/the_gnat_library id82}@anchor{37c}
+@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{37d}@anchor{gnat_rm/the_gnat_library id82}@anchor{37e}
@section @code{GNAT.MBBS_Discrete_Random} (@code{g-mbdira.ads})
@@ -24296,7 +24320,7 @@ The original implementation of @code{Ada.Numerics.Discrete_Random}. Uses
a modified version of the Blum-Blum-Shub generator.
@node GNAT MBBS_Float_Random g-mbflra ads,GNAT MD5 g-md5 ads,GNAT MBBS_Discrete_Random g-mbdira ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{37d}@anchor{gnat_rm/the_gnat_library id83}@anchor{37e}
+@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{37f}@anchor{gnat_rm/the_gnat_library id83}@anchor{380}
@section @code{GNAT.MBBS_Float_Random} (@code{g-mbflra.ads})
@@ -24308,7 +24332,7 @@ The original implementation of @code{Ada.Numerics.Float_Random}. Uses
a modified version of the Blum-Blum-Shub generator.
@node GNAT MD5 g-md5 ads,GNAT Memory_Dump g-memdum ads,GNAT MBBS_Float_Random g-mbflra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{37f}@anchor{gnat_rm/the_gnat_library id84}@anchor{380}
+@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{381}@anchor{gnat_rm/the_gnat_library id84}@anchor{382}
@section @code{GNAT.MD5} (@code{g-md5.ads})
@@ -24321,7 +24345,7 @@ the HMAC-MD5 message authentication function as described in RFC 2104 and
FIPS PUB 198.
@node GNAT Memory_Dump g-memdum ads,GNAT Most_Recent_Exception g-moreex ads,GNAT MD5 g-md5 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{381}@anchor{gnat_rm/the_gnat_library id85}@anchor{382}
+@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{383}@anchor{gnat_rm/the_gnat_library id85}@anchor{384}
@section @code{GNAT.Memory_Dump} (@code{g-memdum.ads})
@@ -24334,7 +24358,7 @@ standard output or standard error files. Uses GNAT.IO for actual
output.
@node GNAT Most_Recent_Exception g-moreex ads,GNAT OS_Lib g-os_lib ads,GNAT Memory_Dump g-memdum ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{383}@anchor{gnat_rm/the_gnat_library id86}@anchor{384}
+@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{385}@anchor{gnat_rm/the_gnat_library id86}@anchor{386}
@section @code{GNAT.Most_Recent_Exception} (@code{g-moreex.ads})
@@ -24348,7 +24372,7 @@ various logging purposes, including duplicating functionality of some
Ada 83 implementation dependent extensions.
@node GNAT OS_Lib g-os_lib ads,GNAT Perfect_Hash_Generators g-pehage ads,GNAT Most_Recent_Exception g-moreex ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{385}@anchor{gnat_rm/the_gnat_library id87}@anchor{386}
+@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{387}@anchor{gnat_rm/the_gnat_library id87}@anchor{388}
@section @code{GNAT.OS_Lib} (@code{g-os_lib.ads})
@@ -24364,7 +24388,7 @@ including a portable spawn procedure, and access to environment variables
and error return codes.
@node GNAT Perfect_Hash_Generators g-pehage ads,GNAT Random_Numbers g-rannum ads,GNAT OS_Lib g-os_lib ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{387}@anchor{gnat_rm/the_gnat_library id88}@anchor{388}
+@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{389}@anchor{gnat_rm/the_gnat_library id88}@anchor{38a}
@section @code{GNAT.Perfect_Hash_Generators} (@code{g-pehage.ads})
@@ -24382,7 +24406,7 @@ hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.
@node GNAT Random_Numbers g-rannum ads,GNAT Regexp g-regexp ads,GNAT Perfect_Hash_Generators g-pehage ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{389}@anchor{gnat_rm/the_gnat_library id89}@anchor{38a}
+@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{38b}@anchor{gnat_rm/the_gnat_library id89}@anchor{38c}
@section @code{GNAT.Random_Numbers} (@code{g-rannum.ads})
@@ -24394,7 +24418,7 @@ Provides random number capabilities which extend those available in the
standard Ada library and are more convenient to use.
@node GNAT Regexp g-regexp ads,GNAT Registry g-regist ads,GNAT Random_Numbers g-rannum ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{260}@anchor{gnat_rm/the_gnat_library id90}@anchor{38b}
+@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{262}@anchor{gnat_rm/the_gnat_library id90}@anchor{38d}
@section @code{GNAT.Regexp} (@code{g-regexp.ads})
@@ -24410,7 +24434,7 @@ simplest of the three pattern matching packages provided, and is particularly
suitable for ‘file globbing’ applications.
@node GNAT Registry g-regist ads,GNAT Regpat g-regpat ads,GNAT Regexp g-regexp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{38c}@anchor{gnat_rm/the_gnat_library id91}@anchor{38d}
+@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{38e}@anchor{gnat_rm/the_gnat_library id91}@anchor{38f}
@section @code{GNAT.Registry} (@code{g-regist.ads})
@@ -24424,7 +24448,7 @@ registry API, but at a lower level of abstraction, refer to the Win32.Winreg
package provided with the Win32Ada binding
@node GNAT Regpat g-regpat ads,GNAT Rewrite_Data g-rewdat ads,GNAT Registry g-regist ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{38e}@anchor{gnat_rm/the_gnat_library id92}@anchor{38f}
+@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{390}@anchor{gnat_rm/the_gnat_library id92}@anchor{391}
@section @code{GNAT.Regpat} (@code{g-regpat.ads})
@@ -24439,7 +24463,7 @@ from the original V7 style regular expression library written in C by
Henry Spencer (and binary compatible with this C library).
@node GNAT Rewrite_Data g-rewdat ads,GNAT Secondary_Stack_Info g-sestin ads,GNAT Regpat g-regpat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{390}@anchor{gnat_rm/the_gnat_library id93}@anchor{391}
+@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{392}@anchor{gnat_rm/the_gnat_library id93}@anchor{393}
@section @code{GNAT.Rewrite_Data} (@code{g-rewdat.ads})
@@ -24453,7 +24477,7 @@ full content to be processed is not loaded into memory all at once. This makes
this interface usable for large files or socket streams.
@node GNAT Secondary_Stack_Info g-sestin ads,GNAT Semaphores g-semaph ads,GNAT Rewrite_Data g-rewdat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{392}@anchor{gnat_rm/the_gnat_library id94}@anchor{393}
+@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{394}@anchor{gnat_rm/the_gnat_library id94}@anchor{395}
@section @code{GNAT.Secondary_Stack_Info} (@code{g-sestin.ads})
@@ -24465,7 +24489,7 @@ Provides the capability to query the high water mark of the current task’s
secondary stack.
@node GNAT Semaphores g-semaph ads,GNAT Serial_Communications g-sercom ads,GNAT Secondary_Stack_Info g-sestin ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{394}@anchor{gnat_rm/the_gnat_library id95}@anchor{395}
+@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{396}@anchor{gnat_rm/the_gnat_library id95}@anchor{397}
@section @code{GNAT.Semaphores} (@code{g-semaph.ads})
@@ -24476,7 +24500,7 @@ secondary stack.
Provides classic counting and binary semaphores using protected types.
@node GNAT Serial_Communications g-sercom ads,GNAT SHA1 g-sha1 ads,GNAT Semaphores g-semaph ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{396}@anchor{gnat_rm/the_gnat_library id96}@anchor{397}
+@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{398}@anchor{gnat_rm/the_gnat_library id96}@anchor{399}
@section @code{GNAT.Serial_Communications} (@code{g-sercom.ads})
@@ -24488,7 +24512,7 @@ Provides a simple interface to send and receive data over a serial
port. This is only supported on GNU/Linux and Windows.
@node GNAT SHA1 g-sha1 ads,GNAT SHA224 g-sha224 ads,GNAT Serial_Communications g-sercom ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{398}@anchor{gnat_rm/the_gnat_library id97}@anchor{399}
+@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{39a}@anchor{gnat_rm/the_gnat_library id97}@anchor{39b}
@section @code{GNAT.SHA1} (@code{g-sha1.ads})
@@ -24501,7 +24525,7 @@ and RFC 3174, and the HMAC-SHA1 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA224 g-sha224 ads,GNAT SHA256 g-sha256 ads,GNAT SHA1 g-sha1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{39a}@anchor{gnat_rm/the_gnat_library id98}@anchor{39b}
+@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{39c}@anchor{gnat_rm/the_gnat_library id98}@anchor{39d}
@section @code{GNAT.SHA224} (@code{g-sha224.ads})
@@ -24514,7 +24538,7 @@ and the HMAC-SHA224 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA256 g-sha256 ads,GNAT SHA384 g-sha384 ads,GNAT SHA224 g-sha224 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{39c}@anchor{gnat_rm/the_gnat_library id99}@anchor{39d}
+@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{39e}@anchor{gnat_rm/the_gnat_library id99}@anchor{39f}
@section @code{GNAT.SHA256} (@code{g-sha256.ads})
@@ -24527,7 +24551,7 @@ and the HMAC-SHA256 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA384 g-sha384 ads,GNAT SHA512 g-sha512 ads,GNAT SHA256 g-sha256 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{39e}@anchor{gnat_rm/the_gnat_library id100}@anchor{39f}
+@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a0}@anchor{gnat_rm/the_gnat_library id100}@anchor{3a1}
@section @code{GNAT.SHA384} (@code{g-sha384.ads})
@@ -24540,7 +24564,7 @@ and the HMAC-SHA384 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA512 g-sha512 ads,GNAT Signals g-signal ads,GNAT SHA384 g-sha384 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a0}@anchor{gnat_rm/the_gnat_library id101}@anchor{3a1}
+@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a2}@anchor{gnat_rm/the_gnat_library id101}@anchor{3a3}
@section @code{GNAT.SHA512} (@code{g-sha512.ads})
@@ -24553,7 +24577,7 @@ and the HMAC-SHA512 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT Signals g-signal ads,GNAT Sockets g-socket ads,GNAT SHA512 g-sha512 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3a2}@anchor{gnat_rm/the_gnat_library id102}@anchor{3a3}
+@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3a4}@anchor{gnat_rm/the_gnat_library id102}@anchor{3a5}
@section @code{GNAT.Signals} (@code{g-signal.ads})
@@ -24565,7 +24589,7 @@ Provides the ability to manipulate the blocked status of signals on supported
targets.
@node GNAT Sockets g-socket ads,GNAT Source_Info g-souinf ads,GNAT Signals g-signal ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3a4}@anchor{gnat_rm/the_gnat_library id103}@anchor{3a5}
+@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3a6}@anchor{gnat_rm/the_gnat_library id103}@anchor{3a7}
@section @code{GNAT.Sockets} (@code{g-socket.ads})
@@ -24580,7 +24604,7 @@ on all native GNAT ports and on VxWorks cross ports. It is not implemented for
the LynxOS cross port.
@node GNAT Source_Info g-souinf ads,GNAT Spelling_Checker g-speche ads,GNAT Sockets g-socket ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3a6}@anchor{gnat_rm/the_gnat_library id104}@anchor{3a7}
+@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3a8}@anchor{gnat_rm/the_gnat_library id104}@anchor{3a9}
@section @code{GNAT.Source_Info} (@code{g-souinf.ads})
@@ -24594,7 +24618,7 @@ subprograms yielding the date and time of the current compilation (like the
C macros @code{__DATE__} and @code{__TIME__})
@node GNAT Spelling_Checker g-speche ads,GNAT Spelling_Checker_Generic g-spchge ads,GNAT Source_Info g-souinf ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3a8}@anchor{gnat_rm/the_gnat_library id105}@anchor{3a9}
+@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3aa}@anchor{gnat_rm/the_gnat_library id105}@anchor{3ab}
@section @code{GNAT.Spelling_Checker} (@code{g-speche.ads})
@@ -24606,7 +24630,7 @@ Provides a function for determining whether one string is a plausible
near misspelling of another string.
@node GNAT Spelling_Checker_Generic g-spchge ads,GNAT Spitbol Patterns g-spipat ads,GNAT Spelling_Checker g-speche ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3aa}@anchor{gnat_rm/the_gnat_library id106}@anchor{3ab}
+@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3ac}@anchor{gnat_rm/the_gnat_library id106}@anchor{3ad}
@section @code{GNAT.Spelling_Checker_Generic} (@code{g-spchge.ads})
@@ -24619,7 +24643,7 @@ determining whether one string is a plausible near misspelling of another
string.
@node GNAT Spitbol Patterns g-spipat ads,GNAT Spitbol g-spitbo ads,GNAT Spelling_Checker_Generic g-spchge ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3ac}@anchor{gnat_rm/the_gnat_library id107}@anchor{3ad}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3ae}@anchor{gnat_rm/the_gnat_library id107}@anchor{3af}
@section @code{GNAT.Spitbol.Patterns} (@code{g-spipat.ads})
@@ -24635,7 +24659,7 @@ the SNOBOL4 dynamic pattern construction and matching capabilities, using the
efficient algorithm developed by Robert Dewar for the SPITBOL system.
@node GNAT Spitbol g-spitbo ads,GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Patterns g-spipat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3ae}@anchor{gnat_rm/the_gnat_library id108}@anchor{3af}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b0}@anchor{gnat_rm/the_gnat_library id108}@anchor{3b1}
@section @code{GNAT.Spitbol} (@code{g-spitbo.ads})
@@ -24650,7 +24674,7 @@ useful for constructing arbitrary mappings from strings in the style of
the SNOBOL4 TABLE function.
@node GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol g-spitbo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b0}@anchor{gnat_rm/the_gnat_library id109}@anchor{3b1}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b2}@anchor{gnat_rm/the_gnat_library id109}@anchor{3b3}
@section @code{GNAT.Spitbol.Table_Boolean} (@code{g-sptabo.ads})
@@ -24665,7 +24689,7 @@ for type @code{Standard.Boolean}, giving an implementation of sets of
string values.
@node GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol Table_VString g-sptavs ads,GNAT Spitbol Table_Boolean g-sptabo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3b2}@anchor{gnat_rm/the_gnat_library id110}@anchor{3b3}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3b4}@anchor{gnat_rm/the_gnat_library id110}@anchor{3b5}
@section @code{GNAT.Spitbol.Table_Integer} (@code{g-sptain.ads})
@@ -24682,7 +24706,7 @@ for type @code{Standard.Integer}, giving an implementation of maps
from string to integer values.
@node GNAT Spitbol Table_VString g-sptavs ads,GNAT SSE g-sse ads,GNAT Spitbol Table_Integer g-sptain ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3b4}@anchor{gnat_rm/the_gnat_library id111}@anchor{3b5}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3b6}@anchor{gnat_rm/the_gnat_library id111}@anchor{3b7}
@section @code{GNAT.Spitbol.Table_VString} (@code{g-sptavs.ads})
@@ -24699,7 +24723,7 @@ a variable length string type, giving an implementation of general
maps from strings to strings.
@node GNAT SSE g-sse ads,GNAT SSE Vector_Types g-ssvety ads,GNAT Spitbol Table_VString g-sptavs ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3b6}@anchor{gnat_rm/the_gnat_library id112}@anchor{3b7}
+@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3b8}@anchor{gnat_rm/the_gnat_library id112}@anchor{3b9}
@section @code{GNAT.SSE} (@code{g-sse.ads})
@@ -24711,7 +24735,7 @@ targets. It exposes vector component types together with a general
introduction to the binding contents and use.
@node GNAT SSE Vector_Types g-ssvety ads,GNAT String_Hash g-strhas ads,GNAT SSE g-sse ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3b8}@anchor{gnat_rm/the_gnat_library id113}@anchor{3b9}
+@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3ba}@anchor{gnat_rm/the_gnat_library id113}@anchor{3bb}
@section @code{GNAT.SSE.Vector_Types} (@code{g-ssvety.ads})
@@ -24720,7 +24744,7 @@ introduction to the binding contents and use.
SSE vector types for use with SSE related intrinsics.
@node GNAT String_Hash g-strhas ads,GNAT Strings g-string ads,GNAT SSE Vector_Types g-ssvety ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3ba}@anchor{gnat_rm/the_gnat_library id114}@anchor{3bb}
+@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3bc}@anchor{gnat_rm/the_gnat_library id114}@anchor{3bd}
@section @code{GNAT.String_Hash} (@code{g-strhas.ads})
@@ -24732,7 +24756,7 @@ Provides a generic hash function working on arrays of scalars. Both the scalar
type and the hash result type are parameters.
@node GNAT Strings g-string ads,GNAT String_Split g-strspl ads,GNAT String_Hash g-strhas ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3bc}@anchor{gnat_rm/the_gnat_library id115}@anchor{3bd}
+@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3be}@anchor{gnat_rm/the_gnat_library id115}@anchor{3bf}
@section @code{GNAT.Strings} (@code{g-string.ads})
@@ -24742,7 +24766,7 @@ Common String access types and related subprograms. Basically it
defines a string access and an array of string access types.
@node GNAT String_Split g-strspl ads,GNAT Table g-table ads,GNAT Strings g-string ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3be}@anchor{gnat_rm/the_gnat_library id116}@anchor{3bf}
+@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3c0}@anchor{gnat_rm/the_gnat_library id116}@anchor{3c1}
@section @code{GNAT.String_Split} (@code{g-strspl.ads})
@@ -24756,7 +24780,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node GNAT Table g-table ads,GNAT Task_Lock g-tasloc ads,GNAT String_Split g-strspl ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c0}@anchor{gnat_rm/the_gnat_library id117}@anchor{3c1}
+@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c2}@anchor{gnat_rm/the_gnat_library id117}@anchor{3c3}
@section @code{GNAT.Table} (@code{g-table.ads})
@@ -24776,7 +24800,7 @@ while an instantiation of @code{GNAT.Dynamic_Tables} creates a type that can be
used to define dynamic instances of the table.
@node GNAT Task_Lock g-tasloc ads,GNAT Time_Stamp g-timsta ads,GNAT Table g-table ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3c2}@anchor{gnat_rm/the_gnat_library id118}@anchor{3c3}
+@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3c4}@anchor{gnat_rm/the_gnat_library id118}@anchor{3c5}
@section @code{GNAT.Task_Lock} (@code{g-tasloc.ads})
@@ -24793,7 +24817,7 @@ single global task lock. Appropriate for use in situations where contention
between tasks is very rarely expected.
@node GNAT Time_Stamp g-timsta ads,GNAT Threads g-thread ads,GNAT Task_Lock g-tasloc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3c4}@anchor{gnat_rm/the_gnat_library id119}@anchor{3c5}
+@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3c6}@anchor{gnat_rm/the_gnat_library id119}@anchor{3c7}
@section @code{GNAT.Time_Stamp} (@code{g-timsta.ads})
@@ -24808,7 +24832,7 @@ represents the current date and time in ISO 8601 format. This is a very simple
routine with minimal code and there are no dependencies on any other unit.
@node GNAT Threads g-thread ads,GNAT Traceback g-traceb ads,GNAT Time_Stamp g-timsta ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3c6}@anchor{gnat_rm/the_gnat_library id120}@anchor{3c7}
+@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3c8}@anchor{gnat_rm/the_gnat_library id120}@anchor{3c9}
@section @code{GNAT.Threads} (@code{g-thread.ads})
@@ -24825,7 +24849,7 @@ further details if your program has threads that are created by a non-Ada
environment which then accesses Ada code.
@node GNAT Traceback g-traceb ads,GNAT Traceback Symbolic g-trasym ads,GNAT Threads g-thread ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3c8}@anchor{gnat_rm/the_gnat_library id121}@anchor{3c9}
+@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3ca}@anchor{gnat_rm/the_gnat_library id121}@anchor{3cb}
@section @code{GNAT.Traceback} (@code{g-traceb.ads})
@@ -24837,7 +24861,7 @@ Provides a facility for obtaining non-symbolic traceback information, useful
in various debugging situations.
@node GNAT Traceback Symbolic g-trasym ads,GNAT UTF_32 g-utf_32 ads,GNAT Traceback g-traceb ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3ca}@anchor{gnat_rm/the_gnat_library id122}@anchor{3cb}
+@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3cc}@anchor{gnat_rm/the_gnat_library id122}@anchor{3cd}
@section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads})
@@ -24846,7 +24870,7 @@ in various debugging situations.
@geindex Trace back facilities
@node GNAT UTF_32 g-utf_32 ads,GNAT UTF_32_Spelling_Checker g-u3spch ads,GNAT Traceback Symbolic g-trasym ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-utf-32-ads}@anchor{3cc}@anchor{gnat_rm/the_gnat_library id123}@anchor{3cd}
+@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-utf-32-ads}@anchor{3ce}@anchor{gnat_rm/the_gnat_library id123}@anchor{3cf}
@section @code{GNAT.UTF_32} (@code{g-utf_32.ads})
@@ -24865,7 +24889,7 @@ lower case to upper case fold routine corresponding to
the Ada 2005 rules for identifier equivalence.
@node GNAT UTF_32_Spelling_Checker g-u3spch ads,GNAT Wide_Spelling_Checker g-wispch ads,GNAT UTF_32 g-utf_32 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-utf-32-spelling-checker-g-u3spch-ads}@anchor{3ce}@anchor{gnat_rm/the_gnat_library id124}@anchor{3cf}
+@anchor{gnat_rm/the_gnat_library gnat-utf-32-spelling-checker-g-u3spch-ads}@anchor{3d0}@anchor{gnat_rm/the_gnat_library id124}@anchor{3d1}
@section @code{GNAT.UTF_32_Spelling_Checker} (@code{g-u3spch.ads})
@@ -24878,7 +24902,7 @@ near misspelling of another wide wide string, where the strings are represented
using the UTF_32_String type defined in System.Wch_Cnv.
@node GNAT Wide_Spelling_Checker g-wispch ads,GNAT Wide_String_Split g-wistsp ads,GNAT UTF_32_Spelling_Checker g-u3spch ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d0}@anchor{gnat_rm/the_gnat_library id125}@anchor{3d1}
+@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d2}@anchor{gnat_rm/the_gnat_library id125}@anchor{3d3}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-wispch.ads})
@@ -24890,7 +24914,7 @@ Provides a function for determining whether one wide string is a plausible
near misspelling of another wide string.
@node GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Spelling_Checker g-wispch ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3d2}@anchor{gnat_rm/the_gnat_library id126}@anchor{3d3}
+@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3d4}@anchor{gnat_rm/the_gnat_library id126}@anchor{3d5}
@section @code{GNAT.Wide_String_Split} (@code{g-wistsp.ads})
@@ -24904,7 +24928,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Wide_String_Split g-zistsp ads,GNAT Wide_String_Split g-wistsp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3d4}@anchor{gnat_rm/the_gnat_library id127}@anchor{3d5}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3d6}@anchor{gnat_rm/the_gnat_library id127}@anchor{3d7}
@section @code{GNAT.Wide_Wide_Spelling_Checker} (@code{g-zspche.ads})
@@ -24916,7 +24940,7 @@ Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string.
@node GNAT Wide_Wide_String_Split g-zistsp ads,Interfaces C Extensions i-cexten ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3d6}@anchor{gnat_rm/the_gnat_library id128}@anchor{3d7}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3d8}@anchor{gnat_rm/the_gnat_library id128}@anchor{3d9}
@section @code{GNAT.Wide_Wide_String_Split} (@code{g-zistsp.ads})
@@ -24930,7 +24954,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node Interfaces C Extensions i-cexten ads,Interfaces C Streams i-cstrea ads,GNAT Wide_Wide_String_Split g-zistsp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id129}@anchor{3d8}@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3d9}
+@anchor{gnat_rm/the_gnat_library id129}@anchor{3da}@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3db}
@section @code{Interfaces.C.Extensions} (@code{i-cexten.ads})
@@ -24941,7 +24965,7 @@ for use with either manually or automatically generated bindings
to C libraries.
@node Interfaces C Streams i-cstrea ads,Interfaces Packed_Decimal i-pacdec ads,Interfaces C Extensions i-cexten ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id130}@anchor{3da}@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3db}
+@anchor{gnat_rm/the_gnat_library id130}@anchor{3dc}@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3dd}
@section @code{Interfaces.C.Streams} (@code{i-cstrea.ads})
@@ -24954,7 +24978,7 @@ This package is a binding for the most commonly used operations
on C streams.
@node Interfaces Packed_Decimal i-pacdec ads,Interfaces VxWorks i-vxwork ads,Interfaces C Streams i-cstrea ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id131}@anchor{3dc}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3dd}
+@anchor{gnat_rm/the_gnat_library id131}@anchor{3de}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3df}
@section @code{Interfaces.Packed_Decimal} (@code{i-pacdec.ads})
@@ -24969,7 +24993,7 @@ from a packed decimal format compatible with that used on IBM
mainframes.
@node Interfaces VxWorks i-vxwork ads,Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces Packed_Decimal i-pacdec ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id132}@anchor{3de}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3df}
+@anchor{gnat_rm/the_gnat_library id132}@anchor{3e0}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e1}
@section @code{Interfaces.VxWorks} (@code{i-vxwork.ads})
@@ -24985,7 +25009,7 @@ In particular, it interfaces with the
VxWorks hardware interrupt facilities.
@node Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces VxWorks IO i-vxwoio ads,Interfaces VxWorks i-vxwork ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id133}@anchor{3e0}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e1}
+@anchor{gnat_rm/the_gnat_library id133}@anchor{3e2}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e3}
@section @code{Interfaces.VxWorks.Int_Connection} (@code{i-vxinco.ads})
@@ -25001,7 +25025,7 @@ intConnect() with a custom routine for installing interrupt
handlers.
@node Interfaces VxWorks IO i-vxwoio ads,System Address_Image s-addima ads,Interfaces VxWorks Int_Connection i-vxinco ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id134}@anchor{3e2}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3e3}
+@anchor{gnat_rm/the_gnat_library id134}@anchor{3e4}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3e5}
@section @code{Interfaces.VxWorks.IO} (@code{i-vxwoio.ads})
@@ -25024,7 +25048,7 @@ function codes. A particular use of this package is
to enable the use of Get_Immediate under VxWorks.
@node System Address_Image s-addima ads,System Assertions s-assert ads,Interfaces VxWorks IO i-vxwoio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id135}@anchor{3e4}@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3e5}
+@anchor{gnat_rm/the_gnat_library id135}@anchor{3e6}@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3e7}
@section @code{System.Address_Image} (@code{s-addima.ads})
@@ -25040,7 +25064,7 @@ function that gives an (implementation dependent)
string which identifies an address.
@node System Assertions s-assert ads,System Atomic_Counters s-atocou ads,System Address_Image s-addima ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id136}@anchor{3e6}@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3e7}
+@anchor{gnat_rm/the_gnat_library id136}@anchor{3e8}@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3e9}
@section @code{System.Assertions} (@code{s-assert.ads})
@@ -25056,7 +25080,7 @@ by an run-time assertion failure, as well as the routine that
is used internally to raise this assertion.
@node System Atomic_Counters s-atocou ads,System Memory s-memory ads,System Assertions s-assert ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id137}@anchor{3e8}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3e9}
+@anchor{gnat_rm/the_gnat_library id137}@anchor{3ea}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3eb}
@section @code{System.Atomic_Counters} (@code{s-atocou.ads})
@@ -25070,7 +25094,7 @@ on most targets, including all Alpha, AARCH64, ARM, ia64, PowerPC, SPARC V9,
x86, and x86_64 platforms.
@node System Memory s-memory ads,System Multiprocessors s-multip ads,System Atomic_Counters s-atocou ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id138}@anchor{3ea}@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3eb}
+@anchor{gnat_rm/the_gnat_library id138}@anchor{3ec}@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3ed}
@section @code{System.Memory} (@code{s-memory.ads})
@@ -25088,7 +25112,7 @@ calls to this unit may be made for low level allocation uses (for
example see the body of @code{GNAT.Tables}).
@node System Multiprocessors s-multip ads,System Multiprocessors Dispatching_Domains s-mudido ads,System Memory s-memory ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id139}@anchor{3ec}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3ed}
+@anchor{gnat_rm/the_gnat_library id139}@anchor{3ee}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3ef}
@section @code{System.Multiprocessors} (@code{s-multip.ads})
@@ -25101,7 +25125,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
@node System Multiprocessors Dispatching_Domains s-mudido ads,System Partition_Interface s-parint ads,System Multiprocessors s-multip ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id140}@anchor{3ee}@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3ef}
+@anchor{gnat_rm/the_gnat_library id140}@anchor{3f0}@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f1}
@section @code{System.Multiprocessors.Dispatching_Domains} (@code{s-mudido.ads})
@@ -25114,7 +25138,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
@node System Partition_Interface s-parint ads,System Pool_Global s-pooglo ads,System Multiprocessors Dispatching_Domains s-mudido ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id141}@anchor{3f0}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f1}
+@anchor{gnat_rm/the_gnat_library id141}@anchor{3f2}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f3}
@section @code{System.Partition_Interface} (@code{s-parint.ads})
@@ -25127,7 +25151,7 @@ is used primarily in a distribution context when using Annex E
with @code{GLADE}.
@node System Pool_Global s-pooglo ads,System Pool_Local s-pooloc ads,System Partition_Interface s-parint ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id142}@anchor{3f2}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3f3}
+@anchor{gnat_rm/the_gnat_library id142}@anchor{3f4}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3f5}
@section @code{System.Pool_Global} (@code{s-pooglo.ads})
@@ -25144,7 +25168,7 @@ declared. It uses malloc/free to allocate/free and does not attempt to
do any automatic reclamation.
@node System Pool_Local s-pooloc ads,System Restrictions s-restri ads,System Pool_Global s-pooglo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id143}@anchor{3f4}@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3f5}
+@anchor{gnat_rm/the_gnat_library id143}@anchor{3f6}@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3f7}
@section @code{System.Pool_Local} (@code{s-pooloc.ads})
@@ -25161,7 +25185,7 @@ a list of allocated blocks, so that all storage allocated for the pool can
be freed automatically when the pool is finalized.
@node System Restrictions s-restri ads,System Rident s-rident ads,System Pool_Local s-pooloc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id144}@anchor{3f6}@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3f7}
+@anchor{gnat_rm/the_gnat_library id144}@anchor{3f8}@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3f9}
@section @code{System.Restrictions} (@code{s-restri.ads})
@@ -25177,7 +25201,7 @@ compiler determined information on which restrictions
are violated by one or more packages in the partition.
@node System Rident s-rident ads,System Strings Stream_Ops s-ststop ads,System Restrictions s-restri ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id145}@anchor{3f8}@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{3f9}
+@anchor{gnat_rm/the_gnat_library id145}@anchor{3fa}@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{3fb}
@section @code{System.Rident} (@code{s-rident.ads})
@@ -25193,7 +25217,7 @@ since the necessary instantiation is included in
package System.Restrictions.
@node System Strings Stream_Ops s-ststop ads,System Unsigned_Types s-unstyp ads,System Rident s-rident ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id146}@anchor{3fa}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{3fb}
+@anchor{gnat_rm/the_gnat_library id146}@anchor{3fc}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{3fd}
@section @code{System.Strings.Stream_Ops} (@code{s-ststop.ads})
@@ -25209,7 +25233,7 @@ stream attributes are applied to string types, but the subprograms in this
package can be used directly by application programs.
@node System Unsigned_Types s-unstyp ads,System Wch_Cnv s-wchcnv ads,System Strings Stream_Ops s-ststop ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id147}@anchor{3fc}@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{3fd}
+@anchor{gnat_rm/the_gnat_library id147}@anchor{3fe}@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{3ff}
@section @code{System.Unsigned_Types} (@code{s-unstyp.ads})
@@ -25222,7 +25246,7 @@ also contains some related definitions for other specialized types
used by the compiler in connection with packed array types.
@node System Wch_Cnv s-wchcnv ads,System Wch_Con s-wchcon ads,System Unsigned_Types s-unstyp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id148}@anchor{3fe}@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{3ff}
+@anchor{gnat_rm/the_gnat_library id148}@anchor{400}@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{401}
@section @code{System.Wch_Cnv} (@code{s-wchcnv.ads})
@@ -25243,7 +25267,7 @@ encoding method. It uses definitions in
package @code{System.Wch_Con}.
@node System Wch_Con s-wchcon ads,,System Wch_Cnv s-wchcnv ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id149}@anchor{400}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{401}
+@anchor{gnat_rm/the_gnat_library id149}@anchor{402}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{403}
@section @code{System.Wch_Con} (@code{s-wchcon.ads})
@@ -25255,7 +25279,7 @@ in ordinary strings. These definitions are used by
the package @code{System.Wch_Cnv}.
@node Interfacing to Other Languages,Specialized Needs Annexes,The GNAT Library,Top
-@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{402}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{403}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}
+@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{404}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{405}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}
@chapter Interfacing to Other Languages
@@ -25273,7 +25297,7 @@ provided.
@end menu
@node Interfacing to C,Interfacing to C++,,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{404}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{405}
+@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{406}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{407}
@section Interfacing to C
@@ -25413,7 +25437,7 @@ of the length corresponding to the @code{type'Size} value in Ada.
@end itemize
@node Interfacing to C++,Interfacing to COBOL,Interfacing to C,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{47}@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{406}
+@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{47}@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{408}
@section Interfacing to C++
@@ -25470,7 +25494,7 @@ The @code{External_Name} is the name of the C++ RTTI symbol. You can then
cover a specific C++ exception in an exception handler.
@node Interfacing to COBOL,Interfacing to Fortran,Interfacing to C++,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{407}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{408}
+@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{409}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{40a}
@section Interfacing to COBOL
@@ -25478,7 +25502,7 @@ Interfacing to COBOL is achieved as described in section B.4 of
the Ada Reference Manual.
@node Interfacing to Fortran,Interfacing to non-GNAT Ada code,Interfacing to COBOL,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{409}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{40a}
+@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{40b}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{40c}
@section Interfacing to Fortran
@@ -25488,7 +25512,7 @@ multi-dimensional array causes the array to be stored in column-major
order as required for convenient interface to Fortran.
@node Interfacing to non-GNAT Ada code,,Interfacing to Fortran,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{40b}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{40c}
+@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{40d}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{40e}
@section Interfacing to non-GNAT Ada code
@@ -25512,7 +25536,7 @@ values or simple record types without variants, or simple array
types with fixed bounds.
@node Specialized Needs Annexes,Implementation of Specific Ada Features,Interfacing to Other Languages,Top
-@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{40d}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{40e}@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}
+@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{40f}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{410}@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}
@chapter Specialized Needs Annexes
@@ -25553,7 +25577,7 @@ in Ada 2005) is fully implemented.
@end table
@node Implementation of Specific Ada Features,Implementation of Ada 2012 Features,Specialized Needs Annexes,Top
-@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{40f}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{410}@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}
+@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{411}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{412}@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}
@chapter Implementation of Specific Ada Features
@@ -25572,7 +25596,7 @@ facilities.
@end menu
@node Machine Code Insertions,GNAT Implementation of Tasking,,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{411}@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{16a}
+@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{413}@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{16a}
@section Machine Code Insertions
@@ -25740,7 +25764,7 @@ according to normal visibility rules. In particular if there is no
qualification is required.
@node GNAT Implementation of Tasking,GNAT Implementation of Shared Passive Packages,Machine Code Insertions,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{412}@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{413}
+@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{414}@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{415}
@section GNAT Implementation of Tasking
@@ -25756,7 +25780,7 @@ to compliance with the Real-Time Systems Annex.
@end menu
@node Mapping Ada Tasks onto the Underlying Kernel Threads,Ensuring Compliance with the Real-Time Annex,,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{414}@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{415}
+@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{416}@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{417}
@subsection Mapping Ada Tasks onto the Underlying Kernel Threads
@@ -25825,7 +25849,7 @@ support this functionality when the parent contains more than one task.
@geindex Forking a new process
@node Ensuring Compliance with the Real-Time Annex,Support for Locking Policies,Mapping Ada Tasks onto the Underlying Kernel Threads,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{416}@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{417}
+@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{418}@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{419}
@subsection Ensuring Compliance with the Real-Time Annex
@@ -25876,7 +25900,7 @@ placed at the end.
@c Support_for_Locking_Policies
@node Support for Locking Policies,,Ensuring Compliance with the Real-Time Annex,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{418}
+@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{41a}
@subsection Support for Locking Policies
@@ -25910,7 +25934,7 @@ then ceiling locking is used.
Otherwise, the @code{Ceiling_Locking} policy is ignored.
@node GNAT Implementation of Shared Passive Packages,Code Generation for Array Aggregates,GNAT Implementation of Tasking,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{419}@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{41a}
+@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{41b}@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{41c}
@section GNAT Implementation of Shared Passive Packages
@@ -26008,7 +26032,7 @@ This is used to provide the required locking
semantics for proper protected object synchronization.
@node Code Generation for Array Aggregates,The Size of Discriminated Records with Default Discriminants,GNAT Implementation of Shared Passive Packages,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{41b}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{41c}
+@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{41d}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{41e}
@section Code Generation for Array Aggregates
@@ -26039,7 +26063,7 @@ component values and static subtypes also lead to simpler code.
@end menu
@node Static constant aggregates with static bounds,Constant aggregates with unconstrained nominal types,,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{41d}@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{41e}
+@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{41f}@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{420}
@subsection Static constant aggregates with static bounds
@@ -26086,7 +26110,7 @@ Zero2: constant two_dim := (others => (others => 0));
@end example
@node Constant aggregates with unconstrained nominal types,Aggregates with static bounds,Static constant aggregates with static bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{41f}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{420}
+@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{421}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{422}
@subsection Constant aggregates with unconstrained nominal types
@@ -26101,7 +26125,7 @@ Cr_Unc : constant One_Unc := (12,24,36);
@end example
@node Aggregates with static bounds,Aggregates with nonstatic bounds,Constant aggregates with unconstrained nominal types,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{421}@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{422}
+@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{423}@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{424}
@subsection Aggregates with static bounds
@@ -26129,7 +26153,7 @@ end loop;
@end example
@node Aggregates with nonstatic bounds,Aggregates in assignment statements,Aggregates with static bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{423}@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{424}
+@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{425}@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{426}
@subsection Aggregates with nonstatic bounds
@@ -26140,7 +26164,7 @@ have to be applied to sub-arrays individually, if they do not have statically
compatible subtypes.
@node Aggregates in assignment statements,,Aggregates with nonstatic bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{425}@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{426}
+@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{427}@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{428}
@subsection Aggregates in assignment statements
@@ -26182,7 +26206,7 @@ a temporary (created either by the front-end or the code generator) and then
that temporary will be copied onto the target.
@node The Size of Discriminated Records with Default Discriminants,Image Values For Nonscalar Types,Code Generation for Array Aggregates,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{427}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{428}
+@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{429}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{42a}
@section The Size of Discriminated Records with Default Discriminants
@@ -26262,7 +26286,7 @@ say) must be consistent, so it is imperative that the object, once created,
remain invariant.
@node Image Values For Nonscalar Types,Strict Conformance to the Ada Reference Manual,The Size of Discriminated Records with Default Discriminants,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{429}@anchor{gnat_rm/implementation_of_specific_ada_features image-values-for-nonscalar-types}@anchor{42a}
+@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{42b}@anchor{gnat_rm/implementation_of_specific_ada_features image-values-for-nonscalar-types}@anchor{42c}
@section Image Values For Nonscalar Types
@@ -26282,7 +26306,7 @@ control of image text is required for some type T, then T’Put_Image should be
explicitly specified.
@node Strict Conformance to the Ada Reference Manual,,Image Values For Nonscalar Types,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id15}@anchor{42b}@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{42c}
+@anchor{gnat_rm/implementation_of_specific_ada_features id15}@anchor{42d}@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{42e}
@section Strict Conformance to the Ada Reference Manual
@@ -26309,7 +26333,7 @@ behavior (although at the cost of a significant performance penalty), so
infinite and NaN values are properly generated.
@node Implementation of Ada 2012 Features,GNAT language extensions,Implementation of Specific Ada Features,Top
-@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{42d}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{42e}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}
+@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{42f}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{430}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}
@chapter Implementation of Ada 2012 Features
@@ -28475,7 +28499,7 @@ RM References: H.04 (8/1)
@end itemize
@node GNAT language extensions,Security Hardening Features,Implementation of Ada 2012 Features,Top
-@anchor{gnat_rm/gnat_language_extensions doc}@anchor{42f}@anchor{gnat_rm/gnat_language_extensions gnat-language-extensions}@anchor{430}@anchor{gnat_rm/gnat_language_extensions id1}@anchor{431}
+@anchor{gnat_rm/gnat_language_extensions doc}@anchor{431}@anchor{gnat_rm/gnat_language_extensions gnat-language-extensions}@anchor{432}@anchor{gnat_rm/gnat_language_extensions id1}@anchor{433}
@chapter GNAT language extensions
@@ -28506,7 +28530,7 @@ prototyping phase.
@end menu
@node How to activate the extended GNAT Ada superset,Curated Extensions,,GNAT language extensions
-@anchor{gnat_rm/gnat_language_extensions how-to-activate-the-extended-gnat-ada-superset}@anchor{432}
+@anchor{gnat_rm/gnat_language_extensions how-to-activate-the-extended-gnat-ada-superset}@anchor{434}
@section How to activate the extended GNAT Ada superset
@@ -28545,7 +28569,7 @@ for serious projects, and is only means as a playground/technology preview.
@end cartouche
@node Curated Extensions,Experimental Language Extensions,How to activate the extended GNAT Ada superset,GNAT language extensions
-@anchor{gnat_rm/gnat_language_extensions curated-extensions}@anchor{433}@anchor{gnat_rm/gnat_language_extensions curated-language-extensions}@anchor{66}
+@anchor{gnat_rm/gnat_language_extensions curated-extensions}@anchor{435}@anchor{gnat_rm/gnat_language_extensions curated-language-extensions}@anchor{66}
@section Curated Extensions
@@ -28562,7 +28586,7 @@ for serious projects, and is only means as a playground/technology preview.
@end menu
@node Conditional when constructs,Case pattern matching,,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions conditional-when-constructs}@anchor{434}
+@anchor{gnat_rm/gnat_language_extensions conditional-when-constructs}@anchor{436}
@subsection Conditional when constructs
@@ -28634,7 +28658,7 @@ Link to the original RFC:
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-conditional-when-constructs.rst}
@node Case pattern matching,Fixed lower bounds for array types and subtypes,Conditional when constructs,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions case-pattern-matching}@anchor{435}
+@anchor{gnat_rm/gnat_language_extensions case-pattern-matching}@anchor{437}
@subsection Case pattern matching
@@ -28766,7 +28790,7 @@ Link to the original RFC:
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-pattern-matching.rst}
@node Fixed lower bounds for array types and subtypes,Prefixed-view notation for calls to primitive subprograms of untagged types,Case pattern matching,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions fixed-lower-bounds-for-array-types-and-subtypes}@anchor{436}
+@anchor{gnat_rm/gnat_language_extensions fixed-lower-bounds-for-array-types-and-subtypes}@anchor{438}
@subsection Fixed lower bounds for array types and subtypes
@@ -28820,7 +28844,7 @@ Link to the original RFC:
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-fixed-lower-bound.rst}
@node Prefixed-view notation for calls to primitive subprograms of untagged types,Expression defaults for generic formal functions,Fixed lower bounds for array types and subtypes,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions prefixed-view-notation-for-calls-to-primitive-subprograms-of-untagged-types}@anchor{437}
+@anchor{gnat_rm/gnat_language_extensions prefixed-view-notation-for-calls-to-primitive-subprograms-of-untagged-types}@anchor{439}
@subsection Prefixed-view notation for calls to primitive subprograms of untagged types
@@ -28873,7 +28897,7 @@ Link to the original RFC:
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-prefixed-untagged.rst}
@node Expression defaults for generic formal functions,String interpolation,Prefixed-view notation for calls to primitive subprograms of untagged types,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions expression-defaults-for-generic-formal-functions}@anchor{438}
+@anchor{gnat_rm/gnat_language_extensions expression-defaults-for-generic-formal-functions}@anchor{43a}
@subsection Expression defaults for generic formal functions
@@ -28902,7 +28926,7 @@ Link to the original RFC:
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-expression-functions-as-default-for-generic-formal-function-parameters.rst}
@node String interpolation,Constrained attribute for generic objects,Expression defaults for generic formal functions,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions string-interpolation}@anchor{439}
+@anchor{gnat_rm/gnat_language_extensions string-interpolation}@anchor{43b}
@subsection String interpolation
@@ -29068,7 +29092,7 @@ Here is a link to the original RFC :
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-string-interpolation.rst}
@node Constrained attribute for generic objects,Static aspect on intrinsic functions,String interpolation,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions constrained-attribute-for-generic-objects}@anchor{43a}
+@anchor{gnat_rm/gnat_language_extensions constrained-attribute-for-generic-objects}@anchor{43c}
@subsection Constrained attribute for generic objects
@@ -29076,7 +29100,7 @@ The @code{Constrained} attribute is permitted for objects of generic types. The
result indicates whether the corresponding actual is constrained.
@node Static aspect on intrinsic functions,,Constrained attribute for generic objects,Curated Extensions
-@anchor{gnat_rm/gnat_language_extensions static-aspect-on-intrinsic-functions}@anchor{43b}
+@anchor{gnat_rm/gnat_language_extensions static-aspect-on-intrinsic-functions}@anchor{43d}
@subsection @code{Static} aspect on intrinsic functions
@@ -29085,7 +29109,7 @@ and the compiler will evaluate some of these intrinsics statically, in
particular the @code{Shift_Left} and @code{Shift_Right} intrinsics.
@node Experimental Language Extensions,,Curated Extensions,GNAT language extensions
-@anchor{gnat_rm/gnat_language_extensions experimental-language-extensions}@anchor{67}@anchor{gnat_rm/gnat_language_extensions id2}@anchor{43c}
+@anchor{gnat_rm/gnat_language_extensions experimental-language-extensions}@anchor{67}@anchor{gnat_rm/gnat_language_extensions id2}@anchor{43e}
@section Experimental Language Extensions
@@ -29096,7 +29120,7 @@ particular the @code{Shift_Left} and @code{Shift_Right} intrinsics.
@end menu
@node Pragma Storage_Model,Simpler accessibility model,,Experimental Language Extensions
-@anchor{gnat_rm/gnat_language_extensions pragma-storage-model}@anchor{43d}
+@anchor{gnat_rm/gnat_language_extensions pragma-storage-model}@anchor{43f}
@subsection Pragma Storage_Model
@@ -29111,7 +29135,7 @@ Here is a link to the full RFC:
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-storage-model.rst}
@node Simpler accessibility model,,Pragma Storage_Model,Experimental Language Extensions
-@anchor{gnat_rm/gnat_language_extensions simpler-accessibility-model}@anchor{43e}
+@anchor{gnat_rm/gnat_language_extensions simpler-accessibility-model}@anchor{440}
@subsection Simpler accessibility model
@@ -29124,7 +29148,7 @@ Here is a link to the full RFC:
@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-simpler-accessibility.md}
@node Security Hardening Features,Obsolescent Features,GNAT language extensions,Top
-@anchor{gnat_rm/security_hardening_features doc}@anchor{43f}@anchor{gnat_rm/security_hardening_features id1}@anchor{440}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15}
+@anchor{gnat_rm/security_hardening_features doc}@anchor{441}@anchor{gnat_rm/security_hardening_features id1}@anchor{442}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15}
@chapter Security Hardening Features
@@ -29146,7 +29170,7 @@ change.
@end menu
@node Register Scrubbing,Stack Scrubbing,,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{441}
+@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{443}
@section Register Scrubbing
@@ -29176,7 +29200,7 @@ programming languages, see @cite{Using the GNU Compiler Collection (GCC)}.
@c Stack Scrubbing:
@node Stack Scrubbing,Hardened Conditionals,Register Scrubbing,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{442}
+@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{444}
@section Stack Scrubbing
@@ -29320,7 +29344,7 @@ Bar_Callable_Ptr.
@c Hardened Conditionals:
@node Hardened Conditionals,Hardened Booleans,Stack Scrubbing,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{443}
+@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{445}
@section Hardened Conditionals
@@ -29410,7 +29434,7 @@ be used with other programming languages supported by GCC.
@c Hardened Booleans:
@node Hardened Booleans,Control Flow Redundancy,Hardened Conditionals,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{444}
+@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{446}
@section Hardened Booleans
@@ -29471,7 +29495,7 @@ and more details on that attribute, see @cite{Using the GNU Compiler Collection
@c Control Flow Redundancy:
@node Control Flow Redundancy,,Hardened Booleans,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{445}
+@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{447}
@section Control Flow Redundancy
@@ -29631,7 +29655,7 @@ see @cite{Using the GNU Compiler Collection (GCC)}. These options
can be used with other programming languages supported by GCC.
@node Obsolescent Features,Compatibility and Porting Guide,Security Hardening Features,Top
-@anchor{gnat_rm/obsolescent_features doc}@anchor{446}@anchor{gnat_rm/obsolescent_features id1}@anchor{447}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16}
+@anchor{gnat_rm/obsolescent_features doc}@anchor{448}@anchor{gnat_rm/obsolescent_features id1}@anchor{449}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16}
@chapter Obsolescent Features
@@ -29650,7 +29674,7 @@ compatibility purposes.
@end menu
@node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id2}@anchor{448}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{449}
+@anchor{gnat_rm/obsolescent_features id2}@anchor{44a}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{44b}
@section pragma No_Run_Time
@@ -29663,7 +29687,7 @@ preferred usage is to use an appropriately configured run-time that
includes just those features that are to be made accessible.
@node pragma Ravenscar,pragma Restricted_Run_Time,pragma No_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id3}@anchor{44a}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{44b}
+@anchor{gnat_rm/obsolescent_features id3}@anchor{44c}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{44d}
@section pragma Ravenscar
@@ -29672,7 +29696,7 @@ The pragma @code{Ravenscar} has exactly the same effect as pragma
is part of the new Ada 2005 standard.
@node pragma Restricted_Run_Time,pragma Task_Info,pragma Ravenscar,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id4}@anchor{44c}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{44d}
+@anchor{gnat_rm/obsolescent_features id4}@anchor{44e}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{44f}
@section pragma Restricted_Run_Time
@@ -29682,7 +29706,7 @@ preferred since the Ada 2005 pragma @code{Profile} is intended for
this kind of implementation dependent addition.
@node pragma Task_Info,package System Task_Info s-tasinf ads,pragma Restricted_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id5}@anchor{44e}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{44f}
+@anchor{gnat_rm/obsolescent_features id5}@anchor{450}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{451}
@section pragma Task_Info
@@ -29708,7 +29732,7 @@ in the spec of package System.Task_Info in the runtime
library.
@node package System Task_Info s-tasinf ads,,pragma Task_Info,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{450}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{451}
+@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{452}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{453}
@section package System.Task_Info (@code{s-tasinf.ads})
@@ -29718,7 +29742,7 @@ to support the @code{Task_Info} pragma. The predefined Ada package
standard replacement for GNAT’s @code{Task_Info} functionality.
@node Compatibility and Porting Guide,GNU Free Documentation License,Obsolescent Features,Top
-@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{452}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{453}
+@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{455}
@chapter Compatibility and Porting Guide
@@ -29740,7 +29764,7 @@ applications developed in other Ada environments.
@end menu
@node Writing Portable Fixed-Point Declarations,Compatibility with Ada 83,,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{455}
+@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{457}
@section Writing Portable Fixed-Point Declarations
@@ -29862,7 +29886,7 @@ If you follow this scheme you will be guaranteed that your fixed-point
types will be portable.
@node Compatibility with Ada 83,Compatibility between Ada 95 and Ada 2005,Writing Portable Fixed-Point Declarations,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{457}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{459}
@section Compatibility with Ada 83
@@ -29890,7 +29914,7 @@ following subsections treat the most likely issues to be encountered.
@end menu
@node Legal Ada 83 programs that are illegal in Ada 95,More deterministic semantics,,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{459}
+@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{45a}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{45b}
@subsection Legal Ada 83 programs that are illegal in Ada 95
@@ -29990,7 +30014,7 @@ the fix is usually simply to add the @code{(<>)} to the generic declaration.
@end itemize
@node More deterministic semantics,Changed semantics,Legal Ada 83 programs that are illegal in Ada 95,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{45a}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{45b}
+@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{45d}
@subsection More deterministic semantics
@@ -30018,7 +30042,7 @@ which open select branches are executed.
@end itemize
@node Changed semantics,Other language compatibility issues,More deterministic semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{45d}
+@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{45e}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{45f}
@subsection Changed semantics
@@ -30060,7 +30084,7 @@ covers only the restricted range.
@end itemize
@node Other language compatibility issues,,Changed semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{45e}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{45f}
+@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{460}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{461}
@subsection Other language compatibility issues
@@ -30093,7 +30117,7 @@ include @code{pragma Interface} and the floating point type attributes
@end itemize
@node Compatibility between Ada 95 and Ada 2005,Implementation-dependent characteristics,Compatibility with Ada 83,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{460}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{461}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{462}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{463}
@section Compatibility between Ada 95 and Ada 2005
@@ -30165,7 +30189,7 @@ can declare a function returning a value from an anonymous access type.
@end itemize
@node Implementation-dependent characteristics,Compatibility with Other Ada Systems,Compatibility between Ada 95 and Ada 2005,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{462}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{463}
+@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{464}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{465}
@section Implementation-dependent characteristics
@@ -30188,7 +30212,7 @@ transition from certain Ada 83 compilers.
@end menu
@node Implementation-defined pragmas,Implementation-defined attributes,,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{464}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{465}
+@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{466}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{467}
@subsection Implementation-defined pragmas
@@ -30210,7 +30234,7 @@ avoiding compiler rejection of units that contain such pragmas; they are not
relevant in a GNAT context and hence are not otherwise implemented.
@node Implementation-defined attributes,Libraries,Implementation-defined pragmas,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{466}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{467}
+@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{468}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{469}
@subsection Implementation-defined attributes
@@ -30224,7 +30248,7 @@ Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and
@code{Type_Class}.
@node Libraries,Elaboration order,Implementation-defined attributes,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{468}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{469}
+@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{46a}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{46b}
@subsection Libraries
@@ -30253,7 +30277,7 @@ be preferable to retrofit the application using modular types.
@end itemize
@node Elaboration order,Target-specific aspects,Libraries,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{46a}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{46b}
+@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{46c}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{46d}
@subsection Elaboration order
@@ -30289,7 +30313,7 @@ pragmas either globally (as an effect of the `-gnatE' switch) or locally
@end itemize
@node Target-specific aspects,,Elaboration order,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{46c}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{46d}
+@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{46e}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{46f}
@subsection Target-specific aspects
@@ -30302,10 +30326,10 @@ on the robustness of the original design. Moreover, Ada 95 (and thus
Ada 2005 and Ada 2012) are sometimes
incompatible with typical Ada 83 compiler practices regarding implicit
packing, the meaning of the Size attribute, and the size of access values.
-GNAT’s approach to these issues is described in @ref{46e,,Representation Clauses}.
+GNAT’s approach to these issues is described in @ref{470,,Representation Clauses}.
@node Compatibility with Other Ada Systems,Representation Clauses,Implementation-dependent characteristics,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{46f}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{470}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{471}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{472}
@section Compatibility with Other Ada Systems
@@ -30348,7 +30372,7 @@ far beyond this minimal set, as described in the next section.
@end itemize
@node Representation Clauses,Compatibility with HP Ada 83,Compatibility with Other Ada Systems,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{471}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{46e}
+@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{473}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{470}
@section Representation Clauses
@@ -30441,7 +30465,7 @@ with thin pointers.
@end itemize
@node Compatibility with HP Ada 83,,Representation Clauses,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{472}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{473}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{474}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{475}
@section Compatibility with HP Ada 83
@@ -30471,7 +30495,7 @@ extension of package System.
@end itemize
@node GNU Free Documentation License,Index,Compatibility and Porting Guide,Top
-@anchor{share/gnu_free_documentation_license doc}@anchor{474}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{475}
+@anchor{share/gnu_free_documentation_license doc}@anchor{476}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{477}
@chapter GNU Free Documentation License
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index b85711b..104adb9 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Jun 16, 2023
+GNAT User's Guide for Native Platforms , Jul 04, 2023
AdaCore
@@ -29528,8 +29528,8 @@ to permit their use in free software.
@printindex ge
-@anchor{d1}@w{ }
@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ }
+@anchor{d1}@w{ }
@c %**end of body
@bye
diff --git a/gcc/ada/libgnat/a-textio.ads b/gcc/ada/libgnat/a-textio.ads
index ddbbd85..4318b6c 100644
--- a/gcc/ada/libgnat/a-textio.ads
+++ b/gcc/ada/libgnat/a-textio.ads
@@ -523,24 +523,28 @@ is
Item : out String;
Last : out Natural)
with
- Pre => Is_Open (File) and then Mode (File) = In_File,
- Post =>
+ Relaxed_Initialization => Item,
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Post =>
(if Item'Length > 0 then Last in Item'First - 1 .. Item'Last
- else Last = Item'First - 1),
- Global => (In_Out => File_System),
- Exceptional_Cases => (End_Error => Item'Length'Old > 0);
+ else Last = Item'First - 1)
+ and (for all I in Item'First .. Last => Item (I)'Initialized),
+ Global => (In_Out => File_System),
+ Exceptional_Cases => (End_Error => Item'Length'Old > 0);
procedure Get_Line
(Item : out String;
Last : out Natural)
with
- Post =>
+ Relaxed_Initialization => Item,
+ Post =>
Line_Length'Old = Line_Length
and Page_Length'Old = Page_Length
and (if Item'Length > 0 then Last in Item'First - 1 .. Item'Last
- else Last = Item'First - 1),
- Global => (In_Out => File_System),
- Exceptional_Cases => (End_Error => Item'Length'Old > 0);
+ else Last = Item'First - 1)
+ and (for all I in Item'First .. Last => Item (I)'Initialized),
+ Global => (In_Out => File_System),
+ Exceptional_Cases => (End_Error => Item'Length'Old > 0);
function Get_Line (File : File_Type) return String with SPARK_Mode => Off;
pragma Ada_05 (Get_Line);
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 87399c8..59a24be 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -209,16 +209,6 @@ package Opt is
-- Unchecked_Conversion instantiations require checking based on annotated
-- values.
- Back_End_Handles_Limited_Types : Boolean;
- -- This flag is set True if the back end can properly handle limited or
- -- other by reference types, and avoid copies. If this flag is False, then
- -- the front end does special expansion for if/case expressions to make
- -- sure that no copy occurs. If the flag is True, then the expansion for
- -- if and case expressions relies on the back end properly handling things.
- -- Currently the default is False for all cases (set in gnat1drv). The
- -- default can be modified using -gnatd.L (sets the flag True). This is
- -- used to test the possibility of having the backend handle this.
-
Back_End_Inlining : Boolean := False;
-- GNAT
-- Set True to activate inlining by back-end expansion. This is the normal
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index d5280ce..61e0ec4 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -7001,11 +7001,11 @@ package body Sem_Ch12 is
-- The enclosing scope of the generic unit
procedure Check_Actual_Type (Typ : Entity_Id);
- -- If the type of the actual is a private type declared in the
- -- enclosing scope of the generic unit, but not a derived type
- -- of a private type declared elsewhere, the body of the generic
- -- sees the full view of the type (because it has to appear in
- -- the corresponding package body). If the type is private now,
+ -- If the type of the actual is a private type declared in the enclosing
+ -- scope of the generic, either directly or through packages nested in
+ -- bodies, but not a derived type of a private type declared elsewhere,
+ -- then the body of the generic sees the full view of the type because
+ -- it has to appear in the package body. If the type is private now then
-- exchange views to restore the proper visibility in the instance.
-----------------------
@@ -7015,16 +7015,48 @@ package body Sem_Ch12 is
procedure Check_Actual_Type (Typ : Entity_Id) is
Btyp : constant Entity_Id := Base_Type (Typ);
+ function Scope_Within_Body_Or_Same
+ (Inner : Entity_Id;
+ Outer : Entity_Id) return Boolean;
+ -- Determine whether scope Inner is within the body of scope Outer
+ -- or is Outer itself.
+
+ -------------------------------
+ -- Scope_Within_Body_Or_Same --
+ -------------------------------
+
+ function Scope_Within_Body_Or_Same
+ (Inner : Entity_Id;
+ Outer : Entity_Id) return Boolean
+ is
+ Curr : Entity_Id := Inner;
+
+ begin
+ while Curr /= Standard_Standard loop
+ if Curr = Outer then
+ return True;
+
+ elsif Is_Package_Body_Entity (Curr) then
+ Curr := Scope (Curr);
+
+ else
+ exit;
+ end if;
+ end loop;
+
+ return False;
+ end Scope_Within_Body_Or_Same;
+
begin
-- The exchange is only needed if the generic is defined
-- within a package which is not a common ancestor of the
-- scope of the instance, and is not already in scope.
if Is_Private_Type (Btyp)
- and then Scope (Btyp) = Parent_Scope
and then not Has_Private_Ancestor (Btyp)
and then Ekind (Parent_Scope) in E_Package | E_Generic_Package
- and then Scope (Instance) /= Parent_Scope
+ and then Scope_Within_Body_Or_Same (Parent_Scope, Scope (Btyp))
+ and then Parent_Scope /= Scope (Instance)
and then not Is_Child_Unit (Gen_Id)
then
Switch_View (Btyp);
@@ -7160,11 +7192,16 @@ package body Sem_Ch12 is
Set_Is_Hidden (E, False);
end if;
- -- Check directly the type of the actual objects
+ -- Check directly the type of the actual objects, including the
+ -- component type for array types.
if Ekind (E) in E_Constant | E_Variable then
Check_Actual_Type (Etype (E));
+ if Is_Array_Type (Etype (E)) then
+ Check_Actual_Type (Component_Type (Etype (E)));
+ end if;
+
-- As well as the type of formal parameters of actual subprograms
elsif Ekind (E) in E_Function | E_Procedure
@@ -7710,6 +7747,9 @@ package body Sem_Ch12 is
Prepend_Elmt (Typ, Exchanged_Views);
Exchange_Declarations (Etype (Get_Associated_Node (N)));
+ -- Check that the available views of Typ match their respective flag.
+ -- Note that the type of a visible discriminant is never private.
+
else
Check_Private_Type (Typ, Has_Private_View (N));
@@ -7720,6 +7760,20 @@ package body Sem_Ch12 is
elsif Is_Array_Type (Typ) then
Check_Private_Type
(Component_Type (Typ), Has_Secondary_Private_View (N));
+
+ elsif (Is_Record_Type (Typ) or else Is_Concurrent_Type (Typ))
+ and then Has_Discriminants (Typ)
+ then
+ declare
+ Disc : Entity_Id;
+
+ begin
+ Disc := First_Discriminant (Typ);
+ while Present (Disc) loop
+ Check_Private_Type (Etype (Disc), False);
+ Next_Discriminant (Disc);
+ end loop;
+ end;
end if;
end if;
end if;
@@ -8471,13 +8525,12 @@ package body Sem_Ch12 is
Copy_Descendants;
end;
- -- Iterator and loop parameter specifications do not have an identifier
- -- denoting the index type, so we must locate it through the expression
- -- to check whether the views are consistent.
+ -- Loop parameter specifications do not have an identifier denoting the
+ -- index type, so we must locate it through the defining identifier to
+ -- check whether the views are consistent.
- elsif Nkind (N) in N_Iterator_Specification
- | N_Loop_Parameter_Specification
- and then Instantiating
+ elsif Nkind (N) = N_Loop_Parameter_Specification
+ and then Instantiating
then
declare
Id : constant Entity_Id :=
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index fa36a5a..72e7d18 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -91,9 +91,14 @@ package body Sem_Ch5 is
function Has_Sec_Stack_Call (N : Node_Id) return Boolean;
-- N is the node for an arbitrary construct. This function searches the
- -- construct N to see if any expressions within it contain function
- -- calls that use the secondary stack, returning True if any such call
- -- is found, and False otherwise.
+ -- construct N to see if it contains a function call that returns on the
+ -- secondary stack, returning True if any such call is found, and False
+ -- otherwise.
+
+ -- ??? The implementation invokes Sem_Util.Requires_Transient_Scope so it
+ -- will return True if N contains a function call that needs finalization,
+ -- in addition to the above specification. See Analyze_Loop_Statement for
+ -- a similar comment about this entanglement.
procedure Preanalyze_Range (R_Copy : Node_Id);
-- Determine expected type of range or domain of iteration of Ada 2012
@@ -3626,9 +3631,13 @@ package body Sem_Ch5 is
Cont_Typ := Etype (Nam_Copy);
-- The iterator loop is traversing an array. This case does not
- -- require any transformation.
+ -- require any transformation, unless the name contains a call
+ -- that returns on the secondary stack since we need to release
+ -- the space allocated there.
- if Is_Array_Type (Cont_Typ) then
+ if Is_Array_Type (Cont_Typ)
+ and then not Has_Sec_Stack_Call (Nam_Copy)
+ then
null;
-- Otherwise unconditionally wrap the loop statement within
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 6c8212c..b22407a 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -2530,6 +2530,7 @@ package body Sem_Disp is
(S : Entity_Id;
No_Interfaces : Boolean := False;
Interfaces_Only : Boolean := False;
+ Skip_Overridden : Boolean := False;
One_Only : Boolean := False) return Subprogram_List
is
Result : Subprogram_List (1 .. 6000);
@@ -2670,6 +2671,34 @@ package body Sem_Disp is
end if;
end if;
+ -- Do not keep an overridden operation if its overridding operation
+ -- is in the results too, and it is not S. This can happen for
+ -- inheritance between interfaces.
+
+ if Skip_Overridden then
+ declare
+ Res : constant Subprogram_List (1 .. N) := Result (1 .. N);
+ M : Nat := 0;
+ begin
+ for J in 1 .. N loop
+ for K in 1 .. N loop
+ if Res (K) /= S
+ and then Res (J) = Overridden_Operation (Res (K))
+ then
+ goto Skip;
+ end if;
+ end loop;
+
+ M := M + 1;
+ Result (M) := Res (J);
+
+ <<Skip>>
+ end loop;
+
+ N := M;
+ end;
+ end if;
+
<<Done>>
return Result (1 .. N);
@@ -2702,6 +2731,7 @@ package body Sem_Disp is
(S : Entity_Id;
No_Interfaces : Boolean := False;
Interfaces_Only : Boolean := False;
+ Skip_Overridden : Boolean := False;
One_Only : Boolean := False) return Subprogram_List renames
Inheritance_Utilities_Inst.Inherited_Subprograms;
diff --git a/gcc/ada/sem_disp.ads b/gcc/ada/sem_disp.ads
index 1e6c9e6..a2cfec8 100644
--- a/gcc/ada/sem_disp.ads
+++ b/gcc/ada/sem_disp.ads
@@ -120,6 +120,7 @@ package Sem_Disp is
(S : Entity_Id;
No_Interfaces : Boolean := False;
Interfaces_Only : Boolean := False;
+ Skip_Overridden : Boolean := False;
One_Only : Boolean := False) return Subprogram_List;
function Is_Overriding_Subprogram (E : Entity_Id) return Boolean;
@@ -129,6 +130,7 @@ package Sem_Disp is
(S : Entity_Id;
No_Interfaces : Boolean := False;
Interfaces_Only : Boolean := False;
+ Skip_Overridden : Boolean := False;
One_Only : Boolean := False) return Subprogram_List;
-- Given the spec of a subprogram, this function gathers any inherited
-- subprograms from direct inheritance or via interfaces. The result is an
@@ -143,6 +145,9 @@ package Sem_Disp is
-- subprograms inherited from interfaces. At most one of No_Interfaces
-- and Interfaces_Only should be True.
--
+ -- If Skip_Overridden is True, subprograms overridden by another subprogram
+ -- in the result list are skipped.
+ --
-- If One_Only is set, the search is discontinued as soon as one entry
-- is found. In this case the resulting array is either null or contains
-- exactly one element.
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index d9ea00e..736751f 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -12272,33 +12272,26 @@ package body Sem_Util is
begin
-- For selected components, the subtype of the selector must be a
-- constrained Unchecked_Union. If the component is subject to a
- -- per-object constraint, then the enclosing object must have inferable
- -- discriminants.
+ -- per-object constraint, then the enclosing object must either be
+ -- a regular discriminated type or must have inferable discriminants.
if Nkind (N) = N_Selected_Component then
- if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then
-
- -- A small hack. If we have a per-object constrained selected
- -- component of a formal parameter, return True since we do not
- -- know the actual parameter association yet.
-
- if Prefix_Is_Formal_Parameter (N) then
- return True;
-
- -- Otherwise, check the enclosing object and the selector
-
- else
- return Has_Inferable_Discriminants (Prefix (N))
- and then Has_Inferable_Discriminants (Selector_Name (N));
- end if;
-
-- The call to Has_Inferable_Discriminants will determine whether
-- the selector has a constrained Unchecked_Union nominal type.
- else
- return Has_Inferable_Discriminants (Selector_Name (N));
+ if not Has_Inferable_Discriminants (Selector_Name (N)) then
+ return False;
end if;
+ -- A small hack. If we have a per-object constrained selected
+ -- component of a formal parameter, return True since we do not
+ -- know the actual parameter association yet.
+
+ return not Has_Per_Object_Constraint (Entity (Selector_Name (N)))
+ or else not Is_Unchecked_Union (Etype (Prefix (N)))
+ or else Has_Inferable_Discriminants (Prefix (N))
+ or else Prefix_Is_Formal_Parameter (N);
+
-- A qualified expression has inferable discriminants if its subtype
-- mark is a constrained Unchecked_Union subtype.
@@ -12310,7 +12303,7 @@ package body Sem_Util is
-- Unchecked_Union nominal subtype.
else
- return Is_Unchecked_Union (Base_Type (Etype (N)))
+ return Is_Unchecked_Union (Etype (N))
and then Is_Constrained (Etype (N));
end if;
end Has_Inferable_Discriminants;
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index dd4f420..f54d409 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -1084,7 +1084,8 @@ package body Sprint is
Write_Str_With_Col_Check_Sloc ("(null record)");
else
- Write_Str_With_Col_Check_Sloc ("(");
+ Write_Str_With_Col_Check_Sloc
+ (if Is_Homogeneous_Aggregate (Node) then "[" else "(");
if Present (Expressions (Node)) then
Sprint_Comma_List (Expressions (Node));
@@ -1120,7 +1121,8 @@ package body Sprint is
Indent_End;
end if;
- Write_Char (')');
+ Write_Char
+ (if Is_Homogeneous_Aggregate (Node) then ']' else ')');
end if;
when N_Allocator =>
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 761674a..6b38d38 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,163 @@
+2023-06-29 benjamin priour <priour.be@gmail.com>
+
+ PR analyzer/110198
+ * region-model-manager.cc
+ (region_model_manager::get_or_create_initial_value): Take an
+ optional boolean value to bypass poisoning checks
+ * region-model-manager.h: Update declaration of the above function.
+ * region-model.cc (region_model::get_store_value): No longer returns
+ on OOB, but rather gives a boolean to get_or_create_initial_value.
+ (region_model::check_region_access): Update docstring.
+ (region_model::check_region_for_write): Update docstring.
+
+2023-06-24 David Malcolm <dmalcolm@redhat.com>
+
+ * access-diagram.cc: Add #define INCLUDE_VECTOR.
+ * bounds-checking.cc: Likewise.
+
+2023-06-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * access-diagram.cc: New file.
+ * access-diagram.h: New file.
+ * analyzer.h (class region_offset): Add default ctor.
+ (region_offset::make_byte_offset): New decl.
+ (region_offset::concrete_p): New.
+ (region_offset::get_concrete_byte_offset): New.
+ (region_offset::calc_symbolic_bit_offset): New decl.
+ (region_offset::calc_symbolic_byte_offset): New decl.
+ (region_offset::dump_to_pp): New decl.
+ (region_offset::dump): New decl.
+ (operator<, operator<=, operator>, operator>=): New decls for
+ region_offset.
+ * analyzer.opt
+ (-param=analyzer-text-art-string-ellipsis-threshold=): New.
+ (-param=analyzer-text-art-string-ellipsis-head-len=): New.
+ (-param=analyzer-text-art-string-ellipsis-tail-len=): New.
+ (-param=analyzer-text-art-ideal-canvas-width=): New.
+ (fanalyzer-debug-text-art): New.
+ * bounds-checking.cc: Include "intl.h", "diagnostic-diagram.h",
+ and "analyzer/access-diagram.h".
+ (class out_of_bounds::oob_region_creation_event_capacity): New.
+ (out_of_bounds::out_of_bounds): Add "model" and "sval_hint"
+ params.
+ (out_of_bounds::mark_interesting_stuff): Use the base region.
+ (out_of_bounds::add_region_creation_events): Use
+ oob_region_creation_event_capacity.
+ (out_of_bounds::get_dir): New pure vfunc.
+ (out_of_bounds::maybe_show_notes): New.
+ (out_of_bounds::maybe_show_diagram): New.
+ (out_of_bounds::make_access_diagram): New.
+ (out_of_bounds::m_model): New field.
+ (out_of_bounds::m_sval_hint): New field.
+ (out_of_bounds::m_region_creation_event_id): New field.
+ (concrete_out_of_bounds::concrete_out_of_bounds): Update for new
+ fields.
+ (concrete_past_the_end::concrete_past_the_end): Likewise.
+ (concrete_past_the_end::add_region_creation_events): Use
+ oob_region_creation_event_capacity.
+ (concrete_buffer_overflow::concrete_buffer_overflow): Update for
+ new fields.
+ (concrete_buffer_overflow::emit): Replace call to
+ maybe_describe_array_bounds with maybe_show_notes.
+ (concrete_buffer_overflow::get_dir): New.
+ (concrete_buffer_over_read::concrete_buffer_over_read): Update for
+ new fields.
+ (concrete_buffer_over_read::emit): Replace call to
+ maybe_describe_array_bounds with maybe_show_notes.
+ (concrete_buffer_overflow::get_dir): New.
+ (concrete_buffer_underwrite::concrete_buffer_underwrite): Update
+ for new fields.
+ (concrete_buffer_underwrite::emit): Replace call to
+ maybe_describe_array_bounds with maybe_show_notes.
+ (concrete_buffer_underwrite::get_dir): New.
+ (concrete_buffer_under_read::concrete_buffer_under_read): Update
+ for new fields.
+ (concrete_buffer_under_read::emit): Replace call to
+ maybe_describe_array_bounds with maybe_show_notes.
+ (concrete_buffer_under_read::get_dir): New.
+ (symbolic_past_the_end::symbolic_past_the_end): Update for new
+ fields.
+ (symbolic_buffer_overflow::symbolic_buffer_overflow): Likewise.
+ (symbolic_buffer_overflow::emit): Call maybe_show_notes.
+ (symbolic_buffer_overflow::get_dir): New.
+ (symbolic_buffer_over_read::symbolic_buffer_over_read): Update for
+ new fields.
+ (symbolic_buffer_over_read::emit): Call maybe_show_notes.
+ (symbolic_buffer_over_read::get_dir): New.
+ (region_model::check_symbolic_bounds): Add "sval_hint" param. Pass
+ it and sized_offset_reg to diagnostics.
+ (region_model::check_region_bounds): Add "sval_hint" param, passing
+ it to diagnostics.
+ * diagnostic-manager.cc
+ (diagnostic_manager::emit_saved_diagnostic): Pass logger to
+ pending_diagnostic::emit.
+ * engine.cc: Add logger param to pending_diagnostic::emit
+ implementations.
+ * infinite-recursion.cc: Likewise.
+ * kf-analyzer.cc: Likewise.
+ * kf.cc: Likewise. Add nullptr for new param of
+ check_region_for_write.
+ * pending-diagnostic.h: Likewise in decl.
+ * region-model-manager.cc
+ (region_model_manager::get_or_create_int_cst): Convert param from
+ poly_int64 to const poly_wide_int_ref &.
+ (region_model_manager::maybe_fold_binop): Support type being NULL
+ when checking for floating-point types.
+ Check for (X + Y) - X => Y. Be less strict about types when folding
+ associative ops. Check for (X + Y) * CST => (X * CST) + (Y * CST).
+ * region-model-manager.h
+ (region_model_manager::get_or_create_int_cst): Convert param from
+ poly_int64 to const poly_wide_int_ref &.
+ * region-model.cc: Add logger param to pending_diagnostic::emit
+ implementations.
+ (region_model::check_external_function_for_access_attr): Update
+ for new param of check_region_for_write.
+ (region_model::deref_rvalue): Use nullptr rather than NULL.
+ (region_model::get_capacity): Handle RK_STRING.
+ (region_model::check_region_access): Add "sval_hint" param; pass it to
+ check_region_bounds.
+ (region_model::check_region_for_write): Add "sval_hint" param;
+ pass it to check_region_access.
+ (region_model::check_region_for_read): Add NULL for new param to
+ check_region_access.
+ (region_model::set_value): Pass rhs_sval to
+ check_region_for_write.
+ (region_model::get_representative_path_var_1): Handle SK_CONSTANT
+ in the check for infinite recursion.
+ * region-model.h (region_model::check_region_for_write): Add
+ "sval_hint" param.
+ (region_model::check_region_access): Likewise.
+ (region_model::check_symbolic_bounds): Likewise.
+ (region_model::check_region_bounds): Likewise.
+ * region.cc (region_offset::make_byte_offset): New.
+ (region_offset::calc_symbolic_bit_offset): New.
+ (region_offset::calc_symbolic_byte_offset): New.
+ (region_offset::dump_to_pp): New.
+ (region_offset::dump): New.
+ (struct linear_op): New.
+ (operator<, operator<=, operator>, operator>=): New, for
+ region_offset.
+ (region::get_next_offset): New.
+ (region::get_relative_symbolic_offset): Use ptrdiff_type_node.
+ (field_region::get_relative_symbolic_offset): Likewise.
+ (element_region::get_relative_symbolic_offset): Likewise.
+ (bit_range_region::get_relative_symbolic_offset): Likewise.
+ * region.h (region::get_next_offset): New decl.
+ * sm-fd.cc: Add logger param to pending_diagnostic::emit
+ implementations.
+ * sm-file.cc: Likewise.
+ * sm-malloc.cc: Likewise.
+ * sm-pattern-test.cc: Likewise.
+ * sm-sensitive.cc: Likewise.
+ * sm-signal.cc: Likewise.
+ * sm-taint.cc: Likewise.
+ * store.cc (bit_range::contains_p): Allow "out" to be null.
+ * store.h (byte_range::get_start_bit_offset): New.
+ (byte_range::get_next_bit_offset): New.
+ * varargs.cc: Add logger param to pending_diagnostic::emit
+ implementations.
+
2023-06-10 Tim Lange <mail@tim-lange.me>
PR analyzer/109577
diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc
index 968ff50..467c9bd 100644
--- a/gcc/analyzer/access-diagram.cc
+++ b/gcc/analyzer/access-diagram.cc
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define INCLUDE_MEMORY
#define INCLUDE_MAP
#define INCLUDE_SET
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
diff --git a/gcc/analyzer/bounds-checking.cc b/gcc/analyzer/bounds-checking.cc
index 10632d1..5e8de9a 100644
--- a/gcc/analyzer/bounds-checking.cc
+++ b/gcc/analyzer/bounds-checking.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#define INCLUDE_MEMORY
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "make-unique.h"
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index 1453acf..4f11ef4 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -293,9 +293,10 @@ region_model_manager::create_unique_svalue (tree type)
necessary. */
const svalue *
-region_model_manager::get_or_create_initial_value (const region *reg)
+region_model_manager::get_or_create_initial_value (const region *reg,
+ bool check_poisoned)
{
- if (!reg->can_have_initial_svalue_p ())
+ if (!reg->can_have_initial_svalue_p () && check_poisoned)
return get_or_create_poisoned_svalue (POISON_KIND_UNINIT,
reg->get_type ());
diff --git a/gcc/analyzer/region-model-manager.h b/gcc/analyzer/region-model-manager.h
index 3340c3e..ff5333b 100644
--- a/gcc/analyzer/region-model-manager.h
+++ b/gcc/analyzer/region-model-manager.h
@@ -49,7 +49,8 @@ public:
tree type);
const svalue *get_or_create_poisoned_svalue (enum poison_kind kind,
tree type);
- const svalue *get_or_create_initial_value (const region *reg);
+ const svalue *get_or_create_initial_value (const region *reg,
+ bool check_poisoned = true);
const svalue *get_ptr_svalue (tree ptr_type, const region *pointee);
const svalue *get_or_create_unaryop (tree type, enum tree_code op,
const svalue *arg);
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 6bc60f8..187013a 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -2373,8 +2373,9 @@ region_model::get_store_value (const region *reg,
if (reg->empty_p ())
return m_mgr->get_or_create_unknown_svalue (reg->get_type ());
+ bool check_poisoned = true;
if (check_region_for_read (reg, ctxt))
- return m_mgr->get_or_create_unknown_svalue(reg->get_type());
+ check_poisoned = false;
/* Special-case: handle var_decls in the constant pool. */
if (const decl_region *decl_reg = reg->dyn_cast_decl_region ())
@@ -2427,7 +2428,7 @@ region_model::get_store_value (const region *reg,
== RK_GLOBALS)
return get_initial_value_for_global (reg);
- return m_mgr->get_or_create_initial_value (reg);
+ return m_mgr->get_or_create_initial_value (reg, check_poisoned);
}
/* Return false if REG does not exist, true if it may do.
@@ -2790,7 +2791,7 @@ region_model::get_string_size (const region *reg) const
/* If CTXT is non-NULL, use it to warn about any problems accessing REG,
using DIR to determine if this access is a read or write.
- Return TRUE if an UNKNOWN_SVALUE needs be created.
+ Return TRUE if an OOB access was detected.
If SVAL_HINT is non-NULL, use it as a hint in diagnostics
about the value that would be written to REG. */
@@ -2804,10 +2805,10 @@ region_model::check_region_access (const region *reg,
if (!ctxt)
return false;
- bool need_unknown_sval = false;
+ bool oob_access_detected = false;
check_region_for_taint (reg, dir, ctxt);
if (!check_region_bounds (reg, dir, sval_hint, ctxt))
- need_unknown_sval = true;
+ oob_access_detected = true;
switch (dir)
{
@@ -2820,7 +2821,7 @@ region_model::check_region_access (const region *reg,
check_for_writable_region (reg, ctxt);
break;
}
- return need_unknown_sval;
+ return oob_access_detected;
}
/* If CTXT is non-NULL, use it to warn about any problems writing to REG. */
@@ -2834,7 +2835,7 @@ region_model::check_region_for_write (const region *dest_reg,
}
/* If CTXT is non-NULL, use it to warn about any problems reading from REG.
- Returns TRUE if an unknown svalue needs be created. */
+ Returns TRUE if an OOB read was detected. */
bool
region_model::check_region_for_read (const region *src_reg,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index c78ad9c..6419820 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,30 @@
+2023-06-29 Qing Zhao <qing.zhao@oracle.com>
+
+ PR c/77650
+ * c.opt: New option -Wflex-array-member-not-at-end.
+
+2023-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/110344
+ * c-cppbuiltin.cc (c_cpp_builtins): Update __cpp_constexpr.
+
+2023-06-26 Richard Biener <rguenther@suse.de>
+
+ * c-common.cc (shorten_binary_op): Exit early for VECTOR_TYPE
+ operations.
+
+2023-06-23 Marek Polacek <polacek@redhat.com>
+
+ * c-common.h (cxx_dialect): Add cxx26 as a dialect.
+ * c-opts.cc (set_std_cxx26): New.
+ (c_common_handle_option): Set options when -std={c,gnu}++2{c,6} is
+ enabled.
+ (c_common_post_options): Adjust comments.
+ * c.opt: Add options for -std=c++26, std=c++2c, -std=gnu++26,
+ and -std=gnu++2c.
+ (std=c++2b): Mark as Undocumented.
+ (std=c++23): No longer Undocumented.
+
2023-06-21 Alexander Monakov <amonakov@ispras.ru>
* c-gimplify.cc (fma_supported_p): New helper.
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 9c8eed5..34566a3 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -1338,6 +1338,10 @@ shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
int uns;
tree type;
+ /* Do not shorten vector operations. */
+ if (VECTOR_TYPE_P (result_type))
+ return result_type;
+
/* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents
excessive narrowing when we call get_narrower below. For
example, suppose that OP0 is of unsigned int extended
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 336a09f..b5ef5ff 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -740,7 +740,9 @@ enum cxx_dialect {
/* C++20 */
cxx20,
/* C++23 */
- cxx23
+ cxx23,
+ /* C++26 */
+ cxx26
};
/* The C++ dialect being used. C++98 is the default. */
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 5d64625..6bd4c12 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1075,12 +1075,18 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_size_t_suffix=202011L");
cpp_define (pfile, "__cpp_if_consteval=202106L");
cpp_define (pfile, "__cpp_auto_cast=202110L");
- cpp_define (pfile, "__cpp_constexpr=202211L");
+ if (cxx_dialect <= cxx23)
+ cpp_define (pfile, "__cpp_constexpr=202211L");
cpp_define (pfile, "__cpp_multidimensional_subscript=202211L");
cpp_define (pfile, "__cpp_named_character_escapes=202207L");
cpp_define (pfile, "__cpp_static_call_operator=202207L");
cpp_define (pfile, "__cpp_implicit_move=202207L");
}
+ if (cxx_dialect > cxx23)
+ {
+ /* Set feature test macros for C++26. */
+ cpp_define (pfile, "__cpp_constexpr=202306L");
+ }
if (flag_concepts)
{
if (cxx_dialect >= cxx20)
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index c68a2a2..af19140 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -111,6 +111,7 @@ static void set_std_cxx14 (int);
static void set_std_cxx17 (int);
static void set_std_cxx20 (int);
static void set_std_cxx23 (int);
+static void set_std_cxx26 (int);
static void set_std_c89 (int, int);
static void set_std_c99 (int);
static void set_std_c11 (int);
@@ -663,6 +664,12 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
set_std_cxx23 (code == OPT_std_c__23 /* ISO */);
break;
+ case OPT_std_c__26:
+ case OPT_std_gnu__26:
+ if (!preprocessing_asm_p)
+ set_std_cxx26 (code == OPT_std_c__26 /* ISO */);
+ break;
+
case OPT_std_c90:
case OPT_std_iso9899_199409:
if (!preprocessing_asm_p)
@@ -1032,7 +1039,8 @@ c_common_post_options (const char **pfilename)
warn_narrowing = 1;
/* Unless -f{,no-}ext-numeric-literals has been used explicitly,
- for -std=c++{11,14,17,20,23} default to -fno-ext-numeric-literals. */
+ for -std=c++{11,14,17,20,23,26} default to
+ -fno-ext-numeric-literals. */
if (flag_iso && !OPTION_SET_P (flag_ext_numeric_literals))
cpp_opts->ext_numeric_literals = 0;
}
@@ -1820,6 +1828,24 @@ set_std_cxx23 (int iso)
lang_hooks.name = "GNU C++23";
}
+/* Set the C++ 2026 standard (without GNU extensions if ISO). */
+static void
+set_std_cxx26 (int iso)
+{
+ cpp_set_lang (parse_in, iso ? CLK_CXX26: CLK_GNUCXX26);
+ flag_no_gnu_keywords = iso;
+ flag_no_nonansi_builtin = iso;
+ flag_iso = iso;
+ /* C++26 includes the C11 standard library. */
+ flag_isoc94 = 1;
+ flag_isoc99 = 1;
+ flag_isoc11 = 1;
+ /* C++26 includes coroutines. */
+ flag_coroutines = true;
+ cxx_dialect = cxx26;
+ lang_hooks.name = "GNU C++26";
+}
+
/* Args to -d specify what to dump. Silently ignore
unrecognized options; they may be aimed at toplev.cc. */
static void
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 0930a3c04..4abdc8d 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -737,6 +737,11 @@ Wformat-truncation=
C ObjC C++ LTO ObjC++ Joined RejectNegative UInteger Var(warn_format_trunc) Warning LangEnabledBy(C ObjC C++ LTO ObjC++,Wformat=, warn_format >= 1, 0) IntegerRange(0, 2)
Warn about calls to snprintf and similar functions that truncate output.
+Wflex-array-member-not-at-end
+C C++ Var(warn_flex_array_member_not_at_end) Warning
+Warn when a structure containing a C99 flexible array member as the last
+field is not at the end of another structure.
+
Wif-not-aligned
C ObjC C++ ObjC++ Var(warn_if_not_aligned) Init(1) Warning
Warn when the field in a struct is not aligned.
@@ -2403,13 +2408,21 @@ C++ ObjC++
Conform to the ISO 2020 C++ standard (experimental and incomplete support).
std=c++2b
-C++ ObjC++ Alias(std=c++23)
+C++ ObjC++ Alias(std=c++23) Undocumented
Conform to the ISO 2023 C++ draft standard (experimental and incomplete support).
std=c++23
-C++ ObjC++ Undocumented
+C++ ObjC++
Conform to the ISO 2023 C++ draft standard (experimental and incomplete support).
+std=c++2c
+C++ ObjC++ Alias(std=c++26)
+Conform to the ISO 2026 C++ draft standard (experimental and incomplete support).
+
+std=c++26
+C++ ObjC++ Undocumented
+Conform to the ISO 2026 C++ draft standard (experimental and incomplete support).
+
std=c11
C ObjC
Conform to the ISO 2011 C standard.
@@ -2489,13 +2502,21 @@ C++ ObjC++
Conform to the ISO 2020 C++ standard with GNU extensions (experimental and incomplete support).
std=gnu++2b
-C++ ObjC++ Alias(std=gnu++23)
+C++ ObjC++ Alias(std=gnu++23) Undocumented
Conform to the ISO 2023 C++ draft standard with GNU extensions (experimental and incomplete support).
std=gnu++23
-C++ ObjC++ Undocumented
+C++ ObjC++
Conform to the ISO 2023 C++ draft standard with GNU extensions (experimental and incomplete support).
+std=gnu++2c
+C++ ObjC++ Alias(std=gnu++26)
+Conform to the ISO 2026 C++ draft standard with GNU extensions (experimental and incomplete support).
+
+std=gnu++26
+C++ ObjC++ Undocumented
+Conform to the ISO 2026 C++ draft standard with GNU extensions (experimental and incomplete support).
+
std=gnu11
C ObjC
Conform to the ISO 2011 C standard with GNU extensions.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 708c1c2..ed332e5 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,24 @@
+2023-06-29 Qing Zhao <qing.zhao@oracle.com>
+
+ PR c/77650
+ * c-decl.cc (finish_struct): Issue warnings for new option.
+
+2023-06-29 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-decl.cc (finish_struct): Set TYPE_INCLUDES_FLEXARRAY for
+ struct/union type.
+
+2023-06-29 Richard Biener <rguenther@suse.de>
+
+ PR c/110454
+ * c-typeck.cc (convert_argument): Sink formal_prec compute
+ to where TYPE_PRECISION is valid to use.
+
+2023-06-29 Eugene Rozenfeld <erozen@microsoft.com>
+
+ * Make-lang.in: Pass correct stage cc1 when processing
+ profile data collected while building target libraries
+
2023-06-16 David Malcolm <dmalcolm@redhat.com>
PR c/107583
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index 20840ac..79bc0df 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -113,10 +113,10 @@ create_fdas_for_cc1: ../stage1-gcc/cc1$(exeext) ../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=cc1_$$component_in_prev_target.fda; \
- $(CREATE_GCOV) -binary ../stage1-gcc/cc1$(exeext) -gcov $$profile_name -profile $$perf_path -gcov_version 2; \
+ $(CREATE_GCOV) -binary ../prev-gcc/cc1$(exeext) -gcov $$profile_name -profile $$perf_path -gcov_version 2; \
fi; \
done;
-#
+#
# Build hooks:
c.info:
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 1af51c4..ecd10eb 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9267,6 +9267,26 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
/* Set DECL_NOT_FLEXARRAY flag for FIELD_DECL x. */
DECL_NOT_FLEXARRAY (x) = !is_flexible_array_member_p (is_last_field, x);
+ /* Set TYPE_INCLUDES_FLEXARRAY for the context of x, t.
+ when x is an array and is the last field. */
+ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+ TYPE_INCLUDES_FLEXARRAY (t)
+ = is_last_field && flexible_array_member_type_p (TREE_TYPE (x));
+ /* Recursively set TYPE_INCLUDES_FLEXARRAY for the context of x, t
+ when x is an union or record and is the last field. */
+ else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
+ TYPE_INCLUDES_FLEXARRAY (t)
+ = is_last_field && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (x));
+
+ if (warn_flex_array_member_not_at_end
+ && !is_last_field
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (x))
+ && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (x)))
+ warning_at (DECL_SOURCE_LOCATION (x),
+ OPT_Wflex_array_member_not_at_end,
+ "structure containing a flexible array member"
+ " is not at the end of another structure");
+
if (DECL_NAME (x)
|| RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
saw_named_field = true;
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 22e240a..7cf4111 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -3385,8 +3385,6 @@ convert_argument (location_t ploc, tree function, tree fundecl,
conversions. */
if (warn_traditional_conversion || warn_traditional)
{
- unsigned int formal_prec = TYPE_PRECISION (type);
-
if (INTEGRAL_TYPE_P (type)
&& SCALAR_FLOAT_TYPE_P (valtype))
warning_at (ploc, OPT_Wtraditional_conversion,
@@ -3429,6 +3427,8 @@ convert_argument (location_t ploc, tree function, tree fundecl,
else if (SCALAR_FLOAT_TYPE_P (type)
&& SCALAR_FLOAT_TYPE_P (valtype))
{
+ unsigned int formal_prec = TYPE_PRECISION (type);
+
/* Warn if any argument is passed as `float',
since without a prototype it would be `double'. */
if (formal_prec == TYPE_PRECISION (float_type_node)
@@ -3472,6 +3472,7 @@ convert_argument (location_t ploc, tree function, tree fundecl,
&& INTEGRAL_TYPE_P (type)
&& INTEGRAL_TYPE_P (valtype))
{
+ unsigned int formal_prec = TYPE_PRECISION (type);
tree would_have_been = default_conversion (val);
tree type1 = TREE_TYPE (would_have_been);
diff --git a/gcc/cfg.cc b/gcc/cfg.cc
index 897ef53..57b4011 100644
--- a/gcc/cfg.cc
+++ b/gcc/cfg.cc
@@ -922,7 +922,6 @@ update_bb_profile_for_threading (basic_block bb,
fprintf (dump_file, "bb %i count became negative after threading",
bb->index);
}
- bb->count -= count;
/* Compute the probability of TAKEN_EDGE being reached via threaded edge.
Watch for overflows. */
@@ -934,8 +933,8 @@ update_bb_profile_for_threading (basic_block bb,
{
if (dump_file)
{
- fprintf (dump_file, "Jump threading proved probability of edge "
- "%i->%i too small (it is ",
+ fprintf (dump_file, "Jump threading proved that the probability of edge "
+ "%i->%i was originally estimated too small (it is ",
taken_edge->src->index, taken_edge->dest->index);
taken_edge->probability.dump (dump_file);
fprintf (dump_file, " should be ");
@@ -945,6 +944,8 @@ update_bb_profile_for_threading (basic_block bb,
prob = taken_edge->probability.apply_scale (6, 8);
}
+ bb->count -= count;
+
/* Now rescale the probabilities. */
taken_edge->probability -= prob;
prob = prob.invert ();
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 61559ed..ae48bc1 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -463,7 +463,6 @@ get_intel_cpu (struct __processor_model *cpu_model,
cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE;
break;
case 0xa7:
- case 0xa8:
/* Rocket Lake. */
cpu = "rocketlake";
CHECK___builtin_cpu_is ("corei7");
@@ -536,9 +535,9 @@ get_intel_cpu (struct __processor_model *cpu_model,
break;
case 0x97:
case 0x9a:
- case 0xbf:
/* Alder Lake. */
case 0xb7:
+ case 0xbf:
/* Raptor Lake. */
case 0xaa:
case 0xac:
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 3247d52..6091d8f 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -102,6 +102,23 @@ static const riscv_implied_info_t riscv_implied_info[] =
{"zvl32768b", "zvl16384b"},
{"zvl65536b", "zvl32768b"},
+ {"zvkn", "zvkned"},
+ {"zvkn", "zvknhb"},
+ {"zvkn", "zvbb"},
+ {"zvkn", "zvkt"},
+ {"zvknc", "zvkn"},
+ {"zvknc", "zvbc"},
+ {"zvkng", "zvkn"},
+ {"zvkng", "zvkg"},
+ {"zvks", "zvksed"},
+ {"zvks", "zvksh"},
+ {"zvks", "zvbb"},
+ {"zvks", "zvkt"},
+ {"zvksc", "zvks"},
+ {"zvksc", "zvbc"},
+ {"zvksg", "zvks"},
+ {"zvksg", "zvkg"},
+
{"zfh", "zfhmin"},
{"zfhmin", "f"},
{"zvfhmin", "zve32f"},
@@ -204,6 +221,22 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
{"zve64f", ISA_SPEC_CLASS_NONE, 1, 0},
{"zve64d", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvbb", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvbc", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvkg", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvkned", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvknha", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvknhb", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvksed", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvksh", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvkn", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvknc", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvkng", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvks", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvksc", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvksg", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvkt", ISA_SPEC_CLASS_NONE, 1, 0},
+
{"zvl32b", ISA_SPEC_CLASS_NONE, 1, 0},
{"zvl64b", ISA_SPEC_CLASS_NONE, 1, 0},
{"zvl128b", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -250,6 +283,12 @@ static const struct riscv_ext_version riscv_combine_info[] =
{"zk", ISA_SPEC_CLASS_NONE, 1, 0},
{"zkn", ISA_SPEC_CLASS_NONE, 1, 0},
{"zks", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvkn", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvknc", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvkng", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvks", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvksc", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zvksg", ISA_SPEC_CLASS_NONE, 1, 0},
/* Terminate the list. */
{NULL, ISA_SPEC_CLASS_NONE, 0, 0}
};
@@ -1251,6 +1290,22 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
{"zvfhmin", &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_16},
{"zvfh", &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_16},
+ {"zvbb", &gcc_options::x_riscv_zvb_subext, MASK_ZVBB},
+ {"zvbc", &gcc_options::x_riscv_zvb_subext, MASK_ZVBC},
+ {"zvkg", &gcc_options::x_riscv_zvk_subext, MASK_ZVKG},
+ {"zvkned", &gcc_options::x_riscv_zvk_subext, MASK_ZVKNED},
+ {"zvknha", &gcc_options::x_riscv_zvk_subext, MASK_ZVKNHA},
+ {"zvknhb", &gcc_options::x_riscv_zvk_subext, MASK_ZVKNHB},
+ {"zvksed", &gcc_options::x_riscv_zvk_subext, MASK_ZVKSED},
+ {"zvksh", &gcc_options::x_riscv_zvk_subext, MASK_ZVKSH},
+ {"zvkn", &gcc_options::x_riscv_zvk_subext, MASK_ZVKN},
+ {"zvknc", &gcc_options::x_riscv_zvk_subext, MASK_ZVKNC},
+ {"zvkng", &gcc_options::x_riscv_zvk_subext, MASK_ZVKNG},
+ {"zvks", &gcc_options::x_riscv_zvk_subext, MASK_ZVKS},
+ {"zvksc", &gcc_options::x_riscv_zvk_subext, MASK_ZVKSC},
+ {"zvksg", &gcc_options::x_riscv_zvk_subext, MASK_ZVKSG},
+ {"zvkt", &gcc_options::x_riscv_zvk_subext, MASK_ZVKT},
+
{"zvl32b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL32B},
{"zvl64b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL64B},
{"zvl128b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL128B},
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index a20a20c..70303d6 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -759,7 +759,7 @@ bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
bool aarch64_const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT,
HOST_WIDE_INT);
bool aarch64_const_vec_rnd_cst_p (rtx, rtx);
-bool aarch64_const_vec_rsra_rnd_imm_p (rtx);
+bool aarch64_rnd_imm_p (rtx);
bool aarch64_constant_address_p (rtx);
bool aarch64_emit_approx_div (rtx, rtx, rtx);
bool aarch64_emit_approx_sqrt (rtx, rtx, bool);
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 90118c6..d953941 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -975,6 +975,66 @@
}
)
+(define_insn "aarch64_<su>abdl<mode>_hi_internal"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (abs:<VWIDE>
+ (minus:<VWIDE>
+ (ANY_EXTEND:<VWIDE>
+ (vec_select:<VHALF>
+ (match_operand:VQW 1 "register_operand" "w")
+ (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
+ (ANY_EXTEND:<VWIDE>
+ (vec_select:<VHALF>
+ (match_operand:VQW 2 "register_operand" "w")
+ (match_dup 3))))))]
+ "TARGET_SIMD"
+ "<su>abdl2\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
+ [(set_attr "type" "neon_abd_long")]
+)
+
+(define_insn "aarch64_<su>abdl<mode>_lo_internal"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (abs:<VWIDE>
+ (minus:<VWIDE>
+ (ANY_EXTEND:<VWIDE>
+ (vec_select:<VHALF>
+ (match_operand:VQW 1 "register_operand" "w")
+ (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
+ (ANY_EXTEND:<VWIDE>
+ (vec_select:<VHALF>
+ (match_operand:VQW 2 "register_operand" "w")
+ (match_dup 3))))))]
+ "TARGET_SIMD"
+ "<su>abdl\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
+ [(set_attr "type" "neon_abd_long")]
+)
+
+(define_expand "vec_widen_<su>abd_hi_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
+ "TARGET_SIMD"
+ {
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
+ emit_insn (gen_aarch64_<su>abdl<mode>_hi_internal (operands[0], operands[1],
+ operands[2], p));
+ DONE;
+ }
+)
+
+(define_expand "vec_widen_<su>abd_lo_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
+ "TARGET_SIMD"
+ {
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
+ emit_insn (gen_aarch64_<su>abdl<mode>_lo_internal (operands[0], operands[1],
+ operands[2], p));
+ DONE;
+ }
+)
+
(define_insn "aarch64_<su>abal<mode>"
[(set (match_operand:<VWIDE> 0 "register_operand" "=w")
(plus:<VWIDE>
@@ -1323,7 +1383,7 @@
(plus:<V2XWIDE>
(<SHIFTEXTEND>:<V2XWIDE>
(match_operand:VSDQ_I_DI 2 "register_operand" "w"))
- (match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
(match_operand:VSDQ_I_DI 3 "aarch64_simd_shift_imm_<vec_or_offset>_<Vel>")))
(match_operand:VSDQ_I_DI 1 "register_operand" "0")))]
"TARGET_SIMD
@@ -6437,7 +6497,7 @@
(plus:<V2XWIDE>
(<SHIFTEXTEND>:<V2XWIDE>
(match_operand:VSDQ_I_DI 1 "register_operand" "w"))
- (match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
(match_operand:VSDQ_I_DI 2 "aarch64_simd_shift_imm_<vec_or_offset>_<Vel>"))))]
"TARGET_SIMD
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
@@ -6557,7 +6617,7 @@
(plus:<V2XWIDE>
(<TRUNCEXTEND>:<V2XWIDE>
(match_operand:VQN 1 "register_operand" "w"))
- (match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
(match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))))]
"TARGET_SIMD
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
@@ -6572,7 +6632,7 @@
(plus:<DWI>
(<TRUNCEXTEND>:<DWI>
(match_operand:SD_HSDI 1 "register_operand" "w"))
- (match_operand:<DWI> 3 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<DWI> 3 "aarch64_int_rnd_operand"))
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>"))))]
"TARGET_SIMD
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
@@ -6702,7 +6762,7 @@
(plus:<V2XWIDE>
(sign_extend:<V2XWIDE>
(match_operand:VQN 1 "register_operand" "w"))
- (match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
(match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))
(match_operand:<V2XWIDE> 4 "aarch64_simd_imm_zero"))
(match_operand:<V2XWIDE> 5 "aarch64_simd_umax_quarter_mode"))))]
@@ -6713,14 +6773,14 @@
)
(define_insn "aarch64_sqrshrun_n<mode>_insn"
- [(set (match_operand:<V2XWIDE> 0 "register_operand" "=w")
- (smin:<V2XWIDE>
- (smax:<V2XWIDE>
- (ashiftrt:<V2XWIDE>
- (plus:<V2XWIDE>
- (sign_extend:<V2XWIDE>
+ [(set (match_operand:<DWI> 0 "register_operand" "=w")
+ (smin:<DWI>
+ (smax:<DWI>
+ (ashiftrt:<DWI>
+ (plus:<DWI>
+ (sign_extend:<DWI>
(match_operand:SD_HSDI 1 "register_operand" "w"))
- (match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<DWI> 3 "aarch64_int_rnd_operand"))
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>"))
(const_int 0))
(const_int <half_mask>)))]
@@ -6736,10 +6796,10 @@
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>")]
"TARGET_SIMD"
{
- int prec = GET_MODE_UNIT_PRECISION (<V2XWIDE>mode);
+ int prec = GET_MODE_UNIT_PRECISION (<DWI>mode);
wide_int rnd_wi = wi::set_bit_in_zero (INTVAL (operands[2]) - 1, prec);
- rtx rnd = immed_wide_int_const (rnd_wi, <V2XWIDE>mode);
- rtx dst = gen_reg_rtx (<V2XWIDE>mode);
+ rtx rnd = immed_wide_int_const (rnd_wi, <DWI>mode);
+ rtx dst = gen_reg_rtx (<DWI>mode);
emit_insn (gen_aarch64_sqrshrun_n<mode>_insn (dst, operands[1], operands[2], rnd));
emit_move_insn (operands[0], gen_lowpart (<VNARROWQ>mode, dst));
DONE;
@@ -6831,7 +6891,7 @@
(plus:<V2XWIDE>
(<TRUNCEXTEND>:<V2XWIDE>
(match_operand:VQN 2 "register_operand" "w"))
- (match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")))))]
"TARGET_SIMD && !BYTES_BIG_ENDIAN
&& aarch64_const_vec_rnd_cst_p (operands[4], operands[3])"
@@ -6847,7 +6907,7 @@
(plus:<V2XWIDE>
(<TRUNCEXTEND>:<V2XWIDE>
(match_operand:VQN 2 "register_operand" "w"))
- (match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")))
(match_operand:<VNARROWQ> 1 "register_operand" "0")))]
"TARGET_SIMD && BYTES_BIG_ENDIAN
@@ -6965,7 +7025,7 @@
(plus:<V2XWIDE>
(sign_extend:<V2XWIDE>
(match_operand:VQN 2 "register_operand" "w"))
- (match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
(match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))))]
@@ -6985,7 +7045,7 @@
(plus:<V2XWIDE>
(sign_extend:<V2XWIDE>
(match_operand:VQN 2 "register_operand" "w"))
- (match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
+ (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
(match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))
@@ -8695,8 +8755,8 @@
"TARGET_SIMD"
{
int start = INTVAL (operands[2]);
- if (start != 0 && start != <nunits> / 2)
- FAIL;
+ gcc_assert (start == 0 || start == 1);
+ start *= <nunits> / 2;
rtx sel = aarch64_gen_stepped_int_parallel (<nunits> / 2, start, 1);
emit_insn (gen_aarch64_get_half<mode> (operands[0], operands[1], sel));
DONE;
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 95b4cb8..9010ecc 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -817,6 +817,52 @@ public:
class svdupq_impl : public quiet<function_base>
{
+private:
+ gimple *
+ fold_nonconst_dupq (gimple_folder &f) const
+ {
+ /* Lower lhs = svdupq (arg0, arg1, ..., argN} into:
+ tmp = {arg0, arg1, ..., arg<N-1>}
+ lhs = VEC_PERM_EXPR (tmp, tmp, {0, 1, 2, N-1, ...}) */
+
+ if (f.type_suffix (0).bool_p
+ || BYTES_BIG_ENDIAN)
+ return NULL;
+
+ tree lhs = gimple_call_lhs (f.call);
+ tree lhs_type = TREE_TYPE (lhs);
+ tree elt_type = TREE_TYPE (lhs_type);
+ scalar_mode elt_mode = SCALAR_TYPE_MODE (elt_type);
+ machine_mode vq_mode = aarch64_vq_mode (elt_mode).require ();
+ tree vq_type = build_vector_type_for_mode (elt_type, vq_mode);
+
+ unsigned nargs = gimple_call_num_args (f.call);
+ vec<constructor_elt, va_gc> *v;
+ vec_alloc (v, nargs);
+ for (unsigned i = 0; i < nargs; i++)
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, gimple_call_arg (f.call, i));
+ tree vec = build_constructor (vq_type, v);
+ tree tmp = make_ssa_name_fn (cfun, vq_type, 0);
+ gimple *g = gimple_build_assign (tmp, vec);
+
+ gimple_seq stmts = NULL;
+ gimple_seq_add_stmt_without_update (&stmts, g);
+
+ poly_uint64 lhs_len = TYPE_VECTOR_SUBPARTS (lhs_type);
+ vec_perm_builder sel (lhs_len, nargs, 1);
+ for (unsigned i = 0; i < nargs; i++)
+ sel.quick_push (i);
+
+ vec_perm_indices indices (sel, 1, nargs);
+ tree mask_type = build_vector_type (ssizetype, lhs_len);
+ tree mask = vec_perm_indices_to_tree (mask_type, indices);
+
+ gimple *g2 = gimple_build_assign (lhs, VEC_PERM_EXPR, tmp, tmp, mask);
+ gimple_seq_add_stmt_without_update (&stmts, g2);
+ gsi_replace_with_seq (f.gsi, stmts, false);
+ return g2;
+ }
+
public:
gimple *
fold (gimple_folder &f) const override
@@ -832,7 +878,7 @@ public:
{
tree elt = gimple_call_arg (f.call, i);
if (!CONSTANT_CLASS_P (elt))
- return NULL;
+ return fold_nonconst_dupq (f);
builder.quick_push (elt);
for (unsigned int j = 1; j < factor; ++j)
builder.quick_push (build_zero_cst (TREE_TYPE (vec_type)));
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 644ebde..560e543 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -11761,14 +11761,14 @@ aarch64_extract_vec_duplicate_wide_int (rtx x, wide_int *ret_wi)
return true;
}
-/* Return true if X is a TImode constant or a constant vector of integer
- immediates that represent the rounding constant used in the RSRA
- instructions.
- The accepted form of the constant is (1 << (C - 1)) where C is within
+/* Return true if X is a scalar or a constant vector of integer
+ immediates that represent the rounding constant used in the fixed-point
+ arithmetic instructions.
+ The accepted form of the constant is (1 << (C - 1)) where C is in the range
[1, MODE_WIDTH/2]. */
bool
-aarch64_const_vec_rsra_rnd_imm_p (rtx x)
+aarch64_rnd_imm_p (rtx x)
{
wide_int rnd_cst;
if (!aarch64_extract_vec_duplicate_wide_int (x, &rnd_cst))
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 7f9a512..9398d71 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1984,6 +1984,9 @@
;; Same as above, but louder.
(define_code_attr MAX_OPP [(smax "SMIN") (umax "UMIN")])
+;; Map smax and umax to sign_extend and zero_extend
+(define_code_attr USMAX_EXT [(smax "sign_extend") (umax "zero_extend")])
+
;; The number of subvectors in an SVE_STRUCT.
(define_mode_attr vector_count [(VNx32QI "2") (VNx16HI "2")
(VNx8SI "2") (VNx4DI "2")
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index b31ba6e..d5a4a1c 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -626,15 +626,11 @@
(and (match_code "const_vector")
(match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 64)")))
-(define_predicate "aarch64_simd_rsra_rnd_imm_vec"
+;; A constant or vector of constants that represents an integer rounding
+;; constant added during fixed-point arithmetic calculations
+(define_predicate "aarch64_int_rnd_operand"
(and (match_code "const_vector,const_int,const_wide_int")
- (match_test "aarch64_const_vec_rsra_rnd_imm_p (op)")))
-
-(define_predicate "aarch64_simd_rshrn_imm_vec"
- (and (match_code "const_vector")
- (match_test "aarch64_const_vec_all_same_in_range_p (op, 1,
- HOST_WIDE_INT_1U
- << (GET_MODE_UNIT_BITSIZE (mode) - 1))")))
+ (match_test "aarch64_rnd_imm_p (op)")))
(define_predicate "aarch64_simd_raddsubhn_imm_vec"
(and (match_code "const_vector")
diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc
index 7fca2af..f04f501 100644
--- a/gcc/config/cris/cris.cc
+++ b/gcc/config/cris/cris.cc
@@ -375,7 +375,6 @@ cris_postdbr_cmpelim ()
for (insn = get_insns (); insn; insn = next)
{
rtx_insn *outer_insn = insn;
- rtx pat = PATTERN (insn);
next = NEXT_INSN (outer_insn);
@@ -389,6 +388,7 @@ cris_postdbr_cmpelim ()
if (!NONDEBUG_INSN_P (insn))
continue;
+ rtx pat = PATTERN (insn);
/* Consider filled delay slots; there might be a comparison there.
It's only the second insn in a sequence that is interesting. */
diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index 7504b63..deb2f0c 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -50,9 +50,6 @@
[
;; Stack frame deallocation barrier.
CRIS_UNSPEC_FRAME_DEALLOC
-
- ;; Swap all 32 bits of the operand; 31 <=> 0, 30 <=> 1...
- CRIS_UNSPEC_SWAP_BITS
])
;; Register numbers.
@@ -2177,8 +2174,7 @@
(define_insn "cris_swap_bits"
[(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "register_operand" "0")]
- CRIS_UNSPEC_SWAP_BITS))
+ (bitreverse:SI (match_operand:SI 1 "register_operand" "0")))
(clobber (reg:CC CRIS_CC0_REGNUM))]
"TARGET_HAS_SWAP"
"swapwbr %0"
@@ -2193,8 +2189,7 @@
(match_operand:SI 1 "register_operand"))
(clobber (reg:CC CRIS_CC0_REGNUM))])
(parallel
- [(set (match_dup 2)
- (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS))
+ [(set (match_dup 2) (bitreverse:SI (match_dup 2)))
(clobber (reg:CC CRIS_CC0_REGNUM))])
(parallel
[(set (match_operand:SI 0 "register_operand")
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index e6f76e5..714d3d5 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -217,8 +217,7 @@ extern GTY(()) int darwin_ms_struct;
"%{image_base*:-Xlinker -image_base -Xlinker %*} %<image_base*", \
"%{init*:-Xlinker -init -Xlinker %*} %<init*", \
"%{multi_module:-Xlinker -multi_module} %<multi_module", \
- "%{multiply_defined*:-Xlinker -multiply_defined -Xlinker %*} \
- %<multiply_defined* ", \
+ "%{multiply_defined*:-Xlinker -multiply_defined -Xlinker %*} ", \
"%{multiplydefinedunused*:\
-Xlinker -multiply_defined_unused -Xlinker %*} \
%<multiplydefinedunused* ", \
@@ -294,7 +293,7 @@ extern GTY(()) int darwin_ms_struct;
%:version-compare(>= 10.7 mmacosx-version-min= -no_pie) }"
#define DARWIN_CC1_SPEC \
- "%<dynamic %<dynamiclib %<force_cpusubtype_ALL "
+ "%<dynamic %<dynamiclib %<force_cpusubtype_ALL %<multiply_defined* "
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
do { \
diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt
index feaa958..d655aae 100644
--- a/gcc/config/darwin.opt
+++ b/gcc/config/darwin.opt
@@ -33,6 +33,10 @@ fapple-kext
Target C++ Var(flag_apple_kext)
Generate code for darwin loadable kernel extensions.
+fconstant-cfstrings
+ObjC ObjC++ Alias(mconstant-cfstrings)
+Generate compile-time CFString objects.
+
iframework
Target RejectNegative C ObjC C++ ObjC++ Joined Separate
-iframework <dir> Add <dir> to the end of the system framework include path.
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 9a8d244..567248d 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -2365,6 +2365,7 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
/* Handle special case - vector comparsion with boolean result, transform
it using ptest instruction. */
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+ || (mode == TImode && !TARGET_64BIT)
|| mode == OImode)
{
rtx flag = gen_rtx_REG (CCZmode, FLAGS_REG);
@@ -2372,7 +2373,7 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
gcc_assert (code == EQ || code == NE);
- if (mode == OImode)
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
{
op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index 4a3b07a..2e751d1 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -582,6 +582,25 @@ general_scalar_chain::compute_convert_gain ()
igain -= vector_const_cost (XEXP (src, 0));
break;
+ case ROTATE:
+ case ROTATERT:
+ igain += m * ix86_cost->shift_const;
+ if (smode == DImode)
+ {
+ int bits = INTVAL (XEXP (src, 1));
+ if ((bits & 0x0f) == 0)
+ igain -= ix86_cost->sse_op;
+ else if ((bits & 0x07) == 0)
+ igain -= 2 * ix86_cost->sse_op;
+ else
+ igain -= 3 * ix86_cost->sse_op;
+ }
+ else if (INTVAL (XEXP (src, 1)) == 16)
+ igain -= ix86_cost->sse_op;
+ else
+ igain -= 2 * ix86_cost->sse_op;
+ break;
+
case AND:
case IOR:
case XOR:
@@ -631,7 +650,31 @@ general_scalar_chain::compute_convert_gain ()
break;
case COMPARE:
- /* Assume comparison cost is the same. */
+ if (XEXP (src, 1) != const0_rtx)
+ {
+ /* cmp vs. pxor;pshufd;ptest. */
+ igain += COSTS_N_INSNS (m - 3);
+ }
+ else if (GET_CODE (XEXP (src, 0)) != AND)
+ {
+ /* test vs. pshufd;ptest. */
+ igain += COSTS_N_INSNS (m - 2);
+ }
+ else if (GET_CODE (XEXP (XEXP (src, 0), 0)) != NOT)
+ {
+ /* and;test vs. pshufd;ptest. */
+ igain += COSTS_N_INSNS (2 * m - 2);
+ }
+ else if (TARGET_BMI)
+ {
+ /* andn;test vs. pandn;pshufd;ptest. */
+ igain += COSTS_N_INSNS (2 * m - 3);
+ }
+ else
+ {
+ /* not;and;test vs. pandn;pshufd;ptest. */
+ igain += COSTS_N_INSNS (3 * m - 3);
+ }
break;
case CONST_INT:
@@ -1154,6 +1197,95 @@ scalar_chain::convert_insn_common (rtx_insn *insn)
}
}
+/* Convert INSN which is an SImode or DImode rotation by a constant
+ to vector mode. CODE is either ROTATE or ROTATERT with operands
+ OP0 and OP1. Returns the SET_SRC of the last instruction in the
+ resulting sequence, which is emitted before INSN. */
+
+rtx
+general_scalar_chain::convert_rotate (enum rtx_code code, rtx op0, rtx op1,
+ rtx_insn *insn)
+{
+ int bits = INTVAL (op1);
+ rtx pat, result;
+
+ convert_op (&op0, insn);
+ if (bits == 0)
+ return op0;
+
+ if (smode == DImode)
+ {
+ if (code == ROTATE)
+ bits = 64 - bits;
+ if (bits == 32)
+ {
+ rtx tmp1 = gen_reg_rtx (V4SImode);
+ pat = gen_sse2_pshufd (tmp1, gen_lowpart (V4SImode, op0),
+ GEN_INT (225));
+ emit_insn_before (pat, insn);
+ result = gen_lowpart (V2DImode, tmp1);
+ }
+ else if (bits == 16 || bits == 48)
+ {
+ rtx tmp1 = gen_reg_rtx (V8HImode);
+ pat = gen_sse2_pshuflw (tmp1, gen_lowpart (V8HImode, op0),
+ GEN_INT (bits == 16 ? 57 : 147));
+ emit_insn_before (pat, insn);
+ result = gen_lowpart (V2DImode, tmp1);
+ }
+ else if ((bits & 0x07) == 0)
+ {
+ rtx tmp1 = gen_reg_rtx (V4SImode);
+ pat = gen_sse2_pshufd (tmp1, gen_lowpart (V4SImode, op0),
+ GEN_INT (68));
+ emit_insn_before (pat, insn);
+ rtx tmp2 = gen_reg_rtx (V1TImode);
+ pat = gen_sse2_lshrv1ti3 (tmp2, gen_lowpart (V1TImode, tmp1),
+ GEN_INT (bits));
+ emit_insn_before (pat, insn);
+ result = gen_lowpart (V2DImode, tmp2);
+ }
+ else
+ {
+ rtx tmp1 = gen_reg_rtx (V4SImode);
+ pat = gen_sse2_pshufd (tmp1, gen_lowpart (V4SImode, op0),
+ GEN_INT (20));
+ emit_insn_before (pat, insn);
+ rtx tmp2 = gen_reg_rtx (V2DImode);
+ pat = gen_lshrv2di3 (tmp2, gen_lowpart (V2DImode, tmp1),
+ GEN_INT (bits & 31));
+ emit_insn_before (pat, insn);
+ rtx tmp3 = gen_reg_rtx (V4SImode);
+ pat = gen_sse2_pshufd (tmp3, gen_lowpart (V4SImode, tmp2),
+ GEN_INT (bits > 32 ? 34 : 136));
+ emit_insn_before (pat, insn);
+ result = gen_lowpart (V2DImode, tmp3);
+ }
+ }
+ else if (bits == 16)
+ {
+ rtx tmp1 = gen_reg_rtx (V8HImode);
+ pat = gen_sse2_pshuflw (tmp1, gen_lowpart (V8HImode, op0), GEN_INT (225));
+ emit_insn_before (pat, insn);
+ result = gen_lowpart (V4SImode, tmp1);
+ }
+ else
+ {
+ if (code == ROTATE)
+ bits = 32 - bits;
+
+ rtx tmp1 = gen_reg_rtx (V4SImode);
+ emit_insn_before (gen_sse2_pshufd (tmp1, op0, GEN_INT (224)), insn);
+ rtx tmp2 = gen_reg_rtx (V2DImode);
+ pat = gen_lshrv2di3 (tmp2, gen_lowpart (V2DImode, tmp1),
+ GEN_INT (bits));
+ emit_insn_before (pat, insn);
+ result = gen_lowpart (V4SImode, tmp2);
+ }
+
+ return result;
+}
+
/* Convert INSN to vector mode. */
void
@@ -1209,6 +1341,12 @@ general_scalar_chain::convert_insn (rtx_insn *insn)
PUT_MODE (src, vmode);
break;
+ case ROTATE:
+ case ROTATERT:
+ src = convert_rotate (GET_CODE (src), XEXP (src, 0), XEXP (src, 1),
+ insn);
+ break;
+
case NEG:
src = XEXP (src, 0);
@@ -1982,6 +2120,8 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode)
case ASHIFT:
case LSHIFTRT:
+ case ROTATE:
+ case ROTATERT:
if (!CONST_INT_P (XEXP (src, 1))
|| !IN_RANGE (INTVAL (XEXP (src, 1)), 0, GET_MODE_BITSIZE (mode)-1))
return false;
@@ -2489,8 +2629,7 @@ public:
/* opt_pass methods: */
bool gate (function *) final override
{
- return TARGET_AVX && TARGET_VZEROUPPER
- && flag_expensive_optimizations && !optimize_size;
+ return TARGET_AVX && TARGET_VZEROUPPER;
}
unsigned int execute (function *) final override
diff --git a/gcc/config/i386/i386-features.h b/gcc/config/i386/i386-features.h
index 72a9f54..af5acbb 100644
--- a/gcc/config/i386/i386-features.h
+++ b/gcc/config/i386/i386-features.h
@@ -189,6 +189,7 @@ class general_scalar_chain : public scalar_chain
void convert_insn (rtx_insn *insn) final override;
void convert_op (rtx *op, rtx_insn *insn) final override;
int vector_const_cost (rtx exp);
+ rtx convert_rotate (enum rtx_code, rtx op0, rtx op1, rtx_insn *insn);
};
class timode_scalar_chain : public scalar_chain
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index 2cb0bdd..37cb5a0 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -1400,7 +1400,11 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args,
if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE])
opts->x_ix86_tune_string
= ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]);
- else if (orig_tune_defaulted)
+ /* If we have explicit arch string and no tune string specified, set
+ tune_string to NULL and later it will be overriden by arch_string
+ so target clones can get proper optimization. */
+ else if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
+ || orig_tune_defaulted)
opts->x_ix86_tune_string = NULL;
/* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */
@@ -2727,7 +2731,9 @@ ix86_option_override_internal (bool main_args_p,
sorry ("%<-mcall-ms2sysv-xlogues%> isn%'t currently supported with SEH");
if (!(opts_set->x_target_flags & MASK_VZEROUPPER)
- && TARGET_EMIT_VZEROUPPER)
+ && TARGET_EMIT_VZEROUPPER
+ && flag_expensive_optimizations
+ && !optimize_size)
opts->x_target_flags |= MASK_VZEROUPPER;
if (!(opts_set->x_target_flags & MASK_STV))
opts->x_target_flags |= MASK_STV;
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 0761965..a9da66d 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -14489,8 +14489,9 @@ ix86_avx_u128_mode_needed (rtx_insn *insn)
modes wider than 256 bits. It's only safe to issue a
vzeroupper if all SSE registers are clobbered. */
const function_abi &abi = insn_callee_abi (insn);
- if (!hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
- abi.mode_clobbers (V4DImode)))
+ if (vzeroupper_pattern (PATTERN (insn), VOIDmode)
+ || !hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
+ abi.mode_clobbers (V4DImode)))
return AVX_U128_ANY;
return AVX_U128_CLEAN;
@@ -21178,6 +21179,32 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
return false;
case IOR:
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+ {
+ /* (ior (not ...) ...) can be a single insn in AVX512. */
+ if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F
+ && (GET_MODE_SIZE (mode) == 64
+ || (TARGET_AVX512VL
+ && (GET_MODE_SIZE (mode) == 32
+ || GET_MODE_SIZE (mode) == 16))))
+ {
+ rtx right = GET_CODE (XEXP (x, 1)) != NOT
+ ? XEXP (x, 1) : XEXP (XEXP (x, 1), 0);
+
+ *total = ix86_vec_cost (mode, cost->sse_op)
+ + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
+ outer_code, opno, speed)
+ + rtx_cost (right, mode, outer_code, opno, speed);
+ return true;
+ }
+ *total = ix86_vec_cost (mode, cost->sse_op);
+ }
+ else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+ *total = cost->add * 2;
+ else
+ *total = cost->add;
+ return false;
+
case XOR:
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
*total = ix86_vec_cost (mode, cost->sse_op);
@@ -21198,11 +21225,20 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
/* pandn is a single instruction. */
if (GET_CODE (XEXP (x, 0)) == NOT)
{
+ rtx right = XEXP (x, 1);
+
+ /* (and (not ...) (not ...)) can be a single insn in AVX512. */
+ if (GET_CODE (right) == NOT && TARGET_AVX512F
+ && (GET_MODE_SIZE (mode) == 64
+ || (TARGET_AVX512VL
+ && (GET_MODE_SIZE (mode) == 32
+ || GET_MODE_SIZE (mode) == 16))))
+ right = XEXP (right, 0);
+
*total = ix86_vec_cost (mode, cost->sse_op)
+ rtx_cost (XEXP (XEXP (x, 0), 0), mode,
outer_code, opno, speed)
- + rtx_cost (XEXP (x, 1), mode,
- outer_code, opno, speed);
+ + rtx_cost (right, mode, outer_code, opno, speed);
return true;
}
else if (GET_CODE (XEXP (x, 1)) == NOT)
@@ -21260,8 +21296,25 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
case NOT:
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
- // vnot is pxor -1.
- *total = ix86_vec_cost (mode, cost->sse_op) + 1;
+ {
+ /* (not (xor ...)) can be a single insn in AVX512. */
+ if (GET_CODE (XEXP (x, 0)) == XOR && TARGET_AVX512F
+ && (GET_MODE_SIZE (mode) == 64
+ || (TARGET_AVX512VL
+ && (GET_MODE_SIZE (mode) == 32
+ || GET_MODE_SIZE (mode) == 16))))
+ {
+ *total = ix86_vec_cost (mode, cost->sse_op)
+ + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
+ outer_code, opno, speed)
+ + rtx_cost (XEXP (XEXP (x, 0), 1), mode,
+ outer_code, opno, speed);
+ return true;
+ }
+
+ // vnot is pxor -1.
+ *total = ix86_vec_cost (mode, cost->sse_op) + 1;
+ }
else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
*total = cost->add * 2;
else
@@ -22718,6 +22771,35 @@ x86_emit_floatuns (rtx operands[2])
emit_label (donelab);
}
+
+/* Return the diagnostic message string if conversion from FROMTYPE to
+ TOTYPE is not allowed, NULL otherwise.
+ Currently it's used to warn for silent implicit conversion between __bf16
+ and short, since __bfloat16 is refined as real __bf16 instead of short
+ since GCC13. */
+
+static const char *
+ix86_invalid_conversion (const_tree fromtype, const_tree totype)
+{
+ if (element_mode (fromtype) != element_mode (totype)
+ && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT))
+ {
+ /* Warn for silent implicit conversion where user may expect
+ a bitcast. */
+ if ((TYPE_MODE (fromtype) == BFmode
+ && TYPE_MODE (totype) == HImode)
+ || (TYPE_MODE (totype) == BFmode
+ && TYPE_MODE (fromtype) == HImode))
+ warning (0, "%<__bfloat16%> is redefined from typedef %<short%> "
+ "to real %<__bf16%> since GCC V13, be careful of "
+ "implicit conversion between %<__bf16%> and %<short%>; "
+ "a explicit bitcast may be needed here");
+ }
+
+ /* Conversion allowed. */
+ return NULL;
+}
+
/* Target hook for scalar_mode_supported_p. */
static bool
@@ -25009,6 +25091,9 @@ ix86_run_selftests (void)
# define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
#endif
+#undef TARGET_INVALID_CONVERSION
+#define TARGET_INVALID_CONVERSION ix86_invalid_conversion
+
#undef TARGET_COMP_TYPE_ATTRIBUTES
#define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 5ac9c78..84ebafd 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2341,7 +2341,7 @@ constexpr wide_int_bitmask PTA_ALDERLAKE = PTA_TREMONT | PTA_ADX | PTA_AVX
| PTA_PCONFIG | PTA_PKU | PTA_VAES | PTA_VPCLMULQDQ | PTA_SERIALIZE
| PTA_HRESET | PTA_KL | PTA_WIDEKL | PTA_AVXVNNI;
constexpr wide_int_bitmask PTA_SIERRAFOREST = PTA_ALDERLAKE | PTA_AVXIFMA
- | PTA_AVXVNNIINT8 | PTA_AVXNECONVERT | PTA_CMPCCXADD;
+ | PTA_AVXVNNIINT8 | PTA_AVXNECONVERT | PTA_CMPCCXADD | PTA_ENQCMD | PTA_UINTR;
constexpr wide_int_bitmask PTA_GRANITERAPIDS = PTA_SAPPHIRERAPIDS | PTA_AMX_FP16
| PTA_PREFETCHI | PTA_AMX_COMPLEX;
constexpr wide_int_bitmask PTA_GRANDRIDGE = PTA_SIERRAFOREST | PTA_RAOINT;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 95a6653c..a82cc35 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1352,8 +1352,8 @@
(define_expand "cbranch<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
- (match_operand:SDWIM 2 "<general_operand>")))
+ (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
+ (match_operand:SWIM1248x 2 "<general_operand>")))
(set (pc) (if_then_else
(match_operator 0 "ordered_comparison_operator"
[(reg:CC FLAGS_REG) (const_int 0)])
@@ -1368,6 +1368,22 @@
DONE;
})
+(define_expand "cbranchti4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:TI 1 "nonimmediate_operand")
+ (match_operand:TI 2 "ix86_timode_comparison_operand")))
+ (set (pc) (if_then_else
+ (match_operator 0 "ix86_timode_comparison_operator"
+ [(reg:CC FLAGS_REG) (const_int 0)])
+ (label_ref (match_operand 3))
+ (pc)))]
+ "TARGET_64BIT || TARGET_SSE4_1"
+{
+ ix86_expand_branch (GET_CODE (operands[0]),
+ operands[1], operands[2], operands[3]);
+ DONE;
+})
+
(define_expand "cbranchoi4"
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:OI 1 "nonimmediate_operand")
@@ -11380,6 +11396,8 @@
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
+;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
+
;; Convert wide AND instructions with immediate operand to shorter QImode
;; equivalents when possible.
;; Don't do the splitting with memory operands, since it introduces risk
@@ -12092,6 +12110,26 @@
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
+(define_insn "*<code>qi_ext<mode>_3"
+ [(set (zero_extract:SWI248
+ (match_operand 0 "int248_register_operand" "+Q")
+ (const_int 8)
+ (const_int 8))
+ (zero_extract:SWI248
+ (any_logic:SWI248
+ (match_operand 1 "int248_register_operand" "%0")
+ (match_operand 2 "int248_register_operand" "Q"))
+ (const_int 8)
+ (const_int 8)))
+ (clobber (reg:CC FLAGS_REG))]
+ "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && (rtx_equal_p (operands[0], operands[1])
+ || rtx_equal_p (operands[0], operands[2]))"
+ "<logic>{b}\t{%h2, %h0|%h0, %h2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "QI")])
+
;; Convert wide OR instructions with immediate operand to shorter QImode
;; equivalents when possible.
;; Don't do the splitting with memory operands, since it introduces risk
@@ -12206,6 +12244,18 @@
(set_attr "type" "alu")
(set_attr "mode" "QI")])
+;; Peephole2 rega = 0; rega op= regb into rega = regb.
+(define_peephole2
+ [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
+ (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (match_dup 0)
+ (any_or_plus:SWI (match_dup 0)
+ (match_operand:SWI 1 "<general_operand>")))
+ (clobber (reg:CC FLAGS_REG))])]
+ ""
+ [(set (match_dup 0) (match_dup 1))])
+
;; Split DST = (HI<<32)|LO early to minimize register usage.
(define_insn_and_split "*concat<mode><dwi>3_1"
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
@@ -13365,6 +13415,28 @@
[(const_int 0)]
"ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
+(define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
+ [(set (match_operand:<DWI> 0 "register_operand" "=r")
+ (ashift:<DWI>
+ (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
+ (match_operand:QI 2 "const_int_operand")))
+ (clobber (reg:CC FLAGS_REG))]
+ "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
+ && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
+ int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
+ if (!rtx_equal_p (operands[3], operands[1]))
+ emit_move_insn (operands[3], operands[1]);
+ if (bits > 0)
+ emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
+ ix86_expand_clear (operands[0]);
+ DONE;
+})
+
(define_insn "x86_64_shld"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
(ior:DI (ashift:DI (match_dup 0)
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index fb07707..7ddbe01 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1641,6 +1641,18 @@
(match_operand 0 "comparison_operator")
(match_operand 0 "ix86_trivial_fp_comparison_operator")))
+;; Return true if we can perform this comparison on TImode operands.
+(define_predicate "ix86_timode_comparison_operator"
+ (if_then_else (match_test "TARGET_64BIT")
+ (match_operand 0 "ordered_comparison_operator")
+ (match_operand 0 "bt_comparison_operator")))
+
+;; Return true if this is a valid second operand for a TImode comparison.
+(define_predicate "ix86_timode_comparison_operand"
+ (if_then_else (match_test "TARGET_64BIT")
+ (match_operand 0 "x86_64_general_operand")
+ (match_operand 0 "nonimmediate_operand")))
+
;; Nearly general operand, but accept any const_double, since we wish
;; to be able to drop them into memory rather than have them get pulled
;; into registers.
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index a847a2b..418c337 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -1465,12 +1465,12 @@
})
(define_insn "*<avx512>_load<mode>_mask"
- [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
- (vec_merge:VI12_AVX512VL
- (unspec:VI12_AVX512VL
- [(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
+ [(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand" "=v")
+ (vec_merge:VI12HFBF_AVX512VL
+ (unspec:VI12HFBF_AVX512VL
+ [(match_operand:VI12HFBF_AVX512VL 1 "memory_operand" "m")]
UNSPEC_MASKLOAD)
- (match_operand:VI12_AVX512VL 2 "nonimm_or_0_operand" "0C")
+ (match_operand:VI12HFBF_AVX512VL 2 "nonimm_or_0_operand" "0C")
(match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
"TARGET_AVX512BW"
"vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
@@ -1479,9 +1479,9 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn_and_split "*<avx512>_load<mode>"
- [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
- (unspec:VI12_AVX512VL
- [(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
+ [(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand" "=v")
+ (unspec:VI12HFBF_AVX512VL
+ [(match_operand:VI12HFBF_AVX512VL 1 "memory_operand" "m")]
UNSPEC_MASKLOAD))]
"TARGET_AVX512BW"
"#"
@@ -1608,7 +1608,7 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<avx512>_store<mode>_mask"
+(define_insn "*<avx512>_store<mode>_mask"
[(set (match_operand:V48_AVX512VL 0 "memory_operand" "=m")
(vec_merge:V48_AVX512VL
(match_operand:V48_AVX512VL 1 "register_operand" "v")
@@ -1636,7 +1636,7 @@
(set_attr "memory" "store")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<avx512>_store<mode>_mask"
+(define_insn "*<avx512>_store<mode>_mask"
[(set (match_operand:VI12HFBF_AVX512VL 0 "memory_operand" "=m")
(vec_merge:VI12HFBF_AVX512VL
(match_operand:VI12HFBF_AVX512VL 1 "register_operand" "v")
@@ -17156,7 +17156,7 @@
(define_expand "one_cmpl<mode>2"
[(set (match_operand:VI 0 "register_operand")
- (xor:VI (match_operand:VI 1 "vector_operand")
+ (xor:VI (match_operand:VI 1 "bcst_vector_operand")
(match_dup 2)))]
"TARGET_SSE"
{
@@ -17168,7 +17168,7 @@
(define_insn "<mask_codefor>one_cmpl<mode>2<mask_name>"
[(set (match_operand:VI 0 "register_operand" "=v,v")
- (xor:VI (match_operand:VI 1 "nonimmediate_operand" "v,m")
+ (xor:VI (match_operand:VI 1 "bcst_vector_operand" "vBr,m")
(match_operand:VI 2 "vector_all_ones_operand" "BC,BC")))]
"TARGET_AVX512F
&& (!<mask_applied>
@@ -17191,6 +17191,19 @@
(symbol_ref "<MODE_SIZE> == 64 || TARGET_AVX512VL")
(const_int 1)))])
+(define_split
+ [(set (match_operand:VI48_AVX512F 0 "register_operand")
+ (vec_duplicate:VI48_AVX512F
+ (not:<ssescalarmode>
+ (match_operand:<ssescalarmode> 1 "nonimmediate_operand"))))]
+ "<MODE_SIZE> == 64 || TARGET_AVX512VL
+ || (TARGET_AVX512F && !TARGET_PREFER_AVX256)"
+ [(set (match_dup 0)
+ (xor:VI48_AVX512F
+ (vec_duplicate:VI48_AVX512F (match_dup 1))
+ (match_dup 2)))]
+ "operands[2] = CONSTM1_RTX (<MODE>mode);")
+
(define_expand "<sse2_avx2>_andnot<mode>3"
[(set (match_operand:VI_AVX2 0 "register_operand")
(and:VI_AVX2
@@ -17210,11 +17223,13 @@
"TARGET_AVX512F")
(define_insn "*andnot<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=x,x,v")
+ [(set (match_operand:VI 0 "register_operand" "=x,x,v,v,v")
(and:VI
- (not:VI (match_operand:VI 1 "vector_operand" "0,x,v"))
- (match_operand:VI 2 "bcst_vector_operand" "xBm,xm,vmBr")))]
- "TARGET_SSE"
+ (not:VI (match_operand:VI 1 "bcst_vector_operand" "0,x,v,m,Br"))
+ (match_operand:VI 2 "bcst_vector_operand" "xBm,xm,vmBr,v,v")))]
+ "TARGET_SSE
+ && (register_operand (operands[1], <MODE>mode)
+ || register_operand (operands[2], <MODE>mode))"
{
char buf[64];
const char *ops;
@@ -17281,6 +17296,15 @@
case 2:
ops = "v%s%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
break;
+ case 3:
+ case 4:
+ tmp = "pternlog";
+ ssesuffix = "<ternlogsuffix>";
+ if (which_alternative != 4 || TARGET_AVX512VL)
+ ops = "v%s%s\t{$0x44, %%1, %%2, %%0|%%0, %%2, %%1, $0x44}";
+ else
+ ops = "v%s%s\t{$0x44, %%g1, %%g2, %%g0|%%g0, %%g2, %%g1, $0x44}";
+ break;
default:
gcc_unreachable ();
}
@@ -17289,7 +17313,7 @@
output_asm_insn (buf, operands);
return "";
}
- [(set_attr "isa" "noavx,avx,avx")
+ [(set_attr "isa" "noavx,avx,avx,*,*")
(set_attr "type" "sselog")
(set (attr "prefix_data16")
(if_then_else
@@ -17297,9 +17321,12 @@
(eq_attr "mode" "TI"))
(const_string "1")
(const_string "*")))
- (set_attr "prefix" "orig,vex,evex")
+ (set_attr "prefix" "orig,vex,evex,evex,evex")
(set (attr "mode")
- (cond [(match_test "TARGET_AVX2")
+ (cond [(and (eq_attr "alternative" "3,4")
+ (match_test "<MODE_SIZE> < 64 && !TARGET_AVX512VL"))
+ (const_string "XI")
+ (match_test "TARGET_AVX2")
(const_string "<sseinsnmode>")
(match_test "TARGET_AVX")
(if_then_else
@@ -17310,7 +17337,15 @@
(match_test "optimize_function_for_size_p (cfun)"))
(const_string "V4SF")
]
- (const_string "<sseinsnmode>")))])
+ (const_string "<sseinsnmode>")))
+ (set (attr "enabled")
+ (cond [(eq_attr "alternative" "3")
+ (symbol_ref "<MODE_SIZE> == 64 || TARGET_AVX512VL")
+ (eq_attr "alternative" "4")
+ (symbol_ref "<MODE_SIZE> == 64 || TARGET_AVX512VL
+ || (TARGET_AVX512F && !TARGET_PREFER_AVX256)")
+ ]
+ (const_string "*")))])
;; PR target/100711: Split notl; vpbroadcastd; vpand as vpbroadcastd; vpandn
(define_split
@@ -17334,7 +17369,7 @@
(and:VI_AVX2
(vec_duplicate:VI_AVX2
(not:<ssescalarmode>
- (match_operand:<ssescalarmode> 1 "register_operand")))
+ (match_operand:<ssescalarmode> 1 "nonimmediate_operand")))
(match_operand:VI_AVX2 2 "vector_operand")))]
"TARGET_AVX2"
[(set (match_dup 3)
@@ -17344,6 +17379,36 @@
(match_dup 2)))]
"operands[3] = gen_reg_rtx (<MODE>mode);")
+(define_split
+ [(set (match_operand:VI 0 "register_operand")
+ (ior:VI
+ (vec_duplicate:VI
+ (not:<ssescalarmode>
+ (match_operand:<ssescalarmode> 1 "nonimmediate_operand")))
+ (match_operand:VI 2 "vector_operand")))]
+ "<MODE_SIZE> == 64 || TARGET_AVX512VL
+ || (TARGET_AVX512F && !TARGET_PREFER_AVX256)"
+ [(set (match_dup 3)
+ (vec_duplicate:VI (match_dup 1)))
+ (set (match_dup 0)
+ (ior:VI (not:VI (match_dup 3)) (match_dup 2)))]
+ "operands[3] = gen_reg_rtx (<MODE>mode);")
+
+(define_split
+ [(set (match_operand:VI 0 "register_operand")
+ (xor:VI
+ (vec_duplicate:VI
+ (not:<ssescalarmode>
+ (match_operand:<ssescalarmode> 1 "nonimmediate_operand")))
+ (match_operand:VI 2 "vector_operand")))]
+ "<MODE_SIZE> == 64 || TARGET_AVX512VL
+ || (TARGET_AVX512F && !TARGET_PREFER_AVX256)"
+ [(set (match_dup 3)
+ (vec_duplicate:VI (match_dup 1)))
+ (set (match_dup 0)
+ (not:VI (xor:VI (match_dup 3) (match_dup 2))))]
+ "operands[3] = gen_reg_rtx (<MODE>mode);")
+
(define_insn "*andnot<mode>3_mask"
[(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v")
(vec_merge:VI48_AVX512VL
@@ -17616,6 +17681,98 @@
operands[2] = force_reg (V1TImode, CONSTM1_RTX (V1TImode));
})
+(define_insn "*iornot<mode>3"
+ [(set (match_operand:VI 0 "register_operand" "=v,v,v,v")
+ (ior:VI
+ (not:VI
+ (match_operand:VI 1 "bcst_vector_operand" "v,Br,v,m"))
+ (match_operand:VI 2 "bcst_vector_operand" "vBr,v,m,v")))]
+ "(<MODE_SIZE> == 64 || TARGET_AVX512VL
+ || (TARGET_AVX512F && !TARGET_PREFER_AVX256))
+ && (register_operand (operands[1], <MODE>mode)
+ || register_operand (operands[2], <MODE>mode))"
+{
+ if (!register_operand (operands[1], <MODE>mode))
+ {
+ if (TARGET_AVX512VL)
+ return "vpternlog<ternlogsuffix>\t{$0xdd, %1, %2, %0|%0, %2, %1, 0xdd}";
+ return "vpternlog<ternlogsuffix>\t{$0xdd, %g1, %g2, %g0|%g0, %g2, %g1, 0xdd}";
+ }
+ if (TARGET_AVX512VL)
+ return "vpternlog<ternlogsuffix>\t{$0xbb, %2, %1, %0|%0, %1, %2, 0xbb}";
+ return "vpternlog<ternlogsuffix>\t{$0xbb, %g2, %g1, %g0|%g0, %g1, %g2, 0xbb}";
+}
+ [(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "evex")
+ (set (attr "mode")
+ (if_then_else (match_test "TARGET_AVX512VL")
+ (const_string "<sseinsnmode>")
+ (const_string "XI")))
+ (set (attr "enabled")
+ (if_then_else (eq_attr "alternative" "2,3")
+ (symbol_ref "<MODE_SIZE> == 64 || TARGET_AVX512VL")
+ (const_string "*")))])
+
+(define_insn "*xnor<mode>3"
+ [(set (match_operand:VI 0 "register_operand" "=v,v")
+ (not:VI
+ (xor:VI
+ (match_operand:VI 1 "bcst_vector_operand" "%v,v")
+ (match_operand:VI 2 "bcst_vector_operand" "vBr,m"))))]
+ "(<MODE_SIZE> == 64 || TARGET_AVX512VL
+ || (TARGET_AVX512F && !TARGET_PREFER_AVX256))
+ && (register_operand (operands[1], <MODE>mode)
+ || register_operand (operands[2], <MODE>mode))"
+{
+ if (TARGET_AVX512VL)
+ return "vpternlog<ternlogsuffix>\t{$0x99, %2, %1, %0|%0, %1, %2, 0x99}";
+ else
+ return "vpternlog<ternlogsuffix>\t{$0x99, %g2, %g1, %g0|%g0, %g1, %g2, 0x99}";
+}
+ [(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "evex")
+ (set (attr "mode")
+ (if_then_else (match_test "TARGET_AVX512VL")
+ (const_string "<sseinsnmode>")
+ (const_string "XI")))
+ (set (attr "enabled")
+ (if_then_else (eq_attr "alternative" "1")
+ (symbol_ref "<MODE_SIZE> == 64 || TARGET_AVX512VL")
+ (const_string "*")))])
+
+(define_code_iterator andor [and ior])
+(define_code_attr nlogic [(and "nor") (ior "nand")])
+(define_code_attr ternlog_nlogic [(and "0x11") (ior "0x77")])
+
+(define_insn "*<nlogic><mode>3"
+ [(set (match_operand:VI 0 "register_operand" "=v,v")
+ (andor:VI
+ (not:VI (match_operand:VI 1 "bcst_vector_operand" "%v,v"))
+ (not:VI (match_operand:VI 2 "bcst_vector_operand" "vBr,m"))))]
+ "(<MODE_SIZE> == 64 || TARGET_AVX512VL
+ || (TARGET_AVX512F && !TARGET_PREFER_AVX256))
+ && (register_operand (operands[1], <MODE>mode)
+ || register_operand (operands[2], <MODE>mode))"
+{
+ if (TARGET_AVX512VL)
+ return "vpternlog<ternlogsuffix>\t{$<ternlog_nlogic>, %2, %1, %0|%0, %1, %2, <ternlog_nlogic>}";
+ else
+ return "vpternlog<ternlogsuffix>\t{$<ternlog_nlogic>, %g2, %g1, %g0|%g0, %g1, %g2, <ternlog_nlogic>}";
+}
+ [(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "evex")
+ (set (attr "mode")
+ (if_then_else (match_test "TARGET_AVX512VL")
+ (const_string "<sseinsnmode>")
+ (const_string "XI")))
+ (set (attr "enabled")
+ (if_then_else (eq_attr "alternative" "1")
+ (symbol_ref "<MODE_SIZE> == 64 || TARGET_AVX512VL")
+ (const_string "*")))])
+
(define_mode_iterator AVX512ZEXTMASK
[(DI "TARGET_AVX512BW") (SI "TARGET_AVX512BW") HI])
@@ -26979,17 +27136,21 @@
"TARGET_AVX")
(define_expand "maskload<mode><avx512fmaskmodelower>"
- [(set (match_operand:V48H_AVX512VL 0 "register_operand")
- (vec_merge:V48H_AVX512VL
- (match_operand:V48H_AVX512VL 1 "memory_operand")
+ [(set (match_operand:V48_AVX512VL 0 "register_operand")
+ (vec_merge:V48_AVX512VL
+ (unspec:V48_AVX512VL
+ [(match_operand:V48_AVX512VL 1 "memory_operand")]
+ UNSPEC_MASKLOAD)
(match_dup 0)
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
"TARGET_AVX512F")
(define_expand "maskload<mode><avx512fmaskmodelower>"
- [(set (match_operand:VI12_AVX512VL 0 "register_operand")
- (vec_merge:VI12_AVX512VL
- (match_operand:VI12_AVX512VL 1 "memory_operand")
+ [(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand")
+ (vec_merge:VI12HFBF_AVX512VL
+ (unspec:VI12HFBF_AVX512VL
+ [(match_operand:VI12HFBF_AVX512VL 1 "memory_operand")]
+ UNSPEC_MASKLOAD)
(match_dup 0)
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
"TARGET_AVX512BW")
@@ -27004,21 +27165,66 @@
"TARGET_AVX")
(define_expand "maskstore<mode><avx512fmaskmodelower>"
- [(set (match_operand:V48H_AVX512VL 0 "memory_operand")
- (vec_merge:V48H_AVX512VL
- (match_operand:V48H_AVX512VL 1 "register_operand")
- (match_dup 0)
- (match_operand:<avx512fmaskmode> 2 "register_operand")))]
+ [(set (match_operand:V48_AVX512VL 0 "memory_operand")
+ (unspec:V48_AVX512VL
+ [(match_operand:V48_AVX512VL 1 "register_operand")
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand")]
+ UNSPEC_MASKMOV))]
"TARGET_AVX512F")
(define_expand "maskstore<mode><avx512fmaskmodelower>"
- [(set (match_operand:VI12_AVX512VL 0 "memory_operand")
- (vec_merge:VI12_AVX512VL
- (match_operand:VI12_AVX512VL 1 "register_operand")
- (match_dup 0)
- (match_operand:<avx512fmaskmode> 2 "register_operand")))]
+ [(set (match_operand:VI12HFBF_AVX512VL 0 "memory_operand")
+ (unspec:VI12HFBF_AVX512VL
+ [(match_operand:VI12HFBF_AVX512VL 1 "register_operand")
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand")]
+ UNSPEC_MASKMOV))]
"TARGET_AVX512BW")
+(define_insn "<avx512>_store<mode>_mask"
+ [(set (match_operand:V48_AVX512VL 0 "memory_operand" "=m")
+ (unspec:V48_AVX512VL
+ [(match_operand:V48_AVX512VL 1 "register_operand" "v")
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand" "Yk")]
+ UNSPEC_MASKMOV))]
+ "TARGET_AVX512F"
+{
+ if (FLOAT_MODE_P (GET_MODE_INNER (<MODE>mode)))
+ {
+ if (misaligned_operand (operands[0], <MODE>mode))
+ return "vmovu<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ else
+ return "vmova<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ }
+ else
+ {
+ if (misaligned_operand (operands[0], <MODE>mode))
+ return "vmovdqu<ssescalarsize>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ else
+ return "vmovdqa<ssescalarsize>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ }
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "memory" "store")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "<avx512>_store<mode>_mask"
+ [(set (match_operand:VI12HFBF_AVX512VL 0 "memory_operand" "=m")
+ (unspec:VI12HFBF_AVX512VL
+ [(match_operand:VI12HFBF_AVX512VL 1 "register_operand" "v")
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand" "Yk")]
+ UNSPEC_MASKMOV))]
+ "TARGET_AVX512BW"
+ "vmovdqu<ssescalarsize>\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "memory" "store")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_expand "cbranch<mode>4"
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:VI48_AVX 1 "register_operand")
diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md
index 49d1a43..22d4d84 100644
--- a/gcc/config/mips/constraints.md
+++ b/gcc/config/mips/constraints.md
@@ -264,6 +264,10 @@
(and (match_code "const_vector")
(match_test "op == CONST0_RTX (mode)")))
+(define_constraint "Yz"
+ "@internal"
+ (match_operand 0 "bit_clear_operand"))
+
(define_constraint "YA"
"@internal
An unsigned 6-bit constant."
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index da7902c..a5a6f6f 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -390,4 +390,8 @@ extern void mips_expand_vec_cmp_expr (rtx *);
extern void mips_emit_speculation_barrier_function (void);
+extern bool mips_bit_clear_p (enum machine_mode, unsigned HOST_WIDE_INT);
+extern void mips_bit_clear_info (enum machine_mode, unsigned HOST_WIDE_INT,
+ int *, int *);
+
#endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 999127a..f986102 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -2376,7 +2376,9 @@ mips_symbol_insns_1 (enum mips_symbol_type type, machine_mode mode)
The final address is then $at + %lo(symbol). With 32-bit
symbols we just need a preparatory LUI for normal mode and
a preparatory LI and SLL for MIPS16. */
- return ABI_HAS_64BIT_SYMBOLS ? 6 : TARGET_MIPS16 ? 3 : 2;
+ return ABI_HAS_64BIT_SYMBOLS
+ ? 6
+ : (TARGET_MIPS16 && !ISA_HAS_MIPS16E2) ? 3 : 2;
case SYMBOL_GP_RELATIVE:
/* Treat GP-relative accesses as taking a single instruction on
@@ -2555,6 +2557,9 @@ mips_regno_mode_ok_for_base_p (int regno, machine_mode mode,
if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
+ if (MIPS16_GP_LOADS && regno == GLOBAL_POINTER_REGNUM)
+ return (UNITS_PER_WORD > 4 ? GET_MODE_SIZE (mode) <= 4 : true);
+
return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
}
@@ -2770,7 +2775,8 @@ static bool
mips16_unextended_reference_p (machine_mode mode, rtx base,
unsigned HOST_WIDE_INT offset)
{
- if (mode != BLKmode && offset % GET_MODE_SIZE (mode) == 0)
+ if (mode != BLKmode && offset % GET_MODE_SIZE (mode) == 0
+ && REGNO (base) != GLOBAL_POINTER_REGNUM)
{
if (GET_MODE_SIZE (mode) == 4 && base == stack_pointer_rtx)
return offset < 256U * GET_MODE_SIZE (mode);
@@ -2920,6 +2926,9 @@ mips_9bit_offset_address_p (rtx x, machine_mode mode)
return (mips_classify_address (&addr, x, mode, false)
&& addr.type == ADDRESS_REG
&& CONST_INT_P (addr.offset)
+ && (!TARGET_MIPS16E2
+ || M16_REG_P (REGNO (addr.reg))
+ || REGNO (addr.reg) >= FIRST_PSEUDO_REGISTER)
&& MIPS_9BIT_OFFSET_P (INTVAL (addr.offset)));
}
@@ -2944,7 +2953,7 @@ mips_const_insns (rtx x)
/* This is simply an LUI for normal mode. It is an extended
LI followed by an extended SLL for MIPS16. */
- return TARGET_MIPS16 ? 4 : 1;
+ return TARGET_MIPS16 ? (ISA_HAS_MIPS16E2 ? 2 : 4) : 1;
case CONST_INT:
if (TARGET_MIPS16)
@@ -2956,7 +2965,10 @@ mips_const_insns (rtx x)
: SMALL_OPERAND_UNSIGNED (INTVAL (x)) ? 2
: IN_RANGE (-INTVAL (x), 0, 255) ? 2
: SMALL_OPERAND_UNSIGNED (-INTVAL (x)) ? 3
- : 0);
+ : ISA_HAS_MIPS16E2
+ ? (trunc_int_for_mode (INTVAL (x), SImode) == INTVAL (x)
+ ? 4 : 8)
+ : 0);
return mips_build_integer (codes, INTVAL (x));
@@ -3330,7 +3342,7 @@ mips16_gp_pseudo_reg (void)
rtx
mips_pic_base_register (rtx temp)
{
- if (!TARGET_MIPS16)
+ if (MIPS16_GP_LOADS ||!TARGET_MIPS16)
return pic_offset_table_rtx;
if (currently_expanding_to_rtl)
@@ -3972,6 +3984,10 @@ mips16_constant_cost (int code, HOST_WIDE_INT x)
return 0;
return -1;
+ case ZERO_EXTRACT:
+ /* The bit position and size are immediate operands. */
+ return ISA_HAS_EXT_INS ? COSTS_N_INSNS (1) : -1;
+
default:
return -1;
}
@@ -5325,6 +5341,11 @@ mips_output_move (rtx dest, rtx src)
if (!TARGET_MIPS16)
return "li\t%0,%1\t\t\t# %X1";
+ if (ISA_HAS_MIPS16E2
+ && LUI_INT (src)
+ && !SMALL_OPERAND_UNSIGNED (INTVAL (src)))
+ return "lui\t%0,%%hi(%1)\t\t\t# %X1";
+
if (SMALL_OPERAND_UNSIGNED (INTVAL (src)))
return "li\t%0,%1";
@@ -5333,7 +5354,7 @@ mips_output_move (rtx dest, rtx src)
}
if (src_code == HIGH)
- return TARGET_MIPS16 ? "#" : "lui\t%0,%h1";
+ return (TARGET_MIPS16 && !ISA_HAS_MIPS16E2) ? "#" : "lui\t%0,%h1";
if (CONST_GP_P (src))
return "move\t%0,%1";
@@ -6271,6 +6292,23 @@ mips_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
}
+/* Given MODE and TYPE of a function argument, return the alignment in
+ bits.
+ In case of typedef, alignment of its original type is
+ used. */
+
+static unsigned int
+mips_function_arg_alignment (machine_mode mode, const_tree type)
+{
+ if (!type)
+ return GET_MODE_ALIGNMENT (mode);
+
+ if (is_typedef_decl (TYPE_NAME (type)))
+ type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
+
+ return TYPE_ALIGN (type);
+}
+
/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
least PARM_BOUNDARY bits of alignment, but will be given anything up
to STACK_BOUNDARY bits if the type requires it. */
@@ -6279,8 +6317,8 @@ static unsigned int
mips_function_arg_boundary (machine_mode mode, const_tree type)
{
unsigned int alignment;
+ alignment = mips_function_arg_alignment (mode, type);
- alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
if (alignment < PARM_BOUNDARY)
alignment = PARM_BOUNDARY;
if (alignment > STACK_BOUNDARY)
@@ -8248,8 +8286,9 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
For ISA_HAS_LWL_LWR we rely on the lwl/lwr & swl/swr load. Otherwise
picking the minimum of alignment or BITS_PER_WORD gets us the
desired size for bits. */
-
- if (!ISA_HAS_LWL_LWR)
+ if (ISA_HAS_UNALIGNED_ACCESS)
+ bits = BITS_PER_WORD;
+ else if (!ISA_HAS_LWL_LWR)
bits = MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest)));
else
{
@@ -8271,7 +8310,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
{
regs[i] = gen_reg_rtx (mode);
- if (MEM_ALIGN (src) >= bits)
+ if (ISA_HAS_UNALIGNED_ACCESS || MEM_ALIGN (src) >= bits)
mips_emit_move (regs[i], adjust_address (src, mode, offset));
else
{
@@ -8284,7 +8323,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
/* Copy the chunks to the destination. */
for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
- if (MEM_ALIGN (dest) >= bits)
+ if (ISA_HAS_UNALIGNED_ACCESS || MEM_ALIGN (dest) >= bits)
mips_emit_move (adjust_address (dest, mode, offset), regs[i]);
else
{
@@ -8380,25 +8419,26 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
bool
mips_expand_block_move (rtx dest, rtx src, rtx length)
{
- if (!ISA_HAS_LWL_LWR
+ if (!CONST_INT_P (length))
+ return false;
+
+ if (mips_isa_rev >= 6 && !ISA_HAS_UNALIGNED_ACCESS
&& (MEM_ALIGN (src) < MIPS_MIN_MOVE_MEM_ALIGN
|| MEM_ALIGN (dest) < MIPS_MIN_MOVE_MEM_ALIGN))
return false;
- if (CONST_INT_P (length))
+ if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER)
{
- if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_STRAIGHT)
- {
- mips_block_move_straight (dest, src, INTVAL (length));
- return true;
- }
- else if (optimize)
- {
- mips_block_move_loop (dest, src, INTVAL (length),
- MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER);
- return true;
- }
+ mips_block_move_straight (dest, src, INTVAL (length));
+ return true;
+ }
+ else if (optimize)
+ {
+ mips_block_move_loop (dest, src, INTVAL (length),
+ MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER);
+ return true;
}
+
return false;
}
@@ -8666,12 +8706,25 @@ mips_expand_ins_as_unaligned_store (rtx dest, rtx src, HOST_WIDE_INT width,
return false;
mode = int_mode_for_size (width, 0).require ();
- src = gen_lowpart (mode, src);
+ if (TARGET_MIPS16
+ && src == const0_rtx)
+ src = force_reg (mode, src);
+ else
+ src = gen_lowpart (mode, src);
+
if (mode == DImode)
{
+ if (TARGET_MIPS16)
+ gcc_unreachable ();
emit_insn (gen_mov_sdl (dest, src, left));
emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right));
}
+ else if (TARGET_MIPS16)
+ {
+ emit_insn (gen_mov_swl_mips16e2 (dest, src, left));
+ emit_insn (gen_mov_swr_mips16e2 (copy_rtx (dest), copy_rtx (src),
+ right));
+ }
else
{
emit_insn (gen_mov_swl (dest, src, left));
@@ -8837,7 +8890,7 @@ mips_init_relocs (void)
}
}
- if (TARGET_MIPS16)
+ if (!MIPS16_GP_LOADS && TARGET_MIPS16)
{
/* The high part is provided by a pseudo copy of $gp. */
mips_split_p[SYMBOL_GP_RELATIVE] = true;
@@ -10128,7 +10181,8 @@ mips_file_start (void)
fputs ("\t.module\tmsa\n", asm_out_file);
if (TARGET_XPA)
fputs ("\t.module\txpa\n", asm_out_file);
- /* FIXME: MIPS16E2 is not supported by GCC? gas does support it */
+ if (TARGET_MIPS16E2)
+ fputs ("\t.module\tmips16e2\n", asm_out_file);
if (TARGET_CRC)
fputs ("\t.module\tcrc\n", asm_out_file);
if (TARGET_GINV)
@@ -12055,13 +12109,25 @@ mips_output_function_prologue (FILE *file)
{
if (TARGET_MIPS16)
{
- /* This is a fixed-form sequence. The position of the
- first two instructions is important because of the
- way _gp_disp is defined. */
- output_asm_insn ("li\t$2,%%hi(_gp_disp)", 0);
- output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
- output_asm_insn ("sll\t$2,16", 0);
- output_asm_insn ("addu\t$2,$3", 0);
+ if (ISA_HAS_MIPS16E2)
+ {
+ /* This is a fixed-form sequence. The position of the
+ first two instructions is important because of the
+ way _gp_disp is defined. */
+ output_asm_insn ("lui\t$2,%%hi(_gp_disp)", 0);
+ output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
+ output_asm_insn ("addu\t$2,$3", 0);
+ }
+ else
+ {
+ /* This is a fixed-form sequence. The position of the
+ first two instructions is important because of the
+ way _gp_disp is defined. */
+ output_asm_insn ("li\t$2,%%hi(_gp_disp)", 0);
+ output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
+ output_asm_insn ("sll\t$2,16", 0);
+ output_asm_insn ("addu\t$2,$3", 0);
+ }
}
else
{
@@ -15453,9 +15519,13 @@ mips_loongson_ext2_prefetch_cookie (rtx write, rtx)
The function is available on the current target if !TARGET_MIPS16.
BUILTIN_AVAIL_MIPS16
- The function is available on the current target if TARGET_MIPS16. */
+ The function is available on the current target if TARGET_MIPS16.
+
+ BUILTIN_AVAIL_MIPS16E2
+ The function is available on the current target if TARGET_MIPS16E2. */
#define BUILTIN_AVAIL_NON_MIPS16 1
#define BUILTIN_AVAIL_MIPS16 2
+#define BUILTIN_AVAIL_MIPS16E2 4
/* Declare an availability predicate for built-in functions that
require non-MIPS16 mode and also require COND to be true.
@@ -15468,6 +15538,17 @@ mips_loongson_ext2_prefetch_cookie (rtx write, rtx)
}
/* Declare an availability predicate for built-in functions that
+ require non-MIPS16 mode or MIPS16E2 and also require COND to be true.
+ NAME is the main part of the predicate's name. */
+#define AVAIL_MIPS16E2_OR_NON_MIPS16(NAME, COND) \
+ static unsigned int \
+ mips_builtin_avail_##NAME (void) \
+ { \
+ return ((COND) ? BUILTIN_AVAIL_NON_MIPS16 | BUILTIN_AVAIL_MIPS16E2 \
+ : 0); \
+ }
+
+/* Declare an availability predicate for built-in functions that
support both MIPS16 and non-MIPS16 code and also require COND
to be true. NAME is the main part of the predicate's name. */
#define AVAIL_ALL(NAME, COND) \
@@ -15512,7 +15593,7 @@ AVAIL_NON_MIPS16 (dsp_32, !TARGET_64BIT && TARGET_DSP)
AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP)
AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2)
AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_MMI)
-AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
+AVAIL_MIPS16E2_OR_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
AVAIL_NON_MIPS16 (msa, TARGET_MSA)
/* Construct a mips_builtin_description from the given arguments.
@@ -17512,7 +17593,8 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
d = &mips_builtins[fcode];
avail = d->avail ();
gcc_assert (avail != 0);
- if (TARGET_MIPS16 && !(avail & BUILTIN_AVAIL_MIPS16))
+ if (TARGET_MIPS16 && !(avail & BUILTIN_AVAIL_MIPS16)
+ && (!TARGET_MIPS16E2 || !(avail & BUILTIN_AVAIL_MIPS16E2)))
{
error ("built-in function %qE not supported for MIPS16",
DECL_NAME (fndecl));
@@ -22855,7 +22937,68 @@ mips_asm_file_end (void)
if (NEED_INDICATE_EXEC_STACK)
file_end_indicate_exec_stack ();
}
-
+
+void
+mips_bit_clear_info (enum machine_mode mode, unsigned HOST_WIDE_INT m,
+ int *start_pos, int *size)
+{
+ unsigned int shift = 0;
+ unsigned int change_count = 0;
+ unsigned int prev_val = 1;
+ unsigned int curr_val = 0;
+ unsigned int end_pos = GET_MODE_SIZE (mode) * BITS_PER_UNIT;
+
+ for (shift = 0 ; shift < (GET_MODE_SIZE (mode) * BITS_PER_UNIT) ; shift++)
+ {
+ curr_val = (unsigned int)((m & (unsigned int)(1 << shift)) >> shift);
+ if (curr_val != prev_val)
+ {
+ change_count++;
+ switch (change_count)
+ {
+ case 1:
+ *start_pos = shift;
+ break;
+ case 2:
+ end_pos = shift;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ prev_val = curr_val;
+ }
+ *size = (end_pos - *start_pos);
+}
+
+bool
+mips_bit_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT m)
+{
+ unsigned int shift = 0;
+ unsigned int change_count = 0;
+ unsigned int prev_val = 1;
+ unsigned int curr_val = 0;
+
+ if (mode != SImode && mode != VOIDmode)
+ return false;
+
+ if (!ISA_HAS_EXT_INS)
+ return false;
+
+ for (shift = 0 ; shift < (UNITS_PER_WORD * BITS_PER_UNIT) ; shift++)
+ {
+ curr_val = (unsigned int)((m & (unsigned int)(1 << shift)) >> shift);
+ if (curr_val != prev_val)
+ change_count++;
+ prev_val = curr_val;
+ }
+
+ if (change_count == 2)
+ return true;
+
+ return false;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 6daf6d3..0b6ea78 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -475,6 +475,9 @@ struct mips_cpu_info {
if (mips_base_compression_flags & MASK_MIPS16) \
builtin_define ("__mips16"); \
\
+ if (TARGET_MIPS16E2) \
+ builtin_define ("__mips_mips16e2"); \
+ \
if (TARGET_MIPS3D) \
builtin_define ("__mips3d"); \
\
@@ -1078,6 +1081,7 @@ struct mips_cpu_info {
ST Loongson 2E/2F. */
#define ISA_HAS_CONDMOVE (ISA_HAS_FP_CONDMOVE \
|| TARGET_MIPS5900 \
+ || ISA_HAS_MIPS16E2 \
|| TARGET_LOONGSON_2EF)
/* ISA has LDC1 and SDC1. */
@@ -1176,7 +1180,8 @@ struct mips_cpu_info {
&& (MODE) == V2SFmode)) \
&& !TARGET_MIPS16)
-#define ISA_HAS_LWL_LWR (mips_isa_rev <= 5 && !TARGET_MIPS16)
+#define ISA_HAS_LWL_LWR (mips_isa_rev <= 5 \
+ && (!TARGET_MIPS16 || ISA_HAS_MIPS16E2))
#define ISA_HAS_IEEE_754_LEGACY (mips_isa_rev <= 5)
@@ -1243,7 +1248,8 @@ struct mips_cpu_info {
&& !TARGET_MIPS16)
/* ISA has data prefetch, LL and SC with limited 9-bit displacement. */
-#define ISA_HAS_9BIT_DISPLACEMENT (mips_isa_rev >= 6)
+#define ISA_HAS_9BIT_DISPLACEMENT (mips_isa_rev >= 6 \
+ || ISA_HAS_MIPS16E2)
/* ISA has data indexed prefetch instructions. This controls use of
'prefx', along with TARGET_HARD_FLOAT and TARGET_DOUBLE_FLOAT.
@@ -1262,7 +1268,8 @@ struct mips_cpu_info {
#define ISA_HAS_SEB_SEH (mips_isa_rev >= 2 && !TARGET_MIPS16)
/* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */
-#define ISA_HAS_EXT_INS (mips_isa_rev >= 2 && !TARGET_MIPS16)
+#define ISA_HAS_EXT_INS ((mips_isa_rev >= 2 && !TARGET_MIPS16) \
+ || ISA_HAS_MIPS16E2)
/* ISA has instructions for accessing top part of 64-bit fp regs. */
#define ISA_HAS_MXHC1 (!TARGET_FLOAT32 \
@@ -1291,6 +1298,10 @@ struct mips_cpu_info {
/* The MSA ASE is available. */
#define ISA_HAS_MSA (TARGET_MSA && !TARGET_MIPS16)
+/* The MIPS16e V2 instructions are available. */
+#define ISA_HAS_MIPS16E2 (TARGET_MIPS16 && TARGET_MIPS16E2 \
+ && !TARGET_64BIT)
+
/* True if the result of a load is not available to the next instruction.
A nop will then be needed between instructions like "lw $4,..."
and "addiu $4,$4,1". */
@@ -1331,7 +1342,8 @@ struct mips_cpu_info {
#define ISA_HAS_SYNCI (mips_isa_rev >= 2 && !TARGET_MIPS16)
/* ISA includes sync. */
-#define ISA_HAS_SYNC ((mips_isa >= MIPS_ISA_MIPS2 || TARGET_MIPS3900) && !TARGET_MIPS16)
+#define ISA_HAS_SYNC ((mips_isa >= MIPS_ISA_MIPS2 || TARGET_MIPS3900) \
+ && (!TARGET_MIPS16 || ISA_HAS_MIPS16E2))
#define GENERATE_SYNC \
(target_flags_explicit & MASK_LLSC \
? TARGET_LLSC && !TARGET_MIPS16 \
@@ -1340,7 +1352,8 @@ struct mips_cpu_info {
/* ISA includes ll and sc. Note that this implies ISA_HAS_SYNC
because the expanders use both ISA_HAS_SYNC and ISA_HAS_LL_SC
instructions. */
-#define ISA_HAS_LL_SC (mips_isa >= MIPS_ISA_MIPS2 && !TARGET_MIPS5900 && !TARGET_MIPS16)
+#define ISA_HAS_LL_SC (mips_isa >= MIPS_ISA_MIPS2 && !TARGET_MIPS5900 \
+ && (!TARGET_MIPS16 || ISA_HAS_MIPS16E2))
#define GENERATE_LL_SC \
(target_flags_explicit & MASK_LLSC \
? TARGET_LLSC && !TARGET_MIPS16 \
@@ -1367,11 +1380,14 @@ struct mips_cpu_info {
/* ISA includes the pop instruction. */
#define ISA_HAS_POP (TARGET_OCTEON && !TARGET_MIPS16)
+#define MIPS16_GP_LOADS (ISA_HAS_MIPS16E2 && !TARGET_64BIT)
+
/* The CACHE instruction is available in non-MIPS16 code. */
#define TARGET_CACHE_BUILTIN (mips_isa >= MIPS_ISA_MIPS3)
/* The CACHE instruction is available. */
-#define ISA_HAS_CACHE (TARGET_CACHE_BUILTIN && !TARGET_MIPS16)
+#define ISA_HAS_CACHE (TARGET_CACHE_BUILTIN && (!TARGET_MIPS16 \
+ || TARGET_MIPS16E2))
/* Tell collect what flags to pass to nm. */
#ifndef NM_FLAGS
@@ -1450,6 +1466,7 @@ struct mips_cpu_info {
%{msym32} %{mno-sym32} \
%{mtune=*}" \
FP_ASM_SPEC "\
+%{mmips16e2} \
%(subtarget_asm_spec)"
/* Extra switches sometimes passed to the linker. */
@@ -2058,10 +2075,6 @@ FP_ASM_SPEC "\
function address than to call an address kept in a register. */
#define NO_FUNCTION_CSE 1
-/* The ABI-defined global pointer. Sometimes we use a different
- register in leaf functions: see PIC_OFFSET_TABLE_REGNUM. */
-#define GLOBAL_POINTER_REGNUM (GP_REG_FIRST + 28)
-
/* We normally use $28 as the global pointer. However, when generating
n32/64 PIC, it is better for leaf functions to use a call-clobbered
register instead. They can then avoid saving and restoring $28
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 5d04ac5..a254547 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -169,6 +169,7 @@
(GET_FCSR_REGNUM 2)
(SET_FCSR_REGNUM 4)
(PIC_FUNCTION_ADDR_REGNUM 25)
+ (GLOBAL_POINTER_REGNUM 28)
(RETURN_ADDR_REGNUM 31)
(CPRESTORE_SLOT_REGNUM 76)
(GOT_VERSION_REGNUM 79)
@@ -462,7 +463,7 @@
(if_then_else (ior ;; In general, constant-pool loads are extended
;; instructions. We don't yet optimize for 16-bit
;; PC-relative references.
- (eq_attr "move_type" "sll0,loadpool")
+ (eq_attr "move_type" "sll0,loadpool,ext_ins")
(eq_attr "jal" "direct")
(eq_attr "got" "load"))
(const_string "yes")
@@ -3313,12 +3314,13 @@
;; register =op1 x
(define_insn "*and<mode>3"
- [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d")
- (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d")
- (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d")))]
+ [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d,d")
+ (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d,0")
+ (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d,Yz")))]
"!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
{
int len;
+ int pos;
switch (which_alternative)
{
@@ -3343,41 +3345,73 @@
case 7:
case 8:
return "and\t%0,%1,%2";
+ case 9:
+ mips_bit_clear_info (<MODE>mode, INTVAL (operands[2]), &pos, &len);
+ operands[1] = GEN_INT (pos);
+ operands[2] = GEN_INT (len);
+ return "<d>ins\t%0,$0,%1,%2";
default:
gcc_unreachable ();
}
}
- [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical")
- (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*")
+ [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical,ext_ins")
+ (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*,*")
(set_attr "mode" "<MODE>")])
(define_insn "*and<mode>3_mips16"
- [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
- (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%W,W,W,d,0")
- (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
+ [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d,d,d,d,d")
+ (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,W,W,W,d,0,d,0,0?")
+ (match_operand:GPR 2 "and_operand" "Yb,Yh,Yb,Yh,Yw,Yw,d,Yx,Yz,K")))]
"TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
{
+ int len;
+ int pos;
+
switch (which_alternative)
{
case 0:
+ return "zeb\t%0";
+ case 1:
+ return "zeh\t%0";
+ case 2:
operands[1] = gen_lowpart (QImode, operands[1]);
return "lbu\t%0,%1";
- case 1:
+ case 3:
operands[1] = gen_lowpart (HImode, operands[1]);
return "lhu\t%0,%1";
- case 2:
+ case 4:
operands[1] = gen_lowpart (SImode, operands[1]);
return "lwu\t%0,%1";
- case 3:
+ case 5:
return "#";
- case 4:
+ case 6:
return "and\t%0,%2";
+ case 7:
+ len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
+ operands[2] = GEN_INT (len);
+ return "ext\t%0,%1,0,%2";
+ case 8:
+ mips_bit_clear_info (<MODE>mode, INTVAL (operands[2]), &pos, &len);
+ operands[1] = GEN_INT (pos);
+ operands[2] = GEN_INT (len);
+ return "ins\t%0,$0,%1,%2";
+ case 9:
+ return "andi\t%0,%x2";
default:
gcc_unreachable ();
}
}
- [(set_attr "move_type" "load,load,load,shift_shift,logical")
- (set_attr "mode" "<MODE>")])
+ [(set_attr "move_type" "andi,andi,load,load,load,shift_shift,logical,ext_ins,ext_ins,andi")
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "no,no,no,no,no,no,no,yes,yes,yes")
+ (set (attr "enabled")
+ (cond [(and (eq_attr "alternative" "9")
+ (not (match_test "ISA_HAS_MIPS16E2")))
+ (const_string "no")
+ (and (eq_attr "alternative" "0,1")
+ (match_test "!GENERATE_MIPS16E"))
+ (const_string "no")]
+ (const_string "yes")))])
(define_expand "ior<mode>3"
[(set (match_operand:GPR 0 "register_operand")
@@ -3385,7 +3419,7 @@
(match_operand:GPR 2 "uns_arith_operand")))]
""
{
- if (TARGET_MIPS16)
+ if (TARGET_MIPS16 && !ISA_HAS_MIPS16E2)
operands[2] = force_reg (<MODE>mode, operands[2]);
})
@@ -3402,11 +3436,23 @@
(set_attr "compression" "micromips,*,*")
(set_attr "mode" "<MODE>")])
+(define_insn "*ior<mode>3_mips16_asmacro"
+ [(set (match_operand:GPR 0 "register_operand" "=d,d")
+ (ior:GPR (match_operand:GPR 1 "register_operand" "%0,0")
+ (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
+ "ISA_HAS_MIPS16E2"
+ "@
+ or\t%0,%2
+ ori\t%0,%x2"
+ [(set_attr "alu_type" "or")
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "*,yes")])
+
(define_insn "*ior<mode>3_mips16"
[(set (match_operand:GPR 0 "register_operand" "=d")
(ior:GPR (match_operand:GPR 1 "register_operand" "%0")
(match_operand:GPR 2 "register_operand" "d")))]
- "TARGET_MIPS16"
+ "TARGET_MIPS16 && !ISA_HAS_MIPS16E2"
"or\t%0,%2"
[(set_attr "alu_type" "or")
(set_attr "mode" "<MODE>")])
@@ -3431,19 +3477,31 @@
(set_attr "compression" "micromips,*,*")
(set_attr "mode" "<MODE>")])
+;; We increase statically the cost of the output register for XORI
+;; to counterweight LRA cost calculation as XORI tends to be chosen
+;; frequently hurting the code size. The reason of not choosing CMPI is
+;; that LRA tends to add up the cost of the T register as it is in a small
+;; class and a possible reload. In reality, the use of T register comes for
+;; free in a number of cases as we don't need any MIPS16 registers.
(define_insn "*xor<mode>3_mips16"
- [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t")
- (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d")
- (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d")))]
+ [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t,d?")
+ (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d,0")
+ (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d,K")))]
"TARGET_MIPS16"
"@
xor\t%0,%2
cmpi\t%1,%2
cmpi\t%1,%2
- cmp\t%1,%2"
+ cmp\t%1,%2
+ xori\t%0,%x2"
[(set_attr "alu_type" "xor")
(set_attr "mode" "<MODE>")
- (set_attr "extended_mips16" "no,no,yes,no")])
+ (set_attr "extended_mips16" "no,no,yes,no,yes")
+ (set (attr "enabled")
+ (cond [(and (eq_attr "alternative" "4")
+ (not (match_test "ISA_HAS_MIPS16E2")))
+ (const_string "no")]
+ (const_string "yes")))])
(define_insn "*nor<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
@@ -4343,6 +4401,7 @@
INTVAL (operands[3]))"
"<d>ext\t%0,%1,%3,%2"
[(set_attr "type" "arith")
+ (set_attr "extended_mips16" "yes")
(set_attr "mode" "<MODE>")])
(define_insn "*extzv_truncsi_exts"
@@ -4393,6 +4452,7 @@
INTVAL (operands[2]))"
"<d>ins\t%0,%z3,%2,%1"
[(set_attr "type" "arith")
+ (set_attr "extended_mips16" "yes")
(set_attr "mode" "<MODE>")])
;; Combiner pattern for cins (clear and insert bit field). We can
@@ -4434,10 +4494,12 @@
(unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
(match_operand:QI 2 "memory_operand" "ZC")]
UNSPEC_LOAD_LEFT))]
- "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
+ "(!TARGET_MIPS16 || ISA_HAS_MIPS16E2)
+ && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
"<load>l\t%0,%2"
[(set_attr "move_type" "load")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "yes")])
(define_insn "mov_<load>r"
[(set (match_operand:GPR 0 "register_operand" "=d")
@@ -4445,17 +4507,20 @@
(match_operand:QI 2 "memory_operand" "ZC")
(match_operand:GPR 3 "register_operand" "0")]
UNSPEC_LOAD_RIGHT))]
- "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
+ "(!TARGET_MIPS16 || ISA_HAS_MIPS16E2)
+ && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
"<load>r\t%0,%2"
[(set_attr "move_type" "load")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "yes")])
(define_insn "mov_<store>l"
[(set (match_operand:BLK 0 "memory_operand" "=m")
(unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
(match_operand:QI 2 "memory_operand" "ZC")]
UNSPEC_STORE_LEFT))]
- "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
+ "!TARGET_MIPS16
+ && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
"<store>l\t%z1,%2"
[(set_attr "move_type" "store")
(set_attr "mode" "<MODE>")])
@@ -4466,11 +4531,37 @@
(match_operand:QI 2 "memory_operand" "ZC")
(match_dup 0)]
UNSPEC_STORE_RIGHT))]
- "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
+ "!TARGET_MIPS16
+ && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
"<store>r\t%z1,%2"
[(set_attr "move_type" "store")
(set_attr "mode" "<MODE>")])
+(define_insn "mov_<store>l_mips16e2"
+ [(set (match_operand:BLK 0 "memory_operand" "=m")
+ (unspec:BLK [(match_operand:GPR 1 "register_operand" "d")
+ (match_operand:QI 2 "memory_operand" "ZC")]
+ UNSPEC_STORE_LEFT))]
+ "TARGET_MIPS16 && ISA_HAS_MIPS16E2
+ && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
+ "<store>l\t%1,%2"
+ [(set_attr "move_type" "store")
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "yes")])
+
+(define_insn "mov_<store>r_mips16e2"
+ [(set (match_operand:BLK 0 "memory_operand" "+m")
+ (unspec:BLK [(match_operand:GPR 1 "register_operand" "d")
+ (match_operand:QI 2 "memory_operand" "ZC")
+ (match_dup 0)]
+ UNSPEC_STORE_RIGHT))]
+ "TARGET_MIPS16 && ISA_HAS_MIPS16E2
+ && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
+ "<store>r\t%1,%2"
+ [(set_attr "move_type" "store")
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "yes")])
+
;; Unaligned direct access
(define_expand "movmisalign<mode>"
[(set (match_operand:JOIN_MODE 0)
@@ -4580,7 +4671,7 @@
(define_split
[(set (match_operand:P 0 "d_operand")
(high:P (match_operand:P 1 "symbolic_operand_with_high")))]
- "TARGET_MIPS16 && reload_completed"
+ "TARGET_MIPS16 && reload_completed && !ISA_HAS_MIPS16E2"
[(set (match_dup 0) (unspec:P [(match_dup 1)] UNSPEC_UNSHIFTED_HIGH))
(set (match_dup 0) (ashift:P (match_dup 0) (const_int 16)))])
@@ -4680,6 +4771,16 @@
[(set_attr "alu_type" "add")
(set_attr "mode" "<MODE>")])
+(define_insn "*lowsi_mips16_gp"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (lo_sum:SI (reg:SI GLOBAL_POINTER_REGNUM)
+ (match_operand 1 "immediate_operand" "")))]
+ "MIPS16_GP_LOADS"
+ "addiu\t%0,$28,%R1"
+ [(set_attr "alu_type" "add")
+ (set_attr "mode" "SI")
+ (set_attr "extended_mips16" "yes")])
+
(define_insn "*low<mode>_mips16"
[(set (match_operand:P 0 "register_operand" "=d")
(lo_sum:P (match_operand:P 1 "register_operand" "0")
@@ -5656,7 +5757,8 @@
(match_operand:QI 1 "address_operand" "ZD")]
UNSPEC_MIPS_CACHE))]
"ISA_HAS_CACHE"
- "cache\t%X0,%a1")
+ "cache\t%X0,%a1"
+ [(set_attr "extended_mips16" "yes")])
;; Similar, but with the operands hard-coded to an R10K cache barrier
;; operation. We keep the pattern distinct so that we can identify
@@ -7343,26 +7445,60 @@
(const_int 0)])
(match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
(match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
- "ISA_HAS_CONDMOVE"
+ "!TARGET_MIPS16 && ISA_HAS_CONDMOVE"
"@
mov%T4\t%0,%z2,%1
mov%t4\t%0,%z3,%1"
[(set_attr "type" "condmove")
(set_attr "mode" "<GPR:MODE>")])
+(define_insn "*mov<GPR:mode>_on_<MOVECC:mode>_mips16e2"
+ [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
+ (if_then_else:GPR
+ (match_operator 4 "equality_operator"
+ [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>,t,t")
+ (const_int 0)])
+ (match_operand:GPR 2 "reg_or_0_operand_mips16e2" "dJ,0,dJ,0")
+ (match_operand:GPR 3 "reg_or_0_operand_mips16e2" "0,dJ,0,dJ")))]
+ "ISA_HAS_MIPS16E2 && ISA_HAS_CONDMOVE"
+ "@
+ mov%T4\t%0,%z2,%1
+ mov%t4\t%0,%z3,%1
+ movt%T4\t%0,%z2
+ movt%t4\t%0,%z3"
+ [(set_attr "type" "condmove")
+ (set_attr "mode" "<GPR:MODE>")
+ (set_attr "extended_mips16" "yes")])
+
(define_insn "*mov<GPR:mode>_on_<GPR2:mode>_ne"
[(set (match_operand:GPR 0 "register_operand" "=d,d")
(if_then_else:GPR
(match_operand:GPR2 1 "register_operand" "<GPR2:reg>,<GPR2:reg>")
(match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
(match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
- "ISA_HAS_CONDMOVE"
+ "!TARGET_MIPS16 && ISA_HAS_CONDMOVE"
"@
movn\t%0,%z2,%1
movz\t%0,%z3,%1"
[(set_attr "type" "condmove")
(set_attr "mode" "<GPR:MODE>")])
+(define_insn "*mov<GPR:mode>_on_<GPR2:mode>_ne_mips16e2"
+ [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
+ (if_then_else:GPR
+ (match_operand:GPR2 1 "register_operand" "<GPR2:reg>,<GPR2:reg>,t,t")
+ (match_operand:GPR 2 "reg_or_0_operand_mips16e2" "dJ,0,dJ,0")
+ (match_operand:GPR 3 "reg_or_0_operand_mips16e2" "0,dJ,0,dJ")))]
+ "ISA_HAS_MIPS16E2 && ISA_HAS_CONDMOVE"
+ "@
+ movn\t%0,%z2,%1
+ movz\t%0,%z3,%1
+ movtn\t%0,%z2
+ movtz\t%0,%z3"
+ [(set_attr "type" "condmove")
+ (set_attr "mode" "<GPR:MODE>")
+ (set_attr "extended_mips16" "yes")])
+
(define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
[(set (match_operand:SCALARF 0 "register_operand" "=f,f")
(if_then_else:SCALARF
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 195f5be..4968ed0 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -380,6 +380,10 @@ msplit-addresses
Target Mask(SPLIT_ADDRESSES)
Optimize lui/addiu address loads.
+mmips16e2
+Target Var(TARGET_MIPS16E2) Init(0)
+Enable the MIPS16e V2 instructions.
+
msym32
Target Var(TARGET_SYM32)
Assume all symbols have 32-bit values.
diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md
index e34de29..e8a85ac 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -114,6 +114,12 @@
(not (match_test "TARGET_MIPS16")))
(match_operand 0 "register_operand")))
+(define_predicate "reg_or_0_operand_mips16e2"
+ (ior (and (match_operand 0 "const_0_operand")
+ (ior (not (match_test "TARGET_MIPS16"))
+ (match_test "ISA_HAS_MIPS16E2")))
+ (match_operand 0 "register_operand")))
+
(define_predicate "const_1_operand"
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST1_RTX (GET_MODE (op))")))
@@ -164,6 +170,10 @@
(and (match_code "const_int")
(match_test "UINTVAL (op) == 0xffffffff")))
+(define_predicate "bit_clear_operand"
+ (and (match_code "const_int")
+ (match_test "mips_bit_clear_p (mode, INTVAL (op))")))
+
(define_predicate "and_load_operand"
(ior (match_operand 0 "qi_mask_operand")
(match_operand 0 "hi_mask_operand")
@@ -178,8 +188,15 @@
(ior (match_operand 0 "register_operand")
(and (not (match_test "TARGET_MIPS16"))
(match_operand 0 "const_uns_arith_operand"))
+ (and (match_test "ISA_HAS_MIPS16E2")
+ (match_operand 0 "const_uns_arith_operand")
+ (not (match_operand 0 "hi_mask_operand"))
+ (not (match_operand 0 "qi_mask_operand")))
+ (and (match_test "ISA_HAS_MIPS16E2")
+ (match_operand 0 "const_uns_arith_operand"))
(match_operand 0 "low_bitmask_operand")
- (match_operand 0 "si_mask_operand")))
+ (match_operand 0 "si_mask_operand")
+ (match_operand 0 "bit_clear_operand")))
(define_predicate "and_operand"
(ior (match_operand 0 "and_load_operand")
@@ -369,7 +386,7 @@
{
/* When generating mips16 code, TARGET_LEGITIMATE_CONSTANT_P rejects
CONST_INTs that can't be loaded using simple insns. */
- if (TARGET_MIPS16)
+ if (TARGET_MIPS16 && !TARGET_MIPS16E2)
return false;
/* Don't handle multi-word moves this way; we don't want to introduce
diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index e3b0304..16ed780 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -7633,9 +7633,6 @@ nvptx_asm_output_def_from_decls (FILE *stream, tree name, tree value)
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE nvptx_attribute_table
-#undef TARGET_LRA_P
-#define TARGET_LRA_P hook_bool_void_false
-
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P nvptx_legitimate_address_p
diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
index 490226b..bbb9261 100755
--- a/gcc/config/riscv/arch-canonicalize
+++ b/gcc/config/riscv/arch-canonicalize
@@ -68,6 +68,13 @@ IMPLIED_EXT = {
"zvl16384b" : ["zvl8192b"],
"zvl32768b" : ["zvl16384b"],
"zvl65536b" : ["zvl32768b"],
+
+ "zvkn" : ["zvkned", "zvknhb", "zvbb", "zvkt"],
+ "zvknc" : ["zvkn", "zvbc"],
+ "zvkng" : ["zvkn", "zvkg"],
+ "zvks" : ["zvksed", "zvksh", "zvbb", "zvkt"],
+ "zvksc" : ["zvks", "zvbc"],
+ "zvksg" : ["zvks", "zvkg"],
}
def arch_canonicalize(arch, isa_spec):
diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 2804080..99b609a 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -405,3 +405,282 @@
"vmv.x.s\t%0,%1"
[(set_attr "type" "vimovvx")
(set_attr "mode" "<MODE>")])
+
+;; We don't have vfwmul.wv instruction like vfwadd.wv in RVV.
+;; This pattern is an intermediate RTL IR as a pseudo vfwmul.wv to enhance
+;; optimization of instructions combine.
+(define_insn_and_split "*pred_single_widen_mul<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand" "=&vr, &vr")
+ (if_then_else:VWEXTF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (match_operand 8 "const_int_operand" " i, i")
+ (match_operand 9 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)
+ (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
+ (mult:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" " vr, vr"))
+ (match_operand:VWEXTF 3 "register_operand" " vr, vr"))
+ (match_operand:VWEXTF 2 "vector_merge_operand" " vu, 0")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ insn_code icode = code_for_pred_extend (<MODE>mode);
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx ops[] = {tmp, operands[4]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ops);
+
+ emit_insn (gen_pred (MULT, <MODE>mode, operands[0], operands[1], operands[2],
+ operands[3], tmp, operands[5], operands[6],
+ operands[7], operands[8], operands[9]));
+ DONE;
+ }
+ [(set_attr "type" "vfwmul")
+ (set_attr "mode" "<MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFWMACC
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfwmacc.vv
+;; -------------------------------------------------------------------------
+
+;; Combine ext + ext + fma ===> widen fma.
+;; Most of circumstantces, LoopVectorizer will generate the following IR:
+;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
+;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
+;; vect__13.182_33 = .FMA (vect__11.180_35, vect__8.176_40, vect__4.172_45);
+(define_insn_and_split "*double_widen_fma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_widen_mul (PLUS, <MODE>mode),
+ riscv_vector::RVV_WIDEN_TERNOP, operands);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; This helps to match ext + fma.
+(define_insn_and_split "*single_widen_fma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (match_operand:VWEXTF 3 "register_operand")
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ insn_code icode = code_for_pred_extend (<MODE>mode);
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ext_ops);
+
+ rtx dst = expand_ternary_op (<MODE>mode, fma_optab, tmp, operands[3],
+ operands[1], operands[0], 0);
+ emit_move_insn (operands[0], dst);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFWNMSAC
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfwnmsac.vv
+;; -------------------------------------------------------------------------
+
+;; Combine ext + ext + fnma ===> widen fnma.
+;; Most of circumstantces, LoopVectorizer will generate the following IR:
+;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
+;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
+;; vect__13.182_33 = .FNMA (vect__11.180_35, vect__8.176_40, vect__4.172_45);
+(define_insn_and_split "*double_widen_fnma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (neg:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_widen_mul_neg (PLUS, <MODE>mode),
+ riscv_vector::RVV_WIDEN_TERNOP, operands);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; This helps to match ext + fnma.
+(define_insn_and_split "*single_widen_fnma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (neg:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
+ (match_operand:VWEXTF 3 "register_operand")
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ insn_code icode = code_for_pred_extend (<MODE>mode);
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ext_ops);
+
+ rtx dst = expand_ternary_op (<MODE>mode, fnma_optab, tmp, operands[3],
+ operands[1], operands[0], 0);
+ emit_move_insn (operands[0], dst);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFWMSAC
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfwmsac.vv
+;; -------------------------------------------------------------------------
+
+;; Combine ext + ext + fms ===> widen fms.
+;; Most of circumstantces, LoopVectorizer will generate the following IR:
+;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
+;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
+;; vect__13.182_33 = .FMS (vect__11.180_35, vect__8.176_40, vect__4.172_45);
+(define_insn_and_split "*double_widen_fms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
+ (neg:VWEXTF
+ (match_operand:VWEXTF 1 "register_operand"))))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_widen_mul (MINUS, <MODE>mode),
+ riscv_vector::RVV_WIDEN_TERNOP, operands);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; This helps to match ext + fms.
+(define_insn_and_split "*single_widen_fms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (match_operand:VWEXTF 3 "register_operand")
+ (neg:VWEXTF
+ (match_operand:VWEXTF 1 "register_operand"))))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ insn_code icode = code_for_pred_extend (<MODE>mode);
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ext_ops);
+
+ rtx dst = expand_ternary_op (<MODE>mode, fms_optab, tmp, operands[3],
+ operands[1], operands[0], 0);
+ emit_move_insn (operands[0], dst);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFWNMACC
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfwnmacc.vv
+;; -------------------------------------------------------------------------
+
+;; Combine ext + ext + fnms ===> widen fnms.
+;; Most of circumstantces, LoopVectorizer will generate the following IR:
+;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
+;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
+;; vect__13.182_33 = .FNMS (vect__11.180_35, vect__8.176_40, vect__4.172_45);
+(define_insn_and_split "*double_widen_fnms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (neg:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
+ (neg:VWEXTF
+ (match_operand:VWEXTF 1 "register_operand"))))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_widen_mul_neg (MINUS, <MODE>mode),
+ riscv_vector::RVV_WIDEN_TERNOP, operands);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; This helps to match ext + fnms.
+(define_insn_and_split "*single_widen_fnms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (fma:VWEXTF
+ (neg:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
+ (match_operand:VWEXTF 3 "register_operand")
+ (neg:VWEXTF
+ (match_operand:VWEXTF 1 "register_operand"))))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ insn_code icode = code_for_pred_extend (<MODE>mode);
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ext_ops);
+
+ rtx dst = expand_ternary_op (<MODE>mode, fnms_optab, tmp, operands[3],
+ operands[1], operands[0], 0);
+ emit_move_insn (operands[0], dst);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f1641d7..4ab0e9f 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -22,29 +22,27 @@
;; == Loads/Stores
;; =========================================================================
-;; len_load/len_store is a sub-optimal pattern for RVV auto-vectorization support.
-;; We will replace them when len_maskload/len_maskstore is supported in loop vectorizer.
-(define_expand "len_load_<mode>"
+(define_expand "len_maskload<mode><vm>"
[(match_operand:V 0 "register_operand")
(match_operand:V 1 "memory_operand")
- (match_operand 2 "vector_length_operand")
- (match_operand 3 "const_0_operand")]
+ (match_operand 2 "autovec_length_operand")
+ (match_operand 3 "const_0_operand")
+ (match_operand:<VM> 4 "vector_mask_operand")]
"TARGET_VECTOR"
{
- riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
- riscv_vector::RVV_UNOP, operands, operands[2]);
+ riscv_vector::expand_load_store (operands, true);
DONE;
})
-(define_expand "len_store_<mode>"
+(define_expand "len_maskstore<mode><vm>"
[(match_operand:V 0 "memory_operand")
(match_operand:V 1 "register_operand")
- (match_operand 2 "vector_length_operand")
- (match_operand 3 "const_0_operand")]
+ (match_operand 2 "autovec_length_operand")
+ (match_operand 3 "const_0_operand")
+ (match_operand:<VM> 4 "vector_mask_operand")]
"TARGET_VECTOR"
{
- riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
- riscv_vector::RVV_UNOP, operands, operands[2]);
+ riscv_vector::expand_load_store (operands, false);
DONE;
})
@@ -164,12 +162,12 @@
riscv_vector::emit_vlmax_insn (code_for_pred_scalar (<CODE>, <MODE>mode),
riscv_vector::RVV_BINOP, operands);
DONE;
-}
+}
[(set_attr "type" "vshift")
(set_attr "mode" "<MODE>")])
;; -------------------------------------------------------------------------
-;; ---- [INT] Binary shifts by scalar.
+;; ---- [INT] Binary shifts by vector.
;; -------------------------------------------------------------------------
;; Includes:
;; - vsll.vv/vsra.vv/vsrl.vv
@@ -314,44 +312,6 @@
)
;; -------------------------------------------------------------------------
-;; ---- [INT,FP] Compare and select
-;; -------------------------------------------------------------------------
-;; The patterns in this section are synthetic.
-;; -------------------------------------------------------------------------
-
-(define_expand "vcond<V:mode><VI:mode>"
- [(set (match_operand:V 0 "register_operand")
- (if_then_else:V
- (match_operator 3 "comparison_operator"
- [(match_operand:VI 4 "register_operand")
- (match_operand:VI 5 "register_operand")])
- (match_operand:V 1 "register_operand")
- (match_operand:V 2 "register_operand")))]
- "TARGET_VECTOR && known_eq (GET_MODE_NUNITS (<V:MODE>mode),
- GET_MODE_NUNITS (<VI:MODE>mode))"
- {
- riscv_vector::expand_vcond (operands);
- DONE;
- }
-)
-
-(define_expand "vcondu<V:mode><VI:mode>"
- [(set (match_operand:V 0 "register_operand")
- (if_then_else:V
- (match_operator 3 "comparison_operator"
- [(match_operand:VI 4 "register_operand")
- (match_operand:VI 5 "register_operand")])
- (match_operand:V 1 "register_operand")
- (match_operand:V 2 "register_operand")))]
- "TARGET_VECTOR && known_eq (GET_MODE_NUNITS (<V:MODE>mode),
- GET_MODE_NUNITS (<VI:MODE>mode))"
- {
- riscv_vector::expand_vcond (operands);
- DONE;
- }
-)
-
-;; -------------------------------------------------------------------------
;; ---- [INT] Sign and zero extension
;; -------------------------------------------------------------------------
;; Includes:
@@ -468,6 +428,90 @@
DONE;
})
+;; -------------------------------------------------------------------------
+;; ---- [FP] Widening.
+;; -------------------------------------------------------------------------
+;; - vfwcvt.f.f.v
+;; -------------------------------------------------------------------------
+(define_insn_and_split "extend<v_double_trunc><mode>2"
+ [(set (match_operand:VWEXTF_ZVFHMIN 0 "register_operand" "=&vr")
+ (float_extend:VWEXTF_ZVFHMIN
+ (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand" " vr")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ insn_code icode = code_for_pred_extend (<MODE>mode);
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, operands);
+ DONE;
+}
+ [(set_attr "type" "vfwcvtftof")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "extend<v_quad_trunc><mode>2"
+ [(set (match_operand:VQEXTF 0 "register_operand")
+ (float_extend:VQEXTF
+ (match_operand:<V_QUAD_TRUNC> 1 "register_operand")))]
+ "TARGET_VECTOR && (TARGET_ZVFHMIN || TARGET_ZVFH)"
+{
+ rtx dblw = gen_reg_rtx (<V_DOUBLE_TRUNC>mode);
+ insn_code icode = code_for_pred_extend (<V_DOUBLE_TRUNC>mode);
+ rtx ops1[] = {dblw, operands[1]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ops1);
+
+ icode = code_for_pred_extend (<MODE>mode);
+ rtx ops2[] = {operands[0], dblw};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ops2);
+ DONE;
+})
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Narrowing.
+;; -------------------------------------------------------------------------
+;; - vfncvt.f.f.w
+;; -------------------------------------------------------------------------
+(define_insn_and_split "trunc<mode><v_double_trunc>2"
+ [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vr")
+ (truncate:<V_DOUBLE_TRUNC>
+ (match_operand:VWEXTF_ZVFHMIN 1 "register_operand" " vr")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ insn_code icode = code_for_pred_trunc (<MODE>mode);
+ riscv_vector::emit_vlmax_fp_insn (icode, riscv_vector::RVV_UNOP, operands);
+ DONE;
+}
+ [(set_attr "type" "vfncvtftof")
+ (set_attr "mode" "<MODE>")])
+
+;; -------------------------------------------------------------------------
+;; Narrowing to a mode whose inner mode size is a quarter of mode's.
+;; We emulate this with two consecutive vfncvts.
+;; -------------------------------------------------------------------------
+(define_expand "trunc<mode><v_quad_trunc>2"
+ [(set (match_operand:<V_QUAD_TRUNC> 0 "register_operand")
+ (truncate:<V_QUAD_TRUNC>
+ (match_operand:VQEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && (TARGET_ZVFHMIN || TARGET_ZVFH)"
+{
+ rtx half = gen_reg_rtx (<V_DOUBLE_TRUNC>mode);
+ rtx opshalf[] = {half, operands[1]};
+
+ /* According to the RISC-V V Spec 13.19. we need to use
+ vfncvt.rod.f.f.w for all steps but the last. */
+ insn_code icode = code_for_pred_rod_trunc (<MODE>mode);
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, opshalf);
+
+ rtx ops[] = {operands[0], half};
+ icode = code_for_pred_trunc (<V_DOUBLE_TRUNC>mode);
+ riscv_vector::emit_vlmax_fp_insn (icode, riscv_vector::RVV_UNOP, ops);
+ DONE;
+})
+
+
;; =========================================================================
;; == Conversions
;; =========================================================================
@@ -491,6 +535,101 @@
DONE;
})
+;; -------------------------------------------------------------------------
+;; ---- [FP<-INT] Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfcvt.f.xu.v
+;; - vfcvt.f.x.v
+;; -------------------------------------------------------------------------
+
+(define_expand "<float_cvt><vconvert><mode>2"
+ [(set (match_operand:VF 0 "register_operand")
+ (any_float:VF
+ (match_operand:<VCONVERT> 1 "register_operand")))]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred (<CODE>, <MODE>mode);
+ riscv_vector::emit_vlmax_fp_insn (icode, riscv_vector::RVV_UNOP, operands);
+ DONE;
+})
+
+;; =========================================================================
+;; == Widening/narrowing Conversions
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT<-FP] Widening Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfwcvt.rtz.xu.f.v
+;; - vfwcvt.rtz.x.f.v
+;; -------------------------------------------------------------------------
+(define_expand "<optab><vnconvert><mode>2"
+ [(set (match_operand:VWCONVERTI 0 "register_operand")
+ (any_fix:VWCONVERTI
+ (match_operand:<VNCONVERT> 1 "register_operand")))]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred_widen (<CODE>, <MODE>mode);
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, operands);
+ DONE;
+})
+
+;; -------------------------------------------------------------------------
+;; ---- [FP<-INT] Widening Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfwcvt.f.xu.v
+;; - vfwcvt.f.x.v
+;; -------------------------------------------------------------------------
+(define_expand "<float_cvt><vnconvert><mode>2"
+ [(set (match_operand:VF 0 "register_operand")
+ (any_float:VF
+ (match_operand:<VNCONVERT> 1 "register_operand")))]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred_widen (<CODE>, <MODE>mode);
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, operands);
+ DONE;
+})
+
+;; -------------------------------------------------------------------------
+;; ---- [INT<-FP] Narrowing Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfncvt.rtz.xu.f.v
+;; - vfncvt.rtz.x.f.v
+;; -------------------------------------------------------------------------
+(define_expand "<optab><mode><vnconvert>2"
+ [(set (match_operand:<VNCONVERT> 0 "register_operand")
+ (any_fix:<VNCONVERT>
+ (match_operand:VF 1 "register_operand")))]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred_narrow (<CODE>, <MODE>mode);
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, operands);
+ DONE;
+})
+
+;; -------------------------------------------------------------------------
+;; ---- [FP<-INT] Narrowing Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfncvt.f.xu.w
+;; - vfncvt.f.x.w
+;; -------------------------------------------------------------------------
+(define_expand "<float_cvt><mode><vnconvert>2"
+ [(set (match_operand:<VNCONVERT> 0 "register_operand")
+ (any_float:<VNCONVERT>
+ (match_operand:VWCONVERTI 1 "register_operand")))]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred_narrow (<CODE>, <MODE>mode);
+ riscv_vector::emit_vlmax_fp_insn (icode, riscv_vector::RVV_UNOP, operands);
+ DONE;
+})
+
;; =========================================================================
;; == Unary arithmetic
;; =========================================================================
@@ -539,9 +678,9 @@
;; - vfneg.v/vfabs.v
;; -------------------------------------------------------------------------------
(define_expand "<optab><mode>2"
- [(set (match_operand:VF_AUTO 0 "register_operand")
- (any_float_unop_nofrm:VF_AUTO
- (match_operand:VF_AUTO 1 "register_operand")))]
+ [(set (match_operand:VF 0 "register_operand")
+ (any_float_unop_nofrm:VF
+ (match_operand:VF 1 "register_operand")))]
"TARGET_VECTOR"
{
insn_code icode = code_for_pred (<CODE>, <MODE>mode);
@@ -556,9 +695,9 @@
;; - vfsqrt.v
;; -------------------------------------------------------------------------------
(define_expand "<optab><mode>2"
- [(set (match_operand:VF_AUTO 0 "register_operand")
- (any_float_unop:VF_AUTO
- (match_operand:VF_AUTO 1 "register_operand")))]
+ [(set (match_operand:VF 0 "register_operand")
+ (any_float_unop:VF
+ (match_operand:VF 1 "register_operand")))]
"TARGET_VECTOR"
{
insn_code icode = code_for_pred (<CODE>, <MODE>mode);
@@ -596,40 +735,41 @@
;; result after reload_completed.
(define_expand "fma<mode>4"
[(parallel
- [(set (match_operand:VI 0 "register_operand" "=vr")
+ [(set (match_operand:VI 0 "register_operand")
(plus:VI
(mult:VI
- (match_operand:VI 1 "register_operand" " vr")
- (match_operand:VI 2 "register_operand" " vr"))
- (match_operand:VI 3 "register_operand" " vr")))
- (clobber (match_scratch:SI 4))])]
+ (match_operand:VI 1 "register_operand")
+ (match_operand:VI 2 "register_operand"))
+ (match_operand:VI 3 "register_operand")))
+ (clobber (match_dup 4))])]
"TARGET_VECTOR"
- {})
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
-(define_insn_and_split "*fma<mode>"
+(define_insn_and_split "*fma<VI:mode><P:mode>"
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
(plus:VI
(mult:VI
(match_operand:VI 1 "register_operand" " %0, vr, vr")
(match_operand:VI 2 "register_operand" " vr, vr, vr"))
(match_operand:VI 3 "register_operand" " vr, 0, vr")))
- (clobber (match_scratch:SI 4 "=r,r,r"))]
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
"TARGET_VECTOR"
"#"
"&& reload_completed"
[(const_int 0)]
{
- PUT_MODE (operands[4], Pmode);
- riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
+ riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
if (which_alternative == 2)
emit_insn (gen_rtx_SET (operands[0], operands[3]));
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
- riscv_vector::emit_vlmax_ternary_insn (code_for_pred_mul_plus (<MODE>mode),
- riscv_vector::RVV_TERNOP, ops, operands[4]);
+ riscv_vector::emit_vlmax_ternary_insn (code_for_pred_mul_plus (<VI:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
DONE;
}
[(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<VI:MODE>")])
;; -------------------------------------------------------------------------
;; ---- [INT] VNMSAC and VNMSUB
@@ -641,40 +781,225 @@
(define_expand "fnma<mode>4"
[(parallel
- [(set (match_operand:VI 0 "register_operand" "=vr")
+ [(set (match_operand:VI 0 "register_operand")
(minus:VI
- (match_operand:VI 3 "register_operand" " vr")
+ (match_operand:VI 3 "register_operand")
(mult:VI
- (match_operand:VI 1 "register_operand" " vr")
- (match_operand:VI 2 "register_operand" " vr"))))
- (clobber (match_scratch:SI 4))])]
+ (match_operand:VI 1 "register_operand")
+ (match_operand:VI 2 "register_operand"))))
+ (clobber (match_dup 4))])]
"TARGET_VECTOR"
- {})
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
-(define_insn_and_split "*fnma<mode>"
+(define_insn_and_split "*fnma<VI:mode><P:mode>"
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
(minus:VI
(match_operand:VI 3 "register_operand" " vr, 0, vr")
(mult:VI
(match_operand:VI 1 "register_operand" " %0, vr, vr")
(match_operand:VI 2 "register_operand" " vr, vr, vr"))))
- (clobber (match_scratch:SI 4 "=r,r,r"))]
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
"TARGET_VECTOR"
"#"
"&& reload_completed"
[(const_int 0)]
{
- PUT_MODE (operands[4], Pmode);
- riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
+ riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
if (which_alternative == 2)
emit_insn (gen_rtx_SET (operands[0], operands[3]));
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
- riscv_vector::emit_vlmax_ternary_insn (code_for_pred_minus_mul (<MODE>mode),
- riscv_vector::RVV_TERNOP, ops, operands[4]);
+ riscv_vector::emit_vlmax_ternary_insn (code_for_pred_minus_mul (<VI:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
DONE;
}
[(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<VI:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMACC and VFMADD
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmacc
+;; - vfmadd
+;; -------------------------------------------------------------------------
+
+(define_expand "fma<mode>4"
+ [(parallel
+ [(set (match_operand:VF 0 "register_operand")
+ (fma:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand")
+ (match_operand:VF 3 "register_operand")))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fma<VF:mode><P:mode>"
+ [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF
+ (match_operand:VF 1 "register_operand" " %0, vr, vr")
+ (match_operand:VF 2 "register_operand" " vr, vr, vr")
+ (match_operand:VF 3 "register_operand" " vr, 0, vr")))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (PLUS, <VF:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFNMSAC and VFNMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfnmsac
+;; - vfnmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fnma<mode>4"
+ [(parallel
+ [(set (match_operand:VF 0 "register_operand")
+ (fma:VF
+ (neg:VF
+ (match_operand:VF 1 "register_operand"))
+ (match_operand:VF 2 "register_operand")
+ (match_operand:VF 3 "register_operand")))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fnma<VF:mode><P:mode>"
+ [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF
+ (neg:VF
+ (match_operand:VF 1 "register_operand" " %0, vr, vr"))
+ (match_operand:VF 2 "register_operand" " vr, vr, vr")
+ (match_operand:VF 3 "register_operand" " vr, 0, vr")))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (PLUS, <VF:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMSAC and VFMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmsac
+;; - vfmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fms<mode>4"
+ [(parallel
+ [(set (match_operand:VF 0 "register_operand")
+ (fma:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand")
+ (neg:VF
+ (match_operand:VF 3 "register_operand"))))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fms<VF:mode><P:mode>"
+ [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF
+ (match_operand:VF 1 "register_operand" " %0, vr, vr")
+ (match_operand:VF 2 "register_operand" " vr, vr, vr")
+ (neg:VF
+ (match_operand:VF 3 "register_operand" " vr, 0, vr"))))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (MINUS, <VF:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMSAC and VFMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmsac
+;; - vfmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fnms<mode>4"
+ [(parallel
+ [(set (match_operand:VF 0 "register_operand")
+ (fma:VF
+ (neg:VF
+ (match_operand:VF 1 "register_operand"))
+ (match_operand:VF 2 "register_operand")
+ (neg:VF
+ (match_operand:VF 3 "register_operand"))))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fnms<VF:mode><P:mode>"
+ [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF
+ (neg:VF
+ (match_operand:VF 1 "register_operand" " %0, vr, vr"))
+ (match_operand:VF 2 "register_operand" " vr, vr, vr")
+ (neg:VF
+ (match_operand:VF 3 "register_operand" " vr, 0, vr"))))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (MINUS, <VF:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF:MODE>")])
;; =========================================================================
;; == SELECT_VL
@@ -777,10 +1102,10 @@
;; - vfadd.vf/vfsub.vf/...
;; -------------------------------------------------------------------------
(define_expand "<optab><mode>3"
- [(match_operand:VF_AUTO 0 "register_operand")
- (any_float_binop:VF_AUTO
- (match_operand:VF_AUTO 1 "register_operand")
- (match_operand:VF_AUTO 2 "register_operand"))]
+ [(match_operand:VF 0 "register_operand")
+ (any_float_binop:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand"))]
"TARGET_VECTOR"
{
riscv_vector::emit_vlmax_fp_insn (code_for_pred (<CODE>, <MODE>mode),
@@ -794,13 +1119,56 @@
;; - vfmin.vf/vfmax.vf
;; -------------------------------------------------------------------------
(define_expand "<optab><mode>3"
- [(match_operand:VF_AUTO 0 "register_operand")
- (any_float_binop_nofrm:VF_AUTO
- (match_operand:VF_AUTO 1 "register_operand")
- (match_operand:VF_AUTO 2 "register_operand"))]
+ [(match_operand:VF 0 "register_operand")
+ (any_float_binop_nofrm:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand"))]
"TARGET_VECTOR"
{
riscv_vector::emit_vlmax_insn (code_for_pred (<CODE>, <MODE>mode),
riscv_vector::RVV_BINOP, operands);
DONE;
})
+
+;; -------------------------------------------------------------------------------
+;; ---- [FP] Sign copying
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - vfsgnj.vv/vfsgnjn.vv
+;; - vfsgnj.vf/vfsgnjn.vf
+;; -------------------------------------------------------------------------------
+
+;; Leave the pattern like this as to still allow combine to match
+;; a negated copysign (see vector.md) before adding the UNSPEC_VPREDICATE later.
+(define_insn_and_split "copysign<mode>3"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (unspec:VF
+ [(match_operand:VF 1 "register_operand" " vr, vr, vr, vr")
+ (match_operand:VF 2 "register_operand" " vr, vr, vr, vr")] UNSPEC_VCOPYSIGN))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ riscv_vector::emit_vlmax_insn (code_for_pred (UNSPEC_VCOPYSIGN, <MODE>mode),
+ riscv_vector::RVV_BINOP, operands);
+ DONE;
+}
+ [(set_attr "type" "vfsgnj")
+ (set_attr "mode" "<MODE>")])
+
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - vfsgnjx.vv
+;; - vfsgnjx.vf
+;; -------------------------------------------------------------------------------
+(define_expand "xorsign<mode>3"
+ [(match_operand:VF 0 "register_operand")
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand")]
+ "TARGET_VECTOR"
+{
+ riscv_vector::emit_vlmax_insn (code_for_pred (UNSPEC_VXORSIGN, <MODE>mode),
+ riscv_vector::RVV_BINOP, operands);
+ DONE;
+})
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 04ca6ce..eb975ea 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -276,6 +276,13 @@
(ior (match_operand 0 "pmode_register_operand")
(match_operand 0 "const_csr_operand")))
+(define_special_predicate "autovec_length_operand"
+ (ior (match_operand 0 "pmode_register_operand")
+ (ior (match_operand 0 "const_csr_operand")
+ (match_test "rtx_equal_p (op, gen_int_mode
+ (GET_MODE_NUNITS (GET_MODE (op)),
+ Pmode))"))))
+
(define_predicate "reg_or_mem_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "memory_operand")))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 208a557..cfcf608 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -168,6 +168,40 @@ enum riscv_entity
#define TARGET_VECTOR_ELEN_FP_16 \
((riscv_vector_elen_flags & MASK_VECTOR_ELEN_FP_16) != 0)
+#define MASK_ZVBB (1 << 0)
+#define MASK_ZVBC (1 << 1)
+
+#define TARGET_ZVBB ((riscv_zvb_subext & MASK_ZVBB) != 0)
+#define TARGET_ZVBC ((riscv_zvb_subext & MASK_ZVBC) != 0)
+
+#define MASK_ZVKG (1 << 0)
+#define MASK_ZVKNED (1 << 1)
+#define MASK_ZVKNHA (1 << 2)
+#define MASK_ZVKNHB (1 << 3)
+#define MASK_ZVKSED (1 << 4)
+#define MASK_ZVKSH (1 << 5)
+#define MASK_ZVKN (1 << 6)
+#define MASK_ZVKNC (1 << 7)
+#define MASK_ZVKNG (1 << 8)
+#define MASK_ZVKS (1 << 9)
+#define MASK_ZVKSC (1 << 10)
+#define MASK_ZVKSG (1 << 11)
+#define MASK_ZVKT (1 << 12)
+
+#define TARGET_ZVKG ((riscv_zvk_subext & MASK_ZVKG) != 0)
+#define TARGET_ZVKNED ((riscv_zvk_subext & MASK_ZVKNED) != 0)
+#define TARGET_ZVKNHA ((riscv_zvk_subext & MASK_ZVKNHA) != 0)
+#define TARGET_ZVKNHB ((riscv_zvk_subext & MASK_ZVKNHB) != 0)
+#define TARGET_ZVKSED ((riscv_zvk_subext & MASK_ZVKSED) != 0)
+#define TARGET_ZVKSH ((riscv_zvk_subext & MASK_ZVKSH) != 0)
+#define TARGET_ZVKN ((riscv_zvk_subext & MASK_ZVKN) != 0)
+#define TARGET_ZVKNC ((riscv_zvk_subext & MASK_ZVKNC) != 0)
+#define TARGET_ZVKNG ((riscv_zvk_subext & MASK_ZVKNG) != 0)
+#define TARGET_ZVKS ((riscv_zvk_subext & MASK_ZVKS) != 0)
+#define TARGET_ZVKSC ((riscv_zvk_subext & MASK_ZVKSC) != 0)
+#define TARGET_ZVKSG ((riscv_zvk_subext & MASK_ZVKSG) != 0)
+#define TARGET_ZVKT ((riscv_zvk_subext & MASK_ZVKT) != 0)
+
#define MASK_ZVL32B (1 << 0)
#define MASK_ZVL64B (1 << 1)
#define MASK_ZVL128B (1 << 2)
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index f052757..5766e35 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -143,6 +143,7 @@ enum insn_type
RVV_CMP_OP = 4,
RVV_CMP_MU_OP = RVV_CMP_OP + 2, /* +2 means mask and maskoff operand. */
RVV_UNOP_MU = RVV_UNOP + 2, /* Likewise. */
+ RVV_UNOP_M = RVV_UNOP + 2, /* Likewise. */
RVV_TERNOP = 5,
RVV_WIDEN_TERNOP = 4,
RVV_SCALAR_MOV_OP = 4, /* +1 for VUNDEF according to vector.md. */
@@ -187,6 +188,7 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx);
void emit_vlmax_insn (unsigned, int, rtx *, rtx = 0);
void emit_vlmax_fp_insn (unsigned, int, rtx *, rtx = 0);
void emit_vlmax_ternary_insn (unsigned, int, rtx *, rtx = 0);
+void emit_vlmax_fp_ternary_insn (unsigned, int, rtx *, rtx = 0);
void emit_nonvlmax_insn (unsigned, int, rtx *, rtx);
void emit_vlmax_slide_insn (unsigned, rtx *);
void emit_nonvlmax_slide_tu_insn (unsigned, rtx *, rtx);
@@ -250,9 +252,9 @@ machine_mode preferred_simd_mode (scalar_mode);
opt_machine_mode get_mask_mode (machine_mode);
void expand_vec_series (rtx, rtx, rtx);
void expand_vec_init (rtx, rtx);
-void expand_vcond (rtx *);
void expand_vec_perm (rtx, rtx, rtx, rtx);
void expand_select_vl (rtx *);
+void expand_load_store (rtx *, bool);
/* Rounding mode bitfield for fixed point VXRM. */
enum fixed_point_rounding_mode
@@ -275,6 +277,8 @@ enum floating_point_rounding_mode
FRM_RUP = 3, /* Aka 0b011. */
FRM_RMM = 4, /* Aka 0b100. */
FRM_DYN = 7, /* Aka 0b111. */
+ FRM_STATIC_MIN = FRM_RNE,
+ FRM_STATIC_MAX = FRM_RMM,
};
opt_machine_mode vectorize_related_mode (machine_mode, scalar_mode,
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 839a2c6..8d5bed7 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -705,19 +705,42 @@ emit_vlmax_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
{
machine_mode dest_mode = GET_MODE (ops[0]);
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
- /* We have a maximum of 11 operands for RVV instruction patterns according to
- * vector.md. */
- insn_expander<11> e (/*OP_NUM*/ op_num, /*HAS_DEST_P*/ true,
- /*FULLY_UNMASKED_P*/ true,
- /*USE_REAL_MERGE_P*/ true, /*HAS_AVL_P*/ true,
- /*VLMAX_P*/ true,
- /*DEST_MODE*/ dest_mode, /*MASK_MODE*/ mask_mode);
+ insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+ /*HAS_DEST_P*/ true,
+ /*FULLY_UNMASKED_P*/ true,
+ /*USE_REAL_MERGE_P*/ true,
+ /*HAS_AVL_P*/ true,
+ /*VLMAX_P*/ true,
+ /*DEST_MODE*/ dest_mode,
+ /*MASK_MODE*/ mask_mode);
e.set_policy (TAIL_ANY);
e.set_policy (MASK_ANY);
e.set_vl (vl);
e.emit_insn ((enum insn_code) icode, ops);
}
+/* This function emits a {VLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
+ * ternary operation which always has a real merge operand. */
+void
+emit_vlmax_fp_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
+{
+ machine_mode dest_mode = GET_MODE (ops[0]);
+ machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+ insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+ /*HAS_DEST_P*/ true,
+ /*FULLY_UNMASKED_P*/ true,
+ /*USE_REAL_MERGE_P*/ true,
+ /*HAS_AVL_P*/ true,
+ /*VLMAX_P*/ true,
+ /*DEST_MODE*/ dest_mode,
+ /*MASK_MODE*/ mask_mode);
+ e.set_policy (TAIL_ANY);
+ e.set_policy (MASK_ANY);
+ e.set_rounding_mode (FRM_DYN);
+ e.set_vl (vl);
+ e.emit_insn ((enum insn_code) icode, ops);
+}
+
/* This function emits a {NONVLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
* actual operation. */
void
@@ -842,16 +865,55 @@ emit_vlmax_cmp_mu_insn (unsigned icode, rtx *ops)
}
/* This function emits a masked instruction. */
+static void
+emit_vlmax_masked_insn (unsigned icode, int op_num, rtx *ops)
+{
+ machine_mode dest_mode = GET_MODE (ops[0]);
+ machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+ insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+ /*HAS_DEST_P*/ true,
+ /*FULLY_UNMASKED_P*/ false,
+ /*USE_REAL_MERGE_P*/ true,
+ /*HAS_AVL_P*/ true,
+ /*VLMAX_P*/ true, dest_mode,
+ mask_mode);
+ e.set_policy (TAIL_ANY);
+ e.set_policy (MASK_ANY);
+ e.emit_insn ((enum insn_code) icode, ops);
+}
+
+/* This function emits a masked instruction. */
+static void
+emit_nonvlmax_masked_insn (unsigned icode, int op_num, rtx *ops, rtx avl)
+{
+ machine_mode dest_mode = GET_MODE (ops[0]);
+ machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+ insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+ /*HAS_DEST_P*/ true,
+ /*FULLY_UNMASKED_P*/ false,
+ /*USE_REAL_MERGE_P*/ true,
+ /*HAS_AVL_P*/ true,
+ /*VLMAX_P*/ false, dest_mode,
+ mask_mode);
+ e.set_policy (TAIL_ANY);
+ e.set_policy (MASK_ANY);
+ e.set_vl (avl);
+ e.emit_insn ((enum insn_code) icode, ops);
+}
+
+/* This function emits a masked instruction. */
void
emit_vlmax_masked_mu_insn (unsigned icode, int op_num, rtx *ops)
{
machine_mode dest_mode = GET_MODE (ops[0]);
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
- insn_expander<11> e (/*OP_NUM*/ op_num, /*HAS_DEST_P*/ true,
- /*FULLY_UNMASKED_P*/ false,
- /*USE_REAL_MERGE_P*/ true,
- /*HAS_AVL_P*/ true,
- /*VLMAX_P*/ true, dest_mode, mask_mode);
+ insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+ /*HAS_DEST_P*/ true,
+ /*FULLY_UNMASKED_P*/ false,
+ /*USE_REAL_MERGE_P*/ true,
+ /*HAS_AVL_P*/ true,
+ /*VLMAX_P*/ true, dest_mode,
+ mask_mode);
e.set_policy (TAIL_ANY);
e.set_policy (MASK_UNDISTURBED);
e.emit_insn ((enum insn_code) icode, ops);
@@ -1196,7 +1258,6 @@ expand_const_vector (rtx target, rtx src)
}
emit_move_insn (target, tmp);
}
- return;
}
else if (CONST_VECTOR_STEPPED_P (src))
{
@@ -1225,9 +1286,20 @@ expand_const_vector (rtx target, rtx src)
*/
rtx imm
= gen_int_mode (-builder.npatterns (), builder.inner_mode ());
- rtx and_ops[] = {target, vid, imm};
+ rtx tmp = gen_reg_rtx (builder.mode ());
+ rtx and_ops[] = {tmp, vid, imm};
icode = code_for_pred_scalar (AND, builder.mode ());
emit_vlmax_insn (icode, RVV_BINOP, and_ops);
+ HOST_WIDE_INT init_val = INTVAL (builder.elt (0));
+ if (init_val == 0)
+ emit_move_insn (target, tmp);
+ else
+ {
+ rtx dup = gen_const_vector_dup (builder.mode (), init_val);
+ rtx add_ops[] = {target, tmp, dup};
+ icode = code_for_pred (PLUS, builder.mode ());
+ emit_vlmax_insn (icode, RVV_BINOP, add_ops);
+ }
}
else
{
@@ -2359,28 +2431,6 @@ expand_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1,
return false;
}
-/* Expand an RVV vcond pattern with operands OPS. DATA_MODE is the mode
- of the data being merged and CMP_MODE is the mode of the values being
- compared. */
-
-void
-expand_vcond (rtx *ops)
-{
- machine_mode cmp_mode = GET_MODE (ops[4]);
- machine_mode data_mode = GET_MODE (ops[1]);
- machine_mode mask_mode = get_mask_mode (cmp_mode).require ();
- rtx mask = gen_reg_rtx (mask_mode);
- if (FLOAT_MODE_P (cmp_mode))
- {
- if (expand_vec_cmp_float (mask, GET_CODE (ops[3]), ops[4], ops[5], true))
- std::swap (ops[1], ops[2]);
- }
- else
- expand_vec_cmp (mask, GET_CODE (ops[3]), ops[4], ops[5]);
- emit_insn (
- gen_vcond_mask (data_mode, data_mode, ops[0], ops[1], ops[2], mask));
-}
-
/* Implement vec_perm<mode>. */
void
@@ -2721,4 +2771,45 @@ expand_select_vl (rtx *ops)
emit_insn (gen_no_side_effects_vsetvl_rtx (rvv_mode, ops[0], ops[1]));
}
+/* Expand LEN_MASK_{LOAD,STORE}. */
+void
+expand_load_store (rtx *ops, bool is_load)
+{
+ poly_int64 value;
+ rtx len = ops[2];
+ rtx mask = ops[4];
+ machine_mode mode = GET_MODE (ops[0]);
+
+ if (poly_int_rtx_p (len, &value) && known_eq (value, GET_MODE_NUNITS (mode)))
+ {
+ /* If the length operand is equal to VF, it is VLMAX load/store. */
+ if (is_load)
+ {
+ rtx m_ops[] = {ops[0], mask, RVV_VUNDEF (mode), ops[1]};
+ emit_vlmax_masked_insn (code_for_pred_mov (mode), RVV_UNOP_M, m_ops);
+ }
+ else
+ {
+ len = gen_reg_rtx (Pmode);
+ emit_vlmax_vsetvl (mode, len);
+ emit_insn (gen_pred_store (mode, ops[0], mask, ops[1], len,
+ get_avl_type_rtx (VLMAX)));
+ }
+ }
+ else
+ {
+ if (!satisfies_constraint_K (len))
+ len = force_reg (Pmode, len);
+ if (is_load)
+ {
+ rtx m_ops[] = {ops[0], mask, RVV_VUNDEF (mode), ops[1]};
+ emit_nonvlmax_masked_insn (code_for_pred_mov (mode), RVV_UNOP_M,
+ m_ops, len);
+ }
+ else
+ emit_insn (gen_pred_store (mode, ops[0], mask, ops[1], len,
+ get_avl_type_rtx (NONVLMAX)));
+ }
+}
+
} // namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index c6c53dc..78c259f 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -281,6 +281,29 @@ public:
}
};
+/* Implements below instructions for now.
+ - vfadd
+*/
+template<rtx_code CODE>
+class binop_frm : public function_base
+{
+public:
+ bool has_rounding_mode_operand_p () const override { return true; }
+
+ rtx expand (function_expander &e) const override
+ {
+ switch (e.op_info->op)
+ {
+ case OP_TYPE_vf:
+ return e.use_exact_insn (code_for_pred_scalar (CODE, e.vector_mode ()));
+ case OP_TYPE_vv:
+ return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
+ default:
+ gcc_unreachable ();
+ }
+ }
+};
+
/* Implements vrsub. */
class vrsub : public function_base
{
@@ -390,8 +413,12 @@ public:
return e.use_exact_insn (
code_for_pred_dual_widen_scalar (CODE, e.vector_mode ()));
case OP_TYPE_wv:
- return e.use_exact_insn (
- code_for_pred_single_widen (CODE, e.vector_mode ()));
+ if (CODE == PLUS)
+ return e.use_exact_insn (
+ code_for_pred_single_widen_add (e.vector_mode ()));
+ else
+ return e.use_exact_insn (
+ code_for_pred_single_widen_sub (e.vector_mode ()));
case OP_TYPE_wf:
return e.use_exact_insn (
code_for_pred_single_widen_scalar (CODE, e.vector_mode ()));
@@ -1212,7 +1239,7 @@ public:
}
};
-/* Implements vfsqrt7/vfrec7/vfclass/vfsgnj/vfsgnjn/vfsgnjx. */
+/* Implements vfsqrt7/vfrec7/vfclass/vfsgnj/vfsgnjx. */
template<int UNSPEC>
class float_misc : public function_base
{
@@ -1227,6 +1254,20 @@ public:
}
};
+/* Implements vfsgnjn. */
+class vfsgnjn : public function_base
+{
+public:
+ rtx expand (function_expander &e) const override
+ {
+ if (e.op_info->op == OP_TYPE_vf)
+ return e.use_exact_insn (code_for_pred_ncopysign_scalar (e.vector_mode ()));
+ if (e.op_info->op == OP_TYPE_vv)
+ return e.use_exact_insn (code_for_pred_ncopysign (e.vector_mode ()));
+ gcc_unreachable ();
+ }
+};
+
/* Implements vmfeq/vmfne/vmflt/vmfgt/vmfle/vmfge. */
template<rtx_code CODE>
class fcmp : public function_base
@@ -1567,7 +1608,7 @@ public:
{
tree arg = CALL_EXPR_ARG (e.exp, 0);
rtx src = expand_normal (arg);
- emit_insn (gen_rtx_SET (gen_lowpart (e.vector_mode (), e.target), src));
+ emit_move_insn (gen_lowpart (e.vector_mode (), e.target), src);
return e.target;
}
};
@@ -2006,6 +2047,7 @@ static CONSTEXPR const viota viota_obj;
static CONSTEXPR const vid vid_obj;
static CONSTEXPR const binop<PLUS> vfadd_obj;
static CONSTEXPR const binop<MINUS> vfsub_obj;
+static CONSTEXPR const binop_frm<PLUS> vfadd_frm_obj;
static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
static CONSTEXPR const widen_binop<PLUS> vfwadd_obj;
static CONSTEXPR const widen_binop<MINUS> vfwsub_obj;
@@ -2031,7 +2073,7 @@ static CONSTEXPR const float_misc<UNSPEC_VFREC7> vfrec7_obj;
static CONSTEXPR const binop<SMIN> vfmin_obj;
static CONSTEXPR const binop<SMAX> vfmax_obj;
static CONSTEXPR const float_misc<UNSPEC_VCOPYSIGN> vfsgnj_obj;
-static CONSTEXPR const float_misc<UNSPEC_VNCOPYSIGN> vfsgnjn_obj;
+static CONSTEXPR const vfsgnjn vfsgnjn_obj;
static CONSTEXPR const float_misc<UNSPEC_VXORSIGN> vfsgnjx_obj;
static CONSTEXPR const unop<NEG> vfneg_obj;
static CONSTEXPR const unop<ABS> vfabs_obj;
@@ -2231,6 +2273,7 @@ BASE (vmsof)
BASE (viota)
BASE (vid)
BASE (vfadd)
+BASE (vfadd_frm)
BASE (vfsub)
BASE (vfrsub)
BASE (vfwadd)
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h
index 62ff38a..e771a36 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -121,8 +121,6 @@ extern const function_base *const vsmul;
extern const function_base *const vssra;
extern const function_base *const vssrl;
extern const function_base *const vnclip;
-extern const function_base *const vnclip;
-extern const function_base *const vnclipu;
extern const function_base *const vnclipu;
extern const function_base *const vmand;
extern const function_base *const vmnand;
@@ -144,8 +142,7 @@ extern const function_base *const vmsof;
extern const function_base *const viota;
extern const function_base *const vid;
extern const function_base *const vfadd;
-extern const function_base *const vfadd;
-extern const function_base *const vfsub;
+extern const function_base *const vfadd_frm;
extern const function_base *const vfsub;
extern const function_base *const vfrsub;
extern const function_base *const vfwadd;
@@ -153,7 +150,6 @@ extern const function_base *const vfwsub;
extern const function_base *const vfmul;
extern const function_base *const vfmul;
extern const function_base *const vfdiv;
-extern const function_base *const vfdiv;
extern const function_base *const vfrdiv;
extern const function_base *const vfwmul;
extern const function_base *const vfmacc;
diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def
index 89aff27..035c9e4 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -289,6 +289,8 @@ DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvf_ops)
DEF_RVV_FUNCTION (vfsub, alu, full_preds, f_vvv_ops)
DEF_RVV_FUNCTION (vfsub, alu, full_preds, f_vvf_ops)
DEF_RVV_FUNCTION (vfrsub, alu, full_preds, f_vvf_ops)
+DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
+DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvf_ops)
// 13.3. Vector Widening Floating-Point Add/Subtract Instructions
DEF_RVV_FUNCTION (vfwadd, widen_alu, full_preds, f_wvv_ops)
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index c8daae0..69a6710 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -226,6 +226,73 @@ struct alu_def : public build_base
}
};
+/* alu_frm_def class. */
+struct alu_frm_def : public build_base
+{
+ /* Normalize vf<op>_frm to vf<op>. */
+ static void normalize_base_name (char *to, const char *from, int limit)
+ {
+ strncpy (to, from, limit - 1);
+ char *suffix = strstr (to, "_frm");
+
+ if (suffix)
+ *suffix = '\0';
+
+ to[limit - 1] = '\0';
+ }
+
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+ char base_name[16] = {};
+
+ /* Return nullptr if it can not be overloaded. */
+ if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+ return nullptr;
+
+ normalize_base_name (base_name, instance.base_name, sizeof (base_name));
+
+ b.append_base_name (base_name);
+
+ /* vop<sew>_<op> --> vop<sew>_<op>_<type>. */
+ if (!overloaded_p)
+ {
+ b.append_name (operand_suffixes[instance.op_info->op]);
+ b.append_name (type_suffixes[instance.type.index].vector);
+ }
+
+ /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+ for vop_m C++ overloaded API. */
+ if (overloaded_p && instance.pred == PRED_TYPE_m)
+ return b.finish_name ();
+
+ b.append_name (predication_suffixes[instance.pred]);
+
+ /* According to rvv-intrinsic-doc, it does not add "_rm" suffix
+ for vop_rm C++ overloaded API. */
+ if (!overloaded_p)
+ b.append_name ("_rm");
+
+ return b.finish_name ();
+ }
+
+ bool check (function_checker &c) const override
+ {
+ gcc_assert (c.any_type_float_p ());
+
+ /* Check whether rounding mode argument is a valid immediate. */
+ if (c.base->has_rounding_mode_operand_p ())
+ {
+ unsigned int frm_num = c.arg_num () - 2;
+
+ return c.require_immediate_range_or (frm_num, FRM_STATIC_MIN,
+ FRM_STATIC_MAX, FRM_DYN);
+ }
+
+ return true;
+ }
+};
+
/* widen_alu_def class. Handle vwadd/vwsub. Unlike
vadd.vx/vadd.vv/vwmul.vv/vwmul.vx, vwadd.vv/vwadd.vx/vwadd.wv/vwadd.wx has
'OP' suffix in overloaded API. */
@@ -743,6 +810,7 @@ SHAPE(vsetvl, vsetvlmax)
SHAPE(loadstore, loadstore)
SHAPE(indexed_loadstore, indexed_loadstore)
SHAPE(alu, alu)
+SHAPE(alu_frm, alu_frm)
SHAPE(widen_alu, widen_alu)
SHAPE(no_mask_policy, no_mask_policy)
SHAPE(return_mask, return_mask)
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h
index 6a51713..15fef83 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -29,6 +29,7 @@ extern const function_shape *const vsetvlmax;
extern const function_shape *const loadstore;
extern const function_shape *const indexed_loadstore;
extern const function_shape *const alu;
+extern const function_shape *const alu_frm;
extern const function_shape *const widen_alu;
extern const function_shape *const no_mask_policy;
extern const function_shape *const return_mask;
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 9e6dae9..648c765 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -3636,6 +3636,7 @@ function_expander::use_contiguous_store_insn (insn_code icode)
for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++)
add_input_operand (argno);
+ add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
return generate_insn (icode);
}
@@ -3851,6 +3852,23 @@ function_checker::report_out_of_range (unsigned int argno, HOST_WIDE_INT actual,
actual, argno + 1, fndecl, min, max);
}
+/* Report that LOCATION has a call to FNDECL in which argument ARGNO has
+ the value ACTUAL, whereas the function requires a value in the range
+ [MIN, MAX] or OR_VAL. ARGNO counts from zero. */
+void
+function_checker::report_out_of_range_and_not (unsigned int argno,
+ HOST_WIDE_INT actual,
+ HOST_WIDE_INT min,
+ HOST_WIDE_INT max,
+ HOST_WIDE_INT or_val) const
+{
+ error_at (location,
+ "passing %wd to argument %d of %qE, which expects"
+ " a value in the range [%wd, %wd] or %wd",
+ actual, argno + 1, fndecl, min, max, or_val);
+}
+
+
/* Check that argument ARGNO is an integer constant expression and
store its value in VALUE_OUT if so. The caller should first
check that argument ARGNO exists. */
@@ -3892,6 +3910,30 @@ function_checker::require_immediate_range (unsigned int argno,
return true;
}
+/* Check that argument REL_ARGNO is an integer constant expression in the
+ range [MIN, MAX] or OR_VAL. REL_ARGNO counts from the end of the
+ predication arguments. */
+bool
+function_checker::require_immediate_range_or (unsigned int argno,
+ HOST_WIDE_INT min,
+ HOST_WIDE_INT max,
+ HOST_WIDE_INT or_val) const
+{
+ gcc_assert (min >= 0 && min <= max);
+ gcc_assert (argno < m_nargs);
+
+ tree arg = m_args[argno];
+ HOST_WIDE_INT actual = tree_to_uhwi (arg);
+
+ if (!IN_RANGE (actual, min, max) && actual != or_val)
+ {
+ report_out_of_range_and_not (argno, actual, min, max, or_val);
+ return false;
+ }
+
+ return true;
+}
+
/* Perform semantic checks on the call. Return true if the call is valid,
otherwise report a suitable error. */
bool
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index b0c3a42..e358a8e 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -442,6 +442,8 @@ public:
bool check (void);
bool require_immediate (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT) const;
+ bool require_immediate_range_or (unsigned int, HOST_WIDE_INT,
+ HOST_WIDE_INT, HOST_WIDE_INT) const;
private:
bool require_immediate_range (unsigned int, HOST_WIDE_INT,
@@ -449,6 +451,8 @@ private:
void report_non_ice (unsigned int) const;
void report_out_of_range (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT) const;
+ void report_out_of_range_and_not (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT,
+ HOST_WIDE_INT, HOST_WIDE_INT) const;
/* The type of the resolved function. */
tree m_fntype;
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 971c3f9..ab47901 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -2003,9 +2003,73 @@ vector_insn_info::parse_insn (insn_info *insn)
new_info.parse_insn (def_insn);
if (!same_vlmax_p (new_info) && !scalar_move_insn_p (insn->rtl ()))
return;
- /* TODO: Currently, we don't forward AVL for non-VLMAX vsetvl. */
- if (vlmax_avl_p (new_info.get_avl ()))
- set_avl_info (avl_info (new_info.get_avl (), get_avl_source ()));
+
+ if (new_info.has_avl ())
+ {
+ if (new_info.has_avl_imm ())
+ set_avl_info (avl_info (new_info.get_avl (), nullptr));
+ else
+ {
+ if (vlmax_avl_p (new_info.get_avl ()))
+ set_avl_info (avl_info (new_info.get_avl (), get_avl_source ()));
+ else
+ {
+ /* Conservatively propagate non-VLMAX AVL of user vsetvl:
+ 1. The user vsetvl should be same block with the rvv insn.
+ 2. The user vsetvl is the only def insn of rvv insn.
+ 3. The AVL is not modified between def-use chain.
+ 4. The VL is only used by insn within EBB.
+ */
+ bool modified_p = false;
+ for (insn_info *i = def_insn->next_nondebug_insn ();
+ real_insn_and_same_bb_p (i, get_insn ()->bb ());
+ i = i->next_nondebug_insn ())
+ {
+ /* Consider this following sequence:
+
+ insn 1: vsetvli a5,a3,e8,mf4,ta,mu
+ insn 2: vsetvli zero,a5,e32,m1,ta,ma
+ ...
+ vle32.v v1,0(a1)
+ vsetvli a2,zero,e32,m1,ta,ma
+ vadd.vv v1,v1,v1
+ vsetvli zero,a5,e32,m1,ta,ma
+ vse32.v v1,0(a0)
+ ...
+ insn 3: sub a3,a3,a5
+ ...
+
+ We can local AVL propagate "a3" from insn 1 to insn 2
+ if no insns between insn 1 and insn 2 modify "a3 even
+ though insn 3 modifies "a3".
+ Otherwise, we can't perform local AVL propagation.
+
+ Early break if we reach the insn 2. */
+ if (!before_p (i, insn))
+ break;
+ if (find_access (i->defs (), REGNO (new_info.get_avl ())))
+ {
+ modified_p = true;
+ break;
+ }
+ }
+
+ bool has_live_out_use = false;
+ for (use_info *use : m_avl.get_source ()->all_uses ())
+ {
+ if (use->is_live_out_use ())
+ {
+ has_live_out_use = true;
+ break;
+ }
+ }
+ if (!modified_p && !has_live_out_use
+ && def_insn == m_avl.get_source ()->insn ()
+ && m_insn->bb () == def_insn->bb ())
+ set_avl_info (new_info.get_avl_info ());
+ }
+ }
+ }
if (scalar_move_insn_p (insn->rtl ()) && m_avl.has_non_zero_avl ())
m_demands[DEMAND_NONZERO_AVL] = true;
diff --git a/gcc/config/riscv/riscv-vsetvl.h b/gcc/config/riscv/riscv-vsetvl.h
index 4257451..87cdd2e 100644
--- a/gcc/config/riscv/riscv-vsetvl.h
+++ b/gcc/config/riscv/riscv-vsetvl.h
@@ -180,6 +180,7 @@ public:
bool has_avl_reg () const { return get_value () && REG_P (get_value ()); }
bool has_avl_no_reg () const { return !get_value (); }
bool has_non_zero_avl () const;
+ bool has_avl () const { return get_value (); }
};
/* Basic structure to save VL/VTYPE information. */
@@ -219,6 +220,7 @@ public:
bool has_avl_reg () const { return m_avl.has_avl_reg (); }
bool has_avl_no_reg () const { return m_avl.has_avl_no_reg (); }
bool has_non_zero_avl () const { return m_avl.has_non_zero_avl (); };
+ bool has_avl () const { return m_avl.has_avl (); }
rtx get_avl () const { return m_avl.get_value (); }
const avl_info &get_avl_info () const { return m_avl; }
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 280aa0b..e4dc811 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7669,6 +7669,16 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode,
if (mode != VXRM_MODE_NONE && mode != prev_mode)
emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode)));
break;
+ case RISCV_FRM:
+ if (mode != FRM_MODE_NONE && mode != prev_mode)
+ {
+ rtx scaler = gen_reg_rtx (SImode);
+ rtx imm = gen_int_mode (mode, SImode);
+
+ emit_insn (gen_movsi (scaler, imm));
+ emit_insn (gen_fsrm (scaler, scaler));
+ }
+ break;
default:
gcc_unreachable ();
}
@@ -7680,11 +7690,14 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode,
static int
riscv_mode_needed (int entity, rtx_insn *insn)
{
+ int code = recog_memoized (insn);
+
switch (entity)
{
case RISCV_VXRM:
- return recog_memoized (insn) >= 0 ? get_attr_vxrm_mode (insn)
- : VXRM_MODE_NONE;
+ return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE;
+ case RISCV_FRM:
+ return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_NONE;
default:
gcc_unreachable ();
}
@@ -7715,6 +7728,21 @@ global_state_unknown_p (rtx_insn *insn, unsigned int regno)
return false;
}
+static int
+riscv_entity_mode_after (int regnum, rtx_insn *insn, int mode,
+ int (*get_attr_mode) (rtx_insn *), int default_mode)
+{
+ if (global_state_unknown_p (insn, regnum))
+ return default_mode;
+ else if (recog_memoized (insn) < 0)
+ return mode;
+
+ rtx reg = gen_rtx_REG (SImode, regnum);
+ bool mentioned_p = reg_mentioned_p (reg, PATTERN (insn));
+
+ return mentioned_p ? get_attr_mode (insn): mode;
+}
+
/* Return the mode that an insn results in. */
static int
@@ -7723,15 +7751,13 @@ riscv_mode_after (int entity, int mode, rtx_insn *insn)
switch (entity)
{
case RISCV_VXRM:
- if (global_state_unknown_p (insn, VXRM_REGNUM))
- return VXRM_MODE_NONE;
- else if (recog_memoized (insn) >= 0)
- return reg_mentioned_p (gen_rtx_REG (SImode, VXRM_REGNUM),
- PATTERN (insn))
- ? get_attr_vxrm_mode (insn)
- : mode;
- else
- return mode;
+ return riscv_entity_mode_after (VXRM_REGNUM, insn, mode,
+ (int (*)(rtx_insn *)) get_attr_vxrm_mode,
+ VXRM_MODE_NONE);
+ case RISCV_FRM:
+ return riscv_entity_mode_after (FRM_REGNUM, insn, mode,
+ (int (*)(rtx_insn *)) get_attr_frm_mode,
+ FRM_MODE_NONE);
default:
gcc_unreachable ();
}
@@ -7747,6 +7773,8 @@ riscv_mode_entry (int entity)
{
case RISCV_VXRM:
return VXRM_MODE_NONE;
+ case RISCV_FRM:
+ return FRM_MODE_NONE;
default:
gcc_unreachable ();
}
@@ -7762,6 +7790,8 @@ riscv_mode_exit (int entity)
{
case RISCV_VXRM:
return VXRM_MODE_NONE;
+ case RISCV_FRM:
+ return FRM_MODE_NONE;
default:
gcc_unreachable ();
}
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index bfd9b75..83dcac1 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -849,7 +849,7 @@ typedef struct {
"fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", \
"fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", \
"fs8", "fs9", "fs10","fs11","ft8", "ft9", "ft10","ft11", \
- "arg", "frame", "vl", "vtype", "vxrm", "N/A", "N/A", "N/A", \
+ "arg", "frame", "vl", "vtype", "vxrm", "frm", "N/A", "N/A", \
"N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", \
"N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", \
"N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", \
@@ -1113,6 +1113,6 @@ extern void riscv_remove_unneeded_save_restore_calls (void);
/* Mode switching (Lazy code motion) for RVV rounding mode instructions. */
#define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_VECTOR)
-#define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE}
+#define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE, FRM_MODE_NONE}
#endif /* ! GCC_RISCV_H */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 245cace..d63b584 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -287,6 +287,7 @@
;; rdvlenb vector byte length vlenb csrr read
;; rdvl vector length vl csrr read
;; wrvxrm vector fixed-point rounding mode write
+;; wrfrm vector floating-point rounding mode write
;; vsetvl vector configuration-setting instrucions
;; 7. Vector Loads and Stores
;; vlde vector unit-stride load instructions
@@ -390,7 +391,8 @@
mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost,bitmanip,rotate,
clmul,min,max,minu,maxu,clz,ctz,cpop,
- atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,vsetvl,vlde,vste,vldm,vstm,vlds,vsts,
+ atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,wrfrm,vsetvl,
+ vlde,vste,vldm,vstm,vlds,vsts,
vldux,vldox,vstux,vstox,vldff,vldr,vstr,
vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff,
vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,viminmax,
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 63d4710..dd062f1 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -224,6 +224,12 @@ TargetVariable
int riscv_zvl_flags
TargetVariable
+int riscv_zvb_subext
+
+TargetVariable
+int riscv_zvk_subext
+
+TargetVariable
int riscv_zicmo_subext
TargetVariable
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 6ca1c54..8afd3dc 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -61,7 +61,6 @@
UNSPEC_VFCLASS
UNSPEC_VCOPYSIGN
- UNSPEC_VNCOPYSIGN
UNSPEC_VXORSIGN
UNSPEC_VFCVT
@@ -82,6 +81,8 @@
UNSPEC_VCOMPRESS
UNSPEC_VLEFF
UNSPEC_MODIFY_VL
+
+ UNSPEC_FSRM
])
(define_mode_iterator V [
@@ -271,7 +272,7 @@
(VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128")
])
-(define_mode_iterator VF [
+(define_mode_iterator VF_ZVFHMIN [
(VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
(VNx2HF "TARGET_VECTOR_ELEN_FP_16")
(VNx4HF "TARGET_VECTOR_ELEN_FP_16")
@@ -295,11 +296,12 @@
;; This iterator is the same as above but with TARGET_VECTOR_ELEN_FP_16
;; changed to TARGET_ZVFH. TARGET_VECTOR_ELEN_FP_16 is also true for
-;; TARGET_ZVFHMIN while we actually disable all instructions apart from
-;; load, store and convert for it.
-;; Consequently the autovec expanders should also only be enabled with
-;; TARGET_ZVFH.
-(define_mode_iterator VF_AUTO [
+;; TARGET_ZVFHMIN while we actually want to disable all instructions apart
+;; from load, store and convert for it.
+;; It is not enough to set the "enabled" attribute to false
+;; since this will only disable insn alternatives in reload but still
+;; allow the instruction and mode to be matched during combine et al.
+(define_mode_iterator VF [
(VNx1HF "TARGET_ZVFH && TARGET_MIN_VLEN < 128")
(VNx2HF "TARGET_ZVFH")
(VNx4HF "TARGET_ZVFH")
@@ -494,7 +496,8 @@
(VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128")
])
-(define_mode_iterator VWEXTF [
+;; Same iterator split reason as VF_ZVFHMIN and VF.
+(define_mode_iterator VWEXTF_ZVFHMIN [
(VNx1SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
(VNx2SF "TARGET_VECTOR_ELEN_FP_16")
(VNx4SF "TARGET_VECTOR_ELEN_FP_16")
@@ -509,13 +512,28 @@
(VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
])
+(define_mode_iterator VWEXTF [
+ (VNx1SF "TARGET_ZVFH && TARGET_MIN_VLEN < 128")
+ (VNx2SF "TARGET_ZVFH")
+ (VNx4SF "TARGET_ZVFH")
+ (VNx8SF "TARGET_ZVFH")
+ (VNx16SF "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
+ (VNx32SF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
+
+ (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128")
+ (VNx2DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx4DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
+])
+
(define_mode_iterator VWCONVERTI [
- (VNx1SI "TARGET_MIN_VLEN < 128 && TARGET_VECTOR_ELEN_FP_16")
- (VNx2SI "TARGET_VECTOR_ELEN_FP_16")
- (VNx4SI "TARGET_VECTOR_ELEN_FP_16")
- (VNx8SI "TARGET_VECTOR_ELEN_FP_16")
- (VNx16SI "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16")
- (VNx32SI "TARGET_MIN_VLEN >= 128 && TARGET_VECTOR_ELEN_FP_16")
+ (VNx1SI "TARGET_ZVFH && TARGET_MIN_VLEN < 128")
+ (VNx2SI "TARGET_ZVFH")
+ (VNx4SI "TARGET_ZVFH")
+ (VNx8SI "TARGET_ZVFH")
+ (VNx16SI "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
+ (VNx32SI "TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
(VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128")
(VNx2DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32")
@@ -531,6 +549,14 @@
(VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128")
])
+(define_mode_iterator VQEXTF [
+ (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128")
+ (VNx2DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx4DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
+])
+
(define_mode_iterator VOEXTI [
(VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64")
(VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64")
@@ -992,13 +1018,13 @@
])
(define_mode_iterator VHF [
- (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
- (VNx2HF "TARGET_VECTOR_ELEN_FP_16")
- (VNx4HF "TARGET_VECTOR_ELEN_FP_16")
- (VNx8HF "TARGET_VECTOR_ELEN_FP_16")
- (VNx16HF "TARGET_VECTOR_ELEN_FP_16")
- (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32")
- (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
+ (VNx1HF "TARGET_ZVFH && TARGET_MIN_VLEN < 128")
+ (VNx2HF "TARGET_ZVFH")
+ (VNx4HF "TARGET_ZVFH")
+ (VNx8HF "TARGET_ZVFH")
+ (VNx16HF "TARGET_ZVFH")
+ (VNx32HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
+ (VNx64HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
])
(define_mode_iterator VSF [
@@ -1042,9 +1068,9 @@
])
(define_mode_iterator VHF_LMUL1 [
- (VNx8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
- (VNx4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN == 64")
- (VNx2HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN == 32")
+ (VNx8HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
+ (VNx4HF "TARGET_ZVFH && TARGET_MIN_VLEN == 64")
+ (VNx2HF "TARGET_ZVFH && TARGET_MIN_VLEN == 32")
])
(define_mode_iterator VSF_LMUL1 [
@@ -1326,6 +1352,9 @@
(VNx16SI "VNx16QI") (VNx32SI "VNx32QI")
(VNx1DI "VNx1HI") (VNx2DI "VNx2HI")
(VNx4DI "VNx4HI") (VNx8DI "VNx8HI") (VNx16DI "VNx16HI")
+
+ (VNx1DF "VNx1HF") (VNx2DF "VNx2HF") (VNx4DF "VNx4HF") (VNx8DF "VNx8HF")
+ (VNx16DF "VNx16HF")
])
(define_mode_attr V_OCT_TRUNC [
@@ -1351,6 +1380,9 @@
(VNx16SI "vnx16qi") (VNx32SI "vnx32qi")
(VNx1DI "vnx1hi") (VNx2DI "vnx2hi") (VNx4DI "vnx4hi") (VNx8DI "vnx8hi")
(VNx16DI "vnx16hi")
+
+ (VNx1DF "vnx1hf") (VNx2DF "vnx2hf") (VNx4DF "vnx4hf") (VNx8DF "vnx8hf")
+ (VNx16DF "vnx16hf")
])
(define_mode_attr v_oct_trunc [
@@ -1421,6 +1453,14 @@
(VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI") (VNx16DF "VNx16SI")
])
+(define_mode_attr vnconvert [
+ (VNx1HF "vnx1qi") (VNx2HF "vnx2qi") (VNx4HF "vnx4qi") (VNx8HF "vnx8qi") (VNx16HF "vnx16qi") (VNx32HF "vnx32qi") (VNx64HF "vnx64qi")
+ (VNx1SF "vnx1hi") (VNx2SF "vnx2hi") (VNx4SF "vnx4hi") (VNx8SF "vnx8hi") (VNx16SF "vnx16hi") (VNx32SF "vnx32hi")
+ (VNx1SI "vnx1hf") (VNx2SI "vnx2hf") (VNx4SI "vnx4hf") (VNx8SI "vnx8hf") (VNx16SI "vnx16hf") (VNx32SI "vnx32hf")
+ (VNx1DI "vnx1sf") (VNx2DI "vnx2sf") (VNx4DI "vnx4sf") (VNx8DI "vnx8sf") (VNx16DI "vnx16sf")
+ (VNx1DF "vnx1si") (VNx2DF "vnx2si") (VNx4DF "vnx4si") (VNx8DF "vnx8si") (VNx16DF "vnx16si")
+])
+
(define_mode_attr VDEMOTE [
(VNx1DI "VNx2SI") (VNx2DI "VNx4SI")
(VNx4DI "VNx8SI") (VNx8DI "VNx16SI") (VNx16DI "VNx32SI")
@@ -1480,14 +1520,11 @@
(define_int_attr float_insn_type [(UNSPEC_VFRSQRT7 "vfsqrt") (UNSPEC_VFREC7 "vfrecp")])
-(define_int_iterator VCOPYSIGNS [UNSPEC_VCOPYSIGN UNSPEC_VNCOPYSIGN UNSPEC_VXORSIGN])
+(define_int_iterator VCOPYSIGNS [UNSPEC_VCOPYSIGN UNSPEC_VXORSIGN])
-(define_int_attr copysign [(UNSPEC_VCOPYSIGN "copysign")
- (UNSPEC_VNCOPYSIGN "ncopysign")
- (UNSPEC_VXORSIGN "xorsign")])
+(define_int_attr copysign [(UNSPEC_VCOPYSIGN "copysign") (UNSPEC_VXORSIGN "xorsign")])
-(define_int_attr nx [(UNSPEC_VCOPYSIGN "") (UNSPEC_VNCOPYSIGN "n")
- (UNSPEC_VXORSIGN "x")])
+(define_int_attr nx [(UNSPEC_VCOPYSIGN "") (UNSPEC_VXORSIGN "x")])
(define_int_attr ud [(UNSPEC_VSLIDEUP "up") (UNSPEC_VSLIDEDOWN "down")
(UNSPEC_VSLIDE1UP "1up") (UNSPEC_VSLIDE1DOWN "1down")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 884e7435..9df40e4 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -98,7 +98,12 @@
VNx2x8HI,VNx3x8HI,VNx4x8HI,VNx5x8HI,VNx6x8HI,VNx7x8HI,VNx8x8HI,\
VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI,\
VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI,\
- VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI")
+ VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI,\
+ VNx2x32HF,VNx2x16HF,VNx3x16HF,VNx4x16HF,\
+ VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF,\
+ VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF,\
+ VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF,\
+ VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF")
(const_int 16)
(eq_attr "mode" "VNx1SI,VNx2SI,VNx4SI,VNx8SI,VNx16SI,VNx32SI,\
VNx1SF,VNx2SF,VNx4SF,VNx8SF,VNx16SF,VNx32SF,\
@@ -156,17 +161,17 @@
(symbol_ref "riscv_vector::get_vlmul(E_VNx64HImode)")
; Half float point
- (eq_attr "mode" "VNx1HF")
+ (eq_attr "mode" "VNx1HF,VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF")
(symbol_ref "riscv_vector::get_vlmul(E_VNx1HFmode)")
- (eq_attr "mode" "VNx2HF")
+ (eq_attr "mode" "VNx2HF,VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF")
(symbol_ref "riscv_vector::get_vlmul(E_VNx2HFmode)")
- (eq_attr "mode" "VNx4HF")
+ (eq_attr "mode" "VNx4HF,VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF")
(symbol_ref "riscv_vector::get_vlmul(E_VNx4HFmode)")
- (eq_attr "mode" "VNx8HF")
+ (eq_attr "mode" "VNx8HF,VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF")
(symbol_ref "riscv_vector::get_vlmul(E_VNx8HFmode)")
- (eq_attr "mode" "VNx16HF")
+ (eq_attr "mode" "VNx16HF,VNx2x16HF,VNx3x16HF,VNx4x16HF")
(symbol_ref "riscv_vector::get_vlmul(E_VNx16HFmode)")
- (eq_attr "mode" "VNx32HF")
+ (eq_attr "mode" "VNx32HF,VNx2x32HF")
(symbol_ref "riscv_vector::get_vlmul(E_VNx32HFmode)")
(eq_attr "mode" "VNx64HF")
(symbol_ref "riscv_vector::get_vlmul(E_VNx64HFmode)")
@@ -249,17 +254,17 @@
(symbol_ref "riscv_vector::get_ratio(E_VNx64HImode)")
; Half float point.
- (eq_attr "mode" "VNx1HF")
+ (eq_attr "mode" "VNx1HF,VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF")
(symbol_ref "riscv_vector::get_ratio(E_VNx1HFmode)")
- (eq_attr "mode" "VNx2HF")
+ (eq_attr "mode" "VNx2HF,VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF")
(symbol_ref "riscv_vector::get_ratio(E_VNx2HFmode)")
- (eq_attr "mode" "VNx4HF")
+ (eq_attr "mode" "VNx4HF,VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF")
(symbol_ref "riscv_vector::get_ratio(E_VNx4HFmode)")
- (eq_attr "mode" "VNx8HF")
+ (eq_attr "mode" "VNx8HF,VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF")
(symbol_ref "riscv_vector::get_ratio(E_VNx8HFmode)")
- (eq_attr "mode" "VNx16HF")
+ (eq_attr "mode" "VNx16HF,VNx2x16HF,VNx3x16HF,VNx4x16HF")
(symbol_ref "riscv_vector::get_ratio(E_VNx16HFmode)")
- (eq_attr "mode" "VNx32HF")
+ (eq_attr "mode" "VNx32HF,VNx2x32HF")
(symbol_ref "riscv_vector::get_ratio(E_VNx32HFmode)")
(eq_attr "mode" "VNx64HF")
(symbol_ref "riscv_vector::get_ratio(E_VNx64HFmode)")
@@ -425,14 +430,14 @@
(eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
viwalu,viwmul,vnshift,vaalu,vsmul,vsshift,\
vnclip,vicmp,vfalu,vfmul,vfminmax,vfdiv,vfwalu,vfwmul,\
- vfsgnj,vfcmp,vfmuladd,vslideup,vslidedown,vislide1up,\
+ vfsgnj,vfcmp,vslideup,vslidedown,vislide1up,\
vislide1down,vfslide1up,vfslide1down,vgather,viwmuladd,vfwmuladd,\
vlsegds,vlsegdux,vlsegdox")
(symbol_ref "INTVAL (operands[8])")
(eq_attr "type" "vstux,vstox,vssegts,vssegtux,vssegtox")
(symbol_ref "INTVAL (operands[5])")
- (eq_attr "type" "vimuladd")
+ (eq_attr "type" "vimuladd,vfmuladd")
(symbol_ref "INTVAL (operands[9])")
(eq_attr "type" "vmsfs,vmidx,vcompress")
@@ -445,22 +450,61 @@
;; Defines rounding mode of an fixed-point operation.
(define_attr "vxrm_mode" "rnu,rne,rdn,rod,none"
- (cond [(and (eq_attr "type" "vsalu,vaalu,vsmul,vsshift,vnclip")
- (match_test "INTVAL(operands[9]) == riscv_vector::VXRM_RNU"))
- (const_string "rnu")
+ (cond
+ [
+ (eq_attr "type" "vsalu,vaalu,vsmul,vsshift,vnclip")
+ (cond
+ [
+ (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RNU")
+ (const_string "rnu")
+
+ (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RNE")
+ (const_string "rne")
- (and (eq_attr "type" "vsalu,vaalu,vsmul,vsshift,vnclip")
- (match_test "INTVAL(operands[9]) == riscv_vector::VXRM_RNE"))
- (const_string "rne")
+ (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RDN")
+ (const_string "rdn")
- (and (eq_attr "type" "vsalu,vaalu,vsmul,vsshift,vnclip")
- (match_test "INTVAL(operands[9]) == riscv_vector::VXRM_RDN"))
- (const_string "rdn")
+ (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_ROD")
+ (const_string "rod")
+ ]
+ (const_string "none")
+ )
+ ]
+ (const_string "none")
+ )
+)
- (and (eq_attr "type" "vsalu,vaalu,vsmul,vsshift,vnclip")
- (match_test "INTVAL(operands[9]) == riscv_vector::VXRM_ROD"))
- (const_string "rod")]
- (const_string "none")))
+;; Defines rounding mode of an floating-point operation.
+(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,none"
+ (cond
+ [
+ (eq_attr "type" "vfalu")
+ (cond
+ [
+ (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RNE")
+ (const_string "rne")
+
+ (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RTZ")
+ (const_string "rtz")
+
+ (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RDN")
+ (const_string "rdn")
+
+ (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RUP")
+ (const_string "rup")
+
+ (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RMM")
+ (const_string "rmm")
+
+ (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RDN")
+ (const_string "rdn")
+ ]
+ (const_string "none")
+ )
+ ]
+ (const_string "none")
+ )
+)
;; -----------------------------------------------------------------
;; ---- Miscellaneous Operations
@@ -538,6 +582,27 @@
[(set_attr "type" "wrvxrm")
(set_attr "mode" "SI")])
+;; Set FRM
+(define_insn "fsrm"
+ [
+ (set
+ (reg:SI FRM_REGNUM)
+ (unspec:SI
+ [
+ (match_operand:SI 0 "register_operand" "=&r")
+ (match_operand:SI 1 "register_operand" "r")
+ ] UNSPEC_FSRM
+ )
+ )
+ ]
+ "TARGET_VECTOR"
+ "fsrm\t%0,%1"
+ [
+ (set_attr "type" "wrfrm")
+ (set_attr "mode" "SI")
+ ]
+)
+
;; -----------------------------------------------------------------
;; ---- Moves Operations
;; -----------------------------------------------------------------
@@ -1063,6 +1128,7 @@
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
(match_operand 3 "vector_length_operand" " rK")
+ (match_operand 4 "const_int_operand" " i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(match_operand:V 2 "register_operand" " vr")
@@ -1071,7 +1137,7 @@
"vse<sew>.v\t%2,%0%p1"
[(set_attr "type" "vste")
(set_attr "mode" "<MODE>")
- (set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
+ (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))
(set_attr "vl_op_idx" "3")])
;; vlm.v/vsm.v/vmclr.m/vmset.m.
@@ -1113,6 +1179,7 @@
(unspec:VB
[(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1")
(match_operand 3 "vector_length_operand" " rK")
+ (match_operand 4 "const_int_operand" " i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(match_operand:VB 2 "register_operand" " vr")
@@ -1121,7 +1188,7 @@
"vsm.v\t%2,%0"
[(set_attr "type" "vstm")
(set_attr "mode" "<MODE>")
- (set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
+ (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))
(set_attr "vl_op_idx" "3")])
(define_insn "@pred_merge<mode>"
@@ -1351,8 +1418,8 @@
(set_attr "mode" "<MODE>")])
(define_insn "*pred_broadcast<mode>"
- [(set (match_operand:VF 0 "register_operand" "=vr, vr, vr, vr, vr, vr, vr, vr")
- (if_then_else:VF
+ [(set (match_operand:VF_ZVFHMIN 0 "register_operand" "=vr, vr, vr, vr, vr, vr, vr, vr")
+ (if_then_else:VF_ZVFHMIN
(unspec:<VM>
[(match_operand:<VM> 1 "vector_broadcast_mask_operand" "Wc1,Wc1, vm, vm,Wc1,Wc1,Wb1,Wb1")
(match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK, rK, rK, rK")
@@ -1361,9 +1428,9 @@
(match_operand 7 "const_int_operand" " i, i, i, i, i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (vec_duplicate:VF
+ (vec_duplicate:VF_ZVFHMIN
(match_operand:<VEL> 3 "direct_broadcast_operand" " f, f,Wdm,Wdm,Wdm,Wdm, f, f"))
- (match_operand:VF 2 "vector_merge_operand" "vu, 0, vu, 0, vu, 0, vu, 0")))]
+ (match_operand:VF_ZVFHMIN 2 "vector_merge_operand" "vu, 0, vu, 0, vu, 0, vu, 0")))]
"TARGET_VECTOR"
"@
vfmv.v.f\t%0,%3
@@ -1433,6 +1500,7 @@
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
(match_operand 4 "vector_length_operand" " rK")
+ (match_operand 5 "const_int_operand" " i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(unspec:V
@@ -1442,7 +1510,8 @@
"TARGET_VECTOR"
"vsse<sew>.v\t%3,%0,%z2%p1"
[(set_attr "type" "vsts")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<MODE>")
+ (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
;; -------------------------------------------------------------------------------
;; ---- Predicated indexed loads/stores
@@ -5820,6 +5889,27 @@
[(set_attr "type" "vfsgnj")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_ncopysign<mode>"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (neg:VF
+ (unspec:VF
+ [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")
+ (match_operand:VF 4 "register_operand" " vr, vr, vr, vr")] UNSPEC_VCOPYSIGN))
+ (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "vfsgnjn.vv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfsgnj")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<copysign><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
@@ -5841,6 +5931,28 @@
[(set_attr "type" "vfsgnj")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_ncopysign<mode>_scalar"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (neg:VF
+ (unspec:VF
+ [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")
+ (vec_duplicate:VF
+ (match_operand:<VEL> 4 "register_operand" " f, f, f, f"))] UNSPEC_VCOPYSIGN))
+ (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "vfsgnjn.vf\t%0,%3,%4%p1"
+ [(set_attr "type" "vfsgnj")
+ (set_attr "mode" "<MODE>")])
+
;; -------------------------------------------------------------------------------
;; ---- Predicated floating-point ternary operations
;; -------------------------------------------------------------------------------
@@ -6527,7 +6639,7 @@
[(set_attr "type" "vf<widen_binop_insn_type>")
(set_attr "mode" "<V_DOUBLE_TRUNC>")])
-(define_insn "@pred_single_widen_<plus_minus:optab><mode>"
+(define_insn "@pred_single_widen_add<mode>"
[(set (match_operand:VWEXTF 0 "register_operand" "=&vr, &vr")
(if_then_else:VWEXTF
(unspec:<VM>
@@ -6540,14 +6652,37 @@
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)
(reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
- (plus_minus:VWEXTF
+ (plus:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" " vr, vr"))
+ (match_operand:VWEXTF 3 "register_operand" " vr, vr"))
+ (match_operand:VWEXTF 2 "vector_merge_operand" " vu, 0")))]
+ "TARGET_VECTOR"
+ "vfwadd.wv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfwalu")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+(define_insn "@pred_single_widen_sub<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand" "=&vr, &vr")
+ (if_then_else:VWEXTF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (match_operand 8 "const_int_operand" " i, i")
+ (match_operand 9 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)
+ (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
+ (minus:VWEXTF
(match_operand:VWEXTF 3 "register_operand" " vr, vr")
(float_extend:VWEXTF
(match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" " vr, vr")))
(match_operand:VWEXTF 2 "vector_merge_operand" " vu, 0")))]
"TARGET_VECTOR"
- "vfw<insn>.wv\t%0,%3,%4%p1"
- [(set_attr "type" "vf<widen_binop_insn_type>")
+ "vfwsub.wv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfwalu")
(set_attr "mode" "<V_DOUBLE_TRUNC>")])
(define_insn "@pred_single_widen_<plus_minus:optab><mode>_scalar"
@@ -7106,8 +7241,8 @@
(set_attr "mode" "<VNCONVERT>")])
(define_insn "@pred_extend<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand" "=&vr, &vr")
- (if_then_else:VWEXTF
+ [(set (match_operand:VWEXTF_ZVFHMIN 0 "register_operand" "=&vr, &vr")
+ (if_then_else:VWEXTF_ZVFHMIN
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
(match_operand 4 "vector_length_operand" " rK, rK")
@@ -7116,9 +7251,9 @@
(match_operand 7 "const_int_operand" " i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (float_extend:VWEXTF
+ (float_extend:VWEXTF_ZVFHMIN
(match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" " vr, vr"))
- (match_operand:VWEXTF 2 "vector_merge_operand" " vu, 0")))]
+ (match_operand:VWEXTF_ZVFHMIN 2 "vector_merge_operand" " vu, 0")))]
"TARGET_VECTOR"
"vfwcvt.f.f.v\t%0,%3%p1"
[(set_attr "type" "vfwcvtftof")
@@ -7206,7 +7341,7 @@
(reg:SI VTYPE_REGNUM)
(reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
(float_truncate:<V_DOUBLE_TRUNC>
- (match_operand:VWEXTF 3 "register_operand" " 0, 0, 0, 0, vr, vr"))
+ (match_operand:VWEXTF_ZVFHMIN 3 "register_operand" " 0, 0, 0, 0, vr, vr"))
(match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" " vu, 0, vu, 0, vu, 0")))]
"TARGET_VECTOR"
"vfncvt.f.f.w\t%0,%3%p1"
@@ -7226,7 +7361,7 @@
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(unspec:<V_DOUBLE_TRUNC>
[(float_truncate:<V_DOUBLE_TRUNC>
- (match_operand:VWEXTF 3 "register_operand" " 0, 0, 0, 0, vr, vr"))] UNSPEC_ROD)
+ (match_operand:VWEXTF_ZVFHMIN 3 "register_operand" " 0, 0, 0, 0, vr, vr"))] UNSPEC_ROD)
(match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" " vu, 0, vu, 0, vu, 0")))]
"TARGET_VECTOR"
"vfncvt.rod.f.f.w\t%0,%3%p1"
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index ad1224e..70db5cf 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -2550,7 +2550,7 @@
}
[(set_attr "type" "vecperm")])
-(define_insn "*altivec_vupkhs<VU_char>_direct"
+(define_insn "altivec_vupkhs<VU_char>_direct"
[(set (match_operand:VP 0 "register_operand" "=v")
(unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
UNSPEC_VUNPACK_HI_SIGN_DIRECT))]
diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index d45fb13..e286bf5 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -22,7 +22,7 @@
;; load mode is DI result mode is clobber compare mode is CC extend is none
(define_insn_and_split "*ld_cmpdi_cr0_DI_clobber_CC_none"
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
- (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m")
+ (compare:CC (match_operand:DI 1 "non_update_memory_operand" "YZ")
(match_operand:DI 3 "const_m1_to_1_operand" "n")))
(clobber (match_scratch:DI 0 "=r"))]
"(TARGET_P10_FUSION)"
@@ -43,7 +43,7 @@
;; load mode is DI result mode is clobber compare mode is CCUNS extend is none
(define_insn_and_split "*ld_cmpldi_cr0_DI_clobber_CCUNS_none"
[(set (match_operand:CCUNS 2 "cc_reg_operand" "=x")
- (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m")
+ (compare:CCUNS (match_operand:DI 1 "non_update_memory_operand" "YZ")
(match_operand:DI 3 "const_0_to_1_operand" "n")))
(clobber (match_scratch:DI 0 "=r"))]
"(TARGET_P10_FUSION)"
@@ -64,7 +64,7 @@
;; load mode is DI result mode is DI compare mode is CC extend is none
(define_insn_and_split "*ld_cmpdi_cr0_DI_DI_CC_none"
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
- (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m")
+ (compare:CC (match_operand:DI 1 "non_update_memory_operand" "YZ")
(match_operand:DI 3 "const_m1_to_1_operand" "n")))
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
"(TARGET_P10_FUSION)"
@@ -85,7 +85,7 @@
;; load mode is DI result mode is DI compare mode is CCUNS extend is none
(define_insn_and_split "*ld_cmpldi_cr0_DI_DI_CCUNS_none"
[(set (match_operand:CCUNS 2 "cc_reg_operand" "=x")
- (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m")
+ (compare:CCUNS (match_operand:DI 1 "non_update_memory_operand" "YZ")
(match_operand:DI 3 "const_0_to_1_operand" "n")))
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
"(TARGET_P10_FUSION)"
@@ -104,17 +104,17 @@
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
;; load mode is SI result mode is clobber compare mode is CC extend is none
-(define_insn_and_split "*lwa_cmpdi_cr0_SI_clobber_CC_none"
+(define_insn_and_split "*lwz_cmpwi_cr0_SI_clobber_CC_none"
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
- (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m")
+ (compare:CC (match_operand:SI 1 "non_update_memory_operand" "m")
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
(clobber (match_scratch:SI 0 "=r"))]
"(TARGET_P10_FUSION)"
- "lwa%X1 %0,%1\;cmpdi %2,%0,%3"
+ "lwz%X1 %0,%1\;cmpwi %2,%0,%3"
"&& reload_completed
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
- SImode, NON_PREFIXED_DS))"
+ SImode, NON_PREFIXED_D))"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2)
(compare:CC (match_dup 0) (match_dup 3)))]
@@ -146,17 +146,17 @@
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
;; load mode is SI result mode is SI compare mode is CC extend is none
-(define_insn_and_split "*lwa_cmpdi_cr0_SI_SI_CC_none"
+(define_insn_and_split "*lwz_cmpwi_cr0_SI_SI_CC_none"
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
- (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m")
+ (compare:CC (match_operand:SI 1 "non_update_memory_operand" "m")
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
(set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
"(TARGET_P10_FUSION)"
- "lwa%X1 %0,%1\;cmpdi %2,%0,%3"
+ "lwz%X1 %0,%1\;cmpwi %2,%0,%3"
"&& reload_completed
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
- SImode, NON_PREFIXED_DS))"
+ SImode, NON_PREFIXED_D))"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2)
(compare:CC (match_dup 0) (match_dup 3)))]
@@ -190,7 +190,7 @@
;; load mode is SI result mode is EXTSI compare mode is CC extend is sign
(define_insn_and_split "*lwa_cmpdi_cr0_SI_EXTSI_CC_sign"
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
- (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m")
+ (compare:CC (match_operand:SI 1 "non_update_memory_operand" "YZ")
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") (sign_extend:EXTSI (match_dup 1)))]
"(TARGET_P10_FUSION)"
@@ -205,6 +205,7 @@
""
[(set_attr "type" "fused_load_cmpi")
(set_attr "cost" "8")
+ (set_attr "sign_extend" "yes")
(set_attr "length" "8")])
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 82e8f86..4d1f825 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -61,20 +61,31 @@ sub gen_ld_cmpi_p10_one
my $mempred = "non_update_memory_operand";
my $extend;
+ # We need to special case lwa. The prefixed_load_p function in rs6000.cc
+ # (which determines if a load instruction is prefixed) uses the fact that the
+ # register mode is different from the memory mode, and that the sign_extend
+ # attribute is set to use DS-form rules for the address instead of D-form.
+ # If the register size is the same, prefixed_load_p assumes we are doing a
+ # lwz. We change to use an lwz and word compare if we don't need to sign
+ # extend the SImode value. Otherwise if we need the value, we need to
+ # make sure the insn is marked as ds-form.
+ my $cmp_size_char = ($lmode eq "SI"
+ && $ccmode eq "CC"
+ && $result !~ /^EXT|^DI$/) ? "w" : "d";
+
if ($ccmode eq "CC") {
# ld and lwa are both DS-FORM.
- ($lmode =~ /^[SD]I$/) and $np = "NON_PREFIXED_DS";
- ($lmode =~ /^[SD]I$/) and $mempred = "ds_form_mem_operand";
+ ($lmode eq "DI") and $np = "NON_PREFIXED_DS";
+ ($lmode eq "SI" && $cmp_size_char eq "d") and $np = "NON_PREFIXED_DS";
} else {
if ($lmode eq "DI") {
# ld is DS-form, but lwz is not.
$np = "NON_PREFIXED_DS";
- $mempred = "ds_form_mem_operand";
}
}
my $cmpl = ($ccmode eq "CC") ? "" : "l";
- my $echr = ($ccmode eq "CC") ? "a" : "z";
+ my $echr = ($ccmode eq "CC" && $cmp_size_char eq "d") ? "a" : "z";
if ($lmode eq "DI") { $echr = ""; }
my $constpred = ($ccmode eq "CC") ? "const_m1_to_1_operand"
: "const_0_to_1_operand";
@@ -91,12 +102,15 @@ sub gen_ld_cmpi_p10_one
}
my $ldst = mode_to_ldst_char($lmode);
+
+ # DS-form addresses need YZ, and not m.
+ my $constraint = ($np eq "NON_PREFIXED_DS") ? "YZ" : "m";
print <<HERE;
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
;; load mode is $lmode result mode is $result compare mode is $ccmode extend is $extend
-(define_insn_and_split "*l${ldst}${echr}_cmp${cmpl}di_cr0_${lmode}_${result}_${ccmode}_${extend}"
+(define_insn_and_split "*l${ldst}${echr}_cmp${cmpl}${cmp_size_char}i_cr0_${lmode}_${result}_${ccmode}_${extend}"
[(set (match_operand:${ccmode} 2 "cc_reg_operand" "=x")
- (compare:${ccmode} (match_operand:${lmode} 1 "${mempred}" "m")
+ (compare:${ccmode} (match_operand:${lmode} 1 "${mempred}" "${constraint}")
HERE
print " " if $ccmode eq "CCUNS";
print <<HERE;
@@ -119,7 +133,7 @@ HERE
print <<HERE;
"(TARGET_P10_FUSION)"
- "l${ldst}${echr}%X1 %0,%1\\;cmp${cmpl}di %2,%0,%3"
+ "l${ldst}${echr}%X1 %0,%1\\;cmp${cmpl}${cmp_size_char}i %2,%0,%3"
"&& reload_completed
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
@@ -140,6 +154,15 @@ HERE
""
[(set_attr "type" "fused_load_cmpi")
(set_attr "cost" "8")
+HERE
+
+ if ($lmode eq "SI" && $ccmode eq "CC" && $cmp_size_char eq "d") {
+ # prefixed_load_p needs the sign_extend attribute to validate lwa as a
+ # DS-form instruction instead of D-form.
+ print " (set_attr \"sign_extend\" \"yes\")\n";
+ }
+
+ print <<HERE
(set_attr "length" "8")])
HERE
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index a16ee30..8479331 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -694,6 +694,12 @@
return num_insns > 1;
})
+;; Return true if the operand is a constant that can be loaded with a vspltisw
+;; instruction and then a vupkhsw instruction.
+
+(define_predicate "vspltisw_vupkhsw_constant_split"
+ (and (match_code "const_vector")
+ (match_test "vspltisw_vupkhsw_constant_p (op, mode)")))
;; Return 1 if the operand is constant that can loaded directly with a XXSPLTIB
;; instruction.
@@ -742,6 +748,11 @@
&& xxspltib_constant_p (op, mode, &num_insns, &value))
return true;
+ /* V2DI constant within RANGE (-16, 15) can be synthesized with a
+ vspltisw and a vupkhsw. */
+ if (vspltisw_vupkhsw_constant_p (op, mode, &value))
+ return true;
+
return easy_altivec_constant (op, mode);
}
@@ -1125,20 +1136,6 @@
return INTVAL (offset) % 4 == 0;
})
-;; Return 1 if the operand is a memory operand that has a valid address for
-;; a DS-form instruction. I.e. the address has to be either just a register,
-;; or register + const where the two low order bits of const are zero.
-(define_predicate "ds_form_mem_operand"
- (match_code "subreg,mem")
-{
- if (!any_memory_operand (op, mode))
- return false;
-
- rtx addr = XEXP (op, 0);
-
- return address_to_insn_form (addr, mode, NON_PREFIXED_DS) == INSN_FORM_DS;
-})
-
;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.
(define_predicate "symbol_ref_operand"
(and (match_code "symbol_ref")
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 9a4cc18..f70118e 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -32,6 +32,7 @@ extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int,
extern int easy_altivec_constant (rtx, machine_mode);
extern bool xxspltib_constant_p (rtx, machine_mode, int *, int *);
+extern bool vspltisw_vupkhsw_constant_p (rtx, machine_mode, int * = nullptr);
extern int vspltis_shifted (rtx);
extern HOST_WIDE_INT const_vector_elt_as_int (rtx, unsigned int);
extern bool macho_lo_sum_memory_operand (rtx, machine_mode);
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 546c353..07c3a3d 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -6642,6 +6642,36 @@ xxspltib_constant_p (rtx op,
return true;
}
+/* Return true if OP mode is V2DI and can be synthesized with ISA 2.07
+ instructions vupkhsw and vspltisw.
+
+ Return the constant that is being split via CONSTANT_PTR. */
+
+bool
+vspltisw_vupkhsw_constant_p (rtx op, machine_mode mode, int *constant_ptr)
+{
+ HOST_WIDE_INT value;
+ rtx elt;
+
+ if (!TARGET_P8_VECTOR)
+ return false;
+
+ if (mode != V2DImode)
+ return false;
+
+ if (!const_vec_duplicate_p (op, &elt))
+ return false;
+
+ value = INTVAL (elt);
+ if (value == 0 || value == 1
+ || !EASY_VECTOR_15 (value))
+ return false;
+
+ if (constant_ptr)
+ *constant_ptr = (int) value;
+ return true;
+}
+
const char *
output_vec_const_move (rtx *operands)
{
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index b0db8ae..cdab49f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -287,7 +287,7 @@
;; Whether this insn has a prefixed form and a non-prefixed form.
(define_attr "maybe_prefixed" "no,yes"
(if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
- integer,add")
+ integer,add,fused_load_cmpi")
(const_string "yes")
(const_string "no")))
@@ -302,7 +302,7 @@
(eq_attr "maybe_prefixed" "no"))
(const_string "no")
- (eq_attr "type" "load,fpload,vecload")
+ (eq_attr "type" "load,fpload,vecload,fused_load_cmpi")
(if_then_else (match_test "prefixed_load_p (insn)")
(const_string "yes")
(const_string "no"))
@@ -491,6 +491,7 @@
; The size of a pointer. Also, the size of the value that a record-condition
; (one with a '.') will compare; and the size used for arithmetic carries.
(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
+(define_mode_iterator WORD [(SI "!TARGET_POWERPC64") (DI "TARGET_POWERPC64")])
; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
; PTImode is GPR only)
@@ -7879,9 +7880,9 @@
(define_insn "*mov<mode>_internal2"
[(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
- (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
+ (compare:CC (match_operand:WORD 1 "gpc_reg_operand" "0,r,r")
(const_int 0)))
- (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
+ (set (match_operand:WORD 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
""
"@
cmp<wd>i %2,%0,0
@@ -7891,11 +7892,41 @@
(set_attr "dot" "yes")
(set_attr "length" "4,4,8")])
+(define_peephole2
+ [(set (match_operand:CC 2 "cc_reg_operand")
+ (compare:CC (match_operand:WORD 1 "int_reg_operand")
+ (const_int 0)))
+ (set (match_operand:WORD 0 "int_reg_operand")
+ (match_dup 1))]
+ "!cc_reg_not_cr0_operand (operands[2], CCmode)"
+ [(parallel [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (match_operand:WORD 1 "int_reg_operand" "r")
+ (const_int 0)))
+ (set (match_operand:WORD 0 "int_reg_operand" "=r")
+ (match_dup 1))])]
+ ""
+)
+
+(define_peephole2
+ [(set (match_operand:WORD 0 "int_reg_operand")
+ (match_operand:WORD 1 "int_reg_operand"))
+ (set (match_operand:CC 2 "cc_reg_operand")
+ (compare:CC (match_dup 1)
+ (const_int 0)))]
+ "!cc_reg_not_cr0_operand (operands[2], CCmode)"
+ [(parallel [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (match_operand:GPR 1 "int_reg_operand" "r")
+ (const_int 0)))
+ (set (match_operand:WORD 0 "int_reg_operand" "=r")
+ (match_dup 1))])]
+ ""
+)
+
(define_split
[(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
- (compare:CC (match_operand:P 1 "gpc_reg_operand")
+ (compare:CC (match_operand:WORD 1 "gpc_reg_operand")
(const_int 0)))
- (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
+ (set (match_operand:WORD 0 "gpc_reg_operand") (match_dup 1))]
"reload_completed"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2)
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index e017381..0c269e4 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -1177,6 +1177,30 @@
[(set_attr "type" "vecperm")
(set_attr "length" "8")])
+(define_insn_and_split "*vspltisw_v2di_split"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (match_operand:V2DI 1 "vspltisw_vupkhsw_constant_split" "W"))]
+ "TARGET_P8_VECTOR && vspltisw_vupkhsw_constant_split (operands[1], V2DImode)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx tmp = can_create_pseudo_p ()
+ ? gen_reg_rtx (V4SImode)
+ : gen_lowpart (V4SImode, op0);
+ int value;
+
+ vspltisw_vupkhsw_constant_p (op1, V2DImode, &value);
+ emit_insn (gen_altivec_vspltisw (tmp, GEN_INT (value)));
+ emit_insn (gen_altivec_vupkhsw_direct (op0, tmp));
+
+ DONE;
+}
+ [(set_attr "type" "vecperm")
+ (set_attr "length" "8")])
+
;; Prefer using vector registers over GPRs. Prefer using ISA 3.0's XXSPLTISB
;; or Altivec VSPLITW 0/-1 over XXLXOR/XXLORC to set a register to all 0's or
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 9284477..d9f10542 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -13706,8 +13706,10 @@ s390_encode_section_info (tree decl, rtx rtl, int first)
{
/* Store the alignment to be able to check if we can use
a larl/load-relative instruction. We only handle the cases
- that can go wrong (i.e. no FUNC_DECLs). */
- if (DECL_ALIGN (decl) == 0 || DECL_ALIGN (decl) % 16)
+ that can go wrong (i.e. no FUNC_DECLs).
+ All symbols without an explicit alignment are assumed to be 2
+ byte aligned as mandated by our ABI. */
+ if (DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) % 16)
SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
else if (DECL_ALIGN (decl) % 32)
SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index dd35e63..992e80d 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -107,7 +107,7 @@ struct GTY(()) machine_function
bool epilogue_done;
bool inhibit_logues_a1_adjusts;
rtx last_logues_a9_content;
- HOST_WIDE_INT eliminated_callee_saved_bmp;
+ HARD_REG_SET eliminated_callee_saved;
};
static void xtensa_option_override (void);
@@ -2649,11 +2649,8 @@ xtensa_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm, rtx scratch,
bool
xtensa_match_CLAMPS_imms_p (rtx cst_max, rtx cst_min)
{
- int max, min;
-
- return IN_RANGE (max = exact_log2 (-INTVAL (cst_max)), 7, 22)
- && IN_RANGE (min = exact_log2 (INTVAL (cst_min) + 1), 7, 22)
- && max == min;
+ return IN_RANGE (exact_log2 (-INTVAL (cst_max)), 7, 22)
+ && (INTVAL (cst_max) + INTVAL (cst_min)) == -1;
}
@@ -3589,7 +3586,8 @@ xtensa_expand_prologue (void)
df_insn_rescan (insnS);
SET_SRC (PATTERN (insnR)) = copy_rtx (mem);
df_insn_rescan (insnR);
- cfun->machine->eliminated_callee_saved_bmp |= 1 << regno;
+ SET_HARD_REG_BIT (cfun->machine->eliminated_callee_saved,
+ regno);
}
else
{
@@ -3693,8 +3691,8 @@ xtensa_expand_epilogue (bool sibcall_p)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
if (xtensa_call_save_reg(regno))
{
- if (! (cfun->machine->eliminated_callee_saved_bmp
- & (1 << regno)))
+ if (! TEST_HARD_REG_BIT (cfun->machine->eliminated_callee_saved,
+ regno))
{
rtx x = gen_rtx_PLUS (Pmode,
stack_pointer_rtx, GEN_INT (offset));
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 4b4ab3f..5386e45 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -522,7 +522,7 @@
(smax:SI (smin:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:SI 3 "const_int_operand" "i")))]
- "TARGET_CLAMPS
+ "TARGET_MINMAX && TARGET_CLAMPS
&& xtensa_match_CLAMPS_imms_p (operands[3], operands[2])"
"#"
"&& 1"
@@ -540,7 +540,7 @@
(smin:SI (smax:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:SI 3 "const_int_operand" "i")))]
- "TARGET_CLAMPS
+ "TARGET_MINMAX && TARGET_CLAMPS
&& xtensa_match_CLAMPS_imms_p (operands[2], operands[3])"
{
static char result[64];
@@ -3191,7 +3191,7 @@
(define_insn_and_split "*eqne_INT_MIN"
[(set (match_operand:SI 0 "register_operand" "=a")
- (match_operator 2 "boolean_operator"
+ (match_operator:SI 2 "boolean_operator"
[(match_operand:SI 1 "register_operand" "r")
(const_int -2147483648)]))]
"TARGET_ABS"
@@ -3240,15 +3240,14 @@
(set (match_dup 3)
(match_dup 7))]
{
- uint32_t check = 0;
+ HARD_REG_SET regs;
int i;
+ CLEAR_HARD_REG_SET (regs);
for (i = 0; i <= 3; ++i)
- {
- uint32_t mask = (uint32_t)1 << REGNO (operands[i]);
- if (check & mask)
- FAIL;
- check |= mask;
- }
+ if (TEST_HARD_REG_BIT (regs, REGNO (operands[i])))
+ FAIL;
+ else
+ SET_HARD_REG_BIT (regs, REGNO (operands[i]));
operands[6] = gen_rtx_MEM (SFmode, XEXP (operands[6], 0));
operands[7] = gen_rtx_MEM (SFmode, XEXP (operands[7], 0));
})
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7230564..76fbc80 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,109 @@
+2023-06-30 Patrick Palka <ppalka@redhat.com>
+
+ * cp-tree.h (TEMPLATE_PARM_DESCENDANTS): Harden.
+ (TEMPLATE_TYPE_DESCENDANTS): Define.
+ (TEMPLATE_TEMPLATE_PARM_SIMPLE_P): Define.
+ * pt.cc (reduce_template_parm_level): Revert
+ r14-418-g0bc2a1dc327af9 change.
+ (process_template_parm): Set TEMPLATE_TEMPLATE_PARM_SIMPLE_P
+ appropriately.
+ (uses_outer_template_parms): Determine the outer depth of
+ a template template parm without relying on DECL_CONTEXT.
+ (tsubst) <case TEMPLATE_TEMPLATE_PARM>: Cache lowering a
+ simple template template parm. Consistently use 'code'.
+
+2023-06-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/110468
+ * init.cc (maybe_instantiate_nsdmi_init): Mask out all
+ tsubst flags except for tf_warning_or_error.
+
+2023-06-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/110463
+ * cp-gimplify.cc (cp_fold) <case CONSTRUCTOR>: Propagate
+ CONSTRUCTOR_MUTABLE_POISON.
+
+2023-06-29 Patrick Palka <ppalka@redhat.com>
+
+ * cp-tree.h (tree_template_info::partial): New data member.
+ (TI_PARTIAL_INFO): New tree accessor.
+ (most_specialized_partial_spec): Add defaulted bool parameter.
+ * module.cc (trees_out::core_vals) <case TEMPLATE_INFO>: Stream
+ TI_PARTIAL_INFO.
+ (trees_in::core_vals) <case TEMPLATE_INFO>: Likewise.
+ * parser.cc (specialization_of): Adjust after making
+ most_specialized_partial_spec return TEMPLATE_INFO instead
+ of TREE_LIST.
+ * pt.cc (process_partial_specialization): Set TI_PARTIAL_INFO
+ of 'decl' to point back to the partial TEMPLATE_DECL. Likewise
+ (and pass rechecking=true to most_specialization_partial_spec).
+ (instantiate_class_template): Likewise.
+ (instantiate_template): Set TI_PARTIAL_INFO to the result of
+ most_specialization_partial_spec after forming a variable
+ template specialization.
+ (most_specialized_partial_spec): Add 'rechecking' parameter.
+ Exit early if the template is not primary. Use the TI_PARTIAL_INFO
+ of the corresponding TEMPLATE_INFO as a cache unless 'rechecking'
+ is true. Don't bother setting TREE_TYPE of each TREE_LIST.
+ (instantiate_decl): Adjust after making
+ most_specialized_partial_spec return TEMPLATE_INFO instead of
+ TREE_LIST.
+ * ptree.cc (cxx_print_xnode) <case TEMPLATE_INFO>: Dump
+ TI_PARTIAL_INFO.
+
+2023-06-29 Eugene Rozenfeld <erozen@microsoft.com>
+
+ * Make-lang.in: Pass correct stage cc1plus when processing
+ profile data collected while building target libraries
+
+2023-06-28 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/89442
+ PR c++/107437
+ * cp-tree.h (lookup_template_variable): Add complain parameter.
+ * parser.cc (cp_parser_template_id): Pass tf_warning_or_error
+ to lookup_template_variable.
+ * pt.cc (lookup_template_variable): Add complain parameter.
+ Coerce template arguments here ...
+ (finish_template_variable): ... instead of here.
+ (lookup_and_finish_template_variable): Check for error_mark_node
+ result from lookup_template_variable.
+ (tsubst_copy) <case TEMPLATE_ID_EXPR>: Pass complain to
+ lookup_template_variable.
+ (instantiate_template): Use build2 instead of
+ lookup_template_variable to build a TEMPLATE_ID_EXPR
+ for most_specialized_partial_spec.
+
+2023-06-28 Marek Polacek <polacek@redhat.com>
+
+ PR c++/110175
+ * typeck.cc (cp_build_unary_op): Check tf_warning before warning.
+
+2023-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/110334
+ * cp-tree.h (clone_attrs): Declare.
+ * method.cc (implicitly_declare_fn): Use it for inherited
+ constructor.
+ * optimize.cc (clone_attrs): New.
+ (maybe_clone_body): Use it.
+
+2023-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/110344
+ * constexpr.cc (cxx_eval_constant_expression): In C++26, allow cast
+ from void* to the type of a pointed-to object.
+
+2023-06-23 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/110164
+ * cp-name-hint.h (maybe_suggest_missing_header): New decl.
+ * decl.cc: Define INCLUDE_MEMORY. Add include of
+ "cp/cp-name-hint.h".
+ (start_decl_1): Call maybe_suggest_missing_header.
+ * name-lookup.cc (maybe_suggest_missing_header): Remove "static".
+
2023-06-16 Alex Coplan <alex.coplan@arm.com>
* parser.cc (cp_parser_enum_specifier): Don't reject
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index c08ee91..ba5e876 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -211,10 +211,10 @@ create_fdas_for_cc1plus: ../stage1-gcc/cc1plus$(exeext) ../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=cc1plus_$$component_in_prev_target.fda; \
- $(CREATE_GCOV) -binary ../stage1-gcc/cc1plus$(exeext) -gcov $$profile_name -profile $$perf_path -gcov_version 2; \
+ $(CREATE_GCOV) -binary ../prev-gcc/cc1plus$(exeext) -gcov $$profile_name -profile $$perf_path -gcov_version 2; \
fi; \
done;
-#
+#
# Build hooks:
c++.all.cross: g++-cross$(exeext)
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 432b3a2..cca0435 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -7681,6 +7681,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
&& !is_std_construct_at (ctx->call)
&& !is_std_allocator_allocate (ctx->call))
{
+ /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
+ cv void" to a pointer-to-object type T unless P points to an
+ object whose type is similar to T. */
+ if (cxx_dialect > cxx23)
+ if (tree ob
+ = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), op))
+ {
+ r = build1 (ADDR_EXPR, type, ob);
+ break;
+ }
+
/* Likewise, don't error when casting from void* when OP is
&heap uninit and similar. */
tree sop = tree_strip_nop_conversions (op);
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 853b1e4..f573419 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -3079,6 +3079,8 @@ cp_fold (tree x, fold_flags_t flags)
x = build_constructor (TREE_TYPE (x), nelts);
CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
= CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
+ CONSTRUCTOR_MUTABLE_POISON (x)
+ = CONSTRUCTOR_MUTABLE_POISON (org_x);
}
if (VECTOR_TYPE_P (TREE_TYPE (x)))
x = fold (x);
diff --git a/gcc/cp/cp-name-hint.h b/gcc/cp/cp-name-hint.h
index bfa7c53..7693980 100644
--- a/gcc/cp/cp-name-hint.h
+++ b/gcc/cp/cp-name-hint.h
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
extern name_hint suggest_alternatives_for (location_t, tree, bool);
extern name_hint suggest_alternatives_in_other_namespaces (location_t, tree);
+extern name_hint maybe_suggest_missing_header (location_t, tree, tree);
extern name_hint suggest_alternative_in_explicit_scope (location_t, tree, tree);
extern name_hint suggest_alternative_in_scoped_enum (tree, tree);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8398223..3de0e15 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -528,6 +528,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE)
ENUM_FIXED_UNDERLYING_TYPE_P (in ENUMERAL_TYPE)
AUTO_IS_DECLTYPE (in TEMPLATE_TYPE_PARM)
+ TEMPLATE_TEMPLATE_PARM_SIMPLE_P (in TEMPLATE_TEMPLATE_PARM)
6: TYPE_DEPENDENT_P_VALID
Usage of DECL_LANG_FLAG_?:
@@ -1564,6 +1565,7 @@ struct GTY(()) tree_template_info {
struct tree_base base;
tree tmpl;
tree args;
+ tree partial;
vec<deferred_access_check, va_gc> *deferred_access_checks;
};
@@ -3755,6 +3757,14 @@ struct GTY(()) lang_decl {
((struct tree_template_info*)TEMPLATE_INFO_CHECK (NODE))->args
#define TI_PENDING_TEMPLATE_FLAG(NODE) \
TREE_LANG_FLAG_1 (TEMPLATE_INFO_CHECK (NODE))
+
+/* For a class or variable template specialization, this contains the
+ TEMPLATE_INFO result of most_specialized_partial_spec, i.e. the selected
+ partial template specialization and arguments relative to it. */
+#define TI_PARTIAL_INFO(NODE) \
+ (gcc_checking_assert (PRIMARY_TEMPLATE_P (TI_TEMPLATE (NODE))), \
+ ((struct tree_template_info*)NODE)->partial)
+
/* For a given TREE_VEC containing a template argument list,
this property contains the number of arguments that are not
defaulted. */
@@ -6004,7 +6014,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
((template_parm_index*)TEMPLATE_PARM_INDEX_CHECK (NODE))
#define TEMPLATE_PARM_IDX(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->index)
#define TEMPLATE_PARM_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->level)
-#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE))
+#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (TEMPLATE_PARM_INDEX_CHECK (NODE)))
#define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
#define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
#define TEMPLATE_PARM_PARAMETER_PACK(NODE) \
@@ -6022,6 +6032,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
(TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
#define TEMPLATE_TYPE_ORIG_LEVEL(NODE) \
(TEMPLATE_PARM_ORIG_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+#define TEMPLATE_TYPE_DESCENDANTS(NODE) \
+ (TEMPLATE_PARM_DESCENDANTS (TEMPLATE_TYPE_PARM_INDEX (NODE)))
#define TEMPLATE_TYPE_DECL(NODE) \
(TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
#define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \
@@ -6031,6 +6043,11 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
#define CLASS_PLACEHOLDER_TEMPLATE(NODE) \
(DECL_INITIAL (TYPE_NAME (TEMPLATE_TYPE_PARM_CHECK (NODE))))
+/* True iff the template parameters of this TEMPLATE_TEMPLATE_PARM don't
+ use any outer template parameters. */
+#define TEMPLATE_TEMPLATE_PARM_SIMPLE_P(NODE) \
+ (TYPE_LANG_FLAG_5 (TEMPLATE_TEMPLATE_PARM_CHECK (NODE)))
+
/* Contexts in which auto deduction occurs. These flags are
used to control diagnostics in do_auto_deduction. */
@@ -7282,6 +7299,7 @@ extern void module_preprocess_options (cpp_reader *);
extern bool handle_module_option (unsigned opt, const char *arg, int value);
/* In optimize.cc */
+extern tree clone_attrs (tree);
extern bool maybe_clone_body (tree);
/* In parser.cc */
@@ -7357,7 +7375,7 @@ extern bool redeclare_class_template (tree, tree, tree);
extern tree lookup_template_class (tree, tree, tree, tree,
int, tsubst_flags_t);
extern tree lookup_template_function (tree, tree);
-extern tree lookup_template_variable (tree, tree);
+extern tree lookup_template_variable (tree, tree, tsubst_flags_t);
extern bool uses_template_parms (tree);
extern bool uses_template_parms_level (tree, int);
extern bool uses_outer_template_parms_in_constraints (tree);
@@ -7397,7 +7415,7 @@ extern bool comp_template_args (tree, tree, tree * = NULL,
extern int template_args_equal (tree, tree, bool = false);
extern tree maybe_process_partial_specialization (tree);
extern tree most_specialized_instantiation (tree);
-extern tree most_specialized_partial_spec (tree, tsubst_flags_t);
+extern tree most_specialized_partial_spec (tree, tsubst_flags_t, bool = false);
extern void print_candidates (tree);
extern void instantiate_pending_templates (int);
extern tree tsubst_default_argument (tree, int, tree, tree,
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index c07a4a8..60f107d 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
line numbers. For example, the CONST_DECLs for enum values. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "target.h"
@@ -46,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-objc.h"
#include "c-family/c-pragma.h"
#include "c-family/c-ubsan.h"
+#include "cp/cp-name-hint.h"
#include "debug.h"
#include "plugin.h"
#include "builtins.h"
@@ -5995,7 +5997,11 @@ start_decl_1 (tree decl, bool initialized)
; /* An auto type is ok. */
else if (TREE_CODE (type) != ARRAY_TYPE)
{
+ auto_diagnostic_group d;
error ("variable %q#D has initializer but incomplete type", decl);
+ maybe_suggest_missing_header (input_location,
+ TYPE_IDENTIFIER (type),
+ CP_TYPE_CONTEXT (type));
type = TREE_TYPE (decl) = error_mark_node;
}
else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
@@ -6011,8 +6017,12 @@ start_decl_1 (tree decl, bool initialized)
gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (type));
else
{
+ auto_diagnostic_group d;
error ("aggregate %q#D has incomplete type and cannot be defined",
decl);
+ maybe_suggest_missing_header (input_location,
+ TYPE_IDENTIFIER (type),
+ CP_TYPE_CONTEXT (type));
/* Change the type so that assemble_variable will give
DECL an rtl we can live with: (mem (const_int 0)). */
type = TREE_TYPE (decl) = error_mark_node;
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index af6e30f..ff5014c 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -579,6 +579,10 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
/* tsubst_decl uses void_node to indicate an uninstantiated DMI. */
if (init == void_node)
{
+ /* Clear any special tsubst flags; the result of NSDMI instantiation
+ should be independent of the substitution context. */
+ complain &= tf_warning_or_error;
+
init = DECL_INITIAL (DECL_TI_TEMPLATE (member));
location_t expr_loc
= cp_expr_loc_or_loc (init, DECL_SOURCE_LOCATION (member));
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 91cf943..8ed967d 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -3294,6 +3294,8 @@ implicitly_declare_fn (special_function_kind kind, tree type,
/* Copy constexpr from the inherited constructor even if the
inheriting constructor doesn't satisfy the requirements. */
constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
+ /* Also copy any attributes. */
+ DECL_ATTRIBUTES (fn) = clone_attrs (DECL_ATTRIBUTES (inherited_ctor));
}
/* Add the "this" parameter. */
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ecde98d..ea362bd 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6364,6 +6364,7 @@ trees_out::core_vals (tree t)
{
WT (((lang_tree_node *)t)->template_info.tmpl);
WT (((lang_tree_node *)t)->template_info.args);
+ WT (((lang_tree_node *)t)->template_info.partial);
const auto *ac = (((lang_tree_node *)t)
->template_info.deferred_access_checks);
@@ -6851,6 +6852,7 @@ trees_in::core_vals (tree t)
case TEMPLATE_INFO:
RT (((lang_tree_node *)t)->template_info.tmpl);
RT (((lang_tree_node *)t)->template_info.args);
+ RT (((lang_tree_node *)t)->template_info.partial);
if (unsigned len = u ())
{
auto &ac = (((lang_tree_node *)t)
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 53b6870..7456518 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -6796,7 +6796,7 @@ maybe_suggest_missing_std_header (location_t location, tree name)
for NAME within SCOPE at LOCATION, or an empty name_hint if this isn't
applicable. */
-static name_hint
+name_hint
maybe_suggest_missing_header (location_t location, tree name, tree scope)
{
if (scope == NULL_TREE)
diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc
index f73d86b..9e8926e 100644
--- a/gcc/cp/optimize.cc
+++ b/gcc/cp/optimize.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "tree-inline.h"
#include "tree-iterator.h"
+#include "attribs.h"
/* Prototypes. */
@@ -446,6 +447,29 @@ maybe_thunk_body (tree fn, bool force)
return 1;
}
+/* Copy most attributes from ATTRS, omitting attributes that can really only
+ apply to a single decl. */
+
+tree
+clone_attrs (tree attrs)
+{
+ tree new_attrs = NULL_TREE;
+ tree *p = &new_attrs;
+
+ for (tree a = attrs; a; a = TREE_CHAIN (a))
+ {
+ tree aname = get_attribute_name (a);
+ if (is_attribute_namespace_p ("", a)
+ && (is_attribute_p ("alias", aname)
+ || is_attribute_p ("ifunc", aname)))
+ continue;
+ *p = copy_node (a);
+ p = &TREE_CHAIN (*p);
+ }
+ *p = NULL_TREE;
+ return new_attrs;
+}
+
/* FN is a function that has a complete body. Clone the body as
necessary. Returns nonzero if there's no longer any need to
process the main body. */
@@ -503,7 +527,7 @@ maybe_clone_body (tree fn)
DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
- DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
+ DECL_ATTRIBUTES (clone) = clone_attrs (DECL_ATTRIBUTES (fn));
DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
set_decl_section_name (clone, fn);
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index dd3665c8..5e2b5cb 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -18525,7 +18525,7 @@ cp_parser_template_id (cp_parser *parser,
}
else if (variable_template_p (templ))
{
- template_id = lookup_template_variable (templ, arguments);
+ template_id = lookup_template_variable (templ, arguments, tf_warning_or_error);
if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
SET_EXPR_LOCATION (template_id, combined_loc);
}
@@ -34352,9 +34352,9 @@ specialization_of (tree type)
/* Determine the template or its partial specialization to which TYPE
corresponds. */
- if (tree spec = most_specialized_partial_spec (type, tf_none))
- if (spec != error_mark_node)
- ret = TREE_TYPE (TREE_VALUE (spec));
+ if (tree ti = most_specialized_partial_spec (type, tf_none))
+ if (ti != error_mark_node)
+ ret = TREE_TYPE (TI_TEMPLATE (ti));
if (ret == type)
ret = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (type);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 2345a18..d7d774f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -220,6 +220,7 @@ static tree enclosing_instantiation_of (tree tctx);
static void instantiate_body (tree pattern, tree args, tree d, bool nested);
static tree maybe_dependent_member_ref (tree, tree, tsubst_flags_t, tree);
static void mark_template_arguments_used (tree, tree);
+static bool uses_outer_template_parms (tree);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
@@ -4540,12 +4541,7 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
|| (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
!= TEMPLATE_PARM_LEVEL (index) - levels)
- || !(TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
- ? (comp_template_parms
- (DECL_TEMPLATE_PARMS (TYPE_NAME (type)),
- DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL
- (TEMPLATE_PARM_DESCENDANTS (index)))))
- : same_type_p (type, TREE_TYPE (TEMPLATE_PARM_DESCENDANTS (index)))))
+ || !same_type_p (type, TREE_TYPE (TEMPLATE_PARM_DESCENDANTS (index))))
{
tree orig_decl = TEMPLATE_PARM_DECL (index);
@@ -4708,6 +4704,10 @@ process_template_parm (tree list, location_t parm_loc, tree parm,
DECL_ARTIFICIAL (decl) = 1;
SET_DECL_TEMPLATE_PARM_P (decl);
+ if (TREE_CODE (parm) == TEMPLATE_DECL
+ && !uses_outer_template_parms (parm))
+ TEMPLATE_TEMPLATE_PARM_SIMPLE_P (TREE_TYPE (parm)) = true;
+
/* Build requirements for the type/template parameter.
This must be done after SET_DECL_TEMPLATE_PARM_P or
process_template_parm could fail. */
@@ -5410,6 +5410,9 @@ process_partial_specialization (tree decl)
= tree_cons (specargs, tmpl,
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
+ /* Link the DECL_TEMPLATE_RESULT back to the partial TEMPLATE_DECL. */
+ gcc_checking_assert (!TI_PARTIAL_INFO (tinfo));
+ TI_PARTIAL_INFO (tinfo) = build_template_info (tmpl, NULL_TREE);
for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst;
inst = TREE_CHAIN (inst))
@@ -5420,16 +5423,17 @@ process_partial_specialization (tree decl)
&& CLASSTYPE_IMPLICIT_INSTANTIATION (instance))
: DECL_TEMPLATE_INSTANTIATION (instance))
{
- tree spec = most_specialized_partial_spec (instance, tf_none);
+ tree partial_ti = most_specialized_partial_spec (instance, tf_none,
+ /*rechecking=*/true);
tree inst_decl = (DECL_P (instance)
? instance : TYPE_NAME (instance));
- if (!spec)
+ if (!partial_ti)
/* OK */;
- else if (spec == error_mark_node)
+ else if (partial_ti == error_mark_node)
permerror (input_location,
"declaration of %qD ambiguates earlier template "
"instantiation for %qD", decl, inst_decl);
- else if (TREE_VALUE (spec) == tmpl)
+ else if (TI_TEMPLATE (partial_ti) == tmpl)
permerror (input_location,
"partial specialization of %qD after instantiation "
"of %qD", decl, inst_decl);
@@ -10335,11 +10339,16 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context,
/* Return a TEMPLATE_ID_EXPR for the given variable template and ARGLIST. */
tree
-lookup_template_variable (tree templ, tree arglist)
+lookup_template_variable (tree templ, tree arglist, tsubst_flags_t complain)
{
if (flag_concepts && variable_concept_p (templ))
return build_concept_check (templ, arglist, tf_none);
+ tree parms = DECL_INNERMOST_TEMPLATE_PARMS (templ);
+ arglist = coerce_template_parms (parms, arglist, templ, complain);
+ if (arglist == error_mark_node)
+ return error_mark_node;
+
/* The type of the expression is NULL_TREE since the template-id could refer
to an explicit or partial specialization. */
return build2 (TEMPLATE_ID_EXPR, NULL_TREE, templ, arglist);
@@ -10360,11 +10369,6 @@ finish_template_variable (tree var, tsubst_flags_t complain)
|| any_dependent_template_arguments_p (arglist))
return var;
- tree parms = DECL_TEMPLATE_PARMS (templ);
- arglist = coerce_template_parms (parms, arglist, templ, complain);
- if (arglist == error_mark_node)
- return error_mark_node;
-
if (flag_concepts && !constraints_satisfied_p (templ, arglist))
{
if (complain & tf_error)
@@ -10386,7 +10390,9 @@ tree
lookup_and_finish_template_variable (tree templ, tree targs,
tsubst_flags_t complain)
{
- tree var = lookup_template_variable (templ, targs);
+ tree var = lookup_template_variable (templ, targs, complain);
+ if (var == error_mark_node)
+ return error_mark_node;
/* We may be called while doing a partial substitution, but the
type of the variable template may be auto, in which case we
will call do_auto_deduction in mark_used (which clears tf_partial)
@@ -10967,7 +10973,11 @@ uses_template_parms_level (tree t, int level)
static bool
uses_outer_template_parms (tree decl)
{
- int depth = template_class_depth (CP_DECL_CONTEXT (decl));
+ int depth;
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (decl))
+ depth = TEMPLATE_TYPE_LEVEL (TREE_TYPE (decl)) - 1;
+ else
+ depth = template_class_depth (CP_DECL_CONTEXT (decl));
if (depth == 0)
return false;
if (for_each_template_parm (TREE_TYPE (decl), template_parm_outer_level,
@@ -12105,8 +12115,8 @@ instantiate_class_template (tree type)
and supposing that we are instantiating S<int*>, ARGS will
presently be {int*} -- but we need {int}. */
- pattern = TREE_TYPE (t);
- args = TREE_PURPOSE (t);
+ pattern = TREE_TYPE (TI_TEMPLATE (t));
+ args = TI_ARGS (t);
}
else
{
@@ -16213,14 +16223,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
t = TYPE_MAIN_VARIANT (t);
}
- if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
- && (arg = TEMPLATE_TYPE_PARM_INDEX (t),
- r = TEMPLATE_PARM_DESCENDANTS (arg))
- && (TEMPLATE_PARM_LEVEL (r)
- == TEMPLATE_PARM_LEVEL (arg) - levels))
- /* Cache the simple case of lowering a type parameter. */
- r = TREE_TYPE (r);
- else
+ if (tree d = TEMPLATE_TYPE_DESCENDANTS (t))
+ if (TEMPLATE_PARM_LEVEL (d) == TEMPLATE_TYPE_LEVEL (t) - levels
+ && (code == TEMPLATE_TYPE_PARM
+ || TEMPLATE_TEMPLATE_PARM_SIMPLE_P (t)))
+ /* Cache lowering a type parameter or a simple template
+ template parameter. */
+ r = TREE_TYPE (d);
+
+ if (!r)
{
r = copy_type (t);
TEMPLATE_TYPE_PARM_INDEX (r)
@@ -16231,7 +16242,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
TYPE_POINTER_TO (r) = NULL_TREE;
TYPE_REFERENCE_TO (r) = NULL_TREE;
- if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
+ if (code == TEMPLATE_TYPE_PARM)
if (tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t))
/* Propagate constraints on placeholders since they are
only instantiated during satisfaction. */
@@ -17766,7 +17777,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
targs = tsubst_template_args (targs, args, complain, in_decl);
if (variable_template_p (tmpl))
- return lookup_template_variable (tmpl, targs);
+ return lookup_template_variable (tmpl, targs, complain);
else
return lookup_template_function (tmpl, targs);
}
@@ -22078,20 +22089,21 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
tree pattern = DECL_TEMPLATE_RESULT (gen_tmpl);
+ tree partial_ti = NULL_TREE;
fndecl = NULL_TREE;
if (VAR_P (pattern))
{
/* We need to determine if we're using a partial or explicit
specialization now, because the type of the variable could be
different. */
- tree tid = lookup_template_variable (tmpl, targ_ptr);
- tree elt = most_specialized_partial_spec (tid, complain);
- if (elt == error_mark_node)
+ tree tid = build2 (TEMPLATE_ID_EXPR, NULL_TREE, tmpl, targ_ptr);
+ partial_ti = most_specialized_partial_spec (tid, complain);
+ if (partial_ti == error_mark_node)
pattern = error_mark_node;
- else if (elt)
+ else if (partial_ti)
{
- tree partial_tmpl = TREE_VALUE (elt);
- tree partial_args = TREE_PURPOSE (elt);
+ tree partial_tmpl = TI_TEMPLATE (partial_ti);
+ tree partial_args = TI_ARGS (partial_ti);
tree partial_pat = DECL_TEMPLATE_RESULT (partial_tmpl);
fndecl = tsubst (partial_pat, partial_args, complain, gen_tmpl);
}
@@ -22114,6 +22126,10 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
template, not the most general template. */
DECL_TI_TEMPLATE (fndecl) = tmpl;
DECL_TI_ARGS (fndecl) = targ_ptr;
+ if (VAR_P (pattern))
+ /* Now that we we've formed this variable template specialization,
+ remember the result of most_specialized_partial_spec for it. */
+ TI_PARTIAL_INFO (DECL_TEMPLATE_INFO (fndecl)) = partial_ti;
set_instantiating_module (fndecl);
@@ -25980,10 +25996,12 @@ most_general_template (tree decl)
/* Return the most specialized of the template partial specializations
which can produce TARGET, a specialization of some class or variable
- template. The value returned is actually a TREE_LIST; the TREE_VALUE is
- a TEMPLATE_DECL node corresponding to the partial specialization, while
- the TREE_PURPOSE is the set of template arguments that must be
- substituted into the template pattern in order to generate TARGET.
+ template. The value returned is a TEMPLATE_INFO; the TI_TEMPLATE is a
+ TEMPLATE_DECL node corresponding to the partial specialization, while
+ the TI_ARGS is the set of template arguments that must be substituted
+ into the template pattern in order to generate TARGET. The result is
+ cached in the TI_PARTIAL_INFO of the corresponding TEMPLATE_INFO unless
+ RECHECKING is true.
If the choice of partial specialization is ambiguous, a diagnostic
is issued, and the error_mark_node is returned. If there are no
@@ -25991,12 +26009,14 @@ most_general_template (tree decl)
returned, indicating that the primary template should be used. */
tree
-most_specialized_partial_spec (tree target, tsubst_flags_t complain)
+most_specialized_partial_spec (tree target, tsubst_flags_t complain,
+ bool rechecking /* = false */)
{
+ tree tinfo = NULL_TREE;
tree tmpl, args, decl;
if (TYPE_P (target))
{
- tree tinfo = CLASSTYPE_TEMPLATE_INFO (target);
+ tinfo = CLASSTYPE_TEMPLATE_INFO (target);
tmpl = TI_TEMPLATE (tinfo);
args = TI_ARGS (tinfo);
decl = TYPE_NAME (target);
@@ -26009,7 +26029,7 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
}
else if (VAR_P (target))
{
- tree tinfo = DECL_TEMPLATE_INFO (target);
+ tinfo = DECL_TEMPLATE_INFO (target);
tmpl = TI_TEMPLATE (tinfo);
args = TI_ARGS (tinfo);
decl = target;
@@ -26017,6 +26037,14 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
else
gcc_unreachable ();
+ if (!PRIMARY_TEMPLATE_P (tmpl))
+ return NULL_TREE;
+
+ if (!rechecking
+ && tinfo
+ && (VAR_P (target) || COMPLETE_TYPE_P (target)))
+ return TI_PARTIAL_INFO (tinfo);
+
tree main_tmpl = most_general_template (tmpl);
tree specs = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl);
if (!specs)
@@ -26066,10 +26094,7 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
/* Keep the candidate only if its constraints are satisfied. */
if (constraints_satisfied_p (ospec_tmpl, spec_args))
- {
- list = tree_cons (spec_args, ospec_tmpl, list);
- TREE_TYPE (list) = TREE_TYPE (t);
- }
+ list = tree_cons (spec_args, ospec_tmpl, list);
}
}
@@ -26131,7 +26156,10 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
return error_mark_node;
}
- return champ;
+ tree result = build_template_info (TREE_VALUE (champ), TREE_PURPOSE (champ));
+ if (!rechecking && tinfo)
+ TI_PARTIAL_INFO (tinfo) = result;
+ return result;
}
/* Explicitly instantiate DECL. */
@@ -27023,11 +27051,11 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
if (variable_template_specialization_p (d))
{
/* Look up an explicit specialization, if any. */
- tree elt = most_specialized_partial_spec (d, tf_warning_or_error);
- if (elt && elt != error_mark_node)
+ tree partial_ti = most_specialized_partial_spec (d, tf_warning_or_error);
+ if (partial_ti && partial_ti != error_mark_node)
{
- td = TREE_VALUE (elt);
- args = TREE_PURPOSE (elt);
+ td = TI_TEMPLATE (partial_ti);
+ args = TI_ARGS (partial_ti);
}
}
diff --git a/gcc/cp/ptree.cc b/gcc/cp/ptree.cc
index e9b5066..33af7b8 100644
--- a/gcc/cp/ptree.cc
+++ b/gcc/cp/ptree.cc
@@ -346,6 +346,9 @@ cxx_print_xnode (FILE *file, tree node, int indent)
case TEMPLATE_INFO:
print_node (file, "template", TI_TEMPLATE (node), indent+4);
print_node (file, "args", TI_ARGS (node), indent+4);
+ if (TI_TEMPLATE (node)
+ && PRIMARY_TEMPLATE_P (TI_TEMPLATE (node)))
+ print_node (file, "partial", TI_PARTIAL_INFO (node), indent+4);
if (TI_PENDING_TEMPLATE_FLAG (node))
{
indent_to (file, indent + 3);
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index da591da..859b133 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -7561,7 +7561,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
/* [depr.volatile.type] "Postfix ++ and -- expressions and
prefix ++ and -- expressions of volatile-qualified arithmetic
and pointer types are deprecated." */
- if (TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg)))
+ if ((TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg)))
+ && (complain & tf_warning))
warning_at (location, OPT_Wvolatile,
"%qs expression of %<volatile%>-qualified type is "
"deprecated",
@@ -7592,7 +7593,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
return error_mark_node;
}
/* Otherwise, [depr.incr.bool] says this is deprecated. */
- else
+ else if (complain & tf_warning)
warning_at (location, OPT_Wdeprecated,
"use of an operand of type %qT "
"in %<operator++%> is deprecated",
diff --git a/gcc/cselib.cc b/gcc/cselib.cc
index 065867b..5b9843a 100644
--- a/gcc/cselib.cc
+++ b/gcc/cselib.cc
@@ -636,7 +636,7 @@ cselib_find_slot (machine_mode mode, rtx x, hashval_t hash,
element has been set to zero, which implies the cselib_val will be
removed. */
-int
+bool
references_value_p (const_rtx x, int only_useless)
{
const enum rtx_code code = GET_CODE (x);
@@ -646,19 +646,19 @@ references_value_p (const_rtx x, int only_useless)
if (GET_CODE (x) == VALUE
&& (! only_useless
|| (CSELIB_VAL_PTR (x)->locs == 0 && !PRESERVED_VALUE_P (x))))
- return 1;
+ return true;
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e' && references_value_p (XEXP (x, i), only_useless))
- return 1;
+ return true;
else if (fmt[i] == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
if (references_value_p (XVECEXP (x, i, j), only_useless))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* Return true if V is a useless VALUE and can be discarded as such. */
@@ -926,13 +926,13 @@ autoinc_split (rtx x, rtx *off, machine_mode memmode)
return x;
}
-/* Return nonzero if we can prove that X and Y contain the same value,
+/* Return true if we can prove that X and Y contain the same value,
taking our gathered information into account. MEMMODE holds the
mode of the enclosing MEM, if any, as required to deal with autoinc
addressing modes. If X and Y are not (known to be) part of
addresses, MEMMODE should be VOIDmode. */
-int
+bool
rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
{
enum rtx_code code;
@@ -956,7 +956,7 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
}
if (x == y)
- return 1;
+ return true;
if (GET_CODE (x) == VALUE)
{
@@ -973,11 +973,11 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
rtx yoff = NULL;
rtx yr = autoinc_split (y, &yoff, memmode);
if ((yr == x || yr == e->val_rtx) && yoff == NULL_RTX)
- return 1;
+ return true;
}
if (depth == 128)
- return 0;
+ return false;
for (l = e->locs; l; l = l->next)
{
@@ -989,10 +989,10 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE)
continue;
else if (rtx_equal_for_cselib_1 (t, y, memmode, depth + 1))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
else if (GET_CODE (y) == VALUE)
{
@@ -1006,11 +1006,11 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
rtx xoff = NULL;
rtx xr = autoinc_split (x, &xoff, memmode);
if ((xr == y || xr == e->val_rtx) && xoff == NULL_RTX)
- return 1;
+ return true;
}
if (depth == 128)
- return 0;
+ return false;
for (l = e->locs; l; l = l->next)
{
@@ -1019,14 +1019,14 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE)
continue;
else if (rtx_equal_for_cselib_1 (x, t, memmode, depth + 1))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
if (GET_MODE (x) != GET_MODE (y))
- return 0;
+ return false;
if (GET_CODE (x) != GET_CODE (y)
|| (GET_CODE (x) == PLUS
@@ -1044,16 +1044,16 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
if (x != xorig || y != yorig)
{
if (!xoff != !yoff)
- return 0;
+ return false;
if (xoff && !rtx_equal_for_cselib_1 (xoff, yoff, memmode, depth))
- return 0;
+ return false;
return rtx_equal_for_cselib_1 (x, y, memmode, depth);
}
if (GET_CODE (xorig) != GET_CODE (yorig))
- return 0;
+ return false;
}
/* These won't be handled correctly by the code below. */
@@ -1061,7 +1061,7 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
{
CASE_CONST_UNIQUE:
case DEBUG_EXPR:
- return 0;
+ return false;
case CONST_VECTOR:
if (!same_vector_encodings_p (x, y))
@@ -1108,31 +1108,31 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
{
case 'w':
if (XWINT (x, i) != XWINT (y, i))
- return 0;
+ return false;
break;
case 'n':
case 'i':
if (XINT (x, i) != XINT (y, i))
- return 0;
+ return false;
break;
case 'p':
if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
- return 0;
+ return false;
break;
case 'V':
case 'E':
/* Two vectors must have the same length. */
if (XVECLEN (x, i) != XVECLEN (y, i))
- return 0;
+ return false;
/* And the corresponding elements must match. */
for (j = 0; j < XVECLEN (x, i); j++)
if (! rtx_equal_for_cselib_1 (XVECEXP (x, i, j),
XVECEXP (y, i, j), memmode, depth))
- return 0;
+ return false;
break;
case 'e':
@@ -1142,16 +1142,16 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
depth)
&& rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 1), memmode,
depth))
- return 1;
+ return true;
if (! rtx_equal_for_cselib_1 (XEXP (x, i), XEXP (y, i), memmode,
depth))
- return 0;
+ return false;
break;
case 'S':
case 's':
if (strcmp (XSTR (x, i), XSTR (y, i)))
- return 0;
+ return false;
break;
case 'u':
@@ -1169,7 +1169,7 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
gcc_unreachable ();
}
}
- return 1;
+ return true;
}
/* Wrapper for rtx_equal_for_cselib_p to determine whether a SET is
diff --git a/gcc/cselib.h b/gcc/cselib.h
index e2fa8e8..0ced5d5 100644
--- a/gcc/cselib.h
+++ b/gcc/cselib.h
@@ -82,9 +82,9 @@ extern void cselib_finish (void);
extern void cselib_process_insn (rtx_insn *);
extern bool fp_setter_insn (rtx_insn *);
extern machine_mode cselib_reg_set_mode (const_rtx);
-extern int rtx_equal_for_cselib_1 (rtx, rtx, machine_mode, int);
+extern bool rtx_equal_for_cselib_1 (rtx, rtx, machine_mode, int);
extern bool cselib_redundant_set_p (rtx);
-extern int references_value_p (const_rtx, int);
+extern bool references_value_p (const_rtx, int);
extern rtx cselib_expand_value_rtx (rtx, bitmap, int);
typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *);
extern rtx cselib_expand_value_rtx_cb (rtx, bitmap, int,
@@ -128,14 +128,14 @@ canonical_cselib_val (cselib_val *val)
return canon;
}
-/* Return nonzero if we can prove that X and Y contain the same value, taking
+/* Return true if we can prove that X and Y contain the same value, taking
our gathered information into account. */
-inline int
+inline bool
rtx_equal_for_cselib_p (rtx x, rtx y)
{
if (x == y)
- return 1;
+ return true;
return rtx_equal_for_cselib_1 (x, y, VOIDmode, 0);
}
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 8748283..750b848 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,52 @@
+2023-07-02 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110516
+ * intrinsics.cc (expand_volatile_load): Set TREE_SIDE_EFFECTS on the
+ expanded expression.
+ (expand_volatile_store): Likewise.
+
+2023-07-01 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110514
+ * decl.cc (get_symbol_decl): Set TREE_READONLY on certain kinds of
+ const and immutable variables.
+ * expr.cc (ExprVisitor::visit (ArrayLiteralExp *)): Set TREE_READONLY
+ on immutable dynamic array literals.
+
+2023-07-01 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110471
+ * d-builtins.cc (d_init_versions): Predefine D_ModuleInfo,
+ D_Exceptions, and D_TypeInfo only if feature is enabled.
+ * lang.opt: Add -fexceptions.
+
+2023-06-28 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/106977
+ PR target/110406
+ * types.cc (finish_aggregate_mode): New function.
+ (finish_incomplete_fields): Call finish_aggregate_mode.
+ (finish_aggregate_type): Replace call to compute_record_mode with
+ finish_aggregate_mode.
+
+2023-06-28 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110193
+ * types.cc (d_signed_or_unsigned_type): Handle being called with any
+ vector or non-integral type.
+
+2023-06-26 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110359
+ * d-convert.cc (convert_for_rvalue): Only apply the @safe boolean
+ conversion to boolean fields of a union.
+ (convert_for_condition): Call convert_for_rvalue in the default case.
+
+2023-06-25 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd a45f4e9f43.
+ * dmd/VERSION: Bump version to v2.103.1.
+
2023-06-15 Marek Polacek <polacek@redhat.com>
* Make-lang.in: Remove NO_PIE_CFLAGS.
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index f408880..60f76fc 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -500,9 +500,12 @@ d_init_versions (void)
VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
else
{
- VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
- VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
- VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
+ if (global.params.useModuleInfo)
+ VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
+ if (global.params.useExceptions)
+ VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
+ if (global.params.useTypeInfo)
+ VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
}
if (optimize)
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index cdbd69c..2b9d8e7 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -619,7 +619,7 @@ convert_expr (tree exp, Type *etype, Type *totype)
return result ? result : convert (build_ctype (totype), exp);
}
-/* Return a TREE represenwation of EXPR, whose type has been converted from
+/* Return a TREE representation of EXPR, whose type has been converted from
* ETYPE to TOTYPE, and is being used in an rvalue context. */
tree
@@ -634,20 +634,27 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
{
/* If casting from bool, the result is either 0 or 1, any other value
violates @safe code, so enforce that it is never invalid. */
- if (CONSTANT_CLASS_P (expr))
- result = d_truthvalue_conversion (expr);
- else
+ for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
+ ref = TREE_OPERAND (ref, 0))
{
- /* Reinterpret the boolean as an integer and test the first bit.
- The generated code should end up being equivalent to:
+ /* If the expression is a field that's part of a union, reinterpret
+ the boolean as an integer and test the first bit. The generated
+ code should end up being equivalent to:
*cast(ubyte *)&expr & 1; */
- machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
- tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
- result = fold_build2 (BIT_AND_EXPR, mtype,
- build_vconvert (mtype, expr),
- build_one_cst (mtype));
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
+ {
+ machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
+ tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
+ result = fold_build2 (BIT_AND_EXPR, mtype,
+ build_vconvert (mtype, expr),
+ build_one_cst (mtype));
+ break;
+ }
}
+ if (result == NULL_TREE)
+ result = d_truthvalue_conversion (expr);
+
result = convert (build_ctype (tbtype), result);
}
@@ -844,7 +851,7 @@ convert_for_condition (tree expr, Type *type)
break;
default:
- result = expr;
+ result = convert_for_rvalue (expr, type, type);
break;
}
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 78c4ab5..3f98085 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1277,6 +1277,20 @@ get_symbol_decl (Declaration *decl)
DECL_INITIAL (decl->csym) = build_expr (ie, true);
}
}
+
+ /* [type-qualifiers/const-and-immutable]
+
+ `immutable` applies to data that cannot change. Immutable data values,
+ once constructed, remain the same for the duration of the program's
+ execution. */
+ if (vd->isImmutable () && !vd->setInCtorOnly ())
+ TREE_READONLY (decl->csym) = 1;
+
+ /* `const` applies to data that cannot be changed by the const reference
+ to that data. It may, however, be changed by another reference to that
+ same data. */
+ if (vd->isConst () && !vd->isDataseg ())
+ TREE_READONLY (decl->csym) = 1;
}
/* Set the declaration mangled identifier if static. */
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 986925e..1205cd9 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-5f7552bb2829b75d5e36cc767a476e1ab35147b7
+a45f4e9f43e9fdbf0b666175e5e66b1ce4f561f6
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index da496a2..8316aaf 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.103.0-rc.1
+v2.103.1
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index 04e5eb2..03fe478 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -108,8 +108,8 @@ public:
Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this)
Visibility visibility;
- bool noDefaultCtor; // no default construction
- bool disableNew; // disallow allocations using `new`
+ d_bool noDefaultCtor; // no default construction
+ d_bool disableNew; // disallow allocations using `new`
Sizeok sizeok; // set when structsize contains valid data
virtual Scope *newScope(Scope *sc);
@@ -269,10 +269,10 @@ public:
// their own vtbl[]
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
- bool com; // true if this is a COM class (meaning it derives from IUnknown)
- bool stack; // true if this is a scope class
+ d_bool com; // true if this is a COM class (meaning it derives from IUnknown)
+ d_bool stack; // true if this is a scope class
int cppDtorVtblIndex; // slot reserved for the virtual destructor [extern(C++)]
- bool inuse; // to prevent recursive attempts
+ d_bool inuse; // to prevent recursive attempts
ThreeState isabstract; // if abstract class
Baseok baseok; // set the progress of base classes resolving
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index 44ceb12..113653e 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -132,7 +132,7 @@ public:
class AnonDeclaration final : public AttribDeclaration
{
public:
- bool isunion;
+ d_bool isunion;
int sem; // 1 if successful semantic()
unsigned anonoffset; // offset of anonymous struct
unsigned anonstructsize; // size of anonymous struct
@@ -175,8 +175,8 @@ class StaticIfDeclaration final : public ConditionalDeclaration
{
public:
ScopeDsymbol *scopesym;
- bool addisdone;
- bool onStack;
+ d_bool addisdone;
+ d_bool onStack;
StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
Dsymbols *include(Scope *sc) override;
@@ -193,8 +193,8 @@ class StaticForeachDeclaration final : public AttribDeclaration
public:
StaticForeach *sfe;
ScopeDsymbol *scopesym;
- bool onStack;
- bool cached;
+ d_bool onStack;
+ d_bool cached;
Dsymbols *cache;
StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
@@ -227,7 +227,7 @@ public:
Expressions *exps;
ScopeDsymbol *scopesym;
- bool compiled;
+ d_bool compiled;
CompileDeclaration *syntaxCopy(Dsymbol *s) override;
void addMember(Scope *sc, ScopeDsymbol *sds) override;
diff --git a/gcc/d/dmd/common/outbuffer.h b/gcc/d/dmd/common/outbuffer.h
index b672842..4c1dcee 100644
--- a/gcc/d/dmd/common/outbuffer.h
+++ b/gcc/d/dmd/common/outbuffer.h
@@ -21,11 +21,11 @@ struct OutBuffer
private:
DArray<unsigned char> data;
d_size_t offset;
- bool notlinehead;
+ d_bool notlinehead;
void *fileMapping; // pointer to a file mapping object not used on the C++ side
public:
- bool doindent;
- bool spaces;
+ d_bool doindent;
+ d_bool spaces;
int level;
OutBuffer()
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index c0c4cf1..c40936c 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -935,9 +935,6 @@ extern (C++) final class StaticIfCondition : Condition
import dmd.staticcond;
bool errors;
- if (!exp)
- return errorReturn();
-
bool result = evalStaticCondition(sc, exp, exp, errors);
// Prevent repeated condition evaluation.
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index 422a715..45094d1 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -52,7 +52,7 @@ public:
ForeachStatement *aggrfe;
ForeachRangeStatement *rangefe;
- bool needExpansion;
+ d_bool needExpansion;
StaticForeach *syntaxCopy();
};
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index b015a64..32b3851 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -213,6 +213,11 @@ private final class CppMangleVisitor : Visitor
{
auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type;
Type rt = preSemantic.nextOf();
+ // https://issues.dlang.org/show_bug.cgi?id=22739
+ // auto return type means that rt is null.
+ // if so, just pick up the type from the instance
+ if (!rt)
+ rt = tf.nextOf();
if (tf.isref)
rt = rt.referenceTo();
auto prev = this.context.push(tf.nextOf());
@@ -560,7 +565,11 @@ private final class CppMangleVisitor : Visitor
foreach (j; i .. (*ti.tiargs).length)
{
Type t = isType((*ti.tiargs)[j]);
- assert(t);
+ if (t is null)
+ {
+ ti.error("internal compiler error: C++ `%s` template value parameter is not supported", (*ti.tiargs)[j].toChars());
+ fatal();
+ }
t.accept(this);
}
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index cd4155d..d75f64f 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -167,8 +167,8 @@ class TupleDeclaration final : public Declaration
public:
Objects *objects;
TypeTuple *tupletype; // !=NULL if this is a type tuple
- bool isexp; // true: expression tuple
- bool building; // it's growing in AliasAssign semantic
+ d_bool isexp; // true: expression tuple
+ d_bool building; // it's growing in AliasAssign semantic
TupleDeclaration *syntaxCopy(Dsymbol *) override;
const char *kind() const override;
@@ -607,7 +607,7 @@ public:
// set if someone took the address of this function
int tookAddressOf;
- bool requiresClosure; // this function needs a closure
+ d_bool requiresClosure; // this function needs a closure
// local variables in this function which are referenced by nested functions
VarDeclarations closureVars;
@@ -742,7 +742,7 @@ class FuncAliasDeclaration final : public FuncDeclaration
{
public:
FuncDeclaration *funcalias;
- bool hasOverloads;
+ d_bool hasOverloads;
FuncAliasDeclaration *isFuncAliasDeclaration() override { return this; }
const char *kind() const override;
@@ -758,7 +758,7 @@ public:
Type *treq; // target of return type inference
// backend
- bool deferToObj;
+ d_bool deferToObj;
FuncLiteralDeclaration *syntaxCopy(Dsymbol *) override;
bool isNested() const override;
@@ -778,7 +778,7 @@ public:
class CtorDeclaration final : public FuncDeclaration
{
public:
- bool isCpCtor;
+ d_bool isCpCtor;
CtorDeclaration *syntaxCopy(Dsymbol *) override;
const char *kind() const override;
const char *toChars() const override;
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 1cee456..039a288 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -172,7 +172,7 @@ struct FieldState
unsigned fieldAlign;
unsigned bitOffset;
- bool inFlight;
+ d_bool inFlight;
};
struct DsymbolAttributes;
@@ -189,7 +189,7 @@ public:
private:
DsymbolAttributes* atts;
public:
- bool errors; // this symbol failed to pass semantic()
+ d_bool errors; // this symbol failed to pass semantic()
PASS semanticRun;
unsigned short localNum; // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab
static Dsymbol *create(Identifier *);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 6697ad6..0f0ed2a 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -1383,10 +1383,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
imp.semanticRun = PASS.semantic;
// Load if not already done so
- bool loadErrored = false;
if (!imp.mod)
{
- loadErrored = imp.load(sc);
+ // https://issues.dlang.org/show_bug.cgi?id=22857
+ // if parser errors occur when loading a module
+ // we should just stop compilation
+ if (imp.load(sc))
+ return;
+
if (imp.mod)
{
imp.mod.importAll(null);
@@ -1427,10 +1431,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
imp.addPackageAccess(scopesym);
}
- if (!loadErrored)
- {
- imp.mod.dsymbolSemantic(null);
- }
+ imp.mod.dsymbolSemantic(null);
if (imp.mod.needmoduleinfo)
{
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index e4716c8..1bc78e7 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -81,7 +81,7 @@ class Expression : public ASTNode
public:
EXP op; // to minimize use of dynamic_cast
unsigned char size; // # of bytes in Expression so we can copy() it
- bool parens; // if this is a parenthesized expression
+ d_bool parens; // if this is a parenthesized expression
Type *type; // !=NULL means that semantic() has been run
Loc loc; // file location
@@ -331,7 +331,7 @@ class DsymbolExp final : public Expression
{
public:
Dsymbol *s;
- bool hasOverloads;
+ d_bool hasOverloads;
DsymbolExp *syntaxCopy() override;
bool isLvalue() override;
@@ -422,7 +422,7 @@ public:
Expression *basis;
Expressions *elements;
OwnedBy ownedByCtfe;
- bool onstack;
+ d_bool onstack;
static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
@@ -476,8 +476,8 @@ public:
*/
int stageflags;
- bool useStaticInit; // if this is true, use the StructDeclaration's init symbol
- bool isOriginal; // used when moving instances to indicate `this is this.origin`
+ d_bool useStaticInit; // if this is true, use the StructDeclaration's init symbol
+ d_bool isOriginal; // used when moving instances to indicate `this is this.origin`
OwnedBy ownedByCtfe;
static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
@@ -537,8 +537,8 @@ public:
Expression *argprefix; // expression to be evaluated just before arguments[]
CtorDeclaration *member; // constructor function
- bool onstack; // allocate on stack
- bool thrownew; // this NewExp is the expression of a ThrowStatement
+ d_bool onstack; // allocate on stack
+ d_bool thrownew; // this NewExp is the expression of a ThrowStatement
Expression *lowering; // lowered druntime hook: `_d_newclass`
@@ -566,7 +566,7 @@ class SymbolExp : public Expression
public:
Declaration *var;
Dsymbol *originalScope;
- bool hasOverloads;
+ d_bool hasOverloads;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -588,7 +588,7 @@ public:
class VarExp final : public SymbolExp
{
public:
- bool delegateWasExtracted;
+ d_bool delegateWasExtracted;
static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
bool equals(const RootObject * const o) const override;
bool isLvalue() override;
@@ -764,9 +764,9 @@ class DotIdExp final : public UnaExp
{
public:
Identifier *ident;
- bool noderef; // true if the result of the expression will never be dereferenced
- bool wantsym; // do not replace Symbol with its initializer during semantic()
- bool arrow; // ImportC: if -> instead of .
+ d_bool noderef; // true if the result of the expression will never be dereferenced
+ d_bool wantsym; // do not replace Symbol with its initializer during semantic()
+ d_bool arrow; // ImportC: if -> instead of .
static DotIdExp *create(const Loc &loc, Expression *e, Identifier *ident);
void accept(Visitor *v) override { v->visit(this); }
@@ -786,7 +786,7 @@ class DotVarExp final : public UnaExp
{
public:
Declaration *var;
- bool hasOverloads;
+ d_bool hasOverloads;
bool isLvalue() override;
Expression *toLvalue(Scope *sc, Expression *e) override;
@@ -810,7 +810,7 @@ class DelegateExp final : public UnaExp
{
public:
FuncDeclaration *func;
- bool hasOverloads;
+ d_bool hasOverloads;
VarDeclaration *vthis2; // container for multi-context
@@ -831,9 +831,9 @@ public:
Expressions *arguments; // function arguments
Identifiers *names;
FuncDeclaration *f; // symbol to call
- bool directcall; // true if a virtual call is devirtualized
- bool inDebugStatement; // true if this was in a debug statement
- bool ignoreAttributes; // don't enforce attributes (e.g. call @gc function in @nogc code)
+ d_bool directcall; // true if a virtual call is devirtualized
+ d_bool inDebugStatement; // true if this was in a debug statement
+ d_bool ignoreAttributes; // don't enforce attributes (e.g. call @gc function in @nogc code)
VarDeclaration *vthis2; // container for multi-context
static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);
@@ -892,7 +892,7 @@ public:
class DeleteExp final : public UnaExp
{
public:
- bool isRAII;
+ d_bool isRAII;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -937,9 +937,9 @@ public:
Expression *upr; // NULL if implicit 0
Expression *lwr; // NULL if implicit [length - 1]
VarDeclaration *lengthVar;
- bool upperIsInBounds; // true if upr <= e1.length
- bool lowerIsLessThanUpper; // true if lwr <= upr
- bool arrayop; // an array operation, rather than a slice
+ d_bool upperIsInBounds; // true if upr <= e1.length
+ d_bool lowerIsLessThanUpper; // true if lwr <= upr
+ d_bool arrayop; // an array operation, rather than a slice
SliceExp *syntaxCopy() override;
bool isLvalue() override;
@@ -1011,8 +1011,8 @@ public:
class CommaExp final : public BinExp
{
public:
- bool isGenerated;
- bool allowCommaExp;
+ d_bool isGenerated;
+ d_bool allowCommaExp;
bool isLvalue() override;
Expression *toLvalue(Scope *sc, Expression *e) override;
Expression *modifiableLvalue(Scope *sc, Expression *e) override;
@@ -1025,8 +1025,8 @@ class IndexExp final : public BinExp
{
public:
VarDeclaration *lengthVar;
- bool modifiable;
- bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1
+ d_bool modifiable;
+ d_bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1
IndexExp *syntaxCopy() override;
bool isLvalue() override;
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 632ea11..45dcb97 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -12158,6 +12158,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!needsArrayLowering)
{
+ // https://issues.dlang.org/show_bug.cgi?id=23783
+ if (exp.e1.checkSharedAccess(sc) || exp.e2.checkSharedAccess(sc))
+ return setError();
if (auto e = typeCombine(exp, sc))
{
result = e;
@@ -13372,6 +13375,12 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
bool visitVar(VarExp e)
{
+ // https://issues.dlang.org/show_bug.cgi?id=20908
+ // direct access to init symbols is ok as they
+ // cannot be modified.
+ if (e.var.isSymbolDeclaration())
+ return false;
+
// https://issues.dlang.org/show_bug.cgi?id=22626
// Synchronized functions don't need to use core.atomic
// when accessing `this`.
@@ -13409,9 +13418,16 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
//printf("dotvarexp = %s\n", e.toChars());
if (e.type.isShared())
{
- // / https://issues.dlang.org/show_bug.cgi?id=22626
- if (e.e1.isThisExp() && sc.func && sc.func.isSynchronized())
- return false;
+ if (e.e1.isThisExp())
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=22626
+ if (sc.func && sc.func.isSynchronized())
+ return false;
+
+ // https://issues.dlang.org/show_bug.cgi?id=23790
+ if (e.e1.type.isTypeStruct())
+ return false;
+ }
auto fd = e.var.isFuncDeclaration();
const sharedFunc = fd && fd.type.isShared;
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index ec8fc32..84fbec6 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -85,8 +85,8 @@ enum class FeatureState : signed char
struct Output
{
/// Configuration for the compiler generator
- bool doOutput; // Output is enabled
- bool fullOutput; // Generate comments for hidden declarations (for -HC),
+ d_bool doOutput; // Output is enabled
+ d_bool fullOutput; // Generate comments for hidden declarations (for -HC),
// and don't strip the bodies of plain (non-template) functions (for -H)
DString dir; // write to directory 'dir'
DString name; // write to file 'name'
@@ -99,71 +99,71 @@ struct Output
// Put command line switches in here
struct Param
{
- bool obj; // write object file
- bool multiobj; // break one object file into multiple ones
- bool trace; // insert profiling hooks
- bool tracegc; // instrument calls to 'new'
- bool verbose; // verbose compile
- bool vcg_ast; // write-out codegen-ast
- bool showColumns; // print character (column) numbers in diagnostics
- bool vtls; // identify thread local variables
- bool vtemplates; // collect and list statistics on template instantiations
- bool vtemplatesListInstances; // collect and list statistics on template instantiations origins
- bool vgc; // identify gc usage
- bool vfield; // identify non-mutable field variables
- bool vcomplex; // identify complex/imaginary type usage
- bool vin; // identify 'in' parameters
+ d_bool obj; // write object file
+ d_bool multiobj; // break one object file into multiple ones
+ d_bool trace; // insert profiling hooks
+ d_bool tracegc; // instrument calls to 'new'
+ d_bool verbose; // verbose compile
+ d_bool vcg_ast; // write-out codegen-ast
+ d_bool showColumns; // print character (column) numbers in diagnostics
+ d_bool vtls; // identify thread local variables
+ d_bool vtemplates; // collect and list statistics on template instantiations
+ d_bool vtemplatesListInstances; // collect and list statistics on template instantiations origins
+ d_bool vgc; // identify gc usage
+ d_bool vfield; // identify non-mutable field variables
+ d_bool vcomplex; // identify complex/imaginary type usage
+ d_bool vin; // identify 'in' parameters
Diagnostic useDeprecated;
- bool useUnitTests; // generate unittest code
- bool useInline; // inline expand functions
- bool release; // build release version
- bool preservePaths; // true means don't strip path from source file
+ d_bool useUnitTests; // generate unittest code
+ d_bool useInline; // inline expand functions
+ d_bool release; // build release version
+ d_bool preservePaths; // true means don't strip path from source file
Diagnostic warnings;
- bool color; // use ANSI colors in console output
- bool cov; // generate code coverage data
+ d_bool color; // use ANSI colors in console output
+ d_bool cov; // generate code coverage data
unsigned char covPercent; // 0..100 code coverage percentage required
- bool ctfe_cov; // generate coverage data for ctfe
- bool ignoreUnsupportedPragmas; // rather than error on them
- bool useModuleInfo; // generate runtime module information
- bool useTypeInfo; // generate runtime type information
- bool useExceptions; // support exception handling
- bool betterC; // be a "better C" compiler; no dependency on D runtime
- bool addMain; // add a default main() function
- bool allInst; // generate code for all template instantiations
- bool bitfields; // support C style bit fields
+ d_bool ctfe_cov; // generate coverage data for ctfe
+ d_bool ignoreUnsupportedPragmas; // rather than error on them
+ d_bool useModuleInfo; // generate runtime module information
+ d_bool useTypeInfo; // generate runtime type information
+ d_bool useExceptions; // support exception handling
+ d_bool betterC; // be a "better C" compiler; no dependency on D runtime
+ d_bool addMain; // add a default main() function
+ d_bool allInst; // generate code for all template instantiations
+ d_bool bitfields; // support C style bit fields
CppStdRevision cplusplus; // version of C++ name mangling to support
- bool showGaggedErrors; // print gagged errors anyway
- bool printErrorContext; // print errors with the error context (the error line in the source file)
- bool manual; // open browser on compiler manual
- bool usage; // print usage and exit
- bool mcpuUsage; // print help on -mcpu switch
- bool transitionUsage; // print help on -transition switch
- bool checkUsage; // print help on -check switch
- bool checkActionUsage; // print help on -checkaction switch
- bool revertUsage; // print help on -revert switch
- bool previewUsage; // print help on -preview switch
- bool externStdUsage; // print help on -extern-std switch
- bool hcUsage; // print help on -HC switch
- bool logo; // print logo;
+ d_bool showGaggedErrors; // print gagged errors anyway
+ d_bool printErrorContext; // print errors with the error context (the error line in the source file)
+ d_bool manual; // open browser on compiler manual
+ d_bool usage; // print usage and exit
+ d_bool mcpuUsage; // print help on -mcpu switch
+ d_bool transitionUsage; // print help on -transition switch
+ d_bool checkUsage; // print help on -check switch
+ d_bool checkActionUsage; // print help on -checkaction switch
+ d_bool revertUsage; // print help on -revert switch
+ d_bool previewUsage; // print help on -preview switch
+ d_bool externStdUsage; // print help on -extern-std switch
+ d_bool hcUsage; // print help on -HC switch
+ d_bool logo; // print logo;
// Options for `-preview=/-revert=`
FeatureState useDIP25; // implement https://wiki.dlang.org/DIP25
FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params
- bool ehnogc; // use @nogc exception handling
- bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
- bool fieldwise; // do struct equality testing field-wise rather than by memcmp()
- bool fixAliasThis; // if the current scope has an alias this, check it before searching upper scopes
+ d_bool ehnogc; // use @nogc exception handling
+ d_bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
+ d_bool fieldwise; // do struct equality testing field-wise rather than by memcmp()
+ d_bool fixAliasThis; // if the current scope has an alias this, check it before searching upper scopes
FeatureState rvalueRefParam; // allow rvalues to be arguments to ref parameters
// https://dconf.org/2019/talks/alexandrescu.html
// https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a
// https://digitalmars.com/d/archives/digitalmars/D/Binding_rvalues_to_ref_parameters_redux_325087.html
// Implementation: https://github.com/dlang/dmd/pull/9817
FeatureState noSharedAccess; // read/write access to shared memory objects
- bool previewIn; // `in` means `[ref] scope const`, accepts rvalues
- bool inclusiveInContracts; // 'in' contracts of overridden methods must be a superset of parent contract
- bool shortenedMethods; // allow => in normal function declarations
- bool fixImmutableConv; // error on unsound immutable conversion - https://github.com/dlang/dmd/pull/14070
- bool fix16997; // fix integral promotions for unary + - ~ operators
+ d_bool previewIn; // `in` means `[ref] scope const`, accepts rvalues
+ d_bool inclusiveInContracts; // 'in' contracts of overridden methods must be a superset of parent contract
+ d_bool shortenedMethods; // allow => in normal function declarations
+ d_bool fixImmutableConv; // error on unsound immutable conversion - https://github.com/dlang/dmd/pull/14070
+ d_bool fix16997; // fix integral promotions for unary + - ~ operators
// https://issues.dlang.org/show_bug.cgi?id=16997
FeatureState dtorFields; // destruct fields of partially constructed objects
// https://issues.dlang.org/show_bug.cgi?id=14246
@@ -208,7 +208,7 @@ struct Param
MessageStyle messageStyle; // style of file/line annotations on messages
- bool run; // run resulting executable
+ d_bool run; // run resulting executable
Strings runargs; // arguments for executable
Array<const char *> cppswitches; // preprocessor switches
@@ -228,7 +228,7 @@ struct Param
struct structalign_t
{
unsigned short value;
- bool pack;
+ d_bool pack;
bool isDefault() const;
void setDefault();
@@ -275,7 +275,7 @@ struct Global
Array<class Identifier*>* versionids; // command line versions and predefined versions
Array<class Identifier*>* debugids; // command line debug versions and predefined versions
- bool hasMainFunction;
+ d_bool hasMainFunction;
unsigned varSequenceNumber;
FileManager* fileManager;
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index c7e5690..e0684e6 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -1586,7 +1586,10 @@ public:
if (hgs.hdrgen)
{
// if the return type is missing (e.g. ref functions or auto)
- if (!tf.next || f.storage_class & STC.auto_)
+ // https://issues.dlang.org/show_bug.cgi?id=20090
+ // constructors are an exception: they don't have an explicit return
+ // type but we still don't output the body.
+ if ((!f.isCtorDeclaration() && !tf.next) || f.storage_class & STC.auto_)
{
hgs.autoMember++;
bodyToBuffer(f);
diff --git a/gcc/d/dmd/identifier.h b/gcc/d/dmd/identifier.h
index c12c355..e7b3ba6 100644
--- a/gcc/d/dmd/identifier.h
+++ b/gcc/d/dmd/identifier.h
@@ -17,7 +17,7 @@ class Identifier final : public RootObject
{
private:
int value;
- bool isAnonymous_;
+ d_bool isAnonymous_;
DString string;
public:
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 66b874c..9a6a56b 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -77,8 +77,8 @@ public:
Initializers value; // of Initializer *'s
unsigned dim; // length of array being initialized
Type *type; // type that array will be used to initialize
- bool sem; // true if semantic() is run
- bool isCarray; // C array semantics
+ d_bool sem; // true if semantic() is run
+ d_bool isCarray; // C array semantics
bool isAssociativeArray() const;
Expression *toAssocArrayLiteral();
@@ -89,7 +89,7 @@ public:
class ExpInitializer final : public Initializer
{
public:
- bool expandTuples;
+ d_bool expandTuples;
Expression *exp;
void accept(Visitor *v) override { v->visit(this); }
@@ -112,7 +112,7 @@ class CInitializer final : public Initializer
public:
DesigInits initializerList;
Type *type; // type that array will be used to initialize
- bool sem; // true if semantic() is run
+ d_bool sem; // true if semantic() is run
void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index c9ed35f..f0f7872 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -2664,14 +2664,19 @@ class Lexer
eSink.error(loc, format, args);
}
- final void deprecation(const(char)* format)
+ void deprecation(T...)(const ref Loc loc, const(char)* format, T args)
{
- eSink.deprecation(token.loc, format);
+ eSink.deprecation(loc, format, args);
}
- final void deprecationSupplemental(const(char)* format)
+ void deprecation(T...)(const(char)* format, T args)
{
- eSink.deprecationSupplemental(token.loc, format);
+ eSink.deprecation(token.loc, format, args);
+ }
+
+ void deprecationSupplemental(T...)(const(char)* format, T args)
+ {
+ eSink.deprecationSupplemental(token.loc, format, args);
}
/***************************************
@@ -2695,12 +2700,21 @@ class Lexer
else
{
const locx = loc();
- eSink.warning(locx, "C preprocessor directive `#%s` is not supported", n.ident.toChars());
+ // @@@DEPRECATED_2.103@@@
+ // Turn into an error in 2.113
+ if (inTokenStringConstant)
+ deprecation(locx, "token string requires valid D tokens, not `#%s`", n.ident.toChars());
+ else
+ error(locx, "C preprocessor directive `#%s` is not supported", n.ident.toChars());
}
}
else if (n.value == TOK.if_)
{
- error("C preprocessor directive `#if` is not supported, use `version` or `static if`");
+ const locx = loc();
+ if (inTokenStringConstant)
+ error(locx, "token string requires valid D tokens, not `#if`");
+ else
+ error(locx, "C preprocessor directive `#if` is not supported, use `version` or `static if`");
}
return false;
}
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 002bb1a..8b48110 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -74,8 +74,8 @@ public:
unsigned errors; // if any errors in file
unsigned numlines; // number of lines in source file
FileType filetype; // source file type
- bool hasAlwaysInlines; // contains references to functions that must be inlined
- bool isPackageFile; // if it is a package.d
+ d_bool hasAlwaysInlines; // contains references to functions that must be inlined
+ d_bool isPackageFile; // if it is a package.d
Package *pkg; // if isPackageFile is true, the Package that contains this package.d
Strings contentImportedFiles; // array of files whose content was imported
int needmoduleinfo;
@@ -90,7 +90,7 @@ public:
Identifier *searchCacheIdent;
Dsymbol *searchCacheSymbol; // cached value of search
int searchCacheFlags; // cached flags
- bool insearch;
+ d_bool insearch;
// module from command line we're imported from,
// i.e. a module that will be taken all the
@@ -165,7 +165,7 @@ struct ModuleDeclaration
Loc loc;
Identifier *id;
DArray<Identifier*> packages; // array of Identifier's representing packages
- bool isdeprecated; // if it is a deprecated module
+ d_bool isdeprecated; // if it is a deprecated module
Expression *msg;
const char *toChars() const;
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index d0775f2..fbfd766 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -589,7 +589,7 @@ struct ParameterList
Parameters* parameters;
StorageClass stc;
VarArg varargs;
- bool hasIdentifierList; // true if C identifier-list style
+ d_bool hasIdentifierList; // true if C identifier-list style
size_t length();
Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); }
@@ -779,7 +779,7 @@ class TypeStruct final : public Type
public:
StructDeclaration *sym;
AliasThisRec att;
- bool inuse;
+ d_bool inuse;
static TypeStruct *create(StructDeclaration *sym);
const char *kind() override;
diff --git a/gcc/d/dmd/objc.h b/gcc/d/dmd/objc.h
index 305ce81..a5cc6f1 100644
--- a/gcc/d/dmd/objc.h
+++ b/gcc/d/dmd/objc.h
@@ -37,8 +37,8 @@ struct ObjcSelector
struct ObjcClassDeclaration
{
- bool isMeta;
- bool isExtern;
+ d_bool isMeta;
+ d_bool isExtern;
Identifier* identifier;
ClassDeclaration* classDeclaration;
@@ -52,7 +52,7 @@ struct ObjcFuncDeclaration
{
ObjcSelector* selector;
VarDeclaration* selectorParameter;
- bool isOptional;
+ d_bool isOptional;
};
class Objc
diff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d
index 541a12d..d1c61be 100644
--- a/gcc/d/dmd/root/array.d
+++ b/gcc/d/dmd/root/array.d
@@ -574,7 +574,7 @@ unittest
private template arraySortWrapper(T, alias fn)
{
pragma(mangle, "arraySortWrapper_" ~ T.mangleof ~ "_" ~ fn.mangleof)
- extern(C) int arraySortWrapper(scope const void* e1, scope const void* e2) nothrow
+ extern(C) int arraySortWrapper(scope const void* e1, scope const void* e2)
{
return fn(cast(const(T*))e1, cast(const(T*))e2);
}
diff --git a/gcc/d/dmd/root/dcompat.h b/gcc/d/dmd/root/dcompat.h
index 0bc23b7..1a49688 100644
--- a/gcc/d/dmd/root/dcompat.h
+++ b/gcc/d/dmd/root/dcompat.h
@@ -36,7 +36,7 @@ struct DString : public DArray<const char>
};
/// Corresponding C++ type that maps to D size_t
-#if __APPLE__ && __i386__
+#if __APPLE__ && (__i386__ || __ppc__)
// size_t is 'unsigned long', which makes it mangle differently than D's 'uint'
typedef unsigned d_size_t;
#elif MARS && DMD_VERSION >= 2079 && DMD_VERSION <= 2081 && \
@@ -49,3 +49,11 @@ typedef unsigned d_size_t;
#else
typedef size_t d_size_t;
#endif
+
+/// Corresponding C++ type that maps to D bool
+#if __APPLE__ && __ppc__
+// bool is defined as an 'int', which does not match same size as D
+typedef uint8_t d_bool;
+#else
+typedef bool d_bool;
+#endif
diff --git a/gcc/d/dmd/root/optional.h b/gcc/d/dmd/root/optional.h
index cc2ee79..353332c 100644
--- a/gcc/d/dmd/root/optional.h
+++ b/gcc/d/dmd/root/optional.h
@@ -11,6 +11,8 @@
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/optional.h
*/
+#include "dcompat.h" // for d_bool
+
/// Optional type that is either `empty` or contains a value of type `T`
template<typename T>
struct Optional final
@@ -20,7 +22,7 @@ private:
T value;
/** whether `value` is set **/
- bool present;
+ d_bool present;
public:
/** Creates an `Optional` with the given value **/
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index b25c26a..da11428 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -81,8 +81,8 @@ struct Scope
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
Scope *callsc; // used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__
Dsymbol *inunion; // !=null if processing members of a union
- bool nofree; // true if shouldn't free it
- bool inLoop; // true if inside a loop (where constructor calls aren't allowed)
+ d_bool nofree; // true if shouldn't free it
+ d_bool inLoop; // true if inside a loop (where constructor calls aren't allowed)
int intypeof; // in typeof(exp)
VarDeclaration *lastVar; // Previous symbol used to prevent goto-skips-init
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index 440e4cb..ee268d9 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -807,9 +807,8 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag)
// but it's a concession to practicality.
// Casts are unfortunately necessary as `implicitConvTo` is not
// `const` (and nor is `StringExp`, by extension).
- static int predicate(const scope Expression* e1, const scope Expression* e2) nothrow
+ static int predicate(const scope Expression* e1, const scope Expression* e2)
{
- scope(failure) assert(0, "An exception was thrown");
return (cast(Expression*)e1).toStringExp().compare((cast(Expression*)e2).toStringExp());
}
ale.elements.sort!predicate;
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index 33a4318..a912e76 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -1420,7 +1420,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
* https://issues.dlang.org/show_bug.cgi?id=14246
*/
AggregateDeclaration ad = ctor.isMemberDecl();
- if (!ctor.fbody || !ad || !ad.fieldDtor || !global.params.dtorFields || global.params.betterC || ctor.type.toTypeFunction.isnothrow)
+ if (!ctor.fbody || !ad || !ad.fieldDtor || !global.params.dtorFields || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow)
return visit(cast(FuncDeclaration)ctor);
/* Generate:
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index 46cc4da..6d1f85b3 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -433,7 +433,7 @@ class SwitchStatement final : public Statement
public:
Expression *condition;
Statement *_body;
- bool isFinal;
+ d_bool isFinal;
DefaultStatement *sdefault;
Statement *tryBody; // set to TryCatchStatement or TryFinallyStatement if in _body portion
@@ -600,11 +600,11 @@ public:
VarDeclaration *var;
// set if semantic processing errors
- bool errors;
+ d_bool errors;
// was generated by the compiler,
// wasn't present in source code
- bool internalCatch;
+ d_bool internalCatch;
Catch *syntaxCopy();
};
@@ -616,7 +616,7 @@ public:
Statement *finalbody;
Statement *tryBody; // set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
- bool bodyFallsThru; // true if _body falls through to finally
+ d_bool bodyFallsThru; // true if _body falls through to finally
static TryFinallyStatement *create(const Loc &loc, Statement *body, Statement *finalbody);
TryFinallyStatement *syntaxCopy() override;
@@ -643,7 +643,7 @@ public:
Expression *exp;
// was generated by the compiler,
// wasn't present in source code
- bool internalThrow;
+ d_bool internalThrow;
ThrowStatement *syntaxCopy() override;
@@ -668,7 +668,7 @@ public:
TryFinallyStatement *tf;
ScopeGuardStatement *os;
VarDeclaration *lastVar;
- bool inCtfeBlock;
+ d_bool inCtfeBlock;
GotoStatement *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
@@ -685,8 +685,8 @@ public:
VarDeclaration *lastVar;
Statement *gotoTarget; // interpret
void* extra; // used by Statement_toIR()
- bool breaks; // someone did a 'break ident'
- bool inCtfeBlock;
+ d_bool breaks; // someone did a 'break ident'
+ d_bool inCtfeBlock;
LabelStatement *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
@@ -697,8 +697,8 @@ class LabelDsymbol final : public Dsymbol
public:
LabelStatement *statement;
- bool deleted; // set if rewritten to return in foreach delegate
- bool iasm; // set if used by inline assembler
+ d_bool deleted; // set if rewritten to return in foreach delegate
+ d_bool iasm; // set if used by inline assembler
static LabelDsymbol *create(Identifier *ident);
LabelDsymbol *isLabel() override;
@@ -722,8 +722,8 @@ public:
code *asmcode;
unsigned asmalign; // alignment of this statement
unsigned regs; // mask of registers modified (must match regm_t in back end)
- bool refparam; // true if function parameter is referenced
- bool naked; // true if function is to be naked
+ d_bool refparam; // true if function parameter is referenced
+ d_bool naked; // true if function is to be naked
InlineAsmStatement *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index bbaee8e..694db28 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -1941,7 +1941,6 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
if (checkNonAssignmentArrayOp(ifs.condition))
ifs.condition = ErrorExp.get();
- ifs.condition = checkGC(scd, ifs.condition);
// Convert to boolean after declaring prm so this works:
// if (S prm = S()) {}
@@ -1953,6 +1952,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
// This feature allows a limited form of conditional compilation.
ifs.condition = ifs.condition.optimize(WANTvalue);
+ // checkGC after optimizing the condition so that
+ // compile time constants are reduced.
+ ifs.condition = checkGC(scd, ifs.condition);
+
// Save 'root' of two branches (then and else) at the point where it forks
CtorFlow ctorflow_root = scd.ctorflow.clone();
@@ -4525,8 +4528,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
decls.append(Dsymbol.arraySyntaxCopy(dbody));
else
{
- if (fs._body) // https://issues.dlang.org/show_bug.cgi?id=17646
- stmts.push(fs._body.syntaxCopy());
+ stmts.push(fs._body.syntaxCopy());
s = new CompoundStatement(loc, stmts);
}
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index ef2c09d..561afa1 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -92,11 +92,11 @@ struct TargetCPP
Microsoft,
Sun
};
- bool reverseOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order
- bool exceptions; // set if catching C++ exceptions is supported
- bool twoDtorInVtable; // target C++ ABI puts deleting and non-deleting destructor into vtable
- bool splitVBasetable; // set if C++ ABI uses separate tables for virtual functions and virtual bases
- bool wrapDtorInExternD; // set if C++ dtors require a D wrapper to be callable from runtime
+ d_bool reverseOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order
+ d_bool exceptions; // set if catching C++ exceptions is supported
+ d_bool twoDtorInVtable; // target C++ ABI puts deleting and non-deleting destructor into vtable
+ d_bool splitVBasetable; // set if C++ ABI uses separate tables for virtual functions and virtual bases
+ d_bool wrapDtorInExternD; // set if C++ dtors require a D wrapper to be callable from runtime
Runtime runtime;
const char *toMangle(Dsymbol *s);
@@ -110,7 +110,7 @@ struct TargetCPP
struct TargetObjC
{
- bool supported; // set if compiler can interface with Objective-C
+ d_bool supported; // set if compiler can interface with Objective-C
};
struct Target
@@ -156,15 +156,15 @@ struct Target
DString architectureName; // name of the platform architecture (e.g. X86_64)
CPU cpu; // CPU instruction set to target
- bool is64bit; // generate 64 bit code for x86_64; true by default for 64 bit dmd
- bool isLP64; // pointers are 64 bits
+ d_bool is64bit; // generate 64 bit code for x86_64; true by default for 64 bit dmd
+ d_bool isLP64; // pointers are 64 bits
// Environmental
DString obj_ext; /// extension for object files
DString lib_ext; /// extension for static library files
DString dll_ext; /// extension for dynamic library files
- bool run_noext; /// allow -run sources without extensions
- bool omfobj; /// for Win32: write OMF object files instead of COFF
+ d_bool run_noext; /// allow -run sources without extensions
+ d_bool omfobj; /// for Win32: write OMF object files instead of COFF
template <typename T>
struct FPTypeProperties
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 12b2120..8622b5c 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -78,12 +78,12 @@ public:
Dsymbol *onemember; // if !=NULL then one member of this template
- bool literal; // this template declaration is a literal
- bool ismixin; // template declaration is only to be used as a mixin
- bool isstatic; // this is static template declaration
- bool isTrivialAliasSeq; // matches `template AliasSeq(T...) { alias AliasSeq = T; }
- bool isTrivialAlias; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
- bool deprecated_; // this template declaration is deprecated
+ d_bool literal; // this template declaration is a literal
+ d_bool ismixin; // template declaration is only to be used as a mixin
+ d_bool isstatic; // this is static template declaration
+ d_bool isTrivialAliasSeq; // matches `template AliasSeq(T...) { alias AliasSeq = T; }
+ d_bool isTrivialAlias; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
+ d_bool deprecated_; // this template declaration is deprecated
Visibility visibility;
TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack
@@ -133,7 +133,7 @@ public:
* A dependent template parameter should return MATCHexact in matchArg()
* to respect the match level of the corresponding precedent parameter.
*/
- bool dependent;
+ d_bool dependent;
virtual TemplateTypeParameter *isTemplateTypeParameter();
virtual TemplateValueParameter *isTemplateValueParameter();
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index f8cbdb4..ed9f9ce 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -10,6 +10,7 @@
#pragma once
#include "root/dsystem.h"
+#include "root/dcompat.h" // for d_bool
class Statement;
class ErrorStatement;
@@ -663,6 +664,6 @@ public:
class StoppableVisitor : public Visitor
{
public:
- bool stop;
+ d_bool stop;
StoppableVisitor() : stop(false) {}
};
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index c6245ff..aeafe43 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2701,6 +2701,10 @@ public:
if (tb->ty == TY::Tarray)
ctor = d_array_value (type, size_int (e->elements->length), ctor);
+ /* Immutable literals can be placed in rodata. */
+ if (tb->isImmutable ())
+ TREE_READONLY (decl) = 1;
+
d_pushdecl (decl);
rest_of_decl_compilation (decl, 1, 0);
}
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc
index 0121d81..aaf04e5 100644
--- a/gcc/d/intrinsics.cc
+++ b/gcc/d/intrinsics.cc
@@ -1007,6 +1007,7 @@ expand_volatile_load (tree callexp)
tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);
tree result = indirect_ref (type, ptr);
TREE_THIS_VOLATILE (result) = 1;
+ TREE_SIDE_EFFECTS (result) = 1;
return result;
}
@@ -1034,6 +1035,7 @@ expand_volatile_store (tree callexp)
tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);
tree result = indirect_ref (type, ptr);
TREE_THIS_VOLATILE (result) = 1;
+ TREE_SIDE_EFFECTS (result) = 1;
/* (*(volatile T *) ptr) = value; */
tree value = CALL_EXPR_ARG (callexp, 1);
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index 26ca92c..98a95c1 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -291,6 +291,10 @@ fdump-d-original
D
Display the frontend AST after parsing and semantic passes.
+fexceptions
+D
+; Documented in common.opt
+
fextern-std=
D Joined RejectNegative Enum(extern_stdcpp) Var(flag_extern_stdcpp)
-fextern-std=<standard> Set C++ name mangling compatibility with <standard>.
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index a4c05bf..ef2d80e 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -49,8 +49,8 @@ along with GCC; see the file COPYING3. If not see
static tree
d_signed_or_unsigned_type (int unsignedp, tree type)
{
- if (TYPE_UNSIGNED (type) == (unsigned) unsignedp)
- return type;
+ if (VECTOR_TYPE_P (type) || !ANY_INTEGRAL_TYPE_P (type))
+ return signed_or_unsigned_type_for (unsignedp, type);
if (TYPE_PRECISION (type) == TYPE_PRECISION (d_cent_type))
return unsignedp ? d_ucent_type : d_cent_type;
@@ -573,6 +573,35 @@ layout_aggregate_type (AggregateDeclaration *decl, tree type,
}
}
+/* Given a record type TYPE compute the finalized record mode if all fields have
+ had their types resolved and sizes determined. */
+
+void
+finish_aggregate_mode (tree type)
+{
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ /* Fields of type `typeof(*null)' have no size, so let them force the
+ record type mode to be computed as BLKmode. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (field)) == noreturn_type_node)
+ break;
+
+ if (DECL_SIZE (field) == NULL_TREE)
+ return;
+ }
+
+ compute_record_mode (type);
+
+ /* Propagate computed mode to all variants of this aggregate type. */
+ for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ if (t == type)
+ continue;
+
+ SET_TYPE_MODE (t, TYPE_MODE (type));
+ }
+}
+
/* If the aggregate type TYPE completes the type of any previous field
declarations, lay them out now. */
@@ -596,6 +625,9 @@ finish_incomplete_fields (tree type)
}
relayout_decl (field);
+
+ /* Relayout of field may change the mode of its RECORD_TYPE. */
+ finish_aggregate_mode (DECL_FIELD_CONTEXT (field));
}
/* No more forward references to process. */
@@ -615,9 +647,6 @@ finish_aggregate_type (unsigned structsize, unsigned alignsize, tree type)
SET_TYPE_ALIGN (type, alignsize * BITS_PER_UNIT);
TYPE_PACKED (type) = (alignsize == 1);
- /* Set the back-end type mode. */
- compute_record_mode (type);
-
/* Layout all fields now the type is complete. */
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
{
@@ -662,6 +691,9 @@ finish_aggregate_type (unsigned structsize, unsigned alignsize, tree type)
}
}
+ /* Set the back-end type mode after all fields have had their size set. */
+ finish_aggregate_mode (type);
+
/* Fix up all forward-referenced variants of this aggregate type. */
for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
{
@@ -673,7 +705,6 @@ finish_aggregate_type (unsigned structsize, unsigned alignsize, tree type)
TYPE_SIZE (t) = TYPE_SIZE (type);
TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
TYPE_PACKED (type) = TYPE_PACKED (type);
- SET_TYPE_MODE (t, TYPE_MODE (type));
SET_TYPE_ALIGN (t, TYPE_ALIGN (type));
TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type);
}
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index ac2f5b8..5e48398 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "diagnostic.h"
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 5fa8e97..65c0cfb 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
message module. */
#include "config.h"
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "version.h"
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index b0a2ce3..3f492b3 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -1908,9 +1908,10 @@ selected, the value of the macro is
@code{201402L} for the 2014 C++ standard,
@code{201703L} for the 2017 C++ standard,
@code{202002L} for the 2020 C++ standard,
-or an unspecified value strictly larger than @code{202002L} for the
-experimental languages enabled by @option{-std=c++23} and
-@option{-std=gnu++23}.
+@code{202302L} for the 2023 C++ standard,
+or an unspecified value strictly larger than @code{202302L} for the
+experimental languages enabled by @option{-std=c++26} and
+@option{-std=gnu++26}.
@item __OBJC__
This macro is defined, with value 1, when the Objective-C compiler is in
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 3040a9b..d1b018e 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1751,7 +1751,49 @@ Flexible array members may only appear as the last member of a
A structure containing a flexible array member, or a union containing
such a structure (possibly recursively), may not be a member of a
structure or an element of an array. (However, these uses are
-permitted by GCC as extensions.)
+permitted by GCC as extensions, see details below.)
+@end itemize
+
+The GCC extension accepts a structure containing an ISO C99 @dfn{flexible array
+member}, or a union containing such a structure (possibly recursively)
+to be a member of a structure.
+
+There are two situations:
+
+@itemize @bullet
+@item
+A structure containing a C99 flexible array member, or a union containing
+such a structure, is the last field of another structure, for example:
+
+@smallexample
+struct flex @{ int length; char data[]; @};
+union union_flex @{ int others; struct flex f; @};
+
+struct out_flex_struct @{ int m; struct flex flex_data; @};
+struct out_flex_union @{ int n; union union_flex flex_data; @};
+@end smallexample
+
+In the above, both @code{out_flex_struct.flex_data.data[]} and
+@code{out_flex_union.flex_data.f.data[]} are considered as flexible arrays too.
+
+@item
+A structure containing a C99 flexible array member, or a union containing
+such a structure, is not the last field of another structure, for example:
+
+@smallexample
+struct flex @{ int length; char data[]; @};
+
+struct mid_flex @{ int m; struct flex flex_data; int n; @};
+@end smallexample
+
+In the above, accessing a member of the array @code{mid_flex.flex_data.data[]}
+might have undefined behavior. Compilers do not handle such a case
+consistently. Any code relying on this case should be modified to ensure
+that flexible array members only end up at the ends of structures.
+
+Please use the warning option @option{-Wflex-array-member-not-at-end} to
+identify all such cases in the source code and modify them. This extension
+is now deprecated.
@end itemize
Non-empty initialization of zero-length
@@ -2573,6 +2615,7 @@ The following attributes are supported on most targets.
@table @code
@c Keep this table alphabetized by attribute name. Treat _ as space.
+@cindex @code{access} function attribute
@item access (@var{access-mode}, @var{ref-index})
@itemx access (@var{access-mode}, @var{ref-index}, @var{size-index})
@@ -3339,6 +3382,8 @@ int S::interface (int) __attribute__ ((ifunc ("_ZN1S8resolverEv")));
Indirect functions cannot be weak. Binutils version 2.20.1 or higher
and GNU C Library version 2.11.1 are required to use this feature.
+@cindex @code{interrupt_handler} function attribute
+@cindex @code{interrupt} function attribute
@item interrupt
@itemx interrupt_handler
Many GCC back ends support attributes to indicate that a function is
@@ -4338,7 +4383,7 @@ through registers.
In order to satisfy users with different security needs and control the
run-time overhead at the same time, the @var{choice} parameter provides a
flexible way to choose the subset of the call-used registers to be zeroed.
-The three basic values of @var{choice} are:
+The four basic values of @var{choice} are:
@itemize @bullet
@item
@@ -4351,10 +4396,16 @@ the function.
@item
@samp{all} zeros all call-used registers.
+
+@item
+@samp{leafy} behaves like @samp{used} in a leaf function, and like
+@samp{all} in a nonleaf function. This makes for leaner zeroing in leaf
+functions, where the set of used registers is known, and that may be
+enough for some purposes of register zeroing.
@end itemize
In addition to these three basic choices, it is possible to modify
-@samp{used} or @samp{all} as follows:
+@samp{used}, @samp{all}, and @samp{leafy} as follows:
@itemize @bullet
@item
@@ -4401,10 +4452,28 @@ zeros all call-used registers that pass arguments.
@item all-gpr-arg
zeros all call-used general purpose registers that pass
arguments.
+
+@item leafy
+Same as @samp{used} in a leaf function, and same as @samp{all} in a
+nonleaf function.
+
+@item leafy-gpr
+Same as @samp{used-gpr} in a leaf function, and same as @samp{all-gpr}
+in a nonleaf function.
+
+@item leafy-arg
+Same as @samp{used-arg} in a leaf function, and same as @samp{all-arg}
+in a nonleaf function.
+
+@item leafy-gpr-arg
+Same as @samp{used-gpr-arg} in a leaf function, and same as
+@samp{all-gpr-arg} in a nonleaf function.
+
@end table
Of this list, @samp{used-arg}, @samp{used-gpr-arg}, @samp{all-arg},
-and @samp{all-gpr-arg} are mainly used for ROP mitigation.
+@samp{all-gpr-arg}, @samp{leafy-arg}, and @samp{leafy-gpr-arg} are
+mainly used for ROP mitigation.
The default for the attribute is controlled by @option{-fzero-call-used-regs}.
@end table
@@ -13731,7 +13800,7 @@ an extension. @xref{Variable Length}, for details.
@enddefbuiltin
-@defbuiltin{{void *}__builtin_alloca_with_align_and_max (size_t size, size_t alignment, size_t max_size)}
+@defbuiltin{{void *} __builtin_alloca_with_align_and_max (size_t size, size_t alignment, size_t max_size)}
Similar to @code{__builtin_alloca_with_align} but takes an extra argument
specifying an upper bound for @var{size} in case its value cannot be computed
at compile time, for use by @option{-fstack-usage}, @option{-Wstack-usage}
diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi
index 3e531a8..ae87434 100644
--- a/gcc/doc/gm2.texi
+++ b/gcc/doc/gm2.texi
@@ -659,6 +659,11 @@ zero.
@item -fwholevalue
generate code to detect whole number overflow and underflow.
+@item -Wuninit-variable-checking
+issue a warning if a variable is used before it is initialized.
+The checking only occurs in the first basic block in each procedure.
+It does not check parameters, array types or set types.
+
@c the following warning options are complete but need to be
@c regression tested against all other front ends
@c to ensure the options do not conflict.
@@ -1452,6 +1457,127 @@ with @samp{-fsoft-check-all} so that the compiler is able to run the
optimizer and perform variable and flow analysis before the semantic
plugin is invoked.
+The @samp{-Wuninit-variable-checking} can be used to identify
+uninitialized variables within the first basic block in a procedure.
+The checking is limited to variables so long as they are
+not an array or set or a variant record.
+
+The following example detects whether a sub component within a record
+is uninitialized.
+
+@example
+MODULE testlarge2 ;
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ p.fg.r := 1 ;
+ p.fg.g := 2 ;
+ p.fg.g := 3 ; (* Deliberate typo should be p.fg.b. *)
+ p.bg := p.fg ; (* Accessing an uninitialized field. *)
+END test ;
+
+BEGIN
+ test
+END testlarge2.
+@end example
+
+@example
+$ gm2 -c -Wuninit-variable-checking testlarge2.mod
+testlarge2.mod:19:13: warning: In procedure ‘test’: attempting to
+access expression before it has been initialized
+ 19 | p.bg := p.fg ; (* Accessing an uninitialized field. *)
+ | ~^~~
+@end example
+
+The following example detects if an individual field is uninitialized.
+
+@example
+MODULE testwithnoptr ;
+
+TYPE
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: Vec ;
+BEGIN
+ WITH p DO
+ x := 1 ;
+ x := 2 (* Deliberate typo, user meant y. *)
+ END ;
+ IF p.y = 2
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testwithnoptr.
+@end example
+
+The following example detects a record is uninitialized via a
+pointer variable in a @samp{WITH} block.
+
+@example
+$ gm2 -g -c -Wuninit-variable-checking testwithnoptr.mod
+testwithnoptr.mod:21:8: warning: In procedure ‘test’: attempting to
+access expression before it has been initialized
+ 21 | IF p.y = 2
+ | ~^~
+@end example
+
+@example
+MODULE testwithptr ;
+
+FROM SYSTEM IMPORT ADR ;
+
+TYPE
+ PtrToVec = POINTER TO Vec ;
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: PtrToVec ;
+ v: Vec ;
+BEGIN
+ p := ADR (v) ;
+ WITH p^ DO
+ x := 1 ;
+ x := 2 (* Deliberate typo, user meant y. *)
+ END ;
+ IF p^.y = 2
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testwithptr.
+@end example
+
+@example
+gm2 -c -Wuninit-variable-checking testwithptr.mod
+testwithptr.mod:26:9: warning: In procedure ‘test’: attempting to
+access expression before it has been initialized
+ 26 | IF p^.y = 2
+ | ~~^~
+@end example
+
@node Extensions, Type compatibility, Semantic checking, Using
@section GNU Modula-2 language extensions
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fd4943b..594b24d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2507,6 +2507,18 @@ change in incompatible ways in future releases.
GNU dialect of @option{-std=c++2b}. Support is highly experimental,
and will almost certainly change in incompatible ways in future
releases.
+
+@item c++2c
+@itemx c++26
+The next revision of the ISO C++ standard, planned for
+2026. Support is highly experimental, and will almost certainly
+change in incompatible ways in future releases.
+
+@item gnu++2c
+@itemx gnu++26
+GNU dialect of @option{-std=c++2c}. Support is highly experimental,
+and will almost certainly change in incompatible ways in future
+releases.
@end table
@opindex aux-info
@@ -4818,10 +4830,12 @@ and Objective-C++ programs:
Use @var{class-name} as the name of the class to instantiate for each
literal string specified with the syntax @code{@@"@dots{}"}. The default
class name is @code{NXConstantString} if the GNU runtime is being used, and
-@code{NSConstantString} if the NeXT runtime is being used (see below). The
-@option{-fconstant-cfstrings} option, if also present, overrides the
-@option{-fconstant-string-class} setting and cause @code{@@"@dots{}"} literals
-to be laid out as constant CoreFoundation strings.
+@code{NSConstantString} if the NeXT runtime is being used (see below). On
+Darwin (macOS, MacOS X) platforms, the @option{-fconstant-cfstrings} option, if
+also present, overrides the @option{-fconstant-string-class} setting and cause
+@code{@@"@dots{}"} literals to be laid out as constant CoreFoundation strings.
+Note that @option{-fconstant-cfstrings} is an alias for the target-specific
+@option{-mconstant-cfstrings} equivalent.
@opindex fgnu-runtime
@item -fgnu-runtime
@@ -24106,10 +24120,21 @@ This is by default ON@.
@item -gfull
Emit debugging information for all symbols and types.
+@opindex fconstant-cfstrings
+@item -fconstant-cfstrings
+The @option{-fconstant-cfstrings} is an alias for @option{-mconstant-cfstrings}.
+
+@opindex mconstant-cfstrings
+@item -mconstant-cfstrings
+When the NeXT runtime is being used (the default on these systems), override
+any @option{-fconstant-string-class} setting and cause @code{@@"@dots{}"}
+literals to be laid out as constant CoreFoundation strings.
+
+@opindex mmacosx-version-min
@item -mmacosx-version-min=@var{version}
-The earliest version of MacOS X that this executable will run on
-is @var{version}. Typical values of @var{version} include @code{10.1},
-@code{10.2}, and @code{10.3.9}.
+The earliest version of MacOS X that this executable will run on is
+@var{version}. Typical values supported for @var{version} include @code{12},
+@code{10.12}, and @code{10.5.8}.
If the compiler was built to use the system's headers by default,
then the default for this option is the system version on which the
@@ -26870,6 +26895,13 @@ MIPS16 code generation can also be controlled on a per-function basis
by means of @code{mips16} and @code{nomips16} attributes.
@xref{Function Attributes}, for more information.
+@opindex mmips16e2
+@opindex mno-mips16e2
+@item -mmips16e2
+@itemx -mno-mips16e2
+Use (do not use) the MIPS16e2 ASE. This option modifies the behavior
+of the @option{-mips16} option such that it targets the MIPS16e2 ASE@.
+
@opindex mflip-mips16
@item -mflip-mips16
Generate MIPS16 code on alternating functions. This option is provided
@@ -32534,7 +32566,8 @@ SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC,
XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL, AVX-VNNI,
-AVXIFMA, AVXVNNIINT8, AVXNECONVERT and CMPCCXADD instruction set support.
+AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, ENQCMD and UINTR instruction set
+support.
@item grandridge
Intel Grand Ridge CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
@@ -32542,8 +32575,8 @@ SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC,
XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL, AVX-VNNI,
-AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD and RAOINT instruction set
-support.
+AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, ENQCMD, UINTR and RAOINT
+instruction set support.
@item knl
Intel Knight's Landing CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 9648fdc..f14dd32 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -5040,6 +5040,15 @@ operand 5. Bit @var{i} of the mask is set if element @var{i}
of the result should be loaded from memory and clear if element @var{i}
of the result should be set to zero.
+@cindex @code{len_mask_gather_load@var{m}@var{n}} instruction pattern
+@item @samp{len_mask_gather_load@var{m}@var{n}}
+Like @samp{gather_load@var{m}@var{n}}, but takes an extra length operand (operand 5),
+a bias operand (operand 6) as well as a mask operand (operand 7). Similar to len_maskload,
+the instruction loads at most (operand 5 + operand 6) elements from memory.
+Bit @var{i} of the mask is set if element @var{i} of the result should
+be loaded from memory and clear if element @var{i} of the result should be undefined.
+Mask elements @var{i} with @var{i} > (operand 5 + operand 6) are ignored.
+
@cindex @code{scatter_store@var{m}@var{n}} instruction pattern
@item @samp{scatter_store@var{m}@var{n}}
Store a vector of mode @var{m} into several distinct memory locations.
@@ -5069,6 +5078,14 @@ Like @samp{scatter_store@var{m}@var{n}}, but takes an extra mask operand as
operand 5. Bit @var{i} of the mask is set if element @var{i}
of the result should be stored to memory.
+@cindex @code{len_mask_scatter_store@var{m}@var{n}} instruction pattern
+@item @samp{len_mask_scatter_store@var{m}@var{n}}
+Like @samp{scatter_store@var{m}@var{n}}, but takes an extra length operand (operand 5),
+a bias operand (operand 6) as well as a mask operand (operand 7). The instruction stores
+at most (operand 5 + operand 6) elements of (operand 4) to memory.
+Bit @var{i} of the mask is set if element @var{i} of (operand 4) should be stored.
+Mask elements @var{i} with @var{i} > (operand 5 + operand 6) are ignored.
+
@cindex @code{vec_set@var{m}} instruction pattern
@item @samp{vec_set@var{m}}
Set given field in the vector value. Operand 0 is the vector to modify,
@@ -5302,15 +5319,15 @@ This pattern is not allowed to @code{FAIL}.
@cindex @code{len_maskload@var{m}@var{n}} instruction pattern
@item @samp{len_maskload@var{m}@var{n}}
Perform a masked load from the memory location pointed to by operand 1
-into register operand 0. (operand 2 + operand 4) elements are loaded from
+into register operand 0. (operand 2 + operand 3) elements are loaded from
memory and other elements in operand 0 are set to undefined values.
This is a combination of len_load and maskload.
Operands 0 and 1 have mode @var{m}, which must be a vector mode. Operand 2
has whichever integer mode the target prefers. A mask is specified in
-operand 3 which must be of type @var{n}. The mask has lower precedence than
+operand 4 which must be of type @var{n}. The mask has lower precedence than
the length and is itself subject to length masking,
-i.e. only mask indices < (operand 2 + operand 4) are used.
-Operand 4 conceptually has mode @code{QI}.
+i.e. only mask indices < (operand 2 + operand 3) are used.
+Operand 3 conceptually has mode @code{QI}.
Operand 2 can be a variable or a constant amount. Operand 4 specifies a
constant bias: it is either a constant 0 or a constant -1. The predicate on
@@ -5329,14 +5346,14 @@ This pattern is not allowed to @code{FAIL}.
@cindex @code{len_maskstore@var{m}@var{n}} instruction pattern
@item @samp{len_maskstore@var{m}@var{n}}
Perform a masked store from vector register operand 1 into memory operand 0.
-(operand 2 + operand 4) elements are stored to memory
+(operand 2 + operand 3) elements are stored to memory
and leave the other elements of operand 0 unchanged.
This is a combination of len_store and maskstore.
Operands 0 and 1 have mode @var{m}, which must be a vector mode. Operand 2 has whichever
-integer mode the target prefers. A mask is specified in operand 3 which must be
+integer mode the target prefers. A mask is specified in operand 4 which must be
of type @var{n}. The mask has lower precedence than the length and is itself subject to
-length masking, i.e. only mask indices < (operand 2 + operand 4) are used.
-Operand 4 conceptually has mode @code{QI}.
+length masking, i.e. only mask indices < (operand 2 + operand 3) are used.
+Operand 3 conceptually has mode @code{QI}.
Operand 2 can be a variable or a constant amount. Operand 3 specifies a
constant bias: it is either a constant 0 or a constant -1. The predicate on
@@ -5871,6 +5888,23 @@ signed/unsigned elements of size S@. Subtract the high/low elements of 2 from
1 and widen the resulting elements. Put the N/2 results of size 2*S in the
output vector (operand 0).
+@cindex @code{vec_widen_sabd_hi_@var{m}} instruction pattern
+@cindex @code{vec_widen_sabd_lo_@var{m}} instruction pattern
+@cindex @code{vec_widen_sabd_odd_@var{m}} instruction pattern
+@cindex @code{vec_widen_sabd_even_@var{m}} instruction pattern
+@cindex @code{vec_widen_uabd_hi_@var{m}} instruction pattern
+@cindex @code{vec_widen_uabd_lo_@var{m}} instruction pattern
+@cindex @code{vec_widen_uabd_odd_@var{m}} instruction pattern
+@cindex @code{vec_widen_uabd_even_@var{m}} instruction pattern
+@item @samp{vec_widen_uabd_hi_@var{m}}, @samp{vec_widen_uabd_lo_@var{m}}
+@itemx @samp{vec_widen_uabd_odd_@var{m}}, @samp{vec_widen_uabd_even_@var{m}}
+@itemx @samp{vec_widen_sabd_hi_@var{m}}, @samp{vec_widen_sabd_lo_@var{m}}
+@itemx @samp{vec_widen_sabd_odd_@var{m}}, @samp{vec_widen_sabd_even_@var{m}}
+Signed/Unsigned widening absolute difference. Operands 1 and 2 are
+vectors with N signed/unsigned elements of size S@. Find the absolute
+difference between operands 1 and 2 and widen the resulting elements.
+Put the N/2 results of size 2*S in the output vector (operand 0).
+
@cindex @code{vec_addsub@var{m}3} instruction pattern
@item @samp{vec_addsub@var{m}3}
Alternating subtract, add with even lanes doing subtract and odd
diff --git a/gcc/doc/optinfo.texi b/gcc/doc/optinfo.texi
index b91bba7..5e8c97e 100644
--- a/gcc/doc/optinfo.texi
+++ b/gcc/doc/optinfo.texi
@@ -100,7 +100,7 @@ that one could also use special file names @code{stdout} and
respectively.
@item @code{alt_stream}
-This steam is used for printing optimization specific output in
+This stream is used for printing optimization specific output in
response to the @option{-fopt-info}. Again a file name can be given. If
the file name is not given, it defaults to @code{stderr}.
@end table
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index e70c47c..e973644 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -16940,6 +16940,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
case CLOBBER:
case SMUL_HIGHPART:
case UMUL_HIGHPART:
+ case BITREVERSE:
break;
case CONST_STRING:
@@ -25105,6 +25106,8 @@ static char *producer_string;
static const char *
highest_c_language (const char *lang1, const char *lang2)
{
+ if (strcmp ("GNU C++26", lang1) == 0 || strcmp ("GNU C++26", lang2) == 0)
+ return "GNU C++26";
if (strcmp ("GNU C++23", lang1) == 0 || strcmp ("GNU C++23", lang2) == 0)
return "GNU C++23";
if (strcmp ("GNU C++20", lang1) == 0 || strcmp ("GNU C++20", lang2) == 0)
@@ -25215,7 +25218,8 @@ gen_compile_unit_die (const char *filename)
language = DW_LANG_C_plus_plus_14;
else if (strcmp (language_string, "GNU C++17") == 0
|| strcmp (language_string, "GNU C++20") == 0
- || strcmp (language_string, "GNU C++23") == 0)
+ || strcmp (language_string, "GNU C++23") == 0
+ || strcmp (language_string, "GNU C++26") == 0)
/* For now. */
language = DW_LANG_C_plus_plus_14;
}
diff --git a/gcc/except.h b/gcc/except.h
index 378a9e4..173b0f0 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -66,7 +66,7 @@ enum eh_region_type
/* A landing pad for a given exception region. Any transfer of control
from the EH runtime to the function happens at a landing pad. */
-struct GTY(()) eh_landing_pad_d
+struct GTY((chain_next("%h.next_lp"))) eh_landing_pad_d
{
/* The linked list of all landing pads associated with the region. */
struct eh_landing_pad_d *next_lp;
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 62cd8fa..fff09dc 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -89,7 +89,7 @@ static rtx store_field (rtx, poly_int64, poly_int64, poly_uint64, poly_uint64,
static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
-static int is_aligning_offset (const_tree, const_tree);
+static bool is_aligning_offset (const_tree, const_tree);
static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
static rtx do_store_flag (sepops, rtx, machine_mode);
#ifdef PUSH_ROUNDING
@@ -1691,9 +1691,9 @@ store_by_pieces_d::finish_retmode (memop_ret retmode)
a pointer which will be passed as argument in every CONSTFUN call.
ALIGN is maximum alignment we can assume. MEMSETP is true if this is
a memset operation and false if it's a copy of a constant string.
- Return nonzero if a call to store_by_pieces should succeed. */
+ Return true if a call to store_by_pieces should succeed. */
-int
+bool
can_store_by_pieces (unsigned HOST_WIDE_INT len,
by_pieces_constfn constfun,
void *constfundata, unsigned int align, bool memsetp)
@@ -1707,14 +1707,14 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
rtx cst ATTRIBUTE_UNUSED;
if (len == 0)
- return 1;
+ return true;
if (!targetm.use_by_pieces_infrastructure_p (len, align,
memsetp
? SET_BY_PIECES
: STORE_BY_PIECES,
optimize_insn_for_speed_p ()))
- return 0;
+ return false;
align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
@@ -1749,7 +1749,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
vector mode for the memset expander. */
if (!((memsetp && VECTOR_MODE_P (mode))
|| targetm.legitimate_constant_p (mode, cst)))
- return 0;
+ return false;
if (!reverse)
offset += size;
@@ -1765,7 +1765,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
gcc_assert (!l);
}
- return 1;
+ return true;
}
/* Generate several move instructions to store LEN bytes generated by
@@ -6868,9 +6868,9 @@ complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
return count_type_elements (type, true) == num_elts;
}
-/* Return 1 if EXP contains mostly (3/4) zeros. */
+/* Return true if EXP contains mostly (3/4) zeros. */
-static int
+static bool
mostly_zeros_p (const_tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
@@ -6886,9 +6886,9 @@ mostly_zeros_p (const_tree exp)
return initializer_zerop (exp);
}
-/* Return 1 if EXP contains all zeros. */
+/* Return true if EXP contains all zeros. */
-static int
+static bool
all_zeros_p (const_tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
@@ -7146,10 +7146,10 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
{
tree value, index;
unsigned HOST_WIDE_INT i;
- int need_to_clear;
+ bool need_to_clear;
tree domain;
tree elttype = TREE_TYPE (type);
- int const_bounds_p;
+ bool const_bounds_p;
HOST_WIDE_INT minelt = 0;
HOST_WIDE_INT maxelt = 0;
@@ -7173,9 +7173,9 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
the whole array first. Similarly if this is static
constructor of a non-BLKmode object. */
if (cleared)
- need_to_clear = 0;
+ need_to_clear = false;
else if (REG_P (target) && TREE_STATIC (exp))
- need_to_clear = 1;
+ need_to_clear = true;
else
{
unsigned HOST_WIDE_INT idx;
@@ -7200,7 +7200,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
if (! tree_fits_uhwi_p (lo_index)
|| ! tree_fits_uhwi_p (hi_index))
{
- need_to_clear = 1;
+ need_to_clear = true;
break;
}
@@ -7221,7 +7221,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
if (! need_to_clear
&& (count < maxelt - minelt + 1
|| 4 * zero_count >= 3 * count))
- need_to_clear = 1;
+ need_to_clear = true;
}
if (need_to_clear && maybe_gt (size, 0))
@@ -7413,7 +7413,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
unsigned HOST_WIDE_INT idx;
constructor_elt *ce;
int i;
- int need_to_clear;
+ bool need_to_clear;
insn_code icode = CODE_FOR_nothing;
tree elt;
tree elttype = TREE_TYPE (type);
@@ -7447,6 +7447,19 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
emit_move_insn (target, ops[0].value);
break;
}
+ /* Use sign-extension for uniform boolean vectors with
+ integer modes. */
+ if (!TREE_SIDE_EFFECTS (exp)
+ && VECTOR_BOOLEAN_TYPE_P (type)
+ && SCALAR_INT_MODE_P (mode)
+ && (elt = uniform_vector_p (exp))
+ && !VECTOR_TYPE_P (TREE_TYPE (elt)))
+ {
+ rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)),
+ expand_normal (elt));
+ convert_move (target, op0, 0);
+ break;
+ }
n_elts = TYPE_VECTOR_SUBPARTS (type);
if (REG_P (target)
@@ -7498,9 +7511,9 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
clear the whole array first. Similarly if this is static
constructor of a non-BLKmode object. */
if (cleared)
- need_to_clear = 0;
+ need_to_clear = false;
else if (REG_P (target) && TREE_STATIC (exp))
- need_to_clear = 1;
+ need_to_clear = true;
else
{
unsigned HOST_WIDE_INT count = 0, zero_count = 0;
@@ -8270,15 +8283,15 @@ force_operand (rtx value, rtx target)
return value;
}
-/* Subroutine of expand_expr: return nonzero iff there is no way that
+/* Subroutine of expand_expr: return true iff there is no way that
EXP can reference X, which is being modified. TOP_P is nonzero if this
call is going to be used to determine whether we need a temporary
for EXP, as opposed to a recursive call to this function.
- It is always safe for this routine to return zero since it merely
+ It is always safe for this routine to return false since it merely
searches for optimization opportunities. */
-int
+bool
safe_from_p (const_rtx x, tree exp, int top_p)
{
rtx exp_rtl = 0;
@@ -8303,7 +8316,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
&& (XEXP (x, 0) == virtual_outgoing_args_rtx
|| (GET_CODE (XEXP (x, 0)) == PLUS
&& XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
- return 1;
+ return true;
/* If this is a subreg of a hard register, declare it unsafe, otherwise,
find the underlying pseudo. */
@@ -8311,7 +8324,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
{
x = SUBREG_REG (x);
if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
- return 0;
+ return false;
}
/* Now look at our tree code and possibly recurse. */
@@ -8322,7 +8335,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
break;
case tcc_constant:
- return 1;
+ return true;
case tcc_exceptional:
if (TREE_CODE (exp) == TREE_LIST)
@@ -8330,10 +8343,10 @@ safe_from_p (const_rtx x, tree exp, int top_p)
while (1)
{
if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
- return 0;
+ return false;
exp = TREE_CHAIN (exp);
if (!exp)
- return 1;
+ return true;
if (TREE_CODE (exp) != TREE_LIST)
return safe_from_p (x, exp, 0);
}
@@ -8346,13 +8359,13 @@ safe_from_p (const_rtx x, tree exp, int top_p)
FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (exp), idx, ce)
if ((ce->index != NULL_TREE && !safe_from_p (x, ce->index, 0))
|| !safe_from_p (x, ce->value, 0))
- return 0;
- return 1;
+ return false;
+ return true;
}
else if (TREE_CODE (exp) == ERROR_MARK)
- return 1; /* An already-visited SAVE_EXPR? */
+ return true; /* An already-visited SAVE_EXPR? */
else
- return 0;
+ return false;
case tcc_statement:
/* The only case we look at here is the DECL_INITIAL inside a
@@ -8365,7 +8378,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
case tcc_binary:
case tcc_comparison:
if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
- return 0;
+ return false;
/* Fall through. */
case tcc_unary:
@@ -8387,7 +8400,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
if (staticp (TREE_OPERAND (exp, 0))
|| TREE_STATIC (exp)
|| safe_from_p (x, TREE_OPERAND (exp, 0), 0))
- return 1;
+ return true;
/* Otherwise, the only way this can conflict is if we are taking
the address of a DECL a that address if part of X, which is
@@ -8397,7 +8410,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
{
if (!DECL_RTL_SET_P (exp)
|| !MEM_P (DECL_RTL (exp)))
- return 0;
+ return false;
else
exp_rtl = XEXP (DECL_RTL (exp), 0);
}
@@ -8407,7 +8420,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
if (MEM_P (x)
&& alias_sets_conflict_p (MEM_ALIAS_SET (x),
get_alias_set (exp)))
- return 0;
+ return false;
break;
case CALL_EXPR:
@@ -8415,7 +8428,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
all of memory. */
if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
|| MEM_P (x))
- return 0;
+ return false;
break;
case WITH_CLEANUP_EXPR:
@@ -8438,7 +8451,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
for (i = 0; i < nops; i++)
if (TREE_OPERAND (exp, i) != 0
&& ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
- return 0;
+ return false;
break;
@@ -8456,7 +8469,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
exp_rtl = SUBREG_REG (exp_rtl);
if (REG_P (exp_rtl)
&& REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
- return 0;
+ return false;
}
/* If the rtl is X, then it is not safe. Otherwise, it is unless both
@@ -8467,7 +8480,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
}
/* If we reach here, it is safe. */
- return 1;
+ return true;
}
@@ -12182,11 +12195,11 @@ reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
}
}
-/* Subroutine of above: returns 1 if OFFSET corresponds to an offset that
+/* Subroutine of above: returns true if OFFSET corresponds to an offset that
when applied to the address of EXP produces an address known to be
aligned more than BIGGEST_ALIGNMENT. */
-static int
+static bool
is_aligning_offset (const_tree offset, const_tree exp)
{
/* Strip off any conversions. */
@@ -12200,7 +12213,7 @@ is_aligning_offset (const_tree offset, const_tree exp)
|| compare_tree_int (TREE_OPERAND (offset, 1),
BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
|| !pow2p_hwi (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1))
- return 0;
+ return false;
/* Look at the first operand of BIT_AND_EXPR and strip any conversion.
It must be NEGATE_EXPR. Then strip any more conversions. */
@@ -12209,7 +12222,7 @@ is_aligning_offset (const_tree offset, const_tree exp)
offset = TREE_OPERAND (offset, 0);
if (TREE_CODE (offset) != NEGATE_EXPR)
- return 0;
+ return false;
offset = TREE_OPERAND (offset, 0);
while (CONVERT_EXPR_P (offset))
@@ -13207,12 +13220,12 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
&& !TYPE_UNSIGNED (ops->type)) ? -1 : 1);
}
-/* Attempt to generate a casesi instruction. Returns 1 if successful,
- 0 otherwise (i.e. if there is no casesi instruction).
+/* Attempt to generate a casesi instruction. Returns true if successful,
+ false otherwise (i.e. if there is no casesi instruction).
DEFAULT_PROBABILITY is the probability of jumping to the default
label. */
-int
+bool
try_casesi (tree index_type, tree index_expr, tree minval, tree range,
rtx table_label, rtx default_label, rtx fallback_label,
profile_probability default_probability)
@@ -13222,7 +13235,7 @@ try_casesi (tree index_type, tree index_expr, tree minval, tree range,
rtx op1, op2, index;
if (! targetm.have_casesi ())
- return 0;
+ return false;
/* The index must be some form of integer. Convert it to SImode. */
scalar_int_mode omode = SCALAR_INT_TYPE_MODE (index_type);
@@ -13266,7 +13279,7 @@ try_casesi (tree index_type, tree index_expr, tree minval, tree range,
? default_label
: fallback_label));
expand_jump_insn (targetm.code_for_casesi, 5, ops);
- return 1;
+ return true;
}
/* Attempt to generate a tablejump instruction; same concept. */
@@ -13361,7 +13374,7 @@ do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label,
emit_barrier ();
}
-int
+bool
try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
rtx table_label, rtx default_label,
profile_probability default_probability)
@@ -13369,7 +13382,7 @@ try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
rtx index;
if (! targetm.have_tablejump ())
- return 0;
+ return false;
index_expr = fold_build2 (MINUS_EXPR, index_type,
fold_convert (index_type, index_expr),
@@ -13383,7 +13396,7 @@ try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
expand_normal (range),
TYPE_UNSIGNED (TREE_TYPE (range))),
table_label, default_label, default_probability);
- return 1;
+ return true;
}
/* Return a CONST_VECTOR rtx representing vector mask for
diff --git a/gcc/expr.h b/gcc/expr.h
index 0c059ed..11bff53 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -222,16 +222,16 @@ extern bool set_storage_via_setmem (rtx, rtx, rtx, unsigned int,
unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT);
-/* Return nonzero if it is desirable to store LEN bytes generated by
+/* Return true if it is desirable to store LEN bytes generated by
CONSTFUN with several move instructions by store_by_pieces
function. CONSTFUNDATA is a pointer which will be passed as argument
in every CONSTFUN call.
ALIGN is maximum alignment we can assume.
MEMSETP is true if this is a real memset/bzero, not a copy
of a const string. */
-extern int can_store_by_pieces (unsigned HOST_WIDE_INT,
- by_pieces_constfn,
- void *, unsigned int, bool);
+extern bool can_store_by_pieces (unsigned HOST_WIDE_INT,
+ by_pieces_constfn,
+ void *, unsigned int, bool);
/* Generate several move instructions to store LEN bytes generated by
CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
@@ -329,10 +329,12 @@ extern enum tree_code maybe_optimize_mod_cmp (enum tree_code, tree *, tree *);
extern void maybe_optimize_sub_cmp_0 (enum tree_code, tree *, tree *);
/* Two different ways of generating switch statements. */
-extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx, profile_probability);
-extern int try_tablejump (tree, tree, tree, tree, rtx, rtx, profile_probability);
+extern bool try_casesi (tree, tree, tree, tree, rtx, rtx, rtx,
+ profile_probability);
+extern bool try_tablejump (tree, tree, tree, tree, rtx, rtx,
+ profile_probability);
-extern int safe_from_p (const_rtx, tree, int);
+extern bool safe_from_p (const_rtx, tree, int);
/* Get the personality libfunc for a function decl. */
rtx get_personality_function (tree);
diff --git a/gcc/final.cc b/gcc/final.cc
index e614491..dd3e225 100644
--- a/gcc/final.cc
+++ b/gcc/final.cc
@@ -163,9 +163,9 @@ static int insn_counter = 0;
static int block_depth;
-/* Nonzero if have enabled APP processing of our assembler output. */
+/* True if have enabled APP processing of our assembler output. */
-static int app_on;
+static bool app_on;
/* If we are outputting an insn sequence, this contains the sequence rtx.
Zero otherwise. */
@@ -603,7 +603,7 @@ insn_current_reference_address (rtx_insn *branch)
/* Compute branch alignments based on CFG profile. */
-unsigned int
+void
compute_alignments (void)
{
basic_block bb;
@@ -617,7 +617,7 @@ compute_alignments (void)
/* If not optimizing or optimizing for size, don't assign any alignments. */
if (! optimize || optimize_function_for_size_p (cfun))
- return 0;
+ return;
if (dump_file)
{
@@ -721,7 +721,6 @@ compute_alignments (void)
loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
- return 0;
}
/* Grow the LABEL_ALIGN array after new labels are created. */
@@ -790,7 +789,8 @@ public:
/* opt_pass methods: */
unsigned int execute (function *) final override
{
- return compute_alignments ();
+ compute_alignments ();
+ return 0;
}
}; // class pass_compute_alignments
@@ -822,7 +822,7 @@ shorten_branches (rtx_insn *first)
int max_uid;
int i;
rtx_insn *seq;
- int something_changed = 1;
+ bool something_changed = true;
char *varying_length;
rtx body;
int uid;
@@ -1103,7 +1103,7 @@ shorten_branches (rtx_insn *first)
while (something_changed)
{
- something_changed = 0;
+ something_changed = false;
insn_current_align = MAX_CODE_ALIGN - 1;
for (insn_current_address = 0, insn = first;
insn != 0;
@@ -1136,7 +1136,7 @@ shorten_branches (rtx_insn *first)
{
log = newlog;
LABEL_TO_ALIGNMENT (insn) = log;
- something_changed = 1;
+ something_changed = true;
}
}
}
@@ -1274,7 +1274,7 @@ shorten_branches (rtx_insn *first)
* GET_MODE_SIZE (table->get_data_mode ()));
insn_current_address += insn_lengths[uid];
if (insn_lengths[uid] != old_length)
- something_changed = 1;
+ something_changed = true;
}
continue;
@@ -1332,7 +1332,7 @@ shorten_branches (rtx_insn *first)
if (!increasing || inner_length > insn_lengths[inner_uid])
{
insn_lengths[inner_uid] = inner_length;
- something_changed = 1;
+ something_changed = true;
}
else
inner_length = insn_lengths[inner_uid];
@@ -1358,7 +1358,7 @@ shorten_branches (rtx_insn *first)
&& (!increasing || new_length > insn_lengths[uid]))
{
insn_lengths[uid] = new_length;
- something_changed = 1;
+ something_changed = true;
}
else
insn_current_address += insn_lengths[uid] - new_length;
@@ -4043,9 +4043,9 @@ asm_fprintf (FILE *file, const char *p, ...)
va_end (argptr);
}
-/* Return nonzero if this function has no function calls. */
+/* Return true if this function has no function calls. */
-int
+bool
leaf_function_p (void)
{
rtx_insn *insn;
@@ -4056,29 +4056,29 @@ leaf_function_p (void)
/* Some back-ends (e.g. s390) want leaf functions to stay leaf
functions even if they call mcount. */
if (crtl->profile && !targetm.keep_leaf_when_profiled ())
- return 0;
+ return false;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
if (CALL_P (insn)
&& ! SIBLING_CALL_P (insn)
&& ! FAKE_CALL_P (insn))
- return 0;
+ return false;
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE
&& CALL_P (XVECEXP (PATTERN (insn), 0, 0))
&& ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-/* Return 1 if branch is a forward branch.
+/* Return true if branch is a forward branch.
Uses insn_shuid array, so it works only in the final pass. May be used by
output templates to customary add branch prediction hints.
*/
-int
+bool
final_forward_branch_p (rtx_insn *insn)
{
int insn_id, label_id;
@@ -4102,10 +4102,10 @@ final_forward_branch_p (rtx_insn *insn)
#ifdef LEAF_REGISTERS
-/* Return 1 if this function uses only the registers that can be
+/* Return bool if this function uses only the registers that can be
safely renumbered. */
-int
+bool
only_leaf_regs_used (void)
{
int i;
@@ -4114,15 +4114,15 @@ only_leaf_regs_used (void)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if ((df_regs_ever_live_p (i) || global_regs[i])
&& ! permitted_reg_in_leaf_functions[i])
- return 0;
+ return false;
if (crtl->uses_pic_offset_table
&& pic_offset_table_rtx != 0
&& REG_P (pic_offset_table_rtx)
&& ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
- return 0;
+ return false;
- return 1;
+ return true;
}
/* Scan all instructions and renumber all registers into those
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 78dbdbe..36305de 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -338,6 +338,7 @@ namespace zero_regs_flags {
const unsigned int ONLY_GPR = 1UL << 2;
const unsigned int ONLY_ARG = 1UL << 3;
const unsigned int ENABLED = 1UL << 4;
+ const unsigned int LEAFY_MODE = 1UL << 5;
const unsigned int USED_GPR_ARG = ENABLED | ONLY_USED | ONLY_GPR | ONLY_ARG;
const unsigned int USED_GPR = ENABLED | ONLY_USED | ONLY_GPR;
const unsigned int USED_ARG = ENABLED | ONLY_USED | ONLY_ARG;
@@ -346,6 +347,10 @@ namespace zero_regs_flags {
const unsigned int ALL_GPR = ENABLED | ONLY_GPR;
const unsigned int ALL_ARG = ENABLED | ONLY_ARG;
const unsigned int ALL = ENABLED;
+ const unsigned int LEAFY_GPR_ARG = ENABLED | LEAFY_MODE | ONLY_GPR | ONLY_ARG;
+ const unsigned int LEAFY_GPR = ENABLED | LEAFY_MODE | ONLY_GPR;
+ const unsigned int LEAFY_ARG = ENABLED | LEAFY_MODE | ONLY_ARG;
+ const unsigned int LEAFY = ENABLED | LEAFY_MODE;
}
/* Settings of flag_incremental_link. */
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 3aa6851..a02ede7 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -922,8 +922,8 @@ split_tree (tree in, tree type, enum tree_code code,
{
tree op0 = TREE_OPERAND (in, 0);
tree op1 = TREE_OPERAND (in, 1);
- int neg1_p = TREE_CODE (in) == MINUS_EXPR;
- int neg_litp_p = 0, neg_conp_p = 0, neg_var_p = 0;
+ bool neg1_p = TREE_CODE (in) == MINUS_EXPR;
+ bool neg_litp_p = false, neg_conp_p = false, neg_var_p = false;
/* First see if either of the operands is a literal, then a constant. */
if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST
@@ -1450,7 +1450,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
FIXED_VALUE_TYPE f2;
FIXED_VALUE_TYPE result;
tree t, type;
- int sat_p;
+ bool sat_p;
bool overflow_p;
/* The following codes are handled by fixed_arithmetic. */
@@ -5680,7 +5680,7 @@ bool
merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
tree high0, int in1_p, tree low1, tree high1)
{
- int no_overlap;
+ bool no_overlap;
int subset;
int temp;
tree tem;
@@ -6855,7 +6855,7 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
> GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type)))
? wide_type : type);
tree t1, t2;
- int same_p = tcode == code;
+ bool same_p = tcode == code;
tree op0 = NULL_TREE, op1 = NULL_TREE;
bool sub_strict_overflow_p;
@@ -7467,17 +7467,17 @@ bool
tree_swap_operands_p (const_tree arg0, const_tree arg1)
{
if (CONSTANT_CLASS_P (arg1))
- return 0;
+ return false;
if (CONSTANT_CLASS_P (arg0))
- return 1;
+ return true;
STRIP_NOPS (arg0);
STRIP_NOPS (arg1);
if (TREE_CONSTANT (arg1))
- return 0;
+ return false;
if (TREE_CONSTANT (arg0))
- return 1;
+ return true;
/* It is preferable to swap two SSA_NAME to ensure a canonical form
for commutative and comparison operators. Ensuring a canonical
@@ -7486,21 +7486,21 @@ tree_swap_operands_p (const_tree arg0, const_tree arg1)
if (TREE_CODE (arg0) == SSA_NAME
&& TREE_CODE (arg1) == SSA_NAME
&& SSA_NAME_VERSION (arg0) > SSA_NAME_VERSION (arg1))
- return 1;
+ return true;
/* Put SSA_NAMEs last. */
if (TREE_CODE (arg1) == SSA_NAME)
- return 0;
+ return false;
if (TREE_CODE (arg0) == SSA_NAME)
- return 1;
+ return true;
/* Put variables last. */
if (DECL_P (arg1))
- return 0;
+ return false;
if (DECL_P (arg0))
- return 1;
+ return true;
- return 0;
+ return false;
}
@@ -9693,10 +9693,10 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type,
tree a01 = TREE_OPERAND (arg0, 1);
tree a10 = TREE_OPERAND (arg1, 0);
tree a11 = TREE_OPERAND (arg1, 1);
- int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
- || TREE_CODE (arg0) == TRUTH_AND_EXPR)
- && (code == TRUTH_AND_EXPR
- || code == TRUTH_OR_EXPR));
+ bool commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
+ || TREE_CODE (arg0) == TRUTH_AND_EXPR)
+ && (code == TRUTH_AND_EXPR
+ || code == TRUTH_OR_EXPR));
if (operand_equal_p (a00, a10, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
@@ -12564,10 +12564,10 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
tree targ1 = strip_float_extensions (arg1);
tree newtype = TREE_TYPE (targ0);
- if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
+ if (element_precision (TREE_TYPE (targ1)) > element_precision (newtype))
newtype = TREE_TYPE (targ1);
- if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
+ if (element_precision (newtype) < element_precision (TREE_TYPE (arg0)))
return fold_build2_loc (loc, code, type,
fold_convert_loc (loc, newtype, targ0),
fold_convert_loc (loc, newtype, targ1));
@@ -14012,8 +14012,8 @@ fold_binary_initializer_loc (location_t loc, tree_code code, tree type,
#undef START_FOLD_INIT
#undef END_FOLD_INIT
-/* Determine if first argument is a multiple of second argument. Return 0 if
- it is not, or we cannot easily determined it to be.
+/* Determine if first argument is a multiple of second argument. Return
+ false if it is not, or we cannot easily determined it to be.
An example of the sort of thing we care about (at this point; this routine
could surely be made more general, and expanded to do what the *_DIV_EXPR's
@@ -14058,17 +14058,17 @@ fold_binary_initializer_loc (location_t loc, tree_code code, tree type,
NOWRAP is mostly used to treat expressions in TYPE_SIZE and friends
as not wrapping even though they are generally using unsigned arithmetic. */
-int
+bool
multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
{
gimple *stmt;
tree op1, op2;
if (operand_equal_p (top, bottom, 0))
- return 1;
+ return true;
if (TREE_CODE (type) != INTEGER_TYPE)
- return 0;
+ return false;
switch (TREE_CODE (top))
{
@@ -14076,7 +14076,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
/* Bitwise and provides a power of two multiple. If the mask is
a multiple of BOTTOM then TOP is a multiple of BOTTOM. */
if (!integer_pow2p (bottom))
- return 0;
+ return false;
return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom, nowrap)
|| multiple_of_p (type, TREE_OPERAND (top, 0), bottom, nowrap));
@@ -14087,7 +14087,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
if (!nowrap
&& !TYPE_OVERFLOW_UNDEFINED (type)
&& !integer_pow2p (bottom))
- return 0;
+ return false;
if (TREE_CODE (bottom) == INTEGER_CST)
{
op1 = TREE_OPERAND (top, 0);
@@ -14097,7 +14097,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
if (TREE_CODE (op2) == INTEGER_CST)
{
if (multiple_of_p (type, op2, bottom, nowrap))
- return 1;
+ return true;
/* Handle multiple_of_p ((x * 2 + 2) * 4, 8). */
if (multiple_of_p (type, bottom, op2, nowrap))
{
@@ -14129,7 +14129,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
nowrap);
}
}
- return 0;
+ return false;
case MINUS_EXPR:
case PLUS_EXPR:
@@ -14139,7 +14139,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
if (!nowrap
&& !TYPE_OVERFLOW_UNDEFINED (type)
&& !integer_pow2p (bottom))
- return 0;
+ return false;
/* Handle cases like op0 + 0xfffffffd as op0 - 3 if the expression has
unsigned type. For example, (X / 3) + 0xfffffffd is multiple of 3,
@@ -14163,7 +14163,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
|| (TYPE_PRECISION (type)
< TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0)))))
- return 0;
+ return false;
/* NOWRAP only extends to operations in the outermost type so
make sure to strip it off here. */
return multiple_of_p (TREE_TYPE (TREE_OPERAND (top, 0)),
@@ -14178,7 +14178,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
case INTEGER_CST:
if (TREE_CODE (bottom) != INTEGER_CST || integer_zerop (bottom))
- return 0;
+ return false;
return wi::multiple_of_p (wi::to_widest (top), wi::to_widest (bottom),
SIGNED);
@@ -14204,7 +14204,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
&& integer_pow2p (bottom)
&& wi::multiple_of_p (wi::to_widest (op2),
wi::to_widest (bottom), UNSIGNED))
- return 1;
+ return true;
op1 = gimple_assign_rhs1 (stmt);
if (code == MINUS_EXPR
@@ -14215,7 +14215,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
&& (code = gimple_assign_rhs_code (stmt)) == TRUNC_MOD_EXPR
&& operand_equal_p (op1, gimple_assign_rhs1 (stmt), 0)
&& operand_equal_p (bottom, gimple_assign_rhs2 (stmt), 0))
- return 1;
+ return true;
}
/* fall through */
@@ -14225,7 +14225,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
return multiple_p (wi::to_poly_widest (top),
wi::to_poly_widest (bottom));
- return 0;
+ return false;
}
}
@@ -14530,7 +14530,8 @@ tree_expr_maybe_real_minus_zero_p (const_tree x)
static bool
tree_simple_nonnegative_warnv_p (enum tree_code code, tree type)
{
- if ((TYPE_PRECISION (type) != 1 || TYPE_UNSIGNED (type))
+ if (!VECTOR_TYPE_P (type)
+ && (TYPE_PRECISION (type) != 1 || TYPE_UNSIGNED (type))
&& truth_value_p (code))
/* Truth values evaluate to 0 or 1, which is nonnegative unless we
have a signed:1 type (where the value is -1 and 0). */
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 24c50fc..3d08528 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -103,7 +103,7 @@ extern void fold_overflow_warning (const char*, enum warn_strict_overflow_code);
extern enum tree_code fold_div_compare (enum tree_code, tree, tree,
tree *, tree *, bool *);
extern bool operand_equal_p (const_tree, const_tree, unsigned int flags = 0);
-extern int multiple_of_p (tree, const_tree, const_tree, bool = true);
+extern bool multiple_of_p (tree, const_tree, const_tree, bool = true);
#define omit_one_operand(T1,T2,T3)\
omit_one_operand_loc (UNKNOWN_LOCATION, T1, T2, T3)
extern tree omit_one_operand_loc (location_t, tree, tree, tree);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f0424c6..92385a0 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,35 @@
+2023-06-28 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/110360
+ * trans-expr.cc (gfc_conv_procedure_call): For non-constant string
+ argument passed to CHARACTER(LEN=1),VALUE dummy, ensure proper
+ dereferencing and truncation of string to length 1.
+
+2023-06-28 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/49213
+ * expr.cc (gfc_is_ptr_fcn): Remove reference to class_pointer.
+ * resolve.cc (resolve_assoc_var): Call gfc_is_ptr_fcn to allow
+ associate names with pointer function targets to be used in
+ variable definition context.
+ * trans-decl.cc (get_symbol_decl): Remove extraneous line.
+ * trans-expr.cc (alloc_scalar_allocatable_subcomponent): Obtain
+ size of intrinsic and character expressions.
+ (gfc_trans_subcomponent_assign): Expand assignment to class
+ components to include intrinsic and character expressions.
+
+2023-06-24 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/110360
+ * trans-expr.cc (gfc_conv_procedure_call): Truncate constant string
+ argument of length > 1 passed to scalar CHARACTER(1),VALUE dummy.
+
+2023-06-23 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/110360
+ * trans-expr.cc (gfc_conv_procedure_call): Pass actual argument
+ to scalar CHARACTER(1),VALUE dummy argument by value.
+
2023-06-21 Paul Thomas <pault@gcc.gnu.org>
PR fortran/87477
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index c960dfe..e418f1f 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -816,9 +816,7 @@ bool
gfc_is_ptr_fcn (gfc_expr *e)
{
return e != NULL && e->expr_type == EXPR_FUNCTION
- && (gfc_expr_attr (e).pointer
- || (e->ts.type == BT_CLASS
- && CLASS_DATA (e)->attr.class_pointer));
+ && gfc_expr_attr (e).pointer;
}
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 82e6ac5..8e018b6 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -1350,6 +1350,9 @@ resolve_structure_cons (gfc_expr *expr, int init)
&& CLASS_DATA (comp)->as)
rank = CLASS_DATA (comp)->as->rank;
+ if (comp->ts.type == BT_CLASS && cons->expr->ts.type != BT_CLASS)
+ gfc_find_vtab (&cons->expr->ts);
+
if (cons->expr->expr_type != EXPR_NULL && rank != cons->expr->rank
&& (comp->attr.allocatable || cons->expr->rank))
{
@@ -1381,7 +1384,7 @@ resolve_structure_cons (gfc_expr *expr, int init)
gfc_basic_typename (comp->ts.type));
t = false;
}
- else
+ else if (!UNLIMITED_POLY (comp))
{
bool t2 = gfc_convert_type (cons->expr, &comp->ts, 1);
if (t)
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 18589e1..b0fd25e 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -1915,7 +1915,6 @@ gfc_get_symbol_decl (gfc_symbol * sym)
gcc_assert (!sym->value || sym->value->expr_type == EXPR_NULL);
}
-
gfc_finish_var_decl (decl, sym);
if (sym->ts.type == BT_CHARACTER)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 3c209bc..30946ba 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6392,6 +6392,35 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else
{
gfc_conv_expr (&parmse, e);
+
+ /* ABI: actual arguments to CHARACTER(len=1),VALUE
+ dummy arguments are actually passed by value.
+ Strings are truncated to length 1.
+ The BIND(C) case is handled elsewhere. */
+ if (fsym->ts.type == BT_CHARACTER
+ && !fsym->ts.is_c_interop
+ && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT
+ && fsym->ts.u.cl->length->ts.type == BT_INTEGER
+ && (mpz_cmp_ui
+ (fsym->ts.u.cl->length->value.integer, 1) == 0))
+ {
+ if (e->expr_type != EXPR_CONSTANT)
+ {
+ tree slen1 = build_int_cst (gfc_charlen_type_node, 1);
+ gfc_conv_string_parameter (&parmse);
+ parmse.expr = gfc_string_to_single_character (slen1,
+ parmse.expr,
+ e->ts.kind);
+ /* Truncate resulting string to length 1. */
+ parmse.string_length = slen1;
+ }
+ else if (e->value.character.length > 1)
+ {
+ e->value.character.length = 1;
+ gfc_conv_expr (&parmse, e);
+ }
+ }
+
if (fsym->attr.optional
&& fsym->ts.type != BT_CLASS
&& fsym->ts.type != BT_DERIVED)
@@ -8781,6 +8810,7 @@ alloc_scalar_allocatable_subcomponent (stmtblock_t *block, tree comp,
tree size;
tree size_in_bytes;
tree lhs_cl_size = NULL_TREE;
+ gfc_se se;
if (!comp)
return;
@@ -8815,16 +8845,30 @@ alloc_scalar_allocatable_subcomponent (stmtblock_t *block, tree comp,
}
else if (cm->ts.type == BT_CLASS)
{
- gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
- if (expr2->ts.type == BT_DERIVED)
+ if (expr2->ts.type != BT_CLASS)
{
- tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
- size = TYPE_SIZE_UNIT (tmp);
+ if (expr2->ts.type == BT_CHARACTER)
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, expr2);
+ size = build_int_cst (gfc_charlen_type_node, expr2->ts.kind);
+ size = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_charlen_type_node,
+ se.string_length, size);
+ size = fold_convert (size_type_node, size);
+ }
+ else
+ {
+ if (expr2->ts.type == BT_DERIVED)
+ tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
+ else
+ tmp = gfc_typenode_for_spec (&expr2->ts);
+ size = TYPE_SIZE_UNIT (tmp);
+ }
}
else
{
gfc_expr *e2vtab;
- gfc_se se;
e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
gfc_add_vptr_component (e2vtab);
gfc_add_size_component (e2vtab);
@@ -8975,6 +9019,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm,
{
gfc_init_se (&se, NULL);
gfc_conv_expr (&se, expr);
+ tree size;
/* Take care about non-array allocatable components here. The alloc_*
routine below is motivated by the alloc_scalar_allocatable_for_
@@ -8990,7 +9035,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm,
&& expr->symtree->n.sym->attr.dummy)
se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
- if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
+ if (cm->ts.type == BT_CLASS)
{
tmp = gfc_class_data_get (dest);
tmp = build_fold_indirect_ref_loc (input_location, tmp);
@@ -9005,7 +9050,6 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm,
/* For deferred strings insert a memcpy. */
if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
{
- tree size;
gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
size = size_of_string_in_bytes (cm->ts.kind, se.string_length
? se.string_length
@@ -9013,6 +9057,36 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm,
tmp = gfc_build_memcpy_call (tmp, se.expr, size);
gfc_add_expr_to_block (&block, tmp);
}
+ else if (cm->ts.type == BT_CLASS)
+ {
+ /* Fix the expression for memcpy. */
+ if (expr->expr_type != EXPR_VARIABLE)
+ se.expr = gfc_evaluate_now (se.expr, &block);
+
+ if (expr->ts.type == BT_CHARACTER)
+ {
+ size = build_int_cst (gfc_charlen_type_node, expr->ts.kind);
+ size = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_charlen_type_node,
+ se.string_length, size);
+ size = fold_convert (size_type_node, size);
+ }
+ else
+ size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr->ts));
+
+ /* Now copy the expression to the constructor component _data. */
+ gfc_add_expr_to_block (&block,
+ gfc_build_memcpy_call (tmp, se.expr, size));
+
+ /* Fill the unlimited polymorphic _len field. */
+ if (UNLIMITED_POLY (cm) && expr->ts.type == BT_CHARACTER)
+ {
+ tmp = gfc_class_len_get (gfc_get_class_from_expr (tmp));
+ gfc_add_modify (&block, tmp,
+ fold_convert (TREE_TYPE (tmp),
+ se.string_length));
+ }
+ }
else
gfc_add_modify (&block, tmp,
fold_convert (TREE_TYPE (tmp), se.expr));
diff --git a/gcc/function.cc b/gcc/function.cc
index 6a79a82..dd2c113 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -5866,6 +5866,9 @@ gen_call_used_regs_seq (rtx_insn *ret, unsigned int zero_regs_type)
only_used = zero_regs_type & ONLY_USED;
only_arg = zero_regs_type & ONLY_ARG;
+ if ((zero_regs_type & LEAFY_MODE) && leaf_function_p ())
+ only_used = true;
+
/* For each of the hard registers, we should zero it if:
1. it is a call-used register;
and 2. it is not a fixed register;
diff --git a/gcc/gengtype-parse.cc b/gcc/gengtype-parse.cc
index 2b2156c..19184d7 100644
--- a/gcc/gengtype-parse.cc
+++ b/gcc/gengtype-parse.cc
@@ -450,6 +450,12 @@ consume_until_comma_or_eos ()
parse_error ("unexpected end of file while scanning for ',' or ';'");
return false;
+ case '=':
+ advance ();
+ if (token () == '{')
+ consume_balanced ('{', '}');
+ break;
+
default:
advance ();
break;
diff --git a/gcc/ggc-page.cc b/gcc/ggc-page.cc
index c25218d..2f0b72e 100644
--- a/gcc/ggc-page.cc
+++ b/gcc/ggc-page.cc
@@ -1538,7 +1538,7 @@ gt_ggc_mx (unsigned char& x ATTRIBUTE_UNUSED)
P must have been allocated by the GC allocator; it mustn't point to
static objects, stack variables, or memory allocated with malloc. */
-int
+bool
ggc_set_mark (const void *p)
{
page_entry *entry;
@@ -1558,7 +1558,7 @@ ggc_set_mark (const void *p)
/* If the bit was previously set, skip it. */
if (entry->in_use_p[word] & mask)
- return 1;
+ return true;
/* Otherwise set it, and decrement the free object count. */
entry->in_use_p[word] |= mask;
@@ -1567,14 +1567,14 @@ ggc_set_mark (const void *p)
if (GGC_DEBUG_LEVEL >= 4)
fprintf (G.debug_file, "Marking %p\n", p);
- return 0;
+ return false;
}
-/* Return 1 if P has been marked, zero otherwise.
+/* Return true if P has been marked, zero otherwise.
P must have been allocated by the GC allocator; it mustn't point to
static objects, stack variables, or memory allocated with malloc. */
-int
+bool
ggc_marked_p (const void *p)
{
page_entry *entry;
diff --git a/gcc/ggc.h b/gcc/ggc.h
index 78eab7e..34108e2 100644
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -90,15 +90,15 @@ extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
/* Actually set the mark on a particular region of memory, but don't
follow pointers. This function is called by ggc_mark_*. It
- returns zero if the object was not previously marked; nonzero if
+ returns false if the object was not previously marked; true if
the object was already marked, or if, for any other reason,
pointers in this data structure should not be traversed. */
-extern int ggc_set_mark (const void *);
+extern bool ggc_set_mark (const void *);
-/* Return 1 if P has been marked, zero otherwise.
+/* Return true if P has been marked, zero otherwise.
P must have been allocated by the GC allocator; it mustn't point to
static objects, stack variables, or memory allocated with malloc. */
-extern int ggc_marked_p (const void *);
+extern bool ggc_marked_p (const void *);
/* PCH and GGC handling for strings, mostly trivial. */
extern void gt_pch_n_S (const void *);
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 55e8056..4027ff7 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -5370,10 +5370,10 @@ arith_overflowed_p (enum tree_code code, const_tree type,
return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
}
-/* If IFN_{MASK,LEN}_LOAD/STORE call CALL is unconditional, return a MEM_REF
- for the memory it references, otherwise return null. VECTYPE is the
- type of the memory vector. MASK_P indicates it's for MASK if true,
- otherwise it's for LEN. */
+/* If IFN_{MASK,LEN,LEN_MASK}_LOAD/STORE call CALL is unconditional,
+ return a MEM_REF for the memory it references, otherwise return null.
+ VECTYPE is the type of the memory vector. MASK_P indicates it's for
+ MASK if true, otherwise it's for LEN. */
static tree
gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype, bool mask_p)
@@ -5391,15 +5391,27 @@ gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype, bool mask_p)
}
else
{
- tree basic_len = gimple_call_arg (call, 2);
+ internal_fn ifn = gimple_call_internal_fn (call);
+ int len_index = internal_fn_len_index (ifn);
+ tree basic_len = gimple_call_arg (call, len_index);
if (!poly_int_tree_p (basic_len))
return NULL_TREE;
- unsigned int nargs = gimple_call_num_args (call);
- tree bias = gimple_call_arg (call, nargs - 1);
+ tree bias = gimple_call_arg (call, len_index + 1);
gcc_assert (TREE_CODE (bias) == INTEGER_CST);
- if (maybe_ne (wi::to_poly_widest (basic_len) - wi::to_widest (bias),
- GET_MODE_SIZE (TYPE_MODE (vectype))))
+ /* For LEN_LOAD/LEN_STORE/LEN_MASK_LOAD/LEN_MASK_STORE,
+ we don't fold when (bias + len) != VF. */
+ if (maybe_ne (wi::to_poly_widest (basic_len) + wi::to_widest (bias),
+ GET_MODE_NUNITS (TYPE_MODE (vectype))))
return NULL_TREE;
+
+ /* For LEN_MASK_{LOAD,STORE}, we should also check whether
+ the mask is all ones mask. */
+ if (ifn == IFN_LEN_MASK_LOAD || ifn == IFN_LEN_MASK_STORE)
+ {
+ tree mask = gimple_call_arg (call, internal_fn_mask_index (ifn));
+ if (!integer_all_onesp (mask))
+ return NULL_TREE;
+ }
}
unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align);
@@ -5438,7 +5450,8 @@ static bool
gimple_fold_partial_store (gimple_stmt_iterator *gsi, gcall *call,
bool mask_p)
{
- tree rhs = gimple_call_arg (call, 3);
+ internal_fn ifn = gimple_call_internal_fn (call);
+ tree rhs = gimple_call_arg (call, internal_fn_stored_value_index (ifn));
if (tree lhs
= gimple_fold_partial_load_store_mem_ref (call, TREE_TYPE (rhs), mask_p))
{
@@ -5676,9 +5689,11 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
changed |= gimple_fold_partial_store (gsi, stmt, true);
break;
case IFN_LEN_LOAD:
+ case IFN_LEN_MASK_LOAD:
changed |= gimple_fold_partial_load (gsi, stmt, false);
break;
case IFN_LEN_STORE:
+ case IFN_LEN_MASK_STORE:
changed |= gimple_fold_partial_store (gsi, stmt, false);
break;
default:
@@ -7836,12 +7851,11 @@ get_base_constructor (tree base, poly_int64_pod *bit_offset,
}
}
-/* CTOR is CONSTRUCTOR of an array type. Fold a reference of SIZE bits
- to the memory at bit OFFSET. When non-null, TYPE is the expected
- type of the reference; otherwise the type of the referenced element
- is used instead. When SIZE is zero, attempt to fold a reference to
- the entire element which OFFSET refers to. Increment *SUBOFF by
- the bit offset of the accessed element. */
+/* CTOR is a CONSTRUCTOR of an array or vector type. Fold a reference of SIZE
+ bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
+ the reference; otherwise the type of the referenced element is used instead.
+ When SIZE is zero, attempt to fold a reference to the entire element OFFSET
+ refers to. Increment *SUBOFF by the bit offset of the accessed element. */
static tree
fold_array_ctor_reference (tree type, tree ctor,
@@ -8006,13 +8020,11 @@ fold_array_ctor_reference (tree type, tree ctor,
return type ? build_zero_cst (type) : NULL_TREE;
}
-/* CTOR is CONSTRUCTOR of an aggregate or vector. Fold a reference
- of SIZE bits to the memory at bit OFFSET. When non-null, TYPE
- is the expected type of the reference; otherwise the type of
- the referenced member is used instead. When SIZE is zero,
- attempt to fold a reference to the entire member which OFFSET
- refers to; in this case. Increment *SUBOFF by the bit offset
- of the accessed member. */
+/* CTOR is a CONSTRUCTOR of a record or union type. Fold a reference of SIZE
+ bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
+ the reference; otherwise the type of the referenced member is used instead.
+ When SIZE is zero, attempt to fold a reference to the entire member OFFSET
+ refers to. Increment *SUBOFF by the bit offset of the accessed member. */
static tree
fold_nonarray_ctor_reference (tree type, tree ctor,
@@ -8024,8 +8036,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
unsigned HOST_WIDE_INT cnt;
tree cfield, cval;
- FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield,
- cval)
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
{
tree byte_offset = DECL_FIELD_OFFSET (cfield);
tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
@@ -8097,6 +8108,19 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
return NULL_TREE;
offset_int inner_offset = offset_int (offset) - bitoffset;
+
+ /* Integral bit-fields are left-justified on big-endian targets, so
+ we must arrange for native_encode_int to start at their MSB. */
+ if (DECL_BIT_FIELD (cfield) && INTEGRAL_TYPE_P (TREE_TYPE (cfield)))
+ {
+ if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ return NULL_TREE;
+ const unsigned int encoding_size
+ = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (cfield)));
+ if (BYTES_BIG_ENDIAN)
+ inner_offset += encoding_size - wi::to_offset (field_size);
+ }
+
return fold_ctor_reference (type, cval,
inner_offset.to_uhwi (), size,
from_decl, suboff);
@@ -8109,7 +8133,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
return build_zero_cst (type);
}
-/* CTOR is value initializing memory. Fold a reference of TYPE and
+/* CTOR is a value initializing memory. Fold a reference of TYPE and
bit size POLY_SIZE to the memory at bit POLY_OFFSET. When POLY_SIZE
is zero, attempt to fold a reference to the entire subobject
which OFFSET refers to. This is used when folding accesses to
@@ -8150,7 +8174,8 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
}
return ret;
}
- /* For constants and byte-aligned/sized reads try to go through
+
+ /* For constants and byte-aligned/sized reads, try to go through
native_encode/interpret. */
if (CONSTANT_CLASS_P (ctor)
&& BITS_PER_UNIT == 8
@@ -8166,7 +8191,12 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
if (len > 0)
return native_interpret_expr (type, buf, len);
}
- if (TREE_CODE (ctor) == CONSTRUCTOR)
+
+ /* For constructors, try first a recursive local processing, but in any case
+ this requires the native storage order. */
+ if (TREE_CODE (ctor) == CONSTRUCTOR
+ && !(AGGREGATE_TYPE_P (TREE_TYPE (ctor))
+ && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (ctor))))
{
unsigned HOST_WIDE_INT dummy = 0;
if (!suboff)
@@ -8181,9 +8211,9 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
ret = fold_nonarray_ctor_reference (type, ctor, offset, size,
from_decl, suboff);
- /* Fall back to native_encode_initializer. Needs to be done
- only in the outermost fold_ctor_reference call (because it itself
- recurses into CONSTRUCTORs) and doesn't update suboff. */
+ /* Otherwise fall back to native_encode_initializer. This may be done
+ only from the outermost fold_ctor_reference call (because it itself
+ recurses into CONSTRUCTORs and doesn't update suboff). */
if (ret == NULL_TREE
&& suboff == &dummy
&& BITS_PER_UNIT == 8
diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index 7f20f81..373163b 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -2216,11 +2216,11 @@ uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb,
return false;
use_preds.simplify (use_stmt, /*is_use=*/true);
+ use_preds.normalize (use_stmt, /*is_use=*/true);
if (use_preds.is_false ())
return true;
if (use_preds.is_true ())
return false;
- use_preds.normalize (use_stmt, /*is_use=*/true);
/* Try to prune the dead incoming phi edges. */
if (!overlap (phi, opnds, visited, use_preds))
@@ -2238,11 +2238,11 @@ uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb,
return false;
m_phi_def_preds.simplify (phi);
+ m_phi_def_preds.normalize (phi);
if (m_phi_def_preds.is_false ())
return false;
if (m_phi_def_preds.is_true ())
return true;
- m_phi_def_preds.normalize (phi);
}
/* Return true if the predicate guarding the valid definition (i.e.,
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index abc70cd..4ee0ae3 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -1291,13 +1291,26 @@ gori_compute::compute_operand1_and_operand2_range (vrange &r,
{
Value_Range op_range (TREE_TYPE (name));
- // 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, handler, lhs, name, src, rel))
+ // If op1 is in the def chain of op2, we'll do the work twice to evalaute
+ // op1. This can result in an exponential time calculation.
+ // Instead just evaluate op2, which will eventualy get to op1.
+ if (in_chain_p (handler.operand1 (), handler.operand2 ()))
+ return compute_operand2_range (r, handler, lhs, name, src, rel);
+
+ // Likewise if op2 is in the def chain of op1.
+ if (in_chain_p (handler.operand2 (), handler.operand1 ()))
+ return compute_operand1_range (r, handler, lhs, name, src, rel);
+
+ // Calculate a good a range through op2.
+ if (!compute_operand2_range (r, handler, lhs, name, src, rel))
return false;
+ // If op1 == op2 there is again no need to go further.
+ if (handler.operand1 () == handler.operand2 ())
+ return true;
+
// Now get the range thru op1.
- if (!compute_operand1_range (r, handler, lhs, name, src, rel))
+ if (!compute_operand1_range (op_range, handler, lhs, name, src, rel))
return false;
// Both operands have to be simultaneously true, so perform an intersection.
diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc
index 401496a..0d19b98 100644
--- a/gcc/gimple-ssa-store-merging.cc
+++ b/gcc/gimple-ssa-store-merging.cc
@@ -650,10 +650,13 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
/* Convert. */
n->type = TREE_TYPE (rhs1);
+ if (!verify_symbolic_number_p (n, stmt))
+ return NULL;
+
if (!n->base_addr)
n->range = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
- return verify_symbolic_number_p (n, stmt) ? stmt : NULL;
+ return stmt;
}
return NULL;
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 0e24b91..36e5df0 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -6935,7 +6935,12 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
inputs, outputs, clobbers, labels);
- gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
+ /* asm is volatile if it was marked by the user as volatile or
+ there are no outputs or this is an asm goto. */
+ gimple_asm_set_volatile (stmt,
+ ASM_VOLATILE_P (expr)
+ || noutputs == 0
+ || labels);
gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 507e2d3..432ae83 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,17 @@
+2023-06-26 Ian Lance Taylor <iant@golang.org>
+
+ * lang.opt (fgo-importcfg): New option.
+ * go-c.h (struct go_create_gogo_args): Add importcfg field.
+ * go-lang.cc (go_importcfg): New static variable.
+ (go_langhook_init): Set args.importcfg.
+ (go_langhook_handle_option): Handle -fgo-importcfg.
+ * gccgo.texi (Invoking gccgo): Document -fgo-importcfg.
+
+2023-06-22 Paul E. Murphy <murphyp@linux.ibm.com>
+
+ * go-backend.cc [TARGET_AIX]: Rename and update usage to TARGET_AIX_OS.
+ * go-lang.cc: Likewise.
+
2023-03-24 Jakub Jelinek <jakub@redhat.com>
PR middle-end/109258
diff --git a/gcc/go/gccgo.texi b/gcc/go/gccgo.texi
index 4ab1a76..90651af 100644
--- a/gcc/go/gccgo.texi
+++ b/gcc/go/gccgo.texi
@@ -271,6 +271,14 @@ pattern to a list of file names, and @code{Files} maps each file name
to a full path to the file. This option is intended for use by the
@command{go} command to implement @code{//go:embed}.
+@cindex @option{-fgo-importcfg}
+@item -fgo-importcfg=@var{file}
+Identify a file that provides mappings for import package paths found
+in the Go source files. The file can contain two commands:
+@code{importpath} to rename import paths for vendoring and
+@code{packagefile} to map from package path to files containing export
+data. This option is intended for use by the @command{go} command.
+
@cindex @option{-g for gccgo}
@item -g
This is the standard @command{gcc} option (@pxref{Debugging Options, ,
diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h
index c605038..6a2b57b 100644
--- a/gcc/go/go-c.h
+++ b/gcc/go/go-c.h
@@ -41,6 +41,7 @@ struct go_create_gogo_args
const char* prefix;
const char* relative_import_path;
const char* c_header;
+ const char* importcfg;
const char* embedcfg;
Backend* backend;
Linemap* linemap;
diff --git a/gcc/go/go-lang.cc b/gcc/go/go-lang.cc
index c6c147b..e85a4bf 100644
--- a/gcc/go/go-lang.cc
+++ b/gcc/go/go-lang.cc
@@ -90,6 +90,7 @@ static const char *go_prefix = NULL;
static const char *go_relative_import_path = NULL;
static const char *go_c_header = NULL;
static const char *go_embedcfg = NULL;
+static const char *go_importcfg = NULL;
/* Language hooks. */
@@ -111,6 +112,7 @@ go_langhook_init (void)
args.relative_import_path = go_relative_import_path;
args.c_header = go_c_header;
args.embedcfg = go_embedcfg;
+ args.importcfg = go_importcfg;
args.check_divide_by_zero = go_check_divide_zero;
args.check_divide_overflow = go_check_divide_overflow;
args.compiling_runtime = go_compiling_runtime;
@@ -286,6 +288,10 @@ go_langhook_handle_option (
go_embedcfg = arg;
break;
+ case OPT_fgo_importcfg_:
+ go_importcfg = arg;
+ break;
+
default:
/* Just return 1 to indicate that the option is valid. */
break;
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index a028350..c44cdc2 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-195060166e6045408a2cb95e6aa88c6f0b98f20b
+92152c88ea8e2dd9e8c67e91bf4ae5e3edf1b506
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/embed.cc b/gcc/go/gofrontend/embed.cc
index 0584f70..6dada5e 100644
--- a/gcc/go/gofrontend/embed.cc
+++ b/gcc/go/gofrontend/embed.cc
@@ -19,8 +19,8 @@
// Read a file into *DATA. Returns false on error.
-static bool
-read_file(const char* filename, Location loc, std::string* data)
+bool
+Gogo::read_file(const char* filename, Location loc, std::string* data)
{
int fd = open(filename, O_RDONLY | O_BINARY);
if (fd < 0)
@@ -346,7 +346,8 @@ Gogo::read_embedcfg(const char *filename)
bool
Embedcfg_reader::initialize_from_file()
{
- if (!read_file(this->filename_, Linemap::unknown_location(), &this->data_))
+ if (!Gogo::read_file(this->filename_, Linemap::unknown_location(),
+ &this->data_))
return false;
if (this->data_.empty())
{
@@ -849,7 +850,7 @@ Gogo::initializer_for_embeds(Type* type,
}
std::string data;
- if (!read_file(this->embed_files_[paths[0]].c_str(), loc, &data))
+ if (!Gogo::read_file(this->embed_files_[paths[0]].c_str(), loc, &data))
return Expression::make_error(loc);
Expression* e = Expression::make_string(data, loc);
@@ -909,7 +910,7 @@ Gogo::initializer_for_embeds(Type* type,
std::string data;
if ((*pp)[pp->size() - 1] != '/')
{
- if (!read_file(this->embed_files_[*pp].c_str(), loc, &data))
+ if (!Gogo::read_file(this->embed_files_[*pp].c_str(), loc, &data))
return Expression::make_error(loc);
}
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2112de6..d276bd8 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -12272,7 +12272,8 @@ Call_expression::intrinsify(Gogo* gogo,
return Runtime::make_call(code, loc, 3, a1, a2, a3);
}
}
- else if (package == "internal/abi")
+ else if (package == "internal/abi"
+ || package == "bootstrap/internal/abi") // for bootstrapping gc
{
if (is_method)
return NULL;
diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc
index 1512770..66d4816 100644
--- a/gcc/go/gofrontend/go.cc
+++ b/gcc/go/gofrontend/go.cc
@@ -40,6 +40,8 @@ go_create_gogo(const struct go_create_gogo_args* args)
::gogo->set_compiling_runtime(args->compiling_runtime);
if (args->c_header != NULL)
::gogo->set_c_header(args->c_header);
+ if (args->importcfg != NULL)
+ ::gogo->read_importcfg(args->importcfg);
if (args->embedcfg != NULL)
::gogo->read_embedcfg(args->embedcfg);
::gogo->set_debug_escape_level(args->debug_escape_level);
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 9197eef..fa3cd6e 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -52,6 +52,10 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size)
prefix_from_option_(false),
relative_import_path_(),
c_header_(),
+ import_map_(),
+ package_file_(),
+ embed_patterns_(),
+ embed_files_(),
check_divide_by_zero_(true),
check_divide_overflow_(true),
compiling_runtime_(false),
@@ -517,7 +521,20 @@ Gogo::import_package(const std::string& filename,
return;
}
- Import::Stream* stream = Import::open_package(filename, location,
+ // If we are using an importcfg file we have to check two mappings.
+ // IMPORT_MAP_ is a mapping from package path to real package path,
+ // for vendoring. PACKAGE_FILE_ is a mapping from package path to
+ // file name, to find the file in the build cache.
+ std::string path = filename;
+ Unordered_map(std::string, std::string)::const_iterator pi;
+ pi = this->import_map_.find(filename);
+ if (pi != this->import_map_.end())
+ path = pi->second;
+ pi = this->package_file_.find(path);
+ if (pi != this->package_file_.end())
+ path = pi->second;
+
+ Import::Stream* stream = Import::open_package(path, location,
this->relative_import_path_);
if (stream == NULL)
{
@@ -3296,6 +3313,9 @@ class Create_function_descriptors : public Traverse
int
expression(Expression**);
+ static bool
+ skip_descriptor(Gogo* gogo, const Named_object*);
+
private:
Gogo* gogo_;
};
@@ -3306,6 +3326,9 @@ class Create_function_descriptors : public Traverse
int
Create_function_descriptors::function(Named_object* no)
{
+ if (Create_function_descriptors::skip_descriptor(this->gogo_, no))
+ return TRAVERSE_CONTINUE;
+
if (no->is_function()
&& no->func_value()->enclosing() == NULL
&& !no->func_value()->is_method()
@@ -3393,6 +3416,28 @@ Create_function_descriptors::expression(Expression** pexpr)
return TRAVERSE_CONTINUE;
}
+// The gc compiler has some special cases that it always compiles as
+// intrinsics. For those we don't want to generate a function
+// descriptor, as there will be no code for it to refer to.
+
+bool
+Create_function_descriptors::skip_descriptor(Gogo* gogo,
+ const Named_object* no)
+{
+ const std::string& pkgpath(no->package() == NULL
+ ? gogo->pkgpath()
+ : no->package()->pkgpath());
+
+ // internal/abi is the standard library package,
+ // bootstrap/internal/abi is the name used when bootstrapping the gc
+ // compiler.
+
+ return ((pkgpath == "internal/abi"
+ || pkgpath == "bootstrap/internal/abi")
+ && (no->name() == "FuncPCABI0"
+ || no->name() == "FuncPCABIInternal"));
+}
+
// Create function descriptors as needed. We need a function
// descriptor for all exported functions and for all functions that
// are referenced without being called.
@@ -3414,7 +3459,8 @@ Gogo::create_function_descriptors()
if (no->is_function_declaration()
&& !no->func_declaration_value()->type()->is_method()
&& !Linemap::is_predeclared_location(no->location())
- && !Gogo::is_hidden_name(no->name()))
+ && !Gogo::is_hidden_name(no->name())
+ && !Create_function_descriptors::skip_descriptor(this, no))
fndecls.push_back(no);
}
for (std::vector<Named_object*>::const_iterator p = fndecls.begin();
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index c08a16b..4fd45bf 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -393,6 +393,10 @@ class Gogo
set_c_header(const std::string& s)
{ this->c_header_ = s; }
+ // Read an importcfg file.
+ void
+ read_importcfg(const char* filename);
+
// Read an embedcfg file.
void
read_embedcfg(const char* filename);
@@ -1126,6 +1130,10 @@ class Gogo
static size_t
special_name_pos(const std::string& name);
+ // Read a file into memory.
+ static bool
+ read_file(const char* filename, Location loc, std::string* data);
+
private:
// During parsing, we keep a stack of functions. Each function on
// the stack is one that we are currently parsing. For each
@@ -1295,6 +1303,10 @@ class Gogo
std::string relative_import_path_;
// The C header file to write, from the -fgo-c-header option.
std::string c_header_;
+ // Mapping from imports in the source file to the real import paths.
+ Unordered_map(std::string, std::string) import_map_;
+ // Mapping from import paths to files to read.
+ Unordered_map(std::string, std::string) package_file_;
// Patterns from an embedcfg file.
Embed_patterns embed_patterns_;
// Mapping from file to full path from an embedcfg file.
diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc
index 6a5491b..21691fa 100644
--- a/gcc/go/gofrontend/import.cc
+++ b/gcc/go/gofrontend/import.cc
@@ -34,6 +34,130 @@ go_add_search_path(const char* path)
search_path.push_back(std::string(path));
}
+// Read an importcfg file.
+
+void
+Gogo::read_importcfg(const char* filename)
+{
+ std::string data;
+ if (!Gogo::read_file(filename, Linemap::unknown_location(), &data))
+ return;
+ const char* p = data.data();
+ const char* pend = p + data.length();
+ int lineno = 0;
+ const char *pnext = NULL;
+ for (; p < pend; p = pnext)
+ {
+ // Line numbers start at 1.
+ lineno++;
+
+ // Find end of line.
+ const char* pnl = static_cast<const char*>(memchr(p, '\n', pend - p));
+ if (pnl != NULL)
+ pnext = pnl + 1;
+ else
+ {
+ pnl = pend;
+ pnext = pnl;
+ }
+
+ // Trim leading spaces.
+ while (p < pnl)
+ {
+ unsigned int rune;
+ int rune_len = Lex::fetch_char(p, &rune);
+ if (rune_len == 0)
+ {
+ go_error_at(Linemap::unknown_location(),
+ "%s:%d: invalid character in importcfg file",
+ filename, lineno);
+ return;
+ }
+ if (!Lex::is_unicode_space(rune))
+ break;
+ p += rune_len;
+ }
+
+ // Trim trailing spaces.
+ while (pnl > p)
+ {
+ size_t start = pnl - p - 1;
+ unsigned int rune = (unsigned char)p[start];
+ int rune_len = 1;
+ if (rune > 0x7f)
+ {
+ for (start--; start > 0; start--)
+ {
+ unsigned char c = p[start];
+ if ((c & 0xc0) != 0x80)
+ break;
+ }
+ rune_len = Lex::fetch_char(p + start, &rune);
+ if (static_cast<size_t>(rune_len) != (pnl - p) - start)
+ {
+ go_error_at(Linemap::unknown_location(),
+ "%s:%d: invalid character in importcfg file",
+ filename, lineno);
+ return;
+ }
+ }
+ if (!Lex::is_unicode_space(rune))
+ break;
+ pnl -= rune_len;
+ }
+
+ // Skip empty lines and comment lines.
+ if (p == pnl || *p == '#')
+ continue;
+
+ size_t verb_len;
+ const char* psp = static_cast<const char*>(memchr(p, ' ', pnl - p));
+ if (psp == NULL)
+ verb_len = pnl - p;
+ else
+ verb_len = psp - p;
+
+ bool importmap = false;
+ bool packagefile = false;
+ if (strncmp(p, "importmap", verb_len) == 0)
+ importmap = true;
+ else if (strncmp(p, "packagefile", verb_len) == 0)
+ packagefile = true;
+ else
+ {
+ go_error_at(Linemap::unknown_location(),
+ "%s:%d: unknown directive in importcfg file",
+ filename, lineno);
+ return;
+ }
+
+ const char* peq;
+ if (psp == NULL)
+ peq = NULL;
+ else
+ {
+ psp++;
+ peq = static_cast<const char*>(memchr(psp, '=', pnl - psp));
+ }
+ if (peq == NULL || peq + 1 == pnl)
+ {
+ go_error_at(Linemap::unknown_location(),
+ "%s:%d: invalid syntax in importcfg file",
+ filename, lineno);
+ return;
+ }
+
+ std::string first(psp, peq - psp);
+ std::string second(peq + 1, pnl - (peq + 1));
+ if (importmap)
+ this->import_map_[first] = second;
+ else if (packagefile)
+ this->package_file_[first] = second;
+ else
+ go_unreachable();
+ }
+}
+
// Find import data. This searches the file system for FILENAME and
// returns a pointer to a Stream object to read the data that it
// exports. If the file is not found, it returns NULL.
diff --git a/gcc/go/lang.opt b/gcc/go/lang.opt
index 4ca989c..0d658fc 100644
--- a/gcc/go/lang.opt
+++ b/gcc/go/lang.opt
@@ -61,6 +61,10 @@ fgo-embedcfg=
Go Joined RejectNegative
-fgo-embedcfg=<file> List embedded files via go:embed.
+fgo-importcfg=
+Go Joined RejectNegative
+-fgo-importcfg=<file> Provide file that tells where to find imports.
+
fgo-optimize-
Go Joined
-fgo-optimize-<type> Turn on optimization passes in the frontend.
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index c911ae7..303df10 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -165,7 +165,7 @@ init_internal_fns ()
#define mask_load_lanes_direct { -1, -1, false }
#define gather_load_direct { 3, 1, false }
#define len_load_direct { -1, -1, false }
-#define len_maskload_direct { -1, 3, false }
+#define len_maskload_direct { -1, 4, false }
#define mask_store_direct { 3, 2, false }
#define store_lanes_direct { 0, 0, false }
#define mask_store_lanes_direct { 0, 0, false }
@@ -173,7 +173,7 @@ init_internal_fns ()
#define vec_cond_direct { 2, 0, false }
#define scatter_store_direct { 3, 1, false }
#define len_store_direct { 3, 3, false }
-#define len_maskstore_direct { 4, 3, false }
+#define len_maskstore_direct { 4, 5, false }
#define vec_set_direct { 3, 3, false }
#define unary_direct { 0, 0, true }
#define unary_convert_direct { -1, 0, true }
@@ -293,6 +293,38 @@ get_multi_vector_move (tree array_type, convert_optab optab)
return convert_optab_handler (optab, imode, vmode);
}
+/* Add len and mask arguments according to the STMT. */
+
+static unsigned int
+add_len_and_mask_args (expand_operand *ops, unsigned int opno, gcall *stmt)
+{
+ internal_fn ifn = gimple_call_internal_fn (stmt);
+ int len_index = internal_fn_len_index (ifn);
+ /* BIAS is always consecutive next of LEN. */
+ int bias_index = len_index + 1;
+ int mask_index = internal_fn_mask_index (ifn);
+ /* The order of arguments are always {len,bias,mask}. */
+ if (len_index >= 0)
+ {
+ tree len = gimple_call_arg (stmt, len_index);
+ rtx len_rtx = expand_normal (len);
+ create_convert_operand_from (&ops[opno++], len_rtx,
+ TYPE_MODE (TREE_TYPE (len)),
+ TYPE_UNSIGNED (TREE_TYPE (len)));
+ tree biast = gimple_call_arg (stmt, bias_index);
+ rtx bias = expand_normal (biast);
+ create_input_operand (&ops[opno++], bias, QImode);
+ }
+ if (mask_index >= 0)
+ {
+ tree mask = gimple_call_arg (stmt, mask_index);
+ rtx mask_rtx = expand_normal (mask);
+ create_input_operand (&ops[opno++], mask_rtx,
+ TYPE_MODE (TREE_TYPE (mask)));
+ }
+ return opno;
+}
+
/* Expand LOAD_LANES call STMT using optab OPTAB. */
static void
@@ -2879,14 +2911,15 @@ expand_call_mem_ref (tree type, gcall *stmt, int index)
* OPTAB. */
static void
-expand_partial_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
+expand_partial_load_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab)
{
+ int i = 0;
class expand_operand ops[5];
- tree type, lhs, rhs, maskt, biast;
- rtx mem, target, mask, bias;
+ tree type, lhs, rhs, maskt;
+ rtx mem, target;
insn_code icode;
- maskt = gimple_call_arg (stmt, 2);
+ maskt = gimple_call_arg (stmt, internal_fn_mask_index (ifn));
lhs = gimple_call_lhs (stmt);
if (lhs == NULL_TREE)
return;
@@ -2903,38 +2936,11 @@ expand_partial_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
gcc_assert (MEM_P (mem));
- mask = expand_normal (maskt);
target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
- create_output_operand (&ops[0], target, TYPE_MODE (type));
- create_fixed_operand (&ops[1], mem);
- if (optab == len_load_optab)
- {
- create_convert_operand_from (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)),
- TYPE_UNSIGNED (TREE_TYPE (maskt)));
- biast = gimple_call_arg (stmt, 3);
- bias = expand_normal (biast);
- create_input_operand (&ops[3], bias, QImode);
- expand_insn (icode, 4, ops);
- }
- else if (optab == len_maskload_optab)
- {
- create_convert_operand_from (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)),
- TYPE_UNSIGNED (TREE_TYPE (maskt)));
- maskt = gimple_call_arg (stmt, 3);
- mask = expand_normal (maskt);
- create_input_operand (&ops[3], mask, TYPE_MODE (TREE_TYPE (maskt)));
- icode = convert_optab_handler (optab, TYPE_MODE (type),
- TYPE_MODE (TREE_TYPE (maskt)));
- biast = gimple_call_arg (stmt, 4);
- bias = expand_normal (biast);
- create_input_operand (&ops[4], bias, QImode);
- expand_insn (icode, 5, ops);
- }
- else
- {
- create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
- expand_insn (icode, 3, ops);
- }
+ create_output_operand (&ops[i++], target, TYPE_MODE (type));
+ create_fixed_operand (&ops[i++], mem);
+ i = add_len_and_mask_args (ops, i, stmt);
+ expand_insn (icode, i, ops);
if (!rtx_equal_p (target, ops[0].value))
emit_move_insn (target, ops[0].value);
@@ -2949,15 +2955,16 @@ expand_partial_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
* OPTAB. */
static void
-expand_partial_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
+expand_partial_store_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab)
{
+ int i = 0;
class expand_operand ops[5];
- tree type, lhs, rhs, maskt, biast;
- rtx mem, reg, mask, bias;
+ tree type, lhs, rhs, maskt;
+ rtx mem, reg;
insn_code icode;
- maskt = gimple_call_arg (stmt, 2);
- rhs = gimple_call_arg (stmt, 3);
+ maskt = gimple_call_arg (stmt, internal_fn_mask_index (ifn));
+ rhs = gimple_call_arg (stmt, internal_fn_stored_value_index (ifn));
type = TREE_TYPE (rhs);
lhs = expand_call_mem_ref (type, stmt, 0);
@@ -2971,37 +2978,11 @@ expand_partial_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
gcc_assert (MEM_P (mem));
- mask = expand_normal (maskt);
reg = expand_normal (rhs);
- create_fixed_operand (&ops[0], mem);
- create_input_operand (&ops[1], reg, TYPE_MODE (type));
- if (optab == len_store_optab)
- {
- create_convert_operand_from (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)),
- TYPE_UNSIGNED (TREE_TYPE (maskt)));
- biast = gimple_call_arg (stmt, 4);
- bias = expand_normal (biast);
- create_input_operand (&ops[3], bias, QImode);
- expand_insn (icode, 4, ops);
- }
- else if (optab == len_maskstore_optab)
- {
- create_convert_operand_from (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)),
- TYPE_UNSIGNED (TREE_TYPE (maskt)));
- maskt = gimple_call_arg (stmt, 3);
- mask = expand_normal (maskt);
- create_input_operand (&ops[3], mask, TYPE_MODE (TREE_TYPE (maskt)));
- biast = gimple_call_arg (stmt, 4);
- bias = expand_normal (biast);
- create_input_operand (&ops[4], bias, QImode);
- icode = convert_optab_handler (optab, TYPE_MODE (type), GET_MODE (mask));
- expand_insn (icode, 5, ops);
- }
- else
- {
- create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
- expand_insn (icode, 3, ops);
- }
+ create_fixed_operand (&ops[i++], mem);
+ create_input_operand (&ops[i++], reg, TYPE_MODE (type));
+ i = add_len_and_mask_args (ops, i, stmt);
+ expand_insn (icode, i, ops);
}
#define expand_mask_store_optab_fn expand_partial_store_optab_fn
@@ -3526,7 +3507,6 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
{
internal_fn ifn = gimple_call_internal_fn (stmt);
int rhs_index = internal_fn_stored_value_index (ifn);
- int mask_index = internal_fn_mask_index (ifn);
tree base = gimple_call_arg (stmt, 0);
tree offset = gimple_call_arg (stmt, 1);
tree scale = gimple_call_arg (stmt, 2);
@@ -3537,19 +3517,14 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
HOST_WIDE_INT scale_int = tree_to_shwi (scale);
rtx rhs_rtx = expand_normal (rhs);
- class expand_operand ops[6];
+ class expand_operand ops[8];
int i = 0;
create_address_operand (&ops[i++], base_rtx);
create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
create_integer_operand (&ops[i++], scale_int);
create_input_operand (&ops[i++], rhs_rtx, TYPE_MODE (TREE_TYPE (rhs)));
- if (mask_index >= 0)
- {
- tree mask = gimple_call_arg (stmt, mask_index);
- rtx mask_rtx = expand_normal (mask);
- create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
- }
+ i = add_len_and_mask_args (ops, i, stmt);
insn_code icode = convert_optab_handler (optab, TYPE_MODE (TREE_TYPE (rhs)),
TYPE_MODE (TREE_TYPE (offset)));
@@ -3572,18 +3547,13 @@ expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
HOST_WIDE_INT scale_int = tree_to_shwi (scale);
int i = 0;
- class expand_operand ops[6];
+ class expand_operand ops[8];
create_output_operand (&ops[i++], lhs_rtx, TYPE_MODE (TREE_TYPE (lhs)));
create_address_operand (&ops[i++], base_rtx);
create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
create_integer_operand (&ops[i++], scale_int);
- if (optab == mask_gather_load_optab)
- {
- tree mask = gimple_call_arg (stmt, 4);
- rtx mask_rtx = expand_normal (mask);
- create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
- }
+ i = add_len_and_mask_args (ops, i, stmt);
insn_code icode = convert_optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs)),
TYPE_MODE (TREE_TYPE (offset)));
expand_insn (icode, i, ops);
@@ -4434,7 +4404,9 @@ internal_load_fn_p (internal_fn fn)
case IFN_MASK_LOAD_LANES:
case IFN_GATHER_LOAD:
case IFN_MASK_GATHER_LOAD:
+ case IFN_LEN_MASK_GATHER_LOAD:
case IFN_LEN_LOAD:
+ case IFN_LEN_MASK_LOAD:
return true;
default:
@@ -4454,7 +4426,9 @@ internal_store_fn_p (internal_fn fn)
case IFN_MASK_STORE_LANES:
case IFN_SCATTER_STORE:
case IFN_MASK_SCATTER_STORE:
+ case IFN_LEN_MASK_SCATTER_STORE:
case IFN_LEN_STORE:
+ case IFN_LEN_MASK_STORE:
return true;
default:
@@ -4471,8 +4445,10 @@ internal_gather_scatter_fn_p (internal_fn fn)
{
case IFN_GATHER_LOAD:
case IFN_MASK_GATHER_LOAD:
+ case IFN_LEN_MASK_GATHER_LOAD:
case IFN_SCATTER_STORE:
case IFN_MASK_SCATTER_STORE:
+ case IFN_LEN_MASK_SCATTER_STORE:
return true;
default:
@@ -4480,6 +4456,29 @@ internal_gather_scatter_fn_p (internal_fn fn)
}
}
+/* If FN takes a vector len argument, return the index of that argument,
+ otherwise return -1. */
+
+int
+internal_fn_len_index (internal_fn fn)
+{
+ switch (fn)
+ {
+ case IFN_LEN_LOAD:
+ case IFN_LEN_STORE:
+ case IFN_LEN_MASK_LOAD:
+ case IFN_LEN_MASK_STORE:
+ return 2;
+
+ case IFN_LEN_MASK_GATHER_LOAD:
+ case IFN_LEN_MASK_SCATTER_STORE:
+ return 4;
+
+ default:
+ return -1;
+ }
+}
+
/* If FN takes a vector mask argument, return the index of that argument,
otherwise return -1. */
@@ -4496,8 +4495,14 @@ internal_fn_mask_index (internal_fn fn)
case IFN_MASK_GATHER_LOAD:
case IFN_MASK_SCATTER_STORE:
+ case IFN_LEN_MASK_LOAD:
+ case IFN_LEN_MASK_STORE:
return 4;
+ case IFN_LEN_MASK_GATHER_LOAD:
+ case IFN_LEN_MASK_SCATTER_STORE:
+ return 6;
+
default:
return (conditional_internal_fn_code (fn) != ERROR_MARK
|| get_unconditional_internal_fn (fn) != IFN_LAST ? 0 : -1);
@@ -4516,9 +4521,15 @@ internal_fn_stored_value_index (internal_fn fn)
case IFN_MASK_STORE_LANES:
case IFN_SCATTER_STORE:
case IFN_MASK_SCATTER_STORE:
- case IFN_LEN_STORE:
+ case IFN_LEN_MASK_SCATTER_STORE:
return 3;
+ case IFN_LEN_STORE:
+ return 4;
+
+ case IFN_LEN_MASK_STORE:
+ return 5;
+
default:
return -1;
}
@@ -4584,6 +4595,24 @@ internal_len_load_store_bias (internal_fn ifn, machine_mode mode)
optab optab = direct_internal_fn_optab (ifn);
insn_code icode = direct_optab_handler (optab, mode);
+ if (icode == CODE_FOR_nothing)
+ {
+ machine_mode mask_mode;
+ if (!targetm.vectorize.get_mask_mode (mode).exists (&mask_mode))
+ return VECT_PARTIAL_BIAS_UNSUPPORTED;
+ if (ifn == IFN_LEN_LOAD)
+ {
+ /* Try LEN_MASK_LOAD. */
+ optab = direct_internal_fn_optab (IFN_LEN_MASK_LOAD);
+ }
+ else
+ {
+ /* Try LEN_MASK_STORE. */
+ optab = direct_internal_fn_optab (IFN_LEN_MASK_STORE);
+ }
+ icode = convert_optab_handler (optab, mode, mask_mode);
+ }
+
if (icode != CODE_FOR_nothing)
{
/* For now we only support biases of 0 or -1. Try both of them. */
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index bc947c0..9b73e54 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -48,14 +48,14 @@ along with GCC; see the file COPYING3. If not see
- mask_load: currently just maskload
- load_lanes: currently just vec_load_lanes
- mask_load_lanes: currently just vec_mask_load_lanes
- - gather_load: used for {mask_,}gather_load
+ - gather_load: used for {mask_,len_mask,}gather_load
- len_load: currently just len_load
- len_maskload: currently just len_maskload
- mask_store: currently just maskstore
- store_lanes: currently just vec_store_lanes
- mask_store_lanes: currently just vec_mask_store_lanes
- - scatter_store: used for {mask_,}scatter_store
+ - scatter_store: used for {mask_,len_mask,}scatter_store
- len_store: currently just len_store
- len_maskstore: currently just len_maskstore
@@ -157,6 +157,8 @@ DEF_INTERNAL_OPTAB_FN (MASK_LOAD_LANES, ECF_PURE,
DEF_INTERNAL_OPTAB_FN (GATHER_LOAD, ECF_PURE, gather_load, gather_load)
DEF_INTERNAL_OPTAB_FN (MASK_GATHER_LOAD, ECF_PURE,
mask_gather_load, gather_load)
+DEF_INTERNAL_OPTAB_FN (LEN_MASK_GATHER_LOAD, ECF_PURE,
+ len_mask_gather_load, gather_load)
DEF_INTERNAL_OPTAB_FN (LEN_LOAD, ECF_PURE, len_load, len_load)
DEF_INTERNAL_OPTAB_FN (LEN_MASK_LOAD, ECF_PURE, len_maskload, len_maskload)
@@ -164,6 +166,8 @@ DEF_INTERNAL_OPTAB_FN (LEN_MASK_LOAD, ECF_PURE, len_maskload, len_maskload)
DEF_INTERNAL_OPTAB_FN (SCATTER_STORE, 0, scatter_store, scatter_store)
DEF_INTERNAL_OPTAB_FN (MASK_SCATTER_STORE, 0,
mask_scatter_store, scatter_store)
+DEF_INTERNAL_OPTAB_FN (LEN_MASK_SCATTER_STORE, 0,
+ len_mask_scatter_store, scatter_store)
DEF_INTERNAL_OPTAB_FN (MASK_STORE, 0, maskstore, mask_store)
DEF_INTERNAL_OPTAB_FN (STORE_LANES, ECF_CONST, vec_store_lanes, store_lanes)
@@ -357,6 +361,11 @@ DEF_INTERNAL_WIDENING_OPTAB_FN (VEC_WIDEN_MINUS,
first,
vec_widen_ssub, vec_widen_usub,
binary)
+DEF_INTERNAL_WIDENING_OPTAB_FN (VEC_WIDEN_ABD,
+ ECF_CONST | ECF_NOTHROW,
+ first,
+ vec_widen_sabd, vec_widen_uabd,
+ binary)
DEF_INTERNAL_OPTAB_FN (VEC_FMADDSUB, ECF_CONST, vec_fmaddsub, ternary)
DEF_INTERNAL_OPTAB_FN (VEC_FMSUBADD, ECF_CONST, vec_fmsubadd, ternary)
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 8f21068..4234bbf 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -234,6 +234,7 @@ extern bool internal_load_fn_p (internal_fn);
extern bool internal_store_fn_p (internal_fn);
extern bool internal_gather_scatter_fn_p (internal_fn);
extern int internal_fn_mask_index (internal_fn);
+extern int internal_fn_len_index (internal_fn);
extern int internal_fn_stored_value_index (internal_fn);
extern bool internal_gather_scatter_fn_supported_p (internal_fn, tree,
tree, tree, int);
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 846dcf8..071c607 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1936,6 +1936,21 @@ ipa_vr_operation_and_type_effects (vrange &dst_vr,
&& !dst_vr.undefined_p ());
}
+/* Same as above, but the SRC_VR argument is an IPA_VR which must
+ first be extracted onto a vrange. */
+
+static bool
+ipa_vr_operation_and_type_effects (vrange &dst_vr,
+ const ipa_vr &src_vr,
+ enum tree_code operation,
+ tree dst_type, tree src_type)
+{
+ Value_Range tmp;
+ src_vr.get_vrange (tmp);
+ return ipa_vr_operation_and_type_effects (dst_vr, tmp, operation,
+ dst_type, src_type);
+}
+
/* Determine range of JFUNC given that INFO describes the caller node or
the one it is inlined to, CS is the call graph edge corresponding to JFUNC
and PARM_TYPE of the parameter. */
@@ -6279,8 +6294,7 @@ decide_whether_version_node (struct cgraph_node *node)
{
/* If some values generated for self-recursive calls with
arithmetic jump functions fall outside of the known
- value_range for the parameter, we can skip them. VR interface
- supports this only for integers now. */
+ range for the parameter, we can skip them. */
if (TREE_CODE (val->value) == INTEGER_CST
&& !plats->m_value_range.bottom_p ()
&& !ipa_range_contains_p (plats->m_value_range.m_vr,
diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index 2c61a49..87529be 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -4147,7 +4147,7 @@ ipa_odr_read_section (struct lto_file_decl_data *file_data, const char *data,
class data_in *data_in;
lto_input_block ib ((const char *) data + main_offset, header->main_size,
- file_data->mode_table);
+ file_data);
data_in
= lto_data_in_create (file_data, (const char *) data + string_offset,
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index a5f5a50..f1244da2 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -500,19 +500,20 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
if (vr.varying_p () || vr.undefined_p ())
break;
- value_range res;
+ Value_Range res (op->type);
if (!op->val[0])
{
+ Value_Range varying (op->type);
+ varying.set_varying (op->type);
range_op_handler handler (op->code);
if (!handler
|| !res.supports_type_p (op->type)
- || !handler.fold_range (res, op->type, vr,
- value_range (op->type)))
+ || !handler.fold_range (res, op->type, vr, varying))
res.set_varying (op->type);
}
else if (!op->val[1])
{
- value_range op0;
+ Value_Range op0 (op->type);
range_op_handler handler (op->code);
ipa_range_set_and_normalize (op0, op->val[0]);
@@ -530,14 +531,14 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
}
if (!vr.varying_p () && !vr.undefined_p ())
{
- value_range res;
- value_range val_vr;
+ int_range<2> res;
+ Value_Range val_vr (TREE_TYPE (c->val));
range_op_handler handler (c->code);
ipa_range_set_and_normalize (val_vr, c->val);
if (!handler
- || !res.supports_type_p (boolean_type_node)
+ || !val_vr.supports_type_p (TREE_TYPE (c->val))
|| !handler.fold_range (res, boolean_type_node, vr, val_vr))
res.set_varying (boolean_type_node);
@@ -1515,6 +1516,19 @@ decompose_param_expr (struct ipa_func_body_info *fbi,
if (TREE_CODE (expr) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (expr))
break;
+ stmt = SSA_NAME_DEF_STMT (expr);
+
+ if (gcall *call = dyn_cast <gcall *> (stmt))
+ {
+ int flags = gimple_call_return_flags (call);
+ if (!(flags & ERF_RETURNS_ARG))
+ goto fail;
+ int arg = flags & ERF_RETURN_ARG_MASK;
+ if (arg >= (int)gimple_call_num_args (call))
+ goto fail;
+ expr = gimple_call_arg (stmt, arg);
+ continue;
+ }
if (!is_gimple_assign (stmt = SSA_NAME_DEF_STMT (expr)))
break;
@@ -1663,6 +1677,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
}
}
vec_free (param_ops);
+ return;
}
if (TREE_CODE (op) != SSA_NAME)
@@ -1732,12 +1747,17 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
int bound_limit = opt_for_fn (fbi->node->decl,
param_ipa_max_switch_predicate_bounds);
int bound_count = 0;
- value_range vr;
+ // This can safely be an integer range, as switches can only hold
+ // integers.
+ int_range<2> vr;
get_range_query (cfun)->range_of_expr (vr, op);
if (vr.undefined_p ())
vr.set_varying (TREE_TYPE (op));
tree vr_min, vr_max;
+ // TODO: This entire function could use a rewrite to use the irange
+ // API, instead of trying to recreate its intersection/union logic.
+ // Any use of get_legacy_range() is a serious code smell.
value_range_kind vr_type = get_legacy_range (vr, vr_min, vr_max);
wide_int vr_wmin = wi::to_wide (vr_min);
wide_int vr_wmax = wi::to_wide (vr_max);
@@ -4528,7 +4548,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
unsigned int f_count;
lto_input_block ib ((const char *) data + main_offset, header->main_size,
- file_data->mode_table);
+ file_data);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
diff --git a/gcc/ipa-fnsummary.h b/gcc/ipa-fnsummary.h
index fcc0116..0c5a81e 100644
--- a/gcc/ipa-fnsummary.h
+++ b/gcc/ipa-fnsummary.h
@@ -126,8 +126,8 @@ public:
ipa_fn_summary ()
: min_size (0),
inlinable (false), single_caller (false),
- fp_expressions (false), target_info (0),
- estimated_stack_size (false),
+ fp_expressions (false), safe_to_inline_to_always_inline (0),
+ target_info (0), estimated_stack_size (false),
time (0), conds (NULL),
size_time_table (), call_size_time_table (vNULL),
loop_iterations (NULL), loop_strides (NULL),
@@ -165,6 +165,8 @@ public:
unsigned int single_caller : 1;
/* True if function contains any floating point expressions. */
unsigned int fp_expressions : 1;
+ /* Cache for analysis of can_early_inline_edge_p. */
+ unsigned int safe_to_inline_to_always_inline : 2;
/* Like fp_expressions field above, but it's to hold some target specific
information, such as some target specific isa flags. Note that for
offloading target compilers, this field isn't streamed. */
diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index cb9f768..836d091 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -2204,7 +2204,7 @@ sem_item_optimizer::read_section (lto_file_decl_data *file_data,
unsigned int count;
lto_input_block ib_main ((const char *) data + main_offset, 0,
- header->main_size, file_data->mode_table);
+ header->main_size, file_data);
data_in
= lto_data_in_create (file_data, (const char *) data + string_offset,
diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
index efc8df7..dc120e6 100644
--- a/gcc/ipa-inline.cc
+++ b/gcc/ipa-inline.cc
@@ -680,28 +680,60 @@ can_early_inline_edge_p (struct cgraph_edge *e)
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
return false;
}
- /* In early inliner some of callees may not be in SSA form yet
- (i.e. the callgraph is cyclic and we did not process
- the callee by early inliner, yet). We don't have CIF code for this
- case; later we will re-do the decision in the real inliner. */
- if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->caller->decl))
- || !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
- " edge not inlinable: not in SSA form\n");
- return false;
- }
- else if (profile_arc_flag
- && ((lookup_attribute ("no_profile_instrument_function",
- DECL_ATTRIBUTES (caller->decl)) == NULL_TREE)
- != (lookup_attribute ("no_profile_instrument_function",
- DECL_ATTRIBUTES (callee->decl)) == NULL_TREE)))
+ gcc_assert (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->caller->decl))
+ && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)));
+ if (profile_arc_flag
+ && ((lookup_attribute ("no_profile_instrument_function",
+ DECL_ATTRIBUTES (caller->decl)) == NULL_TREE)
+ != (lookup_attribute ("no_profile_instrument_function",
+ DECL_ATTRIBUTES (callee->decl)) == NULL_TREE)))
return false;
if (!can_inline_edge_p (e, true, true)
|| !can_inline_edge_by_limits_p (e, true, false, true))
return false;
+ /* When inlining regular functions into always-inline functions
+ during early inlining watch for possible inline cycles. */
+ if (DECL_DISREGARD_INLINE_LIMITS (caller->decl)
+ && lookup_attribute ("always_inline", DECL_ATTRIBUTES (caller->decl))
+ && (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
+ || !lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee->decl))))
+ {
+ /* If there are indirect calls, inlining may produce direct call.
+ TODO: We may lift this restriction if we avoid errors on formely
+ indirect calls to always_inline functions. Taking address
+ of always_inline function is generally bad idea and should
+ have been declared as undefined, but sadly we allow this. */
+ if (caller->indirect_calls || e->callee->indirect_calls)
+ return false;
+ ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
+ if (callee_info->safe_to_inline_to_always_inline)
+ return callee_info->safe_to_inline_to_always_inline - 1;
+ for (cgraph_edge *e2 = callee->callees; e2; e2 = e2->next_callee)
+ {
+ struct cgraph_node *callee2 = e2->callee->ultimate_alias_target ();
+ /* As early inliner runs in RPO order, we will see uninlined
+ always_inline calls only in the case of cyclic graphs. */
+ if (DECL_DISREGARD_INLINE_LIMITS (callee2->decl)
+ || lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee2->decl)))
+ {
+ callee_info->safe_to_inline_to_always_inline = 1;
+ return false;
+ }
+ /* With LTO watch for case where function is later replaced
+ by always_inline definition.
+ TODO: We may either stop treating noninlined cross-module always
+ inlines as errors, or we can extend decl merging to produce
+ syntacic alias and honor always inline only in units it has
+ been declared as such. */
+ if (flag_lto && callee2->externally_visible)
+ {
+ callee_info->safe_to_inline_to_always_inline = 1;
+ return false;
+ }
+ }
+ callee_info->safe_to_inline_to_always_inline = 2;
+ }
return true;
}
@@ -2896,7 +2928,8 @@ ipa_inline (void)
return remove_functions ? TODO_remove_functions : 0;
}
-/* Inline always-inline function calls in NODE. */
+/* Inline always-inline function calls in NODE
+ (which itself is possibly inline). */
static bool
inline_always_inline_functions (struct cgraph_node *node)
@@ -2907,7 +2940,10 @@ inline_always_inline_functions (struct cgraph_node *node)
for (e = node->callees; e; e = e->next_callee)
{
struct cgraph_node *callee = e->callee->ultimate_alias_target ();
- if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl))
+ gcc_checking_assert (!callee->aux || callee->aux == (void *)(size_t)1);
+ if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
+ /* Watch for self-recursive cycles. */
+ || callee->aux)
continue;
if (e->recursive_p ())
@@ -2919,6 +2955,9 @@ inline_always_inline_functions (struct cgraph_node *node)
e->inline_failed = CIF_RECURSIVE_INLINING;
continue;
}
+ if (callee->definition
+ && !ipa_fn_summaries->get (callee))
+ compute_fn_summary (callee, true);
if (!can_early_inline_edge_p (e))
{
@@ -2936,11 +2975,13 @@ inline_always_inline_functions (struct cgraph_node *node)
" Inlining %C into %C (always_inline).\n",
e->callee, e->caller);
inline_call (e, true, NULL, NULL, false);
+ callee->aux = (void *)(size_t)1;
+ /* Inline recursively to handle the case where always_inline function was
+ not optimized yet since it is a part of a cycle in callgraph. */
+ inline_always_inline_functions (e->callee);
+ callee->aux = NULL;
inlined = true;
}
- if (inlined)
- ipa_update_overall_fn_summary (node);
-
return inlined;
}
@@ -3034,18 +3075,7 @@ early_inliner (function *fun)
if (!optimize
|| flag_no_inline
- || !flag_early_inlining
- /* Never inline regular functions into always-inline functions
- during incremental inlining. This sucks as functions calling
- always inline functions will get less optimized, but at the
- same time inlining of functions calling always inline
- function into an always inline function might introduce
- cycles of edges to be always inlined in the callgraph.
-
- We might want to be smarter and just avoid this type of inlining. */
- || (DECL_DISREGARD_INLINE_LIMITS (node->decl)
- && lookup_attribute ("always_inline",
- DECL_ATTRIBUTES (node->decl))))
+ || !flag_early_inlining)
;
else if (lookup_attribute ("flatten",
DECL_ATTRIBUTES (node->decl)) != NULL)
@@ -3063,7 +3093,8 @@ early_inliner (function *fun)
/* If some always_inline functions was inlined, apply the changes.
This way we will not account always inline into growth limits and
moreover we will inline calls from always inlines that we skipped
- previously because of conditional above. */
+ previously because of conditional in can_early_inline_edge_p
+ which prevents some inlining to always_inline. */
if (inlined)
{
timevar_push (TV_INTEGRATION);
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index e3196df..278b2db 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -3816,7 +3816,7 @@ read_section (struct lto_file_decl_data *file_data, const char *data,
unsigned int f_count;
lto_input_block ib ((const char *) data + main_offset, header->main_size,
- file_data->mode_table);
+ file_data);
data_in
= lto_data_in_create (file_data, (const char *) data + string_offset,
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 704fe01..d2b998f 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -109,53 +109,53 @@ struct ipa_bit_ggc_hash_traits : public ggc_cache_remove <ipa_bits *>
/* Hash table for avoid repeated allocations of equal ipa_bits. */
static GTY ((cache)) hash_table<ipa_bit_ggc_hash_traits> *ipa_bits_hash_table;
-/* Traits for a hash table for reusing value_ranges used for IPA. Note that
- the equiv bitmap is not hashed and is expected to be NULL. */
+/* Traits for a hash table for reusing ranges. */
-struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
+struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <ipa_vr *>
{
- typedef value_range *value_type;
- typedef value_range *compare_type;
+ typedef ipa_vr *value_type;
+ typedef const vrange *compare_type;
static hashval_t
- hash (const value_range *p)
+ hash (const ipa_vr *p)
{
- tree min, max;
- value_range_kind kind = get_legacy_range (*p, min, max);
- inchash::hash hstate (kind);
- inchash::add_expr (min, hstate);
- inchash::add_expr (max, hstate);
+ // This never get called, except in the verification code, as
+ // ipa_get_value_range() calculates the hash itself. This
+ // function is mostly here for completness' sake.
+ Value_Range vr;
+ p->get_vrange (vr);
+ inchash::hash hstate;
+ add_vrange (vr, hstate);
return hstate.end ();
}
static bool
- equal (const value_range *a, const value_range *b)
+ equal (const ipa_vr *a, const vrange *b)
{
- return (types_compatible_p (a->type (), b->type ())
- && *a == *b);
+ return a->equal_p (*b);
}
static const bool empty_zero_p = true;
static void
- mark_empty (value_range *&p)
+ mark_empty (ipa_vr *&p)
{
p = NULL;
}
static bool
- is_empty (const value_range *p)
+ is_empty (const ipa_vr *p)
{
return p == NULL;
}
static bool
- is_deleted (const value_range *p)
+ is_deleted (const ipa_vr *p)
{
- return p == reinterpret_cast<const value_range *> (1);
+ return p == reinterpret_cast<const ipa_vr *> (1);
}
static void
- mark_deleted (value_range *&p)
+ mark_deleted (ipa_vr *&p)
{
- p = reinterpret_cast<value_range *> (1);
+ p = reinterpret_cast<ipa_vr *> (1);
}
};
-/* Hash table for avoid repeated allocations of equal value_ranges. */
+/* Hash table for avoid repeated allocations of equal ranges. */
static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
/* Holders of ipa cgraph hooks: */
@@ -265,6 +265,22 @@ ipa_vr::dump (FILE *out) const
fprintf (out, "NO RANGE");
}
+// These stubs are because we use an ipa_vr in a hash_traits and
+// hash-traits.h defines an extern of gt_ggc_mx (T &) instead of
+// picking up the gt_ggc_mx (T *) version.
+void
+gt_pch_nx (ipa_vr *&x)
+{
+ return gt_pch_nx ((ipa_vr *) x);
+}
+
+void
+gt_ggc_mx (ipa_vr *&x)
+{
+ return gt_ggc_mx ((ipa_vr *) x);
+}
+
+
/* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
@@ -2284,53 +2300,39 @@ ipa_set_jfunc_bits (ipa_jump_func *jf, const widest_int &value,
jf->bits = ipa_get_ipa_bits_for_value (value, mask);
}
-/* Return a pointer to a value_range just like *TMP, but either find it in
- ipa_vr_hash_table or allocate it in GC memory. TMP->equiv must be NULL. */
+/* Return a pointer to an ipa_vr just like TMP, but either find it in
+ ipa_vr_hash_table or allocate it in GC memory. */
-static value_range *
-ipa_get_value_range (value_range *tmp)
+static ipa_vr *
+ipa_get_value_range (const vrange &tmp)
{
- value_range **slot = ipa_vr_hash_table->find_slot (tmp, INSERT);
+ inchash::hash hstate;
+ inchash::add_vrange (tmp, hstate);
+ hashval_t hash = hstate.end ();
+ ipa_vr **slot = ipa_vr_hash_table->find_slot_with_hash (&tmp, hash, INSERT);
if (*slot)
return *slot;
- value_range *vr = new (ggc_alloc<value_range> ()) value_range;
- *vr = *tmp;
+ ipa_vr *vr = new (ggc_alloc<ipa_vr> ()) ipa_vr (tmp);
*slot = vr;
-
return vr;
}
-/* Return a pointer to a value range consisting of TYPE, MIN, MAX and an empty
- equiv set. Use hash table in order to avoid creating multiple same copies of
- value_ranges. */
-
-static value_range *
-ipa_get_value_range (enum value_range_kind kind, tree min, tree max)
-{
- value_range tmp (TREE_TYPE (min),
- wi::to_wide (min), wi::to_wide (max), kind);
- return ipa_get_value_range (&tmp);
-}
-
-/* Assign to JF a pointer to a value_range structure with TYPE, MIN and MAX and
- a NULL equiv bitmap. Use hash table in order to avoid creating multiple
- same value_range structures. */
+/* Assign to JF a pointer to a range just like TMP but either fetch a
+ copy from ipa_vr_hash_table or allocate a new on in GC memory. */
static void
-ipa_set_jfunc_vr (ipa_jump_func *jf, enum value_range_kind type,
- tree min, tree max)
+ipa_set_jfunc_vr (ipa_jump_func *jf, const vrange &tmp)
{
- jf->m_vr = ipa_get_value_range (type, min, max);
+ jf->m_vr = ipa_get_value_range (tmp);
}
-/* Assign to JF a pointer to a value_range just like TMP but either fetch a
- copy from ipa_vr_hash_table or allocate a new on in GC memory. */
-
static void
-ipa_set_jfunc_vr (ipa_jump_func *jf, value_range *tmp)
+ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr)
{
- jf->m_vr = ipa_get_value_range (tmp);
+ Value_Range tmp;
+ vr.get_vrange (tmp);
+ ipa_set_jfunc_vr (jf, tmp);
}
/* Compute jump function for all arguments of callsite CS and insert the
@@ -2346,7 +2348,6 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
gcall *call = cs->call_stmt;
int n, arg_num = gimple_call_num_args (call);
bool useful_context = false;
- value_range vr;
if (arg_num == 0 || args->jump_functions)
return;
@@ -2377,6 +2378,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
useful_context = true;
}
+ Value_Range vr (TREE_TYPE (arg));
if (POINTER_TYPE_P (TREE_TYPE (arg)))
{
bool addr_nonzero = false;
@@ -2384,7 +2386,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
if (TREE_CODE (arg) == SSA_NAME
&& param_type
- && get_range_query (cfun)->range_of_expr (vr, arg)
+ && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
&& vr.nonzero_p ())
addr_nonzero = true;
else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
@@ -2392,8 +2394,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
if (addr_nonzero)
{
- tree z = build_int_cst (TREE_TYPE (arg), 0);
- ipa_set_jfunc_vr (jfunc, VR_ANTI_RANGE, z, z);
+ vr.set_nonzero (TREE_TYPE (arg));
+ ipa_set_jfunc_vr (jfunc, vr);
}
else
gcc_assert (!jfunc->m_vr);
@@ -2402,18 +2404,17 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
{
if (TREE_CODE (arg) == SSA_NAME
&& param_type
- /* Limit the ranger query to integral types as the rest
- of this file uses value_range's, which only hold
- integers and pointers. */
+ && Value_Range::supports_type_p (TREE_TYPE (arg))
+ && Value_Range::supports_type_p (param_type)
&& irange::supports_p (TREE_TYPE (arg))
&& irange::supports_p (param_type)
- && get_range_query (cfun)->range_of_expr (vr, arg)
+ && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
&& !vr.undefined_p ())
{
- value_range resvr = vr;
+ Value_Range resvr (vr);
range_cast (resvr, param_type);
if (!resvr.undefined_p () && !resvr.varying_p ())
- ipa_set_jfunc_vr (jfunc, &resvr);
+ ipa_set_jfunc_vr (jfunc, resvr);
else
gcc_assert (!jfunc->m_vr);
}
@@ -3189,7 +3190,9 @@ ipa_analyze_node (struct cgraph_node *node)
bi->cg_edges.safe_push (cs);
}
+ enable_ranger (cfun, false);
analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ disable_ranger (cfun);
ipa_release_body_info (&fbi);
free_dominance_info (CDI_DOMINATORS);
@@ -4865,16 +4868,12 @@ ipa_write_jump_function (struct output_block *ob,
streamer_write_widest_int (ob, jump_func->bits->value);
streamer_write_widest_int (ob, jump_func->bits->mask);
}
- bp_pack_value (&bp, !!jump_func->m_vr, 1);
- streamer_write_bitpack (&bp);
if (jump_func->m_vr)
+ jump_func->m_vr->streamer_write (ob);
+ else
{
- tree min, max;
- value_range_kind kind = get_legacy_range (*jump_func->m_vr, min, max);
- streamer_write_enum (ob->main_stream, value_rang_type,
- VR_LAST, kind);
- stream_write_tree (ob, min, true);
- stream_write_tree (ob, max, true);
+ bp_pack_value (&bp, false, 1);
+ streamer_write_bitpack (&bp);
}
}
@@ -5002,21 +5001,17 @@ ipa_read_jump_function (class lto_input_block *ib,
widest_int value = streamer_read_widest_int (ib);
widest_int mask = streamer_read_widest_int (ib);
if (prevails)
- ipa_set_jfunc_bits (jump_func, value, mask);
+ ipa_set_jfunc_bits (jump_func, value, mask);
}
else
jump_func->bits = NULL;
- struct bitpack_d vr_bp = streamer_read_bitpack (ib);
- bool vr_known = bp_unpack_value (&vr_bp, 1);
- if (vr_known)
+ ipa_vr vr;
+ vr.streamer_read (ib, data_in);
+ if (vr.known_p ())
{
- enum value_range_kind type = streamer_read_enum (ib, value_range_kind,
- VR_LAST);
- tree min = stream_read_tree (ib, data_in);
- tree max = stream_read_tree (ib, data_in);
if (prevails)
- ipa_set_jfunc_vr (jump_func, type, min, max);
+ ipa_set_jfunc_vr (jump_func, vr);
}
else
jump_func->m_vr = NULL;
@@ -5337,7 +5332,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
unsigned int count;
lto_input_block ib_main ((const char *) data + main_offset,
- header->main_size, file_data->mode_table);
+ header->main_size, file_data);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
@@ -5561,7 +5556,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
unsigned int count;
lto_input_block ib_main ((const char *) data + main_offset,
- header->main_size, file_data->mode_table);
+ header->main_size, file_data);
data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
header->string_size, vNULL);
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 9b7fee4..410c951 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -325,6 +325,9 @@ private:
friend void gt_pch_nx (struct ipa_vr &);
friend void gt_ggc_mx (struct ipa_vr &);
friend void gt_pch_nx (struct ipa_vr *, gt_pointer_operator, void *);
+ friend void gt_ggc_mx_ipa_vr (void *);
+ friend void gt_pch_nx_ipa_vr (void*);
+ friend void gt_pch_p_6ipa_vr(void*, void*, gt_pointer_operator, void*);
vrange_storage *m_storage;
tree m_type;
@@ -347,7 +350,7 @@ struct GTY (()) ipa_jump_func
/* Information about value range, containing valid data only when vr_known is
true. The pointed to structure is shared betweed different jump
functions. Use ipa_set_jfunc_vr to set this field. */
- value_range *m_vr;
+ ipa_vr *m_vr;
enum jump_func_type type;
/* Represents a value of a jump function. pass_through is used only in jump
diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
index 21d281a..c35e03b 100644
--- a/gcc/ipa-sra.cc
+++ b/gcc/ipa-sra.cc
@@ -2944,7 +2944,7 @@ isra_read_summary_section (struct lto_file_decl_data *file_data,
unsigned int count;
lto_input_block ib_main ((const char *) data + main_offset,
- header->main_size, file_data->mode_table);
+ header->main_size, file_data);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
diff --git a/gcc/ipa-utils.cc b/gcc/ipa-utils.cc
index 8badcc2..956c629 100644
--- a/gcc/ipa-utils.cc
+++ b/gcc/ipa-utils.cc
@@ -323,13 +323,6 @@ ipa_reverse_postorder (struct cgraph_node **order)
edge = stack[stack_size].edge;
node2 = edge->caller;
stack[stack_size].edge = edge->next_caller;
- /* Break possible cycles involving always-inline
- functions by ignoring edges from always-inline
- functions to non-always-inline functions. */
- if (DECL_DISREGARD_INLINE_LIMITS (edge->caller->decl)
- && !DECL_DISREGARD_INLINE_LIMITS
- (edge->callee->function_symbol ()->decl))
- node2 = NULL;
}
for (; stack[stack_size].node->iterate_referring (
stack[stack_size].ref,
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index aed5e9d..32c0f5a 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -2174,7 +2174,7 @@ input_cgraph_opt_section (struct lto_file_decl_data *file_data,
unsigned int count;
lto_input_block ib_main ((const char *) data + main_offset,
- header->main_size, file_data->mode_table);
+ header->main_size, file_data);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
diff --git a/gcc/lto-section-in.cc b/gcc/lto-section-in.cc
index 07cf732..5ff00a3 100644
--- a/gcc/lto-section-in.cc
+++ b/gcc/lto-section-in.cc
@@ -262,7 +262,7 @@ lto_create_simple_input_block (struct lto_file_decl_data *file_data,
*datar = data;
return new lto_input_block (data + main_offset, header->main_size,
- file_data->mode_table);
+ file_data);
}
diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc
index 2cb8340..1876e19 100644
--- a/gcc/lto-streamer-in.cc
+++ b/gcc/lto-streamer-in.cc
@@ -1629,11 +1629,11 @@ lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symta
/* Set up the struct function. */
from = data_in->reader_cache->nodes.length ();
lto_input_block ib_main (data + main_offset, header->main_size,
- file_data->mode_table);
+ file_data);
if (TREE_CODE (node->decl) == FUNCTION_DECL)
{
lto_input_block ib_cfg (data + cfg_offset, header->cfg_size,
- file_data->mode_table);
+ file_data);
input_function (fn_decl, data_in, &ib_main, &ib_cfg,
dyn_cast <cgraph_node *>(node));
}
@@ -1954,7 +1954,7 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
string_offset = sizeof (*header) + header->main_size;
lto_input_block ib (data + sizeof (*header), header->main_size,
- file_data->mode_table);
+ file_data);
data_in = lto_data_in_create (file_data, data + string_offset,
header->string_size, vNULL);
@@ -1985,8 +1985,6 @@ lto_input_mode_table (struct lto_file_decl_data *file_data)
internal_error ("cannot read LTO mode table from %s",
file_data->file_name);
- unsigned char *table = ggc_cleared_vec_alloc<unsigned char> (1 << 8);
- file_data->mode_table = table;
const struct lto_simple_header_with_strings *header
= (const struct lto_simple_header_with_strings *) data;
int string_offset;
@@ -1998,16 +1996,22 @@ lto_input_mode_table (struct lto_file_decl_data *file_data)
header->string_size, vNULL);
bitpack_d bp = streamer_read_bitpack (&ib);
+ unsigned mode_bits = bp_unpack_value (&bp, 5);
+ unsigned char *table = ggc_cleared_vec_alloc<unsigned char> (1 << mode_bits);
+
+ file_data->mode_table = table;
+ file_data->mode_bits = mode_bits;
+
table[VOIDmode] = VOIDmode;
table[BLKmode] = BLKmode;
unsigned int m;
- while ((m = bp_unpack_value (&bp, 8)) != VOIDmode)
+ while ((m = bp_unpack_value (&bp, mode_bits)) != VOIDmode)
{
enum mode_class mclass
= bp_unpack_enum (&bp, mode_class, MAX_MODE_CLASS);
poly_uint16 size = bp_unpack_poly_value (&bp, 16);
poly_uint16 prec = bp_unpack_poly_value (&bp, 16);
- machine_mode inner = (machine_mode) bp_unpack_value (&bp, 8);
+ machine_mode inner = (machine_mode) bp_unpack_value (&bp, mode_bits);
poly_uint16 nunits = bp_unpack_poly_value (&bp, 16);
unsigned int ibit = 0, fbit = 0;
unsigned int real_fmt_len = 0;
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index 5ab2eb4..5ffa895 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -1373,7 +1373,7 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map<tree, hashval_t> *map,
if (AGGREGATE_TYPE_P (t))
hstate.add_flag (TYPE_TYPELESS_STORAGE (t));
hstate.commit_flag ();
- hstate.add_int (TYPE_PRECISION (t));
+ hstate.add_int (TYPE_PRECISION_RAW (t));
hstate.add_int (TYPE_ALIGN (t));
hstate.add_int (TYPE_EMPTY_P (t));
}
@@ -3196,6 +3196,11 @@ lto_write_mode_table (void)
if (inner_m != m)
streamer_mode_table[(int) inner_m] = 1;
}
+
+ /* Pack the mode_bits value within 5 bits (up to 31) in the beginning. */
+ unsigned mode_bits = ceil_log2 (MAX_MACHINE_MODE);
+ bp_pack_value (&bp, mode_bits, 5);
+
/* First stream modes that have GET_MODE_INNER (m) == m,
so that we can refer to them afterwards. */
for (int pass = 0; pass < 2; pass++)
@@ -3205,11 +3210,11 @@ lto_write_mode_table (void)
machine_mode m = (machine_mode) i;
if ((GET_MODE_INNER (m) == m) ^ (pass == 0))
continue;
- bp_pack_value (&bp, m, 8);
+ bp_pack_value (&bp, m, mode_bits);
bp_pack_enum (&bp, mode_class, MAX_MODE_CLASS, GET_MODE_CLASS (m));
bp_pack_poly_value (&bp, GET_MODE_SIZE (m), 16);
bp_pack_poly_value (&bp, GET_MODE_PRECISION (m), 16);
- bp_pack_value (&bp, GET_MODE_INNER (m), 8);
+ bp_pack_value (&bp, GET_MODE_INNER (m), mode_bits);
bp_pack_poly_value (&bp, GET_MODE_NUNITS (m), 16);
switch (GET_MODE_CLASS (m))
{
@@ -3229,7 +3234,7 @@ lto_write_mode_table (void)
}
bp_pack_string (ob, &bp, GET_MODE_NAME (m), true);
}
- bp_pack_value (&bp, VOIDmode, 8);
+ bp_pack_value (&bp, VOIDmode, mode_bits);
streamer_write_bitpack (&bp);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index fc7133d..0556b34 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -344,14 +344,14 @@ public:
/* Special constructor for the string table, it abuses this to
do random access but use the uhwi decoder. */
lto_input_block (const char *data_, unsigned int p_, unsigned int len_,
- const unsigned char *mode_table_)
- : data (data_), mode_table (mode_table_), p (p_), len (len_) {}
+ const lto_file_decl_data *file_data_)
+ : data (data_), file_data (file_data_), p (p_), len (len_) {}
lto_input_block (const char *data_, unsigned int len_,
- const unsigned char *mode_table_)
- : data (data_), mode_table (mode_table_), p (0), len (len_) {}
+ const lto_file_decl_data *file_data_)
+ : data (data_), file_data (file_data_), p (0), len (len_) {}
const char *data;
- const unsigned char *mode_table;
+ const lto_file_decl_data *file_data;
unsigned int p;
unsigned int len;
};
@@ -604,6 +604,8 @@ struct GTY(()) lto_file_decl_data
int order_base;
int unit_base;
+
+ unsigned mode_bits;
};
typedef struct lto_file_decl_data *lto_file_decl_data_ptr;
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 15464c9..ef375fa 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,28 @@
+2023-07-04 Pan Li <pan2.li@intel.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * lto-common.cc (lto_file_finalize) [!ACCEL_COMPILER]: Initialize
+ 'file_data->mode_bits'.
+
+2023-07-04 Thomas Schwinge <thomas@codesourcery.com>
+
+ * lto-common.cc (lto_read_decls): Adjust.
+
+2023-06-29 Qing Zhao <qing.zhao@oracle.com>
+
+ * lto-common.cc (compare_tree_sccs_1): Compare bit
+ TYPE_NO_NAMED_ARGS_STDARG_P or TYPE_INCLUDES_FLEXARRAY properly
+ for its corresponding type.
+
+2023-06-29 Eugene Rozenfeld <erozen@microsoft.com>
+
+ * Make-lang.in: Pass correct stage lto when processing
+ profile data collected while building target libraries
+
+2023-06-28 Richard Biener <rguenther@suse.de>
+
+ * lto-common.cc (compare_tree_sccs_1): Use TYPE_PRECISION_RAW.
+
2023-05-18 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
* lto-common.cc (lto_maybe_register_decl): Use _P defines from tree.h.
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index 4f60251..98aa9f4 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -130,7 +130,7 @@ create_fdas_for_lto1: ../stage1-gcc/lto1$(exeext) ../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=lto1_$$component_in_prev_target.fda; \
- $(CREATE_GCOV) -binary ../stage1-gcc/lto1$(exeext) -gcov $$profile_name -profile $$perf_path -gcov_version 2; \
+ $(CREATE_GCOV) -binary ../prev-gcc/lto1$(exeext) -gcov $$profile_name -profile $$perf_path -gcov_version 2; \
fi; \
done;
diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc
index 5375702..703e665 100644
--- a/gcc/lto/lto-common.cc
+++ b/gcc/lto/lto-common.cc
@@ -1275,12 +1275,15 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
if (AGGREGATE_TYPE_P (t1))
compare_values (TYPE_TYPELESS_STORAGE);
compare_values (TYPE_EMPTY_P);
- compare_values (TYPE_NO_NAMED_ARGS_STDARG_P);
+ if (FUNC_OR_METHOD_TYPE_P (t1))
+ compare_values (TYPE_NO_NAMED_ARGS_STDARG_P);
+ if (RECORD_OR_UNION_TYPE_P (t1))
+ compare_values (TYPE_INCLUDES_FLEXARRAY);
compare_values (TYPE_PACKED);
compare_values (TYPE_RESTRICT);
compare_values (TYPE_USER_ALIGN);
compare_values (TYPE_READONLY);
- compare_values (TYPE_PRECISION);
+ compare_values (TYPE_PRECISION_RAW);
compare_values (TYPE_ALIGN);
/* Do not compare TYPE_ALIAS_SET. Doing so introduce ordering issues
with calls to get_alias_set which may initialize it for streamed
@@ -1880,7 +1883,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
uint32_t num_decl_states;
lto_input_block ib_main ((const char *) data + main_offset,
- header->main_size, decl_data->mode_table);
+ header->main_size, decl_data);
data_in = lto_data_in_create (decl_data, (const char *) data + string_offset,
header->string_size, resolutions);
@@ -2275,6 +2278,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file,
lto_input_mode_table (file_data);
#else
file_data->mode_table = lto_mode_identity_table;
+ file_data->mode_bits = ceil_log2 (MAX_MACHINE_MODE);
#endif
data = lto_get_summary_section_data (file_data, LTO_section_decls, &len);
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog
index 70ea865..53cce9c 100644
--- a/gcc/m2/ChangeLog
+++ b/gcc/m2/ChangeLog
@@ -1,3 +1,74 @@
+2023-07-03 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/110125
+ * Make-lang.in (GM2-COMP-BOOT-DEFS): Add M2SymInit.def.
+ (GM2-COMP-BOOT-MODS): Add M2SymInit.mod.
+ * gm2-compiler/M2BasicBlock.mod: Formatting changes.
+ * gm2-compiler/M2Code.mod: Remove import of VariableAnalysis from
+ M2Quads. Import VariableAnalysis from M2SymInit.mod.
+ * gm2-compiler/M2GCCDeclare.mod (PrintVerboseFromList):
+ Add debugging print for a component.
+ (TypeConstFullyDeclared): Call RememberType for every type.
+ * gm2-compiler/M2GenGCC.mod (CodeReturnValue): Add parameter to
+ GetQuadOtok.
+ (CodeBecomes): Add parameter to GetQuadOtok.
+ (CodeXIndr): Add parameter to GetQuadOtok.
+ * gm2-compiler/M2Optimize.mod (ReduceBranch): Reformat and
+ preserve operand token positions when reducing the branch
+ quadruples.
+ (ReduceGoto): Reformat.
+ (FoldMultipleGoto): Reformat.
+ (KnownReachable): Reformat.
+ * gm2-compiler/M2Options.def (UninitVariableChecking): New
+ variable declared and exported.
+ (SetUninitVariableChecking): New procedure.
+ * gm2-compiler/M2Options.mod (SetWall): Set
+ UninitVariableChecking.
+ (SetUninitVariableChecking): New procedure.
+ * gm2-compiler/M2Quads.def (PutQuadOtok): Exported and declared.
+ (VariableAnalysis): Removed.
+ * gm2-compiler/M2Quads.mod (PutQuadOtok): New procedure.
+ (doVal): Reformatted.
+ (MarkAsWrite): Reformatted.
+ (MarkArrayAsWritten): Reformatted.
+ (doIndrX): Use PutQuadOtok.
+ (MakeRightValue): Use GenQuadOtok.
+ (MakeLeftValue): Use GenQuadOtok.
+ (CheckReadBeforeInitialized): Remove.
+ (IsNeverAltered): Reformat.
+ (DebugLocation): New procedure.
+ (BuildDesignatorPointer): Use GenQuadO to preserve operand token
+ position.
+ (BuildRelOp): Use GenQuadOtok ditto.
+ * gm2-compiler/SymbolTable.def (VarCheckReadInit): New procedure.
+ (VarInitState): New procedure.
+ (PutVarInitialized): New procedure.
+ (PutVarFieldInitialized): New procedure function.
+ (GetVarFieldInitialized): New procedure function.
+ (PrintInitialized): New procedure.
+ * gm2-compiler/SymbolTable.mod (VarCheckReadInit): New procedure.
+ (VarInitState): New procedure.
+ (PutVarInitialized): New procedure.
+ (PutVarFieldInitialized): New procedure function.
+ (GetVarFieldInitialized): New procedure function.
+ (PrintInitialized): New procedure.
+ (LRInitDesc): New type.
+ (SymVar): InitState new field.
+ (MakeVar): Initialize InitState.
+ * gm2-gcc/m2options.h (M2Options_SetUninitVariableChecking):
+ New function declaration.
+ * gm2-lang.cc (gm2_langhook_handle_option): Detect
+ OPT_Wuninit_variable_checking and call SetUninitVariableChecking.
+ * lang.opt: Add Wuninit-variable-checking.
+ * gm2-compiler/M2SymInit.def: New file.
+ * gm2-compiler/M2SymInit.mod: New file.
+
+2023-06-30 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR testsuite/108835
+ * gm2-libs/RTint.mod: Do not use NIL timeout setting on select,
+ test failures sequentially, finishing on the first success.
+
2023-06-18 Gaius Mulley <gaiusmod2@gmail.com>
PR modula2/110284
diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in
index f6f7b48..6fb551f 100644
--- a/gcc/m2/Make-lang.in
+++ b/gcc/m2/Make-lang.in
@@ -462,7 +462,7 @@ GM2_G=-g -fm2-g
GM2_CPP=
# GM2_DEBUG_STRMEM=-fcpp
GM2_DEBUG_STRMEM=
-GM2_FLAGS=-Wunused-variable -fsoft-check-all \
+GM2_FLAGS=-Wunused-variable -Wuninit-variable-checking -fsoft-check-all \
-fno-return -Wreturn-type \
$(GM2_G) $(GM2_O) \
-funbounded-by-reference -fpim -fextended-opaque \
@@ -750,6 +750,7 @@ GM2-COMP-BOOT-DEFS = \
M2StackWord.def \
M2Students.def \
M2Swig.def \
+ M2SymInit.def \
M2System.def \
NameKey.def \
ObjectFiles.def \
@@ -822,6 +823,7 @@ GM2-COMP-BOOT-MODS = \
M2StackWord.mod \
M2Students.mod \
M2Swig.mod \
+ M2SymInit.mod \
M2System.mod \
NameKey.mod \
NameKey.mod \
@@ -1027,6 +1029,7 @@ GM2-COMP-DEFS = \
M2StackWord.def \
M2Students.def \
M2Swig.def \
+ M2SymInit.def \
M2System.def \
NameKey.def \
ObjectFiles.def \
@@ -1096,6 +1099,7 @@ GM2-COMP-MODS = \
M2StackWord.mod \
M2Students.mod \
M2Swig.mod \
+ M2SymInit.mod \
M2System.mod \
NameKey.mod \
ObjectFiles.mod \
diff --git a/gcc/m2/gm2-compiler/M2BasicBlock.mod b/gcc/m2/gm2-compiler/M2BasicBlock.mod
index 61eb613..1d005f6 100644
--- a/gcc/m2/gm2-compiler/M2BasicBlock.mod
+++ b/gcc/m2/gm2-compiler/M2BasicBlock.mod
@@ -242,7 +242,7 @@ BEGIN
b := bb ;
REPEAT
WITH b^ DO
- p(StartQuad, EndQuad)
+ p (StartQuad, EndQuad)
END ;
b := b^.Right
UNTIL b=bb
diff --git a/gcc/m2/gm2-compiler/M2Code.mod b/gcc/m2/gm2-compiler/M2Code.mod
index 6965b44..c4069e9 100644
--- a/gcc/m2/gm2-compiler/M2Code.mod
+++ b/gcc/m2/gm2-compiler/M2Code.mod
@@ -42,9 +42,11 @@ FROM NameKey IMPORT Name ;
FROM M2Batch IMPORT ForeachSourceModuleDo ;
FROM M2Quads IMPORT CountQuads, GetFirstQuad, DisplayQuadList, DisplayQuadRange,
- BackPatchSubrangesAndOptParam, VariableAnalysis,
+ BackPatchSubrangesAndOptParam,
LoopAnalysis, ForLoopAnalysis, GetQuad, QuadOperator ;
+FROM M2SymInit IMPORT VariableAnalysis ;
+
FROM M2Pass IMPORT SetPassToNoPass, SetPassToCodeGeneration ;
FROM M2BasicBlock IMPORT BasicBlock,
diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
index 5c171f7..c502726 100644
--- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod
+++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
@@ -120,7 +120,7 @@ FROM SymbolTable IMPORT NulSym,
ForeachLocalSymDo, ForeachFieldEnumerationDo,
ForeachProcedureDo, ForeachModuleDo,
ForeachInnerModuleDo, ForeachImportedDo,
- ForeachExportedDo ;
+ ForeachExportedDo, PrintInitialized ;
FROM M2Base IMPORT IsPseudoBaseProcedure, IsPseudoBaseFunction,
GetBaseTypeMinMax, MixTypes,
@@ -339,7 +339,6 @@ END DebugSetNumbers ;
lists.
*)
-(*
PROCEDURE AddSymToWatch (sym: WORD) ;
BEGIN
IF (sym#NulSym) AND (NOT IsElementInSet(WatchList, sym))
@@ -350,7 +349,6 @@ BEGIN
FIO.FlushBuffer(FIO.StdOut)
END
END AddSymToWatch ;
-*)
(*
@@ -409,7 +407,7 @@ BEGIN
tobesolvedbyquads : doInclude(ToBeSolvedByQuads, "symbol %d -> ToBeSolvedByQuads\n", sym) |
fullydeclared : doInclude(FullyDeclared, "symbol %d -> FullyDeclared\n", sym) ;
- IF sym=1265
+ IF sym=8821
THEN
mystop
END |
@@ -2797,7 +2795,7 @@ PROCEDURE StartDeclareScope (scope: CARDINAL) ;
VAR
n: Name ;
BEGIN
- (* AddSymToWatch (1265) ; *)
+ (* AddSymToWatch (8821) ; *)
(* AddSymToWatch (1157) ; *) (* watch goes here *)
(* AddSymToWatch(TryFindSymbol('IOLink', 'DeviceId')) ; *)
(* AddSymToWatch(819) ; *)
@@ -3911,6 +3909,8 @@ BEGIN
THEN
printf0('component ')
END ;
+ printf0 ('\n') ;
+ PrintInitialized (sym) ;
IncludeType(l, sym)
ELSIF IsConst(sym)
THEN
@@ -5229,16 +5229,7 @@ BEGIN
t := CheckAlignment(t, sym)
END
END ;
- IF GetSymName(sym)#NulName
- THEN
- IF Debugging
- THEN
- n := GetSymName(sym) ;
- printf1('declaring type %a\n', n)
- END ;
- t := RememberType(t)
- END ;
- RETURN( t )
+ RETURN RememberType (t)
END TypeConstFullyDeclared ;
diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod
index 90e237d..8b877e2 100644
--- a/gcc/m2/gm2-compiler/M2GenGCC.mod
+++ b/gcc/m2/gm2-compiler/M2GenGCC.mod
@@ -1842,13 +1842,14 @@ END CodeProcedureScope ;
PROCEDURE CodeReturnValue (quad: CARDINAL) ;
VAR
op : QuadOperator ;
+ overflowChecking : BOOLEAN ;
expr, none, procedure : CARDINAL ;
combinedpos,
returnpos, exprpos, nonepos, procpos: CARDINAL ;
value, length : Tree ;
location : location_t ;
BEGIN
- GetQuadOtok (quad, returnpos, op, expr, none, procedure,
+ GetQuadOtok (quad, returnpos, op, expr, none, procedure, overflowChecking,
exprpos, nonepos, procpos) ;
combinedpos := MakeVirtualTok (returnpos, returnpos, exprpos) ;
location := TokenToLocation (combinedpos) ;
@@ -3079,18 +3080,19 @@ END checkDeclare ;
PROCEDURE CodeBecomes (quad: CARDINAL) ;
VAR
- op : QuadOperator ;
- op1, op2,
- op3 : CARDINAL ;
+ overflowChecking: BOOLEAN ;
+ op : QuadOperator ;
+ op1, op2, op3 : CARDINAL ;
becomespos,
op1pos,
op2pos,
- op3pos : CARDINAL ;
+ op3pos : CARDINAL ;
length,
- op3t : Tree ;
- location : location_t ;
+ op3t : Tree ;
+ location : location_t ;
BEGIN
- GetQuadOtok (quad, becomespos, op, op1, op2, op3, op1pos, op2pos, op3pos) ;
+ GetQuadOtok (quad, becomespos, op, op1, op2, op3, overflowChecking,
+ op1pos, op2pos, op3pos) ;
Assert (op2pos = UnknownTokenNo) ;
DeclareConstant (CurrentQuadToken, op3) ; (* Check to see whether op3 is a constant and declare it. *)
DeclareConstructor (CurrentQuadToken, quad, op3) ;
@@ -7177,7 +7179,8 @@ END CodeIndrX ;
PROCEDURE CodeXIndr (quad: CARDINAL) ;
VAR
- op : QuadOperator ;
+ overflowChecking: BOOLEAN ;
+ op : QuadOperator ;
tokenno,
op1,
type,
@@ -7185,12 +7188,13 @@ VAR
op1pos,
op3pos,
typepos,
- xindrpos: CARDINAL ;
+ xindrpos : CARDINAL ;
length,
- newstr : Tree ;
- location: location_t ;
+ newstr : Tree ;
+ location : location_t ;
BEGIN
- GetQuadOtok (quad, xindrpos, op, op1, type, op3, op1pos, typepos, op3pos) ;
+ GetQuadOtok (quad, xindrpos, op, op1, type, op3, overflowChecking,
+ op1pos, typepos, op3pos) ;
tokenno := MakeVirtualTok (xindrpos, op1pos, op3pos) ;
location := TokenToLocation (tokenno) ;
diff --git a/gcc/m2/gm2-compiler/M2Optimize.mod b/gcc/m2/gm2-compiler/M2Optimize.mod
index ca03092..416eb42 100644
--- a/gcc/m2/gm2-compiler/M2Optimize.mod
+++ b/gcc/m2/gm2-compiler/M2Optimize.mod
@@ -58,8 +58,7 @@ FROM SymbolTable IMPORT GetSymName,
FROM M2Quads IMPORT QuadOperator, GetQuad, GetFirstQuad, GetNextQuad,
PutQuad, SubQuad, Opposite, IsReferenced,
- GetRealQuad ;
-
+ GetRealQuad, GetQuadOtok, PutQuadOtok ;
(*
FoldBranches - folds unneccessary branches in the list of quadruples.
@@ -114,14 +113,14 @@ BEGIN
GetQuad(i, Operator, Operand1, Operand2, Operand3) ;
CASE Operator OF
- GotoOp : Folded := ReduceGoto(i, Operand3,
- Right, Folded) |
+ GotoOp : Folded := ReduceGoto (i, Operand3,
+ Right, Folded) |
IfInOp, IfNotInOp,
IfNotEquOp, IfEquOp,
IfLessEquOp, IfGreEquOp,
- IfGreOp, IfLessOp : Folded := ReduceBranch(Operator, i,
- Operand1, Operand2, Operand3,
- Right, Folded)
+ IfGreOp, IfLessOp : Folded := ReduceBranch (Operator, i,
+ Operand1, Operand2, Operand3,
+ Right, Folded)
ELSE
END ;
@@ -154,48 +153,56 @@ PROCEDURE ReduceBranch (Operator: QuadOperator;
VAR NextQuad: CARDINAL;
Folded: BOOLEAN) : BOOLEAN ;
VAR
- OpNext : QuadOperator ;
+ overflowChecking: BOOLEAN ;
+ OpNext : QuadOperator ;
+ tok,
NextPlusOne,
Op1Next,
Op2Next,
Op3Next,
- From,
- To : CARDINAL ;
+ op1tok,
+ op2tok,
+ op3tok,
+ From, To : CARDINAL ;
BEGIN
(* If op NextQuad+1 *)
(* Goto x *)
IF NextQuad#0
THEN
- IF (GetNextQuad(CurrentQuad)=CurrentOperand3) OR
- (GetRealQuad(GetNextQuad(CurrentQuad))=CurrentOperand3)
+ IF (GetNextQuad (CurrentQuad) = CurrentOperand3) OR
+ (GetRealQuad (GetNextQuad (CurrentQuad)) = CurrentOperand3)
THEN
- SubQuad(CurrentQuad) ;
+ SubQuad (CurrentQuad) ;
Folded := TRUE
ELSE
- From := GetNextQuad(CurrentQuad) ; (* start after CurrentQuad *)
+ From := GetNextQuad (CurrentQuad) ; (* start after CurrentQuad *)
To := NextQuad ;
- CurrentOperand3 := GetRealQuad(CurrentOperand3) ;
+ CurrentOperand3 := GetRealQuad (CurrentOperand3) ;
- NextPlusOne := GetRealQuad(GetNextQuad(NextQuad)) ;
- GetQuad(NextQuad, OpNext, Op1Next, Op2Next, Op3Next) ;
- IF (OpNext=GotoOp) AND (NextPlusOne=CurrentOperand3) AND
- IsBasicBlock(From, To)
+ NextPlusOne := GetRealQuad (GetNextQuad (NextQuad)) ;
+ GetQuad (NextQuad, OpNext, Op1Next, Op2Next, Op3Next) ;
+ IF (OpNext = GotoOp) AND (NextPlusOne = CurrentOperand3) AND
+ IsBasicBlock (From, To)
THEN
- (* Op3Next := GetRealQuad(Op3Next) ; *)
- SubQuad(NextQuad) ;
- PutQuad(CurrentQuad, Opposite(Operator),
- CurrentOperand1, CurrentOperand2, Op3Next) ;
+ GetQuadOtok (CurrentQuad, tok, Operator,
+ CurrentOperand1, CurrentOperand2, CurrentOperand3,
+ overflowChecking, op1tok, op2tok, op3tok) ;
+ SubQuad (NextQuad) ;
+ PutQuadOtok (CurrentQuad, tok, Opposite (Operator),
+ CurrentOperand1, CurrentOperand2, Op3Next,
+ overflowChecking,
+ op1tok, op2tok, op3tok) ;
NextQuad := NextPlusOne ;
Folded := TRUE
END
END ;
- IF FoldMultipleGoto(CurrentQuad)
+ IF FoldMultipleGoto (CurrentQuad)
THEN
Folded := TRUE
END
END ;
- RETURN( Folded )
+ RETURN Folded
END ReduceBranch ;
@@ -237,20 +244,20 @@ END IsBasicBlock ;
PROCEDURE ReduceGoto (CurrentQuad, CurrentOperand3, NextQuad: CARDINAL;
Folded: BOOLEAN) : BOOLEAN ;
BEGIN
- CurrentOperand3 := GetRealQuad(CurrentOperand3) ;
+ CurrentOperand3 := GetRealQuad (CurrentOperand3) ;
(* IF next quad is a GotoOp *)
- IF CurrentOperand3=NextQuad
+ IF CurrentOperand3 = NextQuad
THEN
- SubQuad(CurrentQuad) ;
+ SubQuad (CurrentQuad) ;
Folded := TRUE
ELSE
(* Does Goto point to another Goto ? *)
- IF FoldMultipleGoto(CurrentQuad)
+ IF FoldMultipleGoto (CurrentQuad)
THEN
Folded := TRUE
END
END ;
- RETURN( Folded )
+ RETURN Folded
END ReduceGoto ;
@@ -272,18 +279,18 @@ VAR
Operand2,
Operand3: CARDINAL ;
BEGIN
- GetQuad(QuadNo, Operator, Operand1, Operand2, Operand3) ;
- Operand3 := GetRealQuad(Operand3) ; (* skip pseudo quadruples *)
- GetQuad(Operand3, Op, Op1, Op2, Op3) ;
- IF Op=GotoOp
+ GetQuad (QuadNo, Operator, Operand1, Operand2, Operand3) ;
+ Operand3 := GetRealQuad (Operand3) ; (* skip pseudo quadruples *)
+ GetQuad (Operand3, Op, Op1, Op2, Op3) ;
+ IF Op = GotoOp
THEN
- PutQuad(QuadNo, Operator, Operand1, Operand2, Op3) ;
+ PutQuad (QuadNo, Operator, Operand1, Operand2, Op3) ;
(* Dont want success to be returned if in fact the Goto *)
(* line number has not changed... otherwise we loop *)
(* forever. *)
- RETURN( Op3#Operand3 )
+ RETURN Op3 # Operand3
ELSE
- RETURN( FALSE )
+ RETURN FALSE
END
END FoldMultipleGoto ;
@@ -352,29 +359,29 @@ BEGIN
IF Start#0
THEN
REPEAT
- GetQuad(Start, Op, Op1, Op2, Op3) ;
+ GetQuad (Start, Op, Op1, Op2, Op3) ;
CASE Op OF
- CallOp : KnownReach(Op3) |
+ CallOp : KnownReach (Op3) |
AddrOp,
ParamOp,
XIndrOp,
- BecomesOp: KnownReach(Op3) ;
- CheckNeedSavePriority(Op3)
+ BecomesOp: KnownReach (Op3) ;
+ CheckNeedSavePriority (Op3)
ELSE
END ;
- Start := GetNextQuad(Start)
- UNTIL (Start>End) OR (Start=0)
+ Start := GetNextQuad (Start)
+ UNTIL (Start > End) OR (Start = 0)
END
END KnownReachable ;
PROCEDURE KnownReach (sym: CARDINAL) ;
BEGIN
- IF IsProcedure(sym) AND (NOT IsProcedureReachable(sym))
+ IF IsProcedure (sym) AND (NOT IsProcedureReachable (sym))
THEN
- RemoveProcedures(sym)
+ RemoveProcedures (sym)
END
END KnownReach ;
diff --git a/gcc/m2/gm2-compiler/M2Options.def b/gcc/m2/gm2-compiler/M2Options.def
index 7e4d2aa..722e56c 100644
--- a/gcc/m2/gm2-compiler/M2Options.def
+++ b/gcc/m2/gm2-compiler/M2Options.def
@@ -72,6 +72,7 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck,
AutoInit,
VariantValueChecking,
UnusedVariableChecking, UnusedParameterChecking,
+ UninitVariableChecking, SetUninitVariableChecking,
SetUnusedVariableChecking, SetUnusedParameterChecking,
Quiet, LineDirectives, StrictTypeChecking,
CPreProcessor, Xcode, ExtendedOpaque,
@@ -159,6 +160,8 @@ VAR
Exceptions, (* Should we generate exception code? *)
UnusedVariableChecking, (* Should we warn about unused variables? *)
UnusedParameterChecking, (* Should we warn about unused parameters? *)
+ UninitVariableChecking, (* Should we warn about accessing *)
+ (* uninitialized variables in the first bb? *)
LowerCaseKeywords, (* Should keywords in errors be in lower? *)
DebugBuiltins, (* Should we always call a real function? *)
AutoInit, (* -fauto-init assigns pointers to NIL. *)
@@ -919,6 +922,13 @@ PROCEDURE SetShared (value: BOOLEAN) ;
(*
+ SetUninitVariableChecking - sets the UninitVariableChecking flag to value.
+*)
+
+PROCEDURE SetUninitVariableChecking (value: BOOLEAN) ;
+
+
+(*
FinaliseOptions - once all options have been parsed we set any inferred
values.
*)
diff --git a/gcc/m2/gm2-compiler/M2Options.mod b/gcc/m2/gm2-compiler/M2Options.mod
index 7cacee2..84fcb57 100644
--- a/gcc/m2/gm2-compiler/M2Options.mod
+++ b/gcc/m2/gm2-compiler/M2Options.mod
@@ -1190,6 +1190,7 @@ PROCEDURE SetWall (value: BOOLEAN) ;
BEGIN
UnusedVariableChecking := value ;
UnusedParameterChecking := value ;
+ UninitVariableChecking := value ;
PedanticCast := value ;
PedanticParamNames := value ;
StyleChecking := value
@@ -1226,6 +1227,7 @@ BEGIN
RETURN SaveTempsDir
END GetSaveTempsDir ;
+
(*
SetDumpDir - Set the dump dir.
*)
@@ -1363,6 +1365,17 @@ BEGIN
END SetShared ;
+(*
+ SetUninitVariableChecking - sets the UninitVariableChecking flag to value.
+*)
+
+PROCEDURE SetUninitVariableChecking (value: BOOLEAN) ;
+BEGIN
+ UninitVariableChecking := value
+END SetUninitVariableChecking ;
+
+
+
BEGIN
cflag := FALSE ; (* -c. *)
RuntimeModuleOverride := InitString (DefaultRuntimeModuleOverride) ;
@@ -1433,6 +1446,7 @@ BEGIN
MQarg := NIL ;
SaveTempsDir := NIL ;
DumpDir := NIL ;
+ UninitVariableChecking := FALSE ;
M2Prefix := InitString ('') ;
M2PathName := InitString ('')
END M2Options.
diff --git a/gcc/m2/gm2-compiler/M2Quads.def b/gcc/m2/gm2-compiler/M2Quads.def
index fcb59bb..ef6c06c 100644
--- a/gcc/m2/gm2-compiler/M2Quads.def
+++ b/gcc/m2/gm2-compiler/M2Quads.def
@@ -129,13 +129,13 @@ EXPORT QUALIFIED StartBuildDefFile, StartBuildModFile, EndBuildFile,
GetQuad, GetFirstQuad, GetNextQuad, PutQuad,
SubQuad, EraseQuad, GetRealQuad,
- GetQuadtok, GetQuadOtok,
+ GetQuadtok, GetQuadOtok, PutQuadOtok,
GetQuadOp, GetM2OperatorDesc,
CountQuads,
GetLastFileQuad,
GetLastQuadNo,
QuadToLineNo, QuadToTokenNo,
- VariableAnalysis, LoopAnalysis, ForLoopAnalysis,
+ LoopAnalysis, ForLoopAnalysis,
AddVarientFieldToList, AddRecordToList,
AddVarientToList,
AddVarientRange, AddVarientEquality,
@@ -477,10 +477,24 @@ PROCEDURE GetQuadOtok (QuadNo: CARDINAL;
VAR tok: CARDINAL;
VAR Op: QuadOperator;
VAR Oper1, Oper2, Oper3: CARDINAL;
+ VAR overflowChecking: BOOLEAN ;
VAR Op1Pos, Op2Pos, Op3Pos: CARDINAL) ;
(*
+ PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
+ sets a boolean to determinine whether overflow should be checked.
+*)
+
+PROCEDURE PutQuadOtok (QuadNo: CARDINAL;
+ tok: CARDINAL;
+ Op: QuadOperator;
+ Oper1, Oper2, Oper3: CARDINAL;
+ overflowChecking: BOOLEAN ;
+ Op1Pos, Op2Pos, Op3Pos: CARDINAL) ;
+
+
+(*
PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
*)
@@ -2574,16 +2588,6 @@ PROCEDURE BuildStmtNote (offset: INTEGER) ;
(*
- VariableAnalysis - checks to see whether a variable is:
-
- read without being initialized or
- written over when it is a non var parameter
-*)
-
-PROCEDURE VariableAnalysis (Start, End: CARDINAL) ;
-
-
-(*
LoopAnalysis - checks whether an infinite loop exists.
*)
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index a27c3e1..dc73265 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -109,7 +109,7 @@ FROM SymbolTable IMPORT ModeOfAddr, GetMode, PutMode, GetSymName, IsUnknown,
PutConstructor, PutConstructorFrom,
PutDeclared,
MakeComponentRecord, MakeComponentRef,
- IsSubscript,
+ IsSubscript, IsComponent,
IsTemporary,
IsAModula2Type,
PutLeftValueFrontBackType,
@@ -210,6 +210,7 @@ FROM M2Options IMPORT NilChecking,
Pedantic, CompilerDebugging, GenerateDebugging,
GenerateLineDebug, Exceptions,
Profiling, Coding, Optimizing,
+ UninitVariableChecking,
ScaffoldDynamic, ScaffoldStatic, cflag,
ScaffoldMain, SharedFlag, WholeProgram,
GetRuntimeModuleOverride ;
@@ -262,15 +263,14 @@ IMPORT M2Error ;
CONST
DebugStackOn = TRUE ;
DebugVarients = FALSE ;
- BreakAtQuad = 133 ;
+ BreakAtQuad = 53 ;
DebugTokPos = FALSE ;
TYPE
- ConstructorFrame = POINTER TO constructorFrame ;
- constructorFrame = RECORD
- type : CARDINAL ;
- index: CARDINAL ;
- END ;
+ ConstructorFrame = POINTER TO RECORD
+ type : CARDINAL ;
+ index: CARDINAL ;
+ END ;
BoolFrame = POINTER TO RECORD
TrueExit : CARDINAL ;
@@ -1127,7 +1127,7 @@ PROCEDURE GetQuadtok (QuadNo: CARDINAL;
VAR
f: QuadFrame ;
BEGIN
- f := GetQF(QuadNo) ;
+ f := GetQF (QuadNo) ;
LastQuadNo := QuadNo ;
WITH f^ DO
Op := Operator ;
@@ -1149,11 +1149,12 @@ PROCEDURE GetQuadOtok (QuadNo: CARDINAL;
VAR tok: CARDINAL;
VAR Op: QuadOperator;
VAR Oper1, Oper2, Oper3: CARDINAL;
+ VAR overflowChecking: BOOLEAN ;
VAR Op1Pos, Op2Pos, Op3Pos: CARDINAL) ;
VAR
f: QuadFrame ;
BEGIN
- f := GetQF(QuadNo) ;
+ f := GetQF (QuadNo) ;
LastQuadNo := QuadNo ;
WITH f^ DO
Op := Operator ;
@@ -1163,12 +1164,51 @@ BEGIN
Op1Pos := op1pos ;
Op2Pos := op2pos ;
Op3Pos := op3pos ;
- tok := TokenNo
+ tok := TokenNo ;
+ overflowChecking := CheckOverflow
END
END GetQuadOtok ;
(*
+ PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
+ sets a boolean to determinine whether overflow should be checked.
+*)
+
+PROCEDURE PutQuadOtok (QuadNo: CARDINAL;
+ tok: CARDINAL;
+ Op: QuadOperator;
+ Oper1, Oper2, Oper3: CARDINAL;
+ overflowChecking: BOOLEAN ;
+ Op1Pos, Op2Pos, Op3Pos: CARDINAL) ;
+VAR
+ f: QuadFrame ;
+BEGIN
+ IF QuadNo = BreakAtQuad
+ THEN
+ stop
+ END ;
+ IF QuadrupleGeneration
+ THEN
+ EraseQuad (QuadNo) ;
+ AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3) ;
+ f := GetQF (QuadNo) ;
+ WITH f^ DO
+ Operator := Op ;
+ Operand1 := Oper1 ;
+ Operand2 := Oper2 ;
+ Operand3 := Oper3 ;
+ CheckOverflow := overflowChecking ;
+ op1pos := Op1Pos ;
+ op2pos := Op2Pos ;
+ op3pos := Op3Pos ;
+ TokenNo := tok
+ END
+ END
+END PutQuadOtok ;
+
+
+(*
AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
*)
@@ -3118,7 +3158,7 @@ PROCEDURE MarkArrayWritten (Array: CARDINAL) ;
BEGIN
IF (Array#NulSym) AND IsVarAParam(Array)
THEN
- PutVarWritten(Array, TRUE)
+ PutVarWritten (Array, TRUE)
END
END MarkArrayWritten ;
@@ -3157,9 +3197,9 @@ END MarkAsRead ;
PROCEDURE MarkAsWrite (sym: CARDINAL) ;
BEGIN
- IF (sym#NulSym) AND IsVar(sym)
+ IF (sym # NulSym) AND IsVar (sym)
THEN
- PutWriteQuad(sym, RightValue, NextQuad)
+ PutWriteQuad (sym, RightValue, NextQuad)
END
END MarkAsWrite ;
@@ -3171,14 +3211,14 @@ END MarkAsWrite ;
PROCEDURE doVal (type, expr: CARDINAL) : CARDINAL ;
BEGIN
- IF (NOT IsConst(expr)) AND (SkipType(type)#GetDType(expr))
+ IF (NOT IsConst (expr)) AND (SkipType (type) # GetDType (expr))
THEN
- PushTF(Convert, NulSym) ;
- PushT(SkipType(type)) ;
- PushT(expr) ;
- PushT(2) ; (* Two parameters *)
+ PushTF (Convert, NulSym) ;
+ PushT (SkipType(type)) ;
+ PushT (expr) ;
+ PushT (2) ; (* Two parameters *)
BuildConvertFunction ;
- PopT(expr)
+ PopT (expr)
END ;
RETURN( expr )
END doVal ;
@@ -5952,12 +5992,15 @@ VAR
BEGIN
IF GetDType(des)=GetDType(exp)
THEN
- GenQuadO (tok, IndrXOp, des, GetSType(des), exp, TRUE)
+ GenQuadOtok (tok, IndrXOp, des, GetSType (des), exp, TRUE,
+ tok, tok, tok)
ELSE
t := MakeTemporary (tok, RightValue) ;
PutVar (t, GetSType (exp)) ;
- GenQuadO (tok, IndrXOp, t, GetSType (exp), exp, TRUE) ;
- GenQuadO (tok, BecomesOp, des, NulSym, doVal (GetSType(des), t), TRUE)
+ GenQuadOtok (tok, IndrXOp, t, GetSType (exp), exp, TRUE,
+ tok, tok, tok) ;
+ GenQuadOtok (tok, BecomesOp, des, NulSym, doVal (GetSType(des), t), TRUE,
+ tok, UnknownTokenNo, tok)
END
END doIndrX ;
@@ -5986,7 +6029,8 @@ BEGIN
*)
t := MakeTemporary (tok, RightValue) ;
PutVar (t, type) ;
- GenQuadO (tok, BecomesOp, t, NulSym, doVal(type, Sym), TRUE) ;
+ GenQuadOtok (tok, BecomesOp, t, NulSym, doVal (type, Sym), TRUE,
+ tok, tok, tok) ;
RETURN t
END
ELSE
@@ -6022,13 +6066,15 @@ BEGIN
*)
t := MakeTemporary (tok, with) ;
PutVar (t, type) ;
- GenQuadO (tok, BecomesOp, t, NulSym, Sym, TRUE) ;
+ GenQuadOtok (tok, BecomesOp, t, NulSym, Sym, TRUE,
+ tok, UnknownTokenNo, tok) ;
RETURN t
END
ELSE
t := MakeTemporary (tok, with) ;
PutVar (t, type) ;
- GenQuadO (tok, AddrOp, t, NulSym, Sym, TRUE) ;
+ GenQuadOtok (tok, AddrOp, t, NulSym, Sym, TRUE,
+ tok, UnknownTokenNo, tok) ;
RETURN t
END
END MakeLeftValue ;
@@ -6998,13 +7044,13 @@ BEGIN
IF IsExpressionCompatible (dtype, etype)
THEN
(* the easy case simulate a straightforward macro *)
- PushTF(des, dtype) ;
- PushT(tok) ;
- PushTF(expr, etype) ;
- doBuildBinaryOp(FALSE, TRUE)
+ PushTF (des, dtype) ;
+ PushT (tok) ;
+ PushTF (expr, etype) ;
+ doBuildBinaryOp (FALSE, TRUE)
ELSE
- IF (IsOrdinalType(dtype) OR (dtype=Address) OR IsPointer(dtype)) AND
- (IsOrdinalType(etype) OR (etype=Address) OR IsPointer(etype))
+ IF (IsOrdinalType (dtype) OR (dtype = Address) OR IsPointer (dtype)) AND
+ (IsOrdinalType (etype) OR (etype = Address) OR IsPointer (etype))
THEN
PushTF (des, dtype) ;
PushT (tok) ;
@@ -10502,72 +10548,6 @@ END BuildProcedureEnd ;
(*
- CheckReadBeforeInitialized -
-*)
-
-PROCEDURE CheckReadBeforeInitialized (ProcSym: CARDINAL; End: CARDINAL) ;
-VAR
- s1, s2 : String ;
- i, n, ParamNo,
- ReadStart, ReadEnd,
- WriteStart, WriteEnd: CARDINAL ;
-BEGIN
- ParamNo := NoOfParam(ProcSym) ;
- i := 1 ;
- REPEAT
- n := GetNth(ProcSym, i) ;
- IF (n#NulSym) AND (NOT IsTemporary(n))
- THEN
- GetReadQuads(n, RightValue, ReadStart, ReadEnd) ;
- GetWriteQuads(n, RightValue, WriteStart, WriteEnd) ;
- IF i>ParamNo
- THEN
- (* n is a not a parameter thus we can check *)
- IF (ReadStart>0) AND (ReadStart<End)
- THEN
- (* it is read in the first basic block *)
- IF ReadStart<WriteStart
- THEN
- (* read before written, this is a problem which must be fixed *)
- s1 := Mark(InitStringCharStar(KeyToCharStar(GetSymName(n)))) ;
- s2 := Mark(InitStringCharStar(KeyToCharStar(GetSymName(ProcSym)))) ;
- ErrorStringAt2(Sprintf2(Mark(InitString('reading from a variable (%s) before it is initialized in procedure (%s)')),
- s1, s2),
- GetDeclaredMod(n), GetDeclaredMod(n))
- END
- END
- END
- END ;
- INC(i)
- UNTIL n=NulSym
-END CheckReadBeforeInitialized ;
-
-
-(*
- VariableAnalysis - checks to see whether a variable is:
-
- read before it has been initialized
-*)
-
-PROCEDURE VariableAnalysis (Start, End: CARDINAL) ;
-VAR
- Op : QuadOperator ;
- Op1, Op2, Op3: CARDINAL ;
-BEGIN
- IF Pedantic
- THEN
- GetQuad(Start, Op, Op1, Op2, Op3) ;
- CASE Op OF
-
- NewLocalVarOp: CheckReadBeforeInitialized(Op3, End)
-
- ELSE
- END
- END
-END VariableAnalysis ;
-
-
-(*
IsNeverAltered - returns TRUE if variable, sym, is never altered
between quadruples: Start..End
*)
@@ -10576,8 +10556,8 @@ PROCEDURE IsNeverAltered (sym: CARDINAL; Start, End: CARDINAL) : BOOLEAN ;
VAR
WriteStart, WriteEnd: CARDINAL ;
BEGIN
- GetWriteLimitQuads(sym, GetMode(sym), Start, End, WriteStart, WriteEnd) ;
- RETURN( (WriteStart=0) AND (WriteEnd=0) )
+ GetWriteLimitQuads (sym, GetMode (sym), Start, End, WriteStart, WriteEnd) ;
+ RETURN( (WriteStart = 0) AND (WriteEnd = 0) )
END IsNeverAltered ;
@@ -10592,8 +10572,8 @@ VAR
LeftFixed,
RightFixed : BOOLEAN ;
BEGIN
- GetQuad(q, op, op1, op2, op3) ;
- IF op=GotoOp
+ GetQuad (q, op, op1, op2, op3) ;
+ IF op = GotoOp
THEN
RETURN( FALSE )
ELSE
@@ -10844,6 +10824,7 @@ END AsmStatementsInBlock ;
PROCEDURE CheckVariablesInBlock (BlockSym: CARDINAL) ;
BEGIN
CheckVariablesAndParameterTypesInBlock (BlockSym) ;
+ (*
IF UnusedVariableChecking OR UnusedParameterChecking
THEN
IF (NOT AsmStatementsInBlock (BlockSym))
@@ -10851,6 +10832,7 @@ BEGIN
CheckUninitializedVariablesAreUsed (BlockSym)
END
END
+ *)
END CheckVariablesInBlock ;
@@ -11429,6 +11411,19 @@ END BuildDynamicArray ;
(*
+ DebugLocation -
+*)
+
+PROCEDURE DebugLocation (tok: CARDINAL; message: ARRAY OF CHAR) ;
+BEGIN
+ IF DebugTokPos
+ THEN
+ WarnStringAt (InitString (message), tok)
+ END
+END DebugLocation ;
+
+
+(*
BuildDesignatorPointer - Builds a pointer reference.
The Stack is expected to contain:
@@ -11451,6 +11446,8 @@ VAR
Sym2, Type2: CARDINAL ;
BEGIN
PopTFrwtok (Sym1, Type1, rw, exprtok) ;
+ DebugLocation (exprtok, "expression") ;
+
Type1 := SkipType (Type1) ;
IF Type1 = NulSym
THEN
@@ -11473,15 +11470,16 @@ BEGIN
THEN
rw := NulSym ;
PutLeftValueFrontBackType (Sym2, Type2, Type1) ;
- GenQuad (IndrXOp, Sym2, Type1, Sym1) (* Sym2 := *Sym1 *)
+ GenQuadO (ptrtok, IndrXOp, Sym2, Type1, Sym1, FALSE) (* Sym2 := *Sym1 *)
ELSE
PutLeftValueFrontBackType (Sym2, Type2, NulSym) ;
- GenQuad (BecomesOp, Sym2, NulSym, Sym1) (* Sym2 := Sym1 *)
+ GenQuadO (ptrtok, BecomesOp, Sym2, NulSym, Sym1, FALSE) (* Sym2 := Sym1 *)
END ;
PutVarPointerCheck (Sym2, TRUE) ; (* we should check this for *)
(* Sym2 later on (pointer via NIL) *)
combinedtok := MakeVirtualTok (exprtok, exprtok, ptrtok) ;
- PushTFrwtok (Sym2, Type2, rw, combinedtok)
+ PushTFrwtok (Sym2, Type2, rw, combinedtok) ;
+ DebugLocation (combinedtok, "pointer expression")
ELSE
MetaError2 ('{%1ad} is not a pointer type but a {%2d}', Sym1, Type1)
END
@@ -11505,23 +11503,26 @@ VAR
Sym, Type,
Ref : CARDINAL ;
BEGIN
+ DebugLocation (withtok, "with") ;
BuildStmtNoteTok (withTok) ;
DisplayStack ;
PopTFtok (Sym, Type, tok) ;
+ DebugLocation (tok, "expression") ;
Type := SkipType (Type) ;
Ref := MakeTemporary (tok, LeftValue) ;
PutVar (Ref, Type) ;
IF GetMode (Sym) = LeftValue
THEN
- (* copy LeftValue *)
+ (* Copy LeftValue. *)
GenQuadO (tok, BecomesOp, Ref, NulSym, Sym, TRUE)
ELSE
- (* calculate the address of Sym *)
+ (* Calculate the address of Sym. *)
GenQuadO (tok, AddrOp, Ref, NulSym, Sym, TRUE)
END ;
PushWith (Sym, Type, Ref, tok) ;
+ DebugLocation (tok, "with ref") ;
IF Type = NulSym
THEN
MetaError1 ('{%1Ea} {%1d} has a no type, the {%kWITH} statement requires a variable or parameter of a {%kRECORD} type',
@@ -11562,9 +11563,9 @@ BEGIN
IF Pedantic
THEN
n := NoOfItemsInStackAddress(WithStack) ;
- i := 1 ; (* top of the stack *)
+ i := 1 ; (* Top of the stack. *)
WHILE i <= n DO
- (* Search for other declarations of the with using Type *)
+ (* Search for other declarations of the with using Type. *)
f := PeepAddress(WithStack, i) ;
IF f^.RecordSym=Type
THEN
@@ -12454,7 +12455,7 @@ VAR
leftpos, rightpos : CARDINAL ;
value : CARDINAL ;
BEGIN
- Operator := OperandT(2) ;
+ Operator := OperandT (2) ;
IF Operator = OrTok
THEN
CheckBooleanId ;
@@ -12874,6 +12875,7 @@ VAR
t,
rightType, leftType,
right, left : CARDINAL ;
+ s : String ;
BEGIN
IF CompilerDebugging
THEN
@@ -12926,7 +12928,23 @@ BEGIN
left := t
END ;
combinedTok := MakeVirtualTok (optokpos, leftpos, rightpos) ;
- GenQuadO (combinedTok, MakeOp (Op), left, right, 0, FALSE) ; (* True Exit *)
+
+ IF DebugTokPos
+ THEN
+ s := InitStringCharStar (KeyToCharStar (GetTokenName (Op))) ;
+ WarnStringAt (s, optokpos) ;
+ s := InitString ('left') ;
+ WarnStringAt (s, leftpos) ;
+ s := InitString ('right') ;
+ WarnStringAt (s, rightpos) ;
+ s := InitString ('caret') ;
+ WarnStringAt (s, optokpos) ;
+ s := InitString ('combined') ;
+ WarnStringAt (s, combinedTok)
+ END ;
+
+ GenQuadOtok (combinedTok, MakeOp (Op), left, right, 0, FALSE,
+ leftpos, rightpos, UnknownTokenNo) ; (* True Exit *)
GenQuadO (combinedTok, GotoOp, NulSym, NulSym, 0, FALSE) ; (* False Exit *)
PushBool (NextQuad-2, NextQuad-1)
END
diff --git a/gcc/m2/gm2-compiler/M2SymInit.def b/gcc/m2/gm2-compiler/M2SymInit.def
new file mode 100644
index 0000000..2ea6bfc
--- /dev/null
+++ b/gcc/m2/gm2-compiler/M2SymInit.def
@@ -0,0 +1,59 @@
+(* M2SymInit.def records initialization state for variables.
+
+Copyright (C) 2001-2023 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 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.
+
+GNU Modula-2 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 GNU Modula-2; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. *)
+
+DEFINITION MODULE M2SymInit ;
+
+FROM Lists IMPORT List ;
+
+TYPE
+ InitDesc ;
+
+
+PROCEDURE InitSymInit () : InitDesc ;
+PROCEDURE KillSymInit (VAR desc: InitDesc) ;
+
+
+PROCEDURE ConfigSymInit (desc: InitDesc; sym: CARDINAL) ;
+
+
+PROCEDURE SetInitialized (desc: InitDesc) ;
+PROCEDURE GetInitialized (desc: InitDesc) : BOOLEAN ;
+
+
+PROCEDURE GetFieldDesc (desc: InitDesc; field: CARDINAL) : InitDesc ;
+
+PROCEDURE SetFieldInitialized (desc: InitDesc; fieldlist: List) : BOOLEAN ;
+PROCEDURE GetFieldInitialized (desc: InitDesc; fieldlist: List) : BOOLEAN ;
+
+
+(*
+ VariableAnalysis - checks to see whether a variable is:
+
+ read before it has been initialized
+*)
+
+PROCEDURE VariableAnalysis (Start, End: CARDINAL) ;
+
+
+PROCEDURE PrintSymInit (desc: InitDesc) ;
+
+
+END M2SymInit.
diff --git a/gcc/m2/gm2-compiler/M2SymInit.mod b/gcc/m2/gm2-compiler/M2SymInit.mod
new file mode 100644
index 0000000..18200af
--- /dev/null
+++ b/gcc/m2/gm2-compiler/M2SymInit.mod
@@ -0,0 +1,1307 @@
+(* M2SymInit.mod records initialization state for variables.
+
+Copyright (C) 2001-2023 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 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.
+
+GNU Modula-2 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 GNU Modula-2; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. *)
+
+IMPLEMENTATION MODULE M2SymInit ;
+
+FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
+FROM M2Debug IMPORT Assert ;
+FROM libc IMPORT printf ;
+FROM NameKey IMPORT Name, NulName, KeyToCharStar ;
+FROM M2Options IMPORT UninitVariableChecking ;
+FROM M2MetaError IMPORT MetaErrorT1 ;
+FROM M2LexBuf IMPORT UnknownTokenNo ;
+
+IMPORT Indexing ;
+
+FROM Lists IMPORT List, InitList, GetItemFromList, PutItemIntoList,
+ IsItemInList, IncludeItemIntoList, NoOfItemsInList,
+ RemoveItemFromList, ForeachItemInListDo, KillList ;
+
+FROM SymbolTable IMPORT NulSym, ModeOfAddr, IsVar, IsRecord, GetSType,
+ GetNth, IsRecordField, IsSet, IsArray, IsProcedure,
+ GetVarScope, IsVarAParam, IsComponent, GetMode,
+ VarCheckReadInit, VarInitState, PutVarInitialized,
+ PutVarFieldInitialized, GetVarFieldInitialized,
+ IsConst, IsConstString, NoOfParam, IsVarParam,
+ ForeachLocalSymDo, IsTemporary, ModeOfAddr,
+ IsReallyPointer, IsUnbounded,
+ IsVarient, IsFieldVarient, GetVarient ;
+
+FROM M2Quads IMPORT QuadOperator, GetQuadOtok, GetQuad, GetNextQuad ;
+FROM M2Options IMPORT CompilerDebugging ;
+FROM M2Printf IMPORT printf0, printf1, printf2 ;
+FROM M2GCCDeclare IMPORT PrintSym ;
+
+
+CONST
+ Debugging = FALSE ;
+
+TYPE
+ descType = (scalar, record) ;
+
+ InitDesc = POINTER TO RECORD
+ sym, type : CARDINAL ;
+ initialized: BOOLEAN ;
+ CASE kind: descType OF
+
+ scalar: |
+ record: rec: recordDesc |
+
+ END
+ END ;
+
+ recordDesc = RECORD
+ fieldDesc: Indexing.Index ;
+ END ;
+
+ symAlias = POINTER TO RECORD
+ keySym,
+ alias : CARDINAL ;
+ next : symAlias ;
+ END ;
+
+VAR
+ aliasArray: Indexing.Index ;
+ freeList : symAlias ;
+
+
+(*
+ PrintSymInit -
+*)
+
+PROCEDURE PrintSymInit (desc: InitDesc) ;
+VAR
+ i, n: CARDINAL ;
+BEGIN
+ printf ("sym %d: type %d ", desc^.sym, desc^.type) ;
+ IF desc^.kind = scalar
+ THEN
+ printf ("scalar")
+ ELSE
+ printf ("record")
+ END ;
+ IF NOT desc^.initialized
+ THEN
+ printf (" not")
+ END ;
+ printf (" initialized\n") ;
+ IF (desc^.type # NulSym) AND IsRecord (desc^.type)
+ THEN
+ i := 1 ;
+ n := Indexing.HighIndice (desc^.rec.fieldDesc) ;
+ WHILE i <= n DO
+ PrintSymInit (Indexing.GetIndice (desc^.rec.fieldDesc, i)) ;
+ INC (i)
+ END
+ END
+END PrintSymInit ;
+
+
+PROCEDURE InitSymInit () : InitDesc ;
+VAR
+ id: InitDesc ;
+BEGIN
+ NEW (id) ;
+ WITH id^ DO
+ sym := NulSym ;
+ type := NulSym ;
+ initialized := TRUE ;
+ kind := scalar
+ END ;
+ RETURN id
+END InitSymInit ;
+
+
+PROCEDURE KillSymInit (VAR desc: InitDesc) ;
+BEGIN
+ WITH desc^ DO
+ CASE kind OF
+
+ record: KillFieldDesc (rec.fieldDesc)
+
+ ELSE
+ END
+ END ;
+ DISPOSE (desc) ;
+ desc := NIL
+END KillSymInit ;
+
+
+PROCEDURE ConfigSymInit (desc: InitDesc; sym: CARDINAL) ;
+BEGIN
+ IF IsVar (sym) OR IsRecordField (sym)
+ THEN
+ desc^.sym := sym ;
+ desc^.type := GetSType (sym) ;
+ desc^.initialized := FALSE ;
+ IF IsRecord (desc^.type)
+ THEN
+ desc^.kind := record ;
+ desc^.rec.fieldDesc := Indexing.InitIndex (1) ;
+ PopulateFields (desc, desc^.type)
+ ELSE
+ desc^.kind := scalar ;
+ IF IsArray (desc^.type)
+ THEN
+ desc^.initialized := TRUE (* For now we don't attempt to handle array types. *)
+ END
+ END
+ END
+END ConfigSymInit ;
+
+
+(*
+ KillFieldDesc -
+*)
+
+PROCEDURE KillFieldDesc (VAR fielddesc: Indexing.Index) ;
+VAR
+ i, h: CARDINAL ;
+ id : InitDesc ;
+BEGIN
+ i := 1 ;
+ h := Indexing.HighIndice (fielddesc) ;
+ WHILE i <= h DO
+ id := Indexing.GetIndice (fielddesc, i) ;
+ KillSymInit (id) ;
+ INC (i)
+ END ;
+ fielddesc := Indexing.KillIndex (fielddesc)
+END KillFieldDesc ;
+
+
+(*
+ PopulateFields -
+*)
+
+PROCEDURE PopulateFields (desc: InitDesc; recsym: CARDINAL) ;
+VAR
+ field,
+ i : CARDINAL ;
+ fdesc: InitDesc ;
+BEGIN
+ Assert (IsRecord (recsym)) ;
+ i := 1 ;
+ REPEAT
+ field := GetNth (recsym, i) ;
+ IF field # NulSym
+ THEN
+ fdesc := InitSymInit () ;
+ ConfigSymInit (fdesc, field) ;
+ Indexing.IncludeIndiceIntoIndex (desc^.rec.fieldDesc, fdesc) ;
+ INC (i)
+ END
+ UNTIL field = NulSym
+END PopulateFields ;
+
+
+PROCEDURE SetInitialized (desc: InitDesc) ;
+BEGIN
+ desc^.initialized := TRUE
+END SetInitialized ;
+
+
+PROCEDURE GetInitialized (desc: InitDesc) : BOOLEAN ;
+BEGIN
+ IF NOT desc^.initialized
+ THEN
+ IF IsRecord (desc^.type)
+ THEN
+ TrySetInitialized (desc)
+ END
+ END ;
+ IF Debugging
+ THEN
+ PrintSymInit (desc)
+ END ;
+ RETURN desc^.initialized
+END GetInitialized ;
+
+
+PROCEDURE GetFieldDesc (desc: InitDesc; field: CARDINAL) : InitDesc ;
+VAR
+ fsym,
+ i : CARDINAL ;
+BEGIN
+ IF IsRecord (desc^.type)
+ THEN
+ i := 1 ;
+ REPEAT
+ fsym := GetNth (desc^.type, i) ;
+ IF field = fsym
+ THEN
+ RETURN Indexing.GetIndice (desc^.rec.fieldDesc, i)
+ END ;
+ INC (i)
+ UNTIL fsym = NulSym
+ END ;
+ RETURN NIL
+END GetFieldDesc ;
+
+
+PROCEDURE SetFieldInitialized (desc: InitDesc; fieldlist: List) : BOOLEAN ;
+BEGIN
+ RETURN SetFieldInitializedNo (desc, fieldlist, 1)
+END SetFieldInitialized ;
+
+
+(*
+ TrySetInitialized -
+*)
+
+PROCEDURE TrySetInitialized (desc: InitDesc) ;
+VAR
+ i, h : CARDINAL ;
+ fdesc: InitDesc ;
+BEGIN
+ h := Indexing.HighIndice (desc^.rec.fieldDesc) ;
+ i := 1 ;
+ WHILE i <= h DO
+ fdesc := Indexing.GetIndice (desc^.rec.fieldDesc, i) ;
+ IF NOT fdesc^.initialized
+ THEN
+ RETURN
+ END ;
+ INC (i)
+ END ;
+ desc^.initialized := TRUE
+END TrySetInitialized ;
+
+
+(*
+ SetFieldInitializedNo -
+*)
+
+PROCEDURE SetFieldInitializedNo (desc: InitDesc;
+ fieldlist: List; level: CARDINAL) : BOOLEAN ;
+VAR
+ init : BOOLEAN ;
+ nsym : CARDINAL ;
+ fdesc: InitDesc ;
+BEGIN
+ IF level > NoOfItemsInList (fieldlist)
+ THEN
+ RETURN FALSE
+ ELSE
+ nsym := GetItemFromList (fieldlist, level) ;
+ fdesc := GetFieldDesc (desc, nsym) ;
+ IF fdesc = NIL
+ THEN
+ RETURN FALSE
+ ELSIF level = NoOfItemsInList (fieldlist)
+ THEN
+ SetInitialized (fdesc) ;
+ TrySetInitialized (desc) ;
+ RETURN desc^.initialized
+ ELSE
+ init := SetFieldInitializedNo (fdesc, fieldlist, level + 1) ;
+ TrySetInitialized (desc) ;
+ RETURN desc^.initialized
+ END
+ END
+END SetFieldInitializedNo ;
+
+
+PROCEDURE GetFieldInitialized (desc: InitDesc; fieldlist: List) : BOOLEAN ;
+BEGIN
+ RETURN GetFieldInitializedNo (desc, fieldlist, 1)
+END GetFieldInitialized ;
+
+
+PROCEDURE GetFieldInitializedNo (desc: InitDesc;
+ fieldlist: List; level: CARDINAL) : BOOLEAN ;
+VAR
+ nsym : CARDINAL ;
+ fdesc: InitDesc ;
+BEGIN
+ IF desc^.initialized
+ THEN
+ RETURN TRUE
+ ELSIF level > NoOfItemsInList (fieldlist)
+ THEN
+ RETURN FALSE
+ ELSE
+ nsym := GetItemFromList (fieldlist, level) ;
+ fdesc := GetFieldDesc (desc, nsym) ;
+ IF fdesc = NIL
+ THEN
+ (* The pointer variable maybe uninitialized and hence we cannot
+ find the record variable. *)
+ RETURN FALSE
+ ELSIF fdesc^.initialized
+ THEN
+ RETURN TRUE
+ ELSE
+ RETURN GetFieldInitializedNo (fdesc, fieldlist, level + 1)
+ END
+ END
+END GetFieldInitializedNo ;
+
+
+(*
+ IsGlobalVar -
+*)
+
+PROCEDURE IsGlobalVar (sym: CARDINAL) : BOOLEAN ;
+BEGIN
+ RETURN IsVar (sym) AND (NOT IsProcedure (GetVarScope (sym)))
+END IsGlobalVar ;
+
+
+(*
+ IsLocalVar -
+*)
+
+PROCEDURE IsLocalVar (procsym, varsym: CARDINAL) : BOOLEAN ;
+BEGIN
+ RETURN IsVar (varsym) AND (GetVarScope (varsym) = procsym)
+END IsLocalVar ;
+
+
+(*
+ RecordFieldContainsVarient -
+*)
+
+PROCEDURE RecordFieldContainsVarient (sym: CARDINAL) : BOOLEAN ;
+BEGIN
+ Assert (IsRecordField (sym)) ;
+ IF ContainsVariant (GetSType (sym))
+ THEN
+ RETURN TRUE
+ END ;
+ RETURN GetVarient (sym) # NulSym
+END RecordFieldContainsVarient ;
+
+
+(*
+ ContainsVariant - returns TRUE if type sym contains a variant record.
+*)
+
+PROCEDURE ContainsVariant (sym: CARDINAL) : BOOLEAN ;
+VAR
+ i,
+ fieldsym,
+ fieldtype: CARDINAL ;
+BEGIN
+ IF IsRecord (sym)
+ THEN
+ i := 1 ;
+ REPEAT
+ fieldsym := GetNth (sym, i) ;
+ IF fieldsym # NulSym
+ THEN
+ IF IsRecordField (fieldsym)
+ THEN
+ IF RecordFieldContainsVarient (fieldsym)
+ THEN
+ RETURN TRUE
+ END
+ ELSIF IsVarient (fieldsym)
+ THEN
+ RETURN TRUE
+ END ;
+ INC (i)
+ END
+ UNTIL fieldsym = NulSym
+ END ;
+ RETURN FALSE
+END ContainsVariant ;
+
+
+(*
+ CheckDeferredRecordAccess -
+*)
+
+PROCEDURE CheckDeferredRecordAccess (procsym: CARDINAL; tok: CARDINAL;
+ sym: CARDINAL; canDereference: BOOLEAN) ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ IF Debugging
+ THEN
+ Trace ("CheckDeferredRecordAccess %d\n", sym) ;
+ PrintSym (sym) ;
+ IF canDereference
+ THEN
+ printf1 ("checkReadInit (%d, true)\n", sym)
+ ELSE
+ printf1 ("checkReadInit (%d, false)\n", sym)
+ END
+ END ;
+ IF IsExempt (sym)
+ THEN
+ Trace ("checkReadInit sym is a parameter or not a local variable (%d)", sym) ;
+ (* We assume parameters have been initialized. *)
+ PutVarInitialized (sym, LeftValue) ;
+ PutVarInitialized (sym, RightValue)
+ (* SetVarInitialized (sym, TRUE) *)
+ ELSIF IsUnbounded (GetSType (sym))
+ THEN
+ SetVarInitialized (sym, TRUE)
+ ELSIF IsComponent (sym)
+ THEN
+ Trace ("checkReadInit IsComponent (%d) is true)", sym) ;
+ IF NOT GetVarComponentInitialized (sym)
+ THEN
+ MetaErrorT1 (tok,
+ 'attempting to access {%1Wad} before it has been initialized',
+ sym)
+ END
+ ELSIF (GetMode (sym) = LeftValue) AND canDereference
+ THEN
+ Trace ("checkReadInit GetMode (%d) = LeftValue and canDereference (LeftValue and RightValue VarCheckReadInit)", sym) ;
+ IF NOT VarCheckReadInit (sym, LeftValue)
+ THEN
+ MetaErrorT1 (tok,
+ 'attempting to access the address of {%1Wad} before it has been initialized',
+ sym)
+ END ;
+ IF NOT VarCheckReadInit (sym, RightValue)
+ THEN
+ MetaErrorT1 (tok,
+ 'attempting to access {%1Wad} before it has been initialized', sym)
+ END
+ ELSE
+ Trace ("checkReadInit call VarCheckReadInit using GetMode (%d)", sym) ;
+ IF NOT VarCheckReadInit (sym, GetMode (sym))
+ THEN
+ MetaErrorT1 (tok,
+ 'attempting to access {%1Wad} before it has been initialized', sym)
+ END
+ END
+ END
+END CheckDeferredRecordAccess ;
+
+
+(*
+ SetVarUninitialized - resets variable init state.
+*)
+
+PROCEDURE SetVarUninitialized (sym: CARDINAL) ;
+BEGIN
+ IF IsVar (sym) AND (NOT IsUnbounded (GetSType (sym))) AND (NOT IsVarAParam (sym))
+ THEN
+ VarInitState (sym)
+ END
+END SetVarUninitialized ;
+
+
+(*
+ ComponentFindVar -
+*)
+
+PROCEDURE ComponentFindVar (sym: CARDINAL) : CARDINAL ;
+VAR
+ nsym,
+ i : CARDINAL ;
+BEGIN
+ i := 1 ;
+ REPEAT
+ nsym := getAlias (GetNth (sym, i)) ;
+ IF (nsym # NulSym) AND IsVar (nsym)
+ THEN
+ IF (nsym # sym) AND IsComponent (nsym)
+ THEN
+ RETURN ComponentFindVar (nsym)
+ ELSE
+ RETURN nsym
+ END
+ END ;
+ INC (i)
+ UNTIL nsym = NulSym ;
+ RETURN NulSym
+END ComponentFindVar ;
+
+
+(*
+ ComponentCreateFieldList - builds a list of fields accessed by the component var.
+ Each item in the list will be a field of incremental levels
+ though a nested record. It is not a list of fields
+ at the same level.
+
+ foo = RECORD
+ v: RECORD
+ x, y: CARDINAL ;
+ END ;
+ w: CARDINAL ;
+ END ;
+
+ { v, x } for example and not { v, w }
+*)
+
+PROCEDURE ComponentCreateFieldList (sym: CARDINAL) : List ;
+VAR
+ lst: List ;
+BEGIN
+ InitList (lst) ;
+ IF IsVar (sym) AND IsComponent (sym)
+ THEN
+ ComponentBuildFieldList (lst, sym)
+ END ;
+ RETURN lst
+END ComponentCreateFieldList ;
+
+
+PROCEDURE ComponentBuildFieldList (lst: List; sym: CARDINAL) ;
+VAR
+ i, nsym: CARDINAL ;
+BEGIN
+ i := 1 ;
+ REPEAT
+ nsym := GetNth (sym, i) ;
+ IF nsym # NulSym
+ THEN
+ IF IsComponent (nsym)
+ THEN
+ ComponentBuildFieldList (lst, nsym)
+ ELSIF IsRecordField (nsym)
+ THEN
+ IncludeItemIntoList (lst, nsym)
+ END ;
+ INC (i)
+ END
+ UNTIL nsym = NulSym
+END ComponentBuildFieldList ;
+
+
+(*
+ SetVarComponentInitialized -
+*)
+
+PROCEDURE SetVarComponentInitialized (sym: CARDINAL) ;
+VAR
+ i, n,
+ fsym,
+ vsym: CARDINAL ;
+ lst : List ;
+BEGIN
+ vsym := ComponentFindVar (sym) ;
+ IF vsym # NulSym
+ THEN
+ IF Debugging
+ THEN
+ printf0 ("*************** vsym is: ") ;
+ PrintSym (vsym)
+ END ;
+ (* Build list accessing the field. *)
+ lst := ComponentCreateFieldList (sym) ;
+ IF Debugging
+ THEN
+ printf2 ("sym = %d, vsym = %d, fields:", sym, vsym)
+ END ;
+ (* Now mark this field in the record variable as initialized. *)
+ IF PutVarFieldInitialized (vsym, RightValue, lst)
+ THEN
+ IF Debugging
+ THEN
+ i := 1 ;
+ n := NoOfItemsInList (lst) ;
+ WHILE i <= n DO
+ fsym := GetItemFromList (lst, i) ;
+ printf1 (" %d", fsym) ;
+ INC (i)
+ END ;
+ printf0 (" is initialized\n")
+ END
+ ELSIF Debugging
+ THEN
+ printf0 (" vsym is not a var\n")
+ END ;
+ KillList (lst)
+ END
+END SetVarComponentInitialized ;
+
+
+(*
+ GetVarComponentInitialized -
+*)
+
+PROCEDURE GetVarComponentInitialized (sym: CARDINAL) : BOOLEAN ;
+VAR
+ init: BOOLEAN ;
+ vsym: CARDINAL ;
+ lst : List ;
+BEGIN
+ init := FALSE ;
+ vsym := ComponentFindVar (sym) ;
+ IF vsym # NulSym
+ THEN
+ IF IsExempt (vsym)
+ THEN
+ init := TRUE
+ ELSE
+ (* Create list representing how the field is accessed. *)
+ lst := ComponentCreateFieldList (sym) ;
+ (* Now obtain the mark indicating whether this field was initialized. *)
+ init := GetVarFieldInitialized (vsym, RightValue, lst) ;
+ KillList (lst)
+ END
+ END ;
+ RETURN init
+END GetVarComponentInitialized ;
+
+
+(*
+ Trace -
+*)
+
+PROCEDURE Trace (message: ARRAY OF CHAR; sym: CARDINAL) ;
+BEGIN
+ IF Debugging
+ THEN
+ printf1 (message, sym) ;
+ printf0 ("\n")
+ END
+END Trace ;
+
+
+(*
+ SetVarInitialized - if the variable has a left mode and can be dereferenced
+ then set the left and right initialization state.
+*)
+
+PROCEDURE SetVarInitialized (sym: CARDINAL; canDereference: BOOLEAN) ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ IF IsComponent (sym)
+ THEN
+ Trace ("SetVarInitialized sym %d is a component and calling SetVarComponentInitialized", sym);
+ SetVarComponentInitialized (sym)
+ ELSIF (GetMode (sym) = LeftValue) AND canDereference
+ THEN
+ Trace ("SetVarInitialized sym %d is LeftValue and canDeference and calling PutVarInitialized LeftValue and RightValue", sym);
+ PutVarInitialized (sym, LeftValue) ;
+ PutVarInitialized (sym, RightValue)
+ ELSE
+ Trace ("SetVarInitialized sym %d calling PutVarInitialized with its mode", sym);
+ PutVarInitialized (sym, GetMode (sym))
+ END ;
+ IF Debugging
+ THEN
+ PrintSym (sym)
+ END
+ END
+END SetVarInitialized ;
+
+
+(*
+ doGetVarInitialized -
+*)
+
+PROCEDURE doGetVarInitialized (sym: CARDINAL) : BOOLEAN ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ IF IsUnbounded (GetSType (sym))
+ THEN
+ RETURN TRUE
+ ELSIF IsComponent (sym)
+ THEN
+ RETURN GetVarComponentInitialized (sym)
+ END ;
+ RETURN VarCheckReadInit (sym, GetMode (sym))
+ END ;
+ RETURN IsConst (sym) AND IsConstString (sym)
+END doGetVarInitialized ;
+
+
+(*
+ GetVarInitialized -
+*)
+
+PROCEDURE GetVarInitialized (sym: CARDINAL) : BOOLEAN ;
+VAR
+ init: BOOLEAN ;
+BEGIN
+ init := doGetVarInitialized (sym) ;
+ IF Debugging
+ THEN
+ IF init
+ THEN
+ Trace ("GetVarInitialized (sym = %d) returning TRUE", sym)
+ ELSE
+ Trace ("GetVarInitialized (sym = %d) returning FALSE", sym)
+ END
+ END ;
+ RETURN init
+END GetVarInitialized ;
+
+
+(*
+ IsExempt - returns TRUE if sym is a global variable or a parameter or
+ a variable with a variant record type.
+*)
+
+PROCEDURE IsExempt (sym: CARDINAL) : BOOLEAN ;
+BEGIN
+ RETURN (sym # NulSym) AND IsVar (sym) AND
+ (IsGlobalVar (sym) OR IsVarAParam (sym) OR
+ ContainsVariant (GetSType (sym)) OR
+ IsArray (GetSType (sym)) OR IsSet (GetSType (sym)) OR
+ IsUnbounded (GetSType (sym)))
+END IsExempt ;
+
+
+(*
+ CheckBinary -
+*)
+
+PROCEDURE CheckBinary (procSym,
+ op1tok, op1,
+ op2tok, op2,
+ op3tok, op3: CARDINAL) ;
+BEGIN
+ CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE) ;
+ CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) ;
+ SetVarInitialized (op1, FALSE)
+END CheckBinary ;
+
+
+(*
+ CheckUnary -
+*)
+
+PROCEDURE CheckUnary (procSym,
+ lhstok, lhs,
+ rhstok, rhs: CARDINAL) ;
+BEGIN
+ CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE) ;
+ SetVarInitialized (lhs, FALSE)
+END CheckUnary ;
+
+
+(*
+ CheckXIndr -
+*)
+
+PROCEDURE CheckXIndr (procSym, lhstok, lhs, type, rhstok, rhs: CARDINAL) ;
+VAR
+ lst : List ;
+ vsym: CARDINAL ;
+BEGIN
+ CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE) ;
+ CheckDeferredRecordAccess (procSym, lhstok, lhs, FALSE) ;
+ (* Now see if we know what lhs is pointing to and set fields if necessary. *)
+ vsym := getAlias (lhs) ;
+ IF (vsym # lhs) AND (GetSType (vsym) = type)
+ THEN
+ IF IsRecord (type)
+ THEN
+ (* Set all fields of vsym as initialized. *)
+ SetVarInitialized (vsym, FALSE)
+ ELSE
+ (* Set only the field assigned in vsym as initialized. *)
+ lst := ComponentCreateFieldList (rhs) ;
+ IF PutVarFieldInitialized (vsym, RightValue, lst)
+ THEN
+ END ;
+ KillList (lst)
+ END
+ END
+END CheckXIndr ;
+
+
+(*
+ CheckIndrX -
+*)
+
+PROCEDURE CheckIndrX (procSym, lhstok, lhs, type, rhstok, rhs: CARDINAL) ;
+BEGIN
+ CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE) ;
+ CheckDeferredRecordAccess (procSym, rhstok, rhs, TRUE) ;
+ SetVarInitialized (lhs, FALSE)
+END CheckIndrX ;
+
+
+(*
+ CheckRecordField -
+*)
+
+PROCEDURE CheckRecordField (procSym, op1tok, op1, op2tok, op2: CARDINAL) ;
+BEGIN
+ PutVarInitialized (op1, LeftValue)
+END CheckRecordField ;
+
+
+(*
+ CheckBecomes -
+*)
+
+PROCEDURE CheckBecomes (procSym, destok, des, exprtok, expr: CARDINAL) ;
+VAR
+ lst : List ;
+ vsym: CARDINAL ;
+BEGIN
+ CheckDeferredRecordAccess (procSym, exprtok, expr, FALSE) ;
+ SetupAlias (des, expr) ;
+ SetVarInitialized (des, FALSE) ;
+ (* Now see if we know what lhs is pointing to and set fields if necessary. *)
+ IF IsComponent (des)
+ THEN
+ vsym := ComponentFindVar (des) ;
+ (* Set only the field assigned in vsym as initialized. *)
+ lst := ComponentCreateFieldList (des) ;
+ IF PutVarFieldInitialized (vsym, RightValue, lst)
+ THEN
+ END ;
+ KillList (lst)
+ END
+END CheckBecomes ;
+
+
+(*
+ CheckComparison -
+*)
+
+PROCEDURE CheckComparison (procSym, op1tok, op1, op2tok, op2: CARDINAL) ;
+BEGIN
+ CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE) ;
+ CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE)
+END CheckComparison ;
+
+
+(*
+ CheckAddr -
+*)
+
+PROCEDURE CheckAddr (procSym, op1tok, op1, op3tok, op3: CARDINAL) ;
+BEGIN
+ SetVarInitialized (op1, GetVarInitialized (op3)) ;
+ SetupAlias (op1, op3)
+END CheckAddr ;
+
+
+(*
+ DefaultTokPos -
+*)
+
+PROCEDURE DefaultTokPos (preferredPos, defaultPos: CARDINAL) : CARDINAL ;
+BEGIN
+ IF preferredPos = UnknownTokenNo
+ THEN
+ RETURN defaultPos
+ END ;
+ RETURN preferredPos
+END DefaultTokPos ;
+
+
+(*
+ stop -
+*)
+
+PROCEDURE stop ;
+END stop ;
+
+
+(*
+ CheckReadBeforeInitQuad -
+*)
+
+PROCEDURE CheckReadBeforeInitQuad (procSym: CARDINAL; quad: CARDINAL) : BOOLEAN ;
+VAR
+ op : QuadOperator ;
+ op1, op2, op3 : CARDINAL ;
+ op1tok, op2tok, op3tok, qtok: CARDINAL ;
+ overflowChecking : BOOLEAN ;
+BEGIN
+ IF quad = 3140
+ THEN
+ stop
+ END ;
+ IF Debugging
+ THEN
+ printf1 ("CheckReadBeforeInitQuad (quad %d)\n", quad) ;
+ DumpAliases ;
+ ForeachLocalSymDo (procSym, PrintSym) ;
+ printf0 ("***********************************\n")
+ END ;
+ GetQuadOtok (quad, qtok, op, op1, op2, op3, overflowChecking,
+ op1tok, op2tok, op3tok) ;
+ op1tok := DefaultTokPos (op1tok, qtok) ;
+ op2tok := DefaultTokPos (op2tok, qtok) ;
+ op3tok := DefaultTokPos (op3tok, qtok) ;
+ CASE op OF
+
+ (* Jumps, calls and branches. *)
+ IfInOp,
+ IfNotInOp,
+ IfEquOp,
+ IfNotEquOp,
+ IfLessOp,
+ IfLessEquOp,
+ IfGreOp,
+ IfGreEquOp : CheckComparison (procSym, op1tok, op1, op2tok, op2) |
+ TryOp,
+ ReturnOp,
+ CallOp,
+ KillLocalVarOp,
+ RetryOp,
+ GotoOp : RETURN TRUE | (* End of basic block. *)
+
+ (* Variable references. *)
+
+ InclOp,
+ ExclOp : CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE) ;
+ CheckDeferredRecordAccess (procSym, op1tok, op1, TRUE) ;
+ CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) |
+ NegateOp : CheckUnary (procSym, op1tok, op1, op3tok, op3) |
+ BecomesOp : CheckBecomes (procSym, op1tok, op1, op3tok, op3) |
+ UnboundedOp,
+ FunctValueOp,
+ HighOp,
+ SizeOp : SetVarInitialized (op1, FALSE) |
+ AddrOp : CheckAddr (procSym, op1tok, op1, op3tok, op3) |
+ ReturnValueOp : SetVarInitialized (op1, FALSE) |
+ NewLocalVarOp : |
+ ParamOp : CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE) ;
+ CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) ;
+ IF (op1 > 0) AND (op1 <= NoOfParam (op2)) AND
+ IsVarParam (op2, op1)
+ THEN
+ SetVarInitialized (op3, TRUE)
+ END |
+ ArrayOp : CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) ;
+ SetVarInitialized (op1, TRUE) |
+ RecordFieldOp : CheckRecordField (procSym, op1tok, op1, op2tok, op2) |
+ LogicalShiftOp,
+ LogicalRotateOp,
+ LogicalOrOp,
+ LogicalAndOp,
+ LogicalXorOp,
+ CoerceOp,
+ ConvertOp,
+ CastOp,
+ AddOp,
+ ArithAddOp,
+ SubOp,
+ MultOp,
+ DivM2Op,
+ ModM2Op,
+ ModFloorOp,
+ DivCeilOp,
+ ModCeilOp,
+ DivFloorOp,
+ ModTruncOp,
+ DivTruncOp : CheckBinary (procSym,
+ op1tok, op1, op2tok, op2, op3tok, op3) |
+ XIndrOp : CheckXIndr (procSym, op1tok, op1, op2, op3tok, op3) |
+ IndrXOp : CheckIndrX (procSym, op1tok, op1, op2, op3tok, op3) |
+ RangeCheckOp : |
+ SaveExceptionOp : SetVarInitialized (op1, FALSE) |
+ RestoreExceptionOp: CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE)
+
+ ELSE
+ END ;
+ RETURN FALSE
+END CheckReadBeforeInitQuad ;
+
+
+(*
+ FilterCheckReadBeforeInitQuad -
+*)
+
+PROCEDURE FilterCheckReadBeforeInitQuad (procSym: CARDINAL; start: CARDINAL) : BOOLEAN ;
+VAR
+ Op : QuadOperator ;
+ Op1, Op2, Op3: CARDINAL ;
+BEGIN
+ GetQuad (start, Op, Op1, Op2, Op3) ;
+ IF (Op # RangeCheckOp) AND (Op # StatementNoteOp)
+ THEN
+ RETURN CheckReadBeforeInitQuad (procSym, start)
+ END ;
+ RETURN FALSE
+END FilterCheckReadBeforeInitQuad ;
+
+
+(*
+ CheckReadBeforeInitFirstBasicBlock -
+*)
+
+PROCEDURE CheckReadBeforeInitFirstBasicBlock (procSym: CARDINAL;
+ start, end: CARDINAL) ;
+BEGIN
+ ForeachLocalSymDo (procSym, SetVarUninitialized) ;
+ LOOP
+ IF FilterCheckReadBeforeInitQuad (procSym, start) OR (start = end)
+ THEN
+ RETURN
+ END ;
+ start := GetNextQuad (start)
+ END
+END CheckReadBeforeInitFirstBasicBlock ;
+
+
+(*
+ VariableAnalysis - checks to see whether a variable is:
+
+ read before it has been initialized
+*)
+
+PROCEDURE VariableAnalysis (Start, End: CARDINAL) ;
+VAR
+ Op : QuadOperator ;
+ Op1, Op2, Op3: CARDINAL ;
+BEGIN
+ IF UninitVariableChecking
+ THEN
+ GetQuad (Start, Op, Op1, Op2, Op3) ;
+ CASE Op OF
+
+ NewLocalVarOp: initBlock ;
+ CheckReadBeforeInitFirstBasicBlock (Op3, Start, End) ;
+ killBlock
+
+ ELSE
+ END
+ END
+END VariableAnalysis ;
+
+
+(*
+ DumpAlias -
+*)
+
+PROCEDURE DumpAlias (aliasIndex: CARDINAL) ;
+VAR
+ sa: symAlias ;
+BEGIN
+ sa := Indexing.GetIndice (aliasArray, aliasIndex) ;
+ printf2 ("keySym = %d: alias = %d\n", sa^.keySym, sa^.alias) ;
+END DumpAlias ;
+
+
+(*
+ DumpAliases -
+*)
+
+PROCEDURE DumpAliases ;
+VAR
+ i, n: CARDINAL ;
+BEGIN
+ IF Debugging
+ THEN
+ i := 1 ;
+ n := Indexing.HighIndice (aliasArray) ;
+ WHILE i <= n DO
+ DumpAlias (i) ;
+ INC (i)
+ END
+ END
+END DumpAliases ;
+
+
+(*
+ newAlias -
+*)
+
+PROCEDURE newAlias () : symAlias ;
+VAR
+ sa: symAlias ;
+BEGIN
+ IF freeList = NIL
+ THEN
+ NEW (sa)
+ ELSE
+ sa := freeList ;
+ freeList := freeList^.next
+ END ;
+ RETURN sa
+END newAlias ;
+
+
+(*
+ initAlias -
+*)
+
+PROCEDURE initAlias (sym: CARDINAL) : symAlias ;
+VAR
+ sa: symAlias ;
+BEGIN
+ sa := newAlias () ;
+ WITH sa^ DO
+ keySym := sym ;
+ alias := NulSym ;
+ next := NIL
+ END ;
+ RETURN sa
+END initAlias ;
+
+
+(*
+ killAlias -
+*)
+
+PROCEDURE killAlias (sa: symAlias) ;
+BEGIN
+ sa^.next := freeList ;
+ freeList := sa
+END killAlias ;
+
+
+(*
+ initBlock -
+*)
+
+PROCEDURE initBlock ;
+BEGIN
+ aliasArray := Indexing.InitIndex (1) ;
+END initBlock ;
+
+
+(*
+ killBlock -
+*)
+
+PROCEDURE killBlock ;
+VAR
+ i, n: CARDINAL ;
+BEGIN
+ i := 1 ;
+ n := Indexing.HighIndice (aliasArray) ;
+ WHILE i <= n DO
+ killAlias (Indexing.GetIndice (aliasArray, i)) ;
+ INC (i)
+ END ;
+ aliasArray := Indexing.KillIndex (aliasArray)
+END killBlock ;
+
+
+(*
+ addAlias -
+*)
+
+PROCEDURE addAlias (sym: CARDINAL; aliased: CARDINAL) ;
+VAR
+ i, n: CARDINAL ;
+ sa : symAlias ;
+BEGIN
+ i := 1 ;
+ n := Indexing.HighIndice (aliasArray) ;
+ WHILE i <= n DO
+ sa := Indexing.GetIndice (aliasArray, i) ;
+ IF sa^.keySym = sym
+ THEN
+ sa^.alias := aliased ;
+ RETURN
+ END ;
+ INC (i)
+ END ;
+ sa := initAlias (sym) ;
+ Indexing.IncludeIndiceIntoIndex (aliasArray, sa) ;
+ sa^.alias := aliased
+END addAlias ;
+
+
+(*
+ lookupAlias -
+*)
+
+PROCEDURE lookupAlias (sym: CARDINAL) : symAlias ;
+VAR
+ i, n: CARDINAL ;
+ sa : symAlias ;
+BEGIN
+ i := 1 ;
+ n := Indexing.HighIndice (aliasArray) ;
+ WHILE i <= n DO
+ sa := Indexing.GetIndice (aliasArray, i) ;
+ IF sa^.keySym = sym
+ THEN
+ RETURN sa
+ END ;
+ INC (i)
+ END ;
+ RETURN NIL
+END lookupAlias ;
+
+
+(*
+ doGetAlias -
+*)
+
+PROCEDURE doGetAlias (sym: CARDINAL) : CARDINAL ;
+VAR
+ sa: symAlias ;
+BEGIN
+ sa := lookupAlias (sym) ;
+ IF (sa # NIL) AND (sa^.alias # NulSym)
+ THEN
+ RETURN sa^.alias
+ END ;
+ RETURN NulSym
+END doGetAlias ;
+
+
+(*
+ getAlias - attempts to looks up an alias which is not a temporary variable.
+*)
+
+PROCEDURE getAlias (sym: CARDINAL) : CARDINAL ;
+VAR
+ type,
+ nsym: CARDINAL ;
+BEGIN
+ nsym := sym ;
+ REPEAT
+ sym := nsym ;
+ type := GetSType (sym) ;
+ IF (IsTemporary (sym) AND (GetMode (sym) = LeftValue)) OR
+ ((type # NulSym) AND IsReallyPointer (type))
+ THEN
+ nsym := doGetAlias (sym)
+ ELSE
+ RETURN sym
+ END
+ UNTIL nsym = NulSym ;
+ RETURN sym
+END getAlias ;
+
+
+(*
+ SetupAlias -
+*)
+
+PROCEDURE SetupAlias (des, exp: CARDINAL) ;
+BEGIN
+ IF IsVar (exp) AND
+ ((GetMode (des) = LeftValue) OR IsReallyPointer (GetSType (des)))
+ THEN
+ addAlias (des, exp) ;
+ DumpAliases
+ END
+END SetupAlias ;
+
+
+(*
+ init -
+*)
+
+PROCEDURE init ;
+BEGIN
+ freeList := NIL
+END init ;
+
+
+BEGIN
+ init
+END M2SymInit.
diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def
index 5249952..c861cff 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.def
+++ b/gcc/m2/gm2-compiler/SymbolTable.def
@@ -355,7 +355,10 @@ EXPORT QUALIFIED NulSym,
PopOffset,
PopSumOfParamSize,
DisplayTrees,
- DebugLineNumbers ;
+ DebugLineNumbers,
+ VarCheckReadInit, VarInitState, PutVarInitialized,
+ PutVarFieldInitialized, GetVarFieldInitialized,
+ PrintInitialized ;
(*
@@ -3558,4 +3561,51 @@ PROCEDURE IsModuleBuiltin (sym: CARDINAL) : BOOLEAN ;
PROCEDURE PutModuleBuiltin (sym: CARDINAL; value: BOOLEAN) ;
+(*
+ VarCheckReadInit - returns TRUE if sym has been initialized.
+*)
+
+PROCEDURE VarCheckReadInit (sym: CARDINAL; mode: ModeOfAddr) : BOOLEAN ;
+
+
+(*
+ VarInitState - initializes the init state for variable sym.
+*)
+
+PROCEDURE VarInitState (sym: CARDINAL) ;
+
+
+(*
+ PutVarInitialized - set sym as initialized.
+*)
+
+PROCEDURE PutVarInitialized (sym: CARDINAL; mode: ModeOfAddr) ;
+
+
+(*
+ PutVarFieldInitialized - records that field has been initialized with
+ variable sym. TRUE is returned if the field
+ is detected and changed to initialized.
+*)
+
+PROCEDURE PutVarFieldInitialized (sym: CARDINAL; mode: ModeOfAddr;
+ fieldlist: List) : BOOLEAN ;
+
+
+(*
+ GetVarFieldInitialized - return TRUE if fieldlist has been initialized
+ within variable sym.
+*)
+
+PROCEDURE GetVarFieldInitialized (sym: CARDINAL; mode: ModeOfAddr;
+ fieldlist: List) : BOOLEAN ;
+
+
+(*
+ PrintInitialized - display variable sym initialization state.
+*)
+
+PROCEDURE PrintInitialized (sym: CARDINAL) ;
+
+
END SymbolTable.
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod
index ad3788d..c10e20c 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -87,6 +87,10 @@ FROM M2Comp IMPORT CompilingDefinitionModule,
FROM FormatStrings IMPORT HandleEscape ;
FROM M2Scaffold IMPORT DeclareArgEnvParams ;
+FROM M2SymInit IMPORT InitDesc, InitSymInit, GetInitialized, ConfigSymInit,
+ SetInitialized, SetFieldInitialized, GetFieldInitialized,
+ PrintSymInit ;
+
IMPORT Indexing ;
@@ -118,6 +122,8 @@ TYPE
LRLists = ARRAY [RightValue..LeftValue] OF List ;
+ LRInitDesc = ARRAY [RightValue..LeftValue] OF InitDesc ;
+
TypeOfSymbol = (RecordSym, VarientSym, DummySym,
VarSym, EnumerationSym, SubrangeSym, ArraySym,
ConstStringSym, ConstVarSym, ConstLitSym,
@@ -519,6 +525,7 @@ TYPE
IsWritten : BOOLEAN ; (* Is variable written to? *)
IsSSA : BOOLEAN ; (* Is variable a SSA? *)
IsConst : BOOLEAN ; (* Is variable read/only? *)
+ InitState : LRInitDesc ; (* Initialization state. *)
At : Where ; (* Where was sym declared/used *)
ReadUsageList, (* list of var read quads *)
WriteUsageList: LRLists ; (* list of var write quads *)
@@ -4258,7 +4265,9 @@ BEGIN
InitList(ReadUsageList[RightValue]) ;
InitList(WriteUsageList[RightValue]) ;
InitList(ReadUsageList[LeftValue]) ;
- InitList(WriteUsageList[LeftValue])
+ InitList(WriteUsageList[LeftValue]) ;
+ InitState[LeftValue] := InitSymInit () ;
+ InitState[RightValue] := InitSymInit ()
END
END ;
(* Add Var to Procedure or Module variable list. *)
@@ -6696,7 +6705,9 @@ BEGIN
WITH pSym^ DO
CASE SymbolType OF
- VarSym : Var.Type := VarType |
+ VarSym : Var.Type := VarType ;
+ ConfigSymInit (Var.InitState[LeftValue], Sym) ;
+ ConfigSymInit (Var.InitState[RightValue], Sym) |
ConstVarSym: ConstVar.Type := VarType
ELSE
@@ -7933,7 +7944,7 @@ BEGIN
IsHiddenTypeDeclared(CurrentModule) AND
(TypeName#NulName)
THEN
- (* Check to see whether we are declaring a HiddenType. *)
+ (* Check to see whether we are declaring a HiddenType. *)
pSym := GetPsym(CurrentModule) ;
WITH pSym^ DO
CASE SymbolType OF
@@ -14446,6 +14457,162 @@ END GetDefaultRecordFieldAlignment ;
(*
+ VarCheckReadInit - returns TRUE if sym has been initialized.
+*)
+
+PROCEDURE VarCheckReadInit (sym: CARDINAL; mode: ModeOfAddr) : BOOLEAN ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ pSym := GetPsym (sym) ;
+ WITH pSym^ DO
+ CASE SymbolType OF
+
+ VarSym: RETURN GetInitialized (Var.InitState[mode])
+
+ ELSE
+ END
+ END
+ END ;
+ RETURN FALSE
+END VarCheckReadInit ;
+
+
+(*
+ VarInitState - initializes the init state for variable sym.
+*)
+
+PROCEDURE VarInitState (sym: CARDINAL) ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ pSym := GetPsym (sym) ;
+ WITH pSym^ DO
+ CASE SymbolType OF
+
+ VarSym: ConfigSymInit (Var.InitState[LeftValue], sym) ;
+ ConfigSymInit (Var.InitState[RightValue], sym)
+
+ ELSE
+ END
+ END
+ END
+END VarInitState ;
+
+
+(*
+ PutVarInitialized - set sym as initialized.
+*)
+
+PROCEDURE PutVarInitialized (sym: CARDINAL; mode: ModeOfAddr) ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ pSym := GetPsym (sym) ;
+ WITH pSym^ DO
+ CASE SymbolType OF
+
+ VarSym: WITH Var DO
+ SetInitialized (InitState[mode])
+ END
+
+ ELSE
+ END
+ END
+ END
+END PutVarInitialized ;
+
+
+(*
+ PutVarFieldInitialized - records that field has been initialized with
+ variable sym. TRUE is returned if the field
+ is detected and changed to initialized.
+*)
+
+PROCEDURE PutVarFieldInitialized (sym: CARDINAL; mode: ModeOfAddr;
+ fieldlist: List) : BOOLEAN ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ pSym := GetPsym (sym) ;
+ WITH pSym^ DO
+ CASE SymbolType OF
+
+ VarSym: WITH Var DO
+ RETURN SetFieldInitialized (InitState[mode], fieldlist)
+ END
+
+ ELSE
+ END
+ END
+ END ;
+ RETURN FALSE
+END PutVarFieldInitialized ;
+
+
+(*
+ GetVarFieldInitialized - return TRUE if fieldlist has been initialized
+ within variable sym.
+*)
+
+PROCEDURE GetVarFieldInitialized (sym: CARDINAL; mode: ModeOfAddr;
+ fieldlist: List) : BOOLEAN ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ pSym := GetPsym (sym) ;
+ WITH pSym^ DO
+ CASE SymbolType OF
+
+ VarSym: WITH Var DO
+ RETURN GetFieldInitialized (InitState[mode], fieldlist)
+ END
+
+ ELSE
+ END
+ END
+ END ;
+ RETURN FALSE
+END GetVarFieldInitialized ;
+
+
+(*
+ PrintInitialized - display variable sym initialization state.
+*)
+
+PROCEDURE PrintInitialized (sym: CARDINAL) ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ IF IsVar (sym)
+ THEN
+ pSym := GetPsym (sym) ;
+ WITH pSym^ DO
+ CASE SymbolType OF
+
+ VarSym: printf0 ("LeftMode init: ") ;
+ PrintSymInit (Var.InitState[LeftValue]) ;
+ printf0 ("RightMode init: ") ;
+ PrintSymInit (Var.InitState[RightValue])
+
+ ELSE
+ END
+ END
+ END
+END PrintInitialized ;
+
+
+(*
DumpSymbols - display all symbol numbers and their type.
*)
diff --git a/gcc/m2/gm2-gcc/m2options.h b/gcc/m2/gm2-gcc/m2options.h
index 767b617..e203fce4 100644
--- a/gcc/m2/gm2-gcc/m2options.h
+++ b/gcc/m2/gm2-gcc/m2options.h
@@ -136,6 +136,8 @@ EXTERN void M2Options_SetM2Prefix (const char *arg);
EXTERN char *M2Options_GetM2Prefix (void);
EXTERN void M2Options_SetM2PathName (const char *arg);
EXTERN char *M2Options_GetM2PathName (void);
+EXTERN void M2Options_SetUninitVariableChecking (bool value);
+
#undef EXTERN
#endif /* m2options_h. */
diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc
index fe52393..ae999a3 100644
--- a/gcc/m2/gm2-lang.cc
+++ b/gcc/m2/gm2-lang.cc
@@ -469,6 +469,9 @@ gm2_langhook_handle_option (
case OPT_Wunused_parameter:
M2Options_SetUnusedParameterChecking (value);
return 1;
+ case OPT_Wuninit_variable_checking:
+ M2Options_SetUninitVariableChecking (value);
+ return 1;
case OPT_fm2_strict_type:
M2Options_SetStrictTypeChecking (value);
return 1;
diff --git a/gcc/m2/gm2-libs/RTint.mod b/gcc/m2/gm2-libs/RTint.mod
index b3b8737..8b967b5 100644
--- a/gcc/m2/gm2-libs/RTint.mod
+++ b/gcc/m2/gm2-libs/RTint.mod
@@ -441,6 +441,10 @@ END ExcludeVector ;
PROCEDURE AddFd (VAR set: SetOfFd; VAR max: INTEGER; fd: INTEGER) ;
BEGIN
+ IF (fd<0)
+ THEN
+ RETURN
+ END ;
max := Max (fd, max) ;
IF set = NIL
THEN
@@ -667,6 +671,7 @@ PROCEDURE Listen (untilInterrupt: BOOLEAN;
VAR
found : BOOLEAN ;
result : INTEGER ;
+ zero,
after,
b4,
timeval: Timeval ;
@@ -722,14 +727,14 @@ BEGIN
THEN
SetTime (timeval, 0, 0)
END ;
- IF untilInterrupt AND (inSet=NIL) AND (outSet=NIL) AND (NOT found)
+ IF untilInterrupt AND (((inSet=NIL) AND (outSet=NIL)) OR (maxFd=-1)) AND (NOT found)
THEN
Halt ('deadlock found, no more processes to run and no interrupts active',
__FILE__, __FUNCTION__, __LINE__)
END ;
(* printf('timeval = 0x%x\n', timeval) ; *)
(* printf('}\n') ; *)
- IF (NOT found) AND (maxFd=-1) AND (inSet=NIL) AND (outSet=NIL)
+ IF (NOT found) AND (maxFd=-1)
THEN
(* no file descriptors to be selected upon. *)
timeval := KillTime (timeval) ;
@@ -738,6 +743,7 @@ BEGIN
ELSE
GetTime (timeval, sec, micro) ;
Assert (micro < Microseconds) ;
+ zero := InitTime (0, 0) ;
b4 := InitTime (0, 0) ;
after := InitTime (0, 0) ;
result := GetTimeOfDay (b4) ;
@@ -754,26 +760,54 @@ BEGIN
THEN
printf ("select (.., .., .., %u.%06u)\n", sec, micro)
END ;
- result := select (maxFd+1, inSet, outSet, NIL, timeval) ;
+ IF maxFd<0
+ THEN
+ result := select (0, NIL, NIL, NIL, timeval)
+ ELSE
+ result := select (maxFd+1, inSet, outSet, NIL, timeval)
+ END ;
IF result=-1
THEN
- perror ("select") ;
- result := select (maxFd+1, inSet, outSet, NIL, NIL) ;
- IF result=-1
+ IF Debugging
THEN
- perror ("select timeout argument is faulty")
+ perror ("select failed : ") ;
END ;
- result := select (maxFd+1, inSet, NIL, NIL, timeval) ;
- IF result=-1
+ result := select (maxFd+1, inSet, outSet, NIL, zero) ;
+ IF result#-1
THEN
- perror ("select output fd argument is faulty")
- END ;
- result := select (maxFd+1, NIL, outSet, NIL, timeval) ;
- IF result=-1
- THEN
- perror ("select input fd argument is faulty")
+ GetTime (timeval, sec, micro) ;
+ IF Debugging
+ THEN
+ printf ("(nfds : %d timeval: %u.%06u) : \n", maxFd, sec, micro) ;
+ END ;
+ perror ("select timeout argument was faulty : ")
ELSE
- perror ("select maxFD+1 argument is faulty")
+ result := select (maxFd+1, inSet, NIL, NIL, timeval) ;
+ IF result#-1
+ THEN
+ perror ("select output fd argument was faulty : ")
+ ELSE
+ result := select (maxFd+1, NIL, outSet, NIL, timeval) ;
+ IF result#-1
+ THEN
+ perror ("select input fd argument was faulty : ")
+ ELSE
+ IF maxFd=-1
+ THEN
+ result := select (0, NIL, NIL, NIL, timeval) ;
+ IF result=-1
+ THEN
+ IF Debugging
+ THEN
+ perror ("select does not accept nfds == 0 ") ;
+ END ;
+ result := 0
+ END
+ ELSE
+ perror ("select maxFD+1 argument was faulty : ") ;
+ END
+ END
+ END
END
END
UNTIL result#-1
@@ -785,6 +819,10 @@ BEGIN
THEN
timeval := KillTime (timeval)
END ;
+ IF zero#NIL
+ THEN
+ zero := KillTime (zero)
+ END ;
IF after#NIL
THEN
after := KillTime (after)
diff --git a/gcc/m2/lang.opt b/gcc/m2/lang.opt
index 7a0edb7..6dbdf9d 100644
--- a/gcc/m2/lang.opt
+++ b/gcc/m2/lang.opt
@@ -293,6 +293,10 @@ Wunused-parameter
Modula-2
; Documented in c.opt
+Wuninit-variable-checking
+Modula-2
+turns on compile time analysis in the first basic block of a procedure detecting access to uninitialized data.
+
B
Modula-2
; Documented in c.opt
diff --git a/gcc/match.pd b/gcc/match.pd
index 2dd2382..8543f77 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1853,6 +1853,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|| tree_nop_conversion_p (TREE_TYPE (@0), type)))
|| types_match (@0, @1))
&& !POINTER_TYPE_P (TREE_TYPE (@0))
+ && !VECTOR_TYPE_P (TREE_TYPE (@0))
&& TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE
/* ??? This transform conflicts with fold-const.cc doing
Convert (T)(x & c) into (T)x & (T)c, if c is an integer
@@ -3024,19 +3025,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(with { tree cst = const_binop (outer_op == inner_op
? PLUS_EXPR : MINUS_EXPR,
type, @1, @2); }
- (if (cst && !TREE_OVERFLOW (cst))
- (inner_op @0 { cst; } )
- /* X+INT_MAX+1 is X-INT_MIN. */
- (if (INTEGRAL_TYPE_P (type) && cst
- && wi::to_wide (cst) == wi::min_value (type))
- (neg_inner_op @0 { wide_int_to_tree (type, wi::to_wide (cst)); })
- /* Last resort, use some unsigned type. */
- (with { tree utype = unsigned_type_for (type); }
- (if (utype)
- (view_convert (inner_op
- (view_convert:utype @0)
- (view_convert:utype
- { drop_tree_overflow (cst); }))))))))))))))
+ (if (cst)
+ (if (INTEGRAL_TYPE_P (type) && !TREE_OVERFLOW (cst))
+ (inner_op @0 { cst; } )
+ /* X+INT_MAX+1 is X-INT_MIN. */
+ (if (INTEGRAL_TYPE_P (type)
+ && wi::to_wide (cst) == wi::min_value (type))
+ (neg_inner_op @0 { wide_int_to_tree (type, wi::to_wide (cst)); })
+ /* Last resort, use some unsigned type. */
+ (with { tree utype = unsigned_type_for (type); }
+ (if (utype)
+ (view_convert (inner_op
+ (view_convert:utype @0)
+ (view_convert:utype
+ { TREE_OVERFLOW (cst)
+ ? drop_tree_overflow (cst) : cst; })))))))))))))))
/* (CST1 - A) +- CST2 -> CST3 - A */
(for outer_op (plus minus)
@@ -4702,7 +4705,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* a ? -1 : 0 -> -a. No need to check the TYPE_PRECISION not being 1
here as the powerof2cst case above will handle that case correctly. */
(if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
- (negate (convert (convert:boolean_type_node @0))))))
+ (with {
+ auto prec = TYPE_PRECISION (type);
+ auto unsign = TYPE_UNSIGNED (type);
+ tree inttype = build_nonstandard_integer_type (prec, unsign);
+ }
+ (convert (negate (convert:inttype (convert:boolean_type_node @0))))))))
(if (integer_zerop (@1))
(with {
tree booltrue = constant_boolean_node (true, boolean_type_node);
@@ -4721,7 +4729,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* a ? -1 : 0 -> -(!a). No need to check the TYPE_PRECISION not being 1
here as the powerof2cst case above will handle that case correctly. */
(if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
- (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
+ (with {
+ auto prec = TYPE_PRECISION (type);
+ auto unsign = TYPE_UNSIGNED (type);
+ tree inttype = build_nonstandard_integer_type (prec, unsign);
+ }
+ (convert
+ (negate
+ (convert:inttype
+ (bit_xor (convert:boolean_type_node @0) { booltrue; } )
+ )
+ )
+ )
+ )
+ )
)
)
)
@@ -4778,24 +4799,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
tree type1;
if ((eqne == EQ_EXPR) ^ (wi::to_wide (@1) == min))
std::swap (arg0, arg1);
- if (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
- {
- /* Avoid performing the arithmetics in bool type which has different
- semantics, otherwise prefer unsigned types from the two with
- the same precision. */
- if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE
- || !TYPE_UNSIGNED (type))
- type1 = TREE_TYPE (@0);
- else
- type1 = TREE_TYPE (arg0);
- }
- else if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type))
+ if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type))
type1 = TREE_TYPE (@0);
else
type1 = type;
- min = wide_int::from (min, TYPE_PRECISION (type1),
+ auto prec = TYPE_PRECISION (type1);
+ auto unsign = TYPE_UNSIGNED (type1);
+ type1 = build_nonstandard_integer_type (prec, unsign);
+ min = wide_int::from (min, prec,
TYPE_SIGN (TREE_TYPE (@0)));
- wide_int a = wide_int::from (wi::to_wide (arg0), TYPE_PRECISION (type1),
+ wide_int a = wide_int::from (wi::to_wide (arg0), prec,
TYPE_SIGN (type));
enum tree_code code;
wi::overflow_type ovf;
@@ -4803,7 +4816,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{
code = PLUS_EXPR;
a -= min;
- if (!TYPE_UNSIGNED (type1))
+ if (!unsign)
{
/* lhs is known to be in range [min, min+1] and we want to add a
to it. Check if that operation can overflow for those 2 values
@@ -4817,7 +4830,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{
code = MINUS_EXPR;
a += min;
- if (!TYPE_UNSIGNED (type1))
+ if (!unsign)
{
/* lhs is known to be in range [min, min+1] and we want to subtract
it from a. Check if that operation can overflow for those 2
@@ -6034,10 +6047,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
type1 = double_type_node;
}
tree newtype
- = (TYPE_PRECISION (TREE_TYPE (@00)) > TYPE_PRECISION (type1)
+ = (element_precision (TREE_TYPE (@00)) > element_precision (type1)
? TREE_TYPE (@00) : type1);
}
- (if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (newtype))
+ (if (element_precision (TREE_TYPE (@0)) > element_precision (newtype))
(cmp (convert:newtype @00) (convert:newtype @10))))))))
@@ -7428,9 +7441,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& newtype == type
&& types_match (newtype, type))
(op (convert:newtype @1) (convert:newtype @2))
- (with { if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype))
+ (with { if (element_precision (ty1) > element_precision (newtype))
newtype = ty1;
- if (TYPE_PRECISION (ty2) > TYPE_PRECISION (newtype))
+ if (element_precision (ty2) > element_precision (newtype))
newtype = ty2; }
/* Sometimes this transformation is safe (cannot
change results through affecting double rounding
@@ -7453,11 +7466,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
exponent range for the product or ratio of two
values representable in the TYPE to be within the
range of normal values of ITYPE. */
- (if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
+ (if (element_precision (newtype) < element_precision (itype)
+ && (!VECTOR_MODE_P (TYPE_MODE (newtype))
+ || target_supports_op_p (newtype, op, optab_default))
&& (flag_unsafe_math_optimizations
- || (TYPE_PRECISION (newtype) == TYPE_PRECISION (type)
- && real_can_shorten_arithmetic (TYPE_MODE (itype),
- TYPE_MODE (type))
+ || (element_precision (newtype) == element_precision (type)
+ && real_can_shorten_arithmetic (element_mode (itype),
+ element_mode (type))
&& !excess_precision_type (newtype)))
&& !types_match (itype, newtype))
(convert:type (op (convert:newtype @1)
@@ -8672,7 +8687,14 @@ and,
(simplify
(vec_perm vec_same_elem_p@0 @0 @1)
- @0)
+ (if (types_match (type, TREE_TYPE (@0)))
+ @0
+ (with
+ {
+ tree elem = uniform_vector_p (@0);
+ }
+ (if (elem)
+ { build_vector_from_val (type, elem); }))))
/* Push VEC_PERM earlier if that may help FMA perception (PR101895). */
(simplify
diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc
index 77bf745..e6ae159 100644
--- a/gcc/optabs-tree.cc
+++ b/gcc/optabs-tree.cc
@@ -543,19 +543,50 @@ target_supports_op_p (tree type, enum tree_code code,
&& optab_handler (ot, TYPE_MODE (type)) != CODE_FOR_nothing);
}
-/* Return true if target supports vector masked load/store for mode. */
+/* Return true if the target has support for masked load/store.
+ We can support masked load/store by either mask{load,store}
+ or len_mask{load,store}.
+ This helper function checks whether target supports masked
+ load/store and return corresponding IFN in the last argument
+ (IFN_MASK_{LOAD,STORE} or IFN_LEN_MASK_{LOAD,STORE}). */
+
+static bool
+target_supports_mask_load_store_p (machine_mode mode, machine_mode mask_mode,
+ bool is_load, internal_fn *ifn)
+{
+ optab op = is_load ? maskload_optab : maskstore_optab;
+ optab len_op = is_load ? len_maskload_optab : len_maskstore_optab;
+ if (convert_optab_handler (op, mode, mask_mode) != CODE_FOR_nothing)
+ {
+ if (ifn)
+ *ifn = is_load ? IFN_MASK_LOAD : IFN_MASK_STORE;
+ return true;
+ }
+ else if (convert_optab_handler (len_op, mode, mask_mode) != CODE_FOR_nothing)
+ {
+ if (ifn)
+ *ifn = is_load ? IFN_LEN_MASK_LOAD : IFN_LEN_MASK_STORE;
+ return true;
+ }
+ return false;
+}
+
+/* Return true if target supports vector masked load/store for mode.
+ An additional output in the last argument which is the IFN pointer.
+ We set IFN as MASK_{LOAD,STORE} or LEN_MASK_{LOAD,STORE} according
+ which optab is supported in the target. */
bool
can_vec_mask_load_store_p (machine_mode mode,
machine_mode mask_mode,
- bool is_load)
+ bool is_load,
+ internal_fn *ifn)
{
- optab op = is_load ? maskload_optab : maskstore_optab;
machine_mode vmode;
/* If mode is vector mode, check it directly. */
if (VECTOR_MODE_P (mode))
- return convert_optab_handler (op, mode, mask_mode) != CODE_FOR_nothing;
+ return target_supports_mask_load_store_p (mode, mask_mode, is_load, ifn);
/* Otherwise, return true if there is some vector mode with
the mask load/store supported. */
@@ -569,7 +600,7 @@ can_vec_mask_load_store_p (machine_mode mode,
vmode = targetm.vectorize.preferred_simd_mode (smode);
if (VECTOR_MODE_P (vmode)
&& targetm.vectorize.get_mask_mode (vmode).exists (&mask_mode)
- && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
+ && target_supports_mask_load_store_p (vmode, mask_mode, is_load, ifn))
return true;
auto_vector_modes vector_modes;
@@ -577,33 +608,66 @@ can_vec_mask_load_store_p (machine_mode mode,
for (machine_mode base_mode : vector_modes)
if (related_vector_mode (base_mode, smode).exists (&vmode)
&& targetm.vectorize.get_mask_mode (vmode).exists (&mask_mode)
- && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
+ && target_supports_mask_load_store_p (vmode, mask_mode, is_load, ifn))
return true;
return false;
}
+/* Return true if the target has support for len load/store.
+ We can support len load/store by either len_{load,store}
+ or len_mask{load,store}.
+ This helper function checks whether target supports len
+ load/store and return corresponding IFN in the last argument
+ (IFN_LEN_{LOAD,STORE} or IFN_LEN_MASK_{LOAD,STORE}). */
+
+static bool
+target_supports_len_load_store_p (machine_mode mode, bool is_load,
+ internal_fn *ifn)
+{
+ optab op = is_load ? len_load_optab : len_store_optab;
+ optab masked_op = is_load ? len_maskload_optab : len_maskstore_optab;
+
+ if (direct_optab_handler (op, mode))
+ {
+ if (ifn)
+ *ifn = is_load ? IFN_LEN_LOAD : IFN_LEN_STORE;
+ return true;
+ }
+ machine_mode mask_mode;
+ if (targetm.vectorize.get_mask_mode (mode).exists (&mask_mode)
+ && convert_optab_handler (masked_op, mode, mask_mode) != CODE_FOR_nothing)
+ {
+ if (ifn)
+ *ifn = is_load ? IFN_LEN_MASK_LOAD : IFN_LEN_MASK_STORE;
+ return true;
+ }
+ return false;
+}
+
/* If target supports vector load/store with length for vector mode MODE,
return the corresponding vector mode, otherwise return opt_machine_mode ().
There are two flavors for vector load/store with length, one is to measure
length with bytes, the other is to measure length with lanes.
As len_{load,store} optabs point out, for the flavor with bytes, we use
- VnQI to wrap the other supportable same size vector modes. */
+ VnQI to wrap the other supportable same size vector modes.
+ An additional output in the last argument which is the IFN pointer.
+ We set IFN as LEN_{LOAD,STORE} or LEN_MASK_{LOAD,STORE} according
+ which optab is supported in the target. */
opt_machine_mode
-get_len_load_store_mode (machine_mode mode, bool is_load)
+get_len_load_store_mode (machine_mode mode, bool is_load, internal_fn *ifn)
{
- optab op = is_load ? len_load_optab : len_store_optab;
gcc_assert (VECTOR_MODE_P (mode));
/* Check if length in lanes supported for this mode directly. */
- if (direct_optab_handler (op, mode))
+ if (target_supports_len_load_store_p (mode, is_load, ifn))
return mode;
/* Check if length in bytes supported for same vector size VnQI. */
machine_mode vmode;
poly_uint64 nunits = GET_MODE_SIZE (mode);
if (related_vector_mode (mode, QImode, nunits).exists (&vmode)
- && direct_optab_handler (op, vmode))
+ && target_supports_len_load_store_p (vmode, is_load, ifn))
return vmode;
return opt_machine_mode ();
diff --git a/gcc/optabs-tree.h b/gcc/optabs-tree.h
index a3f79b6..e421fc2 100644
--- a/gcc/optabs-tree.h
+++ b/gcc/optabs-tree.h
@@ -47,7 +47,9 @@ bool expand_vec_cond_expr_p (tree, tree, enum tree_code);
void init_tree_optimization_optabs (tree);
bool target_supports_op_p (tree, enum tree_code,
enum optab_subtype = optab_default);
-bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool);
-opt_machine_mode get_len_load_store_mode (machine_mode, bool);
+bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool,
+ internal_fn * = nullptr);
+opt_machine_mode get_len_load_store_mode (machine_mode, bool,
+ internal_fn * = nullptr);
#endif
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 89ab55b..0a2bcf3 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -63,13 +63,13 @@ void debug_optab_libfuncs (void);
the result of operation CODE applied to OP0 (and OP1 if it is a binary
operation). OP0_MODE is OP0's mode.
- If the last insn does not set TARGET, don't do anything, but return 1.
+ If the last insn does not set TARGET, don't do anything, but return true.
If the last insn or a previous insn sets TARGET and TARGET is one of OP0
- or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
+ or OP1, don't add the REG_EQUAL note but return false. Our caller can then
try again, ensuring that TARGET is not one of the operands. */
-static int
+static bool
add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
rtx op1, machine_mode op0_mode)
{
@@ -84,10 +84,10 @@ add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
&& GET_RTX_CLASS (code) != RTX_COMM_COMPARE
&& GET_RTX_CLASS (code) != RTX_COMPARE
&& GET_RTX_CLASS (code) != RTX_UNARY)
- return 1;
+ return true;
if (GET_CODE (target) == ZERO_EXTRACT)
- return 1;
+ return true;
for (last_insn = insns;
NEXT_INSN (last_insn) != NULL_RTX;
@@ -118,20 +118,20 @@ add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
&& (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
|| (op1 && rtx_equal_p (SET_DEST (set),
XEXP (SET_SRC (set), 1)))))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
set = set_for_reg_notes (last_insn);
if (set == NULL_RTX)
- return 1;
+ return true;
if (! rtx_equal_p (SET_DEST (set), target)
/* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
&& (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
|| ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
- return 1;
+ return true;
if (GET_RTX_CLASS (code) == RTX_UNARY)
switch (code)
@@ -165,7 +165,7 @@ add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
set_unique_reg_note (last_insn, REG_EQUAL, note);
- return 1;
+ return true;
}
/* Given two input operands, OP0 and OP1, determine what the correct from_mode
@@ -193,14 +193,14 @@ widened_mode (machine_mode to_mode, rtx op0, rtx op1)
}
/* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
- says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
+ says whether OP is signed or unsigned. NO_EXTEND is true if we need
not actually do a sign-extend or zero-extend, but can leave the
higher-order bits of the result rtx undefined, for example, in the case
of logical operations, but not right shifts. */
static rtx
widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
- int unsignedp, int no_extend)
+ int unsignedp, bool no_extend)
{
rtx result;
scalar_int_mode int_mode;
@@ -1657,7 +1657,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
!= CODE_FOR_nothing)))
{
rtx xop0 = op0, xop1 = op1;
- int no_extend = 0;
+ bool no_extend = false;
/* For certain integer operations, we need not actually extend
the narrow operands, as long as we will truncate
@@ -1669,7 +1669,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
|| binoptab == smul_optab || binoptab == ashl_optab)
&& mclass == MODE_INT)
{
- no_extend = 1;
+ no_extend = true;
xop0 = avoid_expensive_constant (mode, binoptab, 0,
xop0, unsignedp);
if (binoptab != ashl_optab)
@@ -2262,7 +2262,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
&& optab_libfunc (binoptab, wider_mode)))
{
rtx xop0 = op0, xop1 = op1;
- int no_extend = 0;
+ bool no_extend = false;
/* For certain integer operations, we need not actually extend
the narrow operands, as long as we will truncate
@@ -2273,7 +2273,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
|| binoptab == add_optab || binoptab == sub_optab
|| binoptab == smul_optab || binoptab == ashl_optab)
&& mclass == MODE_INT)
- no_extend = 1;
+ no_extend = true;
xop0 = widen_operand (xop0, wider_mode, mode,
unsignedp, no_extend);
@@ -2372,9 +2372,9 @@ sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
the result is not actually wanted. We will generate it into
a dummy pseudo-reg and discard it. They may not both be zero.
- Returns 1 if this operation can be performed; 0 if not. */
+ Returns true if this operation can be performed; false if not. */
-int
+bool
expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
int unsignedp)
{
@@ -2403,7 +2403,7 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
create_fixed_operand (&ops[1], targ1);
create_convert_operand_from (&ops[2], op0, mode, unsignedp);
if (maybe_expand_insn (icode, 3, ops))
- return 1;
+ return true;
}
/* It can't be done in this mode. Can we do it in a wider mode? */
@@ -2422,7 +2422,7 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
{
convert_move (targ0, t0, unsignedp);
convert_move (targ1, t1, unsignedp);
- return 1;
+ return true;
}
else
delete_insns_since (last);
@@ -2431,7 +2431,7 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
}
delete_insns_since (entry_last);
- return 0;
+ return false;
}
/* Generate code to perform an operation specified by BINOPTAB
@@ -2444,9 +2444,9 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
the result is not actually wanted. We will generate it into
a dummy pseudo-reg and discard it. They may not both be zero.
- Returns 1 if this operation can be performed; 0 if not. */
+ Returns true if this operation can be performed; false if not. */
-int
+bool
expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
int unsignedp)
{
@@ -2483,7 +2483,7 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
create_convert_operand_from (&ops[2], xop1, mode, unsignedp);
create_fixed_operand (&ops[3], targ1);
if (maybe_expand_insn (icode, 4, ops))
- return 1;
+ return true;
delete_insns_since (last);
}
@@ -2505,7 +2505,7 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
{
convert_move (targ0, t0, unsignedp);
convert_move (targ1, t1, unsignedp);
- return 1;
+ return true;
}
else
delete_insns_since (last);
@@ -2514,7 +2514,7 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
}
delete_insns_since (entry_last);
- return 0;
+ return false;
}
/* Expand the two-valued library call indicated by BINOPTAB, but
@@ -4298,7 +4298,7 @@ emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
emit_libcall_block_1 (insns, target, result, equiv, false);
}
-/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
+/* True if we can perform a comparison of mode MODE straightforwardly.
PURPOSE describes how this comparison will be used. CODE is the rtx
comparison code we will be using.
@@ -4306,7 +4306,7 @@ emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
required to implement all of the normal bcc operations, but not
required to implement all (or any) of the unordered bcc operations. */
-int
+bool
can_compare_p (enum rtx_code code, machine_mode mode,
enum can_compare_purpose purpose)
{
@@ -4319,21 +4319,21 @@ can_compare_p (enum rtx_code code, machine_mode mode,
if (purpose == ccp_jump
&& (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
&& insn_operand_matches (icode, 0, test))
- return 1;
+ return true;
if (purpose == ccp_store_flag
&& (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
&& insn_operand_matches (icode, 1, test))
- return 1;
+ return true;
if (purpose == ccp_cmov
&& optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
- return 1;
+ return true;
mode = GET_MODE_WIDER_MODE (mode).else_void ();
PUT_MODE (test, mode);
}
while (mode != VOIDmode);
- return 0;
+ return false;
}
/* Return whether RTL code CODE corresponds to an unsigned optab. */
@@ -5369,7 +5369,7 @@ gen_add3_insn (rtx r0, rtx r1, rtx c)
return GEN_FCN (icode) (r0, r1, c);
}
-int
+bool
have_add2_insn (rtx x, rtx y)
{
enum insn_code icode;
@@ -5379,14 +5379,14 @@ have_add2_insn (rtx x, rtx y)
icode = optab_handler (add_optab, GET_MODE (x));
if (icode == CODE_FOR_nothing)
- return 0;
+ return false;
if (!insn_operand_matches (icode, 0, x)
|| !insn_operand_matches (icode, 1, x)
|| !insn_operand_matches (icode, 2, y))
- return 0;
+ return false;
- return 1;
+ return true;
}
/* Generate and return an insn body to add Y to X. */
@@ -5406,7 +5406,7 @@ gen_addptr3_insn (rtx x, rtx y, rtx z)
/* Return true if the target implements an addptr pattern and X, Y,
and Z are valid for the pattern predicates. */
-int
+bool
have_addptr3_insn (rtx x, rtx y, rtx z)
{
enum insn_code icode;
@@ -5416,14 +5416,14 @@ have_addptr3_insn (rtx x, rtx y, rtx z)
icode = optab_handler (addptr3_optab, GET_MODE (x));
if (icode == CODE_FOR_nothing)
- return 0;
+ return false;
if (!insn_operand_matches (icode, 0, x)
|| !insn_operand_matches (icode, 1, y)
|| !insn_operand_matches (icode, 2, z))
- return 0;
+ return false;
- return 1;
+ return true;
}
/* Generate and return an insn body to subtract Y from X. */
@@ -5457,7 +5457,7 @@ gen_sub3_insn (rtx r0, rtx r1, rtx c)
return GEN_FCN (icode) (r0, r1, c);
}
-int
+bool
have_sub2_insn (rtx x, rtx y)
{
enum insn_code icode;
@@ -5467,14 +5467,14 @@ have_sub2_insn (rtx x, rtx y)
icode = optab_handler (sub_optab, GET_MODE (x));
if (icode == CODE_FOR_nothing)
- return 0;
+ return false;
if (!insn_operand_matches (icode, 0, x)
|| !insn_operand_matches (icode, 1, x)
|| !insn_operand_matches (icode, 2, y))
- return 0;
+ return false;
- return 1;
+ return true;
}
/* Generate the body of an insn to extend Y (with mode MFROM)
@@ -6057,7 +6057,7 @@ expand_sfix_optab (rtx to, rtx from, convert_optab tab)
/* Report whether we have an instruction to perform the operation
specified by CODE on operands of mode MODE. */
-int
+bool
have_insn_for (enum rtx_code code, machine_mode mode)
{
return (code_to_optab (code)
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 9533eb1..73c9a0c 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -95,8 +95,10 @@ OPTAB_CD(len_maskload_optab, "len_maskload$a$b")
OPTAB_CD(len_maskstore_optab, "len_maskstore$a$b")
OPTAB_CD(gather_load_optab, "gather_load$a$b")
OPTAB_CD(mask_gather_load_optab, "mask_gather_load$a$b")
+OPTAB_CD(len_mask_gather_load_optab, "len_mask_gather_load$a$b")
OPTAB_CD(scatter_store_optab, "scatter_store$a$b")
OPTAB_CD(mask_scatter_store_optab, "mask_scatter_store$a$b")
+OPTAB_CD(len_mask_scatter_store_optab, "len_mask_scatter_store$a$b")
OPTAB_CD(vec_extract_optab, "vec_extract$a$b")
OPTAB_CD(vec_init_optab, "vec_init$a$b")
@@ -422,6 +424,11 @@ OPTAB_D (vec_widen_sadd_hi_optab, "vec_widen_sadd_hi_$a")
OPTAB_D (vec_widen_sadd_lo_optab, "vec_widen_sadd_lo_$a")
OPTAB_D (vec_widen_sadd_odd_optab, "vec_widen_sadd_odd_$a")
OPTAB_D (vec_widen_sadd_even_optab, "vec_widen_sadd_even_$a")
+OPTAB_D (vec_widen_sabd_optab, "vec_widen_sabd_$a")
+OPTAB_D (vec_widen_sabd_hi_optab, "vec_widen_sabd_hi_$a")
+OPTAB_D (vec_widen_sabd_lo_optab, "vec_widen_sabd_lo_$a")
+OPTAB_D (vec_widen_sabd_odd_optab, "vec_widen_sabd_odd_$a")
+OPTAB_D (vec_widen_sabd_even_optab, "vec_widen_sabd_even_$a")
OPTAB_D (vec_widen_sshiftl_hi_optab, "vec_widen_sshiftl_hi_$a")
OPTAB_D (vec_widen_sshiftl_lo_optab, "vec_widen_sshiftl_lo_$a")
OPTAB_D (vec_widen_umult_even_optab, "vec_widen_umult_even_$a")
@@ -440,6 +447,11 @@ OPTAB_D (vec_widen_uadd_hi_optab, "vec_widen_uadd_hi_$a")
OPTAB_D (vec_widen_uadd_lo_optab, "vec_widen_uadd_lo_$a")
OPTAB_D (vec_widen_uadd_odd_optab, "vec_widen_uadd_odd_$a")
OPTAB_D (vec_widen_uadd_even_optab, "vec_widen_uadd_even_$a")
+OPTAB_D (vec_widen_uabd_optab, "vec_widen_uabd_$a")
+OPTAB_D (vec_widen_uabd_hi_optab, "vec_widen_uabd_hi_$a")
+OPTAB_D (vec_widen_uabd_lo_optab, "vec_widen_uabd_lo_$a")
+OPTAB_D (vec_widen_uabd_odd_optab, "vec_widen_uabd_odd_$a")
+OPTAB_D (vec_widen_uabd_even_optab, "vec_widen_uabd_even_$a")
OPTAB_D (vec_addsub_optab, "vec_addsub$a3")
OPTAB_D (vec_fmaddsub_optab, "vec_fmaddsub$a4")
OPTAB_D (vec_fmsubadd_optab, "vec_fmsubadd$a4")
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 29ccbe9..781d554 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -200,10 +200,10 @@ extern rtx sign_expand_binop (machine_mode, optab, optab, rtx, rtx,
rtx, int, enum optab_methods);
/* Generate code to perform an operation on one operand with two results. */
-extern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
+extern bool expand_twoval_unop (optab, rtx, rtx, rtx, int);
/* Generate code to perform an operation on two operands with two results. */
-extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
+extern bool expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
/* Generate code to perform an operation on two operands with two
results, using a library function. */
@@ -243,8 +243,8 @@ enum can_compare_purpose
/* Nonzero if a compare of mode MODE can be done straightforwardly
(without splitting it into pieces). */
-extern int can_compare_p (enum rtx_code, machine_mode,
- enum can_compare_purpose);
+extern bool can_compare_p (enum rtx_code, machine_mode,
+ enum can_compare_purpose);
/* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
for code CODE, comparing operands of mode VALUE_MODE and producing a result
@@ -298,12 +298,12 @@ rtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, machine_mode,
Likewise for subtraction and for just copying. */
extern rtx_insn *gen_add2_insn (rtx, rtx);
extern rtx_insn *gen_add3_insn (rtx, rtx, rtx);
-extern int have_add2_insn (rtx, rtx);
+extern bool have_add2_insn (rtx, rtx);
extern rtx_insn *gen_addptr3_insn (rtx, rtx, rtx);
-extern int have_addptr3_insn (rtx, rtx, rtx);
+extern bool have_addptr3_insn (rtx, rtx, rtx);
extern rtx_insn *gen_sub2_insn (rtx, rtx);
extern rtx_insn *gen_sub3_insn (rtx, rtx, rtx);
-extern int have_sub2_insn (rtx, rtx);
+extern bool have_sub2_insn (rtx, rtx);
/* Generate the body of an insn to extend Y (with mode MFROM)
into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
@@ -323,7 +323,7 @@ extern bool expand_sfix_optab (rtx, rtx, convert_optab);
/* Report whether the machine description contains an insn which can
perform the operation described by CODE and MODE. */
-extern int have_insn_for (enum rtx_code, machine_mode);
+extern bool have_insn_for (enum rtx_code, machine_mode);
/* Generate a conditional trap instruction. */
extern rtx_insn *gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 3087bda..ac81d4e 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -2115,6 +2115,10 @@ const struct zero_call_used_regs_opts_s zero_call_used_regs_opts[] =
ZERO_CALL_USED_REGS_OPT (all-gpr, zero_regs_flags::ALL_GPR),
ZERO_CALL_USED_REGS_OPT (all-arg, zero_regs_flags::ALL_ARG),
ZERO_CALL_USED_REGS_OPT (all, zero_regs_flags::ALL),
+ ZERO_CALL_USED_REGS_OPT (leafy-gpr-arg, zero_regs_flags::LEAFY_GPR_ARG),
+ ZERO_CALL_USED_REGS_OPT (leafy-gpr, zero_regs_flags::LEAFY_GPR),
+ ZERO_CALL_USED_REGS_OPT (leafy-arg, zero_regs_flags::LEAFY_ARG),
+ ZERO_CALL_USED_REGS_OPT (leafy, zero_regs_flags::LEAFY),
#undef ZERO_CALL_USED_REGS_OPT
{NULL, 0U}
};
diff --git a/gcc/output.h b/gcc/output.h
index 877d2af..76cfd58 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -128,17 +128,17 @@ extern int sprint_ul (char *, unsigned long);
extern void asm_fprintf (FILE *file, const char *p, ...)
ATTRIBUTE_ASM_FPRINTF(2, 3);
-/* Return nonzero if this function has no function calls. */
-extern int leaf_function_p (void);
+/* Return true if this function has no function calls. */
+extern bool leaf_function_p (void);
-/* Return 1 if branch is a forward branch.
+/* Return true if branch is a forward branch.
Uses insn_shuid array, so it works only in the final pass. May be used by
output templates to add branch prediction hints, for example. */
-extern int final_forward_branch_p (rtx_insn *);
+extern bool final_forward_branch_p (rtx_insn *);
-/* Return 1 if this function uses only the registers that can be
+/* Return true if this function uses only the registers that can be
safely renumbered. */
-extern int only_leaf_regs_used (void);
+extern bool only_leaf_regs_used (void);
/* Scan IN_RTX and its subexpressions, and renumber all regs into those
available in leaf functions. */
@@ -621,7 +621,7 @@ extern void default_elf_internal_label (FILE *, const char *, unsigned long);
extern void default_elf_init_array_asm_out_constructor (rtx, int);
extern void default_elf_fini_array_asm_out_destructor (rtx, int);
-extern int maybe_assemble_visibility (tree);
+extern bool maybe_assemble_visibility (tree);
extern int default_address_cost (rtx, machine_mode, addr_space_t, bool);
diff --git a/gcc/predict.cc b/gcc/predict.cc
index 5e3c1d6..d65c26f 100644
--- a/gcc/predict.cc
+++ b/gcc/predict.cc
@@ -89,6 +89,7 @@ static void predict_paths_leading_to_edge (edge, enum br_predictor,
static bool can_predict_insn_p (const rtx_insn *);
static HOST_WIDE_INT get_predictor_value (br_predictor, HOST_WIDE_INT);
static void determine_unlikely_bbs ();
+static void estimate_bb_frequencies (bool force);
/* Information we hold about each branch predictor.
Filled using information from predict.def. */
@@ -2485,7 +2486,11 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
{
if (predictor)
*predictor = PRED_MALLOC_NONNULL;
- return boolean_true_node;
+ /* FIXME: This is wrong and we need to convert the logic
+ to value ranges. This makes predictor to assume that
+ malloc always returns (size_t)1 which is not the same
+ as returning non-NULL. */
+ return fold_convert (type, boolean_true_node);
}
if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
@@ -2563,7 +2568,9 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
case BUILT_IN_REALLOC:
if (predictor)
*predictor = PRED_MALLOC_NONNULL;
- return boolean_true_node;
+ /* FIXME: This is wrong and we need to convert the logic
+ to value ranges. */
+ return fold_convert (type, boolean_true_node);
default:
break;
}
@@ -2575,18 +2582,43 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
{
tree res;
+ tree nop0 = op0;
+ tree nop1 = op1;
+ if (TREE_CODE (op0) != INTEGER_CST)
+ {
+ /* See if expected value of op0 is good enough to determine the result. */
+ nop0 = expr_expected_value (op0, visited, predictor, probability);
+ if (nop0
+ && (res = fold_build2 (code, type, nop0, op1)) != NULL
+ && TREE_CODE (res) == INTEGER_CST)
+ return res;
+ if (!nop0)
+ nop0 = op0;
+ }
enum br_predictor predictor2;
HOST_WIDE_INT probability2;
- op0 = expr_expected_value (op0, visited, predictor, probability);
- if (!op0)
- return NULL;
- op1 = expr_expected_value (op1, visited, &predictor2, &probability2);
- if (!op1)
+ if (TREE_CODE (op1) != INTEGER_CST)
+ {
+ /* See if expected value of op1 is good enough to determine the result. */
+ nop1 = expr_expected_value (op1, visited, &predictor2, &probability2);
+ if (nop1
+ && (res = fold_build2 (code, type, op0, nop1)) != NULL
+ && TREE_CODE (res) == INTEGER_CST)
+ {
+ *predictor = predictor2;
+ *probability = probability2;
+ return res;
+ }
+ if (!nop1)
+ nop1 = op1;
+ }
+ if (nop0 == op0 || nop1 == op1)
return NULL;
- res = fold_build2 (code, type, op0, op1);
+ /* Finally see if we have two known values. */
+ res = fold_build2 (code, type, nop0, nop1);
if (TREE_CODE (res) == INTEGER_CST
- && TREE_CODE (op0) == INTEGER_CST
- && TREE_CODE (op1) == INTEGER_CST)
+ && TREE_CODE (nop0) == INTEGER_CST
+ && TREE_CODE (nop1) == INTEGER_CST)
{
/* Combine binary predictions. */
if (*probability != -1 || probability2 != -1)
@@ -2596,7 +2628,7 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
*probability = RDIV (p1 * p2, REG_BR_PROB_BASE);
}
- if (*predictor < predictor2)
+ if (predictor2 < *predictor)
*predictor = predictor2;
return res;
@@ -3894,7 +3926,7 @@ determine_unlikely_bbs ()
probabilities. If FORCE is true, the frequencies are used to estimate
the counts even when there are already non-zero profile counts. */
-void
+static void
estimate_bb_frequencies (bool force)
{
basic_block bb;
diff --git a/gcc/predict.def b/gcc/predict.def
index 1f391a0..ae7dd82 100644
--- a/gcc/predict.def
+++ b/gcc/predict.def
@@ -51,16 +51,17 @@ DEF_PREDICTOR (PRED_NO_PREDICTION, "no prediction", PROB_ALWAYS, 0)
DEF_PREDICTOR (PRED_UNCONDITIONAL, "unconditional jump", PROB_ALWAYS,
PRED_FLAG_FIRST_MATCH)
-/* Return value of malloc function is almost always non-null. */
-DEF_PREDICTOR (PRED_MALLOC_NONNULL, "malloc returned non-NULL", \
- PROB_VERY_LIKELY, PRED_FLAG_FIRST_MATCH)
-
/* Use number of loop iterations determined by # of iterations
analysis to set probability. We don't want to use Dempster-Shaffer
theory here, as the predictions is exact. */
DEF_PREDICTOR (PRED_LOOP_ITERATIONS, "loop iterations", PROB_UNINITIALIZED,
PRED_FLAG_FIRST_MATCH)
+/* Hints provided by user via __builtin_expect_with_probability. */
+DEF_PREDICTOR (PRED_BUILTIN_EXPECT_WITH_PROBABILITY,
+ "__builtin_expect_with_probability", PROB_UNINITIALIZED,
+ PRED_FLAG_FIRST_MATCH)
+
/* Assume that any given atomic operation has low contention,
and thus the compare-and-swap operation succeeds. */
DEF_PREDICTOR (PRED_COMPARE_AND_SWAP, "compare and swap", PROB_VERY_LIKELY,
@@ -73,11 +74,6 @@ DEF_PREDICTOR (PRED_COMPARE_AND_SWAP, "compare and swap", PROB_VERY_LIKELY,
DEF_PREDICTOR (PRED_BUILTIN_EXPECT, "__builtin_expect", PROB_VERY_LIKELY,
PRED_FLAG_FIRST_MATCH)
-/* Hints provided by user via __builtin_expect_with_probability. */
-DEF_PREDICTOR (PRED_BUILTIN_EXPECT_WITH_PROBABILITY,
- "__builtin_expect_with_probability", PROB_UNINITIALIZED,
- PRED_FLAG_FIRST_MATCH)
-
/* Branches to hot labels are likely. */
DEF_PREDICTOR (PRED_HOT_LABEL, "hot label", HITRATE (90),
PRED_FLAG_FIRST_MATCH)
@@ -86,6 +82,10 @@ DEF_PREDICTOR (PRED_HOT_LABEL, "hot label", HITRATE (90),
DEF_PREDICTOR (PRED_COLD_LABEL, "cold label", HITRATE (90),
PRED_FLAG_FIRST_MATCH)
+/* Return value of malloc function is almost always non-null. */
+DEF_PREDICTOR (PRED_MALLOC_NONNULL, "malloc returned non-NULL", \
+ PROB_VERY_LIKELY, PRED_FLAG_FIRST_MATCH)
+
/* Use number of loop iterations guessed by the contents of the loop. */
DEF_PREDICTOR (PRED_LOOP_ITERATIONS_GUESSED, "guessed loop iterations",
PROB_UNINITIALIZED, PRED_FLAG_FIRST_MATCH)
diff --git a/gcc/predict.h b/gcc/predict.h
index d9a7fc3..4864b7d 100644
--- a/gcc/predict.h
+++ b/gcc/predict.h
@@ -93,7 +93,6 @@ extern void tree_estimate_probability (bool);
extern void handle_missing_profiles (void);
extern bool update_max_bb_count (void);
extern bool expensive_function_p (int);
-extern void estimate_bb_frequencies (bool);
extern void compute_function_frequency (void);
extern tree build_predict_expr (enum br_predictor, enum prediction);
extern const char *predictor_name (enum br_predictor);
diff --git a/gcc/print-tree.cc b/gcc/print-tree.cc
index ccecd3d..62451b6 100644
--- a/gcc/print-tree.cc
+++ b/gcc/print-tree.cc
@@ -632,6 +632,11 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
&& TYPE_CXX_ODR_P (node))
fputs (" cxx-odr-p", file);
+ if ((code == RECORD_TYPE
+ || code == UNION_TYPE)
+ && TYPE_INCLUDES_FLEXARRAY (node))
+ fputs (" includes-flexarray", file);
+
/* The transparent-union flag is used for different things in
different nodes. */
if ((code == UNION_TYPE || code == RECORD_TYPE)
diff --git a/gcc/regcprop.cc b/gcc/regcprop.cc
index 6cbfadb..d28a4d5 100644
--- a/gcc/regcprop.cc
+++ b/gcc/regcprop.cc
@@ -423,7 +423,7 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode,
It's unclear if we need to do the same for other special registers. */
if (regno == STACK_POINTER_REGNUM)
{
- if (orig_mode == new_mode)
+ if (orig_mode == new_mode && new_mode == GET_MODE (stack_pointer_rtx))
return stack_pointer_rtx;
else
return NULL_RTX;
@@ -451,6 +451,31 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode,
return NULL_RTX;
}
+/* Helper function to copy attributes when replacing OLD_REG with NEW_REG.
+ If the changes required for NEW_REG are invalid return NULL_RTX, otherwise
+ return NEW_REG. This is intended to be used with maybe_mode_change. */
+
+static rtx
+maybe_copy_reg_attrs (rtx new_reg, rtx old_reg)
+{
+ if (new_reg != stack_pointer_rtx)
+ {
+ /* NEW_REG is assumed to be a register copy resulting from
+ maybe_mode_change. */
+ ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (old_reg);
+ REG_ATTRS (new_reg) = REG_ATTRS (old_reg);
+ REG_POINTER (new_reg) = REG_POINTER (old_reg);
+ }
+ else if (REG_POINTER (new_reg) != REG_POINTER (old_reg))
+ {
+ /* Only a single instance of STACK_POINTER_RTX must exist and we cannot
+ modify it. Allow propagation if REG_POINTER for OLD_REG matches and
+ don't touch ORIGINAL_REGNO and REG_ATTRS. */
+ return NULL_RTX;
+ }
+ return new_reg;
+}
+
/* Find the oldest copy of the value contained in REGNO that is in
register class CL and has mode MODE. If found, return an rtx
of that oldest register, otherwise return NULL. */
@@ -486,12 +511,7 @@ find_oldest_value_reg (enum reg_class cl, rtx reg, struct value_data *vd)
new_rtx = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i, regno);
if (new_rtx)
- {
- ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (reg);
- REG_ATTRS (new_rtx) = REG_ATTRS (reg);
- REG_POINTER (new_rtx) = REG_POINTER (reg);
- return new_rtx;
- }
+ return maybe_copy_reg_attrs (new_rtx, reg);
}
return NULL_RTX;
@@ -965,15 +985,15 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
if (validate_change (insn, &SET_SRC (set), new_rtx, 0))
{
- ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (src);
- REG_ATTRS (new_rtx) = REG_ATTRS (src);
- REG_POINTER (new_rtx) = REG_POINTER (src);
- if (dump_file)
- fprintf (dump_file,
- "insn %u: replaced reg %u with %u\n",
- INSN_UID (insn), regno, REGNO (new_rtx));
- changed = true;
- goto did_replacement;
+ if (maybe_copy_reg_attrs (new_rtx, src))
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "insn %u: replaced reg %u with %u\n",
+ INSN_UID (insn), regno, REGNO (new_rtx));
+ changed = true;
+ goto did_replacement;
+ }
}
/* We need to re-extract as validate_change clobbers
recog_data. */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 9c6803f..098dc4c 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -4508,7 +4508,7 @@ extern rtx canon_condition (rtx);
extern void simplify_using_condition (rtx, rtx *, bitmap);
/* In final.cc */
-extern unsigned int compute_alignments (void);
+extern void compute_alignments (void);
extern void update_alignments (vec<rtx> &);
extern int asm_str_count (const char *templ);
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
index 25b8ddf..4854d71 100644
--- a/gcc/rust/ChangeLog
+++ b/gcc/rust/ChangeLog
@@ -1,3 +1,8 @@
+2023-06-22 Paul E. Murphy <murphyp@linux.ibm.com>
+
+ * rust-object-export.cc [TARGET_AIX]: Rename and update usage to
+ TARGET_AIX_OS.
+
2023-04-06 Owen Avery <powerboat9.gamer@gmail.com>
* parse/rust-parse-impl.h
diff --git a/gcc/sbitmap.cc b/gcc/sbitmap.cc
index 820fab5..41a9e63 100644
--- a/gcc/sbitmap.cc
+++ b/gcc/sbitmap.cc
@@ -187,7 +187,7 @@ bitmap_copy (sbitmap dst, const_sbitmap src)
}
/* Determine if a == b. */
-int
+bool
bitmap_equal_p (const_sbitmap a, const_sbitmap b)
{
bitmap_check_sizes (a, b);
diff --git a/gcc/sbitmap.h b/gcc/sbitmap.h
index 61172db..93f74f4 100644
--- a/gcc/sbitmap.h
+++ b/gcc/sbitmap.h
@@ -264,7 +264,7 @@ extern sbitmap sbitmap_alloc (unsigned int);
extern sbitmap *sbitmap_vector_alloc (unsigned int, unsigned int);
extern sbitmap sbitmap_resize (sbitmap, unsigned int, int);
extern void bitmap_copy (sbitmap, const_sbitmap);
-extern int bitmap_equal_p (const_sbitmap, const_sbitmap);
+extern bool bitmap_equal_p (const_sbitmap, const_sbitmap);
extern unsigned int bitmap_count_bits (const_sbitmap);
extern bool bitmap_empty_p (const_sbitmap);
extern void bitmap_clear (sbitmap);
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 1b58144..99cbdd4 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -7758,6 +7758,38 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op,
return CONST0_RTX (outermode);
}
+ /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
+ if (GET_CODE (op) == ASHIFT
+ && SCALAR_INT_MODE_P (innermode)
+ && CONST_INT_P (XEXP (op, 1))
+ && INTVAL (XEXP (op, 1)) > 0
+ && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
+ /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
+ if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
+ && known_le (GET_MODE_BITSIZE (outermode), val))
+ return CONST0_RTX (outermode);
+ /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
+ if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
+ && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
+ && known_eq (GET_MODE_BITSIZE (outermode), val)
+ && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
+ && known_eq (subreg_highpart_offset (outermode, innermode), byte))
+ return XEXP (XEXP (op, 0), 0);
+ }
+
+ /* Attempt to simplify WORD_MODE SUBREGs of bitwise expressions. */
+ if (outermode == word_mode
+ && (GET_CODE (op) == IOR || GET_CODE (op) == XOR || GET_CODE (op) == AND)
+ && SCALAR_INT_MODE_P (innermode))
+ {
+ rtx op0 = simplify_subreg (outermode, XEXP (op, 0), innermode, byte);
+ rtx op1 = simplify_subreg (outermode, XEXP (op, 1), innermode, byte);
+ if (op0 && op1)
+ return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
+ }
+
scalar_int_mode int_outermode, int_innermode;
if (is_a <scalar_int_mode> (outermode, &int_outermode)
&& is_a <scalar_int_mode> (innermode, &int_innermode)
diff --git a/gcc/statistics.cc b/gcc/statistics.cc
index 1708e0d..6d1eefd 100644
--- a/gcc/statistics.cc
+++ b/gcc/statistics.cc
@@ -88,7 +88,7 @@ static unsigned nr_statistics_hashes;
statistics. */
static stats_counter_table_type *
-curr_statistics_hash (void)
+curr_statistics_hash (bool alloc = true)
{
unsigned idx;
@@ -99,6 +99,9 @@ curr_statistics_hash (void)
&& statistics_hashes[idx])
return statistics_hashes[idx];
+ if (!alloc)
+ return nullptr;
+
if (idx >= nr_statistics_hashes)
{
statistics_hashes = XRESIZEVEC (stats_counter_table_type *,
@@ -202,23 +205,27 @@ statistics_fini_pass (void)
if (current_pass->static_pass_number == -1)
return;
+ stats_counter_table_type *stat_hash = curr_statistics_hash (false);
+
if (dump_file
&& dump_flags & TDF_STATS)
{
fprintf (dump_file, "\n");
fprintf (dump_file, "Pass statistics of \"%s\": ", current_pass->name);
fprintf (dump_file, "----------------\n");
- curr_statistics_hash ()
- ->traverse_noresize <void *, statistics_fini_pass_1> (NULL);
+ if (stat_hash)
+ stat_hash->traverse_noresize <void *, statistics_fini_pass_1> (NULL);
fprintf (dump_file, "\n");
}
+
+ if (!stat_hash)
+ return;
+
if (statistics_dump_file
&& !(statistics_dump_flags & TDF_STATS
|| statistics_dump_flags & TDF_DETAILS))
- curr_statistics_hash ()
- ->traverse_noresize <void *, statistics_fini_pass_2> (NULL);
- curr_statistics_hash ()
- ->traverse_noresize <void *, statistics_fini_pass_3> (NULL);
+ stat_hash->traverse_noresize <void *, statistics_fini_pass_2> (NULL);
+ stat_hash->traverse_noresize <void *, statistics_fini_pass_3> (NULL);
}
/* Helper for printing summary information. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6ff4c0d..b6ce873 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,919 @@
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110491
+ * gcc.dg/torture/pr110491.c: New testcase.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110376
+ * gcc.dg/torture/pr110376.c: New testcase.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110228
+ * gcc.dg/torture/pr110228.c: New testcase.
+ * gcc.dg/uninit-pr101912.c: Un-XFAIL.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110436
+ * gcc.dg/pr110436.c: New testcase.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/110495
+ * gcc.dg/tree-ssa/addadd-2.c: Amend.
+ * gcc.dg/tree-ssa/forwprop-27.c: Adjust.
+
+2023-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110310
+ * gcc.target/i386/pr110310.c: New testcase.
+ * gcc.dg/vect/slp-perm-12.c: Disable epilogue vectorization.
+
+2023-07-04 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/vsetvl/avl_prop-1.c: New test.
+
+2023-07-03 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * gcc.target/riscv/zvbb.c: New test.
+ * gcc.target/riscv/zvbc.c: New test.
+ * gcc.target/riscv/zvkg.c: New test.
+ * gcc.target/riscv/zvkn-1.c: New test.
+ * gcc.target/riscv/zvkn.c: New test.
+ * gcc.target/riscv/zvknc-1.c: New test.
+ * gcc.target/riscv/zvknc-2.c: New test.
+ * gcc.target/riscv/zvknc.c: New test.
+ * gcc.target/riscv/zvkned.c: New test.
+ * gcc.target/riscv/zvkng-1.c: New test.
+ * gcc.target/riscv/zvkng-2.c: New test.
+ * gcc.target/riscv/zvkng.c: New test.
+ * gcc.target/riscv/zvknha.c: New test.
+ * gcc.target/riscv/zvknhb.c: New test.
+ * gcc.target/riscv/zvks-1.c: New test.
+ * gcc.target/riscv/zvks.c: New test.
+ * gcc.target/riscv/zvksc-1.c: New test.
+ * gcc.target/riscv/zvksc-2.c: New test.
+ * gcc.target/riscv/zvksc.c: New test.
+ * gcc.target/riscv/zvksed.c: New test.
+ * gcc.target/riscv/zvksg-1.c: New test.
+ * gcc.target/riscv/zvksg-2.c: New test.
+ * gcc.target/riscv/zvksg.c: New test.
+ * gcc.target/riscv/zvksh.c: New test.
+ * gcc.target/riscv/zvkt.c: New test.
+
+2023-07-03 Iain Sandoe <iain@sandoe.co.uk>
+
+ * lib/g++.exp: Remove additional flag handled by Darwin specs.
+ * lib/obj-c++.exp: Likewise.
+
+2023-07-03 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/110125
+ * gm2/switches/uninit-variable-checking/fail/testinit.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testlarge.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testlarge2.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testrecinit.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testrecinit2.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testrecinit5.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testsmallrec.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testsmallrec2.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testsmallvec.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testvarinit.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testwithnoptr.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testwithptr.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testwithptr2.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/testwithptr3.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testrecinit3.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testrecinit5.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testsmallrec.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testsmallrec2.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testvarinit.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testwithptr.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testwithptr2.mod: New test.
+ * gm2/switches/uninit-variable-checking/pass/testwithptr3.mod: New test.
+ * gm2/switches/uninit-variable-checking/fail/switches-uninit-variable-checking-fail.exp: New file.
+ * gm2/switches/uninit-variable-checking/pass/switches-uninit-variable-checking-pass.exp: New file.
+
+2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/widen/widen-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-12.c: New test.
+
+2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/widen/widen-3.c: Add floating-point.
+ * gcc.target/riscv/rvv/autovec/widen/widen-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-7.c: New test.
+
+2023-07-03 Lehua Ding <lehua.ding@rivai.ai>
+
+ Revert:
+ 2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/widen/widen-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-12.c: New test.
+
+2023-07-03 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/widen/widen-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-12.c: New test.
+
+2023-07-03 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110506
+ * gcc.dg/pr110506-2.c: New testcase.
+
+2023-07-03 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110506
+ * gcc.dg/pr110506.c: New testcase.
+
+2023-07-03 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/110381
+ * gcc.dg/vect/pr110381.c: Add vect_float_strict.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * gcc.target/mips/mips16e2-cache.c: New tests for mips16e2.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * gcc.target/mips/mips16e2.c: New tests for mips16e2.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * gcc.target/mips/mips16e2.c: Add new tests for mips16e2.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * gcc.target/mips/mips16e2.c: New tests for mips16e2.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * gcc.target/mips/mips16e2-gp.c: New tests for mips16e2.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * gcc.target/mips/mips16e2-cmov.c: Added tests for MOVx instructions.
+
+2023-07-03 Jie Mei <jie.mei@oss.cipunited.com>
+
+ * gcc.target/mips/mips.exp(mips_option_groups): Add -mmips16e2
+ option.
+ (mips-dg-init): Handle the recognization of mips16e2 targets.
+ (mips-dg-options): Add dependencies for mips16e2.
+
+2023-07-02 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.dg/Wbuiltin_declaration_mismatch2.d: Fix failed tests.
+
+2023-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/110508
+ * gcc.dg/pr110508.c: New test.
+
+2023-07-02 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/108962
+ * gdc.dg/pr108962.d: New test.
+
+2023-07-02 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110516
+ * gdc.dg/torture/pr110516a.d: New test.
+ * gdc.dg/torture/pr110516b.d: New test.
+
+2023-07-01 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110514
+ * gdc.dg/pr110514a.d: New test.
+ * gdc.dg/pr110514b.d: New test.
+ * gdc.dg/pr110514c.d: New test.
+ * gdc.dg/pr110514d.d: New test.
+
+2023-07-01 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110471
+ * gdc.dg/pr110471a.d: New test.
+ * gdc.dg/pr110471b.d: New test.
+ * gdc.dg/pr110471c.d: New test.
+
+2023-07-01 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/25623
+ * gfortran.dg/pr25623.f90: New test.
+
+2023-07-01 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/ifc-20040816-1.c: Reduce number of mismatches
+ from 2 to 1.
+ * gcc.dg/tree-ssa/loop-ch-profile-1.c: New test.
+ * gcc.dg/tree-ssa/loop-ch-profile-2.c: New test.
+
+2023-07-01 Roger Sayle <roger@nextmovesoftware.com>
+
+ * gcc.target/i386/rotate-6.c: New test case.
+ * gcc.target/i386/sse2-stv-1.c: Likewise.
+
+2023-07-01 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/103680
+ * gcc.dg/tree-ssa/pr103680.c: New test.
+ * gcc.dg/tree-prof/cmpsf-1.c: Un-xfail.
+
+2023-06-30 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/template/nontype12.C: Refine and XFAIL the dg-bogus
+ duplicate diagnostic check.
+
+2023-06-30 Qing Zhao <qing.zhao@oracle.com>
+
+ PR tree-optimization/101832
+ * gcc.dg/builtin-object-size-pr101832.c: New test.
+
+2023-06-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/execute/20230630-1.c: New test.
+ * gcc.c-torture/execute/20230630-2.c: Likewise.
+ * gcc.c-torture/execute/20230630-3.c: Likewise
+ * gcc.c-torture/execute/20230630-4.c: Likewise
+
+2023-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR jit/110466
+ * jit.dg/jit.exp (jit-check-debug-info): Gracefully handle too
+ early versions of gdb that don't support our dwarf version, via
+ "unsupported".
+
+2023-06-30 David Malcolm <dmalcolm@redhat.com>
+ Marek Polacek <polacek@redhat.com>
+
+ PR jit/110466
+ * jit.dg/test-expressions.c (run_test_of_comparison): Fix size
+ param to gcc_jit_type_get_vector.
+ (verify_comparisons): Use a typedef rather than __vector.
+
+2023-06-30 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/109849
+ * gcc.dg/predict-18.c: Improve testcase.
+
+2023-06-30 Oluwatamilore Adebayo <oluwatamilore.adebayo@arm.com>
+
+ * gcc.target/aarch64/abd_2.c: Added ABDL testcases.
+ * gcc.target/aarch64/abd_3.c: Added ABDL testcases.
+ * gcc.target/aarch64/abd_4.c: Added ABDL testcases.
+ * gcc.target/aarch64/abd_none_2.c: Added ABDL testcases.
+ * gcc.target/aarch64/abd_none_3.c: Added ABDL testcases.
+ * gcc.target/aarch64/abd_none_4.c: Added ABDL testcases.
+ * gcc.target/aarch64/abd_run_1.c: Added ABDL testcases.
+ * gcc.target/aarch64/sve/abd_1.c: Added ABDL testcases.
+ * gcc.target/aarch64/sve/abd_2.c: Added ABDL testcases.
+ * gcc.target/aarch64/sve/abd_none_1.c: Added ABDL testcases.
+ * gcc.target/aarch64/sve/abd_none_2.c: Added ABDL testcases.
+ * gcc.target/aarch64/abd_widen_2.c: New file.
+ * gcc.target/aarch64/abd_widen_3.c: New file.
+ * gcc.target/aarch64/abd_widen_4.c: New file.
+
+2023-06-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110496
+ * gcc.dg/pr110496.c: New testcase.
+
+2023-06-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110381
+ * gcc.dg/vect/pr110381.c: Add check_vect ().
+
+2023-06-30 Jovan Dmitrović <jovan.dmitrovic@syrmia.com>
+
+ * gcc.target/mips/align-1-n64.c: New test.
+ * gcc.target/mips/align-1-o32.c: New test.
+
+2023-06-29 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/109849
+ * gcc.dg/ipa/pr109849.c: New test.
+
+2023-06-29 Marek Polacek <polacek@redhat.com>
+
+ * gcc.dg/plugin/crash-test-ice-sarif.c: Use -fno-report-bug. Adjust
+ scan-sarif-file.
+ * gcc.dg/plugin/crash-test-ice-stderr.c: Use -fno-report-bug.
+ * gcc.dg/plugin/crash-test-write-though-null-sarif.c: Use
+ -fno-report-bug. Adjust scan-sarif-file.
+ * gcc.dg/plugin/crash-test-write-though-null-stderr.c: Use
+ -fno-report-bug.
+
+2023-06-29 Marek Polacek <polacek@redhat.com>
+
+ * gcc.target/i386/pr104610.c: Use -fno-stack-protector.
+ * gcc.target/i386/pr69482-1.c: Likewise.
+
+2023-06-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/110468
+ * g++.dg/cpp0x/noexcept79.C: New test.
+
+2023-06-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/110463
+ * g++.dg/cpp0x/constexpr-mutable6.C: New test.
+
+2023-06-29 Qing Zhao <qing.zhao@oracle.com>
+
+ PR c/77650
+ * gcc.dg/variable-sized-type-flex-array.c: New test.
+
+2023-06-29 Roger Sayle <roger@nextmovesoftware.com>
+
+ * gcc.target/i386/pieces-memcmp-2.c: Specify that 128-bit
+ comparisons are desired, to see if 256-bit instructions are
+ generated inappropriately (fixes test on -march=cascadelake).
+
+2023-06-29 Alexandre Oliva <oliva@adacore.com>
+
+ * lib/options.exp (check_for_options_with_filter): Handle
+ missing frontend compiler like disabled language.
+
+2023-06-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/110452
+ * gcc.target/i386/pr110452.c: New file.
+
+2023-06-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/110461
+ * gcc.dg/pr110461.c: New testcase.
+
+2023-06-29 Richard Biener <rguenther@suse.de>
+
+ PR c/110454
+ * gcc.dg/Wtraditional-conversion-3.c: New testcase.
+
+2023-06-29 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/base/float-point-frm-insert-1.c: New test.
+ * gcc.target/riscv/rvv/base/float-point-frm-insert-2.c: New test.
+ * gcc.target/riscv/rvv/base/float-point-frm-insert-3.c: New test.
+ * gcc.target/riscv/rvv/base/float-point-frm-insert-4.c: New test.
+ * gcc.target/riscv/rvv/base/float-point-frm-insert-5.c: New test.
+
+2023-06-29 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/base/float-point-frm-error.c: New test.
+ * gcc.target/riscv/rvv/base/float-point-frm.c: New test.
+
+2023-06-28 Hans-Peter Nilsson <hp@axis.com>
+
+ * lib/target-supports.exp (check_effective_target_lra): Remove
+ cris-*-* from expression for exceptions to LRA.
+
+2023-06-28 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/110334
+ * g++.dg/opt/pr66119.C: Disable early inlining.
+ * gcc.c-torture/compile/pr110334.c: New test.
+ * gcc.dg/tree-ssa/pr110334.c: New test.
+
+2023-06-28 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/110360
+ * gfortran.dg/value_9.f90: Add tests for intermediate regression.
+
+2023-06-28 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/89442
+ PR c++/107437
+ * g++.dg/cpp/pr64127.C: Expect "expected unqualified-id at end
+ of input" error.
+ * g++.dg/cpp0x/alias-decl-ttp1.C: Fix template parameter/argument
+ kind mismatch for variable template has_P_match_V.
+ * g++.dg/cpp1y/pr72759.C: Expect "template argument 1 is invalid"
+ error.
+ * g++.dg/cpp1z/constexpr-if20.C: XFAIL test due to bogus "'i' is
+ not captured" error.
+ * g++.dg/cpp1z/noexcept-type21.C: Fix arity of variable template d.
+ * g++.dg/diagnostic/not-a-function-template-1.C: Add default
+ template argument to variable template A so that A<> is valid.
+ * g++.dg/parse/error56.C: Don't expect "ISO C++ forbids
+ declaration with no type" error.
+ * g++.dg/parse/template30.C: Don't expect "parse error in
+ template argument list" error.
+ * g++.dg/cpp1y/var-templ82.C: New test.
+
+2023-06-28 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/106977
+ PR target/110406
+ * gdc.dg/torture/pr110406.d: New test.
+
+2023-06-28 Marek Polacek <polacek@redhat.com>
+
+ PR c++/110175
+ * g++.dg/cpp0x/decltype-110175.C: New test.
+
+2023-06-28 Manolis Tsamis <manolis.tsamis@vrull.eu>
+
+ PR debug/110308
+ * g++.dg/torture/pr110308.C: New test.
+
+2023-06-28 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/arm/mve/intrinsics/mve_fp_fpu1.c: Fix .fpu
+ scan-assembler.
+ * gcc.target/arm/mve/intrinsics/mve_fp_fpu2.c: Likewise.
+
+2023-06-28 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/arm/mve/general-c/nomve_fp_1.c: Require arm_fp.
+
+2023-06-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110451
+ * gfortran.dg/vect/pr110451.f: New testcase.
+
+2023-06-28 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/49213
+ * gfortran.dg/pr49213.f90 : New test
+
+2023-06-28 Roger Sayle <roger@nextmovesoftware.com>
+
+ * gcc.target/i386/pieces-memcmp-2.c: New test case.
+
+2023-06-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110443
+ * gcc.dg/torture/pr110443.c: New testcase.
+
+2023-06-28 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * gcc.dg/rtl/powerpc/move_compare_peephole_32.c: New.
+ * gcc.dg/rtl/powerpc/move_compare_peephole_64.c: New.
+
+2023-06-28 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/widen/widen-8.c: Add floating-point.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-8.c: New test.
+
+2023-06-28 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ PR target/104124
+ * gcc.target/powerpc/pr104124.c: New.
+
+2023-06-28 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/110377
+ * gcc.dg/ipa/pr110377.c: New test.
+
+2023-06-28 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/110444
+ * gcc.c-torture/compile/pr110444-1.c: New test.
+
+2023-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/110334
+ * g++.dg/cpp1z/nodiscard-inh1.C: New test.
+
+2023-06-28 Alexandre Oliva <oliva@adacore.com>
+
+ * c-c++-common/zero-scratch-regs-leafy-1.c: New.
+ * c-c++-common/zero-scratch-regs-leafy-2.c: New.
+ * gcc.target/i386/zero-scratch-regs-leafy-1.c: New.
+ * gcc.target/i386/zero-scratch-regs-leafy-2.c: New.
+
+2023-06-28 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.misc-tests/outputs.exp (gld): Note a known mismatch and
+ record a workaround.
+
+2023-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/110344
+ * g++.dg/cpp26/constexpr-voidptr1.C: New test.
+ * g++.dg/cpp26/constexpr-voidptr2.C: New test.
+ * g++.dg/cpp26/feat-cxx26.C: New test.
+
+2023-06-28 Jason Merrill <jason@redhat.com>
+
+ * lib/g++-dg.exp (g++-dg-runtest): Update for C++26.
+
+2023-06-28 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/widen/widen-1.c: Add floating-point.
+ * gcc.target/riscv/rvv/autovec/widen/widen-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c: New test.
+ * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c: New test.
+
+2023-06-28 Hongyu Wang <hongyu.wang@intel.com>
+
+ * gcc.target/i386/mvc17.c: Add -march=x86-64 to dg-options.
+
+2023-06-28 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/bf16_short_warn.c: New test.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-zvfh-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-zvfh-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-zvfh-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-zvfh-run.c: New test.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c: New test.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c: Adjust.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/conversions/vncvt-template.h:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/conversions/vsext-template.h:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/conversions/vzext-template.h:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/zvfhmin-1.c: Add int/float conversions.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-zvfh-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-zvfh-run.c: New file.
+
+2023-06-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/binop/copysign-run.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/copysign-template.h: New test.
+ * gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c: New test.
+
+2023-06-27 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * gcc.target/aarch64/sve/acle/general/dupq_11.c: New test.
+
+2023-06-27 Andrew Pinski <apinski@marvell.com>
+
+ PR middle-end/110420
+ PR middle-end/103979
+ PR middle-end/98619
+ * gcc.c-torture/compile/asmgoto-6.c: New test.
+
+2023-06-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/96208
+ * gcc.dg/vect/slp-46.c: Adjust for new vectorizations.
+ * gcc.dg/vect/bb-slp-pr65935.c: Adjust.
+
+2023-06-27 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/avx-vzeroupper-29.c: New testcase.
+
+2023-06-27 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/avx-vzeroupper-30.c: New test.
+
+2023-06-27 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/partial/slp-17.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/slp-18.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/slp-19.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/slp_run-17.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/slp_run-18.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/slp_run-19.c: New test.
+
+2023-06-26 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * gcc.target/s390/larl-1.c: New test.
+
+2023-06-26 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c: New test.
+
+2023-06-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110381
+ * gcc.dg/vect/pr110381.c: New testcase.
+
+2023-06-26 Roger Sayle <roger@nextmovesoftware.com>
+
+ * gcc.target/i386/ashldi3-1.c: New 32-bit test case.
+ * gcc.target/i386/ashlti3-2.c: New 64-bit test case.
+
+2023-06-26 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/aarch64/pr110371.c: New test.
+
+2023-06-26 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr110018-1.c: Add -fno-trapping-math to dg-options.
+ * gcc.target/i386/pr110018-2.c: Ditto.
+
+2023-06-26 Hongyu Wang <hongyu.wang@intel.com>
+
+ * gcc.target/i386/mvc17.c: New test.
+
+2023-06-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/base/vlmul_ext-2.c: Add -Wno-psabi for dg.
+
+2023-06-26 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110359
+ * gdc.dg/pr110359.d: New test.
+
+2023-06-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/partial/select_vl-1.c: Add dump checks.
+ * gcc.target/riscv/rvv/autovec/partial/select_vl-2.c: New test.
+
+2023-06-25 Li Xu <xuli1@eswincomputing.com>
+
+ * gcc.target/riscv/rvv/base/vlmul_ext-2.c: New test.
+
+2023-06-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.h: New test.
+ * gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.h: New test.
+ * gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-3.c: New test.
+
+2023-06-25 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/base/abi-10.c: Revert.
+ * gcc.target/riscv/rvv/base/abi-11.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-12.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-15.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-8.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-9.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-17.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-18.c: Ditto.
+
+2023-06-25 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/base/tuple-28.c: Removed.
+ * gcc.target/riscv/rvv/base/tuple-29.c: Removed.
+ * gcc.target/riscv/rvv/base/tuple-30.c: Removed.
+ * gcc.target/riscv/rvv/base/tuple-31.c: Removed.
+ * gcc.target/riscv/rvv/base/tuple-32.c: Removed.
+
+2023-06-25 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr110309.c: New test.
+
+2023-06-25 yulong <shiyulong@iscas.ac.cn>
+
+ * gcc.target/riscv/rvv/base/abi-10.c: Add float16 tuple type case.
+ * gcc.target/riscv/rvv/base/abi-11.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-12.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-15.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-8.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-9.c: Ditto.
+ * gcc.target/riscv/rvv/base/abi-17.c: New test.
+ * gcc.target/riscv/rvv/base/abi-18.c: New test.
+
+2023-06-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-1.c: Adjust tests.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c: New test.
+
+2023-06-24 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/diagnostic_plugin_test_text_art.c: Add
+ #define INCLUDE_VECTOR.
+
+2023-06-23 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/110164
+ * g++.dg/diagnostic/missing-header-pr110164.C: New test.
+
+2023-06-23 Marek Polacek <polacek@redhat.com>
+
+ * lib/target-supports.exp (check_effective_target_c++23): Return
+ 1 also if check_effective_target_c++26.
+ (check_effective_target_c++23_down): New.
+ (check_effective_target_c++26_only): New.
+ (check_effective_target_c++26): New.
+ * g++.dg/cpp23/cplusplus.C: Adjust expected value.
+ * g++.dg/cpp26/cplusplus.C: New test.
+
+2023-06-23 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/110360
+ * gfortran.dg/value_9.f90: New test.
+
+2023-06-23 Michael Meissner <meissner@linux.ibm.com>
+ Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ PR target/105325
+ * g++.target/powerpc/pr105325.C: New test.
+ * gcc.target/powerpc/fusion-p10-ldcmpi.c: Update insn counts.
+
+2023-06-23 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-obj-c++-shared/GNUStep/Foundation/NSObjCRuntime.h: Make
+ this header use pragma system_header.
+
+2023-06-23 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR tree-optimization/110280
+ * gcc.target/aarch64/sve/pr110280.c: New test.
+
+2023-06-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/110332
+ * g++.dg/torture/pr110332.C: New testcase.
+ * gcc.dg/torture/pr110332-1.c: Likewise.
+ * gcc.dg/torture/pr110332-2.c: Likewise.
+
+2023-06-22 Roger Sayle <roger@nextmovesoftware.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/avx-vptest-4.c: New test case.
+ * gcc.target/i386/avx-vptest-5.c: Likewise.
+ * gcc.target/i386/avx-vptest-6.c: Likewise.
+ * gcc.target/i386/pr109973-1.c: Update test case.
+ * gcc.target/i386/pr109973-2.c: Likewise.
+ * gcc.target/i386/sse4_1-ptest-4.c: New test case.
+ * gcc.target/i386/sse4_1-ptest-5.c: Likewise.
+ * gcc.target/i386/sse4_1-ptest-6.c: Likewise.
+
+2023-06-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * gcc.dg/analyzer/data-model-1.c (test_16): Update for
+ out-of-bounds working.
+ * gcc.dg/analyzer/out-of-bounds-diagram-1-ascii.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-1-debug.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-1-json.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-1-sarif.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-10.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-11.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-12.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-13.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-14.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-15.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-2.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-3.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-4.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-6.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-7.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-8.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-diagram-9.c: New test.
+ * gcc.dg/analyzer/pattern-test-2.c: Update expected results.
+ * gcc.dg/analyzer/pr101962.c: Update expected results.
+ * gcc.dg/plugin/analyzer_gil_plugin.c: Add logger param to
+ pending_diagnostic::emit implementations.
+
+2023-06-22 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/diagnostic-test-text-art-ascii-bw.c: New test.
+ * gcc.dg/plugin/diagnostic-test-text-art-ascii-color.c: New test.
+ * gcc.dg/plugin/diagnostic-test-text-art-none.c: New test.
+ * gcc.dg/plugin/diagnostic-test-text-art-unicode-bw.c: New test.
+ * gcc.dg/plugin/diagnostic-test-text-art-unicode-color.c: New test.
+ * gcc.dg/plugin/diagnostic_plugin_test_text_art.c: New test plugin.
+ * gcc.dg/plugin/plugin.exp (plugin_test_list): Add them.
+
+2023-06-22 David Malcolm <dmalcolm@redhat.com>
+
+ * c-c++-common/Wlogical-not-parentheses-2.c: Split up the
+ multiline directive.
+ * gcc.dg/analyzer/malloc-macro-inline-events.c: Remove redundant
+ dg-regexp directives.
+ * gcc.dg/missing-header-fixit-5.c: Split up the multiline
+ directives.
+ * lib/gcc-dg.exp (gcc-dg-prune): Move call to
+ handle-multiline-outputs from prune_gcc_output to here.
+ * lib/multiline.exp (dg-end-multiline-output): Move call to
+ maybe-handle-nn-line-numbers from prune_gcc_output to here.
+ * lib/prune.exp (prune_gcc_output): Move calls to
+ maybe-handle-nn-line-numbers and handle-multiline-outputs from
+ here to the above.
+
2023-06-21 Paul Thomas <pault@gcc.gnu.org>
PR fortran/87477
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c b/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c
new file mode 100644
index 0000000..c1a0c31
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fzero-call-used-regs=leafy" } */
+
+volatile int result = 0;
+int
+__attribute__((noipa))
+foo (int x)
+{
+ return x;
+}
+int main()
+{
+ result = foo (2);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c b/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c
new file mode 100644
index 0000000..d450620
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include <assert.h>
+int result = 0;
+
+int
+__attribute__((noipa))
+__attribute__ ((zero_call_used_regs("leafy")))
+foo1 (int x)
+{
+ return (x + 1);
+}
+
+int
+__attribute__((noipa))
+__attribute__ ((zero_call_used_regs("leafy")))
+foo2 (int x)
+{
+ return foo1 (x + 2);
+}
diff --git a/gcc/testsuite/g++.dg/cpp/pr64127.C b/gcc/testsuite/g++.dg/cpp/pr64127.C
index 29c3bf2..8dc3336 100644
--- a/gcc/testsuite/g++.dg/cpp/pr64127.C
+++ b/gcc/testsuite/g++.dg/cpp/pr64127.C
@@ -1,4 +1,4 @@
/* { dg-do compile { target c++98_only } } */
template <0> int __copy_streambufs_eof; // { dg-error "expected identifier|numeric constant|variable templates" }
-__copy_streambufs_eof < // { dg-error "template argument|parse error|not name a type" }
+__copy_streambufs_eof < // { dg-error "template argument|expected unqualified-id" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp1.C
index d1af8d1..52c0362 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp1.C
@@ -2,5 +2,5 @@
// { dg-do compile { target c++14 } }
template <bool> using enable_if_t = int;
-template <class> bool has_P_match_v;
+template <template <class> class> bool has_P_match_v;
template <template <class> class... List> enable_if_t<has_P_match_v<List...>> a;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable6.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable6.C
new file mode 100644
index 0000000..2c946e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable6.C
@@ -0,0 +1,18 @@
+// PR c++/110463
+// { dg-do compile { target c++11 } }
+
+struct U {
+ mutable int x = 1;
+};
+
+struct V {
+ mutable int y = 1+1;
+};
+
+int main() {
+ constexpr U u = {};
+ constexpr int x = u.x; // { dg-error "mutable" }
+
+ constexpr V v = {};
+ constexpr int y = v.y; // { dg-error "mutable" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-110175.C b/gcc/testsuite/g++.dg/cpp0x/decltype-110175.C
new file mode 100644
index 0000000..39643ca
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype-110175.C
@@ -0,0 +1,6 @@
+// PR c++/110175
+// { dg-do compile { target c++11 } }
+
+template<class T> auto f(T t) -> decltype(++t) { return t; } // { dg-warning "reference" "" { target c++14_down } }
+void f(...) {}
+void g() { f(true); }
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept79.C b/gcc/testsuite/g++.dg/cpp0x/noexcept79.C
new file mode 100644
index 0000000..d1f54d1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept79.C
@@ -0,0 +1,18 @@
+// PR c++/110468
+// { dg-do compile { target c++11 } }
+
+template<int T>
+struct variant {
+ variant() noexcept(T > 0);
+};
+
+template<int N>
+struct A {
+ variant<N> m = {};
+};
+
+struct B {
+ B(A<1>);
+};
+
+B b = {{}};
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr72759.C b/gcc/testsuite/g++.dg/cpp1y/pr72759.C
index 4af6ea4..5c2fb9f 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr72759.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr72759.C
@@ -14,5 +14,5 @@ template <> struct SpecPerType<Specializer> {
};
template <unsigned X> void Specializer::A<X>::InnerMemberFn() {
using Spec = SpecPerType<Specializer>;
- Spec ErrorSite = Spec::SpecMbrFnPtr<SpecMbrFnPtr>; // { dg-error "not declared" }
+ Spec ErrorSite = Spec::SpecMbrFnPtr<SpecMbrFnPtr>; // { dg-error "not declared|invalid" }
}
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ82.C b/gcc/testsuite/g++.dg/cpp1y/var-templ82.C
new file mode 100644
index 0000000..5670f23
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ82.C
@@ -0,0 +1,12 @@
+// PR c++/89442
+// { dg-do compile { target c++14 } }
+
+template<class T, class U> bool vt;
+
+template<class T>
+void f() {
+ bool a = vt<T>; // { dg-error "wrong number" }
+ bool b = vt<T, T>;
+ bool c = vt<T, T, T>; // { dg-error "number" }
+ bool d = vt<T, 42>; // { dg-error "mismatch" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C
index 2fd678b..cd4f802 100644
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C
@@ -12,6 +12,7 @@ void ao() {
[](auto j) {
using as = typename C<j>::q;
if constexpr (m<ar, as>) {}
+ // { dg-bogus "'i' is not captured" "PR107437" { xfail { *-*-* } } .-1 }
}(g());
}(g());
}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C b/gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C
new file mode 100644
index 0000000..bc25559
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C
@@ -0,0 +1,15 @@
+// [[nodiscard]] should apply to inherited constructors.
+// { dg-do compile { target c++11 } }
+
+struct A {
+ [[nodiscard]] A(int);
+};
+
+struct B: A {
+ using A::A;
+};
+
+int main()
+{
+ B(42); // { dg-warning nodiscard }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type21.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type21.C
index d0a61d9..4e0a9ea 100644
--- a/gcc/testsuite/g++.dg/cpp1z/noexcept-type21.C
+++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type21.C
@@ -2,7 +2,7 @@
// { dg-do compile { target c++17 } }
template <typename a> using b = typename a ::c;
-template <typename> bool d;
+template <typename, typename> bool d;
template <typename, typename> struct e {
template <typename f, typename g> e(f, g) {}
template <typename h, typename i, typename j>
diff --git a/gcc/testsuite/g++.dg/cpp23/cplusplus.C b/gcc/testsuite/g++.dg/cpp23/cplusplus.C
index 29a941b..ff331c2 100644
--- a/gcc/testsuite/g++.dg/cpp23/cplusplus.C
+++ b/gcc/testsuite/g++.dg/cpp23/cplusplus.C
@@ -1,4 +1,4 @@
// { dg-do compile }
// { dg-options "-std=c++23" }
-static_assert(__cplusplus > 202002L);
+static_assert(__cplusplus == 202302L);
diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C
new file mode 100644
index 0000000..ce0ccbe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C
@@ -0,0 +1,35 @@
+// PR c++/110344
+// { dg-do compile { target c++26 } }
+
+#include <string_view>
+struct Sheep {
+ constexpr std::string_view speak() const noexcept { return "Baaaaaa"; }
+};
+struct Cow {
+ constexpr std::string_view speak() const noexcept { return "Mooo"; }
+};
+class Animal_View {
+private:
+ const void *animal;
+ std::string_view (*speak_function)(const void *);
+public:
+ template <typename Animal>
+ constexpr Animal_View(const Animal &a)
+ : animal{&a}, speak_function{[](const void *object) {
+ return static_cast<const Animal *>(object)->speak();
+ }} {}
+ constexpr std::string_view speak() const noexcept {
+ return speak_function(animal);
+ }
+};
+// This is the key bit here. This is a single concrete function
+// that can take anything that happens to have the "Animal_View"
+// interface
+constexpr std::string_view do_speak(Animal_View av) { return av.speak(); }
+int main() {
+ // A Cow is a cow. The only think that makes it special
+ // is that it has a "std::string_view speak() const" member
+ constexpr Cow cow;
+ constexpr auto result = do_speak(cow);
+ return static_cast<int>(result.size());
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C
new file mode 100644
index 0000000..e746301
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C
@@ -0,0 +1,15 @@
+// PR c++/110344
+// { dg-do compile { target c++26 } }
+
+struct A { int i; };
+struct B { A a; };
+
+constexpr int f()
+{
+ B b { 42 };
+ void *p = &b;
+ A* ap = static_cast<A*>(p);
+ return ap->i;
+}
+
+static_assert (f() == 42);
diff --git a/gcc/testsuite/g++.dg/cpp26/cplusplus.C b/gcc/testsuite/g++.dg/cpp26/cplusplus.C
new file mode 100644
index 0000000..08c502e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/cplusplus.C
@@ -0,0 +1,3 @@
+// { dg-do compile { target c++26_only } }
+
+static_assert(__cplusplus > 202302L);
diff --git a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
new file mode 100644
index 0000000..0977d96
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
@@ -0,0 +1,597 @@
+// { dg-options "-std=c++26 -I${srcdir}/g++.dg/cpp1y -I${srcdir}/g++.dg/cpp1y/testinc" }
+
+// C++98 features:
+
+#ifndef __cpp_rtti
+# error "__cpp_rtti"
+#elif __cpp_rtti != 199711
+# error "__cpp_rtti != 199711"
+#endif
+
+#ifndef __cpp_exceptions
+# error "__cpp_exceptions"
+#elif __cpp_exceptions != 199711
+# error "__cpp_exceptions != 199711"
+#endif
+
+// C++11 features:
+
+#ifndef __cpp_raw_strings
+# error "__cpp_raw_strings"
+#elif __cpp_raw_strings != 200710
+# error "__cpp_raw_strings != 200710"
+#endif
+
+#ifndef __cpp_unicode_literals
+# error "__cpp_unicode_literals"
+#elif __cpp_unicode_literals != 200710
+# error "__cpp_unicode_literals != 200710"
+#endif
+
+#ifndef __cpp_user_defined_literals
+# error "__cpp_user_defined_literals"
+#elif __cpp_user_defined_literals != 200809
+# error "__cpp_user_defined_literals != 200809"
+#endif
+
+#ifndef __cpp_lambdas
+# error "__cpp_lambdas"
+#elif __cpp_lambdas != 200907
+# error "__cpp_lambdas != 200907"
+#endif
+
+#ifndef __cpp_range_based_for
+# error "__cpp_range_based_for"
+#elif __cpp_range_based_for != 201603
+# error "__cpp_range_based_for != 201603"
+#endif
+
+#ifndef __cpp_decltype
+# error "__cpp_decltype"
+#elif __cpp_decltype != 200707
+# error "__cpp_decltype != 200707"
+#endif
+
+#ifndef __cpp_attributes
+# error "__cpp_attributes"
+#elif __cpp_attributes != 200809
+# error "__cpp_attributes != 200809"
+#endif
+
+#ifndef __cpp_rvalue_references
+# error "__cpp_rvalue_references"
+#elif __cpp_rvalue_references != 200610
+# error "__cpp_rvalue_references != 200610"
+#endif
+
+#ifndef __cpp_variadic_templates
+# error "__cpp_variadic_templates"
+#elif __cpp_variadic_templates != 200704
+# error "__cpp_variadic_templates != 200704"
+#endif
+
+#ifndef __cpp_initializer_lists
+# error "__cpp_initializer_lists"
+#elif __cpp_initializer_lists != 200806
+# error "__cpp_initializer_lists != 200806"
+#endif
+
+#ifndef __cpp_delegating_constructors
+# error "__cpp_delegating_constructors"
+#elif __cpp_delegating_constructors != 200604
+# error "__cpp_delegating_constructors != 200604"
+#endif
+
+#ifndef __cpp_nsdmi
+# error "__cpp_nsdmi"
+#elif __cpp_nsdmi != 200809
+# error "__cpp_nsdmi != 200809"
+#endif
+
+#ifndef __cpp_inheriting_constructors
+# error "__cpp_inheriting_constructors"
+#elif __cpp_inheriting_constructors!= 201511
+# error "__cpp_inheriting_constructors != 201511"
+#endif
+
+#ifndef __cpp_ref_qualifiers
+# error "__cpp_ref_qualifiers"
+#elif __cpp_ref_qualifiers != 200710
+# error "__cpp_ref_qualifiers != 200710"
+#endif
+
+#ifndef __cpp_alias_templates
+# error "__cpp_alias_templates"
+#elif __cpp_alias_templates != 200704
+# error "__cpp_alias_templates != 200704"
+#endif
+
+#ifndef __cpp_threadsafe_static_init
+# error "__cpp_threadsafe_static_init"
+#elif __cpp_threadsafe_static_init != 200806
+# error "__cpp_threadsafe_static_init != 200806"
+#endif
+
+// C++14 features:
+
+#ifndef __cpp_binary_literals
+# error "__cpp_binary_literals"
+#elif __cpp_binary_literals != 201304
+# error "__cpp_binary_literals != 201304"
+#endif
+
+#ifndef __cpp_init_captures
+# error "__cpp_init_captures"
+#elif __cpp_init_captures != 201803
+# error "__cpp_init_captures != 201803"
+#endif
+
+#ifndef __cpp_generic_lambdas
+# error "__cpp_generic_lambdas"
+#elif __cpp_generic_lambdas != 201707
+# error "__cpp_generic_lambdas != 201707"
+#endif
+
+#ifndef __cpp_constexpr
+# error "__cpp_constexpr"
+#elif __cpp_constexpr != 202306L
+# error "__cpp_constexpr != 202306L"
+#endif
+
+#ifndef __cpp_decltype_auto
+# error "__cpp_decltype_auto"
+#elif __cpp_decltype_auto != 201304
+# error "__cpp_decltype_auto != 201304"
+#endif
+
+#ifndef __cpp_return_type_deduction
+# error "__cpp_return_type_deduction"
+#elif __cpp_return_type_deduction != 201304
+# error "__cpp_return_type_deduction != 201304"
+#endif
+
+#ifndef __cpp_aggregate_nsdmi
+# error "__cpp_aggregate_nsdmi"
+#elif __cpp_aggregate_nsdmi != 201304
+# error "__cpp_aggregate_nsdmi != 201304"
+#endif
+
+#ifndef __cpp_variable_templates
+# error "__cpp_variable_templates"
+#elif __cpp_variable_templates != 201304
+# error "__cpp_variable_templates != 201304"
+#endif
+
+#ifndef __cpp_digit_separators
+# error "__cpp_digit_separators"
+#elif __cpp_digit_separators != 201309
+# error "__cpp_digit_separators != 201309"
+#endif
+
+#ifndef __cpp_sized_deallocation
+# error "__cpp_sized_deallocation"
+#elif __cpp_sized_deallocation != 201309
+# error "__cpp_sized_deallocation != 201309"
+#endif
+
+// GNU VLA support:
+
+#ifndef __cpp_runtime_arrays
+# error "__cpp_runtime_arrays"
+#elif __cpp_runtime_arrays != 198712
+# error "__cpp_runtime_arrays != 198712"
+#endif
+
+// C++11 attributes:
+
+#ifdef __has_cpp_attribute
+# if ! __has_cpp_attribute(noreturn)
+# error "__has_cpp_attribute(noreturn)"
+# elif __has_cpp_attribute(noreturn) != 200809
+# error "__has_cpp_attribute(noreturn) != 200809"
+# endif
+#else
+# error "__has_cpp_attribute"
+#endif
+
+// Attribute carries_dependency not in yet.
+//#ifdef __has_cpp_attribute
+//# if ! __has_cpp_attribute(carries_dependency)
+//# error "__has_cpp_attribute(carries_dependency)"
+//# elif __has_cpp_attribute(carries_dependency) != 200809
+//# error "__has_cpp_attribute(carries_dependency) != 200809"
+//# endif
+//#else
+//# error "__has_cpp_attribute"
+//#endif
+
+// C++14 attributes:
+
+#ifdef __has_cpp_attribute
+# if ! __has_cpp_attribute(deprecated)
+# error "__has_cpp_attribute(deprecated)"
+# elif __has_cpp_attribute(deprecated) != 201309
+# error "__has_cpp_attribute(deprecated) != 201309"
+# endif
+#else
+# error "__has_cpp_attribute"
+#endif
+
+// Include checks:
+
+// Check for __has_include macro.
+#ifndef __has_include
+# error "__has_include"
+#endif
+
+// Try known bracket header (use operator).
+#if __has_include (<complex>)
+#else
+# error "<complex>"
+#endif
+
+// Define and use a macro to invoke the operator.
+#define sluggo(TXT) __has_include(TXT)
+
+#if sluggo(<complex>)
+#else
+# error "<complex>"
+#endif
+
+#if ! sluggo(<complex>)
+# error "<complex>"
+#else
+#endif
+
+// Quoted complex.h should find at least the bracket version.
+#if __has_include("complex.h")
+#else
+# error "complex.h"
+#endif
+
+// Try known local quote header.
+#if __has_include("complex_literals.h")
+#else
+# error "\"complex_literals.h\""
+#endif
+
+// Try nonexistent bracket header.
+#if __has_include(<stuff>)
+# error "<stuff>"
+#else
+#endif
+
+// Try nonexistent quote header.
+#if __has_include("phlegm")
+# error "\"phlegm\""
+#else
+#endif
+
+// Test __has_include_next.
+#if __has_include("phoobhar.h")
+# include "phoobhar.h"
+#else
+# error "__has_include(\"phoobhar.h\")"
+#endif
+
+// Try a macro.
+#define COMPLEX_INC "complex.h"
+#if __has_include(COMPLEX_INC)
+#else
+# error COMPLEX_INC
+#endif
+
+// Realistic use of __has_include.
+#if __has_include(<array>)
+# define STD_ARRAY 1
+# include <array>
+ template<typename _Tp, std::size_t _Num>
+ using array = std::array<_Tp, _Num>;
+#elif __has_include(<tr1/array>)
+# define TR1_ARRAY 1
+# include <tr1/array>
+ template<typename _Tp, std::size_t _Num>
+ typedef std::tr1::array<_Tp, _Num> array;
+#endif
+
+// C++17 features:
+
+#ifndef __cpp_unicode_characters
+# error "__cpp_unicode_characters"
+#elif __cpp_unicode_characters != 201411
+# error "__cpp_unicode_characters != 201411"
+#endif
+
+#ifndef __cpp_static_assert
+# error "__cpp_static_assert"
+#elif __cpp_static_assert != 201411
+# error "__cpp_static_assert != 201411"
+#endif
+
+#ifndef __cpp_namespace_attributes
+# error "__cpp_namespace_attributes"
+#elif __cpp_namespace_attributes != 201411
+# error "__cpp_namespace_attributes != 201411"
+#endif
+
+#ifndef __cpp_enumerator_attributes
+# error "__cpp_enumerator_attributes"
+#elif __cpp_enumerator_attributes != 201411
+# error "__cpp_enumerator_attributes != 201411"
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+# error "__cpp_nested_namespace_definitions"
+#elif __cpp_nested_namespace_definitions != 201411
+# error "__cpp_nested_namespace_definitions != 201411"
+#endif
+
+#ifndef __cpp_fold_expressions
+# error "__cpp_fold_expressions"
+#elif __cpp_fold_expressions != 201603
+# error "__cpp_fold_expressions != 201603"
+#endif
+
+#ifndef __cpp_nontype_template_args
+# error "__cpp_nontype_template_args"
+#elif __cpp_nontype_template_args != 201911
+# error "__cpp_nontype_template_args != 201911"
+#endif
+
+#ifndef __cpp_hex_float
+# error "__cpp_hex_float"
+#elif __cpp_hex_float != 201603
+# error "__cpp_hex_float != 201603"
+#endif
+
+#ifndef __cpp_aggregate_bases
+# error "__cpp_aggregate_bases"
+#elif __cpp_aggregate_bases != 201603
+# error "__cpp_aggregate_bases != 201603"
+#endif
+
+#ifndef __cpp_deduction_guides
+# error "__cpp_deduction_guides"
+#elif __cpp_deduction_guides != 201907
+# error "__cpp_deduction_guides != 201907"
+#endif
+
+#ifndef __cpp_if_constexpr
+# error "__cpp_if_constexpr"
+#elif __cpp_if_constexpr != 201606
+# error "__cpp_if_constexpr != 201606"
+#endif
+
+#ifndef __cpp_aligned_new
+# error "__cpp_aligned_new"
+#elif __cpp_aligned_new != 201606
+# error "__cpp_aligned_new != 201606"
+#endif
+
+#ifndef __cpp_template_auto
+# error "__cpp_template_auto"
+#elif __cpp_template_auto != 201606
+# error "__cpp_template_auto != 201606"
+#endif
+
+#ifndef __cpp_inline_variables
+# error "__cpp_inline_variables"
+#elif __cpp_inline_variables != 201606
+# error "__cpp_inline_variables != 201606"
+#endif
+
+#ifndef __cpp_capture_star_this
+# error "__cpp_capture_star_this"
+#elif __cpp_capture_star_this != 201603
+# error "__cpp_capture_star_this != 201603"
+#endif
+
+#ifndef __cpp_noexcept_function_type
+# error "__cpp_noexcept_function_type"
+#elif __cpp_noexcept_function_type != 201510
+# error "__cpp_noexcept_function_type != 201510"
+#endif
+
+#ifndef __cpp_structured_bindings
+# error "__cpp_structured_bindings"
+#elif __cpp_structured_bindings != 201606
+# error "__cpp_structured_bindings != 201606"
+#endif
+
+#ifndef __cpp_template_template_args
+# error "__cpp_template_template_args"
+#elif __cpp_template_template_args != 201611
+# error "__cpp_template_template_args != 201611"
+#endif
+
+#ifndef __cpp_variadic_using
+# error "__cpp_variadic_using"
+#elif __cpp_variadic_using != 201611
+# error "__cpp_variadic_using != 201611"
+#endif
+
+#ifndef __cpp_guaranteed_copy_elision
+# error "__cpp_guaranteed_copy_elision"
+#elif __cpp_guaranteed_copy_elision != 201606
+# error "__cpp_guaranteed_copy_elision != 201606"
+#endif
+
+#ifndef __cpp_nontype_template_parameter_auto
+# error "__cpp_nontype_template_parameter_auto"
+#elif __cpp_nontype_template_parameter_auto != 201606
+# error "__cpp_nontype_template_parameter_auto != 201606"
+#endif
+
+// C++20 features:
+
+#ifndef __cpp_conditional_explicit
+# error "__cpp_conditional_explicit"
+#elif __cpp_conditional_explicit != 201806
+# error "__cpp_conditional_explicit != 201806"
+#endif
+
+#ifndef __cpp_nontype_template_parameter_class
+# error "__cpp_nontype_template_parameter_class"
+#elif __cpp_nontype_template_parameter_class != 201806
+# error "__cpp_nontype_template_parameter_class != 201806"
+#endif
+
+#ifndef __cpp_impl_destroying_delete
+# error "__cpp_impl_destroying_delete"
+#elif __cpp_impl_destroying_delete != 201806
+# error "__cpp_impl_destroying_delete != 201806"
+#endif
+
+#ifndef __cpp_constinit
+# error "__cpp_constinit"
+#elif __cpp_constinit != 201907
+# error "__cpp_constinit != 201907"
+#endif
+
+#ifndef __cpp_constexpr_dynamic_alloc
+# error "__cpp_constexpr_dynamic_alloc"
+#elif __cpp_constexpr_dynamic_alloc != 201907
+# error "__cpp_constexpr_dynamic_alloc != 201907"
+#endif
+
+#ifndef __cpp_aggregate_paren_init
+# error "__cpp_aggregate_paren_init"
+#elif __cpp_aggregate_paren_init != 201902
+# error "__cpp_aggregate_paren_init != 201902"
+#endif
+
+#ifndef __cpp_char8_t
+# error "__cpp_char8_t"
+#elif __cpp_char8_t != 202207
+# error "__cpp_char8_t != 202207"
+#endif
+
+#ifndef __cpp_designated_initializers
+# error "__cpp_designated_initializers"
+#elif __cpp_designated_initializers != 201707
+# error "__cpp_designated_initializers != 201707"
+#endif
+
+#ifndef __cpp_constexpr_in_decltype
+# error "__cpp_constexpr_in_decltype"
+#elif __cpp_constexpr_in_decltype != 201711
+# error "__cpp_constexpr_in_decltype != 201711"
+#endif
+
+#ifndef __cpp_consteval
+# error "__cpp_consteval"
+#elif __cpp_consteval != 201811
+# error "__cpp_consteval != 201811"
+#endif
+
+#ifndef __cpp_concepts
+# error "__cpp_concepts"
+#elif __cpp_concepts != 202002
+# error "__cpp_concepts != 202002"
+#endif
+
+#ifndef __cpp_using_enum
+# error "__cpp_using_enum"
+#elif __cpp_using_enum != 201907
+# error "__cpp_using_enum != 201907"
+#endif
+
+// C++20 attributes:
+
+#ifdef __has_cpp_attribute
+
+# if ! __has_cpp_attribute(maybe_unused)
+# error "__has_cpp_attribute(maybe_unused)"
+# elif __has_cpp_attribute(maybe_unused) != 201603
+# error "__has_cpp_attribute(maybe_unused) != 201603"
+# endif
+
+# if ! __has_cpp_attribute(nodiscard)
+# error "__has_cpp_attribute(nodiscard)"
+# elif __has_cpp_attribute(nodiscard) != 201907
+# error "__has_cpp_attribute(nodiscard) != 201907"
+# endif
+
+# if ! __has_cpp_attribute(fallthrough)
+# error "__has_cpp_attribute(fallthrough)"
+# elif __has_cpp_attribute(fallthrough) != 201603
+# error "__has_cpp_attribute(fallthrough) != 201603"
+# endif
+
+# if ! __has_cpp_attribute(no_unique_address)
+# error "__has_cpp_attribute(no_unique_address)"
+# elif __has_cpp_attribute(no_unique_address) != 201803
+# error "__has_cpp_attribute(no_unique_address) != 201803"
+# endif
+
+# if ! __has_cpp_attribute(likely)
+# error "__has_cpp_attribute(likely)"
+# elif __has_cpp_attribute(likely) != 201803
+# error "__has_cpp_attribute(likely) != 201803"
+# endif
+
+# if ! __has_cpp_attribute(unlikely)
+# error "__has_cpp_attribute(unlikely)"
+# elif __has_cpp_attribute(unlikely) != 201803
+# error "__has_cpp_attribute(unlikely) != 201803"
+# endif
+
+#else
+# error "__has_cpp_attribute"
+#endif
+
+// C++23 features:
+
+#ifndef __cpp_size_t_suffix
+# error "__cpp_size_t_suffix"
+#elif __cpp_size_t_suffix != 202011
+# error "__cpp_size_t_suffix != 202011"
+#endif
+
+#ifndef __cpp_if_consteval
+# error "__cpp_if_consteval"
+#elif __cpp_if_consteval != 202106
+# error "__cpp_if_consteval != 202106"
+#endif
+
+#ifndef __cpp_multidimensional_subscript
+# error "__cpp_multidimensional_subscript"
+#elif __cpp_multidimensional_subscript != 202211
+# error "__cpp_multidimensional_subscript != 202211"
+#endif
+
+#ifndef __cpp_named_character_escapes
+# error "__cpp_named_character_escapes"
+#elif __cpp_named_character_escapes != 202207
+# error "__cpp_named_character_escapes != 202207"
+#endif
+
+#ifndef __cpp_static_call_operator
+# error "__cpp_static_call_operator"
+#elif __cpp_static_call_operator != 202207
+# error "__cpp_static_call_operator != 202207"
+#endif
+
+#ifndef __cpp_implicit_move
+# error "__cpp_implicit_move"
+#elif __cpp_implicit_move != 202207
+# error "__cpp_implicit_move != 202207"
+#endif
+
+#ifndef __cpp_auto_cast
+# error "__cpp_auto_cast"
+#elif __cpp_auto_cast != 202110
+# error "__cpp_auto_cast != 202110"
+#endif
+
+// C++23 attributes:
+
+#ifdef __has_cpp_attribute
+# if ! __has_cpp_attribute(assume)
+# error "__has_cpp_attribute(assume)"
+# elif __has_cpp_attribute(assume) != 202207
+# error "__has_cpp_attribute(assume) != 202207"
+# endif
+#else
+# error "__has_cpp_attribute"
+#endif
diff --git a/gcc/testsuite/g++.dg/diagnostic/missing-header-pr110164.C b/gcc/testsuite/g++.dg/diagnostic/missing-header-pr110164.C
new file mode 100644
index 0000000..1598007
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/missing-header-pr110164.C
@@ -0,0 +1,10 @@
+// { dg-require-effective-target c++11 }
+
+#include <map>
+
+std::array<int, 10> a1; /* { dg-error "incomplete type" } */
+/* { dg-message "'std::array' is defined in header '<array>'; this is probably fixable by adding '#include <array>'" "hint" { target *-*-* } .-1 } */
+
+std::array<int, 10> a2 {5}; /* { dg-error "incomplete type" } */
+/* { dg-message "'std::array' is defined in header '<array>'; this is probably fixable by adding '#include <array>'" "hint" { target *-*-* } .-1 } */
+
diff --git a/gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C b/gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C
index caf8afa..56f15609 100644
--- a/gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C
+++ b/gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C
@@ -1,6 +1,6 @@
// { dg-do compile { target c++14 } }
-template<typename> int A; // { dg-message "24:variable template" }
+template<typename=int> int A; // { dg-message "28:variable template" }
template int A<>(); // { dg-error "14:template<class>" }
diff --git a/gcc/testsuite/g++.dg/opt/pr66119.C b/gcc/testsuite/g++.dg/opt/pr66119.C
index 5b420c2..c129633 100644
--- a/gcc/testsuite/g++.dg/opt/pr66119.C
+++ b/gcc/testsuite/g++.dg/opt/pr66119.C
@@ -3,7 +3,7 @@
the value of MOVE_RATIO now is. */
/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && c++11 } } } */
-/* { dg-options "-O3 -mavx -fdump-tree-sra -march=slm -mtune=slm" } */
+/* { dg-options "-O3 -mavx -fdump-tree-sra -march=slm -mtune=slm -fno-early-inlining" } */
#include <immintrin.h>
diff --git a/gcc/testsuite/g++.dg/parse/error56.C b/gcc/testsuite/g++.dg/parse/error56.C
index bd3d27e..7c81ab4 100644
--- a/gcc/testsuite/g++.dg/parse/error56.C
+++ b/gcc/testsuite/g++.dg/parse/error56.C
@@ -2,5 +2,4 @@
template <0> int __copy_streambufs_eof; // { dg-error "" }
class {
-// { dg-error "forbids" "" { target *-*-* } .+1 }
friend __copy_streambufs_eof <> ( // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/parse/template30.C b/gcc/testsuite/g++.dg/parse/template30.C
index fa89889..3bd7dda 100644
--- a/gcc/testsuite/g++.dg/parse/template30.C
+++ b/gcc/testsuite/g++.dg/parse/template30.C
@@ -29,8 +29,7 @@ qux ()
{
return z<A<int>>=0; // { dg-error "'>>=' should be '>> =' to terminate a template argument list" "" { target c++11 } }
} // { dg-error "'>>=' should be '> > =' to terminate a template argument list" "" { target c++98_only } .-1 }
- // { dg-error "parse error in template argument list" "" { target *-*-* } .-2 }
- // { dg-error "template argument 1 is invalid" "" { target *-*-* } .-3 }
+ // { dg-error "template argument 1 is invalid" "" { target *-*-* } .-2 }
void
quux ()
diff --git a/gcc/testsuite/g++.dg/template/nontype12.C b/gcc/testsuite/g++.dg/template/nontype12.C
index 6642ffd..9a9c3ac 100644
--- a/gcc/testsuite/g++.dg/template/nontype12.C
+++ b/gcc/testsuite/g++.dg/template/nontype12.C
@@ -4,7 +4,7 @@
template<typename T> struct A
{
template<T> int foo(); // { dg-error "double" "" { target c++17_down } }
- template<template<T> class> int bar(); // { dg-bogus {double.*C:7:[^\n]*double} }
+ template<template<T> class> int bar(); // { dg-bogus {double[^\n]*\n[^\n]*C:7:[^\n]*double} "" { xfail c++17_down } }
// { dg-error "double" "" { target c++17_down } .-1 }
template<T> struct X; // { dg-error "double" "" { target c++17_down } }
};
diff --git a/gcc/testsuite/g++.dg/torture/pr110308.C b/gcc/testsuite/g++.dg/torture/pr110308.C
new file mode 100644
index 0000000..36c6d38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr110308.C
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+int channelCount, decodeBlock_outputLength;
+struct BlockCodec {
+ virtual int decodeBlock(const unsigned char *, short *);
+};
+struct ms_adpcm_state {
+ char predictorIndex;
+ int sample1;
+ ms_adpcm_state();
+};
+bool decodeBlock_ok;
+void encodeBlock() { ms_adpcm_state(); }
+struct MSADPCM : BlockCodec {
+ int decodeBlock(const unsigned char *, short *);
+};
+void decodeSample(ms_adpcm_state, bool *);
+int MSADPCM::decodeBlock(const unsigned char *, short *) {
+ ms_adpcm_state decoderState[2];
+ ms_adpcm_state *state[2];
+ state[0] = &decoderState[0];
+ if (channelCount == 2)
+ state[1] = &decoderState[0];
+ short m_coefficients[state[1]->predictorIndex];
+ for (int i = 0; i < channelCount; i++)
+ ++state[i]->sample1;
+ decodeSample(*state[1], &decodeBlock_ok);
+ return decodeBlock_outputLength;
+} \ No newline at end of file
diff --git a/gcc/testsuite/g++.target/powerpc/pr105325.C b/gcc/testsuite/g++.target/powerpc/pr105325.C
new file mode 100644
index 0000000..18a2e52
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/pr105325.C
@@ -0,0 +1,28 @@
+/* { dg-do assemble } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-require-effective-target powerpc_prefixed_addr } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -fstack-protector" } */
+
+/* PR target/105324. Test that power10 fusion does not generate an LWA/CMPDI
+ with a large offset that the assembler rejects. Instead it should a
+ PLWZ/CMPWI combination.
+
+ Originally, the code was dying because the fusion load + compare -1/0/1
+ patterns did not handle the possibility that the load might be prefixed.
+ The -fstack-protector option is needed to show the bug. */
+
+struct Ath__array1D {
+ int _current;
+ int getCnt() { return _current; }
+};
+struct extMeasure {
+ int _mapTable[10000];
+ Ath__array1D _metRCTable;
+};
+void measureRC() {
+ extMeasure m;
+ for (; m._metRCTable.getCnt();)
+ for (;;)
+ ;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c b/gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c
new file mode 100644
index 0000000..0652bd4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c
@@ -0,0 +1,26 @@
+
+/* { dg-do compile } */
+/* PR middle-end/110420 */
+/* PR middle-end/103979 */
+/* PR middle-end/98619 */
+/* Test that the middle-end does not remove the asm goto
+ with an output. */
+
+static int t;
+void g(void);
+
+void f(void)
+{
+ int __gu_val;
+ asm goto("#my asm "
+ : "=&r"(__gu_val)
+ :
+ :
+ : Efault);
+ t = __gu_val;
+ g();
+Efault:
+}
+
+/* Make sure "my asm " is still in the assembly. */
+/* { dg-final { scan-assembler "my asm " } } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr110334.c b/gcc/testsuite/gcc.c-torture/compile/pr110334.c
new file mode 100644
index 0000000..5524bf6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr110334.c
@@ -0,0 +1,20 @@
+int n;
+typedef void (*fnptr)();
+fnptr get_me();
+__attribute__ ((always_inline))
+inline void test(void)
+{
+ if (n < 10)
+ (get_me())();
+ n++;
+ return;
+}
+fnptr get_me()
+{
+ return test;
+}
+void
+foo()
+{
+ test();
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr110444-1.c b/gcc/testsuite/gcc.c-torture/compile/pr110444-1.c
new file mode 100644
index 0000000..1cdb400
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr110444-1.c
@@ -0,0 +1,11 @@
+/* This used to ICE after SLP during match-and-simplify
+ as real_can_shorten_arithmetic was called with the vector
+ mode. */
+void f(float *a, float *b, float *c, int size)
+{
+ float t[2];
+ t[0] = b[0] - (float)__builtin_pow(c[0], 2);
+ t[1] = b[1] - (float)__builtin_pow(c[1], 2);
+ a[0] = t[0];
+ a[1] = t[1];
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-1.c b/gcc/testsuite/gcc.c-torture/execute/20230630-1.c
new file mode 100644
index 0000000..7c1f15c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-1.c
@@ -0,0 +1,23 @@
+struct S {
+ short int i : 12;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+};
+
+int main (void)
+{
+ struct S s0 = { 341, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 85)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 21)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-2.c b/gcc/testsuite/gcc.c-torture/execute/20230630-2.c
new file mode 100644
index 0000000..c05c166
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-2.c
@@ -0,0 +1,29 @@
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define REVERSE_SSO __attribute__((scalar_storage_order("big-endian")));
+#else
+#define REVERSE_SSO __attribute__((scalar_storage_order("little-endian")));
+#endif
+
+struct S {
+ short int i : 12;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+} REVERSE_SSO;
+
+int main (void)
+{
+ struct S s0 = { 341, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 21)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 85)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-3.c b/gcc/testsuite/gcc.c-torture/execute/20230630-3.c
new file mode 100644
index 0000000..fc106c9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-3.c
@@ -0,0 +1,27 @@
+struct S {
+ int i : 24;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+ char c5 : 1;
+ char c6 : 1;
+ char c7 : 1;
+ char c8 : 1;
+};
+
+int main (void)
+{
+ struct S s0 = { 1193046, 1, 1, 1, 1, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 86)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 18)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-4.c b/gcc/testsuite/gcc.c-torture/execute/20230630-4.c
new file mode 100644
index 0000000..df33c18
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-4.c
@@ -0,0 +1,33 @@
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define REVERSE_SSO __attribute__((scalar_storage_order("big-endian")));
+#else
+#define REVERSE_SSO __attribute__((scalar_storage_order("little-endian")));
+#endif
+
+struct S {
+ int i : 24;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+ char c5 : 1;
+ char c6 : 1;
+ char c7 : 1;
+ char c8 : 1;
+} REVERSE_SSO;
+
+int main (void)
+{
+ struct S s0 = { 1193046, 1, 1, 1, 1, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 18)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 86)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Wtraditional-conversion-3.c b/gcc/testsuite/gcc.dg/Wtraditional-conversion-3.c
new file mode 100644
index 0000000..796f2eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wtraditional-conversion-3.c
@@ -0,0 +1,9 @@
+/* { dg-options "-Wtraditional-conversion -Wno-psabi" } */
+
+typedef int __attribute__((__vector_size__ (4))) V;
+
+void
+foo (V v)
+{
+ foo (v);
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
new file mode 100644
index 0000000..60078e1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
@@ -0,0 +1,134 @@
+/* PR 101832:
+ GCC extension accepts the case when a struct with a C99 flexible array
+ member is embedded into another struct (possibly recursively).
+ __builtin_object_size will treat such struct as flexible size.
+ However, when a structure with non-C99 flexible array member, i.e, trailing
+ [0], [1], or [4], is embedded into anther struct, the stucture will not
+ be treated as flexible size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+
+#define expect(p, _v) do { \
+ size_t v = _v; \
+ if (p == v) \
+ __builtin_printf ("ok: %s == %zd\n", #p, p); \
+ else {\
+ __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \
+ FAIL (); \
+ } \
+} while (0);
+
+
+struct A {
+ int n;
+ char data[];
+};
+
+struct B {
+ int m;
+ struct A a;
+};
+
+struct C {
+ int q;
+ struct B b;
+};
+
+struct A0 {
+ int n;
+ char data[0];
+};
+
+struct B0 {
+ int m;
+ struct A0 a;
+};
+
+struct C0 {
+ int q;
+ struct B0 b;
+};
+
+struct A1 {
+ int n;
+ char data[1];
+};
+
+struct B1 {
+ int m;
+ struct A1 a;
+};
+
+struct C1 {
+ int q;
+ struct B1 b;
+};
+
+struct An {
+ int n;
+ char data[8];
+};
+
+struct Bn {
+ int m;
+ struct An a;
+};
+
+struct Cn {
+ int q;
+ struct Bn b;
+};
+
+volatile void *magic1, *magic2;
+
+int main (int argc, char *argv[])
+{
+ struct B *outer;
+ struct C *outest;
+
+ /* Make sure optimization can't find some other object size. */
+ outer = (void *)magic1;
+ outest = (void *)magic2;
+
+ expect (__builtin_object_size (&outer->a, 1), -1);
+ expect (__builtin_object_size (&outest->b, 1), -1);
+ expect (__builtin_object_size (&outest->b.a, 1), -1);
+
+ struct B0 *outer0;
+ struct C0 *outest0;
+
+ /* Make sure optimization can't find some other object size. */
+ outer0 = (void *)magic1;
+ outest0 = (void *)magic2;
+
+ expect (__builtin_object_size (&outer0->a, 1), sizeof (outer0->a));
+ expect (__builtin_object_size (&outest0->b, 1), sizeof (outest0->b));
+ expect (__builtin_object_size (&outest0->b.a, 1), sizeof (outest0->b.a));
+
+ struct B1 *outer1;
+ struct C1 *outest1;
+
+ /* Make sure optimization can't find some other object size. */
+ outer1 = (void *)magic1;
+ outest1 = (void *)magic2;
+
+ expect (__builtin_object_size (&outer1->a, 1), sizeof (outer1->a));
+ expect (__builtin_object_size (&outest1->b, 1), sizeof (outest1->b));
+ expect (__builtin_object_size (&outest1->b.a, 1), sizeof (outest1->b.a));
+
+ struct Bn *outern;
+ struct Cn *outestn;
+
+ /* Make sure optimization can't find some other object size. */
+ outern = (void *)magic1;
+ outestn = (void *)magic2;
+
+ expect (__builtin_object_size (&outern->a, 1), sizeof (outern->a));
+ expect (__builtin_object_size (&outestn->b, 1), sizeof (outestn->b));
+ expect (__builtin_object_size (&outestn->b.a, 1), sizeof (outestn->b.a));
+
+ DONE ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr109849.c b/gcc/testsuite/gcc.dg/ipa/pr109849.c
new file mode 100644
index 0000000..09b62f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr109849.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fdump-ipa-inline-details" } */
+void bad (void);
+void
+test(int a)
+{
+ if (__builtin_expect (a>3, 0))
+ {
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ }
+}
+void
+foo (int a)
+{
+ if (a>0)
+ __builtin_unreachable ();
+ test (a);
+}
+/* { dg-final { scan-ipa-dump "Inlined 2 calls" "inline" } } */
+/* { dg-final { scan-ipa-dump "Inlining test" "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr110377.c b/gcc/testsuite/gcc.dg/ipa/pr110377.c
new file mode 100644
index 0000000..63120a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr110377.c
@@ -0,0 +1,16 @@
+/* { dg-do compile */
+/* { dg-options "-O2 -fdump-ipa-cp" } */
+int test3(int);
+__attribute__ ((noinline))
+void test2(int a)
+{
+ test3(a);
+}
+void
+test(int n)
+{
+ if (n > 5)
+ __builtin_unreachable ();
+ test2(n);
+}
+/* { dg-final { scan-ipa-dump "-INF, 5" "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/crash-test-ice-sarif.c b/gcc/testsuite/gcc.dg/plugin/crash-test-ice-sarif.c
index 3b773a9..84a4347 100644
--- a/gcc/testsuite/gcc.dg/plugin/crash-test-ice-sarif.c
+++ b/gcc/testsuite/gcc.dg/plugin/crash-test-ice-sarif.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fdiagnostics-format=sarif-file" } */
+/* { dg-additional-options "-fno-report-bug" } */
extern void inject_ice (void);
@@ -56,7 +57,7 @@ void test_inject_ice (void)
{ dg-final { scan-sarif-file "\"contextRegion\": " } }
{ dg-final { scan-sarif-file "\"artifactLocation\": " } }
{ dg-final { scan-sarif-file "\"region\": " } }
- { dg-final { scan-sarif-file "\"startLine\": 8" } }
+ { dg-final { scan-sarif-file "\"startLine\": 9" } }
{ dg-final { scan-sarif-file "\"startColumn\": 3" } }
{ dg-final { scan-sarif-file "\"endColumn\": 16" } }
{ dg-final { scan-sarif-file "\"message\": " } }
diff --git a/gcc/testsuite/gcc.dg/plugin/crash-test-ice-stderr.c b/gcc/testsuite/gcc.dg/plugin/crash-test-ice-stderr.c
index cee701b..0064d3b 100644
--- a/gcc/testsuite/gcc.dg/plugin/crash-test-ice-stderr.c
+++ b/gcc/testsuite/gcc.dg/plugin/crash-test-ice-stderr.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-fno-report-bug" } */
extern void inject_ice (void);
diff --git a/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-sarif.c b/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-sarif.c
index 57caa20..83b38d2 100644
--- a/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-sarif.c
+++ b/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-sarif.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fdiagnostics-format=sarif-file" } */
+/* { dg-additional-options "-fno-report-bug" } */
extern void inject_write_through_null (void);
@@ -56,7 +57,7 @@ void test_inject_write_through_null (void)
{ dg-final { scan-sarif-file "\"contextRegion\": " } }
{ dg-final { scan-sarif-file "\"artifactLocation\": " } }
{ dg-final { scan-sarif-file "\"region\": " } }
- { dg-final { scan-sarif-file "\"startLine\": 8" } }
+ { dg-final { scan-sarif-file "\"startLine\": 9" } }
{ dg-final { scan-sarif-file "\"startColumn\": 3" } }
{ dg-final { scan-sarif-file "\"endColumn\": 31" } }
{ dg-final { scan-sarif-file "\"message\": " } }
diff --git a/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-stderr.c b/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-stderr.c
index 7b43e42..a9a211a 100644
--- a/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-stderr.c
+++ b/gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-stderr.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-fno-report-bug" } */
extern void inject_write_through_null (void);
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c
index 27c341b..58b219b 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.c
@@ -2,6 +2,7 @@
/* This plugin exercises the text_art code. */
+#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
diff --git a/gcc/testsuite/gcc.dg/pr110436.c b/gcc/testsuite/gcc.dg/pr110436.c
new file mode 100644
index 0000000..8e63ca0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110436.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include "pr83089.c"
diff --git a/gcc/testsuite/gcc.dg/pr110461.c b/gcc/testsuite/gcc.dg/pr110461.c
new file mode 100644
index 0000000..cd23a2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110461.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+typedef int v4si __attribute__ ((vector_size (4*sizeof(int))));
+typedef short v4hi __attribute__ ((vector_size (4*sizeof(short))));
+
+v4hi res;
+v4hi a, b;
+
+void f(void)
+{
+ v4si t = __builtin_convertvector (a, v4si);
+ v4si t1 = __builtin_convertvector (b, v4si);
+ t ^= t1;
+ res = __builtin_convertvector (t, v4hi);
+}
diff --git a/gcc/testsuite/gcc.dg/pr110496.c b/gcc/testsuite/gcc.dg/pr110496.c
new file mode 100644
index 0000000..3c3d12f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110496.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long contents, f_num;
+int decide();
+int f_MV0__x;
+void f() {
+ unsigned char *rptr;
+ unsigned char valbuf[6];
+ rptr = (unsigned char *)contents;
+ if (decide())
+ do {
+ __builtin_memcpy(valbuf, &f_MV0__x, sizeof(int));
+ (&valbuf[0])[4] = (&valbuf[0])[5] = 0;
+ } while (0);
+ else {
+ int MV0__x = f_num;
+ __builtin_memcpy(valbuf, &MV0__x, sizeof(int));
+ (&valbuf[0])[4] = (&valbuf[0])[5] = 0;
+ }
+ rptr[1] = valbuf[4];
+ rptr[2] = valbuf[5];
+ rptr[4] = valbuf[1];
+ rptr[5] = valbuf[2];
+ __builtin_memset(valbuf, 0, 8);
+}
diff --git a/gcc/testsuite/gcc.dg/pr110506-2.c b/gcc/testsuite/gcc.dg/pr110506-2.c
new file mode 100644
index 0000000..aabca0fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110506-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned uint32_t;
+typedef uint32_t uint32x4 __attribute__((vector_size(16)));
+typedef struct {
+ uint32x4 b, d;
+} prng_t;
+prng_t prng_rand_128_r_x;
+int main_flags;
+int main() {
+ uint32_t ref_crc[] = {7, 3};
+ uint32x4 e = (prng_rand_128_r_x.b << 27) + (prng_rand_128_r_x.b >> 32 - 27);
+ prng_rand_128_r_x.d = e;
+ if (ref_crc[main_flags])
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr110506.c b/gcc/testsuite/gcc.dg/pr110506.c
new file mode 100644
index 0000000..10dbd4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110506.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct {
+ long *sp;
+ long *csp;
+} neko_interp_loop_vm;
+int neko_interp_loop_vm_2;
+void neko_interp_loop()
+{
+ void *pc[] = {&&LabelAccGlobal, &&LabelPhysCompare, &&LabelTailCall,
+ &&LabelLoop, &&LabelMakeArray2};
+ long *sp, *csp = neko_interp_loop_vm.csp;
+LabelAccGlobal:
+ neko_interp_loop_vm.sp = sp;
+ neko_interp_loop_vm.csp = csp;
+ goto * 0;
+LabelTailCall:
+ csp = sp -= neko_interp_loop_vm_2;
+LabelMakeArray2:
+LabelPhysCompare:
+LabelLoop:
+ goto * 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr110508.c b/gcc/testsuite/gcc.dg/pr110508.c
new file mode 100644
index 0000000..a1f8f55
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110508.c
@@ -0,0 +1,9 @@
+/* PR tree-optimization/110508 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+foo (unsigned a, unsigned b, unsigned *c, _Bool d)
+{
+ __builtin_addc (a, b, d, c);
+}
diff --git a/gcc/testsuite/gcc.dg/predict-18.c b/gcc/testsuite/gcc.dg/predict-18.c
index 0c93638..073e742 100644
--- a/gcc/testsuite/gcc.dg/predict-18.c
+++ b/gcc/testsuite/gcc.dg/predict-18.c
@@ -8,6 +8,8 @@ int x;
short v = 0;
short expected = 0;
short max = ~0;
+short m = 0;
+short n = 0;
#define STRONG 0
void foo (int a, int b)
@@ -23,9 +25,17 @@ void foo (int a, int b)
if (__builtin_expect_with_probability (a < 10, 1, 0.9f) > __builtin_expect_with_probability (b, 0, 0.8f))
global++;
+
+ if (a * __builtin_expect_with_probability (m, 0, 0.6f) > 0)
+ global++;
+
+ if (__builtin_expect_with_probability (n, 0, 0.65f) * a > 0)
+ global++;
}
/* { dg-final { scan-tree-dump "__builtin_expect_with_probability heuristics of edge .*->.*: 54.00%" "profile_estimate"} } */
/* { dg-final { scan-tree-dump "__builtin_expect_with_probability heuristics of edge .*->.*: 77.70%" "profile_estimate"} } */
/* { dg-final { scan-tree-dump "__builtin_expect_with_probability heuristics of edge .*->.*: 98.96%" "profile_estimate"} } */
/* { dg-final { scan-tree-dump "__builtin_expect_with_probability heuristics of edge .*->.*: 71.99%" "profile_estimate"} } */
+/* { dg-final { scan-tree-dump "__builtin_expect_with_probability heuristics of edge .*->.*: 40.00%" "profile_estimate"} } */
+/* { dg-final { scan-tree-dump "__builtin_expect_with_probability heuristics of edge .*->.*: 35.01%" "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c
new file mode 100644
index 0000000..571a311
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target powerpc*-*-linux* } } */
+/* { dg-skip-if "" { has_arch_ppc64 } } */
+/* { dg-options "-O2 -mregnames" } */
+
+/* Following instruction sequence is found in assembly of
+ Perl_block_start, which is a function of op.c in SPEC2017
+ perlbench. It can be never combined to a move and compare
+ instruction in combine pass. A peephole pattern is needed to
+ converted the sequence to a "mr." instruction.
+
+ cmpdi 0,9,0
+ mr 12,9
+
+ This test case is an analogue of the source code and verifies
+ if the peephole2 patterns work.
+*/
+
+int __RTL (startwith ("peephole2")) compare_move_peephole ()
+{
+(function "compare_move_peephole"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+ (cinsn 8 (set (reg:CC %cr0)
+ (compare:CC (reg:SI %r3)
+ (const_int 0))))
+ (cinsn 2 (set (reg:SI %r4)
+ (reg:SI %r3)))
+ ;; Extra insn to avoid the above being deleted by DCE.
+ (cinsn 18 (use (reg:SI %r4)))
+ (cinsn 19 (use (reg:CC %cr0)))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("peephole2")) move_compare_peephole ()
+{
+(function "move_compare_peephole"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+ (cinsn 2 (set (reg:SI %r4)
+ (reg:SI %r3)))
+ (cinsn 8 (set (reg:CC %cr0)
+ (compare:CC (reg:SI %r3)
+ (const_int 0))))
+ ;; Extra insn to avoid the above being deleted by DCE.
+ (cinsn 18 (use (reg:SI %r4)))
+ (cinsn 19 (use (reg:CC %cr0)))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function "main"
+}
+
+/* { dg-final { scan-assembler-times {\mmr\.} 2 } } */
diff --git a/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c
new file mode 100644
index 0000000..e25d655
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target powerpc*-*-linux* } } */
+/* { dg-options "-O2 -mregnames" } */
+/* { dg-require-effective-target has_arch_ppc64 } */
+
+/* Following instruction sequence is found in assembly of
+ Perl_block_start, which is a function of op.c in SPEC2017
+ perlbench. It can be never combined to a move and compare
+ instruction in combine pass. A peephole pattern is needed to
+ converted the sequence to a "mr." instruction.
+
+ cmpdi 0,9,0
+ mr 12,9
+
+ This test case is an analogue of the source code and verifies
+ if the peephole2 patterns work.
+*/
+
+int __RTL (startwith ("peephole2")) compare_move_peephole ()
+{
+(function "compare_move_peephole"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+ (cinsn 8 (set (reg:CC %cr0)
+ (compare:CC (reg:DI %r3)
+ (const_int 0))))
+ (cinsn 2 (set (reg:DI %r4)
+ (reg:DI %r3)))
+ ;; Extra insn to avoid the above being deleted by DCE.
+ (cinsn 18 (use (reg:DI %r4)))
+ (cinsn 19 (use (reg:CC %cr0)))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("peephole2")) move_compare_peephole ()
+{
+(function "move_compare_peephole"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+ (cinsn 2 (set (reg:DI %r4)
+ (reg:DI %r3)))
+ (cinsn 8 (set (reg:CC %cr0)
+ (compare:CC (reg:DI %r3)
+ (const_int 0))))
+ ;; Extra insn to avoid the above being deleted by DCE.
+ (cinsn 18 (use (reg:DI %r4)))
+ (cinsn 19 (use (reg:CC %cr0)))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function "main"
+}
+
+/* { dg-final { scan-assembler-times {\mmr\.} 2 } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr110228.c b/gcc/testsuite/gcc.dg/torture/pr110228.c
new file mode 100644
index 0000000..add9f17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr110228.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target x86_64-*-* i?86-*-* } } */
+/* { dg-require-effective-target lp64 } */
+
+unsigned a[4] = {1,1,1,1};
+unsigned tt1 = 0;
+
+__attribute__((noipa))
+static void bug(unsigned * p, unsigned *t, int n, int t2)
+{
+ for(int i = 0; i < n; i++)
+ {
+ _Bool LookupFlags ;
+ unsigned v = t[i];
+ unsigned tt = tt1;
+ if (v == 0)
+ LookupFlags = 0;
+ else if (v == 1)
+ LookupFlags = 1;
+ if (LookupFlags) {
+ tt|=3u;
+ LookupFlags = 0;
+ }
+ asm("movq $-1, %q1":"+a"(LookupFlags));
+ *p = tt;
+ }
+}
+
+int main()
+{
+ unsigned r = 42;
+ bug(&r,a, sizeof(a)/sizeof(a[0]), 1);
+ __builtin_printf("%u\n", r);
+ if (r != 3) __builtin_abort();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr110376.c b/gcc/testsuite/gcc.dg/torture/pr110376.c
new file mode 100644
index 0000000..86bfe80
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr110376.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+int f, g, a, c;
+unsigned char k = 204;
+unsigned char *l = &k;
+short m, n;
+static long b;
+unsigned *h = &c;
+unsigned **i = &h;
+int p(unsigned char *aa) {
+ aa[0] && aa[1] && aa[2];
+ return 1;
+}
+int q(unsigned char c) {
+ unsigned char d[] = {c};
+ int e = p(d);
+ return e;
+}
+int r(int j, int h) {
+ f = h / 4;
+ g = f * 6;
+ return g;
+}
+short s() { return **i; }
+void t() {
+ for (; r(9, *l) <= 1;) {
+ int j;
+ long *o = &b;
+ *o = 0 >= 0;
+ for (; q(0) + a > 1; a++)
+ *o = 0 > m;
+ j = s();
+ for (; a;)
+ n = j;
+ for (; (unsigned char)(1 + k + b) + k; --k)
+ ;
+ }
+}
+int main() { t(); }
diff --git a/gcc/testsuite/gcc.dg/torture/pr110443.c b/gcc/testsuite/gcc.dg/torture/pr110443.c
new file mode 100644
index 0000000..61cf705
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr110443.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+typedef struct {
+ float real;
+ float imag;
+} complex_t;
+extern unsigned char fftorder[];
+float *a52_imdct_256_data;
+int a52_imdct_256_i, a52_imdct_256_k;
+float a52_imdct_256_b_r;
+void a52_imdct_256()
+{
+ complex_t buf1[64];
+ a52_imdct_256_i = 0;
+ for (; a52_imdct_256_i < 64; a52_imdct_256_i++) {
+ a52_imdct_256_k = fftorder[a52_imdct_256_i];
+ buf1[a52_imdct_256_i].real = buf1[a52_imdct_256_i].imag =
+ a52_imdct_256_data[a52_imdct_256_k];
+ }
+ a52_imdct_256_b_r = buf1[0].real * buf1[0].imag;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr110491.c b/gcc/testsuite/gcc.dg/torture/pr110491.c
new file mode 100644
index 0000000..00b3bdf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr110491.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+int a, c, d, e;
+short b;
+void f(int *g) { c &= *g; }
+void h(void);
+void i() {
+ a = 1;
+ h();
+ f(&a);
+}
+void h() {
+ int *j = &c;
+ *j = 5;
+k:
+ for (; 4 + b <= 0;)
+ ;
+ for (; d;) {
+ c = e == 0;
+ goto k;
+ }
+}
+int main()
+{
+ i();
+ if (c != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c b/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c
index 696f459..537d15d 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c
@@ -181,4 +181,4 @@ main (void)
exit (0);
}
-/* { dg-final-use-not-autofdo { scan-tree-dump-not "Invalid sum" "dom2" { xfail *-*-* } } } */
+/* { dg-final-use-not-autofdo { scan-tree-dump-not "Invalid sum" "dom2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c b/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
index 39aa032..8c05911 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
@@ -12,4 +12,5 @@ void k(S*x){
*x = (S)(y + __INT_MAX__);
}
+/* { dg-final { scan-tree-dump "4294967294" "optimized" { target int32plus } } } */
/* { dg-final { scan-tree-dump-not "2147483647" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
index 9775a4c..6c71a4f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
@@ -33,7 +33,9 @@ void i (V *v1, V *v2){
*v2 = (c1-*v2)+c2;
}
-/* { dg-final { scan-tree-dump-not "\\\+" "forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "\\\+" 1 "forwprop1"} } */
/* { dg-final { scan-tree-dump "{ 0, 4 }" "forwprop1"} } */
/* { dg-final { scan-tree-dump "{ 37, -5 }" "forwprop1"} } */
+/* { dg-final { scan-tree-dump "{ 27, 23 }" "forwprop1"} } */
+/* { dg-final { scan-tree-dump "{ 37, 3 }" "forwprop1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-20040816-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-20040816-1.c
index f8a6495..b55a533 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ifc-20040816-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-20040816-1.c
@@ -39,4 +39,4 @@ int main1 ()
which is folded by vectorizer. Both outgoing edges must have probability
100% so the resulting profile match after folding. */
/* { dg-final { scan-tree-dump-times "Invalid sum of outgoing probabilities 200.0" 1 "ifcvt" } } */
-/* { dg-final { scan-tree-dump-times "Invalid sum of incoming counts" 2 "ifcvt" } } */
+/* { dg-final { scan-tree-dump-times "Invalid sum of incoming counts" 1 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c
new file mode 100644
index 0000000..e8bab62
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ch2-blocks-details -fdump-tree-optimized" } */
+void foo ();
+void test(int v, int q)
+{
+ for (int i = 0; i < 10 && v/q; i++)
+ foo ();
+}
+/* { dg-final { scan-tree-dump-not "Invalid sum" "ch2"} } */
+/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c
new file mode 100644
index 0000000..99d22ba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ch2-blocks-details -fdump-tree-optimized" } */
+void foo ();
+void test()
+{
+ for (int i = 0; i < 10; i++)
+ foo ();
+}
+/* We should figure out that after header dulication loop iterates 9 times. */
+/* { dg-final { scan-tree-dump "90.00" "ch2"} } */
+/* { dg-final { scan-tree-dump "10.00" "ch2"} } */
+/* { dg-final { scan-tree-dump-not "Invalid sum" "ch2"} } */
+/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr103680.c b/gcc/testsuite/gcc.dg/tree-ssa/pr103680.c
new file mode 100644
index 0000000..30599fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr103680.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized-details-blocks -fno-early-inlining" } */
+void foo ();
+static void
+test (int i)
+{
+ if (__builtin_expect_with_probability (i > 5, 1, 0.6))
+ foo ();
+}
+void
+test2(int i)
+{
+ test (i);
+ if (__builtin_expect_with_probability (i > 4, 1, 0.7))
+ foo ();
+}
+/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110334.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110334.c
new file mode 100644
index 0000000..bc085d4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110334.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-release_ssa" } */
+int a;
+int ret1()
+{
+ return a;
+}
+int inline
+__attribute__((always_inline)) aret1()
+{
+ return ret1();
+}
+int test()
+{
+ return aret1();
+}
+/* { dg-final { scan-tree-dump-not "= ret1" "release_ssa" } } */
diff --git a/gcc/testsuite/gcc.dg/uninit-pr101912.c b/gcc/testsuite/gcc.dg/uninit-pr101912.c
index 62cd2a0..cb7d751 100644
--- a/gcc/testsuite/gcc.dg/uninit-pr101912.c
+++ b/gcc/testsuite/gcc.dg/uninit-pr101912.c
@@ -11,7 +11,7 @@ tzloadbody (void)
for (int i = 0; i < n; i++)
{
int corr = getint ();
- if (corr < 1 || (corr == 1 && !(leapcnt == 0 || (prevcorr < corr ? corr == prevcorr + 1 : (corr == prevcorr || corr == prevcorr - 1))))) /* { dg-bogus "uninitialized" "pr101912" { xfail *-*-* } } */
+ if (corr < 1 || (corr == 1 && !(leapcnt == 0 || (prevcorr < corr ? corr == prevcorr + 1 : (corr == prevcorr || corr == prevcorr - 1))))) /* { dg-bogus "uninitialized" "pr101912" } */
return -1;
prevcorr = corr;
diff --git a/gcc/testsuite/gcc.dg/variable-sized-type-flex-array.c b/gcc/testsuite/gcc.dg/variable-sized-type-flex-array.c
new file mode 100644
index 0000000..3924937
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/variable-sized-type-flex-array.c
@@ -0,0 +1,31 @@
+/* Test for -Wflex-array-member-not-at-end on structure/union with
+ C99 flexible array members being embedded into another structure. */
+/* { dg-do compile } */
+/* { dg-options "-Wflex-array-member-not-at-end" } */
+
+struct flex { int n; int data[]; };
+struct out_flex_end { int m; struct flex flex_data; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+struct out_flex_mid { struct flex flex_data; int m; }; /* { dg-warning "structure containing a flexible array member is not at the end of another structure" } */
+/* since the warning has been issued for out_flex_mid, no need to
+ issue warning again when it is included in another structure/union. */
+struct outer_flex_mid { struct out_flex_mid out_flex_data; int p; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+union flex_union_mid { int a; struct outer_flex_mid b; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+
+
+struct flex0 { int n; int data[0]; };
+struct out_flex_end0 { int m; struct flex0 flex_data; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+struct out_flex_mid0 { struct flex0 flex_data; int m; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+struct outer_flex_mid0 { struct out_flex_mid0 out_flex_data; int p; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+union flex_union_mid0 { int a; struct outer_flex_mid0 b; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+
+struct flex1 { int n; int data[1]; };
+struct out_flex_end1 { int m; struct flex1 flex_data; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+struct out_flex_mid1 { struct flex1 flex_data; int m; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+struct outer_flex_mid1 { struct out_flex_mid1 out_flex_data; int p; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+union flex_union_mid1 { int a; struct outer_flex_mid1 b; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+
+struct flexn { int n; int data[8]; };
+struct out_flex_endn { int m; struct flexn flex_data; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
+struct out_flex_midn { struct flexn flex_data; int m; }; /* { dg-bogus"structure containing a flexible array member is not at the end of another structure" } */
+struct outer_flex_midn { struct out_flex_midn out_flex_data; int p; }; /* { dg-bogus"structure containing a flexible array member is not at the end of another structure" } */
+union flex_union_midn { int a; struct outer_flex_midn b; }; /* { dg-bogus "structure containing a flexible array member is not at the end of another structure" } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
index ee12136..8cefa7f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
@@ -24,11 +24,17 @@ void rephase (void)
struct site *s;
for(i=0,s=lattice;i<sites_on_node;i++,s++)
for(dir=0;dir<32;dir++)
- for(j=0;j<3;j++)for(k=0;k<3;k++)
- {
- s->link[dir].e[j][k].real *= s->phase[dir];
- s->link[dir].e[j][k].imag *= s->phase[dir];
- }
+ {
+ for(j=0;j<3;j++)
+ for(k=0;k<3;k++)
+ {
+ s->link[dir].e[j][k].real *= s->phase[dir];
+ s->link[dir].e[j][k].imag *= s->phase[dir];
+ }
+ /* Avoid loop vectorizing the outer loop after unrolling
+ the inners. */
+ __asm__ volatile ("" : : : "memory");
+ }
}
int main()
diff --git a/gcc/testsuite/gcc.dg/vect/pr110381.c b/gcc/testsuite/gcc.dg/vect/pr110381.c
new file mode 100644
index 0000000..ee78666
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr110381.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_float_strict } */
+
+#include "tree-vect.h"
+
+struct FOO {
+ double a;
+ double b;
+ double c;
+};
+
+double __attribute__((noipa))
+sum_8_foos(const struct FOO* foos)
+{
+ double sum = 0;
+
+ for (int i = 0; i < 8; ++i)
+ {
+ struct FOO foo = foos[i];
+
+ /* Need to use an in-order reduction here, preserving
+ the load permutation. */
+ sum += foo.a;
+ sum += foo.c;
+ sum += foo.b;
+ }
+
+ return sum;
+}
+
+int main()
+{
+ struct FOO foos[8];
+
+ check_vect ();
+
+ __builtin_memset (foos, 0, sizeof (foos));
+ foos[0].a = __DBL_MAX__;
+ foos[0].b = 5;
+ foos[0].c = -__DBL_MAX__;
+
+ if (sum_8_foos (foos) != 5)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/slp-46.c b/gcc/testsuite/gcc.dg/vect/slp-46.c
index 18476a4..79ed0bb 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-46.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-46.c
@@ -94,4 +94,4 @@ main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { xfail vect_load_lanes } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { xfail vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-12.c b/gcc/testsuite/gcc.dg/vect/slp-perm-12.c
index 113223a..635fca5 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-12.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-12.c
@@ -1,5 +1,6 @@
/* { dg-require-effective-target vect_int } */
/* { dg-require-effective-target vect_pack_trunc } */
+/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
/* { dg-additional-options "-msse4" { target { i?86-*-* x86_64-*-* } } } */
#include "tree-vect.h"
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
index 154c00a..f1f5d4f 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
@@ -3,11 +3,7 @@
#include <stdarg.h>
#include "tree-vect.h"
-#if VECTOR_BITS > 512
#define N (VECTOR_BITS * 6 / 16)
-#else
-#define N 200
-#endif
void __attribute__((noinline))
foo (unsigned short *__restrict__ pInput, unsigned short *__restrict__ pOutput)
diff --git a/gcc/testsuite/gcc.misc-tests/outputs.exp b/gcc/testsuite/gcc.misc-tests/outputs.exp
index 7ee3550..9f44cbd 100644
--- a/gcc/testsuite/gcc.misc-tests/outputs.exp
+++ b/gcc/testsuite/gcc.misc-tests/outputs.exp
@@ -50,7 +50,15 @@ if !$skip_lto {
set ltop [check_linker_plugin_available]
}
-# Check for GNU LD. Some files like .ld1_args depend on this.
+# Check for GNU LD. Some files like .ld1_args depend on this. This
+# should really be testing whether HAVE_GNU_LD was set by configure.
+# If we find GNU ld here, but the compiler wasn't configured
+# --with-gnu-ld or with DEFAULT_LINKER pointing at GNU ld, on a target
+# that doesn't set gnu_ld=yes unconditionally, configure and thus
+# collect2 will conservatively assume there's no support for @file in
+# the linker, but our atfile tests will expect ld1_args files to be
+# created, and thus fail. Configuring the compiler --with-gnu-ld
+# fixes this.
set gld [check_effective_target_gld]
# Prepare additional options to be used for linking.
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_2.c b/gcc/testsuite/gcc.target/aarch64/abd_2.c
index c0d41fb..02256c0 100644
--- a/gcc/testsuite/gcc.target/aarch64/abd_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/abd_2.c
@@ -11,25 +11,46 @@ TEST1(signed, int)
TEST1(signed, short)
TEST1(signed, char)
-TEST2(signed, char, short)
-TEST2(signed, char, int)
-TEST2(signed, short, int)
+TEST2(signed, short, char)
+TEST2(signed, int, short)
+TEST2(signed, int, char)
+TEST2(signed, int, long)
+TEST3(signed, char, short, char)
+TEST3(signed, char, int, long)
TEST3(signed, char, int, short)
-TEST3(signed, char, short, int)
+TEST3(signed, char, int, char)
+
+TEST3(signed, short, int, char)
+TEST3(signed, short, char, short)
+TEST3(signed, short, int, short)
+TEST3(signed, short, int, long)
+
+TEST3(signed, int, char, short)
+TEST3(signed, int, short, char)
+TEST3(signed, int, char, int)
+TEST3(signed, int, short, int)
+TEST3(signed, int, char, long)
+TEST3(signed, int, short, long)
TEST1(unsigned, short)
TEST1(unsigned, char)
-TEST2(unsigned, char, short)
-TEST2(unsigned, char, int)
+TEST2(unsigned, short, char)
+
+TEST3(unsigned, char, short, char)
+TEST3(unsigned, short, char, short)
-TEST3(unsigned, char, short, int)
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 48 } } */
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 7 } } */
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 5 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 4 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
-/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 3 } } */
-/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 7 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_3.c b/gcc/testsuite/gcc.target/aarch64/abd_3.c
index 4873c64..cc601ac 100644
--- a/gcc/testsuite/gcc.target/aarch64/abd_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/abd_3.c
@@ -11,26 +11,46 @@ TEST1(signed, int)
TEST1(signed, short)
TEST1(signed, char)
-TEST2(signed, char, short)
-TEST2(signed, char, int)
-TEST2(signed, short, int)
+TEST2(signed, short, char)
+TEST2(signed, int, short)
+TEST2(signed, int, char)
+TEST2(signed, int, long)
+TEST3(signed, char, short, char)
+TEST3(signed, char, int, long)
TEST3(signed, char, int, short)
-TEST3(signed, char, short, int)
+TEST3(signed, char, int, char)
+
+TEST3(signed, short, int, char)
+TEST3(signed, short, char, short)
+TEST3(signed, short, int, short)
+TEST3(signed, short, int, long)
+
+TEST3(signed, int, char, short)
+TEST3(signed, int, short, char)
+TEST3(signed, int, char, int)
+TEST3(signed, int, short, int)
+TEST3(signed, int, char, long)
+TEST3(signed, int, short, long)
TEST1(unsigned, short)
TEST1(unsigned, char)
-TEST2(unsigned, char, short)
-TEST2(unsigned, char, int)
-TEST2(unsigned, short, int)
+TEST2(unsigned, short, char)
+
+TEST3(unsigned, char, short, char)
+TEST3(unsigned, short, char, short)
-TEST3(unsigned, char, short, int)
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 48 } } */
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 7 } } */
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 5 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 4 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
-/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 4 } } */
-/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 7 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_4.c b/gcc/testsuite/gcc.target/aarch64/abd_4.c
index 98aa730..9e078f1 100644
--- a/gcc/testsuite/gcc.target/aarch64/abd_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/abd_4.c
@@ -9,22 +9,20 @@
TEST1(signed, int)
-TEST2(signed, char, short)
-TEST2(signed, char, int)
-TEST2(signed, short, int)
-
-TEST3(signed, char, short, int)
-
-TEST2(unsigned, char, short)
-TEST2(unsigned, char, int)
-TEST2(unsigned, short, int)
-
-TEST3(unsigned, char, short, int)
-
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 1 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 3 } } */
-/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 2 } } */
-/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 3 } } */
-/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 2 } } */
-
+TEST3(signed, int, char, int)
+TEST3(signed, int, short, int)
+
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 7 } } */
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 0 } } */
+/* { dg-final { scan-assembler-times "sabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 0 } } */
+
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 0:w
+ } } */
+
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_none_2.c b/gcc/testsuite/gcc.target/aarch64/abd_none_2.c
index 658e742..d7ef2c1 100644
--- a/gcc/testsuite/gcc.target/aarch64/abd_none_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/abd_none_2.c
@@ -7,8 +7,81 @@
#define ABD_ABS
#include "abd.h"
+TEST1(signed, long)
+
+TEST2(signed, long, char)
+TEST2(signed, long, short)
+TEST2(signed, long, int)
+
+TEST3(signed, char, long, short)
+TEST3(signed, char, long, int)
+TEST3(signed, char, long, char)
+
+TEST3(signed, short, long, char)
+TEST3(signed, short, long, int)
+TEST3(signed, short, long, short)
+
+TEST3(signed, int, long, char)
+TEST3(signed, int, long, short)
+TEST3(signed, int, long, int)
+
+TEST3(signed, long, char, short)
+TEST3(signed, long, short, char)
+TEST3(signed, long, char, int)
+TEST3(signed, long, int, char)
+TEST3(signed, long, short, int)
+TEST3(signed, long, int, short)
+TEST3(signed, long, char, long)
+TEST3(signed, long, short, long)
+TEST3(signed, long, int, long)
+
TEST1(unsigned, int)
+TEST1(unsigned, long)
+
+TEST2(unsigned, int, long)
+
+TEST2(unsigned, long, char)
+TEST2(unsigned, long, short)
+TEST2(unsigned, long, int)
+TEST2(unsigned, int, short)
+TEST2(unsigned, int, char)
+
TEST3(unsigned, char, int, short)
+TEST3(unsigned, char, long, short)
+TEST3(unsigned, char, int, long)
+TEST3(unsigned, char, long, int)
+TEST3(unsigned, char, int, char)
+
+TEST3(unsigned, short, int, char)
+TEST3(unsigned, short, long, char)
+TEST3(unsigned, short, int, long)
+TEST3(unsigned, short, long, int)
+TEST3(unsigned, short, int, short)
+TEST3(unsigned, short, long, short)
+
+TEST3(unsigned, int, char, short)
+TEST3(unsigned, int, short, char)
+TEST3(unsigned, int, char, long)
+TEST3(unsigned, int, long, char)
+TEST3(unsigned, int, short, long)
+TEST3(unsigned, int, long, short)
+TEST3(unsigned, int, char, int)
+TEST3(unsigned, int, short, int)
+TEST3(unsigned, int, long, int)
+
+TEST3(unsigned, long, char, short)
+TEST3(unsigned, long, short, char)
+TEST3(unsigned, long, char, int)
+TEST3(unsigned, long, int, char)
+TEST3(unsigned, long, short, int)
+TEST3(unsigned, long, int, short)
+TEST3(unsigned, long, char, long)
+TEST3(unsigned, long, short, long)
+TEST3(unsigned, long, int, long)
/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_none_3.c b/gcc/testsuite/gcc.target/aarch64/abd_none_3.c
index 14cfdcb..f23dd7d 100644
--- a/gcc/testsuite/gcc.target/aarch64/abd_none_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/abd_none_3.c
@@ -7,8 +7,81 @@
#define ABD_ABS
#include "abd.h"
+TEST1(signed, long)
+
+TEST2(signed, long, char)
+TEST2(signed, long, short)
+TEST2(signed, long, int)
+
+TEST3(signed, char, long, short)
+TEST3(signed, char, long, int)
+TEST3(signed, char, long, char)
+
+TEST3(signed, short, long, char)
+TEST3(signed, short, long, int)
+TEST3(signed, short, long, short)
+
+TEST3(signed, int, long, char)
+TEST3(signed, int, long, short)
+TEST3(signed, int, long, int)
+
+TEST3(signed, long, char, short)
+TEST3(signed, long, short, char)
+TEST3(signed, long, char, int)
+TEST3(signed, long, int, char)
+TEST3(signed, long, short, int)
+TEST3(signed, long, int, short)
+TEST3(signed, long, char, long)
+TEST3(signed, long, short, long)
+TEST3(signed, long, int, long)
+
TEST1(unsigned, int)
+TEST1(unsigned, long)
+
+TEST2(unsigned, int, long)
+
+TEST2(unsigned, long, char)
+TEST2(unsigned, long, short)
+TEST2(unsigned, long, int)
+TEST2(unsigned, int, short)
+TEST2(unsigned, int, char)
+
TEST3(unsigned, char, int, short)
+TEST3(unsigned, char, long, short)
+TEST3(unsigned, char, int, long)
+TEST3(unsigned, char, long, int)
+TEST3(unsigned, char, int, char)
+
+TEST3(unsigned, short, int, char)
+TEST3(unsigned, short, long, char)
+TEST3(unsigned, short, int, long)
+TEST3(unsigned, short, long, int)
+TEST3(unsigned, short, int, short)
+TEST3(unsigned, short, long, short)
+
+TEST3(unsigned, int, char, short)
+TEST3(unsigned, int, short, char)
+TEST3(unsigned, int, char, long)
+TEST3(unsigned, int, long, char)
+TEST3(unsigned, int, short, long)
+TEST3(unsigned, int, long, short)
+TEST3(unsigned, int, char, int)
+TEST3(unsigned, int, short, int)
+TEST3(unsigned, int, long, int)
+
+TEST3(unsigned, long, char, short)
+TEST3(unsigned, long, short, char)
+TEST3(unsigned, long, char, int)
+TEST3(unsigned, long, int, char)
+TEST3(unsigned, long, short, int)
+TEST3(unsigned, long, int, short)
+TEST3(unsigned, long, char, long)
+TEST3(unsigned, long, short, long)
+TEST3(unsigned, long, int, long)
/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_none_4.c b/gcc/testsuite/gcc.target/aarch64/abd_none_4.c
index d612216..f5cfc5d 100644
--- a/gcc/testsuite/gcc.target/aarch64/abd_none_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/abd_none_4.c
@@ -9,14 +9,98 @@
TEST1(signed, short)
TEST1(signed, char)
+TEST1(signed, long)
+
+TEST2(signed, long, char)
+TEST2(signed, long, short)
+TEST2(signed, long, int)
+TEST2(signed, int, short)
+TEST2(signed, int, char)
+TEST2(signed, short, char)
TEST3(signed, char, int, short)
+TEST3(signed, char, long, short)
+TEST3(signed, char, long, int)
+TEST3(signed, char, short, char)
+TEST3(signed, char, int, char)
+TEST3(signed, char, long, char)
+
+TEST3(signed, short, int, char)
+TEST3(signed, short, long, char)
+TEST3(signed, short, long, int)
+TEST3(signed, short, char, short)
+TEST3(signed, short, int, short)
+TEST3(signed, short, long, short)
+
+TEST3(signed, int, char, short)
+TEST3(signed, int, short, char)
+TEST3(signed, int, long, char)
+TEST3(signed, int, long, short)
+TEST3(signed, int, long, int)
+
+TEST3(signed, long, char, short)
+TEST3(signed, long, short, char)
+TEST3(signed, long, char, int)
+TEST3(signed, long, int, char)
+TEST3(signed, long, short, int)
+TEST3(signed, long, int, short)
+TEST3(signed, long, char, long)
+TEST3(signed, long, short, long)
+TEST3(signed, long, int, long)
TEST1(unsigned, int)
TEST1(unsigned, short)
TEST1(unsigned, char)
+TEST1(unsigned, long)
+
+TEST2(unsigned, int, long)
+
+TEST2(unsigned, long, char)
+TEST2(unsigned, long, short)
+TEST2(unsigned, long, int)
+TEST2(unsigned, int, short)
+TEST2(unsigned, int, char)
+TEST2(unsigned, short, char)
TEST3(unsigned, char, int, short)
+TEST3(unsigned, char, long, short)
+TEST3(unsigned, char, int, long)
+TEST3(unsigned, char, long, int)
+TEST3(unsigned, char, short, char)
+TEST3(unsigned, char, int, char)
+TEST3(unsigned, char, long, char)
+
+TEST3(unsigned, short, int, char)
+TEST3(unsigned, short, long, char)
+TEST3(unsigned, short, int, long)
+TEST3(unsigned, short, long, int)
+TEST3(unsigned, short, char, short)
+TEST3(unsigned, short, int, short)
+TEST3(unsigned, short, long, short)
+
+TEST3(unsigned, int, char, short)
+TEST3(unsigned, int, short, char)
+TEST3(unsigned, int, char, long)
+TEST3(unsigned, int, long, char)
+TEST3(unsigned, int, short, long)
+TEST3(unsigned, int, long, short)
+TEST3(unsigned, int, char, int)
+TEST3(unsigned, int, short, int)
+TEST3(unsigned, int, long, int)
+
+TEST3(unsigned, long, char, short)
+TEST3(unsigned, long, short, char)
+TEST3(unsigned, long, char, int)
+TEST3(unsigned, long, int, char)
+TEST3(unsigned, long, short, int)
+TEST3(unsigned, long, int, short)
+TEST3(unsigned, long, char, long)
+TEST3(unsigned, long, short, long)
+TEST3(unsigned, long, int, long)
/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_run_1.c b/gcc/testsuite/gcc.target/aarch64/abd_run_1.c
index 7bb0a80..1bfd6ac 100644
--- a/gcc/testsuite/gcc.target/aarch64/abd_run_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/abd_run_1.c
@@ -11,10 +11,17 @@ TEST1(signed, int)
TEST1(signed, short)
TEST1(signed, char)
+TEST2(signed, char, short)
+TEST2(signed, short, int)
+TEST2(signed, int, long)
+
TEST1(unsigned, int)
TEST1(unsigned, short)
TEST1(unsigned, char)
+TEST2(unsigned, char, short)
+TEST2(unsigned, short, int)
+
#define EMPTY { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
#define sA { -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50 }
#define uA { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }
@@ -27,6 +34,8 @@ typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
+typedef signed long s64;
+typedef unsigned long u64;
s8 sc_out[] = EMPTY;
u8 uc_out[] = EMPTY;
@@ -34,6 +43,8 @@ s16 ss_out[] = EMPTY;
u16 us_out[] = EMPTY;
s32 si_out[] = EMPTY;
u32 ui_out[] = EMPTY;
+s64 sl_out[] = EMPTY;
+u64 ul_out[] = EMPTY;
s8 sc_A[] = sA;
s8 sc_B[] = B;
@@ -56,6 +67,8 @@ s16 ss_gold[] = GOLD;
u16 us_gold[] = GOLD;
s32 si_gold[] = GOLD;
u32 ui_gold[] = GOLD;
+s64 sl_gold[] = GOLD;
+u64 ul_gold[] = GOLD;
extern void abort (void);
@@ -88,6 +101,22 @@ int main ()
fn_unsigned_int (ui_A, ui_B, ui_out);
COMPARE (ui_out, ui_gold);
+
+ fn_signed_char_char_short (sc_B, sc_A, ss_out);
+ COMPARE(ss_gold, ss_out);
+
+ fn_signed_short_short_int (ss_A, ss_B, si_out);
+ COMPARE(si_gold, si_out);
+
+ fn_signed_int_int_long (si_B, si_A, sl_out);
+ COMPARE(sl_gold, sl_out);
+
+ fn_unsigned_char_char_short (uc_B, uc_A, us_out);
+ COMPARE(us_gold, us_out);
+
+ fn_unsigned_short_short_int (us_A, us_B, ui_out);
+ COMPARE(ui_gold, ui_out);
+
return 0;
}
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_widen_2.c b/gcc/testsuite/gcc.target/aarch64/abd_widen_2.c
new file mode 100644
index 0000000..1be1e40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/abd_widen_2.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#pragma GCC target "+nosve"
+#define N 1024
+
+#define ABD_ABS
+#include "abd.h"
+
+TEST2(signed, char, short)
+TEST2(signed, char, int)
+TEST2(signed, char, long)
+TEST2(signed, short, int)
+TEST2(signed, short, long)
+
+TEST3(signed, char, short, int)
+TEST3(signed, char, short, long)
+
+TEST3(signed, short, char, int)
+TEST3(signed, short, char, long)
+
+TEST2(unsigned, char, short)
+TEST2(unsigned, char, int)
+TEST2(unsigned, char, long)
+TEST2(unsigned, short, int)
+TEST2(unsigned, short, long)
+
+TEST3(unsigned, char, short, int)
+TEST3(unsigned, char, short, long)
+
+TEST3(unsigned, short, char, int)
+TEST3(unsigned, short, char, long)
+
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.2d, v\[0-9\]+\.2s, v\[0-9\]+\.2s" 0 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.2d, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.4s, v\[0-9\]+\.4h, v\[0-9\]+\.4h" 10 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.4s, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 10 } } */
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.8h, v\[0-9\]+\.8b, v\[0-9\]+\.8b" 3 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.8h, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.2d, v\[0-9\]+\.2s, v\[0-9\]+\.2s" 0 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.2d, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.4s, v\[0-9\]+\.4h, v\[0-9\]+\.4h" 10 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.4s, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 10 } } */
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.8h, v\[0-9\]+\.8b, v\[0-9\]+\.8b" 3 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.8h, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+
+/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_widen_3.c b/gcc/testsuite/gcc.target/aarch64/abd_widen_3.c
new file mode 100644
index 0000000..ff6ee8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/abd_widen_3.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+
+#pragma GCC target "arch=armv8-a"
+#define N 1024
+
+#define ABD_ABS
+#include "abd.h"
+
+TEST2(signed, char, short)
+TEST2(signed, char, int)
+TEST2(signed, char, long)
+TEST2(signed, short, int)
+TEST2(signed, short, long)
+
+TEST3(signed, char, short, int)
+TEST3(signed, char, short, long)
+
+TEST3(signed, short, char, int)
+TEST3(signed, short, char, long)
+
+TEST2(unsigned, char, short)
+TEST2(unsigned, char, int)
+TEST2(unsigned, char, long)
+TEST2(unsigned, short, int)
+TEST2(unsigned, short, long)
+
+TEST3(unsigned, char, short, int)
+TEST3(unsigned, char, short, long)
+
+TEST3(unsigned, short, char, int)
+TEST3(unsigned, short, char, long)
+
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.2d, v\[0-9\]+\.2s, v\[0-9\]+\.2s" 0 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.2d, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.4s, v\[0-9\]+\.4h, v\[0-9\]+\.4h" 10 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.4s, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 10 } } */
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.8h, v\[0-9\]+\.8b, v\[0-9\]+\.8b" 3 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.8h, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.2d, v\[0-9\]+\.2s, v\[0-9\]+\.2s" 0 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.2d, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.4s, v\[0-9\]+\.4h, v\[0-9\]+\.4h" 10 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.4s, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 10 } } */
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.8h, v\[0-9\]+\.8b, v\[0-9\]+\.8b" 3 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.8h, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+
+/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/abd_widen_4.c b/gcc/testsuite/gcc.target/aarch64/abd_widen_4.c
new file mode 100644
index 0000000..298b1c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/abd_widen_4.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#pragma GCC target "+nosve"
+#define N 1024
+
+#define ABD_IDIOM
+#include "abd.h"
+
+TEST2(signed, char, short)
+TEST2(signed, char, int)
+TEST2(signed, char, long)
+TEST2(signed, short, int)
+TEST2(signed, short, long)
+TEST2(signed, int, long)
+
+TEST3(signed, char, short, int)
+TEST3(signed, char, short, long)
+TEST3(signed, char, int, long)
+
+TEST3(signed, short, char, int)
+TEST3(signed, short, char, long)
+TEST3(signed, short, int, long)
+
+TEST3(signed, int, char, long)
+TEST3(signed, int, short, long)
+
+TEST2(unsigned, char, short)
+TEST2(unsigned, char, int)
+TEST2(unsigned, char, long)
+TEST2(unsigned, short, int)
+TEST2(unsigned, short, long)
+
+TEST3(unsigned, char, short, int)
+TEST3(unsigned, char, short, long)
+
+TEST3(unsigned, short, char, int)
+TEST3(unsigned, short, char, long)
+
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.2d, v\[0-9\]+\.2s, v\[0-9\]+\.2s" 13 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.2d, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 13 } } */
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.4s, v\[0-9\]+\.4h, v\[0-9\]+\.4h" 10 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.4s, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 10 } } */
+/* { dg-final { scan-assembler-times "sabdl\\tv\[0-9\]+\.8h, v\[0-9\]+\.8b, v\[0-9\]+\.8b" 3 } } */
+/* { dg-final { scan-assembler-times "sabdl2\\tv\[0-9\]+\.8h, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.2d, v\[0-9\]+\.2s, v\[0-9\]+\.2s" 0 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.2d, v\[0-9\]+\.4s, v\[0-9\]+\.4s" 0 } } */
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.4s, v\[0-9\]+\.4h, v\[0-9\]+\.4h" 10 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.4s, v\[0-9\]+\.8h, v\[0-9\]+\.8h" 10 } } */
+/* { dg-final { scan-assembler-times "uabdl\\tv\[0-9\]+\.8h, v\[0-9\]+\.8b, v\[0-9\]+\.8b" 3 } } */
+/* { dg-final { scan-assembler-times "uabdl2\\tv\[0-9\]+\.8h, v\[0-9\]+\.16b, v\[0-9\]+\.16b" 3 } } */
+
+/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr110371.c b/gcc/testsuite/gcc.target/aarch64/pr110371.c
new file mode 100644
index 0000000..444e514e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr110371.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef struct dest
+{
+ double m[3][3];
+} dest;
+
+typedef struct src
+{
+ int m[3][3];
+} src;
+
+void
+foo (dest *a, src* s)
+{
+ for (int i = 0; i != 3; i++)
+ for (int j = 0; j != 3; j++)
+ a->m[i][j] = s->m[i][j];
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/abd_1.c b/gcc/testsuite/gcc.target/aarch64/sve/abd_1.c
index e49006f..4f48240 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/abd_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/abd_1.c
@@ -10,26 +10,69 @@ TEST1(signed, int)
TEST1(signed, short)
TEST1(signed, char)
-TEST2(signed, char, int)
TEST2(signed, char, short)
+TEST2(signed, char, int)
+TEST2(signed, char, long)
TEST2(signed, short, int)
+TEST2(signed, short, long)
+TEST2(signed, int, long)
+
+TEST2(signed, int, short)
+TEST2(signed, int, char)
+TEST2(signed, short, char)
-TEST3(signed, char, int, short)
TEST3(signed, char, short, int)
+TEST3(signed, char, int, short)
+TEST3(signed, char, short, long)
+TEST3(signed, char, int, long)
+TEST3(signed, char, short, char)
+TEST3(signed, char, int, char)
+
+TEST3(signed, short, char, int)
+TEST3(signed, short, int, char)
+TEST3(signed, short, char, long)
+TEST3(signed, short, int, long)
+TEST3(signed, short, char, short)
+TEST3(signed, short, int, short)
+
+TEST3(signed, int, char, short)
+TEST3(signed, int, short, char)
+TEST3(signed, int, char, long)
+TEST3(signed, int, short, long)
+TEST3(signed, int, char, int)
+TEST3(signed, int, short, int)
TEST1(unsigned, short)
TEST1(unsigned, char)
TEST2(unsigned, char, short)
TEST2(unsigned, char, int)
+TEST2(unsigned, char, long)
TEST2(unsigned, short, int)
+TEST2(unsigned, short, long)
+
+TEST2(unsigned, short, char)
TEST3(unsigned, char, short, int)
+TEST3(unsigned, char, short, long)
+TEST3(unsigned, char, short, char)
+
+TEST3(unsigned, short, char, int)
+TEST3(unsigned, short, char, long)
+TEST3(unsigned, short, char, short)
+
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.d, p\[0-9\]/m, z\[0-9\]+\.d, z\[0-9\]+\.d" 0 } } */
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.s, p\[0-9\]/m, z\[0-9\]+\.s, z\[0-9\]+\.s" 16 } } */
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 10 } } */
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 4 } } */
-/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.s, p\[0-9\]/m, z\[0-9\]+\.s, z\[0-9\]+\.s" 2 } } */
-/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 3 } } */
-/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 3 } } */
-/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 3 } } */
-/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 3 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.d, p\[0-9\]/m, z\[0-9\]+\.d, z\[0-9\]+\.d" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.s, p\[0-9\]/m, z\[0-9\]+\.s, z\[0-9\]+\.s" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 10 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 4 } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/abd_2.c b/gcc/testsuite/gcc.target/aarch64/sve/abd_2.c
index ea64fa8..ffa978a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/abd_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/abd_2.c
@@ -7,23 +7,56 @@
#include "../abd.h"
TEST1(signed, int)
+TEST1(signed, long)
-TEST2(signed, char, int)
TEST2(signed, char, short)
+TEST2(signed, char, int)
+TEST2(signed, char, long)
TEST2(signed, short, int)
+TEST2(signed, short, long)
+TEST2(signed, int, long)
TEST3(signed, char, short, int)
+TEST3(signed, char, short, long)
+TEST3(signed, char, int, long)
+
+TEST3(signed, short, char, int)
+TEST3(signed, short, char, long)
+TEST3(signed, short, int, long)
+
+TEST3(signed, int, char, long)
+TEST3(signed, int, short, long)
+TEST3(signed, int, char, int)
+TEST3(signed, int, short, int)
+
+TEST3(signed, long, char, long)
+TEST3(signed, long, short, long)
+TEST3(signed, long, int, long)
-TEST2(unsigned, char, int)
TEST2(unsigned, char, short)
+TEST2(unsigned, char, int)
+TEST2(unsigned, char, long)
TEST2(unsigned, short, int)
+TEST2(unsigned, short, long)
TEST3(unsigned, char, short, int)
+TEST3(unsigned, char, short, long)
+
+TEST3(unsigned, short, char, int)
+TEST3(unsigned, short, char, long)
+
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.d, p\[0-9\]/m, z\[0-9\]+\.d, z\[0-9\]+\.d" 4 } } */
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.s, p\[0-9\]/m, z\[0-9\]+\.s, z\[0-9\]+\.s" 8 } } */
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 6 } } */
+/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 3 } } */
-/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.s, p\[0-9\]/m, z\[0-9\]+\.s, z\[0-9\]+\.s" 1 } } */
-/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 2 } } */
-/* { dg-final { scan-assembler-times "sabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 2 } } */
-/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 2 } } */
-/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 2 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.d, p\[0-9\]/m, z\[0-9\]+\.d, z\[0-9\]+\.d" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.s, p\[0-9\]/m, z\[0-9\]+\.s, z\[0-9\]+\.s" 0 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.h, p\[0-9\]/m, z\[0-9\]+\.h, z\[0-9\]+\.h" 6 } } */
+/* { dg-final { scan-assembler-times "uabd\\tz\[0-9\]+\.b, p\[0-9\]/m, z\[0-9\]+\.b, z\[0-9\]+\.b" 3 } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tabs\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/abd_none_1.c b/gcc/testsuite/gcc.target/aarch64/sve/abd_none_1.c
index a4c2053c..1fb58b3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/abd_none_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/abd_none_1.c
@@ -6,8 +6,81 @@
#define ABD_ABS
#include "../abd.h"
+TEST1(signed, long)
+
+TEST2(signed, long, char)
+TEST2(signed, long, short)
+TEST2(signed, long, int)
+
+TEST3(signed, char, long, short)
+TEST3(signed, char, long, int)
+TEST3(signed, char, long, char)
+
+TEST3(signed, short, long, char)
+TEST3(signed, short, long, int)
+TEST3(signed, short, long, short)
+
+TEST3(signed, int, long, char)
+TEST3(signed, int, long, short)
+TEST3(signed, int, long, int)
+
+TEST3(signed, long, char, short)
+TEST3(signed, long, short, char)
+TEST3(signed, long, char, int)
+TEST3(signed, long, int, char)
+TEST3(signed, long, short, int)
+TEST3(signed, long, int, short)
+TEST3(signed, long, char, long)
+TEST3(signed, long, short, long)
+TEST3(signed, long, int, long)
+
TEST1(unsigned, int)
+TEST1(unsigned, long)
+
+TEST2(unsigned, int, long)
+
+TEST2(unsigned, long, char)
+TEST2(unsigned, long, short)
+TEST2(unsigned, long, int)
+TEST2(unsigned, int, short)
+TEST2(unsigned, int, char)
+
TEST3(unsigned, char, int, short)
+TEST3(unsigned, char, long, short)
+TEST3(unsigned, char, int, long)
+TEST3(unsigned, char, long, int)
+TEST3(unsigned, char, int, char)
+
+TEST3(unsigned, short, int, char)
+TEST3(unsigned, short, long, char)
+TEST3(unsigned, short, int, long)
+TEST3(unsigned, short, long, int)
+TEST3(unsigned, short, int, short)
+TEST3(unsigned, short, long, short)
+
+TEST3(unsigned, int, char, short)
+TEST3(unsigned, int, short, char)
+TEST3(unsigned, int, char, long)
+TEST3(unsigned, int, long, char)
+TEST3(unsigned, int, short, long)
+TEST3(unsigned, int, long, short)
+TEST3(unsigned, int, char, int)
+TEST3(unsigned, int, short, int)
+TEST3(unsigned, int, long, int)
+
+TEST3(unsigned, long, char, short)
+TEST3(unsigned, long, short, char)
+TEST3(unsigned, long, char, int)
+TEST3(unsigned, long, int, char)
+TEST3(unsigned, long, short, int)
+TEST3(unsigned, long, int, short)
+TEST3(unsigned, long, char, long)
+TEST3(unsigned, long, short, long)
+TEST3(unsigned, long, int, long)
/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/abd_none_2.c b/gcc/testsuite/gcc.target/aarch64/sve/abd_none_2.c
index 4862db9..a9465b5 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/abd_none_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/abd_none_2.c
@@ -9,13 +9,93 @@
TEST1(signed, short)
TEST1(signed, char)
+TEST2(signed, long, char)
+TEST2(signed, long, short)
+TEST2(signed, long, int)
+TEST2(signed, int, short)
+TEST2(signed, int, char)
+TEST2(signed, short, char)
+
TEST3(signed, char, int, short)
+TEST3(signed, char, long, short)
+TEST3(signed, char, long, int)
+TEST3(signed, char, short, char)
+TEST3(signed, char, int, char)
+TEST3(signed, char, long, char)
+
+TEST3(signed, short, int, char)
+TEST3(signed, short, long, char)
+TEST3(signed, short, long, int)
+TEST3(signed, short, char, short)
+TEST3(signed, short, int, short)
+TEST3(signed, short, long, short)
+
+TEST3(signed, int, char, short)
+TEST3(signed, int, short, char)
+TEST3(signed, int, long, char)
+TEST3(signed, int, long, short)
+TEST3(signed, int, long, int)
+
+TEST3(signed, long, char, short)
+TEST3(signed, long, short, char)
+TEST3(signed, long, char, int)
+TEST3(signed, long, int, char)
+TEST3(signed, long, short, int)
+TEST3(signed, long, int, short)
TEST1(unsigned, int)
TEST1(unsigned, short)
TEST1(unsigned, char)
+TEST1(unsigned, long)
+
+TEST2(unsigned, int, long)
+
+TEST2(unsigned, long, char)
+TEST2(unsigned, long, short)
+TEST2(unsigned, long, int)
+TEST2(unsigned, int, short)
+TEST2(unsigned, int, char)
+TEST2(unsigned, short, char)
TEST3(unsigned, char, int, short)
+TEST3(unsigned, char, long, short)
+TEST3(unsigned, char, int, long)
+TEST3(unsigned, char, long, int)
+TEST3(unsigned, char, short, char)
+TEST3(unsigned, char, int, char)
+TEST3(unsigned, char, long, char)
+
+TEST3(unsigned, short, int, char)
+TEST3(unsigned, short, long, char)
+TEST3(unsigned, short, int, long)
+TEST3(unsigned, short, long, int)
+TEST3(unsigned, short, char, short)
+TEST3(unsigned, short, int, short)
+TEST3(unsigned, short, long, short)
+
+TEST3(unsigned, int, char, short)
+TEST3(unsigned, int, short, char)
+TEST3(unsigned, int, char, long)
+TEST3(unsigned, int, long, char)
+TEST3(unsigned, int, short, long)
+TEST3(unsigned, int, long, short)
+TEST3(unsigned, int, char, int)
+TEST3(unsigned, int, short, int)
+TEST3(unsigned, int, long, int)
+
+TEST3(unsigned, long, char, short)
+TEST3(unsigned, long, short, char)
+TEST3(unsigned, long, char, int)
+TEST3(unsigned, long, int, char)
+TEST3(unsigned, long, short, int)
+TEST3(unsigned, long, int, short)
+TEST3(unsigned, long, char, long)
+TEST3(unsigned, long, short, long)
+TEST3(unsigned, long, int, long)
/* { dg-final { scan-assembler-not {\tsabd\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tsabdl2\t} } } */
/* { dg-final { scan-assembler-not {\tuabd\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl\t} } } */
+/* { dg-final { scan-assembler-not {\tuabdl2\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_11.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_11.c
new file mode 100644
index 0000000..f19f8de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_11.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+
+#include <arm_sve.h>
+#include <arm_neon.h>
+
+svint8_t f_s8(int8x16_t x)
+{
+ return svdupq_s8 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7],
+ x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]);
+}
+
+svint16_t f_s16(int16x8_t x)
+{
+ return svdupq_s16 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
+}
+
+svint32_t f_s32(int32x4_t x)
+{
+ return svdupq_s32 (x[0], x[1], x[2], x[3]);
+}
+
+svint64_t f_s64(int64x2_t x)
+{
+ return svdupq_s64 (x[0], x[1]);
+}
+
+/* { dg-final { scan-tree-dump "VEC_PERM_EXPR" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "svdupq" "optimized" } } */
+
+/* { dg-final { scan-assembler-times {\tdup\tz[0-9]+\.q, z[0-9]+\.q\[0\]\n} 4 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr110280.c b/gcc/testsuite/gcc.target/aarch64/sve/pr110280.c
new file mode 100644
index 0000000..d3279f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr110280.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+
+#include "arm_sve.h"
+
+svuint32_t l()
+{
+ _Alignas(16) const unsigned int lanes[4] = {0, 0, 0, 0};
+ return svld1rq_u32(svptrue_b8(), lanes);
+}
+
+/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/general-c/nomve_fp_1.c b/gcc/testsuite/gcc.target/arm/mve/general-c/nomve_fp_1.c
index 21c2af1..c9d279e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/general-c/nomve_fp_1.c
+++ b/gcc/testsuite/gcc.target/arm/mve/general-c/nomve_fp_1.c
@@ -1,9 +1,11 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-require-effective-target arm_fp_ok } */
/* Do not use dg-add-options arm_v8_1m_mve, because this might expand to "",
which could imply mve+fp depending on the user settings. We want to make
sure the '+fp' extension is not enabled. */
/* { dg-options "-mfpu=auto -march=armv8.1-m.main+mve" } */
+/* { dg-add-options arm_fp } */
#include <arm_mve.h>
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu1.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu1.c
index e375327..8358a61 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu1.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu1.c
@@ -12,4 +12,4 @@ foo1 (int8x16_t value)
return b;
}
-/* { dg-final { scan-assembler "\.fpu fpv5-sp-d16" } } */
+/* { dg-final { scan-assembler "\.fpu fpv5(-sp|)-d16" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu2.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu2.c
index 1fca110..5dd2fee 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu2.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu2.c
@@ -12,4 +12,4 @@ foo1 (int8x16_t value)
return b;
}
-/* { dg-final { scan-assembler "\.fpu fpv5-sp-d16" } } */
+/* { dg-final { scan-assembler "\.fpu fpv5(-sp|)-d16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/ashldi3-1.c b/gcc/testsuite/gcc.target/i386/ashldi3-1.c
new file mode 100644
index 0000000..b61d63b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/ashldi3-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2" } */
+
+long long foo(long long x, int y)
+{
+ long long t = (long long)y << 32;
+ return x ^ t;
+}
+
+long long bar(long long x, int y)
+{
+ long long t = (long long)y << 35;
+ return x ^ t;
+}
+
+/* { dg-final { scan-assembler-times "xorl" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/ashlti3-2.c b/gcc/testsuite/gcc.target/i386/ashlti3-2.c
new file mode 100644
index 0000000..7e21ab9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/ashlti3-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+__int128 foo(__int128 x, long long y)
+{
+ __int128 t = (__int128)y << 64;
+ return x ^ t;
+}
+
+__int128 bar(__int128 x, long long y)
+{
+ __int128 t = (__int128)y << 67;
+ return x ^ t;
+}
+
+/* { dg-final { scan-assembler-not "xorl" } } */
+/* { dg-final { scan-assembler-times "xorq" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c
new file mode 100644
index 0000000..4af6377
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mavx -mtune=generic -mvzeroupper -dp" } */
+
+#include <immintrin.h>
+
+extern __m256 x, y;
+
+void
+foo ()
+{
+ x = y;
+}
+
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-30.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-30.c
new file mode 100644
index 0000000..c1c9baa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-30.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mvzeroupper -dp" } */
+
+#include <immintrin.h>
+
+extern __m256 x, y;
+
+void
+foo ()
+{
+ x = y;
+ _mm256_zeroupper ();
+}
+
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512-binop-not-1.h b/gcc/testsuite/gcc.target/i386/avx512-binop-not-1.h
new file mode 100644
index 0000000..c68f2a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512-binop-not-1.h
@@ -0,0 +1,13 @@
+#include <immintrin.h>
+
+#define PASTER2(x,y) x##y
+#define PASTER3(x,y,z) _mm##x##_##y##_##z
+#define OP(vec, op, suffix) PASTER3 (vec, op, suffix)
+#define DUP(vec, suffix, val) PASTER3 (vec, set1, suffix) (val)
+
+type
+foo (type x, SCALAR *f)
+{
+ return OP (vec, op, suffix) (x, OP (vec, xor, suffix) (DUP (vec, suffix, *f),
+ DUP (vec, suffix, ~0)));
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512-binop-not-2.h b/gcc/testsuite/gcc.target/i386/avx512-binop-not-2.h
new file mode 100644
index 0000000..9f0900750
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512-binop-not-2.h
@@ -0,0 +1,13 @@
+#include <immintrin.h>
+
+#define PASTER2(x,y) x##y
+#define PASTER3(x,y,z) _mm##x##_##y##_##z
+#define OP(vec, op, suffix) PASTER3 (vec, op, suffix)
+#define DUP(vec, suffix, val) PASTER3 (vec, set1, suffix) (val)
+
+type
+foo (type x, SCALAR *f)
+{
+ return OP (vec, op, suffix) (OP (vec, xor, suffix) (x, DUP (vec, suffix, ~0)),
+ DUP (vec, suffix, *f));
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-andn-di-zmm-2.c b/gcc/testsuite/gcc.target/i386/avx512f-andn-di-zmm-2.c
new file mode 100644
index 0000000..4ebb30f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-andn-di-zmm-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */
+/* { dg-final { scan-assembler-times "vpternlogq\[ \\t\]+\\\$0x44, \\(%(?:eax|rdi|edi)\\)\\\{1to\[1-8\]+\\\}, %zmm\[0-9\]+, %zmm0" 1 } } */
+/* { dg-final { scan-assembler-not "vpbroadcast" } } */
+
+#define type __m512i
+#define vec 512
+#define op andnot
+#define suffix epi64
+#define SCALAR long long
+
+#include "avx512-binop-2.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-andn-si-zmm-2.c b/gcc/testsuite/gcc.target/i386/avx512f-andn-si-zmm-2.c
index a9608ca..86e7ebe 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-andn-si-zmm-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-andn-si-zmm-2.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-mavx512f -O2" } */
-/* { dg-final { scan-assembler-times "vpbroadcastd\[^\n\]*%zmm\[0-9\]+" 1 } } */
-/* { dg-final { scan-assembler-times "vpandnd\[^\n\]*%zmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vpternlogd\[ \\t\]+\\\$0x44, \\(%(?:eax|rdi|edi)\\)\\\{1to\[1-8\]+\\\}, %zmm\[0-9\]+, %zmm0" 1 } } */
+/* { dg-final { scan-assembler-not "vpbroadcast" } } */
#define type __m512i
#define vec 512
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-copysign.c b/gcc/testsuite/gcc.target/i386/avx512f-copysign.c
index 51ca028..e08df9a 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-copysign.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-copysign.c
@@ -1,4 +1,4 @@
-/* { dg-do compile } */
+/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */
/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[ \\t\]+\\\$(?:216|228|0xd8|0xe4)," 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-1.c b/gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-1.c
new file mode 100644
index 0000000..7d02f03
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */
+/* { dg-final { scan-assembler-times "vpternlogd\[ \\t\]+\\\$0xdd, \\(%(?:eax|rdi|edi)\\)\\\{1to\[1-8\]+\\\}, %zmm\[0-9\]+, %zmm0" 1 } } */
+/* { dg-final { scan-assembler-not "vpbroadcast" } } */
+
+#define type __m512i
+#define vec 512
+#define op or
+#define suffix epi32
+#define SCALAR int
+
+#include "avx512-binop-not-1.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-2.c b/gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-2.c
new file mode 100644
index 0000000..c793083
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-orn-si-zmm-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */
+/* { dg-final { scan-assembler-times "vpternlogd\[ \\t\]+\\\$0xbb, \\(%(?:eax|rdi|edi)\\)\\\{1to\[1-8\]+\\\}, %zmm\[0-9\]+, %zmm0" 1 } } */
+/* { dg-final { scan-assembler-not "vpbroadcast" } } */
+
+#define type __m512i
+#define vec 512
+#define op or
+#define suffix epi32
+#define SCALAR int
+
+#include "avx512-binop-not-2.h"
diff --git a/gcc/testsuite/gcc.target/i386/bf16_short_warn.c b/gcc/testsuite/gcc.target/i386/bf16_short_warn.c
new file mode 100644
index 0000000..3e47a81
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bf16_short_warn.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include<immintrin.h>
+typedef struct {
+short payload;
+} BFloat16;
+
+__attribute__((target("avx512vl,avx512bf16")))
+BFloat16 tobf16_avx512(float f)
+{
+ BFloat16 r;
+ __m128bh m = _mm_cvtneps_pbh(_mm_set_ss(f));
+ r.payload = m[0]; /* { dg-warning " be careful of implicit conversion between '__bf16' and 'short'" } */
+ return r;
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/mvc17.c b/gcc/testsuite/gcc.target/i386/mvc17.c
new file mode 100644
index 0000000..8b83c1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mvc17.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2 -march=x86-64" } */
+/* { dg-final { scan-assembler-times "rep mov" 1 } } */
+
+__attribute__((target_clones("default","arch=icelake-server")))
+void
+foo (char *a, char *b, int size)
+{
+ __builtin_memcpy (a, b, size & 0x7F);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pieces-memcmp-2.c b/gcc/testsuite/gcc.target/i386/pieces-memcmp-2.c
new file mode 100644
index 0000000..6061c91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pieces-memcmp-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mavx2 -mmove-max=128 -mstore-max=128" } */
+
+int foo(char *a)
+{
+ static const char t[] = "0123456789012345678901234567890";
+ return __builtin_memcmp(a, &t[0], sizeof(t)) == 0;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \\t]*\\\$0," } } */
+/* { dg-final { scan-assembler-not "vptest\[ \\t]*%ymm" } } */
+/* { dg-final { scan-assembler-times "vptest\[ \\t]*%xmm" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/pr100711-3.c b/gcc/testsuite/gcc.target/i386/pr100711-3.c
index e90f2a4..98cc1c3 100644
--- a/gcc/testsuite/gcc.target/i386/pr100711-3.c
+++ b/gcc/testsuite/gcc.target/i386/pr100711-3.c
@@ -37,4 +37,6 @@ v8di foo_v8di (long long a, v8di b)
return (__extension__ (v8di) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) & b;
}
-/* { dg-final { scan-assembler-times "vpandn" 4 } } */
+/* { dg-final { scan-assembler-times "vpandn" 4 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "vpandn" 2 { target { ia32 } } } } */
+/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[ \\t\]+\\\$0x44" 2 { target { ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100711-4.c b/gcc/testsuite/gcc.target/i386/pr100711-4.c
new file mode 100644
index 0000000..3ca524f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100711-4.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512bw -mno-avx512vl -mprefer-vector-width=512 -O2" } */
+
+typedef char v64qi __attribute__ ((vector_size (64)));
+typedef short v32hi __attribute__ ((vector_size (64)));
+typedef int v16si __attribute__ ((vector_size (64)));
+typedef long long v8di __attribute__((vector_size (64)));
+
+v64qi foo_v64qi (char a, v64qi b)
+{
+ return (__extension__ (v64qi) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) | b;
+}
+
+v32hi foo_v32hi (short a, v32hi b)
+{
+ return (__extension__ (v32hi) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) | b;
+}
+
+v16si foo_v16si (int a, v16si b)
+{
+ return (__extension__ (v16si) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) | b;
+}
+
+v8di foo_v8di (long long a, v8di b)
+{
+ return (__extension__ (v8di) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) | b;
+}
+
+/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[ \\t\]+\\\$0xbb" 4 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[ \\t\]+\\\$0xbb" 2 { target { ia32 } } } } */
+/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[ \\t\]+\\\$0xdd" 2 { target { ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100711-5.c b/gcc/testsuite/gcc.target/i386/pr100711-5.c
new file mode 100644
index 0000000..161fbfc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100711-5.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512bw -mno-avx512vl -mprefer-vector-width=512 -O2" } */
+
+typedef char v64qi __attribute__ ((vector_size (64)));
+typedef short v32hi __attribute__ ((vector_size (64)));
+typedef int v16si __attribute__ ((vector_size (64)));
+typedef long long v8di __attribute__((vector_size (64)));
+
+v64qi foo_v64qi (char a, v64qi b)
+{
+ return (__extension__ (v64qi) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) ^ b;
+}
+
+v32hi foo_v32hi (short a, v32hi b)
+{
+ return (__extension__ (v32hi) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) ^ b;
+}
+
+v16si foo_v16si (int a, v16si b)
+{
+ return (__extension__ (v16si) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a,
+ ~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) ^ b;
+}
+
+v8di foo_v8di (long long a, v8di b)
+{
+ return (__extension__ (v8di) {~a, ~a, ~a, ~a, ~a, ~a, ~a, ~a}) ^ b;
+}
+
+/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[ \\t\]+\\\$0x99" 4 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100711-6.c b/gcc/testsuite/gcc.target/i386/pr100711-6.c
new file mode 100644
index 0000000..7142a98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100711-6.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */
+
+typedef int v16si __attribute__ ((vector_size (64)));
+typedef long long v8di __attribute__((vector_size (64)));
+
+v16si foo_v16si (const int *a)
+{
+ return (__extension__ (v16si) {~*a, ~*a, ~*a, ~*a, ~*a, ~*a, ~*a, ~*a,
+ ~*a, ~*a, ~*a, ~*a, ~*a, ~*a, ~*a, ~*a});
+}
+
+v8di foo_v8di (const long long *a)
+{
+ return (__extension__ (v8di) {~*a, ~*a, ~*a, ~*a, ~*a, ~*a, ~*a, ~*a});
+}
+
+/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[ \\t\]+\\\$0x55, \\(%(?:eax|rdi|edi)\\)\\\{1to\[1-8\]+\\\}" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr104610.c b/gcc/testsuite/gcc.target/i386/pr104610.c
index fe39cbe..5173fc8 100644
--- a/gcc/testsuite/gcc.target/i386/pr104610.c
+++ b/gcc/testsuite/gcc.target/i386/pr104610.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mavx -mmove-max=256 -mstore-max=256" } */
+/* { dg-options "-O2 -mavx -mmove-max=256 -mstore-max=256 -fno-stack-protector" } */
/* { dg-final { scan-assembler-times {(?n)vptest.*ymm} 1 } } */
/* { dg-final { scan-assembler-times {sete} 1 } } */
/* { dg-final { scan-assembler-not {(?n)je.*L[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr110018-1.c b/gcc/testsuite/gcc.target/i386/pr110018-1.c
index b6a3be7..24eeca6 100644
--- a/gcc/testsuite/gcc.target/i386/pr110018-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr110018-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mavx512fp16 -mavx512vl -O2 -mavx512dq" } */
+/* { dg-options "-mavx512fp16 -mavx512vl -O2 -mavx512dq -fno-trapping-math" } */
/* { dg-final { scan-assembler-times {(?n)vcvttp[dsh]2[dqw]} 5 } } */
/* { dg-final { scan-assembler-times {(?n)vcvt[dqw]*2p[dsh]} 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr110018-2.c b/gcc/testsuite/gcc.target/i386/pr110018-2.c
index a663e07..9a2d9e1 100644
--- a/gcc/testsuite/gcc.target/i386/pr110018-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr110018-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mavx512fp16 -mavx512vl -O2 -mavx512dq" } */
+/* { dg-options "-mavx512fp16 -mavx512vl -O2 -mavx512dq -fno-trapping-math" } */
/* { dg-final { scan-assembler-times {(?n)vcvttp[dsh]2[dqw]} 5 } } */
/* { dg-final { scan-assembler-times {(?n)vcvt[dqw]*2p[dsh]} 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr110309.c b/gcc/testsuite/gcc.target/i386/pr110309.c
new file mode 100644
index 0000000..f6e9e9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr110309.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 --param vect-partial-vector-usage=1 -march=znver4 -mprefer-vector-width=256" } */
+/* { dg-final { scan-assembler-not {(?n)vpblendd.*ymm} } } */
+
+
+void foo (int * __restrict a, int *b)
+{
+ for (int i = 0; i < 6; ++i)
+ a[i] = b[i] + 42;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr110310.c b/gcc/testsuite/gcc.target/i386/pr110310.c
new file mode 100644
index 0000000..dce388a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr110310.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=znver4 -fdump-tree-vect-optimized" } */
+
+void foo (int * __restrict a, int *b)
+{
+ for (int i = 0; i < 20; ++i)
+ a[i] = b[i] + 42;
+}
+
+/* We should vectorize the main loop with AVX512 and the epilog with SSE. */
+
+/* { dg-final { scan-tree-dump "optimized: loop vectorized using 64 byte vectors" "vect" } } */
+/* { dg-final { scan-tree-dump "optimized: loop vectorized using 16 byte vectors" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr110452.c b/gcc/testsuite/gcc.target/i386/pr110452.c
new file mode 100644
index 0000000..8a3e2e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr110452.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model -mavx512f -mprefer-vector-width=512" } */
+
+double a[1024], b[1024], c[1024];
+
+void foo (int flag, int n)
+{
+ _Bool x = flag == 3;
+ for (int i = 0; i < n; ++i)
+ a[i] = (x ? b[i] : c[i]) * 42.;
+}
+
+/* { dg-final { scan-assembler-not "\[^x\]orl" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr69482-1.c b/gcc/testsuite/gcc.target/i386/pr69482-1.c
index f192261..99bb6ad 100644
--- a/gcc/testsuite/gcc.target/i386/pr69482-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr69482-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3" } */
+/* { dg-options "-O3 -fno-stack-protector" } */
static inline void memset_s(void* s, int n) {
volatile unsigned char * p = s;
diff --git a/gcc/testsuite/gcc.target/i386/rotate-6.c b/gcc/testsuite/gcc.target/i386/rotate-6.c
new file mode 100644
index 0000000..42c2072
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/rotate-6.c
@@ -0,0 +1,195 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-require-effective-target sse2 } */
+
+/* scalar 64-bit DImode rotations. */
+unsigned long long rot1(unsigned long long x) { return (x>>1) | (x<<63); }
+unsigned long long rot2(unsigned long long x) { return (x>>2) | (x<<62); }
+unsigned long long rot3(unsigned long long x) { return (x>>3) | (x<<61); }
+unsigned long long rot4(unsigned long long x) { return (x>>4) | (x<<60); }
+unsigned long long rot5(unsigned long long x) { return (x>>5) | (x<<59); }
+unsigned long long rot6(unsigned long long x) { return (x>>6) | (x<<58); }
+unsigned long long rot7(unsigned long long x) { return (x>>7) | (x<<57); }
+unsigned long long rot8(unsigned long long x) { return (x>>8) | (x<<56); }
+unsigned long long rot9(unsigned long long x) { return (x>>9) | (x<<55); }
+unsigned long long rot10(unsigned long long x) { return (x>>10) | (x<<54); }
+unsigned long long rot15(unsigned long long x) { return (x>>15) | (x<<49); }
+unsigned long long rot16(unsigned long long x) { return (x>>16) | (x<<48); }
+unsigned long long rot17(unsigned long long x) { return (x>>17) | (x<<47); }
+unsigned long long rot20(unsigned long long x) { return (x>>20) | (x<<44); }
+unsigned long long rot24(unsigned long long x) { return (x>>24) | (x<<40); }
+unsigned long long rot30(unsigned long long x) { return (x>>30) | (x<<34); }
+unsigned long long rot31(unsigned long long x) { return (x>>31) | (x<<33); }
+unsigned long long rot32(unsigned long long x) { return (x>>32) | (x<<32); }
+unsigned long long rot33(unsigned long long x) { return (x>>33) | (x<<31); }
+unsigned long long rot34(unsigned long long x) { return (x>>34) | (x<<30); }
+unsigned long long rot40(unsigned long long x) { return (x>>40) | (x<<24); }
+unsigned long long rot42(unsigned long long x) { return (x>>42) | (x<<22); }
+unsigned long long rot48(unsigned long long x) { return (x>>48) | (x<<16); }
+unsigned long long rot50(unsigned long long x) { return (x>>50) | (x<<14); }
+unsigned long long rot56(unsigned long long x) { return (x>>56) | (x<<8); }
+unsigned long long rot58(unsigned long long x) { return (x>>58) | (x<<6); }
+unsigned long long rot60(unsigned long long x) { return (x>>60) | (x<<4); }
+unsigned long long rot61(unsigned long long x) { return (x>>61) | (x<<3); }
+unsigned long long rot62(unsigned long long x) { return (x>>62) | (x<<2); }
+unsigned long long rot63(unsigned long long x) { return (x>>63) | (x<<1); }
+
+/* DImode mem-to-mem rotations. These STV with -m32. */
+void mem1(unsigned long long *p) { *p = rot1(*p); }
+void mem2(unsigned long long *p) { *p = rot2(*p); }
+void mem3(unsigned long long *p) { *p = rot3(*p); }
+void mem4(unsigned long long *p) { *p = rot4(*p); }
+void mem5(unsigned long long *p) { *p = rot5(*p); }
+void mem6(unsigned long long *p) { *p = rot6(*p); }
+void mem7(unsigned long long *p) { *p = rot7(*p); }
+void mem8(unsigned long long *p) { *p = rot8(*p); }
+void mem9(unsigned long long *p) { *p = rot9(*p); }
+void mem10(unsigned long long *p) { *p = rot10(*p); }
+void mem15(unsigned long long *p) { *p = rot15(*p); }
+void mem16(unsigned long long *p) { *p = rot16(*p); }
+void mem17(unsigned long long *p) { *p = rot17(*p); }
+void mem20(unsigned long long *p) { *p = rot20(*p); }
+void mem24(unsigned long long *p) { *p = rot24(*p); }
+void mem30(unsigned long long *p) { *p = rot30(*p); }
+void mem31(unsigned long long *p) { *p = rot31(*p); }
+void mem32(unsigned long long *p) { *p = rot32(*p); }
+void mem33(unsigned long long *p) { *p = rot33(*p); }
+void mem34(unsigned long long *p) { *p = rot34(*p); }
+void mem40(unsigned long long *p) { *p = rot40(*p); }
+void mem42(unsigned long long *p) { *p = rot42(*p); }
+void mem48(unsigned long long *p) { *p = rot48(*p); }
+void mem50(unsigned long long *p) { *p = rot50(*p); }
+void mem56(unsigned long long *p) { *p = rot56(*p); }
+void mem58(unsigned long long *p) { *p = rot58(*p); }
+void mem60(unsigned long long *p) { *p = rot60(*p); }
+void mem61(unsigned long long *p) { *p = rot61(*p); }
+void mem62(unsigned long long *p) { *p = rot62(*p); }
+void mem63(unsigned long long *p) { *p = rot63(*p); }
+
+/* Check that rotN and memN give the same result. */
+typedef unsigned long long (*rotN)(unsigned long long);
+typedef void (*memN)(unsigned long long*);
+
+void eval(rotN s, memN v, unsigned long long x)
+{
+ unsigned long long r = s(x);
+ unsigned long long t = x;
+ v(&t);
+
+ if (t != r)
+ __builtin_abort ();
+}
+
+void test(rotN s, memN v)
+{
+ eval(s,v,0x0000000000000000ll);
+ eval(s,v,0x0000000000000001ll);
+ eval(s,v,0x0000000000000002ll);
+ eval(s,v,0x0000000000000004ll);
+ eval(s,v,0x0000000000000008ll);
+ eval(s,v,0x0000000000000010ll);
+ eval(s,v,0x0000000000000020ll);
+ eval(s,v,0x0000000000000040ll);
+ eval(s,v,0x0000000000000080ll);
+ eval(s,v,0x0000000000000100ll);
+ eval(s,v,0x0000000000000200ll);
+ eval(s,v,0x0000000000000400ll);
+ eval(s,v,0x0000000000000800ll);
+ eval(s,v,0x0000000000001000ll);
+ eval(s,v,0x0000000000002000ll);
+ eval(s,v,0x0000000000004000ll);
+ eval(s,v,0x0000000000008000ll);
+ eval(s,v,0x0000000000010000ll);
+ eval(s,v,0x0000000000020000ll);
+ eval(s,v,0x0000000000040000ll);
+ eval(s,v,0x0000000000080000ll);
+ eval(s,v,0x0000000000100000ll);
+ eval(s,v,0x0000000000200000ll);
+ eval(s,v,0x0000000000400000ll);
+ eval(s,v,0x0000000000800000ll);
+ eval(s,v,0x0000000001000000ll);
+ eval(s,v,0x0000000002000000ll);
+ eval(s,v,0x0000000004000000ll);
+ eval(s,v,0x0000000008000000ll);
+ eval(s,v,0x0000000010000000ll);
+ eval(s,v,0x0000000020000000ll);
+ eval(s,v,0x0000000040000000ll);
+ eval(s,v,0x0000000080000000ll);
+ eval(s,v,0x0000000100000000ll);
+ eval(s,v,0x0000000200000000ll);
+ eval(s,v,0x0000000400000000ll);
+ eval(s,v,0x0000000800000000ll);
+ eval(s,v,0x0000001000000000ll);
+ eval(s,v,0x0000002000000000ll);
+ eval(s,v,0x0000004000000000ll);
+ eval(s,v,0x0000008000000000ll);
+ eval(s,v,0x0000010000000000ll);
+ eval(s,v,0x0000020000000000ll);
+ eval(s,v,0x0000040000000000ll);
+ eval(s,v,0x0000080000000000ll);
+ eval(s,v,0x0000100000000000ll);
+ eval(s,v,0x0000200000000000ll);
+ eval(s,v,0x0000400000000000ll);
+ eval(s,v,0x0000800000000000ll);
+ eval(s,v,0x0001000000000000ll);
+ eval(s,v,0x0002000000000000ll);
+ eval(s,v,0x0004000000000000ll);
+ eval(s,v,0x0008000000000000ll);
+ eval(s,v,0x0010000000000000ll);
+ eval(s,v,0x0020000000000000ll);
+ eval(s,v,0x0040000000000000ll);
+ eval(s,v,0x0080000000000000ll);
+ eval(s,v,0x0100000000000000ll);
+ eval(s,v,0x0200000000000000ll);
+ eval(s,v,0x0400000000000000ll);
+ eval(s,v,0x0800000000000000ll);
+ eval(s,v,0x1000000000000000ll);
+ eval(s,v,0x2000000000000000ll);
+ eval(s,v,0x4000000000000000ll);
+ eval(s,v,0x8000000000000000ll);
+ eval(s,v,0x0123456789abcdefll);
+ eval(s,v,0x1111111111111111ll);
+ eval(s,v,0x5555555555555555ll);
+ eval(s,v,0x8888888888888888ll);
+ eval(s,v,0xaaaaaaaaaaaaaaaall);
+ eval(s,v,0xcafebabecafebabell);
+ eval(s,v,0xdeadbeefdeadbeefll);
+ eval(s,v,0xfedcba9876543210ll);
+ eval(s,v,0xffffffffffffffffll);
+}
+
+int main()
+{
+ test(rot1,mem1);
+ test(rot2,mem2);
+ test(rot3,mem3);
+ test(rot4,mem4);
+ test(rot5,mem5);
+ test(rot6,mem6);
+ test(rot7,mem7);
+ test(rot8,mem8);
+ test(rot9,mem9);
+ test(rot10,mem10);
+ test(rot15,mem15);
+ test(rot16,mem16);
+ test(rot17,mem17);
+ test(rot20,mem20);
+ test(rot24,mem24);
+ test(rot30,mem30);
+ test(rot31,mem31);
+ test(rot32,mem32);
+ test(rot33,mem33);
+ test(rot34,mem34);
+ test(rot40,mem40);
+ test(rot42,mem42);
+ test(rot48,mem48);
+ test(rot50,mem50);
+ test(rot56,mem56);
+ test(rot58,mem58);
+ test(rot60,mem60);
+ test(rot61,mem61);
+ test(rot62,mem62);
+ test(rot63,mem63);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/sse2-stv-1.c b/gcc/testsuite/gcc.target/i386/sse2-stv-1.c
new file mode 100644
index 0000000..a95d4ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-stv-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2" } */
+
+unsigned long long a,b,c,d;
+
+static unsigned long rot(unsigned long long x, int y)
+{
+ /* Only called with y in 1..63. */
+ return (x<<y) | (x>>(64-y));
+}
+
+void foo()
+{
+ d = rot(d ^ a,32);
+ c = c + d;
+ b = rot(b ^ c,24);
+ a = a + b;
+ d = rot(d ^ a,16);
+ c = c + d;
+ b = rot(b ^ c,63);
+}
+
+/* { dg-final { scan-assembler-not "shldl" } } */
+/* { dg-final { scan-assembler-not "%\[er\]sp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c
new file mode 100644
index 0000000..2277710
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fzero-call-used-regs=leafy -fno-stack-protector -fno-PIC" } */
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler-not "vzeroall" } } */
+/* { dg-final { scan-assembler-not "%xmm" } } */
+/* { dg-final { scan-assembler-not "xorl\[ \t\]+%" } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]+%" } } */
diff --git a/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c
new file mode 100644
index 0000000..24b85c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fzero-call-used-regs=leafy-gpr -fno-stack-protector -fno-PIC" } */
+
+extern int bar (int);
+
+void
+foo (void)
+{
+ int x = bar (0);
+ if (x)
+ bar (1);
+}
+
+/* { dg-final { scan-assembler "xorl\[ \t\]+%eax, %eax" } } */
+/* { dg-final { scan-assembler "xorl\[ \t\]+%edx, %edx" } } */
+/* { dg-final { scan-assembler "xorl\[ \t\]+%ecx, %ecx" } } */
diff --git a/gcc/testsuite/gcc.target/mips/align-1-n64.c b/gcc/testsuite/gcc.target/mips/align-1-n64.c
new file mode 100644
index 0000000..3ede539
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/align-1-n64.c
@@ -0,0 +1,20 @@
+/* Check that typedef alignment does not affect passing of function
+ parameters for N64/N32 ABIs. */
+/* { dg-do compile { target { "mips*-*-*" } } } */
+/* { dg-options "-mabi=64" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+
+typedef struct ui8
+{
+ unsigned v[8];
+} uint8 __attribute__ ((aligned(64)));
+
+unsigned
+callee (int x, uint8 a)
+{
+ return a.v[0];
+}
+
+/* { dg-final { scan-assembler "\tsd\t\\\$5,0\\(\\\$\[0-9\]\\)" } } */
+/* { dg-final { scan-assembler "\tsd\t\\\$6,8\\(\\\$\[0-9\]\\)" } } */
+/* { dg-final { scan-assembler "\tsd\t\\\$7,16\\(\\\$\[0-9\]\\)" } } */
diff --git a/gcc/testsuite/gcc.target/mips/align-1-o32.c b/gcc/testsuite/gcc.target/mips/align-1-o32.c
new file mode 100644
index 0000000..e043d6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/align-1-o32.c
@@ -0,0 +1,20 @@
+/* Check that typedef alignment does not affect passing of function
+ parameters for O32 ABI. */
+/* { dg-do compile { target { "mips*-*-*" } } } */
+/* { dg-options "-mabi=32" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+
+typedef struct ui8
+{
+ unsigned v[8];
+} uint8 __attribute__ ((aligned(64)));
+
+unsigned
+callee (int x, uint8 a)
+{
+ return a.v[0];
+}
+
+/* { dg-final { scan-assembler "\tsw\t\\\$5,1\\d\\d\\(\\\$(sp|fp)\\)" } } */
+/* { dg-final { scan-assembler "\tsw\t\\\$6,1\\d\\d\\(\\\$(sp|fp)\\)" } } */
+/* { dg-final { scan-assembler "\tsw\t\\\$7,1\\d\\d\\(\\\$(sp|fp)\\)" } } */
diff --git a/gcc/testsuite/gcc.target/mips/expand-block-move-r6-no-unaligned.c b/gcc/testsuite/gcc.target/mips/expand-block-move-r6-no-unaligned.c
new file mode 100644
index 0000000..0fdcac2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/expand-block-move-r6-no-unaligned.c
@@ -0,0 +1,15 @@
+/* { dg-options "isa_rev>=6 -mno-unaligned-access" } */
+/* { dg-final { scan-assembler "memcpy" } } */
+
+char a[4097], b[4097];
+#ifdef __mips64
+#define MAX_SIZE 128
+#else
+#define MAX_SIZE 64
+#endif
+
+NOCOMPRESSION void
+foo ()
+{
+ __builtin_memcpy(&a[1], &b[1], MAX_SIZE-16);
+}
diff --git a/gcc/testsuite/gcc.target/mips/expand-block-move-r6.c b/gcc/testsuite/gcc.target/mips/expand-block-move-r6.c
new file mode 100644
index 0000000..9e247b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/expand-block-move-r6.c
@@ -0,0 +1,20 @@
+/* { dg-options "isa_rev>=6" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-final { scan-assembler-not "memcpy" } } */
+/* { dg-final { scan-assembler-not "lb\t" } } */
+/* { dg-final { scan-assembler-not "sb\t" } } */
+/* { dg-final { scan-assembler-not "lh\t" } } */
+/* { dg-final { scan-assembler-not "sh\t" } } */
+
+char a[4097], b[4097];
+#ifdef __mips64
+#define MAX_SIZE 128
+#else
+#define MAX_SIZE 64
+#endif
+
+NOCOMPRESSION void
+foo ()
+{
+ __builtin_memcpy(&a[1], &b[1], MAX_SIZE-16);
+}
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 15d5742..e79f685 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -301,6 +301,7 @@ foreach option {
loongson-mmi
loongson-ext
loongson-ext2
+ mips16e2
} {
lappend mips_option_groups $option "-m(no-|)$option"
}
@@ -821,6 +822,12 @@ proc mips-dg-init {} {
"-mno-mips16",
#endif
+ #ifdef __mips_mips16e2
+ "-mmips16e2",
+ #else
+ "-mno-mips16e2",
+ #endif
+
#ifdef __mips3d
"-mips3d",
#else
@@ -1038,6 +1045,7 @@ proc mips-dg-options { args } {
# dependency diagram.
mips_option_dependency options "-mips16" "-mno-micromips"
mips_option_dependency options "-mmicromips" "-mno-mips16"
+ mips_option_dependency options "-mmicromips" "-mno-mips16e2"
mips_option_dependency options "-mips3d" "-mpaired-single"
mips_option_dependency options "-mips3d" "-mno-micromips"
mips_option_dependency options "-mpaired-single" "-mfp64"
@@ -1417,6 +1425,7 @@ proc mips-dg-options { args } {
mips_make_test_option options "-mfp32"
}
mips_make_test_option options "-mno-dsp"
+ mips_make_test_option options "-mno-mips16e2"
mips_make_test_option options "-mno-synci"
mips_make_test_option options "-mno-micromips"
mips_make_test_option options "-mnan=legacy"
@@ -1449,6 +1458,7 @@ proc mips-dg-options { args } {
# Handle dependencies between options on the right of the diagram.
mips_option_dependency options "-mno-dsp" "-mno-dspr2"
+ mips_option_dependency options "-mno-mips16" "-mno-mips16e2"
mips_option_dependency options "-mno-explicit-relocs" "-mgpopt"
switch -- [mips_test_option options small-data] {
"" -
diff --git a/gcc/testsuite/gcc.target/mips/mips16e2-cache.c b/gcc/testsuite/gcc.target/mips/mips16e2-cache.c
new file mode 100644
index 0000000..dcc39b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips16e2-cache.c
@@ -0,0 +1,34 @@
+/* { dg-options "-mno-abicalls -mgpopt -G8 -mabi=32 -mips32r2 -mips16 -mmips16e2" } */
+/* { dg-skip-if "naming registers makes this a code quality test" { *-*-* } { "-O0" } { "" } } */
+
+/* Test cache. */
+
+void
+test01 (int *area)
+{
+ __builtin_mips_cache (20, area);
+}
+
+void
+test02 (const short *area)
+{
+ __builtin_mips_cache (24, area + 10);
+}
+
+void
+test03 (volatile unsigned int *area, int offset)
+{
+ __builtin_mips_cache (0, area + offset);
+}
+
+void
+test04 (const volatile unsigned char *area)
+{
+ __builtin_mips_cache (4, area - 80);
+}
+
+/* { dg-final { scan-assembler "\tcache\t0x14,0\\(\\\$4\\)" } } */
+/* { dg-final { scan-assembler "\tcache\t0x18,20\\(\\\$4\\)" } } */
+/* { dg-final { scan-assembler "\tcache\t(0x|)0,0\\(\\\$.\\)" } } */
+/* { dg-final { scan-assembler "\tcache\t0x4,-80\\(\\\$4\\)" } } */
+
diff --git a/gcc/testsuite/gcc.target/mips/mips16e2-cmov.c b/gcc/testsuite/gcc.target/mips/mips16e2-cmov.c
new file mode 100644
index 0000000..129ea23
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips16e2-cmov.c
@@ -0,0 +1,68 @@
+/* { dg-options "-mno-abicalls -mgpopt -G8 -mabi=32 -mips16 -mmips16e2 -mbranch-cost=2" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+/* Test MOVN. */
+
+/* { dg-final { scan-assembler-times "test01:.*\tmovn\t.*test01\n" 1 } } */
+int
+test01 (int a, int b, int c)
+{
+ return (a==0) ? b : c;
+}
+
+/* { dg-final { scan-assembler-times "test02:.*\tmovn\t\\\$.,\\\$0.*test02\n" 1 } } */
+int
+test02 (int a, int b, int c)
+{
+ return (a==0) ? b : 0;
+}
+
+/* Test MOVZ. */
+
+/* { dg-final { scan-assembler-times "test03:.*\tmovz\t.*test03\n" 1 } } */
+int
+test03 (int a, int b, int c)
+{
+ return a ? b : c;
+}
+
+/* { dg-final { scan-assembler-times "test04:.*\tmovz\t\\\$.,\\\$0.*test04\n" 1 } } */
+int
+test04 (int a, int b, int c)
+{
+ return a ? b : 0;
+}
+
+/* Test MOVTN. */
+
+/* { dg-final { scan-assembler-times "test05:.*\tmovtn\t.*test05\n" 1 } } */
+int
+test05 (int a, int b, int c, int d)
+{
+ return a >= b ? c : d;
+}
+
+/* { dg-final { scan-assembler-times "test06:.*\tmovtn\t\\\$2,\\\$0.*test06\n" 1 } } */
+int
+test06 (int a, int b, int c, int d)
+{
+ return a >= b ? c : 0;
+}
+
+/* Test MOVTZ. */
+
+/* { dg-final { scan-assembler-times "test07:.*\tmovtz\t.*test07\n" 1 } } */
+int
+test07 (int a, int b, int c, int d)
+{
+ return a < b ? c : d;
+}
+
+/* { dg-final { scan-assembler-times "test08:.*\tmovtz\t\\\$.,\\\$0.*test08\n" 1 } } */
+int
+test08 (int a, int b, int c, int d)
+{
+ return a < b ? c : 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.target/mips/mips16e2-gp.c b/gcc/testsuite/gcc.target/mips/mips16e2-gp.c
new file mode 100644
index 0000000..7955472
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips16e2-gp.c
@@ -0,0 +1,101 @@
+/* { dg-options "-mno-abicalls -mgpopt -G8 -mabi=32 -mips16 -mmips16e2" } */
+/* { dg-skip-if "per-function expected output" { *-*-* } { "-flto" } { "" } } */
+
+/* Generate GP-relative ADDIU. */
+
+/* { dg-final { scan-assembler "test01:.*\taddiu\t\\\$2,\\\$28.*test01\n" } } */
+int arr[2];
+
+int *
+test01 (void)
+{
+ return (&arr[1]);
+}
+
+/* Test LB[GP]. */
+
+/* { dg-final { scan-assembler "test02:.*\tlb\t.*\\\$28.*test02\n" } } */
+signed char c02;
+
+signed char
+test02 (void)
+{
+ return c02;
+}
+
+/* Test LBU[GP]. */
+
+/* { dg-final { scan-assembler "test03:.*\tlbu\t.*\\\$28.*test03\n" } } */
+unsigned char uc03;
+
+unsigned char
+test03 (void)
+{
+ return uc03;
+}
+
+/* Test LH[GP]. */
+
+/* { dg-final { scan-assembler "test04:.*\tlh\t.*\\\$28.*test04\n" } } */
+short s04;
+
+short
+test04 (void)
+{
+ return s04;
+}
+
+/* Test LHU[GP]. */
+
+/* { dg-final { scan-assembler "test05:.*\tlhu\t.*\\\$28.*test05\n" } } */
+unsigned short s05;
+
+unsigned short
+test05 (void)
+{
+ return s05;
+}
+
+/* Test LW[GP]. */
+
+/* { dg-final { scan-assembler "test06:.*\tlw\t.*\\\$28.*test06\n" } } */
+int i06;
+
+int
+test06 (void)
+{
+ return i06;
+}
+
+/* Test SB[GP]. */
+
+/* { dg-final { scan-assembler "test07:.*\tsb\t.*\\\$28.*test07\n" } } */
+char c07;
+
+void
+test07 (char x)
+{
+ c07 = x;
+}
+
+/* Test SH[GP]. */
+
+/* { dg-final { scan-assembler "test08:.*\tsh\t.*\\\$28.*test08\n" } } */
+short s08;
+
+void
+test08 (short x)
+{
+ s08 = x;
+}
+
+/* Test SW[GP]. */
+
+/* { dg-final { scan-assembler "test09:.*\tsw\t.*\\\$28.*test09\n" } } */
+int i09;
+
+void
+test09 (int x)
+{
+ i09 = x;
+}
diff --git a/gcc/testsuite/gcc.target/mips/mips16e2.c b/gcc/testsuite/gcc.target/mips/mips16e2.c
new file mode 100644
index 0000000..166aa74
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips16e2.c
@@ -0,0 +1,240 @@
+/* { dg-options "-mno-abicalls -mgpopt -G8 -mabi=32 -mips16 -mmips16e2" } */
+/* { dg-skip-if "per-function expected output" { *-*-* } { "-flto" } { "" } } */
+
+/* ANDI is a two operand instruction. Hence, it won't be generated if src and
+ * dest are in different registers. */
+
+/* { dg-final { scan-assembler "test01:.*\tandi\t.*test01\n" } } */
+unsigned int
+test01 (unsigned int a)
+{
+ return ((a + 0x2) & 0x3ff);
+}
+
+/* Test EXT */
+
+/* { dg-final { scan-assembler "test02:.*\text\t.*test02\n" } } */
+struct
+{
+ unsigned int a:9;
+ unsigned int d:31;
+ unsigned int e:9;
+ unsigned int f:10;
+} t02;
+
+unsigned int
+test02 (void)
+{
+ return t02.f;
+}
+
+/* Use EXT when ANDing with low-order bitmasks. */
+
+/* { dg-final { scan-assembler "test03:.*\text\t.*test03\n" } } */
+/* { dg-final { scan-assembler-not "test03.*\tandi?\t.*test03\n" } } */
+unsigned int
+test03 (unsigned int x)
+{
+ return (x & 0x1fffffff);
+}
+
+/* Test INS */
+
+/* { dg-final { scan-assembler "test04:.*\tins\t.*test04\n" } } */
+struct
+{
+ unsigned int i : 9;
+ unsigned int j : 15;
+ unsigned int k : 4;
+} s04;
+
+void
+test04 (void)
+{
+ s04.j = 1;
+}
+
+/* Use INS with hardcoded $0. */
+
+/* { dg-final { scan-assembler "test05:.*\tins\t\\\$.*,\\\$0.*test05\n" } } */
+struct
+{
+ unsigned int i : 8;
+ unsigned int j : 9;
+ unsigned int k : 10;
+} __attribute__ ((packed)) s05 __attribute__((aligned(1)));
+
+void
+test05 (void)
+{
+ s05.k = 0;
+}
+
+/* Use INS when ANDing to clear only one consecutive chunk of bits. */
+
+/* { dg-final { scan-assembler "test06:.*\tins\t\\\$.*,\\\$0,11,5.*test06\n" } } */
+/* { dg-final { scan-assembler-not "test06:.*\tandi?\t.*test06\n" } } */
+unsigned int
+test06 (unsigned int x)
+{
+ return (x & 0xffff07ff);
+}
+
+/* ORI is a two operand instruction. Hence, it won't be generated if src and
+ dest are in different registers. */
+
+/* { dg-final { scan-assembler "test07:.*\tori\t.*test07\n" } } */
+unsigned int
+test07 (unsigned int a)
+{
+ return (a + 0x2) | 0x7f0;
+}
+
+/* XORI is a two operand instruction. Hence, it won't be generated if src and
+ dest are in different registers. */
+
+/* { dg-final { scan-assembler "test08:.*\txori\t.*test08\n" } } */
+unsigned int
+test08 (unsigned int a)
+{
+ return ((a + 0x2) ^ 0x3f0);
+}
+
+/* Test LUI. */
+
+/* { dg-final { scan-assembler "test09:.*\tlui\t.*test09\n" } } */
+int
+test09 (void)
+{
+ return 0x44440000;
+}
+
+/* Test LUI relocation sequence chang. */
+
+/* { dg-final { scan-assembler "test10:.*\tlui\t.*test10\n" } } */
+int *a10;
+
+int
+test10 (int i)
+{
+ a10 = &i;
+ *a10 = 0x44440000;
+ return i;
+}
+
+/* Test 32bit unaligned load. */
+
+/* { dg-final { scan-assembler "test11:.*\tlwl\t.*test11\n" } } */
+/* { dg-final { scan-assembler "test11:.*\tlwr\t.*test11\n" } } */
+struct node11
+{
+ char c;
+ int i;
+} __attribute__ ((packed)) obj11 __attribute__((aligned(1)));
+
+int
+test11 (void)
+{
+ return obj11.i;
+}
+
+/* Test 32bit unaligned load. */
+
+/* { dg-final { scan-assembler "test12:.*\tlwl\t.*test12\n" } } */
+/* { dg-final { scan-assembler "test12:.*\tlwr\t.*test12\n" } } */
+struct node12
+{
+ unsigned int i : 8;
+ unsigned int j : 32;
+} __attribute__ ((packed)) obj12 __attribute__((aligned(16)));
+
+int
+test12 (void)
+{
+ return obj12.j;
+}
+
+/* Test 32bit unaligned store with non-zero constant */
+
+/* { dg-final { scan-assembler "test13:.*\tswl\t.*test13\n" } } */
+/* { dg-final { scan-assembler "test13:.*\tswr\t.*test13\n" } } */
+struct node13
+{
+ char c;
+ int i;
+} __attribute__ ((packed)) obj13 __attribute__((aligned(1)));
+
+void
+test13 (void)
+{
+ obj13.i = 1234;
+}
+
+/* Test 32bit unaligned store with zero constant. */
+
+/* { dg-final { scan-assembler "test14:.*\tswl\t.*test14\n" } } */
+/* { dg-final { scan-assembler "test14:.*\tswr\t.*test14\n" } } */
+/* { dg-final { scan-assembler-not "test14:.*\tswl\t\\\$0,.*test14\n" } } */
+/* { dg-final { scan-assembler-not "test14:.*\tswr\t\\\$0,.*test14\n" } } */
+struct node14
+{
+ char c;
+ int i;
+} __attribute__ ((packed)) obj14 __attribute__((aligned(1)));
+
+void
+test14 (void)
+{
+ obj14.i = 0;
+}
+
+/* Test 32bit unaligned store with non-constant. */
+
+/* { dg-final { scan-assembler "test15:.*\tswl\t.*test15\n" } } */
+/* { dg-final { scan-assembler "test15:.*\tswr\t.*test15\n" } } */
+struct node15
+{
+ char c;
+ int i;
+} __attribute__ ((packed)) obj15 __attribute__((aligned(1)));
+
+int i15 = 1234;
+
+void
+test15 (void)
+{
+ obj15.i = i15;
+}
+
+/* Test 32bit unaligned store with non-constant */
+
+/* { dg-final { scan-assembler "test16:.*\tswl\t.*test16\n" } } */
+/* { dg-final { scan-assembler "test16:.*\tswr\t.*test16\n" } } */
+struct node16
+{
+ char c;
+ int i;
+} __attribute__ ((packed)) obj16 __attribute__((aligned(1)));
+
+void
+test16 (int i)
+{
+ obj16.i = i;
+}
+
+/* Test 32bit unaligned store with non-constant. */
+
+/* { dg-final { scan-assembler "test17:.*\tswl\t.*test17\n" } } */
+/* { dg-final { scan-assembler "test17:.*\tswr\t.*test17\n" } } */
+struct node17
+{
+ unsigned int i : 8;
+ unsigned int j : 32;
+} __attribute__ ((packed)) obj17 __attribute__((aligned(16)));
+
+void
+test17 (int i)
+{
+ obj17.j = i;
+}
+
diff --git a/gcc/testsuite/gcc.target/mips/movcc-3.c b/gcc/testsuite/gcc.target/mips/movcc-3.c
index 80d4409..569a004 100644
--- a/gcc/testsuite/gcc.target/mips/movcc-3.c
+++ b/gcc/testsuite/gcc.target/mips/movcc-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "(HAS_MOVN) -mhard-float -mbranch-cost=2" } */
+/* { dg-options "(HAS_MOVN) -mhard-float -mbranch-cost=3" } */
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os" } { "" } } */
/* { dg-final { scan-assembler "\tmovt\t" } } */
/* { dg-final { scan-assembler "\tmovf\t" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/fusion-p10-ldcmpi.c b/gcc/testsuite/gcc.target/powerpc/fusion-p10-ldcmpi.c
index 526a026..165bd9a 100644
--- a/gcc/testsuite/gcc.target/powerpc/fusion-p10-ldcmpi.c
+++ b/gcc/testsuite/gcc.target/powerpc/fusion-p10-ldcmpi.c
@@ -54,15 +54,17 @@ TEST(uint8_t)
TEST(int8_t)
/* { dg-final { scan-assembler-times "lbz_cmpldi_cr0_QI_clobber_CCUNS_zero" 4 { target lp64 } } } */
-/* { dg-final { scan-assembler-times "ld_cmpdi_cr0_DI_DI_CC_none" 4 { target lp64 } } } */
-/* { dg-final { scan-assembler-times "ld_cmpdi_cr0_DI_clobber_CC_none" 4 { target lp64 } } } */
-/* { dg-final { scan-assembler-times "ld_cmpldi_cr0_DI_DI_CCUNS_none" 1 { target lp64 } } } */
-/* { dg-final { scan-assembler-times "ld_cmpldi_cr0_DI_clobber_CCUNS_none" 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "ld_cmpdi_cr0_DI_DI_CC_none" 24 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "ld_cmpdi_cr0_DI_clobber_CC_none" 8 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "ld_cmpldi_cr0_DI_DI_CCUNS_none" 2 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "ld_cmpldi_cr0_DI_clobber_CCUNS_none" 2 { target lp64 } } } */
/* { dg-final { scan-assembler-times "lha_cmpdi_cr0_HI_clobber_CC_sign" 16 { target lp64 } } } */
/* { dg-final { scan-assembler-times "lhz_cmpldi_cr0_HI_clobber_CCUNS_zero" 4 { target lp64 } } } */
/* { dg-final { scan-assembler-times "lwa_cmpdi_cr0_SI_EXTSI_CC_sign" 0 { target lp64 } } } */
-/* { dg-final { scan-assembler-times "lwa_cmpdi_cr0_SI_clobber_CC_none" 4 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "lwz_cmpwi_cr0_SI_clobber_CC_none" 8 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "lwz_cmpwi_cr0_SI_SI_CC_none" 8 { target lp64 } } } */
/* { dg-final { scan-assembler-times "lwz_cmpldi_cr0_SI_EXTSI_CCUNS_zero" 0 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "lwz_cmpldi_cr0_SI_SI_CCUNS_none" 2 { target lp64 } } } */
/* { dg-final { scan-assembler-times "lwz_cmpldi_cr0_SI_clobber_CCUNS_none" 2 { target lp64 } } } */
/* { dg-final { scan-assembler-times "lbz_cmpldi_cr0_QI_clobber_CCUNS_zero" 2 { target ilp32 } } } */
@@ -73,6 +75,8 @@ TEST(int8_t)
/* { dg-final { scan-assembler-times "lha_cmpdi_cr0_HI_clobber_CC_sign" 8 { target ilp32 } } } */
/* { dg-final { scan-assembler-times "lhz_cmpldi_cr0_HI_clobber_CCUNS_zero" 2 { target ilp32 } } } */
/* { dg-final { scan-assembler-times "lwa_cmpdi_cr0_SI_EXTSI_CC_sign" 0 { target ilp32 } } } */
-/* { dg-final { scan-assembler-times "lwa_cmpdi_cr0_SI_clobber_CC_none" 9 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "lwz_cmpwi_cr0_SI_SI_CC_none" 36 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "lwz_cmpwi_cr0_SI_clobber_CC_none" 16 { target ilp32 } } } */
/* { dg-final { scan-assembler-times "lwz_cmpldi_cr0_SI_EXTSI_CCUNS_zero" 0 { target ilp32 } } } */
/* { dg-final { scan-assembler-times "lwz_cmpldi_cr0_SI_clobber_CCUNS_none" 6 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "lwz_cmpldi_cr0_SI_SI_CCUNS_none" 2 { target ilp32 } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104124.c b/gcc/testsuite/gcc.target/powerpc/pr104124.c
new file mode 100644
index 0000000..30e3b6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104124.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=power8 -mpower8-vector -O2" } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-final { scan-assembler {\mvspltisw\M} } } */
+/* { dg-final { scan-assembler {\mvupkhsw\M} } } */
+/* { dg-final { scan-assembler-not {\mlvx\M} } } */
+
+#include <altivec.h>
+
+vector unsigned long long
+foo ()
+{
+ return vec_splats ((unsigned long long) 12);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c
new file mode 100644
index 0000000..7a6d429
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c
@@ -0,0 +1,89 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "copysign-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define EPS 1e-6
+
+#define RUN(TYPE,VAL) \
+ TYPE a##TYPE[SZ]; \
+ TYPE b##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE[i] = i; \
+ b##TYPE[i] = (i & 1) ? VAL : -VAL; \
+ } \
+ copysign_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \
+
+#define RUN2(TYPE,VAL) \
+ TYPE a2##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ a2##TYPE[i] = i; \
+ copysigns_##TYPE (a2##TYPE, a2##TYPE, -VAL, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a2##TYPE[i] + i) < EPS); \
+
+#define RUN3(TYPE,VAL) \
+ TYPE a3##TYPE[SZ]; \
+ TYPE b3##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a3##TYPE[i] = (i & 1) ? -i : i; \
+ b3##TYPE[i] = (i & 1) ? VAL : -VAL; \
+ } \
+ xorsign_##TYPE (a3##TYPE, a3##TYPE, b3##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a3##TYPE[i] + i) < EPS); \
+
+#define RUN4(TYPE,VAL) \
+ TYPE a4##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ a4##TYPE[i] = -i; \
+ xorsigns_##TYPE (a4##TYPE, a4##TYPE, -VAL, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a4##TYPE[i] - i) < EPS); \
+
+#define RUN5(TYPE,VAL) \
+ TYPE a5##TYPE[SZ]; \
+ TYPE b5##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a5##TYPE[i] = i; \
+ b5##TYPE[i] = (i & 1) ? VAL : -VAL; \
+ } \
+ ncopysign_##TYPE (a5##TYPE, a5##TYPE, b##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (-a5##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \
+
+#define RUN6(TYPE,VAL) \
+ TYPE a6##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ a6##TYPE[i] = i; \
+ ncopysigns_##TYPE (a6##TYPE, a6##TYPE, -VAL, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (-a6##TYPE[i] + i) < EPS); \
+
+#define RUN_ALL() \
+ RUN(float, 5) \
+ RUN(double, 6) \
+ RUN2(float, 11) \
+ RUN2(double, 12) \
+ RUN3(float, 16) \
+ RUN3(double, 18) \
+ RUN4(float, 17) \
+ RUN4(double, 19) \
+ RUN5(float, 123) \
+ RUN5(double, 523) \
+ RUN6(float, 777) \
+ RUN6(double, 877) \
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c
new file mode 100644
index 0000000..db29e37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -O3 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "copysign-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfsgnj\.vv} 6 } } */
+/* The vectorizer wraps scalar variants of copysign into vector constants which
+ expand cannot handle currently. Therefore only expect 3 instead of 6
+ vfsgnjx.vv. */
+/* { dg-final { scan-assembler-times {\tvfsgnjx\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfsgnjn\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c
new file mode 100644
index 0000000..1c25049
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -O3 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "copysign-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfsgnj\.vv} 6 } } */
+/* The vectorizer wraps scalar variants of copysign into vector constants which
+ expand cannot handle currently. Therefore only expect 3 instead of 6
+ vfsgnjx.vv. */
+/* { dg-final { scan-assembler-times {\tvfsgnjx\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfsgnjn\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h
new file mode 100644
index 0000000..df2274f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h
@@ -0,0 +1,78 @@
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE, SUFFIX) \
+ __attribute__((noipa)) \
+ void copysign_##TYPE (TYPE *restrict dst, TYPE *restrict a, \
+ TYPE *restrict b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = __builtin_copysign##SUFFIX (a[i], b[i]); \
+ }
+
+#define TEST_TYPE2(TYPE, SUFFIX) \
+ __attribute__((noipa)) \
+ void copysigns_##TYPE (TYPE *restrict dst, TYPE *restrict a, \
+ TYPE b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = __builtin_copysign##SUFFIX (a[i], b); \
+ }
+
+#define TEST_TYPE3(TYPE, SUFFIX) \
+ __attribute__((noipa)) \
+ void xorsign_##TYPE (TYPE *restrict dst, TYPE *restrict a, \
+ TYPE *restrict b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = a[i] * __builtin_copysign##SUFFIX (1.0, b[i]); \
+ }
+
+#define TEST_TYPE4(TYPE, SUFFIX) \
+ __attribute__((noipa)) \
+ void xorsigns_##TYPE (TYPE *restrict dst, TYPE *restrict a, \
+ TYPE b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = a[i] * __builtin_copysign##SUFFIX (1.0, b); \
+ }
+
+#define TEST_TYPE5(TYPE, SUFFIX) \
+ __attribute__((noipa)) \
+ void ncopysign_##TYPE (TYPE *restrict dst, TYPE *restrict a, \
+ TYPE *restrict b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = -__builtin_copysign##SUFFIX (a[i], b[i]); \
+ }
+
+#define TEST_TYPE6(TYPE, SUFFIX) \
+ __attribute__((noipa)) \
+ void ncopysigns_##TYPE (TYPE *restrict dst, TYPE *restrict a, \
+ TYPE b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = -__builtin_copysign##SUFFIX (a[i], b); \
+ }
+
+
+#define TEST_ALL() \
+ TEST_TYPE(_Float16,f16) \
+ TEST_TYPE(float,f) \
+ TEST_TYPE(double,) \
+ TEST_TYPE2(_Float16,f16) \
+ TEST_TYPE2(float,f) \
+ TEST_TYPE2(double,) \
+ TEST_TYPE3(_Float16,f16) \
+ TEST_TYPE3(float,f) \
+ TEST_TYPE3(double,) \
+ TEST_TYPE4(_Float16,f16) \
+ TEST_TYPE4(float,f) \
+ TEST_TYPE4(double,) \
+ TEST_TYPE5(_Float16,f16) \
+ TEST_TYPE5(float,f) \
+ TEST_TYPE5(double,) \
+ TEST_TYPE6(_Float16,f16) \
+ TEST_TYPE6(float,f) \
+ TEST_TYPE6(double,) \
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c
new file mode 100644
index 0000000..7aaac97
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c
@@ -0,0 +1,83 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "copysign-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define EPS 1e-6
+
+#define RUN(TYPE,VAL) \
+ TYPE a##TYPE[SZ]; \
+ TYPE b##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE[i] = i; \
+ b##TYPE[i] = (i & 1) ? VAL : -VAL; \
+ } \
+ copysign_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \
+
+#define RUN2(TYPE,VAL) \
+ TYPE a2##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ a2##TYPE[i] = i; \
+ copysigns_##TYPE (a2##TYPE, a2##TYPE, -VAL, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a2##TYPE[i] + i) < EPS); \
+
+#define RUN3(TYPE,VAL) \
+ TYPE a3##TYPE[SZ]; \
+ TYPE b3##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a3##TYPE[i] = (i & 1) ? -i : i; \
+ b3##TYPE[i] = (i & 1) ? VAL : -VAL; \
+ } \
+ xorsign_##TYPE (a3##TYPE, a3##TYPE, b3##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a3##TYPE[i] + i) < EPS); \
+
+#define RUN4(TYPE,VAL) \
+ TYPE a4##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ a4##TYPE[i] = -i; \
+ xorsigns_##TYPE (a4##TYPE, a4##TYPE, -VAL, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (a4##TYPE[i] - i) < EPS); \
+
+#define RUN5(TYPE,VAL) \
+ TYPE a5##TYPE[SZ]; \
+ TYPE b5##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a5##TYPE[i] = i; \
+ b5##TYPE[i] = (i & 1) ? VAL : -VAL; \
+ } \
+ ncopysign_##TYPE (a5##TYPE, a5##TYPE, b##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (-a5##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \
+
+#define RUN6(TYPE,VAL) \
+ TYPE a6##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ a6##TYPE[i] = i; \
+ ncopysigns_##TYPE (a6##TYPE, a6##TYPE, -VAL, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (-a6##TYPE[i] + i) < EPS); \
+
+#define RUN_ALL() \
+ RUN(_Float16, 5) \
+ RUN2(_Float16, 11) \
+ RUN3(_Float16, 16) \
+ RUN4(_Float16, 17) \
+ RUN5(_Float16, 123) \
+ RUN6(_Float16, 777) \
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-run.c
new file mode 100644
index 0000000..dfe7328
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-run.c
@@ -0,0 +1,96 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfcvt-itof-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3 - 88932; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3 + 88932; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (int32_t, float, 3)
+ RUN (int32_t, float, 4)
+ RUN (int32_t, float, 7)
+ RUN (int32_t, float, 99)
+ RUN (int32_t, float, 119)
+ RUN (int32_t, float, 128)
+ RUN (int32_t, float, 256)
+ RUN (int32_t, float, 279)
+ RUN (int32_t, float, 555)
+ RUN (int32_t, float, 1024)
+ RUN (int32_t, float, 1389)
+ RUN (int32_t, float, 2048)
+ RUN (int32_t, float, 3989)
+ RUN (int32_t, float, 4096)
+ RUN (int32_t, float, 5975)
+
+ RUN2 (uint32_t, float, 3)
+ RUN2 (uint32_t, float, 4)
+ RUN2 (uint32_t, float, 7)
+ RUN2 (uint32_t, float, 99)
+ RUN2 (uint32_t, float, 119)
+ RUN2 (uint32_t, float, 128)
+ RUN2 (uint32_t, float, 256)
+ RUN2 (uint32_t, float, 279)
+ RUN2 (uint32_t, float, 555)
+ RUN2 (uint32_t, float, 1024)
+ RUN2 (uint32_t, float, 1389)
+ RUN2 (uint32_t, float, 2048)
+ RUN2 (uint32_t, float, 3989)
+ RUN2 (uint32_t, float, 4096)
+ RUN2 (uint32_t, float, 5975)
+
+ RUN (int64_t, double, 3)
+ RUN (int64_t, double, 4)
+ RUN (int64_t, double, 7)
+ RUN (int64_t, double, 99)
+ RUN (int64_t, double, 119)
+ RUN (int64_t, double, 128)
+ RUN (int64_t, double, 256)
+ RUN (int64_t, double, 279)
+ RUN (int64_t, double, 555)
+ RUN (int64_t, double, 1024)
+ RUN (int64_t, double, 1389)
+ RUN (int64_t, double, 2048)
+ RUN (int64_t, double, 3989)
+ RUN (int64_t, double, 4096)
+ RUN (int64_t, double, 5975)
+
+ RUN2 (uint64_t, double, 3)
+ RUN2 (uint64_t, double, 4)
+ RUN2 (uint64_t, double, 7)
+ RUN2 (uint64_t, double, 99)
+ RUN2 (uint64_t, double, 119)
+ RUN2 (uint64_t, double, 128)
+ RUN2 (uint64_t, double, 256)
+ RUN2 (uint64_t, double, 279)
+ RUN2 (uint64_t, double, 555)
+ RUN2 (uint64_t, double, 1024)
+ RUN2 (uint64_t, double, 1389)
+ RUN2 (uint64_t, double, 2048)
+ RUN2 (uint64_t, double, 3989)
+ RUN2 (uint64_t, double, 4096)
+ RUN2 (uint64_t, double, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv32gcv.c
new file mode 100644
index 0000000..dae1442
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv32gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfcvt-itof-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfcvt\.f\.x\.v} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfcvt\.f\.xu\.v} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv64gcv.c
new file mode 100644
index 0000000..ccb2bb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-rv64gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfcvt-itof-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfcvt\.f\.x\.v} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfcvt\.f\.xu\.v} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-template.h
new file mode 100644
index 0000000..92b3b81
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-template.h
@@ -0,0 +1,20 @@
+#include <stdint-gcc.h>
+
+#define TEST(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) \
+ void vfcvt_##TYPE1##TYPE2 (TYPE2 *restrict dst, \
+ TYPE1 *restrict a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE2) a[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST (int32_t, float) \
+ TEST (uint32_t, float) \
+ TEST (int64_t, double) \
+ TEST (uint64_t, double) \
+ TEST (int16_t, _Float16) \
+ TEST (uint16_t, _Float16) \
+
+TEST_ALL ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-zvfh-run.c
new file mode 100644
index 0000000..e7a8f0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt-itof-zvfh-run.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfcvt-itof-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3 - 8932; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3 + 8932; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (int16_t, _Float16, 3)
+ RUN (int16_t, _Float16, 4)
+ RUN (int16_t, _Float16, 7)
+ RUN (int16_t, _Float16, 99)
+ RUN (int16_t, _Float16, 119)
+ RUN (int16_t, _Float16, 128)
+ RUN (int16_t, _Float16, 256)
+ RUN (int16_t, _Float16, 279)
+ RUN (int16_t, _Float16, 555)
+ RUN (int16_t, _Float16, 1024)
+ RUN (int16_t, _Float16, 1389)
+ RUN (int16_t, _Float16, 2048)
+ RUN (int16_t, _Float16, 3989)
+ RUN (int16_t, _Float16, 4096)
+ RUN (int16_t, _Float16, 5975)
+
+ RUN2 (uint16_t, _Float16, 3)
+ RUN2 (uint16_t, _Float16, 4)
+ RUN2 (uint16_t, _Float16, 7)
+ RUN2 (uint16_t, _Float16, 99)
+ RUN2 (uint16_t, _Float16, 119)
+ RUN2 (uint16_t, _Float16, 128)
+ RUN2 (uint16_t, _Float16, 256)
+ RUN2 (uint16_t, _Float16, 279)
+ RUN2 (uint16_t, _Float16, 555)
+ RUN2 (uint16_t, _Float16, 1024)
+ RUN2 (uint16_t, _Float16, 1389)
+ RUN2 (uint16_t, _Float16, 2048)
+ RUN2 (uint16_t, _Float16, 3989)
+ RUN2 (uint16_t, _Float16, 4096)
+ RUN2 (uint16_t, _Float16, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c
index 05f8d91..e4dca60 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c
@@ -8,6 +8,18 @@
TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
for (int i = 0; i < NUM; i++) \
{ \
+ src##TYPE1##TYPE2##NUM[i] = i * -3.1315926 - 88932.947289; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
src##TYPE1##TYPE2##NUM[i] = i * 3.1315926 + 88932.947289; \
} \
vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
@@ -34,6 +46,22 @@ main ()
RUN (float, int32_t, 4096)
RUN (float, int32_t, 5975)
+ RUN2 (float, uint32_t, 3)
+ RUN2 (float, uint32_t, 4)
+ RUN2 (float, uint32_t, 7)
+ RUN2 (float, uint32_t, 99)
+ RUN2 (float, uint32_t, 119)
+ RUN2 (float, uint32_t, 128)
+ RUN2 (float, uint32_t, 256)
+ RUN2 (float, uint32_t, 279)
+ RUN2 (float, uint32_t, 555)
+ RUN2 (float, uint32_t, 1024)
+ RUN2 (float, uint32_t, 1389)
+ RUN2 (float, uint32_t, 2048)
+ RUN2 (float, uint32_t, 3989)
+ RUN2 (float, uint32_t, 4096)
+ RUN2 (float, uint32_t, 5975)
+
RUN (double, int64_t, 3)
RUN (double, int64_t, 4)
RUN (double, int64_t, 7)
@@ -49,4 +77,20 @@ main ()
RUN (double, int64_t, 3989)
RUN (double, int64_t, 4096)
RUN (double, int64_t, 5975)
+
+ RUN2 (double, uint64_t, 3)
+ RUN2 (double, uint64_t, 4)
+ RUN2 (double, uint64_t, 7)
+ RUN2 (double, uint64_t, 99)
+ RUN2 (double, uint64_t, 119)
+ RUN2 (double, uint64_t, 128)
+ RUN2 (double, uint64_t, 256)
+ RUN2 (double, uint64_t, 279)
+ RUN2 (double, uint64_t, 555)
+ RUN2 (double, uint64_t, 1024)
+ RUN2 (double, uint64_t, 1389)
+ RUN2 (double, uint64_t, 2048)
+ RUN2 (double, uint64_t, 3989)
+ RUN2 (double, uint64_t, 4096)
+ RUN2 (double, uint64_t, 5975)
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c
index 2f84631..0a79adf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
#include "vfcvt_rtz-template.h"
-/* { dg-final { scan-assembler-times {\tvfcvt\.rtz} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcvt\.rtz\.x\.f\.v} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfcvt\.rtz\.xu\.f\.v} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c
index 40e3e7a..e749847 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
#include "vfcvt_rtz-template.h"
-/* { dg-final { scan-assembler-times {\tvfcvt\.rtz} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcvt\.rtz\.x\.f\.v} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfcvt\.rtz\.xu\.f\.v} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h
index 73bc1ad..b9dab0f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h
@@ -5,11 +5,15 @@
int n) \
{ \
for (int i = 0; i < n; i++) \
- dst[i] = (TYPE1) a[i]; \
+ dst[i] = (TYPE2) a[i]; \
}
#define TEST_ALL() \
TEST (float, int32_t) \
- TEST (double, int64_t)
+ TEST (float, uint32_t) \
+ TEST (double, int64_t) \
+ TEST (double, uint64_t) \
+ TEST (_Float16, int16_t) \
+ TEST (_Float16, uint16_t) \
TEST_ALL ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-zvfh-run.c
new file mode 100644
index 0000000..e75aee7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-zvfh-run.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfcvt_rtz-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3.1315926 - 8932.947289; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3.1315926 + 8932.947289; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (_Float16, int16_t, 3)
+ RUN (_Float16, int16_t, 4)
+ RUN (_Float16, int16_t, 7)
+ RUN (_Float16, int16_t, 99)
+ RUN (_Float16, int16_t, 119)
+ RUN (_Float16, int16_t, 128)
+ RUN (_Float16, int16_t, 256)
+ RUN (_Float16, int16_t, 279)
+ RUN (_Float16, int16_t, 555)
+ RUN (_Float16, int16_t, 1024)
+ RUN (_Float16, int16_t, 1389)
+ RUN (_Float16, int16_t, 2048)
+ RUN (_Float16, int16_t, 3989)
+ RUN (_Float16, int16_t, 4096)
+ RUN (_Float16, int16_t, 5975)
+
+ RUN2 (_Float16, uint16_t, 3)
+ RUN2 (_Float16, uint16_t, 4)
+ RUN2 (_Float16, uint16_t, 7)
+ RUN2 (_Float16, uint16_t, 99)
+ RUN2 (_Float16, uint16_t, 119)
+ RUN2 (_Float16, uint16_t, 128)
+ RUN2 (_Float16, uint16_t, 256)
+ RUN2 (_Float16, uint16_t, 279)
+ RUN2 (_Float16, uint16_t, 555)
+ RUN2 (_Float16, uint16_t, 1024)
+ RUN2 (_Float16, uint16_t, 1389)
+ RUN2 (_Float16, uint16_t, 2048)
+ RUN2 (_Float16, uint16_t, 3989)
+ RUN2 (_Float16, uint16_t, 4096)
+ RUN2 (_Float16, uint16_t, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-run.c
new file mode 100644
index 0000000..ce3fcfa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-run.c
@@ -0,0 +1,96 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-ftoi-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3.1315926 - 92.947289; \
+ } \
+ vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3.1315926 + 92.947289; \
+ } \
+ vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (float, int16_t, 3)
+ RUN (float, int16_t, 4)
+ RUN (float, int16_t, 7)
+ RUN (float, int16_t, 99)
+ RUN (float, int16_t, 119)
+ RUN (float, int16_t, 128)
+ RUN (float, int16_t, 256)
+ RUN (float, int16_t, 279)
+ RUN (float, int16_t, 555)
+ RUN (float, int16_t, 1024)
+ RUN (float, int16_t, 1389)
+ RUN (float, int16_t, 2048)
+ RUN (float, int16_t, 3989)
+ RUN (float, int16_t, 4096)
+ RUN (float, int16_t, 5975)
+
+ RUN2 (float, uint16_t, 3)
+ RUN2 (float, uint16_t, 4)
+ RUN2 (float, uint16_t, 7)
+ RUN2 (float, uint16_t, 99)
+ RUN2 (float, uint16_t, 119)
+ RUN2 (float, uint16_t, 128)
+ RUN2 (float, uint16_t, 256)
+ RUN2 (float, uint16_t, 279)
+ RUN2 (float, uint16_t, 555)
+ RUN2 (float, uint16_t, 1024)
+ RUN2 (float, uint16_t, 1389)
+ RUN2 (float, uint16_t, 2048)
+ RUN2 (float, uint16_t, 3989)
+ RUN2 (float, uint16_t, 4096)
+ RUN2 (float, uint16_t, 5975)
+
+ RUN (double, int32_t, 3)
+ RUN (double, int32_t, 4)
+ RUN (double, int32_t, 7)
+ RUN (double, int32_t, 99)
+ RUN (double, int32_t, 119)
+ RUN (double, int32_t, 128)
+ RUN (double, int32_t, 256)
+ RUN (double, int32_t, 279)
+ RUN (double, int32_t, 555)
+ RUN (double, int32_t, 1024)
+ RUN (double, int32_t, 1389)
+ RUN (double, int32_t, 2048)
+ RUN (double, int32_t, 3989)
+ RUN (double, int32_t, 4096)
+ RUN (double, int32_t, 5975)
+
+ RUN2 (double, uint32_t, 3)
+ RUN2 (double, uint32_t, 4)
+ RUN2 (double, uint32_t, 7)
+ RUN2 (double, uint32_t, 99)
+ RUN2 (double, uint32_t, 119)
+ RUN2 (double, uint32_t, 128)
+ RUN2 (double, uint32_t, 256)
+ RUN2 (double, uint32_t, 279)
+ RUN2 (double, uint32_t, 555)
+ RUN2 (double, uint32_t, 1024)
+ RUN2 (double, uint32_t, 1389)
+ RUN2 (double, uint32_t, 2048)
+ RUN2 (double, uint32_t, 3989)
+ RUN2 (double, uint32_t, 4096)
+ RUN2 (double, uint32_t, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv32gcv.c
new file mode 100644
index 0000000..4bed5eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv32gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-ftoi-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.x\.f\.w} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.xu\.f\.w} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv64gcv.c
new file mode 100644
index 0000000..7efc3f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-rv64gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-ftoi-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.x\.f\.w} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.xu\.f\.w} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-template.h
new file mode 100644
index 0000000..c6efbf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-template.h
@@ -0,0 +1,19 @@
+#include <stdint-gcc.h>
+
+#define TEST(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vfncvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, \
+ int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE2) a[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST (double, int32_t) \
+ TEST (double, uint32_t) \
+ TEST (float, int16_t) \
+ TEST (float, uint16_t) \
+ TEST (_Float16, int8_t) \
+ TEST (_Float16, uint8_t) \
+
+TEST_ALL ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-zvfh-run.c
new file mode 100644
index 0000000..9771562
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-ftoi-zvfh-run.c
@@ -0,0 +1,42 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-ftoi-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3.1315926 - 8.947289; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3.1315926 + 8.947289; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (_Float16, int8_t, 3)
+ RUN (_Float16, int8_t, 4)
+ RUN (_Float16, int8_t, 13)
+ RUN (_Float16, int8_t, 40)
+
+ RUN2 (_Float16, uint8_t, 1)
+ RUN2 (_Float16, uint8_t, 8)
+ RUN2 (_Float16, uint8_t, 21)
+ RUN2 (_Float16, uint8_t, 33)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-run.c
new file mode 100644
index 0000000..9f3db6c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-run.c
@@ -0,0 +1,52 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-itof-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3 + 88932; \
+ } \
+ vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (int64_t, float, 3)
+ RUN (int64_t, float, 4)
+ RUN (int64_t, float, 7)
+ RUN (int64_t, float, 99)
+ RUN (int64_t, float, 119)
+ RUN (int64_t, float, 128)
+ RUN (int64_t, float, 256)
+ RUN (int64_t, float, 279)
+ RUN (int64_t, float, 555)
+ RUN (int64_t, float, 1024)
+ RUN (int64_t, float, 1389)
+ RUN (int64_t, float, 2048)
+ RUN (int64_t, float, 3989)
+ RUN (int64_t, float, 4096)
+ RUN (int64_t, float, 5975)
+
+ RUN (uint64_t, float, 3)
+ RUN (uint64_t, float, 4)
+ RUN (uint64_t, float, 7)
+ RUN (uint64_t, float, 99)
+ RUN (uint64_t, float, 119)
+ RUN (uint64_t, float, 128)
+ RUN (uint64_t, float, 256)
+ RUN (uint64_t, float, 279)
+ RUN (uint64_t, float, 555)
+ RUN (uint64_t, float, 1024)
+ RUN (uint64_t, float, 1389)
+ RUN (uint64_t, float, 2048)
+ RUN (uint64_t, float, 3989)
+ RUN (uint64_t, float, 4096)
+ RUN (uint64_t, float, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv32gcv.c
new file mode 100644
index 0000000..dd5b95c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv32gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-itof-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.x\.w} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.xu\.w} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv64gcv.c
new file mode 100644
index 0000000..b3bdece
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-rv64gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-itof-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.x\.w} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.xu\.w} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-template.h
new file mode 100644
index 0000000..b06deeb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-template.h
@@ -0,0 +1,18 @@
+#include <stdint-gcc.h>
+
+#define TEST(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) \
+ void vfncvt_##TYPE1##TYPE2 (TYPE2 *restrict dst, \
+ TYPE1 *restrict a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE2) a[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST (int64_t, float) \
+ TEST (uint64_t, float) \
+ TEST (int32_t, _Float16) \
+ TEST (uint32_t, _Float16) \
+
+TEST_ALL ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-zvfh-run.c
new file mode 100644
index 0000000..b4e59c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-itof-zvfh-run.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-itof-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3 - 832; \
+ } \
+ vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3 + 892; \
+ } \
+ vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (int32_t, _Float16, 3)
+ RUN (int32_t, _Float16, 4)
+ RUN (int32_t, _Float16, 7)
+ RUN (int32_t, _Float16, 99)
+ RUN (int32_t, _Float16, 119)
+ RUN (int32_t, _Float16, 128)
+ RUN (int32_t, _Float16, 256)
+ RUN (int32_t, _Float16, 279)
+ RUN (int32_t, _Float16, 555)
+ RUN (int32_t, _Float16, 1024)
+ RUN (int32_t, _Float16, 1389)
+ RUN (int32_t, _Float16, 2048)
+ RUN (int32_t, _Float16, 3989)
+ RUN (int32_t, _Float16, 4096)
+ RUN (int32_t, _Float16, 5975)
+
+ RUN2 (uint32_t, _Float16, 3)
+ RUN2 (uint32_t, _Float16, 4)
+ RUN2 (uint32_t, _Float16, 7)
+ RUN2 (uint32_t, _Float16, 99)
+ RUN2 (uint32_t, _Float16, 119)
+ RUN2 (uint32_t, _Float16, 128)
+ RUN2 (uint32_t, _Float16, 256)
+ RUN2 (uint32_t, _Float16, 279)
+ RUN2 (uint32_t, _Float16, 555)
+ RUN2 (uint32_t, _Float16, 1024)
+ RUN2 (uint32_t, _Float16, 1389)
+ RUN2 (uint32_t, _Float16, 2048)
+ RUN2 (uint32_t, _Float16, 3989)
+ RUN2 (uint32_t, _Float16, 4096)
+ RUN2 (uint32_t, _Float16, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c
new file mode 100644
index 0000000..65d2826
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vfncvt-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+#define EPS 1e-4
+
+#define RUN(TYPE1,TYPE2) \
+ TYPE1 src##TYPE1##TYPE2[SZ]; \
+ TYPE2 dst##TYPE1##TYPE2[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \
+ src##TYPE1##TYPE2[i] *= 3.141592; \
+ dst##TYPE1##TYPE2[i] = -1; \
+ } \
+ vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \
+ src##TYPE1##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \
+ - ((i & 1) ? -i : i) * 3.141592) < EPS); \
+
+
+#define RUN_ALL() \
+ RUN(double, float) \
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c
new file mode 100644
index 0000000..10fe75d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vfncvt-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c
new file mode 100644
index 0000000..fd40fa2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vfncvt-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h
new file mode 100644
index 0000000..221e883
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h
@@ -0,0 +1,16 @@
+#include <stdint-gcc.h>
+
+#define TEST(TYPE1, TYPE2) \
+ __attribute__((noipa)) \
+ void vfncvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE2)a[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST(float, _Float16) \
+ TEST(double, _Float16) \
+ TEST(double, float) \
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c
new file mode 100644
index 0000000..38e0d84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfncvt-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+#define EPS 1e-4
+
+#define RUN(TYPE1,TYPE2) \
+ TYPE1 src##TYPE1##TYPE2[SZ]; \
+ TYPE2 dst##TYPE1##TYPE2[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \
+ src##TYPE1##TYPE2[i] *= 0.0003141592; \
+ dst##TYPE1##TYPE2[i] = -1; \
+ } \
+ vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \
+ src##TYPE1##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \
+ - ((i & 1) ? -i : i) * 0.0003141592) < EPS); \
+
+
+#define RUN_ALL() \
+ RUN(float, _Float16) \
+ RUN(double, _Float16) \
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-run.c
new file mode 100644
index 0000000..928e0b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-run.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-ftoi-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3.1315926 - 932.947289; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3.1315926 + 932.947289; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (float, int64_t, 3)
+ RUN (float, int64_t, 4)
+ RUN (float, int64_t, 7)
+ RUN (float, int64_t, 99)
+ RUN (float, int64_t, 119)
+ RUN (float, int64_t, 128)
+ RUN (float, int64_t, 256)
+ RUN (float, int64_t, 279)
+ RUN (float, int64_t, 555)
+ RUN (float, int64_t, 1024)
+ RUN (float, int64_t, 1389)
+ RUN (float, int64_t, 2048)
+ RUN (float, int64_t, 3989)
+ RUN (float, int64_t, 4096)
+ RUN (float, int64_t, 5975)
+
+ RUN2 (float, uint64_t, 3)
+ RUN2 (float, uint64_t, 4)
+ RUN2 (float, uint64_t, 7)
+ RUN2 (float, uint64_t, 99)
+ RUN2 (float, uint64_t, 119)
+ RUN2 (float, uint64_t, 128)
+ RUN2 (float, uint64_t, 256)
+ RUN2 (float, uint64_t, 279)
+ RUN2 (float, uint64_t, 555)
+ RUN2 (float, uint64_t, 1024)
+ RUN2 (float, uint64_t, 1389)
+ RUN2 (float, uint64_t, 2048)
+ RUN2 (float, uint64_t, 3989)
+ RUN2 (float, uint64_t, 4096)
+ RUN2 (float, uint64_t, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv32gcv.c
new file mode 100644
index 0000000..ce2bea4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv32gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-ftoi-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfwcvt\.rtz\.x\.f\.v} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfwcvt\.rtz\.xu\.f\.v} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv64gcv.c
new file mode 100644
index 0000000..99aa3de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-rv64gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-ftoi-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfwcvt\.rtz\.x\.f\.v} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfwcvt\.rtz\.xu\.f\.v} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-template.h
new file mode 100644
index 0000000..a276351
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-template.h
@@ -0,0 +1,17 @@
+#include <stdint-gcc.h>
+
+#define TEST(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vfwcvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, \
+ int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE2) a[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST (_Float16, int32_t) \
+ TEST (_Float16, uint32_t) \
+ TEST (float, int64_t) \
+ TEST (float, uint64_t) \
+
+TEST_ALL ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-zvfh-run.c
new file mode 100644
index 0000000..15bcd05
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-ftoi-zvfh-run.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfcvt_rtz-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3.1315926 - 832.947289; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3.1315926 + 832.947289; \
+ } \
+ vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (_Float16, int32_t, 3)
+ RUN (_Float16, int32_t, 4)
+ RUN (_Float16, int32_t, 7)
+ RUN (_Float16, int32_t, 99)
+ RUN (_Float16, int32_t, 119)
+ RUN (_Float16, int32_t, 128)
+ RUN (_Float16, int32_t, 256)
+ RUN (_Float16, int32_t, 279)
+ RUN (_Float16, int32_t, 555)
+ RUN (_Float16, int32_t, 1024)
+ RUN (_Float16, int32_t, 1389)
+ RUN (_Float16, int32_t, 2048)
+ RUN (_Float16, int32_t, 3989)
+ RUN (_Float16, int32_t, 4096)
+ RUN (_Float16, int32_t, 5975)
+
+ RUN2 (_Float16, uint32_t, 3)
+ RUN2 (_Float16, uint32_t, 4)
+ RUN2 (_Float16, uint32_t, 7)
+ RUN2 (_Float16, uint32_t, 99)
+ RUN2 (_Float16, uint32_t, 119)
+ RUN2 (_Float16, uint32_t, 128)
+ RUN2 (_Float16, uint32_t, 256)
+ RUN2 (_Float16, uint32_t, 279)
+ RUN2 (_Float16, uint32_t, 555)
+ RUN2 (_Float16, uint32_t, 1024)
+ RUN2 (_Float16, uint32_t, 1389)
+ RUN2 (_Float16, uint32_t, 2048)
+ RUN2 (_Float16, uint32_t, 3989)
+ RUN2 (_Float16, uint32_t, 4096)
+ RUN2 (_Float16, uint32_t, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-run.c
new file mode 100644
index 0000000..b9287f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-run.c
@@ -0,0 +1,96 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-itof-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3 - 88932; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3 + 88932; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (int16_t, float, 3)
+ RUN (int16_t, float, 4)
+ RUN (int16_t, float, 7)
+ RUN (int16_t, float, 99)
+ RUN (int16_t, float, 119)
+ RUN (int16_t, float, 128)
+ RUN (int16_t, float, 256)
+ RUN (int16_t, float, 279)
+ RUN (int16_t, float, 555)
+ RUN (int16_t, float, 1024)
+ RUN (int16_t, float, 1389)
+ RUN (int16_t, float, 2048)
+ RUN (int16_t, float, 3989)
+ RUN (int16_t, float, 4096)
+ RUN (int16_t, float, 5975)
+
+ RUN2 (uint16_t, float, 3)
+ RUN2 (uint16_t, float, 4)
+ RUN2 (uint16_t, float, 7)
+ RUN2 (uint16_t, float, 99)
+ RUN2 (uint16_t, float, 119)
+ RUN2 (uint16_t, float, 128)
+ RUN2 (uint16_t, float, 256)
+ RUN2 (uint16_t, float, 279)
+ RUN2 (uint16_t, float, 555)
+ RUN2 (uint16_t, float, 1024)
+ RUN2 (uint16_t, float, 1389)
+ RUN2 (uint16_t, float, 2048)
+ RUN2 (uint16_t, float, 3989)
+ RUN2 (uint16_t, float, 4096)
+ RUN2 (uint16_t, float, 5975)
+
+ RUN (int32_t, double, 3)
+ RUN (int32_t, double, 4)
+ RUN (int32_t, double, 7)
+ RUN (int32_t, double, 99)
+ RUN (int32_t, double, 119)
+ RUN (int32_t, double, 128)
+ RUN (int32_t, double, 256)
+ RUN (int32_t, double, 279)
+ RUN (int32_t, double, 555)
+ RUN (int32_t, double, 1024)
+ RUN (int32_t, double, 1389)
+ RUN (int32_t, double, 2048)
+ RUN (int32_t, double, 3989)
+ RUN (int32_t, double, 4096)
+ RUN (int32_t, double, 5975)
+
+ RUN2 (uint32_t, double, 3)
+ RUN2 (uint32_t, double, 4)
+ RUN2 (uint32_t, double, 7)
+ RUN2 (uint32_t, double, 99)
+ RUN2 (uint32_t, double, 119)
+ RUN2 (uint32_t, double, 128)
+ RUN2 (uint32_t, double, 256)
+ RUN2 (uint32_t, double, 279)
+ RUN2 (uint32_t, double, 555)
+ RUN2 (uint32_t, double, 1024)
+ RUN2 (uint32_t, double, 1389)
+ RUN2 (uint32_t, double, 2048)
+ RUN2 (uint32_t, double, 3989)
+ RUN2 (uint32_t, double, 4096)
+ RUN2 (uint32_t, double, 5975)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv32gcv.c
new file mode 100644
index 0000000..898b9c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv32gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-itof-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.x\.v} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.xu\.v} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv64gcv.c
new file mode 100644
index 0000000..e177b63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-rv64gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-itof-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.x\.v} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.xu\.v} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-template.h
new file mode 100644
index 0000000..bd6d238
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-template.h
@@ -0,0 +1,20 @@
+#include <stdint-gcc.h>
+
+#define TEST(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) \
+ void vfwcvt_##TYPE1##TYPE2 (TYPE2 *restrict dst, \
+ TYPE1 *restrict a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE2) a[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST (int16_t, float) \
+ TEST (uint16_t, float) \
+ TEST (int32_t, double) \
+ TEST (uint32_t, double) \
+ TEST (int8_t, _Float16) \
+ TEST (uint8_t, _Float16) \
+
+TEST_ALL ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-zvfh-run.c
new file mode 100644
index 0000000..f89dc46
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-itof-zvfh-run.c
@@ -0,0 +1,45 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-itof-template.h"
+
+#define RUN(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * -3 - 8; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+#define RUN2(TYPE1, TYPE2, NUM) \
+ TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \
+ TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ src##TYPE1##TYPE2##NUM[i] = i * 3 + 8; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \
+ __builtin_abort ();
+
+int
+main ()
+{
+ RUN (int8_t, _Float16, 3)
+ RUN (int8_t, _Float16, 4)
+ RUN (int8_t, _Float16, 7)
+ RUN (int8_t, _Float16, 12)
+ RUN (int8_t, _Float16, 20)
+ RUN (int8_t, _Float16, 27)
+
+ RUN (int8_t, _Float16, 4)
+ RUN (int8_t, _Float16, 8)
+ RUN (int8_t, _Float16, 11)
+ RUN (int8_t, _Float16, 29)
+ RUN (int8_t, _Float16, 49)
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c
new file mode 100644
index 0000000..9594909
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vfwcvt-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+#define EPS 1e-4
+
+#define RUN(TYPE1,TYPE2) \
+ TYPE1 src##TYPE1##TYPE2[SZ]; \
+ TYPE2 dst##TYPE1##TYPE2[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \
+ src##TYPE1##TYPE2[i] *= 3.141592; \
+ dst##TYPE1##TYPE2[i] = -1; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \
+ src##TYPE1##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \
+ - ((i & 1) ? -i : i) * 3.141592) < EPS); \
+
+
+#define RUN_ALL() \
+ RUN(float, double) \
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c
new file mode 100644
index 0000000..006bdb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vfwcvt-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.f\.v} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c
new file mode 100644
index 0000000..7ec7107
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vfwcvt-template.h"
+
+/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.f\.v} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h
new file mode 100644
index 0000000..b6ccf3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h
@@ -0,0 +1,16 @@
+#include <stdint-gcc.h>
+
+#define TEST(TYPE1, TYPE2) \
+ __attribute__((noipa)) \
+ void vfwcvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE2)a[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST(_Float16, float) \
+ TEST(_Float16, double) \
+ TEST(float, double) \
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c
new file mode 100644
index 0000000..77d653e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+#include "vfwcvt-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+#define EPS 1e-4
+
+#define RUN(TYPE1,TYPE2) \
+ TYPE1 src##TYPE1##TYPE2[SZ]; \
+ TYPE2 dst##TYPE1##TYPE2[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \
+ src##TYPE1##TYPE2[i] *= 0.0003141592; \
+ dst##TYPE1##TYPE2[i] = -1; \
+ } \
+ vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \
+ src##TYPE1##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \
+ - ((i & 1) ? -i : i) * 0.0003141592) < EPS); \
+
+
+#define RUN_ALL() \
+ RUN(_Float16, float) \
+ RUN(_Float16, double) \
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vncvt-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vncvt-template.h
index 6b19ff1..f63e095 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vncvt-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vncvt-template.h
@@ -5,7 +5,7 @@
void vncvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, int n) \
{ \
for (int i = 0; i < n; i++) \
- dst[i] = (TYPE1)a[i]; \
+ dst[i] = (TYPE2)a[i]; \
}
#define TEST_ALL() \
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vsext-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vsext-template.h
index c2f5fc9..f85edcc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vsext-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vsext-template.h
@@ -5,7 +5,7 @@
void vsext_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, int n) \
{ \
for (int i = 0; i < n; i++) \
- dst[i] = (TYPE1)a[i]; \
+ dst[i] = (TYPE2)a[i]; \
}
#define TEST_ALL() \
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vzext-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vzext-template.h
index 847905b..7b40423 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vzext-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vzext-template.h
@@ -5,7 +5,7 @@
void vzext_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, int n) \
{ \
for (int i = 0; i < n; i++) \
- dst[i] = (TYPE1)a[i]; \
+ dst[i] = (TYPE2)a[i]; \
}
#define TEST_ALL() \
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c
new file mode 100644
index 0000000..23407a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3 -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define SZ 255
+
+#define DEF(TYPE) void fn_##TYPE (TYPE *__restrict a);
+
+#define RUN(TYPE) \
+ TYPE a##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE[i] = 127; \
+ } \
+ fn_##TYPE (a##TYPE);
+
+#define RUN_ALL() \
+ RUN (int8_t) \
+ RUN (int16_t) \
+ RUN (int32_t) \
+ RUN (int64_t) \
+ RUN (uint8_t) \
+ RUN (uint16_t) \
+ RUN (uint32_t) \
+ RUN (uint64_t)
+
+DEF (int8_t)
+DEF (int16_t)
+DEF (int32_t)
+DEF (int64_t)
+DEF (uint8_t)
+DEF (uint16_t)
+DEF (uint32_t)
+DEF (uint64_t)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
+
+/* { dg-final { scan-tree-dump-times "\.LEN_MASK_STORE" 6 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-1.c
index 74bbf40..e27090d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fno-vect-cost-model -fno-tree-loop-distribute-patterns -fdump-tree-optimized-details" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param riscv-autovec-preference=scalable -fno-vect-cost-model -fno-tree-loop-distribute-patterns -fdump-tree-optimized-details" } */
#include <stdint-gcc.h>
@@ -20,7 +20,10 @@
TEST_TYPE (uint32_t) \
TEST_TYPE (int64_t) \
TEST_TYPE (uint64_t) \
+ TEST_TYPE (_Float16) \
TEST_TYPE (float) \
TEST_TYPE (double)
TEST_ALL ()
+
+/* { dg-final { scan-tree-dump-times "\.SELECT_VL" 11 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
new file mode 100644
index 0000000..eac7cbc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d --param riscv-autovec-preference=scalable -fno-schedule-insns --param riscv-autovec-lmul=m1 -O3 -ftree-vectorize" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <stdint-gcc.h>
+
+/*
+** foo:
+** vsetivli\t[a-x0-9]+,\s*8,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
+** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ...
+** vsetvli\t[a-x0-9]+,\s*[a-x0-9]+,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
+** add\t[a-x0-9]+,[a-x0-9]+,[a-x0-9]+
+** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ...
+*/
+void
+foo (int32_t *__restrict a,
+ int32_t *__restrict b,
+ int32_t *__restrict cond)
+{
+ for (int i = 0; i < 8; i++)
+ if (cond[i])
+ a[i] = b[i];
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.c
new file mode 100644
index 0000000..24490dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfhmin -mabi=ilp32d --param riscv-autovec-preference=fixed-vlmax -fdump-tree-vect-details" } */
+
+#include "single_rgroup-2.h"
+
+TEST_ALL (test_1)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.h
new file mode 100644
index 0000000..a94f3eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-2.h
@@ -0,0 +1,44 @@
+#include <assert.h>
+#include <stdint-gcc.h>
+
+#define N 777
+
+#define test_1(TYPE) \
+ TYPE a_##TYPE[N] = {0}; \
+ TYPE b_##TYPE[N] = {0}; \
+ void __attribute__ ((noinline, noclone)) \
+ test_1_##TYPE (int *__restrict cond) \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < 8; i++) \
+ if (cond[i]) \
+ b_##TYPE[i] = a_##TYPE[i]; \
+ }
+
+#define run_1(TYPE) \
+ int cond_##TYPE[N] = {0}; \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 33 + 1 + 109; \
+ for (unsigned int i = 0; i < N; i++) \
+ cond_##TYPE[i] = i & 1; \
+ test_1_##TYPE (cond_##TYPE); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond_##TYPE[i] && i < 8) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t) \
+ T (_Float16) \
+ T (float) \
+ T (double)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.c
new file mode 100644
index 0000000..9cbae13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfhmin -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */
+
+#include "single_rgroup-3.h"
+
+TEST_ALL (test_1)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.h
new file mode 100644
index 0000000..e60e0b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup-3.h
@@ -0,0 +1,149 @@
+#include <assert.h>
+#include <stdint-gcc.h>
+
+#define N 777
+
+int cond[N] = {0};
+#define test_1(TYPE) \
+ TYPE a_##TYPE[N]; \
+ TYPE b_##TYPE[N]; \
+ void __attribute__ ((noinline, noclone)) test_1_##TYPE (unsigned int n) \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < n; i++) \
+ if (cond[i]) \
+ b_##TYPE[i] = a_##TYPE[i]; \
+ }
+
+#define run_1(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 33 + 1 + 109; \
+ test_1_##TYPE (5); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 5) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_2(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 57 + 1 + 999; \
+ test_1_##TYPE (17); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 17) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_3(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 77 + 1 + 3; \
+ test_1_##TYPE (32); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 32) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_4(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 45 + 1 + 11; \
+ test_1_##TYPE (128); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 128) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_5(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 199 + 1 + 79; \
+ test_1_##TYPE (177); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 177) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_6(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 377 + 1 + 73; \
+ test_1_##TYPE (255); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 255) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_7(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 98 + 1 + 66; \
+ test_1_##TYPE (333); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 333) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_8(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 7 + 1 * 7; \
+ test_1_##TYPE (512); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 512) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_9(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 + 1 + 88; \
+ test_1_##TYPE (637); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 637) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define run_10(TYPE) \
+ for (unsigned int i = 0; i < N; i++) \
+ a_##TYPE[i] = i * 2 * 331 + 1 + 547; \
+ test_1_##TYPE (777); \
+ for (unsigned int i = 0; i < N; i++) \
+ { \
+ if (cond[i] && i < 777) \
+ assert (b_##TYPE[i] == a_##TYPE[i]); \
+ else \
+ assert (b_##TYPE[i] == 0); \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t) \
+ T (_Float16) \
+ T (float) \
+ T (double)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-2.c
new file mode 100644
index 0000000..8767efe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-2.c
@@ -0,0 +1,10 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param riscv-autovec-preference=fixed-vlmax" } */
+
+#include "single_rgroup-2.c"
+
+int main (void)
+{
+ TEST_ALL (run_1)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-3.c
new file mode 100644
index 0000000..9ff6e92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/single_rgroup_run-3.c
@@ -0,0 +1,22 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param riscv-autovec-preference=scalable" } */
+
+#include "single_rgroup-3.c"
+
+int
+main (void)
+{
+ for (int i = 0; i < N; i++)
+ cond[i] = i & 1;
+ TEST_ALL (run_1)
+ TEST_ALL (run_2)
+ TEST_ALL (run_3)
+ TEST_ALL (run_4)
+ TEST_ALL (run_5)
+ TEST_ALL (run_6)
+ TEST_ALL (run_7)
+ TEST_ALL (run_8)
+ TEST_ALL (run_9)
+ TEST_ALL (run_10)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c
new file mode 100644
index 0000000..2f2c3d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+void
+f (uint8_t *restrict a, uint8_t *restrict b,
+ uint8_t *restrict c, uint8_t *restrict d,
+ int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[i * 8] = c[i * 8] + d[i * 8];
+ a[i * 8 + 1] = c[i * 8] + d[i * 8 + 1];
+ a[i * 8 + 2] = c[i * 8 + 2] + d[i * 8 + 2];
+ a[i * 8 + 3] = c[i * 8 + 2] + d[i * 8 + 3];
+ a[i * 8 + 4] = c[i * 8 + 4] + d[i * 8 + 4];
+ a[i * 8 + 5] = c[i * 8 + 4] + d[i * 8 + 5];
+ a[i * 8 + 6] = c[i * 8 + 6] + d[i * 8 + 6];
+ a[i * 8 + 7] = c[i * 8 + 6] + d[i * 8 + 7];
+ b[i * 8] = c[i * 8 + 1] + d[i * 8];
+ b[i * 8 + 1] = c[i * 8 + 1] + d[i * 8 + 1];
+ b[i * 8 + 2] = c[i * 8 + 3] + d[i * 8 + 2];
+ b[i * 8 + 3] = c[i * 8 + 3] + d[i * 8 + 3];
+ b[i * 8 + 4] = c[i * 8 + 5] + d[i * 8 + 4];
+ b[i * 8 + 5] = c[i * 8 + 5] + d[i * 8 + 5];
+ b[i * 8 + 6] = c[i * 8 + 7] + d[i * 8 + 6];
+ b[i * 8 + 7] = c[i * 8 + 7] + d[i * 8 + 7];
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 2 "optimized" } } */
+/* { dg-final { scan-assembler {\tvid\.v} } } */
+/* { dg-final { scan-assembler-not {\tvmul} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c
new file mode 100644
index 0000000..7210331
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+void
+f (float *restrict a, float *restrict b,
+ float *restrict c, float *restrict d,
+ int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[i * 4] = c[i * 4] + d[i * 4];
+ a[i * 4 + 1] = c[i * 4] + d[i * 4 + 1];
+ a[i * 4 + 2] = c[i * 4 + 2] + d[i * 4 + 2];
+ a[i * 4 + 3] = c[i * 4 + 2] + d[i * 4 + 3];
+ b[i * 4] = c[i * 4 + 1] + d[i * 4];
+ b[i * 4 + 1] = c[i * 4 + 1] + d[i * 4 + 1];
+ b[i * 4 + 2] = c[i * 4 + 3] + d[i * 4 + 2];
+ b[i * 4 + 3] = c[i * 4 + 3] + d[i * 4 + 3];
+ }
+}
+
+/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" } } */
+/* { dg-final { scan-assembler {\tvid\.v} } } */
+/* { dg-final { scan-assembler-not {\tvmul} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c
new file mode 100644
index 0000000..41ce0fc5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+void
+f (float *restrict a, float *restrict b,
+ float *restrict c, float *restrict d,
+ int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[i * 4] = c[i * 4] + d[i * 4];
+ a[i * 4 + 1] = c[i * 4] + d[i * 4 + 1];
+ a[i * 4 + 2] = c[i * 4 + 2] + d[i * 4 + 2];
+ a[i * 4 + 3] = c[i * 4 + 3] + d[i * 4 + 3];
+ b[i * 4] = c[i * 4 + 2] + d[i * 4];
+ b[i * 4 + 1] = c[i * 4 + 1] + d[i * 4 + 1];
+ b[i * 4 + 2] = c[i * 4 + 3] + d[i * 4 + 2];
+ b[i * 4 + 3] = c[i * 4 + 3] + d[i * 4 + 3];
+ }
+}
+
+/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" } } */
+/* { dg-final { scan-assembler {\tvid\.v} } } */
+/* { dg-final { scan-assembler-not {\tvmul} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-17.c
new file mode 100644
index 0000000..224db4e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-17.c
@@ -0,0 +1,84 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param riscv-autovec-preference=scalable" } */
+
+#include "slp-17.c"
+
+#define LIMIT 256
+void __attribute__ ((optimize (0)))
+f_golden (uint8_t *restrict a, uint8_t *restrict b, uint8_t *restrict c,
+ uint8_t *restrict d, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[i * 8] = c[i * 8] + d[i * 8];
+ a[i * 8 + 1] = c[i * 8] + d[i * 8 + 1];
+ a[i * 8 + 2] = c[i * 8 + 2] + d[i * 8 + 2];
+ a[i * 8 + 3] = c[i * 8 + 2] + d[i * 8 + 3];
+ a[i * 8 + 4] = c[i * 8 + 4] + d[i * 8 + 4];
+ a[i * 8 + 5] = c[i * 8 + 4] + d[i * 8 + 5];
+ a[i * 8 + 6] = c[i * 8 + 6] + d[i * 8 + 6];
+ a[i * 8 + 7] = c[i * 8 + 6] + d[i * 8 + 7];
+ b[i * 8] = c[i * 8 + 1] + d[i * 8];
+ b[i * 8 + 1] = c[i * 8 + 1] + d[i * 8 + 1];
+ b[i * 8 + 2] = c[i * 8 + 3] + d[i * 8 + 2];
+ b[i * 8 + 3] = c[i * 8 + 3] + d[i * 8 + 3];
+ b[i * 8 + 4] = c[i * 8 + 5] + d[i * 8 + 4];
+ b[i * 8 + 5] = c[i * 8 + 5] + d[i * 8 + 5];
+ b[i * 8 + 6] = c[i * 8 + 7] + d[i * 8 + 6];
+ b[i * 8 + 7] = c[i * 8 + 7] + d[i * 8 + 7];
+ }
+}
+
+int
+main (void)
+{
+#define RUN(NUM) \
+ uint8_t a_##NUM[NUM * 8 + 8] = {0}; \
+ uint8_t a_golden_##NUM[NUM * 8 + 8] = {0}; \
+ uint8_t b_##NUM[NUM * 8 + 8] = {0}; \
+ uint8_t b_golden_##NUM[NUM * 8 + 8] = {0}; \
+ uint8_t c_##NUM[NUM * 8 + 8] = {0}; \
+ uint8_t d_##NUM[NUM * 8 + 8] = {0}; \
+ for (int i = 0; i < NUM * 8 + 8; i++) \
+ { \
+ if (i % NUM == 0) \
+ c_##NUM[i] = (i + NUM) % LIMIT; \
+ else \
+ c_##NUM[i] = (i * 3) % LIMIT; \
+ if (i % 2 == 0) \
+ d_##NUM[i] = i % LIMIT; \
+ else \
+ d_##NUM[i] = (i * 7) % LIMIT; \
+ } \
+ f (a_##NUM, b_##NUM, c_##NUM, d_##NUM, NUM); \
+ f_golden (a_golden_##NUM, b_golden_##NUM, c_##NUM, d_##NUM, NUM); \
+ for (int i = 0; i < NUM * 8 + 8; i++) \
+ { \
+ if (a_##NUM[i] != a_golden_##NUM[i]) \
+ __builtin_abort (); \
+ if (b_##NUM[i] != b_golden_##NUM[i]) \
+ __builtin_abort (); \
+ }
+
+ RUN (3);
+ RUN (5);
+ RUN (15);
+ RUN (16);
+ RUN (17);
+ RUN (31);
+ RUN (32);
+ RUN (33);
+ RUN (63);
+ RUN (64);
+ RUN (65);
+ RUN (127);
+ RUN (128);
+ RUN (129);
+ RUN (239);
+ RUN (359);
+ RUN (498);
+ RUN (799);
+ RUN (977);
+ RUN (5789);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-18.c
new file mode 100644
index 0000000..7d22e1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-18.c
@@ -0,0 +1,69 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param riscv-autovec-preference=scalable" } */
+
+#include "slp-18.c"
+
+void __attribute__ ((optimize (0)))
+f_golden (float *restrict a, float *restrict b, float *restrict c,
+ float *restrict d, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[i * 4] = c[i * 4] + d[i * 4];
+ a[i * 4 + 1] = c[i * 4] + d[i * 4 + 1];
+ a[i * 4 + 2] = c[i * 4 + 2] + d[i * 4 + 2];
+ a[i * 4 + 3] = c[i * 4 + 2] + d[i * 4 + 3];
+ b[i * 4] = c[i * 4 + 1] + d[i * 4];
+ b[i * 4 + 1] = c[i * 4 + 1] + d[i * 4 + 1];
+ b[i * 4 + 2] = c[i * 4 + 3] + d[i * 4 + 2];
+ b[i * 4 + 3] = c[i * 4 + 3] + d[i * 4 + 3];
+ }
+}
+
+int
+main (void)
+{
+#define RUN(NUM) \
+ float a_##NUM[NUM * 4 + 4] = {0}; \
+ float a_golden_##NUM[NUM * 4 + 4] = {0}; \
+ float b_##NUM[NUM * 4 + 4] = {0}; \
+ float b_golden_##NUM[NUM * 4 + 4] = {0}; \
+ float c_##NUM[NUM * 4 + 4] = {0}; \
+ float d_##NUM[NUM * 4 + 4] = {0}; \
+ for (int i = 0; i < NUM * 4 + 4; i++) \
+ { \
+ c_##NUM[i] = i * 3.789 - 987.135; \
+ d_##NUM[i] = i * -13.789 + 1987.135; \
+ } \
+ f (a_##NUM, b_##NUM, c_##NUM, d_##NUM, NUM); \
+ f_golden (a_golden_##NUM, b_golden_##NUM, c_##NUM, d_##NUM, NUM); \
+ for (int i = 0; i < NUM * 4 + 4; i++) \
+ { \
+ if (a_##NUM[i] != a_golden_##NUM[i]) \
+ __builtin_abort (); \
+ if (b_##NUM[i] != b_golden_##NUM[i]) \
+ __builtin_abort (); \
+ }
+
+ RUN (3);
+ RUN (5);
+ RUN (15);
+ RUN (16);
+ RUN (17);
+ RUN (31);
+ RUN (32);
+ RUN (33);
+ RUN (63);
+ RUN (64);
+ RUN (65);
+ RUN (127);
+ RUN (128);
+ RUN (129);
+ RUN (239);
+ RUN (359);
+ RUN (498);
+ RUN (799);
+ RUN (977);
+ RUN (5789);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-19.c
new file mode 100644
index 0000000..5cd7156
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp_run-19.c
@@ -0,0 +1,69 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param riscv-autovec-preference=scalable" } */
+
+#include "slp-19.c"
+
+void __attribute__ ((optimize (0)))
+f_golden (float *restrict a, float *restrict b, float *restrict c,
+ float *restrict d, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[i * 4] = c[i * 4] + d[i * 4];
+ a[i * 4 + 1] = c[i * 4] + d[i * 4 + 1];
+ a[i * 4 + 2] = c[i * 4 + 2] + d[i * 4 + 2];
+ a[i * 4 + 3] = c[i * 4 + 3] + d[i * 4 + 3];
+ b[i * 4] = c[i * 4 + 2] + d[i * 4];
+ b[i * 4 + 1] = c[i * 4 + 1] + d[i * 4 + 1];
+ b[i * 4 + 2] = c[i * 4 + 3] + d[i * 4 + 2];
+ b[i * 4 + 3] = c[i * 4 + 3] + d[i * 4 + 3];
+ }
+}
+
+int
+main (void)
+{
+#define RUN(NUM) \
+ float a_##NUM[NUM * 4 + 4] = {0}; \
+ float a_golden_##NUM[NUM * 4 + 4] = {0}; \
+ float b_##NUM[NUM * 4 + 4] = {0}; \
+ float b_golden_##NUM[NUM * 4 + 4] = {0}; \
+ float c_##NUM[NUM * 4 + 4] = {0}; \
+ float d_##NUM[NUM * 4 + 4] = {0}; \
+ for (int i = 0; i < NUM * 4 + 4; i++) \
+ { \
+ c_##NUM[i] = i * 3.789 - 987.135; \
+ d_##NUM[i] = i * -13.789 + 1987.135; \
+ } \
+ f (a_##NUM, b_##NUM, c_##NUM, d_##NUM, NUM); \
+ f_golden (a_golden_##NUM, b_golden_##NUM, c_##NUM, d_##NUM, NUM); \
+ for (int i = 0; i < NUM * 4 + 4; i++) \
+ { \
+ if (a_##NUM[i] != a_golden_##NUM[i]) \
+ __builtin_abort (); \
+ if (b_##NUM[i] != b_golden_##NUM[i]) \
+ __builtin_abort (); \
+ }
+
+ RUN (3);
+ RUN (5);
+ RUN (15);
+ RUN (16);
+ RUN (17);
+ RUN (31);
+ RUN (32);
+ RUN (33);
+ RUN (63);
+ RUN (64);
+ RUN (65);
+ RUN (127);
+ RUN (128);
+ RUN (129);
+ RUN (239);
+ RUN (359);
+ RUN (498);
+ RUN (799);
+ RUN (977);
+ RUN (5789);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c
index 1996ca6..4420001 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -20,9 +20,13 @@
TEST_TYPE (int32_t) \
TEST_TYPE (uint32_t) \
TEST_TYPE (int64_t) \
- TEST_TYPE (uint64_t)
+ TEST_TYPE (uint64_t) \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvmadd\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmadd\.vv} 3 } } */
/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c
new file mode 100644
index 0000000..fc66def
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dst, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = -(a[i] * b[i]) - dst[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfnmadd\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c
new file mode 100644
index 0000000..23c542f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1, \
+ TYPE *__restrict dest2, \
+ TYPE *__restrict dest3, \
+ TYPE *__restrict src1, \
+ TYPE *__restrict src2, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ { \
+ dest1[i] = -(src1[i] * src2[i]) - dest1[i]; \
+ dest2[i] = src1[i] * dest1[i] - dest2[i]; \
+ dest3[i] = src2[i] * dest2[i] - dest3[i]; \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfnmacc\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c
new file mode 100644
index 0000000..8ec261b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1, \
+ TYPE *__restrict dest2, \
+ TYPE *__restrict dest3, \
+ TYPE *__restrict src1, \
+ TYPE *__restrict src2, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ { \
+ dest1[i] = -(src1[i] * src2[i]) - dest2[i]; \
+ dest2[i] = src1[i] * dest1[i] - dest2[i]; \
+ dest3[i] = src2[i] * dest2[i] - dest3[i]; \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvmv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c
index e52e07d..ad2673a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
#include <stdint-gcc.h>
@@ -26,9 +26,13 @@
TEST_TYPE (int32_t) \
TEST_TYPE (uint32_t) \
TEST_TYPE (int64_t) \
- TEST_TYPE (uint64_t)
+ TEST_TYPE (uint64_t) \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvmacc\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmacc\.vv} 3 } } */
/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c
index 127e701..cd97f4d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -26,8 +26,11 @@
TEST_TYPE (int32_t) \
TEST_TYPE (uint32_t) \
TEST_TYPE (int64_t) \
- TEST_TYPE (uint64_t)
+ TEST_TYPE (uint64_t) \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
TEST_ALL ()
-/* { dg-final { scan-assembler-times {\tvmv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvmv} 11 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c
index 1b8b934..a225ea0 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -20,9 +20,13 @@
TEST_TYPE (int32_t) \
TEST_TYPE (uint32_t) \
TEST_TYPE (int64_t) \
- TEST_TYPE (uint64_t)
+ TEST_TYPE (uint64_t) \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvnmsub\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfnmsub\.vv} 3 } } */
/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c
index 49c85efb..12dfa0a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
#include <stdint-gcc.h>
@@ -26,9 +26,13 @@
TEST_TYPE (int32_t) \
TEST_TYPE (uint32_t) \
TEST_TYPE (int64_t) \
- TEST_TYPE (uint64_t)
+ TEST_TYPE (uint64_t) \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvnmsac\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfnmsac\.vv} 3 } } */
/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c
index f38f303..b83590f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -26,8 +26,11 @@
TEST_TYPE (int32_t) \
TEST_TYPE (uint32_t) \
TEST_TYPE (int64_t) \
- TEST_TYPE (uint64_t)
+ TEST_TYPE (uint64_t) \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
TEST_ALL ()
-/* { dg-final { scan-assembler-times {\tvmv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvmv} 11 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c
new file mode 100644
index 0000000..0f80da4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dst, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = a[i] * b[i] - dst[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfmsub\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c
new file mode 100644
index 0000000..ae65298
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1, \
+ TYPE *__restrict dest2, \
+ TYPE *__restrict dest3, \
+ TYPE *__restrict src1, \
+ TYPE *__restrict src2, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ { \
+ dest1[i] = src1[i] * src2[i] - dest1[i]; \
+ dest2[i] = src1[i] * dest1[i] - dest2[i]; \
+ dest3[i] = src2[i] * dest2[i] - dest3[i]; \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfmsac\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c
new file mode 100644
index 0000000..299bd2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1, \
+ TYPE *__restrict dest2, \
+ TYPE *__restrict dest3, \
+ TYPE *__restrict src1, \
+ TYPE *__restrict src2, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ { \
+ dest1[i] = src1[i] * src2[i] - dest2[i]; \
+ dest2[i] = src1[i] * dest1[i] - dest2[i]; \
+ dest3[i] = src2[i] * dest2[i] - dest3[i]; \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvmv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c
index 1f69b69..e0ec9ed 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include "ternop-1.c"
@@ -80,5 +80,15 @@ int __attribute__ ((optimize (0))) main ()
TEST_LOOP (int64_t, 795)
TEST_LOOP (uint64_t, 795)
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
return 0;
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c
new file mode 100644
index 0000000..854827f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c
@@ -0,0 +1,40 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-10.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 3 - i; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (array3_##NUM[i] \
+ != (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array4_##NUM[i])) \
+ __builtin_abort (); \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c
new file mode 100644
index 0000000..b5a0845
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c
@@ -0,0 +1,60 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-11.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array6_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c
new file mode 100644
index 0000000..c7c4b4b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c
@@ -0,0 +1,60 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-12.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array7_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c
index 103b98a..ee7c725 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include "ternop-2.c"
@@ -100,5 +100,15 @@ int __attribute__ ((optimize (0))) main ()
TEST_LOOP (int64_t, 795)
TEST_LOOP (uint64_t, 795)
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
return 0;
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c
index eac5408..6c4f28e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include "ternop-3.c"
@@ -100,5 +100,15 @@ int __attribute__ ((optimize (0))) main ()
TEST_LOOP (int64_t, 795)
TEST_LOOP (uint64_t, 795)
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
return 0;
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c
index c6f1fe5..44a4771 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include "ternop-4.c"
@@ -80,5 +80,15 @@ int __attribute__ ((optimize (0))) main ()
TEST_LOOP (int64_t, 795)
TEST_LOOP (uint64_t, 795)
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
return 0;
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c
index 81af4b6..efe2f36 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include "ternop-5.c"
@@ -100,5 +100,15 @@ int __attribute__ ((optimize (0))) main ()
TEST_LOOP (int64_t, 795)
TEST_LOOP (uint64_t, 795)
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
return 0;
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c
index b5e579e..f1ce6a7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include "ternop-6.c"
@@ -100,5 +100,15 @@ int __attribute__ ((optimize (0))) main ()
TEST_LOOP (int64_t, 795)
TEST_LOOP (uint64_t, 795)
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
return 0;
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c
new file mode 100644
index 0000000..1809b23
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c
@@ -0,0 +1,40 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-7.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 3 - i; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (array3_##NUM[i] \
+ != (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array4_##NUM[i])) \
+ __builtin_abort (); \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c
new file mode 100644
index 0000000..f048652
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c
@@ -0,0 +1,60 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-8.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array6_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c
new file mode 100644
index 0000000..dcf87f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c
@@ -0,0 +1,60 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-9.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array7_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (float, 7)
+ TEST_LOOP (double, 7)
+ TEST_LOOP (float, 16)
+ TEST_LOOP (double, 16)
+ TEST_LOOP (float, 77)
+ TEST_LOOP (double, 77)
+ TEST_LOOP (float, 128)
+ TEST_LOOP (double, 128)
+ TEST_LOOP (float, 795)
+ TEST_LOOP (double, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c
new file mode 100644
index 0000000..84fcb68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-1.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 3 - i; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (array3_##NUM[i] \
+ != (TYPE) (array1_##NUM[i] * array2_##NUM[i] + array4_##NUM[i])) \
+ __builtin_abort (); \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c
new file mode 100644
index 0000000..d669cd4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-10.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 3 - i; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (array3_##NUM[i] \
+ != (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array4_##NUM[i])) \
+ __builtin_abort (); \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c
new file mode 100644
index 0000000..fac17b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-11.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array6_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c
new file mode 100644
index 0000000..a51b926
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-12.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array7_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c
new file mode 100644
index 0000000..8fc6a1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-2.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array2_##NUM[i] + array6_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c
new file mode 100644
index 0000000..3601307
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-3.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array2_##NUM[i] + array7_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c
new file mode 100644
index 0000000..a26bcaa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-4.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 3 - i; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (array3_##NUM[i] \
+ != (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) + array4_##NUM[i])) \
+ __builtin_abort (); \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c
new file mode 100644
index 0000000..6dee6ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-5.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) + array6_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c
new file mode 100644
index 0000000..3fdf2d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-6.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) + array7_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c
new file mode 100644
index 0000000..a25a6f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-7.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 3 - i; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ if (array3_##NUM[i] \
+ != (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array4_##NUM[i])) \
+ __builtin_abort (); \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c
new file mode 100644
index 0000000..1d90bee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-8.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array6_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c
new file mode 100644
index 0000000..c633f54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-9.c"
+
+#define TEST_LOOP(TYPE, NUM) \
+ { \
+ TYPE array1_##NUM[NUM] = {}; \
+ TYPE array2_##NUM[NUM] = {}; \
+ TYPE array3_##NUM[NUM] = {}; \
+ TYPE array4_##NUM[NUM] = {}; \
+ TYPE array5_##NUM[NUM] = {}; \
+ TYPE array6_##NUM[NUM] = {}; \
+ TYPE array7_##NUM[NUM] = {}; \
+ TYPE array8_##NUM[NUM] = {}; \
+ for (int i = 0; i < NUM; ++i) \
+ { \
+ array1_##NUM[i] = (i & 1) + 5; \
+ array2_##NUM[i] = i - NUM / 3; \
+ array3_##NUM[i] = NUM - NUM / 3 - i; \
+ array6_##NUM[i] = NUM - NUM / 3 - i; \
+ array4_##NUM[i] = NUM - NUM / 2 + i; \
+ array7_##NUM[i] = NUM - NUM / 2 + i; \
+ array5_##NUM[i] = NUM + i * 7; \
+ array8_##NUM[i] = NUM + i * 7; \
+ asm volatile("" ::: "memory"); \
+ } \
+ ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM, \
+ array2_##NUM, NUM); \
+ for (int i = 0; i < NUM; i++) \
+ { \
+ array6_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array7_##NUM[i]); \
+ if (array3_##NUM[i] != array6_##NUM[i]) \
+ __builtin_abort (); \
+ array7_##NUM[i] \
+ = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]); \
+ if (array4_##NUM[i] != array7_##NUM[i]) \
+ __builtin_abort (); \
+ array8_##NUM[i] \
+ = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]); \
+ if (array5_##NUM[i] != array8_##NUM[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (0))) main ()
+{
+ TEST_LOOP (_Float16, 7)
+ TEST_LOOP (_Float16, 16)
+ TEST_LOOP (_Float16, 77)
+ TEST_LOOP (_Float16, 128)
+ TEST_LOOP (_Float16, 795)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c
index 00edeca..e2ec4ee 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -19,9 +19,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwadd\.vv} 3 } } */
/* { dg-final { scan-assembler-times {\tvwaddu\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwadd\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c
new file mode 100644
index 0000000..490f1a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vwmacc_##TYPE1_##TYPE2 (TYPE1 *__restrict dst, \
+ TYPE2 *__restrict a, \
+ TYPE2 *__restrict b, \
+ int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] += -((TYPE1) a[i] * (TYPE1) b[i]); \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfwnmsac\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c
new file mode 100644
index 0000000..4d44a40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vwmacc_##TYPE1_##TYPE2 (TYPE1 *__restrict dst, \
+ TYPE2 *__restrict a, \
+ TYPE2 *__restrict b, \
+ int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = (TYPE1) a[i] * (TYPE1) b[i] - dst[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfwmsac\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c
new file mode 100644
index 0000000..2cb2a1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vwmacc_##TYPE1_##TYPE2 (TYPE1 *__restrict dst, \
+ TYPE2 *__restrict a, \
+ TYPE2 *__restrict b, \
+ int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = -((TYPE1) a[i] * (TYPE1) b[i]) - dst[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfwnmacc\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c
index 4d370f5..246acf2 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -19,9 +19,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwsub\.vv} 3 } } */
/* { dg-final { scan-assembler-times {\tvwsubu\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwsub\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c
index 609a5c0..b2b1440 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -19,9 +19,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwmul\.vv} 3 } } */
/* { dg-final { scan-assembler-times {\tvwmulu\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwmul\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c
index 7f89092..62b121d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -19,9 +19,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwadd\.wv} 3 } } */
/* { dg-final { scan-assembler-times {\tvwaddu\.wv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwadd\.wv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c
index f9542d7..cd48537 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -19,9 +19,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwsub\.wv} 3 } } */
/* { dg-final { scan-assembler-times {\tvwsubu\.wv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwsub\.wv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c
index cc43d9b..3806e8b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -19,9 +19,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvsext\.vf2} 3 } } */
/* { dg-final { scan-assembler-times {\tvzext\.vf2} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwcvt} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c
index f3ca07c..8f41bdf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -19,9 +19,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwmacc\.vv} 3 } } */
/* { dg-final { scan-assembler-times {\tvwmaccu\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwmacc\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c
index baf91b7..83e16c6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -23,9 +23,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwadd\.vv} 9 } } */
/* { dg-final { scan-assembler-times {\tvwaddu\.vv} 9 } } */
+/* { dg-final { scan-assembler-times {\tvfwadd\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c
index 6d1709b..97036e6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -23,9 +23,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwsub\.vv} 9 } } */
/* { dg-final { scan-assembler-times {\tvwsubu\.vv} 9 } } */
+/* { dg-final { scan-assembler-times {\tvfwsub\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c
index e1fd794..1515374 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -24,9 +24,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwmul\.vv} 12 } } */
/* { dg-final { scan-assembler-times {\tvwmulu\.vv} 12 } } */
+/* { dg-final { scan-assembler-times {\tvfwmul\.vv} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c
index 187b6db..3ff8483 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
#include <stdint-gcc.h>
@@ -24,9 +24,12 @@
TEST_TYPE (int32_t, int16_t) \
TEST_TYPE (uint32_t, uint16_t) \
TEST_TYPE (int64_t, int32_t) \
- TEST_TYPE (uint64_t, uint32_t)
+ TEST_TYPE (uint64_t, uint32_t) \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
TEST_ALL ()
/* { dg-final { scan-assembler-times {\tvwmacc\.vv} 12 } } */
/* { dg-final { scan-assembler-times {\tvwmaccu\.vv} 12 } } */
+/* { dg-final { scan-assembler-times {\tvfwmacc\.vv} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c
new file mode 100644
index 0000000..2e3f666
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vwadd_##TYPE1_##TYPE2 ( \
+ TYPE1 *__restrict dst, TYPE1 *__restrict dst2, TYPE1 *__restrict dst3, \
+ TYPE1 *__restrict dst4, TYPE2 *__restrict a, TYPE2 *__restrict b, \
+ TYPE2 *__restrict a2, TYPE2 *__restrict b2, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ { \
+ dst[i] += -((TYPE1) a[i] * (TYPE1) b[i]); \
+ dst2[i] += -((TYPE1) a2[i] * (TYPE1) b[i]); \
+ dst3[i] += -((TYPE1) a2[i] * (TYPE1) a[i]); \
+ dst4[i] += -((TYPE1) a[i] * (TYPE1) b2[i]); \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfwnmsac\.vv} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c
new file mode 100644
index 0000000..2acfbd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vwadd_##TYPE1_##TYPE2 ( \
+ TYPE1 *__restrict dst, TYPE1 *__restrict dst2, TYPE1 *__restrict dst3, \
+ TYPE1 *__restrict dst4, TYPE2 *__restrict a, TYPE2 *__restrict b, \
+ TYPE2 *__restrict a2, TYPE2 *__restrict b2, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ { \
+ dst[i] = (TYPE1) a[i] * (TYPE1) b[i] - dst[i]; \
+ dst2[i] = (TYPE1) a2[i] * (TYPE1) b[i] - dst2[i]; \
+ dst3[i] = (TYPE1) a2[i] * (TYPE1) a[i] - dst3[i]; \
+ dst4[i] = (TYPE1) a[i] * (TYPE1) b2[i] - dst4[i]; \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfwmsac\.vv} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c
new file mode 100644
index 0000000..da7f870
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE1, TYPE2) \
+ __attribute__ ((noipa)) void vwadd_##TYPE1_##TYPE2 ( \
+ TYPE1 *__restrict dst, TYPE1 *__restrict dst2, TYPE1 *__restrict dst3, \
+ TYPE1 *__restrict dst4, TYPE2 *__restrict a, TYPE2 *__restrict b, \
+ TYPE2 *__restrict a2, TYPE2 *__restrict b2, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ { \
+ dst[i] = -((TYPE1) a[i] * (TYPE1) b[i]) - dst[i]; \
+ dst2[i] = -((TYPE1) a2[i] * (TYPE1) b[i]) - dst2[i]; \
+ dst3[i] = -((TYPE1) a2[i] * (TYPE1) a[i]) - dst3[i]; \
+ dst4[i] = -((TYPE1) a[i] * (TYPE1) b2[i]) - dst4[i]; \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (float, _Float16) \
+ TEST_TYPE (double, float)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfwnmacc\.vv} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c
index 6cdeb57..21d0934 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include <assert.h>
#include "widen-1.c"
@@ -25,7 +25,8 @@
RUN (int32_t, int16_t, -32768) \
RUN (uint32_t, uint16_t, 65535) \
RUN (int64_t, int32_t, -2147483648) \
- RUN (uint64_t, uint32_t, 4294967295)
+ RUN (uint64_t, uint32_t, 4294967295) \
+ RUN (double, float, -2147483648)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-10.c
new file mode 100644
index 0000000..262660c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-10.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-10.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ TYPE1 dst2##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ dst##TYPE1[i] = LIMIT + i & 628; \
+ dst2##TYPE1[i] = LIMIT + i & 628; \
+ } \
+ vwmacc_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] \
+ == -((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]) + dst2##TYPE1[i]);
+
+#define RUN_ALL() RUN (double, float, -2147483648)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-11.c
new file mode 100644
index 0000000..246999c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-11.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-11.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ TYPE1 dst2##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ dst##TYPE1[i] = LIMIT + i & 628; \
+ dst2##TYPE1[i] = LIMIT + i & 628; \
+ } \
+ vwmacc_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] \
+ == ((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]) - dst2##TYPE1[i]);
+
+#define RUN_ALL() RUN (double, float, -2147483648)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-12.c
new file mode 100644
index 0000000..2a6a03b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-12.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-12.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ TYPE1 dst2##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ dst##TYPE1[i] = LIMIT + i & 628; \
+ dst2##TYPE1[i] = LIMIT + i & 628; \
+ } \
+ vwmacc_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] \
+ == -((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]) - dst2##TYPE1[i]);
+
+#define RUN_ALL() RUN (double, float, -2147483648)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c
index 84baa51..e5805a9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include <assert.h>
#include "widen-2.c"
@@ -25,7 +25,8 @@
RUN (int32_t, int16_t, -32768) \
RUN (uint32_t, uint16_t, 65535) \
RUN (int64_t, int32_t, -2147483648) \
- RUN (uint64_t, uint32_t, 4294967295)
+ RUN (uint64_t, uint32_t, 4294967295) \
+ RUN (double, float, -2147483648)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-3.c
index beb0cc2..b7dd60f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-3.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include <assert.h>
#include "widen-3.c"
@@ -25,7 +25,8 @@
RUN (int32_t, int16_t, -32768) \
RUN (uint32_t, uint16_t, 65535) \
RUN (int64_t, int32_t, -2147483648) \
- RUN (uint64_t, uint32_t, 4294967295)
+ RUN (uint64_t, uint32_t, 4294967295) \
+ RUN (double, float, -2147483648)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c
index ca16585..d94f704 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include <assert.h>
#include "widen-5.c"
@@ -25,7 +25,8 @@
RUN (int32_t, int16_t, -32768) \
RUN (uint32_t, uint16_t, 65535) \
RUN (int64_t, int32_t, -2147483648) \
- RUN (uint64_t, uint32_t, 4294967295)
+ RUN (uint64_t, uint32_t, 4294967295) \
+ RUN (double, float, -2147483648)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c
index 5b69c2a..6c4ccec 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include <assert.h>
#include "widen-6.c"
@@ -25,7 +25,8 @@
RUN (int32_t, int16_t, -32768) \
RUN (uint32_t, uint16_t, 65535) \
RUN (int64_t, int32_t, -2147483648) \
- RUN (uint64_t, uint32_t, 4294967295)
+ RUN (uint64_t, uint32_t, 4294967295) \
+ RUN (double, float, -2147483648)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-7.c
index 4abddd5..ab29f4a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-7.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include <assert.h>
#include "widen-7.c"
@@ -25,7 +25,8 @@
RUN (int32_t, int16_t, -32768) \
RUN (uint32_t, uint16_t, 65535) \
RUN (int64_t, int32_t, -2147483648) \
- RUN (uint64_t, uint32_t, 4294967295)
+ RUN (uint64_t, uint32_t, 4294967295) \
+ RUN (double, float, -2147483648)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-8.c
index f4840d3..1509500 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-8.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
#include <assert.h>
#include "widen-8.c"
@@ -29,7 +29,8 @@
RUN (int32_t, int16_t, -32768) \
RUN (uint32_t, uint16_t, 65535) \
RUN (int64_t, int32_t, -2147483648) \
- RUN (uint64_t, uint32_t, 4294967295)
+ RUN (uint64_t, uint32_t, 4294967295) \
+ RUN (double, float, -2147483648)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c
new file mode 100644
index 0000000..e70f06f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-1.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ } \
+ vwadd_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] == ((TYPE1) a##TYPE2[i] + (TYPE1) b##TYPE2[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-10.c
new file mode 100644
index 0000000..f678c35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-10.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-10.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ TYPE1 dst2##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ dst##TYPE1[i] = LIMIT + i & 628; \
+ dst2##TYPE1[i] = LIMIT + i & 628; \
+ } \
+ vwmacc_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] \
+ == -((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]) + dst2##TYPE1[i]);
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-11.c
new file mode 100644
index 0000000..294f77d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-11.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-11.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ TYPE1 dst2##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ dst##TYPE1[i] = LIMIT + i & 628; \
+ dst2##TYPE1[i] = LIMIT + i & 628; \
+ } \
+ vwmacc_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] \
+ == ((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]) - dst2##TYPE1[i]);
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-12.c
new file mode 100644
index 0000000..013291c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-12.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-12.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ TYPE1 dst2##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ dst##TYPE1[i] = LIMIT + i & 628; \
+ dst2##TYPE1[i] = LIMIT + i & 628; \
+ } \
+ vwmacc_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] \
+ == -((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]) - dst2##TYPE1[i]);
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c
new file mode 100644
index 0000000..e07a828
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-2.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ } \
+ vwsub_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] == ((TYPE1) a##TYPE2[i] - (TYPE1) b##TYPE2[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-3.c
new file mode 100644
index 0000000..c3efd0b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-3.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-3.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ } \
+ vwmul_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] == ((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c
new file mode 100644
index 0000000..144e3d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-5.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE1 b##TYPE1[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE1[i] = LIMIT + i & 1964; \
+ } \
+ vwadd_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE1, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] == ((TYPE1) a##TYPE2[i] + (TYPE1) b##TYPE1[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c
new file mode 100644
index 0000000..006dade
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-6.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE1 a##TYPE1[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE1[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ } \
+ vwsub_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE1, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] == ((TYPE1) a##TYPE1[i] - (TYPE1) b##TYPE2[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-7.c
new file mode 100644
index 0000000..60e2401c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-7.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-7.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE1 b##TYPE1[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % LIMIT; \
+ b##TYPE1[i] = LIMIT + i & LIMIT; \
+ } \
+ vwmul_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE1, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] == (((TYPE1) a##TYPE2[i]) * b##TYPE1[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-8.c
new file mode 100644
index 0000000..63563b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-8.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-8.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT) \
+ TYPE2 a##TYPE2[SZ]; \
+ TYPE2 b##TYPE2[SZ]; \
+ TYPE1 dst##TYPE1[SZ]; \
+ TYPE1 dst2##TYPE1[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE2[i] = LIMIT + i % 8723; \
+ b##TYPE2[i] = LIMIT + i & 1964; \
+ dst##TYPE1[i] = LIMIT + i & 628; \
+ dst2##TYPE1[i] = LIMIT + i & 628; \
+ } \
+ vwmacc_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE1[i] \
+ == ((TYPE1) a##TYPE2[i] * (TYPE1) b##TYPE2[i]) + dst2##TYPE1[i]);
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvfhmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvfhmin-1.c
index 109fcbc..1c41790 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvfhmin-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvfhmin-1.c
@@ -1,5 +1,7 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv32gcv_zvfhmin -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */
+/* { dg-options "-march=rv32gcv_zvfhmin -mabi=ilp32d --param riscv-autovec-preference=scalable -ffast-math -fdump-rtl-final" } */
+
+#include <stdint-gcc.h>
void f0 (_Float16 * __restrict a, _Float16 * __restrict b, int n)
{
@@ -40,10 +42,44 @@ void f6 (_Float16 * __restrict a, _Float16 * __restrict b, int n)
void f7 (_Float16 * __restrict a, _Float16 * __restrict b, int n)
{
for (int i = 0; i < n; i++)
- a[i] = __builtin_sqrtf (b[i]);
+ a[i] = __builtin_sqrtf16 (b[i]);
+}
+
+void f8 (_Float16 * __restrict a, int16_t * __restrict b, int n)
+{
+ for (int i = 0; i < n; i++)
+ a[i] = (_Float16) (b[i]);
+}
+
+void f9 (_Float16 * __restrict a, uint16_t * __restrict b, int n)
+{
+ for (int i = 0; i < n; i++)
+ a[i] = (_Float16) (b[i]);
+}
+
+void f10 (int16_t * __restrict a, _Float16 * __restrict b, int n)
+{
+ for (int i = 0; i < n; i++)
+ a[i] = (int16_t) (b[i]);
+}
+
+void f11 (uint16_t * __restrict a, _Float16 * __restrict b, int n)
+{
+ for (int i = 0; i < n; i++)
+ a[i] = (uint16_t) (b[i]);
}
-/* We can't enable FP16 NEG/PLUS/MINUS/MULT/DIV/ABS/SQRTF auto-vectorization
- when -march="*zvfhmin*" because the min variant of the extension only
- provides loads, stores and conversions. */
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 0 "vect" } } */
+/* We can't enable FP16 NEG/PLUS/MINUS/MULT/DIV/ABS/SQRTF as well as int/float
+ conversion auto-vectorization when -march="*zvfhmin*" because the min
+ variant of the extension only provides loads, stores and conversions.
+ As we might still vectorize after promotion to float, we need to make
+ sure that no vector operations with an HFmode are being generated. */
+/* { dg-final { scan-rtl-dump-not "plus:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "minus:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "mult:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "div:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "neg:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "abs:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "sqrt:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "float:VNx\[0-9\]+HF" "final" } } */
+/* { dg-final { scan-rtl-dump-not "fix:VNx\[0-9\]+HI\s*.+reg:VNx\[0-9\]+HF" "final" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-10.c
index 62dd7c8..53ee24b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-10.c
@@ -173,6 +173,31 @@ void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;}
void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;}
void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;}
void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;}
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x2_t'} } */
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x3_t'} } */
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x4_t'} } */
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x5_t'} } */
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x6_t'} } */
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x7_t'} } */
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x8_t'} } */
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x2_t'} } */
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x3_t'} } */
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x4_t'} } */
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x5_t'} } */
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x6_t'} } */
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x7_t'} } */
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x8_t'} } */
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;} /* { dg-error {unknown type name '__rvv_float16m1x2_t'} } */
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;} /* { dg-error {unknown type name '__rvv_float16m1x3_t'} } */
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;} /* { dg-error {unknown type name '__rvv_float16m1x4_t'} } */
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;} /* { dg-error {unknown type name '__rvv_float16m1x5_t'} } */
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;} /* { dg-error {unknown type name '__rvv_float16m1x6_t'} } */
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;} /* { dg-error {unknown type name '__rvv_float16m1x7_t'} } */
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;} /* { dg-error {unknown type name '__rvv_float16m1x8_t'} } */
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;} /* { dg-error {unknown type name '__rvv_float16m2x2_t'} } */
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;} /* { dg-error {unknown type name '__rvv_float16m2x3_t'} } */
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;} /* { dg-error {unknown type name '__rvv_float16m2x4_t'} } */
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;} /* { dg-error {unknown type name '__rvv_float16m4x2_t'} } */
void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x2_t'} } */
void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x3_t'} } */
void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x4_t'} } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-11.c
index a524b41..66ce59b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-11.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -march=rv32gc_zve64f -mabi=ilp32d" } */
+/* { dg-options "-O3 -march=rv32gc_zve64f_zvfhmin -mabi=ilp32d" } */
void f___rvv_int8mf8x2_t () {__rvv_int8mf8x2_t t;}
void f___rvv_uint8mf8x2_t () {__rvv_uint8mf8x2_t t;}
@@ -173,6 +173,31 @@ void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;}
void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;}
void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;}
void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;}
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;}
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;}
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;}
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;}
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;}
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;}
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;}
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;}
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;}
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;}
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;}
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;}
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;}
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;}
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;}
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;}
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;}
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;}
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;}
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;}
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;}
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;}
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;}
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;}
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;}
void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;}
void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;}
void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-12.c
index 925aa9e..d05e3cb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-12.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-12.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -march=rv32gc_zve64d -mabi=ilp32d" } */
+/* { dg-options "-O3 -march=rv32gc_zve64d_zvfhmin -mabi=ilp32d" } */
void f___rvv_int8mf8x2_t () {__rvv_int8mf8x2_t t;}
void f___rvv_uint8mf8x2_t () {__rvv_uint8mf8x2_t t;}
@@ -173,6 +173,31 @@ void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;}
void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;}
void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;}
void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;}
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;}
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;}
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;}
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;}
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;}
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;}
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;}
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;}
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;}
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;}
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;}
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;}
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;}
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;}
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;}
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;}
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;}
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;}
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;}
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;}
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;}
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;}
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;}
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;}
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;}
void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;}
void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;}
void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-15.c
index b52d86c6..c1e5b1a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-15.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-15.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -march=rv32gc_zve32f -mabi=ilp32d" } */
+/* { dg-options "-O3 -march=rv32gc_zve32f_zvfhmin -mabi=ilp32d" } */
void f___rvv_int8mf8x2_t () {__rvv_int8mf8x2_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x2_t'} } */
void f___rvv_uint8mf8x2_t () {__rvv_uint8mf8x2_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x2_t'} } */
@@ -173,6 +173,31 @@ void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;} /* { dg-error {unknown type n
void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x4_t'} } */
void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;} /* { dg-error {unknown type name '__rvv_int64m4x2_t'} } */
void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m4x2_t'} } */
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x2_t'} } */
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x3_t'} } */
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x4_t'} } */
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x5_t'} } */
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x6_t'} } */
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x7_t'} } */
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x8_t'} } */
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;}
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;}
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;}
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;}
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;}
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;}
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;}
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;}
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;}
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;}
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;}
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;}
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;}
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;}
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;}
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;}
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;}
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;}
void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x2_t'} } */
void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x3_t'} } */
void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x4_t'} } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-17.c
new file mode 100644
index 0000000..79715e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-17.c
@@ -0,0 +1,229 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv32gc_zve32x_zvfhmin -mabi=ilp32d" } */
+
+void f___rvv_int8mf8x2_t () {__rvv_int8mf8x2_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x2_t'} } */
+void f___rvv_uint8mf8x2_t () {__rvv_uint8mf8x2_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x2_t'} } */
+void f___rvv_int8mf8x3_t () {__rvv_int8mf8x3_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x3_t'} } */
+void f___rvv_uint8mf8x3_t () {__rvv_uint8mf8x3_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x3_t'} } */
+void f___rvv_int8mf8x4_t () {__rvv_int8mf8x4_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x4_t'} } */
+void f___rvv_uint8mf8x4_t () {__rvv_uint8mf8x4_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x4_t'} } */
+void f___rvv_int8mf8x5_t () {__rvv_int8mf8x5_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x5_t'} } */
+void f___rvv_uint8mf8x5_t () {__rvv_uint8mf8x5_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x5_t'} } */
+void f___rvv_int8mf8x6_t () {__rvv_int8mf8x6_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x6_t'} } */
+void f___rvv_uint8mf8x6_t () {__rvv_uint8mf8x6_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x6_t'} } */
+void f___rvv_int8mf8x7_t () {__rvv_int8mf8x7_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x7_t'} } */
+void f___rvv_uint8mf8x7_t () {__rvv_uint8mf8x7_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x7_t'} } */
+void f___rvv_int8mf8x8_t () {__rvv_int8mf8x8_t t;} /* { dg-error {unknown type name '__rvv_int8mf8x8_t'} } */
+void f___rvv_uint8mf8x8_t () {__rvv_uint8mf8x8_t t;} /* { dg-error {unknown type name '__rvv_uint8mf8x8_t'} } */
+void f___rvv_int8mf4x2_t () {__rvv_int8mf4x2_t t;}
+void f___rvv_uint8mf4x2_t () {__rvv_uint8mf4x2_t t;}
+void f___rvv_int8mf4x3_t () {__rvv_int8mf4x3_t t;}
+void f___rvv_uint8mf4x3_t () {__rvv_uint8mf4x3_t t;}
+void f___rvv_int8mf4x4_t () {__rvv_int8mf4x4_t t;}
+void f___rvv_uint8mf4x4_t () {__rvv_uint8mf4x4_t t;}
+void f___rvv_int8mf4x5_t () {__rvv_int8mf4x5_t t;}
+void f___rvv_uint8mf4x5_t () {__rvv_uint8mf4x5_t t;}
+void f___rvv_int8mf4x6_t () {__rvv_int8mf4x6_t t;}
+void f___rvv_uint8mf4x6_t () {__rvv_uint8mf4x6_t t;}
+void f___rvv_int8mf4x7_t () {__rvv_int8mf4x7_t t;}
+void f___rvv_uint8mf4x7_t () {__rvv_uint8mf4x7_t t;}
+void f___rvv_int8mf4x8_t () {__rvv_int8mf4x8_t t;}
+void f___rvv_uint8mf4x8_t () {__rvv_uint8mf4x8_t t;}
+void f___rvv_int8mf2x2_t () {__rvv_int8mf2x2_t t;}
+void f___rvv_uint8mf2x2_t () {__rvv_uint8mf2x2_t t;}
+void f___rvv_int8mf2x3_t () {__rvv_int8mf2x3_t t;}
+void f___rvv_uint8mf2x3_t () {__rvv_uint8mf2x3_t t;}
+void f___rvv_int8mf2x4_t () {__rvv_int8mf2x4_t t;}
+void f___rvv_uint8mf2x4_t () {__rvv_uint8mf2x4_t t;}
+void f___rvv_int8mf2x5_t () {__rvv_int8mf2x5_t t;}
+void f___rvv_uint8mf2x5_t () {__rvv_uint8mf2x5_t t;}
+void f___rvv_int8mf2x6_t () {__rvv_int8mf2x6_t t;}
+void f___rvv_uint8mf2x6_t () {__rvv_uint8mf2x6_t t;}
+void f___rvv_int8mf2x7_t () {__rvv_int8mf2x7_t t;}
+void f___rvv_uint8mf2x7_t () {__rvv_uint8mf2x7_t t;}
+void f___rvv_int8mf2x8_t () {__rvv_int8mf2x8_t t;}
+void f___rvv_uint8mf2x8_t () {__rvv_uint8mf2x8_t t;}
+void f___rvv_int8m1x2_t () {__rvv_int8m1x2_t t;}
+void f___rvv_uint8m1x2_t () {__rvv_uint8m1x2_t t;}
+void f___rvv_int8m1x3_t () {__rvv_int8m1x3_t t;}
+void f___rvv_uint8m1x3_t () {__rvv_uint8m1x3_t t;}
+void f___rvv_int8m1x4_t () {__rvv_int8m1x4_t t;}
+void f___rvv_uint8m1x4_t () {__rvv_uint8m1x4_t t;}
+void f___rvv_int8m1x5_t () {__rvv_int8m1x5_t t;}
+void f___rvv_uint8m1x5_t () {__rvv_uint8m1x5_t t;}
+void f___rvv_int8m1x6_t () {__rvv_int8m1x6_t t;}
+void f___rvv_uint8m1x6_t () {__rvv_uint8m1x6_t t;}
+void f___rvv_int8m1x7_t () {__rvv_int8m1x7_t t;}
+void f___rvv_uint8m1x7_t () {__rvv_uint8m1x7_t t;}
+void f___rvv_int8m1x8_t () {__rvv_int8m1x8_t t;}
+void f___rvv_uint8m1x8_t () {__rvv_uint8m1x8_t t;}
+void f___rvv_int8m2x2_t () {__rvv_int8m2x2_t t;}
+void f___rvv_uint8m2x2_t () {__rvv_uint8m2x2_t t;}
+void f___rvv_int8m2x3_t () {__rvv_int8m2x3_t t;}
+void f___rvv_uint8m2x3_t () {__rvv_uint8m2x3_t t;}
+void f___rvv_int8m2x4_t () {__rvv_int8m2x4_t t;}
+void f___rvv_uint8m2x4_t () {__rvv_uint8m2x4_t t;}
+void f___rvv_int8m4x2_t () {__rvv_int8m4x2_t t;}
+void f___rvv_uint8m4x2_t () {__rvv_uint8m4x2_t t;}
+void f___rvv_int16mf4x2_t () {__rvv_int16mf4x2_t t;} /* { dg-error {unknown type name '__rvv_int16mf4x2_t'} } */
+void f___rvv_uint16mf4x2_t () {__rvv_uint16mf4x2_t t;} /* { dg-error {unknown type name '__rvv_uint16mf4x2_t'} } */
+void f___rvv_int16mf4x3_t () {__rvv_int16mf4x3_t t;} /* { dg-error {unknown type name '__rvv_int16mf4x3_t'} } */
+void f___rvv_uint16mf4x3_t () {__rvv_uint16mf4x3_t t;} /* { dg-error {unknown type name '__rvv_uint16mf4x3_t'} } */
+void f___rvv_int16mf4x4_t () {__rvv_int16mf4x4_t t;} /* { dg-error {unknown type name '__rvv_int16mf4x4_t'} } */
+void f___rvv_uint16mf4x4_t () {__rvv_uint16mf4x4_t t;} /* { dg-error {unknown type name '__rvv_uint16mf4x4_t'} } */
+void f___rvv_int16mf4x5_t () {__rvv_int16mf4x5_t t;} /* { dg-error {unknown type name '__rvv_int16mf4x5_t'} } */
+void f___rvv_uint16mf4x5_t () {__rvv_uint16mf4x5_t t;} /* { dg-error {unknown type name '__rvv_uint16mf4x5_t'} } */
+void f___rvv_int16mf4x6_t () {__rvv_int16mf4x6_t t;} /* { dg-error {unknown type name '__rvv_int16mf4x6_t'} } */
+void f___rvv_uint16mf4x6_t () {__rvv_uint16mf4x6_t t;} /* { dg-error {unknown type name '__rvv_uint16mf4x6_t'} } */
+void f___rvv_int16mf4x7_t () {__rvv_int16mf4x7_t t;} /* { dg-error {unknown type name '__rvv_int16mf4x7_t'} } */
+void f___rvv_uint16mf4x7_t () {__rvv_uint16mf4x7_t t;} /* { dg-error {unknown type name '__rvv_uint16mf4x7_t'} } */
+void f___rvv_int16mf4x8_t () {__rvv_int16mf4x8_t t;} /* { dg-error {unknown type name '__rvv_int16mf4x8_t'} } */
+void f___rvv_uint16mf4x8_t () {__rvv_uint16mf4x8_t t;} /* { dg-error {unknown type name '__rvv_uint16mf4x8_t'} } */
+void f___rvv_int16mf2x2_t () {__rvv_int16mf2x2_t t;}
+void f___rvv_uint16mf2x2_t () {__rvv_uint16mf2x2_t t;}
+void f___rvv_int16mf2x3_t () {__rvv_int16mf2x3_t t;}
+void f___rvv_uint16mf2x3_t () {__rvv_uint16mf2x3_t t;}
+void f___rvv_int16mf2x4_t () {__rvv_int16mf2x4_t t;}
+void f___rvv_uint16mf2x4_t () {__rvv_uint16mf2x4_t t;}
+void f___rvv_int16mf2x5_t () {__rvv_int16mf2x5_t t;}
+void f___rvv_uint16mf2x5_t () {__rvv_uint16mf2x5_t t;}
+void f___rvv_int16mf2x6_t () {__rvv_int16mf2x6_t t;}
+void f___rvv_uint16mf2x6_t () {__rvv_uint16mf2x6_t t;}
+void f___rvv_int16mf2x7_t () {__rvv_int16mf2x7_t t;}
+void f___rvv_uint16mf2x7_t () {__rvv_uint16mf2x7_t t;}
+void f___rvv_int16mf2x8_t () {__rvv_int16mf2x8_t t;}
+void f___rvv_uint16mf2x8_t () {__rvv_uint16mf2x8_t t;}
+void f___rvv_int16m1x2_t () {__rvv_int16m1x2_t t;}
+void f___rvv_uint16m1x2_t () {__rvv_uint16m1x2_t t;}
+void f___rvv_int16m1x3_t () {__rvv_int16m1x3_t t;}
+void f___rvv_uint16m1x3_t () {__rvv_uint16m1x3_t t;}
+void f___rvv_int16m1x4_t () {__rvv_int16m1x4_t t;}
+void f___rvv_uint16m1x4_t () {__rvv_uint16m1x4_t t;}
+void f___rvv_int16m1x5_t () {__rvv_int16m1x5_t t;}
+void f___rvv_uint16m1x5_t () {__rvv_uint16m1x5_t t;}
+void f___rvv_int16m1x6_t () {__rvv_int16m1x6_t t;}
+void f___rvv_uint16m1x6_t () {__rvv_uint16m1x6_t t;}
+void f___rvv_int16m1x7_t () {__rvv_int16m1x7_t t;}
+void f___rvv_uint16m1x7_t () {__rvv_uint16m1x7_t t;}
+void f___rvv_int16m1x8_t () {__rvv_int16m1x8_t t;}
+void f___rvv_uint16m1x8_t () {__rvv_uint16m1x8_t t;}
+void f___rvv_int16m2x2_t () {__rvv_int16m2x2_t t;}
+void f___rvv_uint16m2x2_t () {__rvv_uint16m2x2_t t;}
+void f___rvv_int16m2x3_t () {__rvv_int16m2x3_t t;}
+void f___rvv_uint16m2x3_t () {__rvv_uint16m2x3_t t;}
+void f___rvv_int16m2x4_t () {__rvv_int16m2x4_t t;}
+void f___rvv_uint16m2x4_t () {__rvv_uint16m2x4_t t;}
+void f___rvv_int16m4x2_t () {__rvv_int16m4x2_t t;}
+void f___rvv_uint16m4x2_t () {__rvv_uint16m4x2_t t;}
+void f___rvv_int32mf2x2_t () {__rvv_int32mf2x2_t t;} /* { dg-error {unknown type name '__rvv_int32mf2x2_t'} } */
+void f___rvv_uint32mf2x2_t () {__rvv_uint32mf2x2_t t;} /* { dg-error {unknown type name '__rvv_uint32mf2x2_t'} } */
+void f___rvv_int32mf2x3_t () {__rvv_int32mf2x3_t t;} /* { dg-error {unknown type name '__rvv_int32mf2x3_t'} } */
+void f___rvv_uint32mf2x3_t () {__rvv_uint32mf2x3_t t;} /* { dg-error {unknown type name '__rvv_uint32mf2x3_t'} } */
+void f___rvv_int32mf2x4_t () {__rvv_int32mf2x4_t t;} /* { dg-error {unknown type name '__rvv_int32mf2x4_t'} } */
+void f___rvv_uint32mf2x4_t () {__rvv_uint32mf2x4_t t;} /* { dg-error {unknown type name '__rvv_uint32mf2x4_t'} } */
+void f___rvv_int32mf2x5_t () {__rvv_int32mf2x5_t t;} /* { dg-error {unknown type name '__rvv_int32mf2x5_t'} } */
+void f___rvv_uint32mf2x5_t () {__rvv_uint32mf2x5_t t;} /* { dg-error {unknown type name '__rvv_uint32mf2x5_t'} } */
+void f___rvv_int32mf2x6_t () {__rvv_int32mf2x6_t t;} /* { dg-error {unknown type name '__rvv_int32mf2x6_t'} } */
+void f___rvv_uint32mf2x6_t () {__rvv_uint32mf2x6_t t;} /* { dg-error {unknown type name '__rvv_uint32mf2x6_t'} } */
+void f___rvv_int32mf2x7_t () {__rvv_int32mf2x7_t t;} /* { dg-error {unknown type name '__rvv_int32mf2x7_t'} } */
+void f___rvv_uint32mf2x7_t () {__rvv_uint32mf2x7_t t;} /* { dg-error {unknown type name '__rvv_uint32mf2x7_t'} } */
+void f___rvv_int32mf2x8_t () {__rvv_int32mf2x8_t t;} /* { dg-error {unknown type name '__rvv_int32mf2x8_t'} } */
+void f___rvv_uint32mf2x8_t () {__rvv_uint32mf2x8_t t;} /* { dg-error {unknown type name '__rvv_uint32mf2x8_t'} } */
+void f___rvv_int32m1x2_t () {__rvv_int32m1x2_t t;}
+void f___rvv_uint32m1x2_t () {__rvv_uint32m1x2_t t;}
+void f___rvv_int32m1x3_t () {__rvv_int32m1x3_t t;}
+void f___rvv_uint32m1x3_t () {__rvv_uint32m1x3_t t;}
+void f___rvv_int32m1x4_t () {__rvv_int32m1x4_t t;}
+void f___rvv_uint32m1x4_t () {__rvv_uint32m1x4_t t;}
+void f___rvv_int32m1x5_t () {__rvv_int32m1x5_t t;}
+void f___rvv_uint32m1x5_t () {__rvv_uint32m1x5_t t;}
+void f___rvv_int32m1x6_t () {__rvv_int32m1x6_t t;}
+void f___rvv_uint32m1x6_t () {__rvv_uint32m1x6_t t;}
+void f___rvv_int32m1x7_t () {__rvv_int32m1x7_t t;}
+void f___rvv_uint32m1x7_t () {__rvv_uint32m1x7_t t;}
+void f___rvv_int32m1x8_t () {__rvv_int32m1x8_t t;}
+void f___rvv_uint32m1x8_t () {__rvv_uint32m1x8_t t;}
+void f___rvv_int32m2x2_t () {__rvv_int32m2x2_t t;}
+void f___rvv_uint32m2x2_t () {__rvv_uint32m2x2_t t;}
+void f___rvv_int32m2x3_t () {__rvv_int32m2x3_t t;}
+void f___rvv_uint32m2x3_t () {__rvv_uint32m2x3_t t;}
+void f___rvv_int32m2x4_t () {__rvv_int32m2x4_t t;}
+void f___rvv_uint32m2x4_t () {__rvv_uint32m2x4_t t;}
+void f___rvv_int32m4x2_t () {__rvv_int32m4x2_t t;}
+void f___rvv_uint32m4x2_t () {__rvv_uint32m4x2_t t;}
+void f___rvv_int64m1x2_t () {__rvv_int64m1x2_t t;} /* { dg-error {unknown type name '__rvv_int64m1x2_t'} } */
+void f___rvv_uint64m1x2_t () {__rvv_uint64m1x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x2_t'} } */
+void f___rvv_int64m1x3_t () {__rvv_int64m1x3_t t;} /* { dg-error {unknown type name '__rvv_int64m1x3_t'} } */
+void f___rvv_uint64m1x3_t () {__rvv_uint64m1x3_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x3_t'} } */
+void f___rvv_int64m1x4_t () {__rvv_int64m1x4_t t;} /* { dg-error {unknown type name '__rvv_int64m1x4_t'} } */
+void f___rvv_uint64m1x4_t () {__rvv_uint64m1x4_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x4_t'} } */
+void f___rvv_int64m1x5_t () {__rvv_int64m1x5_t t;} /* { dg-error {unknown type name '__rvv_int64m1x5_t'} } */
+void f___rvv_uint64m1x5_t () {__rvv_uint64m1x5_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x5_t'} } */
+void f___rvv_int64m1x6_t () {__rvv_int64m1x6_t t;} /* { dg-error {unknown type name '__rvv_int64m1x6_t'} } */
+void f___rvv_uint64m1x6_t () {__rvv_uint64m1x6_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x6_t'} } */
+void f___rvv_int64m1x7_t () {__rvv_int64m1x7_t t;} /* { dg-error {unknown type name '__rvv_int64m1x7_t'} } */
+void f___rvv_uint64m1x7_t () {__rvv_uint64m1x7_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x7_t'} } */
+void f___rvv_int64m1x8_t () {__rvv_int64m1x8_t t;} /* { dg-error {unknown type name '__rvv_int64m1x8_t'} } */
+void f___rvv_uint64m1x8_t () {__rvv_uint64m1x8_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x8_t'} } */
+void f___rvv_int64m2x2_t () {__rvv_int64m2x2_t t;} /* { dg-error {unknown type name '__rvv_int64m2x2_t'} } */
+void f___rvv_uint64m2x2_t () {__rvv_uint64m2x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x2_t'} } */
+void f___rvv_int64m2x3_t () {__rvv_int64m2x3_t t;} /* { dg-error {unknown type name '__rvv_int64m2x3_t'} } */
+void f___rvv_uint64m2x3_t () {__rvv_uint64m2x3_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x3_t'} } */
+void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;} /* { dg-error {unknown type name '__rvv_int64m2x4_t'} } */
+void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x4_t'} } */
+void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;} /* { dg-error {unknown type name '__rvv_int64m4x2_t'} } */
+void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m4x2_t'} } */
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x2_t'} } */
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x3_t'} } */
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x4_t'} } */
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x5_t'} } */
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x6_t'} } */
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x7_t'} } */
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x8_t'} } */
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;}
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;}
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;}
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;}
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;}
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;}
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;}
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;}
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;}
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;}
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;}
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;}
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;}
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;}
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;}
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;}
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;}
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;}
+void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x2_t'} } */
+void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x3_t'} } */
+void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x4_t'} } */
+void f___rvv_float32mf2x5_t () {__rvv_float32mf2x5_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x5_t'} } */
+void f___rvv_float32mf2x6_t () {__rvv_float32mf2x6_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x6_t'} } */
+void f___rvv_float32mf2x7_t () {__rvv_float32mf2x7_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x7_t'} } */
+void f___rvv_float32mf2x8_t () {__rvv_float32mf2x8_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x8_t'} } */
+void f___rvv_float32m1x2_t () {__rvv_float32m1x2_t t;}
+void f___rvv_float32m1x3_t () {__rvv_float32m1x3_t t;}
+void f___rvv_float32m1x4_t () {__rvv_float32m1x4_t t;}
+void f___rvv_float32m1x5_t () {__rvv_float32m1x5_t t;}
+void f___rvv_float32m1x6_t () {__rvv_float32m1x6_t t;}
+void f___rvv_float32m1x7_t () {__rvv_float32m1x7_t t;}
+void f___rvv_float32m1x8_t () {__rvv_float32m1x8_t t;}
+void f___rvv_float32m2x2_t () {__rvv_float32m2x2_t t;}
+void f___rvv_float32m2x3_t () {__rvv_float32m2x3_t t;}
+void f___rvv_float32m2x4_t () {__rvv_float32m2x4_t t;}
+void f___rvv_float32m4x2_t () {__rvv_float32m4x2_t t;}
+void f___rvv_float64m1x2_t () {__rvv_float64m1x2_t t;} /* { dg-error {unknown type name '__rvv_float64m1x2_t'} } */
+void f___rvv_float64m1x3_t () {__rvv_float64m1x3_t t;} /* { dg-error {unknown type name '__rvv_float64m1x3_t'} } */
+void f___rvv_float64m1x4_t () {__rvv_float64m1x4_t t;} /* { dg-error {unknown type name '__rvv_float64m1x4_t'} } */
+void f___rvv_float64m1x5_t () {__rvv_float64m1x5_t t;} /* { dg-error {unknown type name '__rvv_float64m1x5_t'} } */
+void f___rvv_float64m1x6_t () {__rvv_float64m1x6_t t;} /* { dg-error {unknown type name '__rvv_float64m1x6_t'} } */
+void f___rvv_float64m1x7_t () {__rvv_float64m1x7_t t;} /* { dg-error {unknown type name '__rvv_float64m1x7_t'} } */
+void f___rvv_float64m1x8_t () {__rvv_float64m1x8_t t;} /* { dg-error {unknown type name '__rvv_float64m1x8_t'} } */
+void f___rvv_float64m2x2_t () {__rvv_float64m2x2_t t;} /* { dg-error {unknown type name '__rvv_float64m2x2_t'} } */
+void f___rvv_float64m2x3_t () {__rvv_float64m2x3_t t;} /* { dg-error {unknown type name '__rvv_float64m2x3_t'} } */
+void f___rvv_float64m2x4_t () {__rvv_float64m2x4_t t;} /* { dg-error {unknown type name '__rvv_float64m2x4_t'} } */
+void f___rvv_float64m4x2_t () {__rvv_float64m4x2_t t;} /* { dg-error {unknown type name '__rvv_float64m4x2_t'} } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-18.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-18.c
new file mode 100644
index 0000000..402e8f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-18.c
@@ -0,0 +1,229 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv32gc_zve32x_zvl64b_zvfhmin -mabi=ilp32d" } */
+
+void f___rvv_int8mf8x2_t () {__rvv_int8mf8x2_t t;}
+void f___rvv_uint8mf8x2_t () {__rvv_uint8mf8x2_t t;}
+void f___rvv_int8mf8x3_t () {__rvv_int8mf8x3_t t;}
+void f___rvv_uint8mf8x3_t () {__rvv_uint8mf8x3_t t;}
+void f___rvv_int8mf8x4_t () {__rvv_int8mf8x4_t t;}
+void f___rvv_uint8mf8x4_t () {__rvv_uint8mf8x4_t t;}
+void f___rvv_int8mf8x5_t () {__rvv_int8mf8x5_t t;}
+void f___rvv_uint8mf8x5_t () {__rvv_uint8mf8x5_t t;}
+void f___rvv_int8mf8x6_t () {__rvv_int8mf8x6_t t;}
+void f___rvv_uint8mf8x6_t () {__rvv_uint8mf8x6_t t;}
+void f___rvv_int8mf8x7_t () {__rvv_int8mf8x7_t t;}
+void f___rvv_uint8mf8x7_t () {__rvv_uint8mf8x7_t t;}
+void f___rvv_int8mf8x8_t () {__rvv_int8mf8x8_t t;}
+void f___rvv_uint8mf8x8_t () {__rvv_uint8mf8x8_t t;}
+void f___rvv_int8mf4x2_t () {__rvv_int8mf4x2_t t;}
+void f___rvv_uint8mf4x2_t () {__rvv_uint8mf4x2_t t;}
+void f___rvv_int8mf4x3_t () {__rvv_int8mf4x3_t t;}
+void f___rvv_uint8mf4x3_t () {__rvv_uint8mf4x3_t t;}
+void f___rvv_int8mf4x4_t () {__rvv_int8mf4x4_t t;}
+void f___rvv_uint8mf4x4_t () {__rvv_uint8mf4x4_t t;}
+void f___rvv_int8mf4x5_t () {__rvv_int8mf4x5_t t;}
+void f___rvv_uint8mf4x5_t () {__rvv_uint8mf4x5_t t;}
+void f___rvv_int8mf4x6_t () {__rvv_int8mf4x6_t t;}
+void f___rvv_uint8mf4x6_t () {__rvv_uint8mf4x6_t t;}
+void f___rvv_int8mf4x7_t () {__rvv_int8mf4x7_t t;}
+void f___rvv_uint8mf4x7_t () {__rvv_uint8mf4x7_t t;}
+void f___rvv_int8mf4x8_t () {__rvv_int8mf4x8_t t;}
+void f___rvv_uint8mf4x8_t () {__rvv_uint8mf4x8_t t;}
+void f___rvv_int8mf2x2_t () {__rvv_int8mf2x2_t t;}
+void f___rvv_uint8mf2x2_t () {__rvv_uint8mf2x2_t t;}
+void f___rvv_int8mf2x3_t () {__rvv_int8mf2x3_t t;}
+void f___rvv_uint8mf2x3_t () {__rvv_uint8mf2x3_t t;}
+void f___rvv_int8mf2x4_t () {__rvv_int8mf2x4_t t;}
+void f___rvv_uint8mf2x4_t () {__rvv_uint8mf2x4_t t;}
+void f___rvv_int8mf2x5_t () {__rvv_int8mf2x5_t t;}
+void f___rvv_uint8mf2x5_t () {__rvv_uint8mf2x5_t t;}
+void f___rvv_int8mf2x6_t () {__rvv_int8mf2x6_t t;}
+void f___rvv_uint8mf2x6_t () {__rvv_uint8mf2x6_t t;}
+void f___rvv_int8mf2x7_t () {__rvv_int8mf2x7_t t;}
+void f___rvv_uint8mf2x7_t () {__rvv_uint8mf2x7_t t;}
+void f___rvv_int8mf2x8_t () {__rvv_int8mf2x8_t t;}
+void f___rvv_uint8mf2x8_t () {__rvv_uint8mf2x8_t t;}
+void f___rvv_int8m1x2_t () {__rvv_int8m1x2_t t;}
+void f___rvv_uint8m1x2_t () {__rvv_uint8m1x2_t t;}
+void f___rvv_int8m1x3_t () {__rvv_int8m1x3_t t;}
+void f___rvv_uint8m1x3_t () {__rvv_uint8m1x3_t t;}
+void f___rvv_int8m1x4_t () {__rvv_int8m1x4_t t;}
+void f___rvv_uint8m1x4_t () {__rvv_uint8m1x4_t t;}
+void f___rvv_int8m1x5_t () {__rvv_int8m1x5_t t;}
+void f___rvv_uint8m1x5_t () {__rvv_uint8m1x5_t t;}
+void f___rvv_int8m1x6_t () {__rvv_int8m1x6_t t;}
+void f___rvv_uint8m1x6_t () {__rvv_uint8m1x6_t t;}
+void f___rvv_int8m1x7_t () {__rvv_int8m1x7_t t;}
+void f___rvv_uint8m1x7_t () {__rvv_uint8m1x7_t t;}
+void f___rvv_int8m1x8_t () {__rvv_int8m1x8_t t;}
+void f___rvv_uint8m1x8_t () {__rvv_uint8m1x8_t t;}
+void f___rvv_int8m2x2_t () {__rvv_int8m2x2_t t;}
+void f___rvv_uint8m2x2_t () {__rvv_uint8m2x2_t t;}
+void f___rvv_int8m2x3_t () {__rvv_int8m2x3_t t;}
+void f___rvv_uint8m2x3_t () {__rvv_uint8m2x3_t t;}
+void f___rvv_int8m2x4_t () {__rvv_int8m2x4_t t;}
+void f___rvv_uint8m2x4_t () {__rvv_uint8m2x4_t t;}
+void f___rvv_int8m4x2_t () {__rvv_int8m4x2_t t;}
+void f___rvv_uint8m4x2_t () {__rvv_uint8m4x2_t t;}
+void f___rvv_int16mf4x2_t () {__rvv_int16mf4x2_t t;}
+void f___rvv_uint16mf4x2_t () {__rvv_uint16mf4x2_t t;}
+void f___rvv_int16mf4x3_t () {__rvv_int16mf4x3_t t;}
+void f___rvv_uint16mf4x3_t () {__rvv_uint16mf4x3_t t;}
+void f___rvv_int16mf4x4_t () {__rvv_int16mf4x4_t t;}
+void f___rvv_uint16mf4x4_t () {__rvv_uint16mf4x4_t t;}
+void f___rvv_int16mf4x5_t () {__rvv_int16mf4x5_t t;}
+void f___rvv_uint16mf4x5_t () {__rvv_uint16mf4x5_t t;}
+void f___rvv_int16mf4x6_t () {__rvv_int16mf4x6_t t;}
+void f___rvv_uint16mf4x6_t () {__rvv_uint16mf4x6_t t;}
+void f___rvv_int16mf4x7_t () {__rvv_int16mf4x7_t t;}
+void f___rvv_uint16mf4x7_t () {__rvv_uint16mf4x7_t t;}
+void f___rvv_int16mf4x8_t () {__rvv_int16mf4x8_t t;}
+void f___rvv_uint16mf4x8_t () {__rvv_uint16mf4x8_t t;}
+void f___rvv_int16mf2x2_t () {__rvv_int16mf2x2_t t;}
+void f___rvv_uint16mf2x2_t () {__rvv_uint16mf2x2_t t;}
+void f___rvv_int16mf2x3_t () {__rvv_int16mf2x3_t t;}
+void f___rvv_uint16mf2x3_t () {__rvv_uint16mf2x3_t t;}
+void f___rvv_int16mf2x4_t () {__rvv_int16mf2x4_t t;}
+void f___rvv_uint16mf2x4_t () {__rvv_uint16mf2x4_t t;}
+void f___rvv_int16mf2x5_t () {__rvv_int16mf2x5_t t;}
+void f___rvv_uint16mf2x5_t () {__rvv_uint16mf2x5_t t;}
+void f___rvv_int16mf2x6_t () {__rvv_int16mf2x6_t t;}
+void f___rvv_uint16mf2x6_t () {__rvv_uint16mf2x6_t t;}
+void f___rvv_int16mf2x7_t () {__rvv_int16mf2x7_t t;}
+void f___rvv_uint16mf2x7_t () {__rvv_uint16mf2x7_t t;}
+void f___rvv_int16mf2x8_t () {__rvv_int16mf2x8_t t;}
+void f___rvv_uint16mf2x8_t () {__rvv_uint16mf2x8_t t;}
+void f___rvv_int16m1x2_t () {__rvv_int16m1x2_t t;}
+void f___rvv_uint16m1x2_t () {__rvv_uint16m1x2_t t;}
+void f___rvv_int16m1x3_t () {__rvv_int16m1x3_t t;}
+void f___rvv_uint16m1x3_t () {__rvv_uint16m1x3_t t;}
+void f___rvv_int16m1x4_t () {__rvv_int16m1x4_t t;}
+void f___rvv_uint16m1x4_t () {__rvv_uint16m1x4_t t;}
+void f___rvv_int16m1x5_t () {__rvv_int16m1x5_t t;}
+void f___rvv_uint16m1x5_t () {__rvv_uint16m1x5_t t;}
+void f___rvv_int16m1x6_t () {__rvv_int16m1x6_t t;}
+void f___rvv_uint16m1x6_t () {__rvv_uint16m1x6_t t;}
+void f___rvv_int16m1x7_t () {__rvv_int16m1x7_t t;}
+void f___rvv_uint16m1x7_t () {__rvv_uint16m1x7_t t;}
+void f___rvv_int16m1x8_t () {__rvv_int16m1x8_t t;}
+void f___rvv_uint16m1x8_t () {__rvv_uint16m1x8_t t;}
+void f___rvv_int16m2x2_t () {__rvv_int16m2x2_t t;}
+void f___rvv_uint16m2x2_t () {__rvv_uint16m2x2_t t;}
+void f___rvv_int16m2x3_t () {__rvv_int16m2x3_t t;}
+void f___rvv_uint16m2x3_t () {__rvv_uint16m2x3_t t;}
+void f___rvv_int16m2x4_t () {__rvv_int16m2x4_t t;}
+void f___rvv_uint16m2x4_t () {__rvv_uint16m2x4_t t;}
+void f___rvv_int16m4x2_t () {__rvv_int16m4x2_t t;}
+void f___rvv_uint16m4x2_t () {__rvv_uint16m4x2_t t;}
+void f___rvv_int32mf2x2_t () {__rvv_int32mf2x2_t t;}
+void f___rvv_uint32mf2x2_t () {__rvv_uint32mf2x2_t t;}
+void f___rvv_int32mf2x3_t () {__rvv_int32mf2x3_t t;}
+void f___rvv_uint32mf2x3_t () {__rvv_uint32mf2x3_t t;}
+void f___rvv_int32mf2x4_t () {__rvv_int32mf2x4_t t;}
+void f___rvv_uint32mf2x4_t () {__rvv_uint32mf2x4_t t;}
+void f___rvv_int32mf2x5_t () {__rvv_int32mf2x5_t t;}
+void f___rvv_uint32mf2x5_t () {__rvv_uint32mf2x5_t t;}
+void f___rvv_int32mf2x6_t () {__rvv_int32mf2x6_t t;}
+void f___rvv_uint32mf2x6_t () {__rvv_uint32mf2x6_t t;}
+void f___rvv_int32mf2x7_t () {__rvv_int32mf2x7_t t;}
+void f___rvv_uint32mf2x7_t () {__rvv_uint32mf2x7_t t;}
+void f___rvv_int32mf2x8_t () {__rvv_int32mf2x8_t t;}
+void f___rvv_uint32mf2x8_t () {__rvv_uint32mf2x8_t t;}
+void f___rvv_int32m1x2_t () {__rvv_int32m1x2_t t;}
+void f___rvv_uint32m1x2_t () {__rvv_uint32m1x2_t t;}
+void f___rvv_int32m1x3_t () {__rvv_int32m1x3_t t;}
+void f___rvv_uint32m1x3_t () {__rvv_uint32m1x3_t t;}
+void f___rvv_int32m1x4_t () {__rvv_int32m1x4_t t;}
+void f___rvv_uint32m1x4_t () {__rvv_uint32m1x4_t t;}
+void f___rvv_int32m1x5_t () {__rvv_int32m1x5_t t;}
+void f___rvv_uint32m1x5_t () {__rvv_uint32m1x5_t t;}
+void f___rvv_int32m1x6_t () {__rvv_int32m1x6_t t;}
+void f___rvv_uint32m1x6_t () {__rvv_uint32m1x6_t t;}
+void f___rvv_int32m1x7_t () {__rvv_int32m1x7_t t;}
+void f___rvv_uint32m1x7_t () {__rvv_uint32m1x7_t t;}
+void f___rvv_int32m1x8_t () {__rvv_int32m1x8_t t;}
+void f___rvv_uint32m1x8_t () {__rvv_uint32m1x8_t t;}
+void f___rvv_int32m2x2_t () {__rvv_int32m2x2_t t;}
+void f___rvv_uint32m2x2_t () {__rvv_uint32m2x2_t t;}
+void f___rvv_int32m2x3_t () {__rvv_int32m2x3_t t;}
+void f___rvv_uint32m2x3_t () {__rvv_uint32m2x3_t t;}
+void f___rvv_int32m2x4_t () {__rvv_int32m2x4_t t;}
+void f___rvv_uint32m2x4_t () {__rvv_uint32m2x4_t t;}
+void f___rvv_int32m4x2_t () {__rvv_int32m4x2_t t;}
+void f___rvv_uint32m4x2_t () {__rvv_uint32m4x2_t t;}
+void f___rvv_int64m1x2_t () {__rvv_int64m1x2_t t;} /* { dg-error {unknown type name '__rvv_int64m1x2_t'} } */
+void f___rvv_uint64m1x2_t () {__rvv_uint64m1x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x2_t'} } */
+void f___rvv_int64m1x3_t () {__rvv_int64m1x3_t t;} /* { dg-error {unknown type name '__rvv_int64m1x3_t'} } */
+void f___rvv_uint64m1x3_t () {__rvv_uint64m1x3_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x3_t'} } */
+void f___rvv_int64m1x4_t () {__rvv_int64m1x4_t t;} /* { dg-error {unknown type name '__rvv_int64m1x4_t'} } */
+void f___rvv_uint64m1x4_t () {__rvv_uint64m1x4_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x4_t'} } */
+void f___rvv_int64m1x5_t () {__rvv_int64m1x5_t t;} /* { dg-error {unknown type name '__rvv_int64m1x5_t'} } */
+void f___rvv_uint64m1x5_t () {__rvv_uint64m1x5_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x5_t'} } */
+void f___rvv_int64m1x6_t () {__rvv_int64m1x6_t t;} /* { dg-error {unknown type name '__rvv_int64m1x6_t'} } */
+void f___rvv_uint64m1x6_t () {__rvv_uint64m1x6_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x6_t'} } */
+void f___rvv_int64m1x7_t () {__rvv_int64m1x7_t t;} /* { dg-error {unknown type name '__rvv_int64m1x7_t'} } */
+void f___rvv_uint64m1x7_t () {__rvv_uint64m1x7_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x7_t'} } */
+void f___rvv_int64m1x8_t () {__rvv_int64m1x8_t t;} /* { dg-error {unknown type name '__rvv_int64m1x8_t'} } */
+void f___rvv_uint64m1x8_t () {__rvv_uint64m1x8_t t;} /* { dg-error {unknown type name '__rvv_uint64m1x8_t'} } */
+void f___rvv_int64m2x2_t () {__rvv_int64m2x2_t t;} /* { dg-error {unknown type name '__rvv_int64m2x2_t'} } */
+void f___rvv_uint64m2x2_t () {__rvv_uint64m2x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x2_t'} } */
+void f___rvv_int64m2x3_t () {__rvv_int64m2x3_t t;} /* { dg-error {unknown type name '__rvv_int64m2x3_t'} } */
+void f___rvv_uint64m2x3_t () {__rvv_uint64m2x3_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x3_t'} } */
+void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;} /* { dg-error {unknown type name '__rvv_int64m2x4_t'} } */
+void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x4_t'} } */
+void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;} /* { dg-error {unknown type name '__rvv_int64m4x2_t'} } */
+void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m4x2_t'} } */
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;}
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;}
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;}
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;}
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;}
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;}
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;}
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;}
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;}
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;}
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;}
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;}
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;}
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;}
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;}
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;}
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;}
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;}
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;}
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;}
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;}
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;}
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;}
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;}
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;}
+void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;}
+void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;}
+void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;}
+void f___rvv_float32mf2x5_t () {__rvv_float32mf2x5_t t;}
+void f___rvv_float32mf2x6_t () {__rvv_float32mf2x6_t t;}
+void f___rvv_float32mf2x7_t () {__rvv_float32mf2x7_t t;}
+void f___rvv_float32mf2x8_t () {__rvv_float32mf2x8_t t;}
+void f___rvv_float32m1x2_t () {__rvv_float32m1x2_t t;}
+void f___rvv_float32m1x3_t () {__rvv_float32m1x3_t t;}
+void f___rvv_float32m1x4_t () {__rvv_float32m1x4_t t;}
+void f___rvv_float32m1x5_t () {__rvv_float32m1x5_t t;}
+void f___rvv_float32m1x6_t () {__rvv_float32m1x6_t t;}
+void f___rvv_float32m1x7_t () {__rvv_float32m1x7_t t;}
+void f___rvv_float32m1x8_t () {__rvv_float32m1x8_t t;}
+void f___rvv_float32m2x2_t () {__rvv_float32m2x2_t t;}
+void f___rvv_float32m2x3_t () {__rvv_float32m2x3_t t;}
+void f___rvv_float32m2x4_t () {__rvv_float32m2x4_t t;}
+void f___rvv_float32m4x2_t () {__rvv_float32m4x2_t t;}
+void f___rvv_float64m1x2_t () {__rvv_float64m1x2_t t;} /* { dg-error {unknown type name '__rvv_float64m1x2_t'} } */
+void f___rvv_float64m1x3_t () {__rvv_float64m1x3_t t;} /* { dg-error {unknown type name '__rvv_float64m1x3_t'} } */
+void f___rvv_float64m1x4_t () {__rvv_float64m1x4_t t;} /* { dg-error {unknown type name '__rvv_float64m1x4_t'} } */
+void f___rvv_float64m1x5_t () {__rvv_float64m1x5_t t;} /* { dg-error {unknown type name '__rvv_float64m1x5_t'} } */
+void f___rvv_float64m1x6_t () {__rvv_float64m1x6_t t;} /* { dg-error {unknown type name '__rvv_float64m1x6_t'} } */
+void f___rvv_float64m1x7_t () {__rvv_float64m1x7_t t;} /* { dg-error {unknown type name '__rvv_float64m1x7_t'} } */
+void f___rvv_float64m1x8_t () {__rvv_float64m1x8_t t;} /* { dg-error {unknown type name '__rvv_float64m1x8_t'} } */
+void f___rvv_float64m2x2_t () {__rvv_float64m2x2_t t;} /* { dg-error {unknown type name '__rvv_float64m2x2_t'} } */
+void f___rvv_float64m2x3_t () {__rvv_float64m2x3_t t;} /* { dg-error {unknown type name '__rvv_float64m2x3_t'} } */
+void f___rvv_float64m2x4_t () {__rvv_float64m2x4_t t;} /* { dg-error {unknown type name '__rvv_float64m2x4_t'} } */
+void f___rvv_float64m4x2_t () {__rvv_float64m4x2_t t;} /* { dg-error {unknown type name '__rvv_float64m4x2_t'} } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-8.c
index 282ee48..6347b25 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -march=rv32gcv -mabi=ilp32d" } */
+/* { dg-options "-O3 -march=rv32gcv_zvfhmin -mabi=ilp32d" } */
void f___rvv_int8mf8x2_t () {__rvv_int8mf8x2_t t;}
void f___rvv_uint8mf8x2_t () {__rvv_uint8mf8x2_t t;}
@@ -173,6 +173,31 @@ void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;}
void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;}
void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;}
void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;}
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;}
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;}
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;}
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;}
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;}
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;}
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;}
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;}
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;}
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;}
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;}
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;}
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;}
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;}
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;}
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;}
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;}
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;}
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;}
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;}
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;}
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;}
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;}
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;}
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;}
void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;}
void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;}
void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-9.c
index 37f78d1..71702ca 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-9.c
@@ -173,6 +173,31 @@ void f___rvv_int64m2x4_t () {__rvv_int64m2x4_t t;} /* { dg-error {unknown type n
void f___rvv_uint64m2x4_t () {__rvv_uint64m2x4_t t;} /* { dg-error {unknown type name '__rvv_uint64m2x4_t'} } */
void f___rvv_int64m4x2_t () {__rvv_int64m4x2_t t;} /* { dg-error {unknown type name '__rvv_int64m4x2_t'} } */
void f___rvv_uint64m4x2_t () {__rvv_uint64m4x2_t t;} /* { dg-error {unknown type name '__rvv_uint64m4x2_t'} } */
+void f___rvv_float16mf4x2_t () {__rvv_float16mf4x2_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x2_t'} } */
+void f___rvv_float16mf4x3_t () {__rvv_float16mf4x3_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x3_t'} } */
+void f___rvv_float16mf4x4_t () {__rvv_float16mf4x4_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x4_t'} } */
+void f___rvv_float16mf4x5_t () {__rvv_float16mf4x5_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x5_t'} } */
+void f___rvv_float16mf4x6_t () {__rvv_float16mf4x6_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x6_t'} } */
+void f___rvv_float16mf4x7_t () {__rvv_float16mf4x7_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x7_t'} } */
+void f___rvv_float16mf4x8_t () {__rvv_float16mf4x8_t t;} /* { dg-error {unknown type name '__rvv_float16mf4x8_t'} } */
+void f___rvv_float16mf2x2_t () {__rvv_float16mf2x2_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x2_t'} } */
+void f___rvv_float16mf2x3_t () {__rvv_float16mf2x3_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x3_t'} } */
+void f___rvv_float16mf2x4_t () {__rvv_float16mf2x4_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x4_t'} } */
+void f___rvv_float16mf2x5_t () {__rvv_float16mf2x5_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x5_t'} } */
+void f___rvv_float16mf2x6_t () {__rvv_float16mf2x6_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x6_t'} } */
+void f___rvv_float16mf2x7_t () {__rvv_float16mf2x7_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x7_t'} } */
+void f___rvv_float16mf2x8_t () {__rvv_float16mf2x8_t t;} /* { dg-error {unknown type name '__rvv_float16mf2x8_t'} } */
+void f___rvv_float16m1x2_t () {__rvv_float16m1x2_t t;} /* { dg-error {unknown type name '__rvv_float16m1x2_t'} } */
+void f___rvv_float16m1x3_t () {__rvv_float16m1x3_t t;} /* { dg-error {unknown type name '__rvv_float16m1x3_t'} } */
+void f___rvv_float16m1x4_t () {__rvv_float16m1x4_t t;} /* { dg-error {unknown type name '__rvv_float16m1x4_t'} } */
+void f___rvv_float16m1x5_t () {__rvv_float16m1x5_t t;} /* { dg-error {unknown type name '__rvv_float16m1x5_t'} } */
+void f___rvv_float16m1x6_t () {__rvv_float16m1x6_t t;} /* { dg-error {unknown type name '__rvv_float16m1x6_t'} } */
+void f___rvv_float16m1x7_t () {__rvv_float16m1x7_t t;} /* { dg-error {unknown type name '__rvv_float16m1x7_t'} } */
+void f___rvv_float16m1x8_t () {__rvv_float16m1x8_t t;} /* { dg-error {unknown type name '__rvv_float16m1x8_t'} } */
+void f___rvv_float16m2x2_t () {__rvv_float16m2x2_t t;} /* { dg-error {unknown type name '__rvv_float16m2x2_t'} } */
+void f___rvv_float16m2x3_t () {__rvv_float16m2x3_t t;} /* { dg-error {unknown type name '__rvv_float16m2x3_t'} } */
+void f___rvv_float16m2x4_t () {__rvv_float16m2x4_t t;} /* { dg-error {unknown type name '__rvv_float16m2x4_t'} } */
+void f___rvv_float16m4x2_t () {__rvv_float16m4x2_t t;} /* { dg-error {unknown type name '__rvv_float16m4x2_t'} } */
void f___rvv_float32mf2x2_t () {__rvv_float32mf2x2_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x2_t'} } */
void f___rvv_float32mf2x3_t () {__rvv_float32mf2x3_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x3_t'} } */
void f___rvv_float32mf2x4_t () {__rvv_float32mf2x4_t t;} /* { dg-error {unknown type name '__rvv_float32mf2x4_t'} } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c
new file mode 100644
index 0000000..4ebaa15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+typedef float float32_t;
+
+void test_float_point_frm_error (float32_t *out, vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t v1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 5, vl); /* { dg-error {passing 5 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\] or 7} } */
+ vfloat32m1_t v2 = __riscv_vfadd_vv_f32m1_rm (v1, v1, 6, vl); /* { dg-error {passing 6 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\] or 7} } */
+ vfloat32m1_t v3 = __riscv_vfadd_vv_f32m1_rm (v2, v2, 8, vl); /* { dg-error {passing 8 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\] or 7} } */
+
+ __riscv_vse32_v_f32m1 (out, v3, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c
new file mode 100644
index 0000000..732e030
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+typedef float float32_t;
+
+vfloat32m1_t
+test_riscv_vfadd_vv_f32m1_rm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) {
+ return __riscv_vfadd_vv_f32m1_rm (op1, op2, 0, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vv_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, vfloat32m1_t op2,
+ size_t vl) {
+ return __riscv_vfadd_vv_f32m1_m_rm(mask, op1, op2, 1, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vf_f32m1_rm(vfloat32m1_t op1, float32_t op2, size_t vl) {
+ return __riscv_vfadd_vf_f32m1_rm(op1, op2, 2, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2,
+ size_t vl) {
+ return __riscv_vfadd_vf_f32m1_m_rm(mask, op1, op2, 3, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c
new file mode 100644
index 0000000..72e5d20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) {
+ vfloat32m1_t v1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 0, vl);
+ vfloat32m1_t v2 = __riscv_vfmin_vv_f32m1 (op1, v1, vl);
+ return __riscv_vfadd_vv_f32m1_rm (v1, v2, 0, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c
new file mode 100644
index 0000000..c9e8d0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) {
+ vfloat32m1_t v1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 0, vl);
+ vfloat32m1_t v2 = __riscv_vfmin_vv_f32m1 (op1, v1, vl);
+ return __riscv_vfadd_vv_f32m1_rm (v1, v2, 1, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c
new file mode 100644
index 0000000..a288e0b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl,
+ size_t count) {
+ vfloat32m1_t tmp = op1, result;
+
+ result = __riscv_vfadd_vv_f32m1_rm (result, op1, 1, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+
+ for (int i = 0; i < count; i++) {
+ tmp = __riscv_vfadd_vv_f32m1_rm (op1, tmp, 1, vl + i);
+ result = __riscv_vfrsqrt7_v_f32m1 (tmp, vl + i);
+ }
+
+ return __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c
new file mode 100644
index 0000000..bb77a6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl,
+ size_t count) {
+ vfloat32m1_t tmp = op1, result;
+
+ result = __riscv_vfadd_vv_f32m1_rm (result, op1, 1, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+
+ for (int i = 0; i < count; i++) {
+ tmp = __riscv_vfadd_vv_f32m1_rm (op1, tmp, 2, vl + i);
+ result = __riscv_vfrsqrt7_v_f32m1 (tmp, vl + i);
+ }
+
+ return __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c
new file mode 100644
index 0000000..95271b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+typedef float float32_t;
+
+vfloat32m1_t
+test_riscv_vfadd_vv_f32m1_rm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) {
+ return __riscv_vfadd_vv_f32m1_rm (op1, op2, 0, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vv_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, vfloat32m1_t op2,
+ size_t vl) {
+ return __riscv_vfadd_vv_f32m1_m_rm(mask, op1, op2, 0, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vf_f32m1_rm(vfloat32m1_t op1, float32_t op2, size_t vl) {
+ return __riscv_vfadd_vf_f32m1_rm(op1, op2, 0, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2,
+ size_t vl) {
+ return __riscv_vfadd_vf_f32m1_m_rm(mask, op1, op2, 0, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c
new file mode 100644
index 0000000..3749d97
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O0 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void test_vlmul_ext_v_i8mf8_i8mf4(vint8mf8_t op1) {
+ vint8mf4_t res = __riscv_vlmul_ext_v_i8mf8_i8mf4(op1);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-1.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-1.c
new file mode 100644
index 0000000..19ea0f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include "riscv_vector.h"
+
+void
+foo (void *a, void *b, void *c, size_t n)
+{
+ for (size_t vl; n > 0; n -= vl, a += vl, b += vl * 4, c += vl)
+ {
+ vl = __riscv_vsetvl_e8mf4 (n);
+ vint32m1_t vec_b = __riscv_vle32_v_i32m1 (b, vl);
+ vint32m1_t vec_a = __riscv_vadd_vv_i32m1 (vec_b, vec_b, __riscv_vsetvlmax_e32m1 ());
+ __riscv_vse32_v_i32m1 (a, vec_a, vl);
+ }
+}
+
+/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e32,\s*m1,\s*t[au],\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e32,\s*m1,\s*t[au],\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zvbb.c b/gcc/testsuite/gcc.target/riscv/zvbb.c
new file mode 100644
index 0000000..b592f56
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvbb.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvbb" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvbb" { target { rv32 } } } */
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvbc.c b/gcc/testsuite/gcc.target/riscv/zvbc.c
new file mode 100644
index 0000000..37239fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvbc.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvbc" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvbc" { target { rv32 } } } */
+
+#ifndef __riscv_zvbc
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkg.c b/gcc/testsuite/gcc.target/riscv/zvkg.c
new file mode 100644
index 0000000..1e2a05a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkg.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkg" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkg" { target { rv32 } } } */
+
+#ifndef __riscv_zvkg
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkn-1.c b/gcc/testsuite/gcc.target/riscv/zvkn-1.c
new file mode 100644
index 0000000..83935b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkn-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkned_zvknhb_zvbb_zvkt" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkned_zvknhb_zvbb_zvkt" { target { rv32 } } } */
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkn.c b/gcc/testsuite/gcc.target/riscv/zvkn.c
new file mode 100644
index 0000000..af3db40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkn.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkn" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkn" { target { rv32 } } } */
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvknc-1.c b/gcc/testsuite/gcc.target/riscv/zvknc-1.c
new file mode 100644
index 0000000..eca2767
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvknc-1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkned_zvknhb_zvbb_zvkt_zvbc" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkned_zvknhb_zvbb_zvkt_zvbc" { target { rv32 } } } */
+
+#ifndef __riscv_zvknc
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbc
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvknc-2.c b/gcc/testsuite/gcc.target/riscv/zvknc-2.c
new file mode 100644
index 0000000..e77343a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvknc-2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkn_zvbc" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkn_zvbc" { target { rv32 } } } */
+
+#ifndef __riscv_zvknc
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbc
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvknc.c b/gcc/testsuite/gcc.target/riscv/zvknc.c
new file mode 100644
index 0000000..10bd471
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvknc.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvknc" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvknc" { target { rv32 } } } */
+
+#ifndef __riscv_zvknc
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbc
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkned.c b/gcc/testsuite/gcc.target/riscv/zvkned.c
new file mode 100644
index 0000000..fcdc4b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkned.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkned" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkned" { target { rv32 } } } */
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkng-1.c b/gcc/testsuite/gcc.target/riscv/zvkng-1.c
new file mode 100644
index 0000000..f4f3cc8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkng-1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkned_zvknhb_zvbb_zvkt_zvkg" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkned_zvknhb_zvbb_zvkt_zvkg" { target { rv32 } } } */
+
+#ifndef __riscv_zvkng
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkg
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkng-2.c b/gcc/testsuite/gcc.target/riscv/zvkng-2.c
new file mode 100644
index 0000000..2631c1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkng-2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkn_zvkg" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkn_zvkg" { target { rv32 } } } */
+
+#ifndef __riscv_zvkng
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkg
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkng.c b/gcc/testsuite/gcc.target/riscv/zvkng.c
new file mode 100644
index 0000000..e6c950e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkng.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkng" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkng" { target { rv32 } } } */
+
+#ifndef __riscv_zvkng
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkn
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkned
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkg
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvknha.c b/gcc/testsuite/gcc.target/riscv/zvknha.c
new file mode 100644
index 0000000..1275f9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvknha.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvknha" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvknha" { target { rv32 } } } */
+
+#ifndef __riscv_zvknha
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvknhb.c b/gcc/testsuite/gcc.target/riscv/zvknhb.c
new file mode 100644
index 0000000..669ff01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvknhb.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvknhb" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvknhb" { target { rv32 } } } */
+
+#ifndef __riscv_zvknhb
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvks-1.c b/gcc/testsuite/gcc.target/riscv/zvks-1.c
new file mode 100644
index 0000000..28ad26a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvks-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvksed_zvksh_zvbb_zvkt" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvksed_zvksh_zvbb_zvkt" { target { rv32 } } } */
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvks.c b/gcc/testsuite/gcc.target/riscv/zvks.c
new file mode 100644
index 0000000..a48c918
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvks.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvks" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvks" { target { rv32 } } } */
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksc-1.c b/gcc/testsuite/gcc.target/riscv/zvksc-1.c
new file mode 100644
index 0000000..72d9676
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksc-1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvksed_zvksh_zvbb_zvkt_zvbc" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvksed_zvksh_zvbb_zvkt_zvbc" { target { rv32 } } } */
+
+#ifndef __riscv_zvksc
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbc
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksc-2.c b/gcc/testsuite/gcc.target/riscv/zvksc-2.c
new file mode 100644
index 0000000..c78b4fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksc-2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvks_zvbc" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvks_zvbc" { target { rv32 } } } */
+
+#ifndef __riscv_zvksc
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbc
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksc.c b/gcc/testsuite/gcc.target/riscv/zvksc.c
new file mode 100644
index 0000000..fb61561
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksc.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvksc" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvksc" { target { rv32 } } } */
+
+#ifndef __riscv_zvksc
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbc
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksed.c b/gcc/testsuite/gcc.target/riscv/zvksed.c
new file mode 100644
index 0000000..439b546
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksed.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvksed" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvksed" { target { rv32 } } } */
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksg-1.c b/gcc/testsuite/gcc.target/riscv/zvksg-1.c
new file mode 100644
index 0000000..8cbd033
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksg-1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvksed_zvksh_zvbb_zvkt_zvkg" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvksed_zvksh_zvbb_zvkt_zvkg" { target { rv32 } } } */
+
+#ifndef __riscv_zvksg
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkg
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksg-2.c b/gcc/testsuite/gcc.target/riscv/zvksg-2.c
new file mode 100644
index 0000000..d56c47e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksg-2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvks_zvkg" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvks_zvkg" { target { rv32 } } } */
+
+#ifndef __riscv_zvksg
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkg
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksg.c b/gcc/testsuite/gcc.target/riscv/zvksg.c
new file mode 100644
index 0000000..44dffb4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksg.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvksg" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvksg" { target { rv32 } } } */
+
+#ifndef __riscv_zvksg
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvks
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksed
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvbb
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+#ifndef __riscv_zvkg
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvksh.c b/gcc/testsuite/gcc.target/riscv/zvksh.c
new file mode 100644
index 0000000..5359ca5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvksh.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvksh" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvksh" { target { rv32 } } } */
+
+#ifndef __riscv_zvksh
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zvkt.c b/gcc/testsuite/gcc.target/riscv/zvkt.c
new file mode 100644
index 0000000..49822b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zvkt.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zvkt" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zvkt" { target { rv32 } } } */
+
+#ifndef __riscv_zvkt
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/s390/larl-1.c b/gcc/testsuite/gcc.target/s390/larl-1.c
new file mode 100644
index 0000000..5ef2ef6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/larl-1.c
@@ -0,0 +1,32 @@
+/* Check if load-address-relative instructions are created */
+
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O2 -march=z10 -mzarch -fno-section-anchors" } */
+
+/* An explicitely misaligned symbol. This symbol is NOT aligned as
+ mandated by our ABI. However, the back-end needs to handle that in
+ order to make things like __attribute__((packed)) work. The symbol
+ address is expected to be loaded from literal pool. */
+/* { dg-final { scan-assembler "lgrl\t%r2," { target { lp64 } } } } */
+/* { dg-final { scan-assembler "lrl\t%r2," { target { ! lp64 } } } } */
+extern char align1 __attribute__((aligned(1)));
+
+/* { dg-final { scan-assembler "larl\t%r2,align2" } } */
+extern char align2 __attribute__((aligned(2)));
+
+/* { dg-final { scan-assembler "larl\t%r2,align4" } } */
+extern char align4 __attribute__((aligned(4)));
+
+/* An external char symbol without explicit alignment has a DECL_ALIGN
+ of just 8. In contrast to local definitions DATA_ABI_ALIGNMENT is
+ NOT applied to DECL_ALIGN in that case. Make sure the backend
+ still assumes this symbol to be aligned according to ABI
+ requirements. */
+/* { dg-final { scan-assembler "larl\t%r2,align_default" } } */
+extern char align_default;
+
+char * foo1 () { return &align1; }
+char * foo2 () { return &align2; }
+char * foo3 () { return &align4; }
+char * foo4 () { return &align_default; }
+
diff --git a/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d b/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
index 7b83fff..0d12bcb 100644
--- a/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
+++ b/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
@@ -77,32 +77,32 @@ void test_shuffle()
void test_shufflevector()
{
- shufflevector!(int, int4, int)(0, 0, 0); // { dg-warning "mismatch in argument 1" }
- shufflevector!(double, int4, int)(0, 0, 0); // { dg-warning "mismatch in argument 1" }
- shufflevector!(fake4, int4, int)(f, 0, 0); // { dg-warning "mismatch in argument 1" }
-
- shufflevector!(int4, int, int)(0, 0, 0); // { dg-warning "mismatch in argument 2" }
- shufflevector!(int4, double, int)(0, 0, 0); // { dg-warning "mismatch in argument 2" }
- shufflevector!(int4, int4, int)(0, 0, 0);
- shufflevector!(int4, short8, int)(0, 0, 0); // { dg-error "mismatch in argument 2" }
- shufflevector!(int4, float4, int)(0, 0, 0); // { dg-error "mismatch in argument 2" }
- shufflevector!(int4, byte16, int)(0, 0, 0); // { dg-error "mismatch in argument 2" }
- shufflevector!(int4, fake4, int)(0, f, 0); // { dg-warning "mismatch in argument 2" }
-
- shufflevector!(int4, int4, double)(0, 0, 0); // { dg-warning "mismatch in argument 3" }
- shufflevector!(int4, int4, int4)(0, 0, 0); // { dg-warning "mismatch in argument 3" }
- shufflevector!(int4, int4, short8)(0, 0, 0); // { dg-warning "mismatch in argument 3" }
- shufflevector!(int4, int4, float4)(0, 0, 0); // { dg-warning "mismatch in argument 3" }
- shufflevector!(int4, int4, byte16)(0, 0, 0); // { dg-warning "mismatch in argument 3" }
-
- shufflevector!(int4, int4, int, double)(0, 0, 0, 0); // { dg-warning "mismatch in argument 4" }
+ shufflevector!(int, int4, int, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 1" }
+ shufflevector!(double, int4, int, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 1" }
+ shufflevector!(fake4, int4, int, int, int, int)(f, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 1" }
+
+ shufflevector!(int4, int, int, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 2" }
+ shufflevector!(int4, double, int, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 2" }
+ shufflevector!(int4, int4, int, int, int, int)(0, 0, 0, 0, 0, 0);
+ shufflevector!(int4, short8, int, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-error "mismatch in argument 2" }
+ shufflevector!(int4, float4, int, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-error "mismatch in argument 2" }
+ shufflevector!(int4, byte16, int, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-error "mismatch in argument 2" }
+ shufflevector!(int4, fake4, int, int, int, int)(0, f, 0, 0, 0, 0); // { dg-warning "mismatch in argument 2" }
+
+ shufflevector!(int4, int4, double, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 3" }
+ shufflevector!(int4, int4, int4, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 3" }
+ shufflevector!(int4, int4, short8, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 3" }
+ shufflevector!(int4, int4, float4, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 3" }
+ shufflevector!(int4, int4, byte16, int, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 3" }
+
+ shufflevector!(int4, int4, int, double, int, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 4" }
shufflevector!(int4, int4, int, int, double, int)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 5" }
shufflevector!(int4, int4, int, int, int, double)(0, 0, 0, 0, 0, 0); // { dg-warning "mismatch in argument 6" }
int i;
- shufflevector!(int4, int4, int)(0, 0, i); // { dg-error "argument .i. cannot be read at compile time" }
- shufflevector!(int4, int4, int)(0, 0, -1u); // { dg-error "element index .-1. is out of bounds" }
- shufflevector!(int4, int4, int)(0, 0, 8); // { dg-error "element index .8. is out of bounds" }
+ shufflevector!(int4, int4, int, int, int, int)(0, 0, i, 0, 0, 0); // { dg-error "argument .i. cannot be read at compile time" }
+ shufflevector!(int4, int4, int, int, int, int)(0, 0, -1u, 0, 0, 0); // { dg-error "element index .-1. is out of bounds" }
+ shufflevector!(int4, int4, int, int, int, int)(0, 0, 8, 0, 0, 0); // { dg-error "element index .8. is out of bounds" }
}
void test_convertvector()
diff --git a/gcc/testsuite/gdc.dg/pr108962.d b/gcc/testsuite/gdc.dg/pr108962.d
new file mode 100644
index 0000000..0fefa12
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr108962.d
@@ -0,0 +1,13 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108962
+// { dg-do compile }
+// { dg-options "-fno-exceptions -fdump-tree-original" }
+extern(C) void main()
+{
+ final switch (0)
+ {
+ case 1:
+ return;
+ }
+}
+// { dg-final { scan-tree-dump-times "_d_assert_msg" 1 "original" } }
+// { dg-final { scan-tree-dump-not "_d_throw" "original" } }
diff --git a/gcc/testsuite/gdc.dg/pr110359.d b/gcc/testsuite/gdc.dg/pr110359.d
new file mode 100644
index 0000000..bf69201
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110359.d
@@ -0,0 +1,22 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110359
+// { dg-do compile }
+// { dg-options "-fdump-tree-original" }
+double pow(in double x, in ulong p)
+{
+ import gcc.builtins : __builtin_expect;
+ if (__builtin_expect(p == 0, false))
+ return 1;
+ if (__builtin_expect(p == 1, false))
+ return x;
+
+ double s = x;
+ double v = 1;
+ for (ulong i = p; i > 1; i >>= 1)
+ {
+ v = (i & 0x1) ? s * v : v;
+ s = s * s;
+ }
+ return v * s;
+}
+// { dg-final { scan-tree-dump "if \\(__builtin_expect \\(p == 0, 0\\) != 0\\)" "original" } }
+// { dg-final { scan-tree-dump "if \\(__builtin_expect \\(p == 1, 0\\) != 0\\)" "original" } }
diff --git a/gcc/testsuite/gdc.dg/pr110471a.d b/gcc/testsuite/gdc.dg/pr110471a.d
new file mode 100644
index 0000000..2182f3d
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110471a.d
@@ -0,0 +1,5 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110471
+// { dg-do compile }
+// { dg-options "-fno-exceptions" }
+version (D_Exceptions)
+ static assert(0);
diff --git a/gcc/testsuite/gdc.dg/pr110471b.d b/gcc/testsuite/gdc.dg/pr110471b.d
new file mode 100644
index 0000000..32562c1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110471b.d
@@ -0,0 +1,5 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110471
+// { dg-do compile }
+// { dg-options "-fno-moduleinfo" }
+version (D_ModuleInfo)
+ static assert(0);
diff --git a/gcc/testsuite/gdc.dg/pr110471c.d b/gcc/testsuite/gdc.dg/pr110471c.d
new file mode 100644
index 0000000..6d13dba
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110471c.d
@@ -0,0 +1,5 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110471
+// { dg-do compile }
+// { dg-options "-fno-rtti" }
+version (D_TypeInfo)
+ static assert(0);
diff --git a/gcc/testsuite/gdc.dg/pr110514a.d b/gcc/testsuite/gdc.dg/pr110514a.d
new file mode 100644
index 0000000..46e3705
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110514a.d
@@ -0,0 +1,9 @@
+// { dg-do "compile" }
+// { dg-options "-O -fdump-tree-optimized" }
+immutable uint[] imm_arr = [1,2,3];
+int test_imm(immutable uint[] ptr)
+{
+ return imm_arr[2] == 3 ? 123 : 456;
+}
+// { dg-final { scan-assembler-not "_d_arraybounds_indexp" } }
+// { dg-final { scan-tree-dump "return 123;" optimized } }
diff --git a/gcc/testsuite/gdc.dg/pr110514b.d b/gcc/testsuite/gdc.dg/pr110514b.d
new file mode 100644
index 0000000..86aeb48
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110514b.d
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-options "-O" }
+immutable uint[] imm_ctor_arr;
+int test_imm_ctor(immutable uint[] ptr)
+{
+ return imm_ctor_arr[2] == 3;
+}
+// { dg-final { scan-assembler "_d_arraybounds_indexp" } }
diff --git a/gcc/testsuite/gdc.dg/pr110514c.d b/gcc/testsuite/gdc.dg/pr110514c.d
new file mode 100644
index 0000000..94779e1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110514c.d
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-options "-O" }
+const uint[] cst_arr = [1,2,3];
+int test_cst(const uint[] ptr)
+{
+ return cst_arr[2] == 3;
+}
+// { dg-final { scan-assembler "_d_arraybounds_indexp" } }
diff --git a/gcc/testsuite/gdc.dg/pr110514d.d b/gcc/testsuite/gdc.dg/pr110514d.d
new file mode 100644
index 0000000..56e9a31
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110514d.d
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-options "-O" }
+const uint[] cst_ctor_arr;
+int test_cst_ctor(const uint[] ptr)
+{
+ return cst_ctor_arr[2] == 3;
+}
+// { dg-final { scan-assembler "_d_arraybounds_indexp" } }
diff --git a/gcc/testsuite/gdc.dg/torture/pr110406.d b/gcc/testsuite/gdc.dg/torture/pr110406.d
new file mode 100644
index 0000000..c380e4b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr110406.d
@@ -0,0 +1,25 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110406
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "-fdump-tree-optimized" }
+struct cpuid_abcd_t
+{
+ uint eax;
+ uint ebx;
+ uint ecx;
+ uint edx;
+};
+
+cpuid_abcd_t cpuid_insn(const uint in_eax)
+{
+ cpuid_abcd_t ret = void;
+ asm { "cpuid"
+ : "=a" (ret.eax),
+ "=b" (ret.ebx),
+ "=c" (ret.ecx),
+ "=d" (ret.edx)
+ : "a" (in_eax)
+ :;
+ }
+ return ret;
+}
+// { dg-final { scan-tree-dump-not "MEM <vector\\(4\\) uint>" "optimized" } }
diff --git a/gcc/testsuite/gdc.dg/torture/pr110516a.d b/gcc/testsuite/gdc.dg/torture/pr110516a.d
new file mode 100644
index 0000000..276455a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr110516a.d
@@ -0,0 +1,12 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110516
+// { dg-do compile }
+// { dg-options "-fno-moduleinfo -fdump-tree-optimized" }
+void fn110516(ubyte* ptr)
+{
+ import core.volatile : volatileLoad;
+ volatileLoad(ptr);
+ volatileLoad(ptr);
+ volatileLoad(ptr);
+ volatileLoad(ptr);
+}
+// { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } }
diff --git a/gcc/testsuite/gdc.dg/torture/pr110516b.d b/gcc/testsuite/gdc.dg/torture/pr110516b.d
new file mode 100644
index 0000000..b7a67e7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr110516b.d
@@ -0,0 +1,12 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110516
+// { dg-do compile }
+// { dg-options "-fno-moduleinfo -fdump-tree-optimized" }
+void fn110516(ubyte* ptr)
+{
+ import core.volatile : volatileStore;
+ volatileStore(ptr, 0);
+ volatileStore(ptr, 0);
+ volatileStore(ptr, 0);
+ volatileStore(ptr, 0);
+}
+// { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } }
diff --git a/gcc/testsuite/gdc.test/compilable/shared.d b/gcc/testsuite/gdc.test/compilable/shared.d
index 695083a..647910e 100644
--- a/gcc/testsuite/gdc.test/compilable/shared.d
+++ b/gcc/testsuite/gdc.test/compilable/shared.d
@@ -11,34 +11,48 @@ ref shared(int) f(return shared ref int y)
}
// https://issues.dlang.org/show_bug.cgi?id=20908
+struct S
+{
+ int i = 2;
+}
+
+union U
+{
+ int i = 1;
+ bool b;
+}
+
void test20908()
{
- // shared locals (or struct members) should be able to be initialised:
- shared int x;
+ // shared locals (or struct members) should be able to be initialised:
+ shared int x;
- ref shared(int) fun()
- {
- static shared(int) val;
+ ref shared(int) fun()
+ {
+ static shared(int) val;
- // return by reference
- return val;
- }
+ // return by reference
+ return val;
+ }
- ref shared(int) fun2()
- {
- static shared(int)* val;
+ ref shared(int) fun2()
+ {
+ static shared(int)* val;
- // transfer pointer to reference
- return *val;
- }
+ // transfer pointer to reference
+ return *val;
+ }
- ref shared(int) fun3()
- {
- static shared(int)*** val;
+ ref shared(int) fun3()
+ {
+ static shared(int)*** val;
+
+ // Multiple indirections
+ return ***val;
+ }
- // Multiple indirections
- return ***val;
- }
+ shared S s;
+ shared U u;
}
// Simple tests for `DotVarExp`
@@ -130,3 +144,15 @@ void main()
{
auto b = new shared Class();
}
+
+// https://issues.dlang.org/show_bug.cgi?id=23790
+bool cas(shared bool*, bool, bool) { return true; }
+
+struct Argh
+{
+ bool locked;
+ void lock() shared
+ {
+ while(!cas(&locked, false, true)) {}
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22739.d b/gcc/testsuite/gdc.test/compilable/test22739.d
new file mode 100644
index 0000000..6aeb5d6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22739.d
@@ -0,0 +1,10 @@
+// https://issues.dlang.org/show_bug.cgi?id=22739
+
+extern(C++) auto f(T)()
+{
+ return T.init;
+}
+void main()
+{
+ f!int;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23799.d b/gcc/testsuite/gdc.test/compilable/test23799.d
new file mode 100644
index 0000000..0073516
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23799.d
@@ -0,0 +1,37 @@
+// https://issues.dlang.org/show_bug.cgi?id=23799
+
+// REQUIRED_ARGS: -betterC
+
+struct Data
+{
+ Data[] range;
+ string test;
+}
+
+Data[] foo()
+{
+ Data[] ret;
+ if (__ctfe)
+ {
+ Data tmp;
+ tmp.range ~= Data.init;
+ ret ~= tmp;
+ }
+ return ret;
+}
+
+void func(Data dat)()
+{
+}
+
+void bar(Data dat)()
+{
+ if (dat.test.length)
+ func!(dat.range[0])();
+}
+
+extern (C) void main()
+{
+ static immutable data = foo();
+ bar!(data[0])();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
index f456454..c980d76 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
@@ -4,7 +4,7 @@ TEST_OUTPUT:
fail_compilation/bug9631.d(20): Error: cannot implicitly convert expression `F()` of type `bug9631.T1!().F` to `bug9631.T2!().F`
---
*/
-
+// DISABLED: win32
template T1()
{
struct F { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/cerrors.d b/gcc/testsuite/gdc.test/fail_compilation/cerrors.d
index 3d69d41..db306c1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/cerrors.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/cerrors.d
@@ -1,10 +1,12 @@
/* REQUIRED_ARGS: -wi
TEST_OUTPUT:
---
-fail_compilation/cerrors.d(11): Error: C preprocessor directive `#if` is not supported, use `version` or `static if`
-fail_compilation/cerrors.d(11): Error: declaration expected, not `#`
-fail_compilation/cerrors.d(15): Warning: C preprocessor directive `#endif` is not supported
-fail_compilation/cerrors.d(15): Error: declaration expected, not `#`
+fail_compilation/cerrors.d(13): Error: C preprocessor directive `#if` is not supported, use `version` or `static if`
+fail_compilation/cerrors.d(13): Error: declaration expected, not `#`
+fail_compilation/cerrors.d(17): Error: C preprocessor directive `#endif` is not supported
+fail_compilation/cerrors.d(17): Error: declaration expected, not `#`
+fail_compilation/cerrors.d(21): Error: token string requires valid D tokens, not `#if`
+fail_compilation/cerrors.d(22): Deprecation: token string requires valid D tokens, not `#include`
---
*/
@@ -13,3 +15,9 @@ fail_compilation/cerrors.d(15): Error: declaration expected, not `#`
void test(wchar_t u);
#endif
+
+// https://issues.dlang.org/show_bug.cgi?id=23792
+enum s1 = q{
+#if 1
+#include <test>
+};
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17646.d b/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
index 39e7cb9..2074b47 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
@@ -4,7 +4,7 @@ EXTRA_FILES: imports/fail17646.d
TEST_OUTPUT:
---
fail_compilation/imports/fail17646.d(10): Error: found `}` instead of statement
-fail_compilation/fail17646.d(11): Error: function `fail17646.runTests!"".runTests` has no `return` statement, but is expected to return a value of type `int`
+fail_compilation/fail17646.d(15): Error: template instance `allTestData!Modules` template `allTestData` is not defined
fail_compilation/fail17646.d(18): Error: template instance `fail17646.runTests!""` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19948.d b/gcc/testsuite/gdc.test/fail_compilation/fail19948.d
index 6122e41..e8a9e77 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19948.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19948.d
@@ -7,7 +7,7 @@ fail_compilation/fail19948.d(15): Error: function `fail19948.func(const(X))` is
fail_compilation/fail19948.d(15): cannot pass argument `X()` of type `fail19948.main.X` to parameter `const(fail19948.X)`
---
*/
-
+// DISABLED: win32
struct X {}
void main()
{
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22857.d b/gcc/testsuite/gdc.test/fail_compilation/fail22857.d
new file mode 100644
index 0000000..061eb62
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22857.d
@@ -0,0 +1,18 @@
+// https://issues.dlang.org/show_bug.cgi?id=22857
+// EXTRA_FILES: imports/import22857.d
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/import22857.d(4): Error: (expression) expected following `static if`
+fail_compilation/imports/import22857.d(4): Error: declaration expected, not `}`
+fail_compilation/fail22857.d(17): Error: template instance `unaryFun!()` template `unaryFun` is not defined
+---
+*/
+
+void isPrettyPropertyName()
+{
+ import imports.import22857;
+
+ unaryFun!();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23816.d b/gcc/testsuite/gdc.test/fail_compilation/fail23816.d
new file mode 100644
index 0000000..574a712
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23816.d
@@ -0,0 +1,16 @@
+// https://issues.dlang.org/show_bug.cgi?id=23816
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail23816.d(14): Error: opcode expected, not `NOP`
+---
+*/
+
+void main()
+{
+ asm
+ {
+ NOP;
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d b/gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d
new file mode 100644
index 0000000..280c2eb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d
@@ -0,0 +1,4 @@
+template unaryFun()
+{
+ static if
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/shared.d b/gcc/testsuite/gdc.test/fail_compilation/shared.d
index afdea64..8b94a79 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/shared.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/shared.d
@@ -259,3 +259,22 @@ void test_casting_safe() @safe
auto x1 = cast(int*)s;
auto x2 = cast(const(shared(int*)))s;
}
+
+#line 3100
+
+// https://issues.dlang.org/show_bug.cgi?id=23783
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/shared.d(3114): Error: direct access to shared `x` is not allowed, see `core.atomic`
+fail_compilation/shared.d(3115): Error: direct access to shared `x` is not allowed, see `core.atomic`
+---
+*/
+
+void test23783()
+{
+ shared int x = 3;
+ assert(x == 3);
+ bool b = x == 3;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21164.d b/gcc/testsuite/gdc.test/fail_compilation/test21164.d
index f42c4bc..a120024 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21164.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21164.d
@@ -3,7 +3,8 @@ TEST_OUTPUT:
---
fail_compilation/imports/test21164d.d(3): Error: (expression) expected following `static if`
fail_compilation/imports/test21164d.d(3): Error: found `}` instead of statement
-fail_compilation/test21164.d(11): Error: template instance `test21164a.D!(R!(O(), 1))` error instantiating
+fail_compilation/imports/test21164a.d(5): Error: undefined identifier `I`
+fail_compilation/test21164.d(12): Error: template instance `test21164a.D!(R!(O(), 1))` error instantiating
---
*/
import imports.test21164a;
diff --git a/gcc/testsuite/gdc.test/runnable/complex3.d b/gcc/testsuite/gdc.test/runnable/complex3.d
new file mode 100644
index 0000000..7167b0b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/complex3.d
@@ -0,0 +1,31 @@
+// https://issues.dlang.org/show_bug.cgi?id=23778
+
+
+enum __c_long_double : double;
+
+alias __c_long_double c_long_double;
+
+struct _Complex
+{
+ c_long_double re;
+ c_long_double im;
+}
+
+version (all) // bug to test
+{
+ enum __c_complex_real : _Complex;
+ alias c_complex_real = __c_complex_real;
+}
+else // works
+ enum c_complex_real : _Complex;
+
+c_complex_real toNative2(real re, real im)
+{
+ return c_complex_real(re, im);
+}
+
+void main()
+{
+ c_complex_real n = toNative2(123, 456);
+ assert(123 == n.re && 456 == n.im);
+}
diff --git a/gcc/testsuite/gfortran.dg/pr25623.f90 b/gcc/testsuite/gfortran.dg/pr25623.f90
new file mode 100644
index 0000000..30905e4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr25623.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-optimized-blocks -O2" }
+
+SUBROUTINE S42(a,b,c,N)
+ IMPLICIT NONE
+ integer :: N
+ real*8 :: a(N),b(N),c(N),tmp,tmp2,tmp4
+ real*8, parameter :: p=1.0D0/3.0D0
+ integer :: i
+ c=0.0D0
+ DO i=1,N
+ tmp=a(i)**p ! could even be done with a cube root
+ tmp2=tmp*tmp
+ tmp4=tmp2*tmp2
+ b(i)=b(i)+tmp4
+ c(i)=c(i)+tmp2
+ ENDDO
+END SUBROUTINE
+! { dg-final { scan-tree-dump-not "Invalid sum" "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/pr49213.f90 b/gcc/testsuite/gfortran.dg/pr49213.f90
new file mode 100644
index 0000000..293dce8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr49213.f90
@@ -0,0 +1,109 @@
+! { dg-do run }
+!
+! Contributed by Neil Carlson <neil.n.carlson@gmail.com>
+!
+program main
+ character(2) :: c
+
+ type :: S
+ integer :: n
+ end type
+ type(S) :: Sobj
+
+ type, extends(S) :: S2
+ integer :: m
+ end type
+ type(S2) :: S2obj
+
+ type :: T
+ class(S), allocatable :: x
+ end type
+
+ type tContainer
+ class(*), allocatable :: x
+ end type
+
+ type(T) :: Tobj
+
+ Sobj = S(1)
+ Tobj = T(Sobj)
+
+ S2obj = S2(1,2)
+ Tobj = T(S2obj) ! Failed here
+ select type (x => Tobj%x)
+ type is (S2)
+ if ((x%n .ne. 1) .or. (x%m .ne. 2)) stop 1
+ class default
+ stop 2
+ end select
+
+ c = " "
+ call pass_it (T(Sobj))
+ if (c .ne. "S ") stop 3
+ call pass_it (T(S2obj)) ! and here
+ if (c .ne. "S2") stop 4
+
+ call bar
+
+contains
+
+ subroutine pass_it (foo)
+ type(T), intent(in) :: foo
+ select type (x => foo%x)
+ type is (S)
+ c = "S "
+ if (x%n .ne. 1) stop 5
+ type is (S2)
+ c = "S2"
+ if ((x%n .ne. 1) .or. (x%m .ne. 2)) stop 6
+ class default
+ stop 7
+ end select
+ end subroutine
+
+ subroutine check_it (t, errno)
+ type(tContainer) :: t
+ integer :: errno
+ select type (x => t%x)
+ type is (integer)
+ if (x .ne. 42) stop errno
+ type is (integer(8))
+ if (x .ne. 42_8) stop errno
+ type is (real(8))
+ if (int(x**2) .ne. 2) stop errno
+ type is (character(*, kind=1))
+ if (x .ne. "end of tests") stop errno
+ type is (character(*, kind=4))
+ if ((x .ne. 4_"hello!") .and. (x .ne. 4_"goodbye")) stop errno
+ class default
+ stop errno
+ end select
+ end subroutine
+
+ subroutine bar
+ ! Test from comment #29 extended by Harald Anlauf to check kinds /= default
+ integer(8), parameter :: i = 0_8
+ integer :: j = 42
+ character(7,kind=4) :: chr4 = 4_"goodbye"
+ type(tContainer) :: cont
+
+ cont%x = j
+ call check_it (cont, 8)
+
+ cont = tContainer(i+42_8)
+ call check_it (cont, 9)
+
+ cont = tContainer(sqrt (2.0_8))
+ call check_it (cont, 10)
+
+ cont = tContainer(4_"hello!")
+ call check_it (cont, 11)
+
+ cont = tContainer(chr4)
+ call check_it (cont, 12)
+
+ cont = tContainer("end of tests")
+ call check_it (cont, 13)
+
+ end subroutine bar
+end program
diff --git a/gcc/testsuite/gfortran.dg/value_9.f90 b/gcc/testsuite/gfortran.dg/value_9.f90
new file mode 100644
index 0000000..1a2fa80
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/value_9.f90
@@ -0,0 +1,101 @@
+! { dg-do run }
+! PR fortran/110360 - ABI for scalar character(len=1),value dummy argument
+
+program p
+ implicit none
+ character, allocatable :: ca
+ character, pointer :: cp
+ character(len=:), allocatable :: cd
+ character (kind=4), allocatable :: ca4
+ character (kind=4), pointer :: cp4
+ character(len=:,kind=4), allocatable :: cd4
+ character :: c = "1"
+ character (kind=4) :: c4 = 4_"4"
+ character(len=3) :: d = "210"
+ character(len=3,kind=4) :: d4 = 4_"321"
+ integer :: a = 65
+ integer :: l = 2
+ allocate (ca, cp, ca4, cp4)
+
+ ! Check len=1 actual argument cases first
+ ca = "a"; cp = "b"; cd = "c"
+ ca4 = 4_"d"; cp4 = 4_"e"; cd4 = 4_"f"
+ call val ("B","B")
+ call val ("A",char(65))
+ call val ("A",char(a))
+ call val ("A",mychar(65))
+ call val ("A",mychar(a))
+ call val ("1",c)
+ call val ("1",(c))
+ call val4 (4_"C",4_"C")
+ call val4 (4_"A",char(65,kind=4))
+ call val4 (4_"A",char(a, kind=4))
+ call val4 (4_"4",c4)
+ call val4 (4_"4",(c4))
+ call val (ca,ca)
+ call val (cp,cp)
+ call val (cd,cd)
+ call val (ca,(ca))
+ call val4 (ca4,ca4)
+ call val4 (cp4,cp4)
+ call val4 (cd4,cd4)
+ call val4 (cd4,(cd4))
+ call sub ("S")
+ call sub4 (4_"T")
+
+ ! Check that always the first character of the string is finally used
+ call val ( "U++", "U--")
+ call val4 (4_"V**",4_"V//")
+ call sub ( "WTY")
+ call sub4 (4_"ZXV")
+ call val ( "234", d )
+ call val4 (4_"345", d4 )
+ call val ( "234", (d) )
+ call val4 (4_"345", (d4) )
+ call val ( "234", d (1:2))
+ call val4 (4_"345", d4(1:2))
+ call val ( "234", d (1:l))
+ call val4 (4_"345", d4(1:l))
+ call val ("1",c // d)
+ call val ("1",trim (c // d))
+ call val4 (4_"4",c4 // d4)
+ call val4 (4_"4",trim (c4 // d4))
+ cd = "gkl"; cd4 = 4_"hmn"
+ call val (cd,cd)
+ call val4 (cd4,cd4)
+ call sub (cd)
+ call sub4 (cd4)
+ deallocate (ca, cp, ca4, cp4, cd, cd4)
+contains
+ subroutine val (x, c)
+ character(kind=1), intent(in) :: x ! control: pass by reference
+ character(kind=1), value :: c
+ print *, "by value(kind=1): ", c
+ if (c /= x) stop 1
+ c = "*"
+ if (c /= "*") stop 2
+ end
+
+ subroutine val4 (x, c)
+ character(kind=4), intent(in) :: x ! control: pass by reference
+ character(kind=4), value :: c
+ print *, "by value(kind=4): ", c
+ if (c /= x) stop 3
+ c = 4_"#"
+ if (c /= 4_"#") stop 4
+ end
+
+ subroutine sub (s)
+ character(*), intent(in) :: s
+ call val (s, s)
+ end
+ subroutine sub4 (s)
+ character(kind=4,len=*), intent(in) :: s
+ call val4 (s, s)
+ end
+
+ character function mychar (i)
+ integer, intent(in) :: i
+ mychar = char (i)
+ end
+end
diff --git a/gcc/testsuite/gfortran.dg/vect/pr110451.f b/gcc/testsuite/gfortran.dg/vect/pr110451.f
new file mode 100644
index 0000000..ba77b0d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/vect/pr110451.f
@@ -0,0 +1,51 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_condition }
+! { dg-require-effective-target vect_double }
+! { dg-additional-options "-ffast-math -floop-interchange -fdump-tree-linterchange-details -fdump-tree-vect-details" }
+! { dg-additional-options "-mprefer-vector-width=128" { target x86_64-*-* i?86-*-* } }
+
+ subroutine mat_times_vec(y,x,a,axp,ayp,azp,axm,aym,azm,
+ $ nb,nx,ny,nz)
+ implicit none
+ integer nb,nx,ny,nz,i,j,k,m,l,kit,im1,ip1,jm1,jp1,km1,kp1
+
+ real*8 y(nb,nx,ny,nz),x(nb,nx,ny,nz)
+
+ real*8 a(nb,nb,nx,ny,nz),
+ 1 axp(nb,nb,nx,ny,nz),ayp(nb,nb,nx,ny,nz),azp(nb,nb,nx,ny,nz),
+ 2 axm(nb,nb,nx,ny,nz),aym(nb,nb,nx,ny,nz),azm(nb,nb,nx,ny,nz)
+
+
+ do k=1,nz
+ km1=mod(k+nz-2,nz)+1
+ kp1=mod(k,nz)+1
+ do j=1,ny
+ jm1=mod(j+ny-2,ny)+1
+ jp1=mod(j,ny)+1
+ do i=1,nx
+ im1=mod(i+nx-2,nx)+1
+ ip1=mod(i,nx)+1
+ do l=1,nb
+ y(l,i,j,k)=0.0d0
+ do m=1,nb
+ y(l,i,j,k)=y(l,i,j,k)+
+ 1 a(l,m,i,j,k)*x(m,i,j,k)+
+ 2 axp(l,m,i,j,k)*x(m,ip1,j,k)+
+ 3 ayp(l,m,i,j,k)*x(m,i,jp1,k)+
+ 4 azp(l,m,i,j,k)*x(m,i,j,kp1)+
+ 5 axm(l,m,i,j,k)*x(m,im1,j,k)+
+ 6 aym(l,m,i,j,k)*x(m,i,jm1,k)+
+ 7 azm(l,m,i,j,k)*x(m,i,j,km1)
+ enddo
+ enddo
+ enddo
+ enddo
+ enddo
+ return
+ end
+
+! loop interchange adds a conditional on m != 1 in the innermost loop
+! verify that is hoisted and thus not affecting the vectorization factor
+
+! { dg-final { scan-tree-dump-times "is interchanged" 1 "linterchange" } }
+! { dg-final { scan-tree-dump "vectorization factor = 2" "vect" { target x86_64-*-* i?86-*-* } } }
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/switches-uninit-variable-checking-fail.exp b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/switches-uninit-variable-checking-fail.exp
new file mode 100644
index 0000000..36b36d2
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/switches-uninit-variable-checking-fail.exp
@@ -0,0 +1,37 @@
+# Expect driver script for GCC Regression Tests
+# Copyright (C) 2023 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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/>.
+
+# This file was written by Gaius Mulley (gaius.mulley@southwales.ac.uk)
+# for GNU Modula-2.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# load support procs
+load_lib gm2-torture.exp
+
+gm2_init_pim "${srcdir}/gm2/switches/uninit-variable-checking/fail" -Wuninit-variable-checking
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+
+ gm2-torture-fail $testcase
+}
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testinit.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testinit.mod
new file mode 100644
index 0000000..cc5b60b
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testinit.mod
@@ -0,0 +1,17 @@
+MODULE testinit ;
+
+
+PROCEDURE test ;
+VAR
+ p: CARDINAL ;
+BEGIN
+ (* p := 6 ; *)
+ IF p = 6
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testinit.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge.mod
new file mode 100644
index 0000000..8503c17
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge.mod
@@ -0,0 +1,27 @@
+MODULE testlarge ;
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ p.fg.r := 1 ;
+ p.fg.g := 2 ;
+ (* p.fg.b := 3 ; *)
+ p.bg := p.fg ; (* this should result in a warning. *)
+ IF p.bg.b = 6
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testlarge.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge2.mod
new file mode 100644
index 0000000..803f5ca
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testlarge2.mod
@@ -0,0 +1,24 @@
+MODULE testlarge2 ;
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ p.fg.r := 1 ;
+ p.fg.g := 2 ;
+ p.fg.g := 3 ; (* Deliberate typo should be p.fg.b. *)
+ p.bg := p.fg ; (* This should result in a warning. *)
+END test ;
+
+BEGIN
+ test
+END testlarge2.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit.mod
new file mode 100644
index 0000000..15bd1df
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit.mod
@@ -0,0 +1,31 @@
+MODULE testrecinit ;
+
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ p.fg.r := 1 ;
+ p.fg.g := 2 ;
+ p.fg.b := 3 ;
+ p.bg.r := 4 ;
+ p.bg.g := 5 ;
+ (* p.bg.b := 6 ; *)
+ (* forget to initialize p.bg.b *)
+ IF p.bg.b = 6 (* should catch error. *)
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testrecinit.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit2.mod
new file mode 100644
index 0000000..decce3b
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit2.mod
@@ -0,0 +1,25 @@
+MODULE testrecinit ;
+
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ p.fg.r := 1 ;
+ IF p.fg.g = 6 (* should catch error. *)
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testrecinit.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit5.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit5.mod
new file mode 100644
index 0000000..c67620a
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testrecinit5.mod
@@ -0,0 +1,25 @@
+MODULE testrecinit5 ;
+
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ (* p.bg.b := 6 ; *)
+ IF p.bg.b = 6
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testrecinit5.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec.mod
new file mode 100644
index 0000000..ce97473
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec.mod
@@ -0,0 +1,22 @@
+MODULE testsmallrec ;
+
+
+TYPE
+ vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ v: vec ;
+BEGIN
+ (* v.x := 1 ; *)
+ v.y := 2 ;
+ IF v.x = 1 (* This line should be the cause of a warning. *)
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testsmallrec.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec2.mod
new file mode 100644
index 0000000..c0be5d9
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallrec2.mod
@@ -0,0 +1,24 @@
+MODULE testsmallrec2 ;
+
+
+TYPE
+ vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ v: vec ;
+BEGIN
+ (* v.x := 1 ; *)
+ v.y := 2 ;
+ WITH v DO
+ IF x = 1
+ THEN
+ END
+ END
+END test ;
+
+BEGIN
+ test
+END testsmallrec2.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallvec.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallvec.mod
new file mode 100644
index 0000000..1e55bd1
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testsmallvec.mod
@@ -0,0 +1,20 @@
+MODULE testsmallvec ;
+
+TYPE
+ vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ v: vec ;
+BEGIN
+ IF v.x = 2
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testsmallvec.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testvarinit.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testvarinit.mod
new file mode 100644
index 0000000..8f188eb
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testvarinit.mod
@@ -0,0 +1,17 @@
+MODULE testvarinit ;
+
+
+PROCEDURE test ;
+VAR
+ x: CARDINAL ;
+BEGIN
+ (* x := 1 ; *)
+ IF x = 1
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testvarinit.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithnoptr.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithnoptr.mod
new file mode 100644
index 0000000..3836470
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithnoptr.mod
@@ -0,0 +1,29 @@
+MODULE testwithnoptr ;
+
+TYPE
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+
+(*
+ test -
+*)
+
+PROCEDURE test ;
+VAR
+ p: Vec ;
+BEGIN
+ WITH p DO
+ x := 1 ;
+ x := 2 (* deliberate typo - should be y *)
+ END ;
+ IF p.y = 2
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testwithnoptr.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr.mod
new file mode 100644
index 0000000..063ddc4
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr.mod
@@ -0,0 +1,34 @@
+MODULE testwithptr ;
+
+FROM SYSTEM IMPORT ADR ;
+
+TYPE
+ PtrToVec = POINTER TO Vec ;
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+
+(*
+ test -
+*)
+
+PROCEDURE test ;
+VAR
+ p: PtrToVec ;
+ v: Vec ;
+BEGIN
+ p := ADR (v) ;
+ WITH p^ DO
+ x := 1 ;
+ x := 2 (* deliberate typo - should be y *)
+ END ;
+ IF p^.y = 2
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testwithptr.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr2.mod
new file mode 100644
index 0000000..176b830
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr2.mod
@@ -0,0 +1,30 @@
+MODULE testwithptr2 ;
+
+TYPE
+ PtrToVec = POINTER TO Vec ;
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+
+(*
+ test -
+*)
+
+PROCEDURE test ;
+VAR
+ p: PtrToVec ;
+BEGIN
+ WITH p^ DO
+ x := 1 ;
+ x := 2 (* deliberate typo - should be y *)
+ END ;
+ IF p^.y = 2
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testwithptr2.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr3.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr3.mod
new file mode 100644
index 0000000..b442a62
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/fail/testwithptr3.mod
@@ -0,0 +1,21 @@
+MODULE testwithptr3 ;
+
+TYPE
+ ptr = POINTER TO vec ;
+ vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+
+PROCEDURE test ;
+VAR
+ p: ptr ;
+BEGIN
+ WITH p^ DO
+
+ END
+END test ;
+
+BEGIN
+ test
+END testwithptr3.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/switches-uninit-variable-checking-pass.exp b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/switches-uninit-variable-checking-pass.exp
new file mode 100644
index 0000000..078daeb
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/switches-uninit-variable-checking-pass.exp
@@ -0,0 +1,37 @@
+# Expect driver script for GCC Regression Tests
+# Copyright (C) 2023 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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/>.
+
+# This file was written by Gaius Mulley (gaius.mulley@southwales.ac.uk)
+# for GNU Modula-2.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# load support procs
+load_lib gm2-torture.exp
+
+gm2_init_pim "${srcdir}/gm2/switches/pedantic-params/pass" -Wuninit-variable-checking
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+
+ gm2-torture $testcase
+}
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit3.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit3.mod
new file mode 100644
index 0000000..872e875
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit3.mod
@@ -0,0 +1,30 @@
+MODULE testrecinit3 ;
+
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ p.fg.r := 1 ;
+ p.fg.g := 2 ;
+ p.fg.b := 3 ;
+ p.bg.r := 4 ;
+ p.bg.g := 5 ;
+ p.bg.b := 6 ;
+ IF p.bg.b = 6
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testrecinit3.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit5.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit5.mod
new file mode 100644
index 0000000..ea15c57
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testrecinit5.mod
@@ -0,0 +1,25 @@
+MODULE testrecinit5 ;
+
+
+TYPE
+ color = RECORD
+ r, g, b: CARDINAL ;
+ END ;
+
+ pixel = RECORD
+ fg, bg: color ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ p: pixel ;
+BEGIN
+ p.bg.b := 6 ;
+ IF p.bg.b = 6
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testrecinit5.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec.mod
new file mode 100644
index 0000000..37d855c
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec.mod
@@ -0,0 +1,22 @@
+MODULE testsmallrec ;
+
+
+TYPE
+ vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ v: vec ;
+BEGIN
+ v.x := 1 ;
+ v.y := 2 ;
+ IF v.x = 1
+ THEN
+ END
+END test ;
+
+BEGIN
+ test
+END testsmallrec.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec2.mod
new file mode 100644
index 0000000..095d72e
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testsmallrec2.mod
@@ -0,0 +1,24 @@
+MODULE testsmallrec2 ;
+
+
+TYPE
+ vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+PROCEDURE test ;
+VAR
+ v: vec ;
+BEGIN
+ v.x := 1 ;
+ v.y := 2 ;
+ WITH v DO
+ IF x = 1
+ THEN
+ END
+ END
+END test ;
+
+BEGIN
+ test
+END testsmallrec2.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testvarinit.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testvarinit.mod
new file mode 100644
index 0000000..8229bef
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testvarinit.mod
@@ -0,0 +1,17 @@
+MODULE testvarinit ;
+
+
+PROCEDURE test ;
+VAR
+ x: CARDINAL ;
+BEGIN
+ x := 1 ;
+ IF x = 1
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testvarinit.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr.mod
new file mode 100644
index 0000000..90d6373
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr.mod
@@ -0,0 +1,34 @@
+MODULE testwithptr ;
+
+FROM SYSTEM IMPORT ADR ;
+
+TYPE
+ PtrToVec = POINTER TO Vec ;
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+
+(*
+ test -
+*)
+
+PROCEDURE test ;
+VAR
+ p: PtrToVec ;
+ v: Vec ;
+BEGIN
+ p := ADR (v) ;
+ WITH p^ DO
+ x := 1 ;
+ y := 2
+ END ;
+ IF p^.y = 2
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testwithptr.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr2.mod
new file mode 100644
index 0000000..bb0c7b5
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr2.mod
@@ -0,0 +1,31 @@
+MODULE testwithptr2 ;
+
+FROM SYSTEM IMPORT ADR ;
+
+TYPE
+ PtrToVec = POINTER TO Vec ;
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+
+(*
+ test -
+*)
+
+PROCEDURE test ;
+VAR
+ p: PtrToVec ;
+ v: Vec ;
+BEGIN
+ p := ADR (v) ;
+ p^ := Vec {1, 2} ;
+ IF p^.y = 2
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testwithptr2.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr3.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr3.mod
new file mode 100644
index 0000000..71ffe1f
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/testwithptr3.mod
@@ -0,0 +1,31 @@
+MODULE testwithptr3 ;
+
+FROM SYSTEM IMPORT ADR ;
+
+TYPE
+ PtrToVec = POINTER TO Vec ;
+ Vec = RECORD
+ x, y: CARDINAL ;
+ END ;
+
+
+(*
+ test -
+*)
+
+PROCEDURE test ;
+VAR
+ p: PtrToVec ;
+ v: Vec ;
+BEGIN
+ p := ADR (v) ;
+ v := Vec {1, 2} ;
+ IF p^.y = 2
+ THEN
+ END
+END test ;
+
+
+BEGIN
+ test
+END testwithptr3.
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 3568dbb..8bf7e51 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -440,6 +440,10 @@ proc jit-check-debug-info { obj_file cmds match } {
send $cmd
}
expect {
+ -re "Dwarf Error: wrong version in compilation unit header" {
+ set testcase [testname-for-summary]
+ unsupported "$testcase: gdb does not support dwarf version"
+ }
-re $match { pass OK }
default { fail FAIL }
}
diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c
index 13b3baf..2337b01 100644
--- a/gcc/testsuite/jit.dg/test-expressions.c
+++ b/gcc/testsuite/jit.dg/test-expressions.c
@@ -417,7 +417,7 @@ static void run_test_of_comparison(gcc_jit_context *ctxt,
const char *expected)
{
gcc_jit_type *vec_type =
- gcc_jit_type_get_vector (type, 4);
+ gcc_jit_type_get_vector (type, 2);
CHECK_STRING_VALUE (
make_test_of_comparison (ctxt,
@@ -560,17 +560,17 @@ verify_comparisons (gcc_jit_result *result)
CHECK_VALUE (test_COMPARISON_GE_on_int (1, 2), 0);
CHECK_VALUE (test_COMPARISON_GE_on_int (2, 1), 1);
- typedef int __vector __attribute__ ((__vector_size__ (sizeof(int) * 2)));
- typedef __vector (*test_vec_fn) (__vector, __vector);
+ typedef int v2si __attribute__ ((__vector_size__ (sizeof(int) * 2)));
+ typedef v2si (*test_vec_fn) (v2si, v2si);
- __vector zero_zero = {0, 0};
- __vector zero_one = {0, 1};
- __vector one_zero = {1, 0};
+ v2si zero_zero = {0, 0};
+ v2si zero_one = {0, 1};
+ v2si one_zero = {1, 0};
- __vector true_true = {-1, -1};
- __vector false_true = {0, -1};
- __vector true_false = {-1, 0};
- __vector false_false = {0, 0};
+ v2si true_true = {-1, -1};
+ v2si false_true = {0, -1};
+ v2si true_false = {-1, 0};
+ v2si false_false = {0, 0};
test_vec_fn test_COMPARISON_EQ_on_vec_int =
(test_vec_fn)gcc_jit_result_get_code (result,
@@ -615,7 +615,7 @@ verify_comparisons (gcc_jit_result *result)
CHECK_VECTOR_VALUE (2, test_COMPARISON_GE_on_vec_int (zero_one, one_zero), false_true);
typedef float __vector_f __attribute__ ((__vector_size__ (sizeof(float) * 2)));
- typedef __vector (*test_vec_f_fn) (__vector_f, __vector_f);
+ typedef v2si (*test_vec_f_fn) (__vector_f, __vector_f);
__vector_f zero_zero_f = {0, 0};
__vector_f zero_one_f = {0, 1};
diff --git a/gcc/testsuite/lib/g++-dg.exp b/gcc/testsuite/lib/g++-dg.exp
index 08185a8..046d631 100644
--- a/gcc/testsuite/lib/g++-dg.exp
+++ b/gcc/testsuite/lib/g++-dg.exp
@@ -58,17 +58,17 @@ proc g++-dg-runtest { testcases flags default-extra-flags } {
# single test. This should be updated or commented
# out whenever the default std_list is updated or newer
# C++ effective target is added.
- if [search_for $test "{ dg-do * { target c++23 } }"] {
- set std_list { 23 }
+ if [search_for $test "\{ dg-do * \{ target c++23"] {
+ set std_list { 23 26 }
+ } elseif [search_for $test "\{ dg-do * \{ target c++26"] {
+ set std_list { 26 }
} else {
set std_list { 98 14 17 20 }
}
}
set option_list { }
foreach x $std_list {
- # Handle "concepts" as C++17 plus Concepts TS.
- if { $x eq "concepts" } then { set x "17 -fconcepts"
- } elseif { $x eq "impcx" } then { set x "23 -fimplicit-constexpr" }
+ if { $x eq "impcx" } then { set x "26 -fimplicit-constexpr" }
lappend option_list "${std_prefix}$x"
}
} else {
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index e759f76..db6e5b8 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -285,10 +285,6 @@ proc g++_init { args } {
set gcc_warning_prefix "warning:"
set gcc_error_prefix "(fatal )?error:"
- if { [istarget *-*-darwin*] } {
- lappend ALWAYS_CXXFLAGS "ldflags=-multiply_defined suppress"
- }
-
verbose -log "ALWAYS_CXXFLAGS set to $ALWAYS_CXXFLAGS"
verbose "g++ is initialized" 3
diff --git a/gcc/testsuite/lib/obj-c++.exp b/gcc/testsuite/lib/obj-c++.exp
index 51268fd..98f1e5c 100644
--- a/gcc/testsuite/lib/obj-c++.exp
+++ b/gcc/testsuite/lib/obj-c++.exp
@@ -277,10 +277,6 @@ proc obj-c++_init { args } {
set gcc_warning_prefix "warning:"
set gcc_error_prefix "(fatal )?error:"
- if { [istarget *-*-darwin*] } {
- lappend ALWAYS_OBJCXXFLAGS "ldflags=-multiply_defined suppress"
- }
-
verbose -log "ALWAYS_OBJCXXFLAGS set to $ALWAYS_OBJCXXFLAGS"
verbose "obj-c++ is initialized" 3
diff --git a/gcc/testsuite/lib/options.exp b/gcc/testsuite/lib/options.exp
index 30e6e50..a4b15c1 100644
--- a/gcc/testsuite/lib/options.exp
+++ b/gcc/testsuite/lib/options.exp
@@ -59,7 +59,7 @@ proc check_for_options_with_filter { language gcc_options exclude \
set gcc_output [gcc_target_compile $srcfname $filebase.x executable $gcc_options]
remote_file build delete $srcfname $filebase.x $filebase.gcno
- if {[regexp -- "compiler not installed on this system" $gcc_output]} {
+ if {[regexp -- "compiler not installed on this system|cannot execute" $gcc_output]} {
unsupported "$test: $language compiler not available"
return
}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index d79ad4b..4d04df2 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -10785,7 +10785,35 @@ proc check_effective_target_c++23_only { } {
return 0
}
proc check_effective_target_c++23 { } {
- return [check_effective_target_c++23_only]
+ if [check_effective_target_c++23_only] {
+ return 1
+ }
+ return [check_effective_target_c++26]
+}
+
+proc check_effective_target_c++23_down { } {
+ if ![check_effective_target_c++] {
+ return 0
+ }
+ return [expr ![check_effective_target_c++26] ]
+}
+
+proc check_effective_target_c++26_only { } {
+ global cxx_default
+ if ![check_effective_target_c++] {
+ return 0
+ }
+ if [check-flags { { } { } { -std=c++26 -std=gnu++26 -std=c++2c -std=gnu++2c } }] {
+ return 1
+ }
+ if { $cxx_default == "c++26" && [check-flags { { } { } { } { -std=* } }] } {
+ return 1
+ }
+ return 0
+}
+
+proc check_effective_target_c++26 { } {
+ return [check_effective_target_c++26_only]
}
# Check for C++ Concepts support, i.e. -fconcepts flag.
@@ -12330,7 +12358,7 @@ proc check_effective_target_o_flag_in_section { } {
# return 1 if LRA is supported.
proc check_effective_target_lra { } {
- if { [istarget hppa*-*-*] || [istarget cris-*-*] || [istarget avr-*-*] } {
+ if { [istarget hppa*-*-*] || [istarget avr-*-*] } {
return 0
}
return 1
diff --git a/gcc/testsuite/objc-obj-c++-shared/GNUStep/Foundation/NSObjCRuntime.h b/gcc/testsuite/objc-obj-c++-shared/GNUStep/Foundation/NSObjCRuntime.h
index 189af80..62556f9 100644
--- a/gcc/testsuite/objc-obj-c++-shared/GNUStep/Foundation/NSObjCRuntime.h
+++ b/gcc/testsuite/objc-obj-c++-shared/GNUStep/Foundation/NSObjCRuntime.h
@@ -29,6 +29,9 @@
#ifndef __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE
#define __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE
+/* Allow the elaborated enum use in _GS_NAMED_ENUM. */
+#pragma GCC system_header
+
#ifdef __cplusplus
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
diff --git a/gcc/text-art/box-drawing.cc b/gcc/text-art/box-drawing.cc
index 981d0b0..7d49921 100644
--- a/gcc/text-art/box-drawing.cc
+++ b/gcc/text-art/box-drawing.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "text-art/box-drawing.h"
diff --git a/gcc/text-art/canvas.cc b/gcc/text-art/canvas.cc
index f229612..26ea051 100644
--- a/gcc/text-art/canvas.cc
+++ b/gcc/text-art/canvas.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "pretty-print.h"
diff --git a/gcc/text-art/ruler.cc b/gcc/text-art/ruler.cc
index 80c623f..3323a05 100644
--- a/gcc/text-art/ruler.cc
+++ b/gcc/text-art/ruler.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#define INCLUDE_ALGORITHM
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "pretty-print.h"
diff --git a/gcc/text-art/selftests.cc b/gcc/text-art/selftests.cc
index 60ad003..25d81c1 100644
--- a/gcc/text-art/selftests.cc
+++ b/gcc/text-art/selftests.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "selftest.h"
diff --git a/gcc/text-art/selftests.h b/gcc/text-art/selftests.h
index 706a1d8..ba29f69 100644
--- a/gcc/text-art/selftests.h
+++ b/gcc/text-art/selftests.h
@@ -22,7 +22,9 @@ along with GCC; see the file COPYING3. If not see
#if CHECKING_P
-#include "text-art/types.h"
+namespace text_art {
+ class canvas;
+} // namespace text_art
namespace selftest {
diff --git a/gcc/text-art/style.cc b/gcc/text-art/style.cc
index 00b0563..85ad49e 100644
--- a/gcc/text-art/style.cc
+++ b/gcc/text-art/style.cc
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#define INCLUDE_ALGORITHM
#define INCLUDE_MEMORY
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "make-unique.h"
diff --git a/gcc/text-art/styled-string.cc b/gcc/text-art/styled-string.cc
index cd176b2..a0cc187 100644
--- a/gcc/text-art/styled-string.cc
+++ b/gcc/text-art/styled-string.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#define INCLUDE_MEMORY
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "make-unique.h"
diff --git a/gcc/text-art/table.cc b/gcc/text-art/table.cc
index 42cc422..71a1024 100644
--- a/gcc/text-art/table.cc
+++ b/gcc/text-art/table.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#define INCLUDE_MEMORY
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "make-unique.h"
diff --git a/gcc/text-art/table.h b/gcc/text-art/table.h
index 5e6c8ff..2dc5c3c 100644
--- a/gcc/text-art/table.h
+++ b/gcc/text-art/table.h
@@ -23,7 +23,6 @@ along with GCC; see the file COPYING3. If not see
#include "text-art/canvas.h"
#include "text-art/theme.h"
-#include <vector>
namespace text_art {
diff --git a/gcc/text-art/theme.cc b/gcc/text-art/theme.cc
index 54dfe7c..19c39fa 100644
--- a/gcc/text-art/theme.cc
+++ b/gcc/text-art/theme.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "pretty-print.h"
diff --git a/gcc/text-art/types.h b/gcc/text-art/types.h
index b66188a..ea4ff4b 100644
--- a/gcc/text-art/types.h
+++ b/gcc/text-art/types.h
@@ -21,10 +21,16 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TEXT_ART_TYPES_H
#define GCC_TEXT_ART_TYPES_H
+/* This header uses std::vector, but <vector> can't be directly
+ included due to issues with macros. Hence it must be included from
+ system.h by defining INCLUDE_MEMORY in any source file using it. */
+
+#ifndef INCLUDE_VECTOR
+# error "You must define INCLUDE_VECTOR before including system.h to use text-art/types.h"
+#endif
+
#include "cpplib.h"
#include "pretty-print.h"
-#include <vector>
-#include <string>
namespace text_art {
diff --git a/gcc/text-art/widget.cc b/gcc/text-art/widget.cc
index e6e544d..b64a623 100644
--- a/gcc/text-art/widget.cc
+++ b/gcc/text-art/widget.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#define INCLUDE_MEMORY
+#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "pretty-print.h"
diff --git a/gcc/text-art/widget.h b/gcc/text-art/widget.h
index 9120944..8798e43 100644
--- a/gcc/text-art/widget.h
+++ b/gcc/text-art/widget.h
@@ -21,7 +21,6 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TEXT_ART_WIDGET_H
#define GCC_TEXT_ART_WIDGET_H
-#include <vector>
#include "text-art/canvas.h"
#include "text-art/table.h"
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 30f26af..4989906 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -6658,13 +6658,17 @@ add_phi_args_after_copy (basic_block *region_copy, unsigned n_region,
blocks are stored to REGION_COPY in the same order as they had in REGION,
provided that REGION_COPY is not NULL.
The function returns false if it is unable to copy the region,
- true otherwise. */
+ true otherwise.
+
+ ELIMINATED_EDGE is an edge that is known to be removed in the dupicated
+ region. */
bool
gimple_duplicate_sese_region (edge entry, edge exit,
- basic_block *region, unsigned n_region,
- basic_block *region_copy,
- bool update_dominance)
+ basic_block *region, unsigned n_region,
+ basic_block *region_copy,
+ bool update_dominance,
+ edge eliminated_edge)
{
unsigned i;
bool free_region_copy = false, copying_header = false;
@@ -6743,11 +6747,92 @@ gimple_duplicate_sese_region (edge entry, edge exit,
split_edge_bb_loc (entry), update_dominance);
if (total_count.initialized_p () && entry_count.initialized_p ())
{
- scale_bbs_frequencies_profile_count (region, n_region,
- total_count - entry_count,
- total_count);
- scale_bbs_frequencies_profile_count (region_copy, n_region, entry_count,
- total_count);
+ if (!eliminated_edge)
+ {
+ scale_bbs_frequencies_profile_count (region, n_region,
+ total_count - entry_count,
+ total_count);
+ scale_bbs_frequencies_profile_count (region_copy, n_region,
+ entry_count, total_count);
+ }
+ else
+ {
+ /* We only support only case where eliminated_edge is one and it
+ exists first BB. We also assume that the duplicated region is
+ acyclic. So we expect the following:
+
+ // region_copy_start entry will be scaled to entry_count
+ if (cond1) <- this condition will become false
+ and we update probabilities
+ goto loop_exit;
+ if (cond2)
+ goto loop_exit;
+ goto loop_header <- this will be redirected to loop.
+ // region_copy_end
+ loop:
+ <body>
+ // region start
+ loop_header:
+ if (cond1) <- we need to update probabbility here
+ goto loop_exit;
+ if (cond2) <- and determine scaling factor here.
+ goto loop_exit;
+ else
+ goto loop;
+ // region end
+
+ Adding support for more exits can be done similarly,
+ but only consumer so far is tree-ssa-loop-ch and it uses only this
+ to handle the common case of peeling headers which have
+ conditionals known to be always true upon entry. */
+ gcc_assert (eliminated_edge->src == region[0]
+ && EDGE_COUNT (region[0]->succs) == 2
+ && copying_header);
+
+ edge e, e_copy, eliminated_edge_copy;
+ if (EDGE_SUCC (region[0], 0) == eliminated_edge)
+ {
+ e = EDGE_SUCC (region[0], 1);
+ e_copy = EDGE_SUCC (region_copy[0], 1);
+ eliminated_edge_copy = EDGE_SUCC (region_copy[0], 0);
+ }
+ else
+ {
+ e = EDGE_SUCC (region[0], 0);
+ e_copy = EDGE_SUCC (region_copy[0], 0);
+ eliminated_edge_copy = EDGE_SUCC (region_copy[0], 1);
+ }
+ gcc_checking_assert (e != e_copy
+ && eliminated_edge_copy != eliminated_edge
+ && eliminated_edge_copy->dest
+ == eliminated_edge->dest);
+
+
+ /* Handle first basic block in duplicated region as in the
+ non-eliminating case. */
+ scale_bbs_frequencies_profile_count (region_copy, n_region,
+ entry_count, total_count);
+ /* Now update redirecting eliminated edge to the other edge.
+ Actual CFG update is done by caller. */
+ e_copy->probability = profile_probability::always ();
+ eliminated_edge_copy->probability = profile_probability::never ();
+ /* Header copying is a special case of jump threading, so use
+ common code to update loop body exit condition. */
+ update_bb_profile_for_threading (region[0], e_copy->count (), e);
+ /* If we duplicated more conditionals first scale the profile of
+ rest of the preheader. Then work out the probability of
+ entering the loop and scale rest of the loop. */
+ if (n_region > 1)
+ {
+ scale_bbs_frequencies_profile_count (region_copy + 1,
+ n_region - 1,
+ e_copy->count (),
+ region_copy[1]->count);
+ scale_bbs_frequencies_profile_count (region + 1, n_region - 1,
+ e->count (),
+ region[1]->count);
+ }
+ }
}
if (copying_header)
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 57865c5..b9ccd58 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -70,7 +70,7 @@ extern void add_phi_args_after_copy_bb (basic_block);
extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
extern basic_block split_edge_bb_loc (edge);
extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
- basic_block *, bool);
+ basic_block *, bool, edge);
extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
basic_block *);
extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index c48a12b..668808a 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1713,6 +1713,8 @@ struct GTY(()) tree_type_common {
unsigned typeless_storage : 1;
unsigned empty_flag : 1;
unsigned indivisible_p : 1;
+ /* TYPE_NO_NAMED_ARGS_STDARG_P for a stdarg function.
+ Or TYPE_INCLUDES_FLEXARRAY for RECORD_TYPE and UNION_TYPE. */
unsigned no_named_args_stdarg_p : 1;
unsigned spare : 1;
diff --git a/gcc/tree-nrv.cc b/gcc/tree-nrv.cc
index ff47439..99c4e21 100644
--- a/gcc/tree-nrv.cc
+++ b/gcc/tree-nrv.cc
@@ -264,7 +264,17 @@ pass_nrv::execute (function *fun)
data.modified = 0;
walk_gimple_op (stmt, finalize_nrv_r, &wi);
if (data.modified)
- update_stmt (stmt);
+ {
+ /* If this is a CLOBBER of VAR, remove it. */
+ if (gimple_clobber_p (stmt))
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ continue;
+ }
+ update_stmt (stmt);
+ }
gsi_next (&gsi);
}
}
diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
index 9a936a9..a62af05 100644
--- a/gcc/tree-object-size.cc
+++ b/gcc/tree-object-size.cc
@@ -633,11 +633,32 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
v = NULL_TREE;
break;
case COMPONENT_REF:
- if (TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
+ /* When the ref is not to an aggregate type, i.e, an array,
+ a record or a union, it will not have flexible size,
+ compute the object size directly. */
+ if (!AGGREGATE_TYPE_P (TREE_TYPE (v)))
{
v = NULL_TREE;
break;
}
+ /* if the ref is to a record or union type, but the type
+ does not include a flexible array recursively, compute
+ the object size directly. */
+ if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (v)))
+ {
+ if (!TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (v)))
+ {
+ v = NULL_TREE;
+ break;
+ }
+ else
+ {
+ v = TREE_OPERAND (v, 0);
+ break;
+ }
+ }
+ /* Now the ref is to an array type. */
+ gcc_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
is_flexible_array_mem_ref = array_ref_flexible_size_p (v);
while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index e1bc04b8..f31fd04 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -2815,11 +2815,13 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref, bool tbaa_p)
case IFN_SCATTER_STORE:
case IFN_MASK_SCATTER_STORE:
case IFN_LEN_STORE:
+ case IFN_LEN_MASK_STORE:
return false;
case IFN_MASK_STORE_LANES:
goto process_args;
case IFN_MASK_LOAD:
case IFN_LEN_LOAD:
+ case IFN_LEN_MASK_LOAD:
case IFN_MASK_LOAD_LANES:
{
ao_ref rhs_ref;
@@ -3068,6 +3070,7 @@ call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref, bool tbaa_p)
return false;
case IFN_MASK_STORE:
case IFN_LEN_STORE:
+ case IFN_LEN_MASK_STORE:
case IFN_MASK_STORE_LANES:
{
tree rhs = gimple_call_arg (call,
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 26d5e44..0d0f02a 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -682,6 +682,7 @@ get_value_for_expr (tree expr, bool for_bits_p)
}
if (val.lattice_val == VARYING
+ && INTEGRAL_TYPE_P (TREE_TYPE (expr))
&& TYPE_UNSIGNED (TREE_TYPE (expr)))
val.mask = wi::zext (val.mask, TYPE_PRECISION (TREE_TYPE (expr)));
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 2949957..f0b0245 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -1865,12 +1865,15 @@ make_forwarders_with_degenerate_phis (function *fn)
}
free_dominance_info (fn, CDI_DOMINATORS);
basic_block forwarder = split_edge (args[start].first);
+ profile_count count = profile_count::zero ();
for (unsigned j = start + 1; j < i; ++j)
{
edge e = args[j].first;
redirect_edge_and_branch_force (e, forwarder);
redirect_edge_var_map_clear (e);
+ count += e->count ();
}
+ forwarder->count = count;
if (vphi)
{
tree def = copy_ssa_name (vphi_args[0]);
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index 9f534b5..f7f8b73 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -1338,6 +1338,71 @@ all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
return true;
}
+/* Handle
+ _4 = x_3 & 31;
+ if (_4 != 0)
+ goto <bb 6>;
+ else
+ goto <bb 7>;
+ <bb 6>:
+ __builtin_unreachable ();
+ <bb 7>:
+
+ If x_3 has no other immediate uses (checked by caller), var is the
+ x_3 var, we can clear low 5 bits from the non-zero bitmask. */
+
+static void
+maybe_set_nonzero_bits (edge e, tree var)
+{
+ basic_block cond_bb = e->src;
+ gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
+ tree cst;
+
+ if (cond == NULL
+ || gimple_cond_code (cond) != ((e->flags & EDGE_TRUE_VALUE)
+ ? EQ_EXPR : NE_EXPR)
+ || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
+ || !integer_zerop (gimple_cond_rhs (cond)))
+ return;
+
+ gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
+ if (!is_gimple_assign (stmt)
+ || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
+ || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
+ return;
+ if (gimple_assign_rhs1 (stmt) != var)
+ {
+ gimple *stmt2;
+
+ if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
+ return;
+ stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+ if (!gimple_assign_cast_p (stmt2)
+ || gimple_assign_rhs1 (stmt2) != var
+ || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2))
+ || (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))
+ != TYPE_PRECISION (TREE_TYPE (var))))
+ return;
+ }
+ cst = gimple_assign_rhs2 (stmt);
+ if (POINTER_TYPE_P (TREE_TYPE (var)))
+ {
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (var);
+ if (pi && pi->misalign)
+ return;
+ wide_int w = wi::bit_not (wi::to_wide (cst));
+ unsigned int bits = wi::ctz (w);
+ if (bits == 0 || bits >= HOST_BITS_PER_INT)
+ return;
+ unsigned int align = 1U << bits;
+ if (pi == NULL || pi->align < align)
+ set_ptr_info_alignment (get_ptr_info (var), align, 0);
+ }
+ else
+ set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var),
+ wi::to_wide (cst)));
+}
+
/* Set global ranges that can be determined from the C->M edge:
<bb C>:
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 3c7a2e9..9c6004c 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop-niter.h"
#include "cfgloop.h"
#include "tree-data-ref.h"
+#include "internal-fn.h"
/* This file implements dead store elimination.
@@ -157,23 +158,37 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write, bool may_def_ok = false)
switch (gimple_call_internal_fn (stmt))
{
case IFN_LEN_STORE:
- ao_ref_init_from_ptr_and_size
- (write, gimple_call_arg (stmt, 0),
- int_const_binop (MINUS_EXPR,
- gimple_call_arg (stmt, 2),
- gimple_call_arg (stmt, 4)));
- return true;
case IFN_MASK_STORE:
- /* We cannot initialize a must-def ao_ref (in all cases) but we
- can provide a may-def variant. */
- if (may_def_ok)
- {
- ao_ref_init_from_ptr_and_size
- (write, gimple_call_arg (stmt, 0),
- TYPE_SIZE_UNIT (TREE_TYPE (gimple_call_arg (stmt, 3))));
- return true;
- }
- break;
+ case IFN_LEN_MASK_STORE:
+ {
+ internal_fn ifn = gimple_call_internal_fn (stmt);
+ int stored_value_index = internal_fn_stored_value_index (ifn);
+ int len_index = internal_fn_len_index (ifn);
+ if (ifn == IFN_LEN_STORE)
+ {
+ tree len = gimple_call_arg (stmt, len_index);
+ tree bias = gimple_call_arg (stmt, len_index + 1);
+ if (tree_fits_uhwi_p (len))
+ {
+ ao_ref_init_from_ptr_and_size (write,
+ gimple_call_arg (stmt, 0),
+ int_const_binop (MINUS_EXPR,
+ len, bias));
+ return true;
+ }
+ }
+ /* We cannot initialize a must-def ao_ref (in all cases) but we
+ can provide a may-def variant. */
+ if (may_def_ok)
+ {
+ ao_ref_init_from_ptr_and_size (
+ write, gimple_call_arg (stmt, 0),
+ TYPE_SIZE_UNIT (
+ TREE_TYPE (gimple_call_arg (stmt, stored_value_index))));
+ return true;
+ }
+ break;
+ }
default:;
}
}
@@ -1502,6 +1517,7 @@ dse_optimize_stmt (function *fun, gimple_stmt_iterator *gsi, sbitmap live_bytes)
{
case IFN_LEN_STORE:
case IFN_MASK_STORE:
+ case IFN_LEN_MASK_STORE:
{
enum dse_store_status store_status;
store_status = dse_classify_store (&ref, stmt, false, live_bytes);
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 21a77dd..58e19c1 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -128,7 +128,6 @@ bb_no_side_effects_p (basic_block bb)
gassign *ass;
enum tree_code rhs_code;
if (gimple_has_side_effects (stmt)
- || gimple_uses_undefined_value_p (stmt)
|| gimple_could_trap_p (stmt)
|| gimple_vuse (stmt)
/* We need to rewrite stmts with undefined overflow to use
@@ -153,6 +152,12 @@ bb_no_side_effects_p (basic_block bb)
should handle this. */
|| is_gimple_call (stmt))
return false;
+
+ ssa_op_iter it;
+ tree use;
+ FOR_EACH_SSA_TREE_OPERAND (use, stmt, it, SSA_OP_USE)
+ if (ssa_name_maybe_undef_p (use))
+ return false;
}
return true;
@@ -836,6 +841,7 @@ pass_tree_ifcombine::execute (function *fun)
bbs = single_pred_before_succ_order ();
calculate_dominance_info (CDI_DOMINATORS);
+ mark_ssa_maybe_undefs ();
/* Search every basic block for COND_EXPR we may be able to optimize.
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 22252be..291f2db 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -59,17 +59,18 @@ edge_range_query (irange &r, edge e, gcond *cond, gimple_ranger &ranger)
r.set_varying (boolean_type_node);
}
-/* Return true if the condition on the first iteration of the loop can
- be statically determined. */
+/* Return edge that is true in the first iteration of the loop
+ and NULL otherwise. */
-static bool
-entry_loop_condition_is_static (class loop *l, gimple_ranger *ranger)
+static edge
+static_loop_exit (class loop *l, gimple_ranger *ranger)
{
edge e = loop_preheader_edge (l);
gcond *last = safe_dyn_cast <gcond *> (*gsi_last_bb (e->dest));
+ edge ret_e;
if (!last)
- return false;
+ return NULL;
edge true_e, false_e;
extract_true_false_edges_from_block (e->dest, &true_e, &false_e);
@@ -77,17 +78,23 @@ entry_loop_condition_is_static (class loop *l, gimple_ranger *ranger)
/* If neither edge is the exit edge, this is not a case we'd like to
special-case. */
if (!loop_exit_edge_p (l, true_e) && !loop_exit_edge_p (l, false_e))
- return false;
+ return NULL;
int_range<1> desired_static_range;
if (loop_exit_edge_p (l, true_e))
- desired_static_range = range_false ();
+ {
+ desired_static_range = range_false ();
+ ret_e = true_e;
+ }
else
+ {
desired_static_range = range_true ();
+ ret_e = false_e;
+ }
int_range<2> r;
edge_range_query (r, e, last, *ranger);
- return r == desired_static_range;
+ return r == desired_static_range ? ret_e : NULL;
}
/* Check whether we should duplicate HEADER of LOOP. At most *LIMIT
@@ -394,7 +401,8 @@ ch_base::copy_headers (function *fun)
copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
bbs_size = n_basic_blocks_for_fn (fun);
- auto_vec<loop_p> candidates;
+ struct candidate {class loop *loop; edge static_exit;};
+ auto_vec<struct candidate> candidates;
auto_vec<std::pair<edge, loop_p> > copied;
auto_vec<class loop *> loops_to_unloop;
auto_vec<int> loops_to_unloop_nunroll;
@@ -427,12 +435,14 @@ ch_base::copy_headers (function *fun)
|| !process_loop_p (loop))
continue;
+ edge static_exit = static_loop_exit (loop, ranger);
+
/* Avoid loop header copying when optimizing for size unless we can
determine that the loop condition is static in the first
iteration. */
if (optimize_loop_for_size_p (loop)
&& !loop->force_vectorize
- && !entry_loop_condition_is_static (loop, ranger))
+ && !static_exit)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
@@ -442,13 +452,14 @@ ch_base::copy_headers (function *fun)
}
if (should_duplicate_loop_header_p (header, loop, &remaining_limit))
- candidates.safe_push (loop);
+ candidates.safe_push ({loop, static_exit});
}
/* Do not use ranger after we change the IL and not have updated SSA. */
delete ranger;
- for (auto loop : candidates)
+ for (auto candidate : candidates)
{
+ class loop *loop = candidate.loop;
int initial_limit = param_max_loop_header_insns;
int remaining_limit = initial_limit;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -501,11 +512,17 @@ ch_base::copy_headers (function *fun)
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "Duplicating header of the loop %d up to edge %d->%d,"
- " %i insns.\n",
- loop->num, exit->src->index, exit->dest->index,
- initial_limit - remaining_limit);
+ {
+ fprintf (dump_file,
+ "Duplicating header of the loop %d up to edge %d->%d,"
+ " %i insns.\n",
+ loop->num, exit->src->index, exit->dest->index,
+ initial_limit - remaining_limit);
+ if (candidate.static_exit)
+ fprintf (dump_file,
+ " Will eliminate peeled conditional in bb %d.\n",
+ candidate.static_exit->src->index);
+ }
/* Ensure that the header will have just the latch as a predecessor
inside the loop. */
@@ -519,7 +536,7 @@ ch_base::copy_headers (function *fun)
propagate_threaded_block_debug_into (exit->dest, entry->dest);
if (!gimple_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs,
- true))
+ true, candidate.static_exit))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Duplication failed.\n");
diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 86ce6ac..f5b01e9 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -617,7 +617,8 @@ stmt_cost (gimple *stmt)
if (gimple_code (stmt) != GIMPLE_ASSIGN)
return 1;
- switch (gimple_assign_rhs_code (stmt))
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ switch (code)
{
case MULT_EXPR:
case WIDEN_MULT_EXPR:
@@ -645,6 +646,11 @@ stmt_cost (gimple *stmt)
/* Shifts and rotates are usually expensive. */
return LIM_EXPENSIVE;
+ case COND_EXPR:
+ case VEC_COND_EXPR:
+ /* Conditionals are expensive. */
+ return LIM_EXPENSIVE;
+
case CONSTRUCTOR:
/* Make vector construction cost proportional to the number
of elements. */
@@ -658,6 +664,9 @@ stmt_cost (gimple *stmt)
return 0;
default:
+ /* Comparisons are usually expensive. */
+ if (TREE_CODE_CLASS (code) == tcc_comparison)
+ return LIM_EXPENSIVE;
return 1;
}
}
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 6671ff6..243ce86 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -2442,6 +2442,7 @@ get_mem_type_for_internal_fn (gcall *call, tree *op_p)
case IFN_MASK_LOAD:
case IFN_MASK_LOAD_LANES:
case IFN_LEN_LOAD:
+ case IFN_LEN_MASK_LOAD:
if (op_p == gimple_call_arg_ptr (call, 0))
return TREE_TYPE (gimple_call_lhs (call));
return NULL_TREE;
@@ -2449,9 +2450,16 @@ get_mem_type_for_internal_fn (gcall *call, tree *op_p)
case IFN_MASK_STORE:
case IFN_MASK_STORE_LANES:
case IFN_LEN_STORE:
- if (op_p == gimple_call_arg_ptr (call, 0))
- return TREE_TYPE (gimple_call_arg (call, 3));
- return NULL_TREE;
+ case IFN_LEN_MASK_STORE:
+ {
+ if (op_p == gimple_call_arg_ptr (call, 0))
+ {
+ internal_fn ifn = gimple_call_internal_fn (call);
+ int index = internal_fn_stored_value_index (ifn);
+ return TREE_TYPE (gimple_call_arg (call, index));
+ }
+ return NULL_TREE;
+ }
default:
return NULL_TREE;
@@ -7559,6 +7567,8 @@ get_alias_ptr_type_for_ptr_address (iv_use *use)
case IFN_MASK_STORE_LANES:
case IFN_LEN_LOAD:
case IFN_LEN_STORE:
+ case IFN_LEN_MASK_LOAD:
+ case IFN_LEN_MASK_STORE:
/* The second argument contains the correct alias type. */
gcc_assert (use->op_p = gimple_call_arg_ptr (call, 0));
return TREE_TYPE (gimple_call_arg (call, 1));
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index da01d4a..68fc518 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -4861,11 +4861,14 @@ match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
gsi_remove (&gsi2, true);
/* Replace the re2 statement with __real__ of the newly added
.UADDC/.USUBC call. */
- gsi2 = gsi_for_stmt (re2);
- tree rlhs = gimple_assign_lhs (re2);
- g = gimple_build_assign (rlhs, REALPART_EXPR,
- build1 (REALPART_EXPR, TREE_TYPE (rlhs), nlhs));
- gsi_replace (&gsi2, g, true);
+ if (re2)
+ {
+ gsi2 = gsi_for_stmt (re2);
+ tree rlhs = gimple_assign_lhs (re2);
+ g = gimple_build_assign (rlhs, REALPART_EXPR,
+ build1 (REALPART_EXPR, TREE_TYPE (rlhs), nlhs));
+ gsi_replace (&gsi2, g, true);
+ }
if (rhs[2])
{
/* If this is the arg1 + arg2 + (ovf1 + ovf2) or
@@ -4995,8 +4998,8 @@ divmod_candidate_p (gassign *stmt)
if (integer_pow2p (op2))
return false;
- if (TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT
- && TYPE_PRECISION (type) <= BITS_PER_WORD)
+ if (element_precision (type) <= HOST_BITS_PER_WIDE_INT
+ && element_precision (type) <= BITS_PER_WORD)
return false;
/* If the divisor is not power of 2 and the precision wider than
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 2fb28b4..467c9fd 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -630,8 +630,11 @@ empty_bb_or_one_feeding_into_p (basic_block bb,
|| gimple_has_side_effects (stmt_to_move))
return false;
- if (gimple_uses_undefined_value_p (stmt_to_move))
- return false;
+ ssa_op_iter it;
+ tree use;
+ FOR_EACH_SSA_TREE_OPERAND (use, stmt_to_move, it, SSA_OP_USE)
+ if (ssa_name_maybe_undef_p (use))
+ return false;
/* Allow assignments but allow some builtin/internal calls.
As const calls don't match any of the above, yet they could
@@ -782,6 +785,13 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
arg_false = arg0;
}
+ /* Do not make conditional undefs unconditional. */
+ if ((TREE_CODE (arg_true) == SSA_NAME
+ && ssa_name_maybe_undef_p (arg_true))
+ || (TREE_CODE (arg_false) == SSA_NAME
+ && ssa_name_maybe_undef_p (arg_false)))
+ return false;
+
tree type = TREE_TYPE (gimple_phi_result (phi));
result = gimple_simplify_phiopt (early_p, type, stmt,
arg_true, arg_false,
@@ -3967,6 +3977,7 @@ pass_phiopt::execute (function *)
bool cfgchanged = false;
calculate_dominance_info (CDI_DOMINATORS);
+ mark_ssa_maybe_undefs ();
/* Search every basic block for COND_EXPR we may be able to optimize.
diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc
index 8c9ce90..b01ef44 100644
--- a/gcc/tree-ssa-phiprop.cc
+++ b/gcc/tree-ssa-phiprop.cc
@@ -340,6 +340,9 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn,
gimple *def_stmt;
tree vuse;
+ if (!dom_info_available_p (cfun, CDI_POST_DOMINATORS))
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+
/* Only replace loads in blocks that post-dominate the PHI node. That
makes sure we don't end up speculating loads. */
if (!dominated_by_p (CDI_POST_DOMINATORS,
@@ -485,7 +488,7 @@ const pass_data pass_data_phiprop =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_update_ssa, /* todo_flags_finish */
+ 0, /* todo_flags_finish */
};
class pass_phiprop : public gimple_opt_pass
@@ -513,7 +516,6 @@ pass_phiprop::execute (function *fun)
size_t n;
calculate_dominance_info (CDI_DOMINATORS);
- calculate_dominance_info (CDI_POST_DOMINATORS);
n = num_ssa_names;
phivn = XCNEWVEC (struct phiprop_d, n);
@@ -539,7 +541,7 @@ pass_phiprop::execute (function *fun)
free_dominance_info (CDI_POST_DOMINATORS);
- return 0;
+ return did_something ? TODO_update_ssa_only_virtuals : 0;
}
} // anon namespace
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 96c88ec..eda03bf 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -5471,37 +5471,62 @@ get_reassociation_width (int ops_num, enum tree_code opc,
return width;
}
+#define SPECIAL_BIASED_END_STMT 0 /* It is the end stmt of all ops. */
+#define BIASED_END_STMT 1 /* It is the end stmt of normal or biased ops. */
+#define NORMAL_END_STMT 2 /* It is the end stmt of normal ops. */
+
/* Rewrite statements with dependency chain with regard the chance to generate
FMA.
For the chain with FMA: Try to keep fma opportunity as much as possible.
For the chain without FMA: Putting the computation in rank order and trying
to allow operations to be executed in parallel.
E.g.
- e + f + g + a * b + c * d;
+ e + f + a * b + c * d;
- ssa1 = e + f;
- ssa2 = g + a * b;
- ssa3 = ssa1 + c * d;
- ssa4 = ssa2 + ssa3;
+ ssa1 = e + a * b;
+ ssa2 = f + c * d;
+ ssa3 = ssa1 + ssa2;
This reassociation approach preserves the chance of fma generation as much
- as possible. */
+ as possible.
+
+ Another thing is to avoid adding loop-carried ops to long chains, otherwise
+ the whole chain will have dependencies across the loop iteration. Just keep
+ loop-carried ops in a separate chain.
+ E.g.
+ x_1 = phi (x_0, x_2)
+ y_1 = phi (y_0, y_2)
+
+ a + b + c + d + e + x1 + y1
+
+ SSA1 = a + b;
+ SSA2 = c + d;
+ SSA3 = SSA1 + e;
+ SSA4 = SSA3 + SSA2;
+ SSA5 = x1 + y1;
+ SSA6 = SSA4 + SSA5;
+ */
static void
rewrite_expr_tree_parallel (gassign *stmt, int width, bool has_fma,
- const vec<operand_entry *> &ops)
+ const vec<operand_entry *> &ops)
{
enum tree_code opcode = gimple_assign_rhs_code (stmt);
int op_num = ops.length ();
+ int op_normal_num = op_num;
gcc_assert (op_num > 0);
int stmt_num = op_num - 1;
gimple **stmts = XALLOCAVEC (gimple *, stmt_num);
- int op_index = op_num - 1;
- int width_count = width;
int i = 0, j = 0;
tree tmp_op[2], op1;
operand_entry *oe;
gimple *stmt1 = NULL;
tree last_rhs1 = gimple_assign_rhs1 (stmt);
+ int last_rhs1_stmt_index = 0, last_rhs2_stmt_index = 0;
+ int width_active = 0, width_count = 0;
+ bool has_biased = false, ops_changed = false;
+ auto_vec<operand_entry *> ops_normal;
+ auto_vec<operand_entry *> ops_biased;
+ vec<operand_entry *> *ops1;
/* We start expression rewriting from the top statements.
So, in this loop we create a full list of statements
@@ -5510,83 +5535,160 @@ rewrite_expr_tree_parallel (gassign *stmt, int width, bool has_fma,
for (i = stmt_num - 2; i >= 0; i--)
stmts[i] = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmts[i+1]));
- /* Width should not be larger than op_num / 2, since we can not create
+ /* Avoid adding loop-carried ops to long chains, first filter out the
+ loop-carried. But we need to make sure that the length of the remainder
+ is not less than 4, which is the smallest ops length we can break the
+ dependency. */
+ FOR_EACH_VEC_ELT (ops, i, oe)
+ {
+ if (TREE_CODE (oe->op) == SSA_NAME
+ && bitmap_bit_p (biased_names, SSA_NAME_VERSION (oe->op))
+ && op_normal_num > 4)
+ {
+ ops_biased.safe_push (oe);
+ has_biased = true;
+ op_normal_num --;
+ }
+ else
+ ops_normal.safe_push (oe);
+ }
+
+ /* Width should not be larger than ops length / 2, since we can not create
more parallel dependency chains that exceeds such value. */
- width = width <= op_num / 2 ? width : op_num / 2;
+ int width_normal = op_normal_num / 2;
+ int width_biased = (op_num - op_normal_num) / 2;
+ width_normal = width <= width_normal ? width : width_normal;
+ width_biased = width <= width_biased ? width : width_biased;
+
+ ops1 = &ops_normal;
+ width_count = width_active = width_normal;
/* Build parallel dependency chain according to width. */
- for (i = 0; i < width; i++)
+ for (i = 0; i < stmt_num; i++)
{
- /* If the chain has FAM, we do not swap two operands. */
- if (op_index > 1 && !has_fma)
- swap_ops_for_binary_stmt (ops, op_index - 2);
-
- for (j = 0; j < 2; j++)
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- gcc_assert (op_index >= 0);
- oe = ops[op_index--];
- tmp_op[j] = oe->op;
- /* If the stmt that defines operand has to be inserted, insert it
- before the use. */
- stmt1 = oe->stmt_to_insert;
- if (stmt1)
- insert_stmt_before_use (stmts[i], stmt1);
- stmt1 = NULL;
+ fprintf (dump_file, "Transforming ");
+ print_gimple_stmt (dump_file, stmts[i], 0);
}
- stmts[i] = build_and_add_sum (TREE_TYPE (last_rhs1),
- tmp_op[1],
- tmp_op[0],
- opcode);
- gimple_set_visited (stmts[i], true);
- if (dump_file && (dump_flags & TDF_DETAILS))
+ /* When the work of normal ops is over, but the loop is not over,
+ continue to do biased ops. */
+ if (width_count == 0 && ops1 == &ops_normal)
{
- fprintf (dump_file, " into ");
- print_gimple_stmt (dump_file, stmts[i], 0);
+ ops1 = &ops_biased;
+ width_count = width_active = width_biased;
+ ops_changed = true;
}
- }
- for (i = width; i < stmt_num; i++)
- {
- /* We keep original statement only for the last one. All others are
- recreated. */
- if ( op_index < 0)
+ /* Swap the operands if no FMA in the chain. */
+ if (ops1->length () > 2 && !has_fma)
+ swap_ops_for_binary_stmt (*ops1, ops1->length () - 3);
+
+ if (i < width_active
+ || (ops_changed && i <= (last_rhs1_stmt_index + width_active)))
{
- if (width_count == 2)
+ for (j = 0; j < 2; j++)
{
-
- /* We keep original statement only for the last one. All
- others are recreated. */
- gimple_assign_set_rhs1 (stmts[i], gimple_assign_lhs (stmts[i-1]));
- gimple_assign_set_rhs2 (stmts[i], gimple_assign_lhs (stmts[i-2]));
- update_stmt (stmts[i]);
+ oe = ops1->pop ();
+ tmp_op[j] = oe->op;
+ /* If the stmt that defines operand has to be inserted, insert it
+ before the use. */
+ stmt1 = oe->stmt_to_insert;
+ if (stmt1)
+ insert_stmt_before_use (stmts[i], stmt1);
+ stmt1 = NULL;
}
- else
- {
+ stmts[i] = build_and_add_sum (TREE_TYPE (last_rhs1),
+ tmp_op[1],
+ tmp_op[0],
+ opcode);
+ gimple_set_visited (stmts[i], true);
- stmts[i] =
- build_and_add_sum (TREE_TYPE (last_rhs1),
- gimple_assign_lhs (stmts[i-width_count]),
- gimple_assign_lhs (stmts[i-width_count+1]),
- opcode);
- gimple_set_visited (stmts[i], true);
- width_count--;
- }
}
else
{
- /* Attach the rest of the ops to the parallel dependency chain. */
- oe = ops[op_index--];
- op1 = oe->op;
- stmt1 = oe->stmt_to_insert;
- if (stmt1)
- insert_stmt_before_use (stmts[i], stmt1);
- stmt1 = NULL;
- stmts[i] = build_and_add_sum (TREE_TYPE (last_rhs1),
- gimple_assign_lhs (stmts[i-width]),
- op1,
- opcode);
- gimple_set_visited (stmts[i], true);
+ /* We keep original statement only for the last one. All others are
+ recreated. */
+ if (!ops1->length ())
+ {
+ /* For biased length equal to 2. */
+ if (width_count == BIASED_END_STMT && !last_rhs2_stmt_index)
+ last_rhs2_stmt_index = i - 1;
+
+ /* When width_count == 2 and there is no biased, just finish. */
+ if (width_count == NORMAL_END_STMT && !has_biased)
+ {
+ last_rhs1_stmt_index = i - 1;
+ last_rhs2_stmt_index = i - 2;
+ }
+ if (last_rhs1_stmt_index && (last_rhs2_stmt_index || !has_biased))
+ {
+ /* We keep original statement only for the last one. All
+ others are recreated. */
+ gimple_assign_set_rhs1 (stmts[i], gimple_assign_lhs
+ (stmts[last_rhs1_stmt_index]));
+ gimple_assign_set_rhs2 (stmts[i], gimple_assign_lhs
+ (stmts[last_rhs2_stmt_index]));
+ update_stmt (stmts[i]);
+ }
+ else
+ {
+ stmts[i] =
+ build_and_add_sum (TREE_TYPE (last_rhs1),
+ gimple_assign_lhs (stmts[i-width_count]),
+ gimple_assign_lhs
+ (stmts[i-width_count+1]),
+ opcode);
+ gimple_set_visited (stmts[i], true);
+ width_count--;
+
+ /* It is the end of normal or biased ops.
+ last_rhs1_stmt_index used to record the last stmt index
+ for normal ops. last_rhs2_stmt_index used to record the
+ last stmt index for biased ops. */
+ if (width_count == BIASED_END_STMT)
+ {
+ gcc_assert (has_biased);
+ if (ops_biased.length ())
+ last_rhs1_stmt_index = i;
+ else
+ last_rhs2_stmt_index = i;
+ width_count--;
+ }
+ }
+ }
+ else
+ {
+ /* Attach the rest ops to the parallel dependency chain. */
+ oe = ops1->pop ();
+ op1 = oe->op;
+ stmt1 = oe->stmt_to_insert;
+ if (stmt1)
+ insert_stmt_before_use (stmts[i], stmt1);
+ stmt1 = NULL;
+
+ /* For only one biased ops. */
+ if (width_count == SPECIAL_BIASED_END_STMT)
+ {
+ /* We keep original statement only for the last one. All
+ others are recreated. */
+ gcc_assert (has_biased);
+ gimple_assign_set_rhs1 (stmts[i], gimple_assign_lhs
+ (stmts[last_rhs1_stmt_index]));
+ gimple_assign_set_rhs2 (stmts[i], op1);
+ update_stmt (stmts[i]);
+ }
+ else
+ {
+ stmts[i] = build_and_add_sum (TREE_TYPE (last_rhs1),
+ gimple_assign_lhs
+ (stmts[i-width_active]),
+ op1,
+ opcode);
+ gimple_set_visited (stmts[i], true);
+ }
+ }
}
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -5595,6 +5697,7 @@ rewrite_expr_tree_parallel (gassign *stmt, int width, bool has_fma,
print_gimple_stmt (dump_file, stmts[i], 0);
}
}
+
remove_visited_stmt_chain (last_rhs1);
}
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 27c84e78..11061a3 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -3346,17 +3346,17 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype)));
if (mask)
{
- HOST_WIDE_INT start = 0, len = 0;
+ HOST_WIDE_INT start = 0, length = 0;
unsigned mask_idx = 0;
do
{
if (integer_zerop (VECTOR_CST_ELT (mask, mask_idx)))
{
- if (len != 0)
+ if (length != 0)
{
pd.rhs_off = start;
pd.offset = offset2i + start;
- pd.size = len;
+ pd.size = length;
if (ranges_known_overlap_p
(offset, maxsize, pd.offset, pd.size))
{
@@ -3367,18 +3367,18 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
}
}
start = (mask_idx + 1) * elsz;
- len = 0;
+ length = 0;
}
else
- len += elsz;
+ length += elsz;
mask_idx++;
}
while (known_lt (mask_idx, TYPE_VECTOR_SUBPARTS (vectype)));
- if (len != 0)
+ if (length != 0)
{
pd.rhs_off = start;
pd.offset = offset2i + start;
- pd.size = len;
+ pd.size = length;
if (ranges_known_overlap_p (offset, maxsize,
pd.offset, pd.size))
return data->push_partial_def (pd, set, set,
diff --git a/gcc/tree-ssa-scopedtables.cc b/gcc/tree-ssa-scopedtables.cc
index 528ddf2..e698ef9 100644
--- a/gcc/tree-ssa-scopedtables.cc
+++ b/gcc/tree-ssa-scopedtables.cc
@@ -574,7 +574,7 @@ hashable_expr_equal_p (const struct hashable_expr *expr0,
&& (TREE_CODE (type0) == ERROR_MARK
|| TREE_CODE (type1) == ERROR_MARK
|| TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)
- || TYPE_PRECISION (type0) != TYPE_PRECISION (type1)
+ || element_precision (type0) != element_precision (type1)
|| TYPE_MODE (type0) != TYPE_MODE (type1)))
return false;
diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index 607b37e..ebba02b 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -1377,23 +1377,6 @@ ssa_undefined_value_p (tree t, bool partial)
}
-/* Return TRUE iff STMT, a gimple statement, references an undefined
- SSA name. */
-
-bool
-gimple_uses_undefined_value_p (gimple *stmt)
-{
- ssa_op_iter iter;
- tree op;
-
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
- if (ssa_undefined_value_p (op))
- return true;
-
- return false;
-}
-
-
/* Return TRUE iff there are any non-PHI uses of VAR that dominate the
end of BB. If we return TRUE and BB is a loop header, then VAR we
be assumed to be defined within the loop, even if it is marked as
diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h
index fa8c808..18c279f 100644
--- a/gcc/tree-ssa.h
+++ b/gcc/tree-ssa.h
@@ -54,7 +54,6 @@ extern tree find_released_ssa_name (tree *, int *, void *);
extern bool ssa_defined_default_def_p (tree t);
extern bool ssa_undefined_value_p (tree, bool = true);
-extern bool gimple_uses_undefined_value_p (gimple *);
bool ssa_name_any_use_dominates_bb_p (tree var, basic_block bb);
diff --git a/gcc/tree-streamer-in.cc b/gcc/tree-streamer-in.cc
index c803800..5bead0c 100644
--- a/gcc/tree-streamer-in.cc
+++ b/gcc/tree-streamer-in.cc
@@ -386,8 +386,11 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
if (AGGREGATE_TYPE_P (expr))
TYPE_TYPELESS_STORAGE (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_EMPTY_P (expr) = (unsigned) bp_unpack_value (bp, 1);
- TYPE_NO_NAMED_ARGS_STDARG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
- TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp);
+ if (FUNC_OR_METHOD_TYPE_P (expr))
+ TYPE_NO_NAMED_ARGS_STDARG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ if (RECORD_OR_UNION_TYPE_P (expr))
+ TYPE_INCLUDES_FLEXARRAY (expr) = (unsigned) bp_unpack_value (bp, 1);
+ TYPE_PRECISION_RAW (expr) = bp_unpack_var_len_unsigned (bp);
SET_TYPE_ALIGN (expr, bp_unpack_var_len_unsigned (bp));
#ifdef ACCEL_COMPILER
if (TYPE_ALIGN (expr) > targetm.absolute_biggest_alignment)
diff --git a/gcc/tree-streamer-out.cc b/gcc/tree-streamer-out.cc
index 5751f77..ff9694e 100644
--- a/gcc/tree-streamer-out.cc
+++ b/gcc/tree-streamer-out.cc
@@ -355,8 +355,11 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
if (AGGREGATE_TYPE_P (expr))
bp_pack_value (bp, TYPE_TYPELESS_STORAGE (expr), 1);
bp_pack_value (bp, TYPE_EMPTY_P (expr), 1);
- bp_pack_value (bp, TYPE_NO_NAMED_ARGS_STDARG_P (expr), 1);
- bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
+ if (FUNC_OR_METHOD_TYPE_P (expr))
+ bp_pack_value (bp, TYPE_NO_NAMED_ARGS_STDARG_P (expr), 1);
+ if (RECORD_OR_UNION_TYPE_P (expr))
+ bp_pack_value (bp, TYPE_INCLUDES_FLEXARRAY (expr), 1);
+ bp_pack_var_len_unsigned (bp, TYPE_PRECISION_RAW (expr));
bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
}
diff --git a/gcc/tree-streamer.cc b/gcc/tree-streamer.cc
index ed65a76..a28ef9c 100644
--- a/gcc/tree-streamer.cc
+++ b/gcc/tree-streamer.cc
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see
During streaming in, we translate the on the disk mode using this
table. For normal LTO it is set to identity, for ACCEL_COMPILER
depending on the mode_table content. */
-unsigned char streamer_mode_table[1 << 8];
+unsigned char streamer_mode_table[MAX_MACHINE_MODE];
/* Check that all the TS_* structures handled by the streamer_write_* and
streamer_read_* routines are exactly ALL the structures defined in
diff --git a/gcc/tree-streamer.h b/gcc/tree-streamer.h
index 170d61c..ff49d1b 100644
--- a/gcc/tree-streamer.h
+++ b/gcc/tree-streamer.h
@@ -75,7 +75,7 @@ void streamer_write_tree_body (struct output_block *, tree);
void streamer_write_integer_cst (struct output_block *, tree);
/* In tree-streamer.cc. */
-extern unsigned char streamer_mode_table[1 << 8];
+extern unsigned char streamer_mode_table[MAX_MACHINE_MODE];
void streamer_check_handled_ts_structures (void);
bool streamer_tree_cache_insert (struct streamer_tree_cache_d *, tree,
hashval_t, unsigned *);
@@ -108,15 +108,17 @@ inline void
bp_pack_machine_mode (struct bitpack_d *bp, machine_mode mode)
{
streamer_mode_table[mode] = 1;
- bp_pack_enum (bp, machine_mode, 1 << 8, mode);
+ int last = 1 << ceil_log2 (MAX_MACHINE_MODE);
+ bp_pack_enum (bp, machine_mode, last, mode);
}
inline machine_mode
bp_unpack_machine_mode (struct bitpack_d *bp)
{
- return (machine_mode)
- ((class lto_input_block *)
- bp->stream)->mode_table[bp_unpack_enum (bp, machine_mode, 1 << 8)];
+ lto_input_block *ib = (class lto_input_block *) bp->stream;
+ int last = 1 << ib->file_data->mode_bits;
+ unsigned ix = bp_unpack_enum (bp, machine_mode, last);
+ return (machine_mode) ib->file_data->mode_table[ix];
}
#endif /* GCC_TREE_STREAMER_H */
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 20f570e..6c452e0 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -2882,34 +2882,6 @@ slpeel_update_phi_nodes_for_lcssa (class loop *epilog)
rename_use_op (PHI_ARG_DEF_PTR_FROM_EDGE (gsi.phi (), e));
}
-/* EPILOGUE_VINFO is an epilogue loop that we now know would need to
- iterate exactly CONST_NITERS times. Make a final decision about
- whether the epilogue loop should be used, returning true if so. */
-
-static bool
-vect_update_epilogue_niters (loop_vec_info epilogue_vinfo,
- unsigned HOST_WIDE_INT const_niters)
-{
- /* Avoid wrap-around when computing const_niters - 1. Also reject
- using an epilogue loop for a single scalar iteration, even if
- we could in principle implement that using partial vectors. */
- unsigned int gap_niters = LOOP_VINFO_PEELING_FOR_GAPS (epilogue_vinfo);
- if (const_niters <= gap_niters + 1)
- return false;
-
- /* Install the number of iterations. */
- tree niters_type = TREE_TYPE (LOOP_VINFO_NITERS (epilogue_vinfo));
- tree niters_tree = build_int_cst (niters_type, const_niters);
- tree nitersm1_tree = build_int_cst (niters_type, const_niters - 1);
-
- LOOP_VINFO_NITERS (epilogue_vinfo) = niters_tree;
- LOOP_VINFO_NITERSM1 (epilogue_vinfo) = nitersm1_tree;
-
- /* Decide what to do if the number of epilogue iterations is not
- a multiple of the epilogue loop's vectorization factor. */
- return vect_determine_partial_vectors_and_peeling (epilogue_vinfo, true);
-}
-
/* LOOP_VINFO is an epilogue loop whose corresponding main loop can be skipped.
Return a value that equals:
@@ -3039,7 +3011,6 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
int estimated_vf;
int prolog_peeling = 0;
bool vect_epilogues = loop_vinfo->epilogue_vinfos.length () > 0;
- bool vect_epilogues_updated_niters = false;
/* We currently do not support prolog peeling if the target alignment is not
known at compile time. 'vect_gen_prolog_loop_niters' depends on the
target alignment being constant. */
@@ -3167,36 +3138,6 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
tree before_loop_niters = LOOP_VINFO_NITERS (loop_vinfo);
edge update_e = NULL, skip_e = NULL;
unsigned int lowest_vf = constant_lower_bound (vf);
- /* If we know the number of scalar iterations for the main loop we should
- check whether after the main loop there are enough iterations left over
- for the epilogue. */
- if (vect_epilogues
- && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
- && prolog_peeling >= 0
- && known_eq (vf, lowest_vf))
- {
- unsigned HOST_WIDE_INT eiters
- = (LOOP_VINFO_INT_NITERS (loop_vinfo)
- - LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo));
-
- eiters -= prolog_peeling;
- eiters
- = eiters % lowest_vf + LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo);
-
- while (!vect_update_epilogue_niters (epilogue_vinfo, eiters))
- {
- delete epilogue_vinfo;
- epilogue_vinfo = NULL;
- if (loop_vinfo->epilogue_vinfos.length () == 0)
- {
- vect_epilogues = false;
- break;
- }
- epilogue_vinfo = loop_vinfo->epilogue_vinfos[0];
- loop_vinfo->epilogue_vinfos.ordered_remove (0);
- }
- vect_epilogues_updated_niters = true;
- }
/* Prolog loop may be skipped. */
bool skip_prolog = (prolog_peeling != 0);
/* Skip this loop to epilog when there are not enough iterations to enter this
@@ -3473,9 +3414,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
skip_e edge. */
if (skip_vector)
{
- gcc_assert (update_e != NULL
- && skip_e != NULL
- && !vect_epilogues_updated_niters);
+ gcc_assert (update_e != NULL && skip_e != NULL);
gphi *new_phi = create_phi_node (make_ssa_name (TREE_TYPE (niters)),
update_e->dest);
tree new_ssa = make_ssa_name (TREE_TYPE (niters));
@@ -3506,28 +3445,25 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
loop and its prologue. */
*advance = niters;
- if (!vect_epilogues_updated_niters)
- {
- /* Subtract the number of iterations performed by the vectorized loop
- from the number of total iterations. */
- tree epilogue_niters = fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
- before_loop_niters,
- niters);
-
- LOOP_VINFO_NITERS (epilogue_vinfo) = epilogue_niters;
- LOOP_VINFO_NITERSM1 (epilogue_vinfo)
- = fold_build2 (MINUS_EXPR, TREE_TYPE (epilogue_niters),
- epilogue_niters,
- build_one_cst (TREE_TYPE (epilogue_niters)));
-
- /* Decide what to do if the number of epilogue iterations is not
- a multiple of the epilogue loop's vectorization factor.
- We should have rejected the loop during the analysis phase
- if this fails. */
- if (!vect_determine_partial_vectors_and_peeling (epilogue_vinfo,
- true))
- gcc_unreachable ();
- }
+ /* Subtract the number of iterations performed by the vectorized loop
+ from the number of total iterations. */
+ tree epilogue_niters = fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
+ before_loop_niters,
+ niters);
+
+ LOOP_VINFO_NITERS (epilogue_vinfo) = epilogue_niters;
+ LOOP_VINFO_NITERSM1 (epilogue_vinfo)
+ = fold_build2 (MINUS_EXPR, TREE_TYPE (epilogue_niters),
+ epilogue_niters,
+ build_one_cst (TREE_TYPE (epilogue_niters)));
+
+ /* Decide what to do if the number of epilogue iterations is not
+ a multiple of the epilogue loop's vectorization factor.
+ We should have rejected the loop during the analysis phase
+ if this fails. */
+ bool res = vect_determine_partial_vectors_and_peeling (epilogue_vinfo,
+ true);
+ gcc_assert (res);
}
adjust_vec.release ();
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 0a03f56..3b46c58 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -2144,14 +2144,69 @@ vect_analyze_loop_costing (loop_vec_info loop_vinfo,
/* Only loops that can handle partially-populated vectors can have iteration
counts less than the vectorization factor. */
- if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo))
+ if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
+ && vect_known_niters_smaller_than_vf (loop_vinfo))
{
- if (vect_known_niters_smaller_than_vf (loop_vinfo))
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: iteration count smaller than "
+ "vectorization factor.\n");
+ return 0;
+ }
+
+ /* If we know the number of iterations we can do better, for the
+ epilogue we can also decide whether the main loop leaves us
+ with enough iterations, prefering a smaller vector epilog then
+ also possibly used for the case we skip the vector loop. */
+ if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
+ && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
+ {
+ widest_int scalar_niters
+ = wi::to_widest (LOOP_VINFO_NITERSM1 (loop_vinfo)) + 1;
+ if (LOOP_VINFO_EPILOGUE_P (loop_vinfo))
+ {
+ loop_vec_info orig_loop_vinfo
+ = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo);
+ unsigned lowest_vf
+ = constant_lower_bound (LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo));
+ int prolog_peeling = 0;
+ if (!vect_use_loop_mask_for_alignment_p (loop_vinfo))
+ prolog_peeling = LOOP_VINFO_PEELING_FOR_ALIGNMENT (orig_loop_vinfo);
+ if (prolog_peeling >= 0
+ && known_eq (LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo),
+ lowest_vf))
+ {
+ unsigned gap
+ = LOOP_VINFO_PEELING_FOR_GAPS (orig_loop_vinfo) ? 1 : 0;
+ scalar_niters = ((scalar_niters - gap - prolog_peeling)
+ % lowest_vf + gap);
+ }
+ }
+
+ /* Check that the loop processes at least one full vector. */
+ poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ if (known_lt (scalar_niters, vf))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "loop does not have enough iterations "
+ "to support vectorization.\n");
+ return 0;
+ }
+
+ /* If we need to peel an extra epilogue iteration to handle data
+ accesses with gaps, check that there are enough scalar iterations
+ available.
+
+ The check above is redundant with this one when peeling for gaps,
+ but the distinction is useful for diagnostics. */
+ if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)
+ && known_le (scalar_niters, vf))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: iteration count smaller than "
- "vectorization factor.\n");
+ "loop does not have enough iterations "
+ "to support peeling for gaps.\n");
return 0;
}
}
@@ -2502,31 +2557,6 @@ vect_determine_partial_vectors_and_peeling (loop_vec_info loop_vinfo,
LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo)));
}
- if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
- && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo))
- {
- /* Check that the loop processes at least one full vector. */
- poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
- tree scalar_niters = LOOP_VINFO_NITERS (loop_vinfo);
- if (known_lt (wi::to_widest (scalar_niters), vf))
- return opt_result::failure_at (vect_location,
- "loop does not have enough iterations"
- " to support vectorization.\n");
-
- /* If we need to peel an extra epilogue iteration to handle data
- accesses with gaps, check that there are enough scalar iterations
- available.
-
- The check above is redundant with this one when peeling for gaps,
- but the distinction is useful for diagnostics. */
- tree scalar_nitersm1 = LOOP_VINFO_NITERSM1 (loop_vinfo);
- if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)
- && known_lt (wi::to_widest (scalar_nitersm1), vf))
- return opt_result::failure_at (vect_location,
- "loop does not have enough iterations"
- " to support peeling for gaps.\n");
- }
-
LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo)
= (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
&& need_peeling_or_partial_vectors_p);
@@ -3002,7 +3032,8 @@ start_over:
assuming that the loop will be used as a main loop. We will redo
this analysis later if we instead decide to use the loop as an
epilogue loop. */
- ok = vect_determine_partial_vectors_and_peeling (loop_vinfo, false);
+ ok = vect_determine_partial_vectors_and_peeling
+ (loop_vinfo, LOOP_VINFO_EPILOGUE_P (loop_vinfo));
if (!ok)
return ok;
@@ -3295,7 +3326,7 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared,
machine_mode vector_mode = vector_modes[mode_i];
loop_vinfo->vector_mode = vector_mode;
unsigned int suggested_unroll_factor = 1;
- bool slp_done_for_suggested_uf;
+ bool slp_done_for_suggested_uf = false;
/* Run the main analysis. */
opt_result res = vect_analyze_loop_2 (loop_vinfo, fatal,
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 60bc9be..de20e9d 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -398,8 +398,11 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op,
vect_unpromoted_value *unprom,
bool *single_use_p = NULL)
{
- tree res = NULL_TREE;
tree op_type = TREE_TYPE (op);
+ if (!INTEGRAL_TYPE_P (op_type))
+ return NULL_TREE;
+
+ tree res = NULL_TREE;
unsigned int orig_precision = TYPE_PRECISION (op_type);
unsigned int min_precision = orig_precision;
stmt_vec_info caster = NULL;
@@ -1404,15 +1407,28 @@ vect_recog_sad_pattern (vec_info *vinfo,
gcall *abd_stmt = dyn_cast <gcall *> (abs_stmt_vinfo->stmt);
if (!abd_stmt
|| !gimple_call_internal_p (abd_stmt)
- || gimple_call_internal_fn (abd_stmt) != IFN_ABD)
+ || gimple_call_num_args (abd_stmt) != 2)
return NULL;
tree abd_oprnd0 = gimple_call_arg (abd_stmt, 0);
tree abd_oprnd1 = gimple_call_arg (abd_stmt, 1);
- if (!vect_look_through_possible_promotion (vinfo, abd_oprnd0, &unprom[0])
- || !vect_look_through_possible_promotion (vinfo, abd_oprnd1,
- &unprom[1]))
+ if (gimple_call_internal_fn (abd_stmt) == IFN_ABD)
+ {
+ if (!vect_look_through_possible_promotion (vinfo, abd_oprnd0,
+ &unprom[0])
+ || !vect_look_through_possible_promotion (vinfo, abd_oprnd1,
+ &unprom[1]))
+ return NULL;
+ }
+ else if (gimple_call_internal_fn (abd_stmt) == IFN_VEC_WIDEN_ABD)
+ {
+ unprom[0].op = abd_oprnd0;
+ unprom[0].type = TREE_TYPE (abd_oprnd0);
+ unprom[1].op = abd_oprnd1;
+ unprom[1].type = TREE_TYPE (abd_oprnd1);
+ }
+ else
return NULL;
half_type = unprom[0].type;
@@ -1442,16 +1458,19 @@ vect_recog_sad_pattern (vec_info *vinfo,
/* Function vect_recog_abd_pattern
- Try to find the following ABsolute Difference (ABD) pattern:
+ Try to find the following ABsolute Difference (ABD) or
+ widening ABD (WIDEN_ABD) pattern:
- VTYPE x, y, out;
- type diff;
- loop i in range:
- S1 diff = x[i] - y[i]
- S2 out[i] = ABS_EXPR <diff>;
+ TYPE1 x;
+ TYPE2 y;
+ TYPE3 x_cast = (TYPE3) x; // widening or no-op
+ TYPE3 y_cast = (TYPE3) y; // widening or no-op
+ TYPE3 diff = x_cast - y_cast;
+ TYPE4 diff_cast = (TYPE4) diff; // widening or no-op
+ TYPE5 abs = ABS(U)_EXPR <diff_cast>;
- where 'type' is a integer and 'VTYPE' is a vector of integers
- the same size as 'type'
+ WIDEN_ABD exists to optimize the case where TYPE4 is at least
+ twice as wide as TYPE3.
Input:
@@ -1459,30 +1478,18 @@ vect_recog_sad_pattern (vec_info *vinfo,
Output:
- * TYPE_out: The type of the output of this pattern
+ * TYPE_OUT: The type of the output of this pattern
* Return value: A new stmt that will be used to replace the sequence of
- stmts that constitute the pattern; either SABD or UABD:
- SABD_EXPR<x, y, out>
- UABD_EXPR<x, y, out>
+ stmts that constitute the pattern, principally:
+ out = IFN_ABD (x, y)
+ out = IFN_WIDEN_ABD (x, y)
*/
static gimple *
vect_recog_abd_pattern (vec_info *vinfo,
stmt_vec_info stmt_vinfo, tree *type_out)
{
- /* Look for the following patterns
- X = x[i]
- Y = y[i]
- DIFF = X - Y
- DAD = ABS_EXPR<DIFF>
- out[i] = DAD
-
- In which
- - X, Y, DIFF, DAD all have the same type
- - x, y, out are all vectors of the same type
- */
-
gassign *last_stmt = dyn_cast <gassign *> (STMT_VINFO_STMT (stmt_vinfo));
if (!last_stmt)
return NULL;
@@ -1496,54 +1503,83 @@ vect_recog_abd_pattern (vec_info *vinfo,
unprom, &diff_stmt))
return NULL;
- tree abd_type = out_type, vectype;
- tree abd_oprnds[2];
- bool extend = false;
+ tree abd_in_type, abd_out_type;
+
if (half_type)
{
- vectype = get_vectype_for_scalar_type (vinfo, half_type);
- abd_type = half_type;
- extend = TYPE_PRECISION (abd_type) < TYPE_PRECISION (out_type);
+ abd_in_type = half_type;
+ abd_out_type = abd_in_type;
}
else
{
unprom[0].op = gimple_assign_rhs1 (diff_stmt);
unprom[1].op = gimple_assign_rhs2 (diff_stmt);
- tree signed_out = signed_type_for (out_type);
- vectype = get_vectype_for_scalar_type (vinfo, signed_out);
+ abd_in_type = signed_type_for (out_type);
+ abd_out_type = abd_in_type;
}
- vect_pattern_detected ("vect_recog_abd_pattern", last_stmt);
+ tree vectype_in = get_vectype_for_scalar_type (vinfo, abd_in_type);
+ if (!vectype_in)
+ return NULL;
- if (!vectype
- || !direct_internal_fn_supported_p (IFN_ABD, vectype,
+ internal_fn ifn = IFN_ABD;
+ tree vectype_out = vectype_in;
+
+ if (TYPE_PRECISION (out_type) >= TYPE_PRECISION (abd_in_type) * 2
+ && stmt_vinfo->min_output_precision >= TYPE_PRECISION (abd_in_type) * 2)
+ {
+ tree mid_type
+ = build_nonstandard_integer_type (TYPE_PRECISION (abd_in_type) * 2,
+ TYPE_UNSIGNED (abd_in_type));
+ tree mid_vectype = get_vectype_for_scalar_type (vinfo, mid_type);
+
+ code_helper dummy_code;
+ int dummy_int;
+ auto_vec<tree> dummy_vec;
+ if (mid_vectype
+ && supportable_widening_operation (vinfo, IFN_VEC_WIDEN_ABD,
+ stmt_vinfo, mid_vectype,
+ vectype_in,
+ &dummy_code, &dummy_code,
+ &dummy_int, &dummy_vec))
+ {
+ ifn = IFN_VEC_WIDEN_ABD;
+ abd_out_type = mid_type;
+ vectype_out = mid_vectype;
+ }
+ }
+
+ if (ifn == IFN_ABD
+ && !direct_internal_fn_supported_p (ifn, vectype_in,
OPTIMIZE_FOR_SPEED))
return NULL;
+ vect_pattern_detected ("vect_recog_abd_pattern", last_stmt);
+
+ tree abd_oprnds[2];
vect_convert_inputs (vinfo, stmt_vinfo, 2, abd_oprnds,
- TREE_TYPE (vectype), unprom, vectype);
+ abd_in_type, unprom, vectype_in);
*type_out = get_vectype_for_scalar_type (vinfo, out_type);
- tree abd_result = vect_recog_temp_ssa_var (abd_type, NULL);
- gcall *abd_stmt = gimple_build_call_internal (IFN_ABD, 2,
+ tree abd_result = vect_recog_temp_ssa_var (abd_out_type, NULL);
+ gcall *abd_stmt = gimple_build_call_internal (ifn, 2,
abd_oprnds[0], abd_oprnds[1]);
gimple_call_set_lhs (abd_stmt, abd_result);
gimple_set_location (abd_stmt, gimple_location (last_stmt));
- if (!extend)
- return abd_stmt;
-
gimple *stmt = abd_stmt;
- if (!TYPE_UNSIGNED (abd_type))
+ if (TYPE_PRECISION (abd_in_type) == TYPE_PRECISION (abd_out_type)
+ && TYPE_PRECISION (abd_out_type) < TYPE_PRECISION (out_type)
+ && !TYPE_UNSIGNED (abd_out_type))
{
- tree unsign = unsigned_type_for (abd_type);
+ tree unsign = unsigned_type_for (abd_out_type);
tree unsign_vectype = get_vectype_for_scalar_type (vinfo, unsign);
stmt = vect_convert_output (vinfo, stmt_vinfo, unsign, stmt,
unsign_vectype);
}
- return vect_convert_output (vinfo, stmt_vinfo, out_type, stmt, vectype);
+ return vect_convert_output (vinfo, stmt_vinfo, out_type, stmt, vectype_out);
}
/* Recognize an operation that performs ORIG_CODE on widened inputs,
@@ -1684,6 +1720,68 @@ vect_recog_widen_minus_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info,
false, "vect_recog_widen_minus_pattern");
}
+/* Try to detect abd on widened inputs, converting IFN_ABD
+ to IFN_VEC_WIDEN_ABD. */
+static gimple *
+vect_recog_widen_abd_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
+ tree *type_out)
+{
+ gassign *last_stmt = dyn_cast <gassign *> (STMT_VINFO_STMT (stmt_vinfo));
+ if (!last_stmt || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (last_stmt)))
+ return NULL;
+
+ tree last_rhs = gimple_assign_rhs1 (last_stmt);
+
+ tree in_type = TREE_TYPE (last_rhs);
+ tree out_type = TREE_TYPE (gimple_assign_lhs (last_stmt));
+ if (!INTEGRAL_TYPE_P (in_type)
+ || !INTEGRAL_TYPE_P (out_type)
+ || TYPE_PRECISION (in_type) * 2 != TYPE_PRECISION (out_type)
+ || !TYPE_UNSIGNED (in_type))
+ return NULL;
+
+ vect_unpromoted_value unprom;
+ tree op = vect_look_through_possible_promotion (vinfo, last_rhs, &unprom);
+ if (!op || TYPE_PRECISION (TREE_TYPE (op)) != TYPE_PRECISION (in_type))
+ return NULL;
+
+ stmt_vec_info abd_pattern_vinfo = vect_get_internal_def (vinfo, op);
+ if (!abd_pattern_vinfo)
+ return NULL;
+
+ abd_pattern_vinfo = vect_stmt_to_vectorize (abd_pattern_vinfo);
+ gcall *abd_stmt = dyn_cast <gcall *> (STMT_VINFO_STMT (abd_pattern_vinfo));
+ if (!abd_stmt
+ || !gimple_call_internal_p (abd_stmt)
+ || gimple_call_internal_fn (abd_stmt) != IFN_ABD)
+ return NULL;
+
+ tree vectype_in = get_vectype_for_scalar_type (vinfo, in_type);
+ tree vectype_out = get_vectype_for_scalar_type (vinfo, out_type);
+
+ code_helper dummy_code;
+ int dummy_int;
+ auto_vec<tree> dummy_vec;
+ if (!supportable_widening_operation (vinfo, IFN_VEC_WIDEN_ABD, stmt_vinfo,
+ vectype_out, vectype_in,
+ &dummy_code, &dummy_code,
+ &dummy_int, &dummy_vec))
+ return NULL;
+
+ vect_pattern_detected ("vect_recog_widen_abd_pattern", last_stmt);
+
+ *type_out = vectype_out;
+
+ tree abd_oprnd0 = gimple_call_arg (abd_stmt, 0);
+ tree abd_oprnd1 = gimple_call_arg (abd_stmt, 1);
+ tree widen_abd_result = vect_recog_temp_ssa_var (out_type, NULL);
+ gcall *widen_abd_stmt = gimple_build_call_internal (IFN_VEC_WIDEN_ABD, 2,
+ abd_oprnd0, abd_oprnd1);
+ gimple_call_set_lhs (widen_abd_stmt, widen_abd_result);
+ gimple_set_location (widen_abd_stmt, gimple_location (last_stmt));
+ return widen_abd_stmt;
+}
+
/* Function vect_recog_ctz_ffs_pattern
Try to find the following pattern:
@@ -3628,8 +3726,8 @@ vect_recog_rotate_pattern (vec_info *vinfo,
return NULL;
if (TREE_CODE (oprnd0) != SSA_NAME
- || TYPE_PRECISION (TREE_TYPE (lhs)) != TYPE_PRECISION (type)
- || !INTEGRAL_TYPE_P (type))
+ || !INTEGRAL_TYPE_P (type)
+ || TYPE_PRECISION (TREE_TYPE (lhs)) != TYPE_PRECISION (type))
return NULL;
stmt_vec_info def_stmt_info;
@@ -3881,6 +3979,7 @@ vect_recog_vector_vector_shift_pattern (vec_info *vinfo,
if (TREE_CODE (oprnd0) != SSA_NAME
|| TREE_CODE (oprnd1) != SSA_NAME
|| TYPE_MODE (TREE_TYPE (oprnd0)) == TYPE_MODE (TREE_TYPE (oprnd1))
+ || !INTEGRAL_TYPE_P (TREE_TYPE (oprnd0))
|| !type_has_mode_precision_p (TREE_TYPE (oprnd1))
|| TYPE_PRECISION (TREE_TYPE (lhs))
!= TYPE_PRECISION (TREE_TYPE (oprnd0)))
@@ -6651,6 +6750,7 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = {
{ vect_recog_mask_conversion_pattern, "mask_conversion" },
{ vect_recog_widen_plus_pattern, "widen_plus" },
{ vect_recog_widen_minus_pattern, "widen_minus" },
+ { vect_recog_widen_abd_pattern, "widen_abd" },
/* These must come after the double widening ones. */
};
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index ab89a82..355d078 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -1286,15 +1286,20 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
{
if (load_p
&& rhs_code != CFN_GATHER_LOAD
- && rhs_code != CFN_MASK_GATHER_LOAD)
+ && rhs_code != CFN_MASK_GATHER_LOAD
+ /* Not grouped loads are handled as externals for BB
+ vectorization. For loop vectorization we can handle
+ splats the same we handle single element interleaving. */
+ && (is_a <bb_vec_info> (vinfo)
+ || stmt_info != first_stmt_info
+ || STMT_VINFO_GATHER_SCATTER_P (stmt_info)))
{
/* Not grouped load. */
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Build SLP failed: not grouped load %G", stmt);
- /* FORNOW: Not grouped loads are not supported. */
- if (is_a <bb_vec_info> (vinfo) && i != 0)
+ if (i != 0)
continue;
/* Fatal mismatch. */
matches[0] = false;
@@ -1302,7 +1307,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
}
/* Not memory operation. */
- if (!phi_p
+ if (!load_p
+ && !phi_p
&& rhs_code.is_tree_code ()
&& TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_binary
&& TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_unary
@@ -1774,7 +1780,7 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
return NULL;
/* If the SLP node is a load, terminate the recursion unless masked. */
- if (STMT_VINFO_GROUPED_ACCESS (stmt_info)
+ if (STMT_VINFO_DATA_REF (stmt_info)
&& DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
{
if (gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt))
@@ -1798,8 +1804,12 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
= DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (node)[0]);
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info)
{
- int load_place = vect_get_place_in_interleaving_chain
- (load_info, first_stmt_info);
+ int load_place;
+ if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
+ load_place = vect_get_place_in_interleaving_chain
+ (load_info, first_stmt_info);
+ else
+ load_place = 0;
gcc_assert (load_place != -1);
load_permutation.safe_push (load_place);
}
@@ -4673,14 +4683,28 @@ vect_optimize_slp_pass::start_choosing_layouts ()
m_partition_layout_costs.safe_grow_cleared (m_partitions.length ()
* m_perms.length ());
- /* We have to mark outgoing permutations facing non-reduction graph
- entries that are not represented as to be materialized. */
+ /* We have to mark outgoing permutations facing non-associating-reduction
+ graph entries that are not represented as to be materialized.
+ slp_inst_kind_bb_reduc currently only covers associatable reductions. */
for (slp_instance instance : m_vinfo->slp_instances)
if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_ctor)
{
unsigned int node_i = SLP_INSTANCE_TREE (instance)->vertex;
m_partitions[m_vertices[node_i].partition].layout = 0;
}
+ else if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_reduc_chain)
+ {
+ stmt_vec_info stmt_info
+ = SLP_TREE_REPRESENTATIVE (SLP_INSTANCE_TREE (instance));
+ stmt_vec_info reduc_info = info_for_reduction (m_vinfo, stmt_info);
+ if (needs_fold_left_reduction_p (TREE_TYPE
+ (gimple_get_lhs (stmt_info->stmt)),
+ STMT_VINFO_REDUC_CODE (reduc_info)))
+ {
+ unsigned int node_i = SLP_INSTANCE_TREE (instance)->vertex;
+ m_partitions[m_vertices[node_i].partition].layout = 0;
+ }
+ }
/* Check which layouts each node and partition can handle. Calculate the
weights associated with inserting layout changes on edges. */
@@ -5425,6 +5449,16 @@ vect_optimize_slp_pass::remove_redundant_permutations ()
this_load_permuted = true;
break;
}
+ /* When this isn't a grouped access we know it's single element
+ and contiguous. */
+ if (!STMT_VINFO_GROUPED_ACCESS (SLP_TREE_SCALAR_STMTS (node)[0]))
+ {
+ if (!this_load_permuted
+ && (known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 1U)
+ || SLP_TREE_LANES (node) == 1))
+ SLP_TREE_LOAD_PERMUTATION (node).release ();
+ continue;
+ }
stmt_vec_info first_stmt_info
= DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (node)[0]);
if (!this_load_permuted
@@ -8115,12 +8149,16 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node,
tree vectype = SLP_TREE_VECTYPE (node);
unsigned int group_size = SLP_TREE_SCALAR_STMTS (node).length ();
unsigned int mask_element;
+ unsigned dr_group_size;
machine_mode mode;
if (!STMT_VINFO_GROUPED_ACCESS (stmt_info))
- return false;
-
- stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
+ dr_group_size = 1;
+ else
+ {
+ stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
+ dr_group_size = DR_GROUP_SIZE (stmt_info);
+ }
mode = TYPE_MODE (vectype);
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
@@ -8161,7 +8199,7 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node,
unsigned int nelts_to_build;
unsigned int nvectors_per_build;
unsigned int in_nlanes;
- bool repeating_p = (group_size == DR_GROUP_SIZE (stmt_info)
+ bool repeating_p = (group_size == dr_group_size
&& multiple_p (nunits, group_size));
if (repeating_p)
{
@@ -8174,7 +8212,7 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node,
it at least one to ensure the later computation for n_perms
proceed. */
nvectors_per_build = nstmts > 0 ? nstmts : 1;
- in_nlanes = DR_GROUP_SIZE (stmt_info) * 3;
+ in_nlanes = dr_group_size * 3;
}
else
{
@@ -8186,7 +8224,7 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node,
mask.new_vector (const_nunits, const_nunits, 1);
nelts_to_build = const_vf * group_size;
nvectors_per_build = 1;
- in_nlanes = const_vf * DR_GROUP_SIZE (stmt_info);
+ in_nlanes = const_vf * dr_group_size;
}
auto_sbitmap used_in_lanes (in_nlanes);
bitmap_clear (used_in_lanes);
@@ -8200,7 +8238,7 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node,
{
unsigned int iter_num = j / group_size;
unsigned int stmt_num = j % group_size;
- unsigned int i = (iter_num * DR_GROUP_SIZE (stmt_info) + perm[stmt_num]);
+ unsigned int i = (iter_num * dr_group_size + perm[stmt_num]);
bitmap_set_bit (used_in_lanes, i);
if (repeating_p)
{
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index ae24f3e..161ad80 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -261,11 +261,26 @@ vect_mark_relevant (vec<stmt_vec_info> *worklist, stmt_vec_info stmt_info,
dump_printf_loc (MSG_NOTE, vect_location,
"last stmt in pattern. don't mark"
" relevant/live.\n");
+
stmt_vec_info old_stmt_info = stmt_info;
stmt_info = STMT_VINFO_RELATED_STMT (stmt_info);
gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == old_stmt_info);
save_relevant = STMT_VINFO_RELEVANT (stmt_info);
save_live_p = STMT_VINFO_LIVE_P (stmt_info);
+
+ if (live_p && relevant == vect_unused_in_scope)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vec_stmt_relevant_p: forcing live pattern stmt "
+ "relevant.\n");
+ relevant = vect_used_only_live;
+ }
+
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "mark relevant %d, live %d: %G", relevant, live_p,
+ stmt_info->stmt);
}
STMT_VINFO_LIVE_P (stmt_info) |= live_p;
@@ -1150,6 +1165,8 @@ vect_model_load_cost (vec_info *vinfo,
/* If the load is permuted then the alignment is determined by
the first group element not by the first scalar stmt DR. */
stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
+ if (!first_stmt_info)
+ first_stmt_info = stmt_info;
/* Record the cost for the permutation. */
unsigned n_perms, n_loads;
vect_transform_slp_perm_load (vinfo, slp_node, vNULL, NULL,
@@ -1819,16 +1836,8 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype,
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
machine_mode mask_mode;
- bool using_partial_vectors_p = false;
- if (targetm.vectorize.get_mask_mode (vecmode).exists (&mask_mode)
- && can_vec_mask_load_store_p (vecmode, mask_mode, is_load))
- {
- nvectors = group_memory_nvectors (group_size * vf, nunits);
- vect_record_loop_mask (loop_vinfo, masks, nvectors, vectype, scalar_mask);
- using_partial_vectors_p = true;
- }
-
machine_mode vmode;
+ bool using_partial_vectors_p = false;
if (get_len_load_store_mode (vecmode, is_load).exists (&vmode))
{
nvectors = group_memory_nvectors (group_size * vf, nunits);
@@ -1837,6 +1846,13 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype,
vect_record_loop_len (loop_vinfo, lens, nvectors, vectype, factor);
using_partial_vectors_p = true;
}
+ else if (targetm.vectorize.get_mask_mode (vecmode).exists (&mask_mode)
+ && can_vec_mask_load_store_p (vecmode, mask_mode, is_load))
+ {
+ nvectors = group_memory_nvectors (group_size * vf, nunits);
+ vect_record_loop_mask (loop_vinfo, masks, nvectors, vectype, scalar_mask);
+ using_partial_vectors_p = true;
+ }
if (!using_partial_vectors_p)
{
@@ -2143,6 +2159,14 @@ vector_vector_composition_type (tree vtype, poly_uint64 nelts, tree *ptype)
if (!VECTOR_MODE_P (vmode))
return NULL_TREE;
+ /* When we are asked to compose the vector from its components let
+ that happen directly. */
+ if (known_eq (TYPE_VECTOR_SUBPARTS (vtype), nelts))
+ {
+ *ptype = TREE_TYPE (vtype);
+ return vtype;
+ }
+
poly_uint64 vbsize = GET_MODE_BITSIZE (vmode);
unsigned int pbsize;
if (constant_multiple_p (vbsize, nelts, &pbsize))
@@ -2196,12 +2220,24 @@ get_group_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info,
{
loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
class loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
- stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
+ stmt_vec_info first_stmt_info;
+ unsigned int group_size;
+ unsigned HOST_WIDE_INT gap;
+ if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
+ {
+ first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
+ group_size = DR_GROUP_SIZE (first_stmt_info);
+ gap = DR_GROUP_GAP (first_stmt_info);
+ }
+ else
+ {
+ first_stmt_info = stmt_info;
+ group_size = 1;
+ gap = 0;
+ }
dr_vec_info *first_dr_info = STMT_VINFO_DR_INFO (first_stmt_info);
- unsigned int group_size = DR_GROUP_SIZE (first_stmt_info);
bool single_element_p = (stmt_info == first_stmt_info
&& !DR_GROUP_NEXT_ELEMENT (stmt_info));
- unsigned HOST_WIDE_INT gap = DR_GROUP_GAP (first_stmt_info);
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
/* True if the vectorized statements would access beyond the last
@@ -2304,11 +2340,16 @@ get_group_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info,
*memory_access_type = VMAT_ELEMENTWISE;
}
}
- else
+ else if (cmp == 0 && loop_vinfo)
{
- gcc_assert (!loop_vinfo || cmp > 0);
- *memory_access_type = VMAT_CONTIGUOUS;
+ gcc_assert (vls_type == VLS_LOAD);
+ *memory_access_type = VMAT_INVARIANT;
+ /* Invariant accesses perform only component accesses, alignment
+ is irrelevant for them. */
+ *alignment_support_scheme = dr_unaligned_supported;
}
+ else
+ *memory_access_type = VMAT_CONTIGUOUS;
/* When we have a contiguous access across loop iterations
but the access in the loop doesn't cover the full vector
@@ -2533,7 +2574,7 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info,
is irrelevant for them. */
*alignment_support_scheme = dr_unaligned_supported;
}
- else if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
+ else if (STMT_VINFO_GROUPED_ACCESS (stmt_info) || slp_node)
{
if (!get_group_load_store_type (vinfo, stmt_info, vectype, slp_node,
masked_p,
@@ -5037,7 +5078,7 @@ vectorizable_conversion (vec_info *vinfo,
gimple **vec_stmt, slp_tree slp_node,
stmt_vector_for_cost *cost_vec)
{
- tree vec_dest;
+ tree vec_dest, cvt_op = NULL_TREE;
tree scalar_dest;
tree op0, op1 = NULL_TREE;
loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
@@ -5256,7 +5297,8 @@ vectorizable_conversion (vec_info *vinfo,
if ((code == FLOAT_EXPR
&& GET_MODE_SIZE (lhs_mode) > GET_MODE_SIZE (rhs_mode))
|| (code == FIX_TRUNC_EXPR
- && GET_MODE_SIZE (rhs_mode) > GET_MODE_SIZE (lhs_mode)))
+ && GET_MODE_SIZE (rhs_mode) > GET_MODE_SIZE (lhs_mode)
+ && !flag_trapping_math))
{
bool float_expr_p = code == FLOAT_EXPR;
scalar_mode imode = float_expr_p ? rhs_mode : lhs_mode;
@@ -5470,8 +5512,9 @@ vectorizable_conversion (vec_info *vinfo,
if (modifier == NONE)
{
STMT_VINFO_TYPE (stmt_info) = type_conversion_vec_info_type;
- vect_model_simple_cost (vinfo, stmt_info, ncopies, dt, ndts, slp_node,
- cost_vec);
+ vect_model_simple_cost (vinfo, stmt_info,
+ ncopies * (1 + multi_step_cvt),
+ dt, ndts, slp_node, cost_vec);
}
else if (modifier == NARROW_SRC || modifier == NARROW_DST)
{
@@ -5561,6 +5604,13 @@ vectorizable_conversion (vec_info *vinfo,
case NONE:
vect_get_vec_defs (vinfo, stmt_info, slp_node, ncopies,
op0, &vec_oprnds0);
+ /* vec_dest is intermediate type operand when multi_step_cvt. */
+ if (multi_step_cvt)
+ {
+ cvt_op = vec_dest;
+ vec_dest = vec_dsts[0];
+ }
+
FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0)
{
/* Arguments are ready, create the new vector stmt. */
@@ -5568,12 +5618,11 @@ vectorizable_conversion (vec_info *vinfo,
if (multi_step_cvt)
{
gcc_assert (multi_step_cvt == 1);
- new_stmt = vect_gimple_build (vec_dest, codecvt1, vop0);
- new_temp = make_ssa_name (vec_dest, new_stmt);
+ new_stmt = vect_gimple_build (cvt_op, codecvt1, vop0);
+ new_temp = make_ssa_name (cvt_op, new_stmt);
gimple_assign_set_lhs (new_stmt, new_temp);
vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
vop0 = new_temp;
- vec_dest = vec_dsts[0];
}
new_stmt = vect_gimple_build (vec_dest, code1, vop0);
new_temp = make_ssa_name (vec_dest, new_stmt);
@@ -5825,12 +5874,15 @@ vectorizable_assignment (vec_info *vinfo,
/* We do not handle bit-precision changes. */
if ((CONVERT_EXPR_CODE_P (code)
|| code == VIEW_CONVERT_EXPR)
- && INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
- && (!type_has_mode_precision_p (TREE_TYPE (scalar_dest))
- || !type_has_mode_precision_p (TREE_TYPE (op)))
+ && ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
+ && !type_has_mode_precision_p (TREE_TYPE (scalar_dest)))
+ || (INTEGRAL_TYPE_P (TREE_TYPE (op))
+ && !type_has_mode_precision_p (TREE_TYPE (op))))
/* But a conversion that does not change the bit-pattern is ok. */
- && !((TYPE_PRECISION (TREE_TYPE (scalar_dest))
- > TYPE_PRECISION (TREE_TYPE (op)))
+ && !(INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
+ && INTEGRAL_TYPE_P (TREE_TYPE (op))
+ && (TYPE_PRECISION (TREE_TYPE (scalar_dest))
+ > TYPE_PRECISION (TREE_TYPE (op)))
&& TYPE_UNSIGNED (TREE_TYPE (op))))
{
if (dump_enabled_p ())
@@ -9006,30 +9058,63 @@ vectorizable_store (vec_info *vinfo,
vec_oprnd = new_temp;
}
- /* Arguments are ready. Create the new vector stmt. */
- if (final_mask)
- {
- tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT);
- gcall *call
- = gimple_build_call_internal (IFN_MASK_STORE, 4,
- dataref_ptr, ptr,
- final_mask, vec_oprnd);
- gimple_call_set_nothrow (call, true);
- vect_finish_stmt_generation (vinfo, stmt_info, call, gsi);
- new_stmt = call;
- }
- else if (loop_lens)
+ /* Compute IFN when LOOP_LENS or final_mask valid. */
+ machine_mode vmode = TYPE_MODE (vectype);
+ machine_mode new_vmode = vmode;
+ internal_fn partial_ifn = IFN_LAST;
+ /* Produce 'len' and 'bias' argument. */
+ tree final_len = NULL_TREE;
+ tree bias = NULL_TREE;
+ if (loop_lens)
{
- machine_mode vmode = TYPE_MODE (vectype);
opt_machine_mode new_ovmode
- = get_len_load_store_mode (vmode, false);
- machine_mode new_vmode = new_ovmode.require ();
+ = get_len_load_store_mode (vmode, false, &partial_ifn);
+ new_vmode = new_ovmode.require ();
unsigned factor
= (new_ovmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vmode);
- tree final_len
- = vect_get_loop_len (loop_vinfo, gsi, loop_lens,
- vec_num * ncopies, vectype,
- vec_num * j + i, factor);
+ final_len = vect_get_loop_len (loop_vinfo, gsi, loop_lens,
+ vec_num * ncopies, vectype,
+ vec_num * j + i, factor);
+ }
+ else if (final_mask)
+ {
+ if (!can_vec_mask_load_store_p (vmode,
+ TYPE_MODE (TREE_TYPE (final_mask)),
+ false, &partial_ifn))
+ gcc_unreachable ();
+ }
+
+ if (partial_ifn == IFN_LEN_MASK_STORE)
+ {
+ if (!final_len)
+ {
+ /* Pass VF value to 'len' argument of
+ LEN_MASK_STORE if LOOP_LENS is invalid. */
+ tree iv_type = LOOP_VINFO_RGROUP_IV_TYPE (loop_vinfo);
+ final_len
+ = build_int_cst (iv_type,
+ TYPE_VECTOR_SUBPARTS (vectype));
+ }
+ if (!final_mask)
+ {
+ /* Pass all ones value to 'mask' argument of
+ LEN_MASK_STORE if final_mask is invalid. */
+ mask_vectype = truth_type_for (vectype);
+ final_mask = build_minus_one_cst (mask_vectype);
+ }
+ }
+ if (final_len)
+ {
+ signed char biasval
+ = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo);
+
+ bias = build_int_cst (intQI_type_node, biasval);
+ }
+
+ /* Arguments are ready. Create the new vector stmt. */
+ if (final_len)
+ {
+ gcall *call;
tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT);
/* Need conversion if it's wrapped with VnQI. */
if (vmode != new_vmode)
@@ -9049,14 +9134,28 @@ vectorizable_store (vec_info *vinfo,
vec_oprnd = var;
}
- signed char biasval =
- LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo);
-
- tree bias = build_int_cst (intQI_type_node, biasval);
+ if (partial_ifn == IFN_LEN_MASK_STORE)
+ call = gimple_build_call_internal (IFN_LEN_MASK_STORE, 6,
+ dataref_ptr, ptr,
+ final_len, bias,
+ final_mask, vec_oprnd);
+ else
+ call
+ = gimple_build_call_internal (IFN_LEN_STORE, 5,
+ dataref_ptr, ptr,
+ final_len, bias,
+ vec_oprnd);
+ gimple_call_set_nothrow (call, true);
+ vect_finish_stmt_generation (vinfo, stmt_info, call, gsi);
+ new_stmt = call;
+ }
+ else if (final_mask)
+ {
+ tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT);
gcall *call
- = gimple_build_call_internal (IFN_LEN_STORE, 5, dataref_ptr,
- ptr, final_len, vec_oprnd,
- bias);
+ = gimple_build_call_internal (IFN_MASK_STORE, 4,
+ dataref_ptr, ptr,
+ final_mask, vec_oprnd);
gimple_call_set_nothrow (call, true);
vect_finish_stmt_generation (vinfo, stmt_info, call, gsi);
new_stmt = call;
@@ -9400,46 +9499,6 @@ vectorizable_load (vec_info *vinfo,
return false;
}
- if (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
- {
- slp_perm = true;
-
- if (!loop_vinfo)
- {
- /* In BB vectorization we may not actually use a loaded vector
- accessing elements in excess of DR_GROUP_SIZE. */
- stmt_vec_info group_info = SLP_TREE_SCALAR_STMTS (slp_node)[0];
- group_info = DR_GROUP_FIRST_ELEMENT (group_info);
- unsigned HOST_WIDE_INT nunits;
- unsigned j, k, maxk = 0;
- FOR_EACH_VEC_ELT (SLP_TREE_LOAD_PERMUTATION (slp_node), j, k)
- if (k > maxk)
- maxk = k;
- tree vectype = SLP_TREE_VECTYPE (slp_node);
- if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant (&nunits)
- || maxk >= (DR_GROUP_SIZE (group_info) & ~(nunits - 1)))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "BB vectorization with gaps at the end of "
- "a load is not supported\n");
- return false;
- }
- }
-
- auto_vec<tree> tem;
- unsigned n_perms;
- if (!vect_transform_slp_perm_load (vinfo, slp_node, tem, NULL, vf,
- true, &n_perms))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION,
- vect_location,
- "unsupported load permutation\n");
- return false;
- }
- }
-
/* Invalidate assumptions made by dependence analysis when vectorization
on the unrolled body effectively re-orders stmts. */
if (!PURE_SLP_STMT (stmt_info)
@@ -9457,6 +9516,46 @@ vectorizable_load (vec_info *vinfo,
else
group_size = 1;
+ if (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
+ {
+ slp_perm = true;
+
+ if (!loop_vinfo)
+ {
+ /* In BB vectorization we may not actually use a loaded vector
+ accessing elements in excess of DR_GROUP_SIZE. */
+ stmt_vec_info group_info = SLP_TREE_SCALAR_STMTS (slp_node)[0];
+ group_info = DR_GROUP_FIRST_ELEMENT (group_info);
+ unsigned HOST_WIDE_INT nunits;
+ unsigned j, k, maxk = 0;
+ FOR_EACH_VEC_ELT (SLP_TREE_LOAD_PERMUTATION (slp_node), j, k)
+ if (k > maxk)
+ maxk = k;
+ tree vectype = SLP_TREE_VECTYPE (slp_node);
+ if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant (&nunits)
+ || maxk >= (DR_GROUP_SIZE (group_info) & ~(nunits - 1)))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "BB vectorization with gaps at the end of "
+ "a load is not supported\n");
+ return false;
+ }
+ }
+
+ auto_vec<tree> tem;
+ unsigned n_perms;
+ if (!vect_transform_slp_perm_load (vinfo, slp_node, tem, NULL, vf,
+ true, &n_perms))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION,
+ vect_location,
+ "unsupported load permutation\n");
+ return false;
+ }
+ }
+
vect_memory_access_type memory_access_type;
enum dr_alignment_support alignment_support_scheme;
int misalignment;
@@ -9585,27 +9684,26 @@ vectorizable_load (vec_info *vinfo,
gimple_set_vuse (new_stmt, vuse);
gsi_insert_on_edge_immediate (pe, new_stmt);
}
- /* These copies are all equivalent, but currently the representation
- requires a separate STMT_VINFO_VEC_STMT for each one. */
- gimple_stmt_iterator gsi2 = *gsi;
- gsi_next (&gsi2);
- for (j = 0; j < ncopies; j++)
+ /* These copies are all equivalent. */
+ if (hoist_p)
+ new_temp = vect_init_vector (vinfo, stmt_info, scalar_dest,
+ vectype, NULL);
+ else
{
- if (hoist_p)
- new_temp = vect_init_vector (vinfo, stmt_info, scalar_dest,
- vectype, NULL);
- else
- new_temp = vect_init_vector (vinfo, stmt_info, scalar_dest,
- vectype, &gsi2);
- gimple *new_stmt = SSA_NAME_DEF_STMT (new_temp);
- if (slp)
- SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
- else
- {
- if (j == 0)
- *vec_stmt = new_stmt;
- STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt);
- }
+ gimple_stmt_iterator gsi2 = *gsi;
+ gsi_next (&gsi2);
+ new_temp = vect_init_vector (vinfo, stmt_info, scalar_dest,
+ vectype, &gsi2);
+ }
+ gimple *new_stmt = SSA_NAME_DEF_STMT (new_temp);
+ if (slp)
+ for (j = 0; j < (int) SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); ++j)
+ SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
+ else
+ {
+ for (j = 0; j < ncopies; ++j)
+ STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt);
+ *vec_stmt = new_stmt;
}
return true;
}
@@ -9835,10 +9933,19 @@ vectorizable_load (vec_info *vinfo,
|| (!slp && memory_access_type == VMAT_CONTIGUOUS))
grouped_load = false;
- if (grouped_load)
+ if (grouped_load
+ || (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()))
{
- first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
- group_size = DR_GROUP_SIZE (first_stmt_info);
+ if (grouped_load)
+ {
+ first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
+ group_size = DR_GROUP_SIZE (first_stmt_info);
+ }
+ else
+ {
+ first_stmt_info = stmt_info;
+ group_size = 1;
+ }
/* For SLP vectorization we directly vectorize a subchain
without permutation. */
if (slp && ! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
@@ -10366,45 +10473,77 @@ vectorizable_load (vec_info *vinfo,
align, misalign);
align = least_bit_hwi (misalign | align);
- if (final_mask)
- {
- tree ptr = build_int_cst (ref_type,
- align * BITS_PER_UNIT);
- gcall *call
- = gimple_build_call_internal (IFN_MASK_LOAD, 3,
- dataref_ptr, ptr,
- final_mask);
- gimple_call_set_nothrow (call, true);
- new_stmt = call;
- data_ref = NULL_TREE;
- }
- else if (loop_lens && memory_access_type != VMAT_INVARIANT)
+ /* Compute IFN when LOOP_LENS or final_mask valid. */
+ machine_mode vmode = TYPE_MODE (vectype);
+ machine_mode new_vmode = vmode;
+ internal_fn partial_ifn = IFN_LAST;
+ /* Produce 'len' and 'bias' argument. */
+ tree final_len = NULL_TREE;
+ tree bias = NULL_TREE;
+ if (loop_lens)
{
- machine_mode vmode = TYPE_MODE (vectype);
opt_machine_mode new_ovmode
- = get_len_load_store_mode (vmode, true);
- machine_mode new_vmode = new_ovmode.require ();
+ = get_len_load_store_mode (vmode, true,
+ &partial_ifn);
+ new_vmode = new_ovmode.require ();
unsigned factor = (new_ovmode == vmode)
? 1
: GET_MODE_UNIT_SIZE (vmode);
- tree final_len
+ final_len
= vect_get_loop_len (loop_vinfo, gsi, loop_lens,
vec_num * ncopies, vectype,
vec_num * j + i, factor);
- tree ptr
- = build_int_cst (ref_type, align * BITS_PER_UNIT);
-
- tree qi_type = unsigned_intQI_type_node;
+ }
+ else if (final_mask)
+ {
+ if (!can_vec_mask_load_store_p (
+ vmode, TYPE_MODE (TREE_TYPE (final_mask)), true,
+ &partial_ifn))
+ gcc_unreachable ();
+ }
- signed char biasval =
- LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo);
+ if (partial_ifn == IFN_LEN_MASK_LOAD)
+ {
+ if (!final_len)
+ {
+ /* Pass VF value to 'len' argument of
+ LEN_MASK_LOAD if LOOP_LENS is invalid. */
+ tree iv_type
+ = LOOP_VINFO_RGROUP_IV_TYPE (loop_vinfo);
+ final_len
+ = build_int_cst (iv_type,
+ TYPE_VECTOR_SUBPARTS (vectype));
+ }
+ if (!final_mask)
+ {
+ /* Pass all ones value to 'mask' argument of
+ LEN_MASK_LOAD if final_mask is invalid. */
+ mask_vectype = truth_type_for (vectype);
+ final_mask = build_minus_one_cst (mask_vectype);
+ }
+ }
+ if (final_len)
+ {
+ signed char biasval
+ = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo);
- tree bias = build_int_cst (intQI_type_node, biasval);
+ bias = build_int_cst (intQI_type_node, biasval);
+ }
- gcall *call
- = gimple_build_call_internal (IFN_LEN_LOAD, 4,
- dataref_ptr, ptr,
- final_len, bias);
+ if (final_len && memory_access_type != VMAT_INVARIANT)
+ {
+ tree ptr
+ = build_int_cst (ref_type, align * BITS_PER_UNIT);
+ gcall *call;
+ if (partial_ifn == IFN_LEN_MASK_LOAD)
+ call = gimple_build_call_internal (IFN_LEN_MASK_LOAD,
+ 5, dataref_ptr,
+ ptr, final_len,
+ bias, final_mask);
+ else
+ call = gimple_build_call_internal (IFN_LEN_LOAD, 4,
+ dataref_ptr, ptr,
+ final_len, bias);
gimple_call_set_nothrow (call, true);
new_stmt = call;
data_ref = NULL_TREE;
@@ -10412,8 +10551,8 @@ vectorizable_load (vec_info *vinfo,
/* Need conversion if it's wrapped with VnQI. */
if (vmode != new_vmode)
{
- tree new_vtype
- = build_vector_type_for_mode (qi_type, new_vmode);
+ tree new_vtype = build_vector_type_for_mode (
+ unsigned_intQI_type_node, new_vmode);
tree var = vect_get_new_ssa_name (new_vtype,
vect_simple_var);
gimple_set_lhs (call, var);
@@ -10425,6 +10564,18 @@ vectorizable_load (vec_info *vinfo,
VIEW_CONVERT_EXPR, op);
}
}
+ else if (final_mask)
+ {
+ tree ptr = build_int_cst (ref_type,
+ align * BITS_PER_UNIT);
+ gcall *call
+ = gimple_build_call_internal (IFN_MASK_LOAD, 3,
+ dataref_ptr, ptr,
+ final_mask);
+ gimple_call_set_nothrow (call, true);
+ new_stmt = call;
+ data_ref = NULL_TREE;
+ }
else
{
tree ltype = vectype;
@@ -12039,8 +12190,11 @@ get_related_vectype_for_scalar_type (machine_mode prevailing_mode,
machine_mode simd_mode;
tree vectype;
- if (!is_int_mode (TYPE_MODE (scalar_type), &inner_mode)
- && !is_float_mode (TYPE_MODE (scalar_type), &inner_mode))
+ if ((!INTEGRAL_TYPE_P (scalar_type)
+ && !POINTER_TYPE_P (scalar_type)
+ && !SCALAR_FLOAT_TYPE_P (scalar_type))
+ || (!is_int_mode (TYPE_MODE (scalar_type), &inner_mode)
+ && !is_float_mode (TYPE_MODE (scalar_type), &inner_mode)))
return NULL_TREE;
unsigned int nbytes = GET_MODE_SIZE (inner_mode);
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index c52e997..d61b087 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -633,71 +633,6 @@ overflow_comparison_p (tree_code code, tree name, tree val, tree *new_cst)
true, new_cst);
}
-/* Handle
- _4 = x_3 & 31;
- if (_4 != 0)
- goto <bb 6>;
- else
- goto <bb 7>;
- <bb 6>:
- __builtin_unreachable ();
- <bb 7>:
-
- If x_3 has no other immediate uses (checked by caller), var is the
- x_3 var, we can clear low 5 bits from the non-zero bitmask. */
-
-void
-maybe_set_nonzero_bits (edge e, tree var)
-{
- basic_block cond_bb = e->src;
- gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
- tree cst;
-
- if (cond == NULL
- || gimple_cond_code (cond) != ((e->flags & EDGE_TRUE_VALUE)
- ? EQ_EXPR : NE_EXPR)
- || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
- || !integer_zerop (gimple_cond_rhs (cond)))
- return;
-
- gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
- if (!is_gimple_assign (stmt)
- || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
- || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
- return;
- if (gimple_assign_rhs1 (stmt) != var)
- {
- gimple *stmt2;
-
- if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
- return;
- stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
- if (!gimple_assign_cast_p (stmt2)
- || gimple_assign_rhs1 (stmt2) != var
- || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2))
- || (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))
- != TYPE_PRECISION (TREE_TYPE (var))))
- return;
- }
- cst = gimple_assign_rhs2 (stmt);
- if (POINTER_TYPE_P (TREE_TYPE (var)))
- {
- struct ptr_info_def *pi = SSA_NAME_PTR_INFO (var);
- if (pi && pi->misalign)
- return;
- wide_int w = wi::bit_not (wi::to_wide (cst));
- unsigned int bits = wi::ctz (w);
- if (bits == 0 || bits >= HOST_BITS_PER_INT)
- return;
- unsigned int align = 1U << bits;
- if (pi == NULL || pi->align < align)
- set_ptr_info_alignment (get_ptr_info (var), align, 0);
- }
- else
- set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var),
- wi::to_wide (cst)));
-}
-
/* Searches the case label vector VEC for the index *IDX of the CASE_LABEL
that includes the value VAL. The search is restricted to the range
[START_IDX, n - 1] where n is the size of VEC.
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index ba0a314..fe7ecbb 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -32,6 +32,5 @@ extern bool find_case_label_range (gswitch *, tree, tree, size_t *, size_t *);
extern tree find_case_label_range (gswitch *, const irange *vr);
extern bool find_case_label_index (gswitch *, size_t, tree, size_t *);
extern bool overflow_comparison_p (tree_code, tree, tree, tree *);
-extern void maybe_set_nonzero_bits (edge, tree);
#endif /* GCC_TREE_VRP_H */
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 8e144bc..bd500ec 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -2839,7 +2839,7 @@ grow_tree_vec (tree v, int len MEM_STAT_DECL)
return v;
}
-/* Return 1 if EXPR is the constant zero, whether it is integral, float or
+/* Return true if EXPR is the constant zero, whether it is integral, float or
fixed, and scalar, complex or vector. */
bool
@@ -2850,7 +2850,7 @@ zerop (const_tree expr)
|| fixed_zerop (expr));
}
-/* Return 1 if EXPR is the integer constant zero or a complex constant
+/* Return true if EXPR is the integer constant zero or a complex constant
of zero, or a location wrapper for such a constant. */
bool
@@ -2874,7 +2874,7 @@ integer_zerop (const_tree expr)
}
}
-/* Return 1 if EXPR is the integer constant one or the corresponding
+/* Return true if EXPR is the integer constant one or the corresponding
complex constant, or a location wrapper for such a constant. */
bool
@@ -2898,9 +2898,9 @@ integer_onep (const_tree expr)
}
}
-/* Return 1 if EXPR is the integer constant one. For complex and vector,
- return 1 if every piece is the integer constant one.
- Also return 1 for location wrappers for such a constant. */
+/* Return true if EXPR is the integer constant one. For complex and vector,
+ return true if every piece is the integer constant one.
+ Also return true for location wrappers for such a constant. */
bool
integer_each_onep (const_tree expr)
@@ -2914,8 +2914,8 @@ integer_each_onep (const_tree expr)
return integer_onep (expr);
}
-/* Return 1 if EXPR is an integer containing all 1's in as much precision as
- it contains, or a complex or vector whose subparts are such integers,
+/* Return true if EXPR is an integer containing all 1's in as much precision
+ as it contains, or a complex or vector whose subparts are such integers,
or a location wrapper for such a constant. */
bool
@@ -2940,8 +2940,8 @@ integer_all_onesp (const_tree expr)
== wi::to_wide (expr));
}
-/* Return 1 if EXPR is the integer constant minus one, or a location wrapper
- for such a constant. */
+/* Return true if EXPR is the integer constant minus one, or a location
+ wrapper for such a constant. */
bool
integer_minus_onep (const_tree expr)
@@ -2955,8 +2955,8 @@ integer_minus_onep (const_tree expr)
return integer_all_onesp (expr);
}
-/* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
- one bit on), or a location wrapper for such a constant. */
+/* Return true if EXPR is an integer constant that is a power of 2 (i.e., has
+ only one bit on), or a location wrapper for such a constant. */
bool
integer_pow2p (const_tree expr)
@@ -2974,7 +2974,7 @@ integer_pow2p (const_tree expr)
return wi::popcount (wi::to_wide (expr)) == 1;
}
-/* Return 1 if EXPR is an integer constant other than zero or a
+/* Return true if EXPR is an integer constant other than zero or a
complex constant other than zero, or a location wrapper for such a
constant. */
@@ -2990,10 +2990,10 @@ integer_nonzerop (const_tree expr)
|| integer_nonzerop (TREE_IMAGPART (expr)))));
}
-/* Return 1 if EXPR is the integer constant one. For vector,
- return 1 if every piece is the integer constant minus one
+/* Return true if EXPR is the integer constant one. For vector,
+ return true if every piece is the integer constant minus one
(representing the value TRUE).
- Also return 1 for location wrappers for such a constant. */
+ Also return true for location wrappers for such a constant. */
bool
integer_truep (const_tree expr)
@@ -3005,7 +3005,7 @@ integer_truep (const_tree expr)
return integer_onep (expr);
}
-/* Return 1 if EXPR is the fixed-point constant zero, or a location wrapper
+/* Return true if EXPR is the fixed-point constant zero, or a location wrapper
for such a constant. */
bool
@@ -3152,9 +3152,9 @@ tree_ctz (const_tree expr)
}
}
-/* Return 1 if EXPR is the real constant zero. Trailing zeroes matter for
- decimal float constants, so don't return 1 for them.
- Also return 1 for location wrappers around such a constant. */
+/* Return true if EXPR is the real constant zero. Trailing zeroes matter for
+ decimal float constants, so don't return true for them.
+ Also return true for location wrappers around such a constant. */
bool
real_zerop (const_tree expr)
@@ -3184,10 +3184,10 @@ real_zerop (const_tree expr)
}
}
-/* Return 1 if EXPR is the real constant one in real or complex form.
+/* Return true if EXPR is the real constant one in real or complex form.
Trailing zeroes matter for decimal float constants, so don't return
- 1 for them.
- Also return 1 for location wrappers around such a constant. */
+ true for them.
+ Also return true for location wrappers around such a constant. */
bool
real_onep (const_tree expr)
@@ -3211,9 +3211,9 @@ real_onep (const_tree expr)
}
}
-/* Return 1 if EXPR is the real constant minus one. Trailing zeroes
- matter for decimal float constants, so don't return 1 for them.
- Also return 1 for location wrappers around such a constant. */
+/* Return true if EXPR is the real constant minus one. Trailing zeroes
+ matter for decimal float constants, so don't return true for them.
+ Also return true for location wrappers around such a constant. */
bool
real_minus_onep (const_tree expr)
@@ -3266,7 +3266,7 @@ real_maybe_zerop (const_tree expr)
}
}
-/* Nonzero if EXP is a constant or a cast of a constant. */
+/* True if EXP is a constant or a cast of a constant. */
bool
really_constant_p (const_tree exp)
@@ -3381,7 +3381,7 @@ chain_index (int idx, tree chain)
return chain;
}
-/* Return nonzero if ELEM is part of the chain CHAIN. */
+/* Return true if ELEM is part of the chain CHAIN. */
bool
chain_member (const_tree elem, const_tree chain)
@@ -4099,11 +4099,11 @@ contains_placeholder_p (const_tree exp)
enum tree_code code;
if (!exp)
- return 0;
+ return false;
code = TREE_CODE (exp);
if (code == PLACEHOLDER_EXPR)
- return 1;
+ return true;
switch (TREE_CODE_CLASS (code))
{
@@ -4138,7 +4138,7 @@ contains_placeholder_p (const_tree exp)
case SAVE_EXPR:
/* The save_expr function never wraps anything containing
a PLACEHOLDER_EXPR. */
- return 0;
+ return false;
default:
break;
@@ -4152,7 +4152,7 @@ contains_placeholder_p (const_tree exp)
return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)));
default:
- return 0;
+ return false;
}
case tcc_vl_exp:
@@ -4164,17 +4164,17 @@ contains_placeholder_p (const_tree exp)
const_call_expr_arg_iterator iter;
FOR_EACH_CONST_CALL_EXPR_ARG (arg, iter, exp)
if (CONTAINS_PLACEHOLDER_P (arg))
- return 1;
- return 0;
+ return true;
+ return false;
}
default:
- return 0;
+ return false;
}
default:
- return 0;
+ return false;
}
- return 0;
+ return false;
}
/* Return true if any part of the structure of TYPE involves a PLACEHOLDER_EXPR
@@ -5792,7 +5792,7 @@ tree_map_base_hash (const void *item)
purposes. We simply return true if the from tree is marked, so that this
structure goes away when the from tree goes away. */
-int
+bool
tree_map_base_marked_p (const void *p)
{
return ggc_marked_p (((const struct tree_map_base *) p)->from);
@@ -6088,7 +6088,7 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
TYPE_ATTRIBUTES (b->type))
|| (TREE_CODE (a->type) != COMPLEX_TYPE
&& TYPE_NAME (a->type) != TYPE_NAME (b->type)))
- return 0;
+ return false;
/* Be careful about comparing arrays before and after the element type
has been completed; don't compare TYPE_ALIGN unless both types are
@@ -6096,7 +6096,7 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
if (COMPLETE_TYPE_P (a->type) && COMPLETE_TYPE_P (b->type)
&& (TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
|| TYPE_MODE (a->type) != TYPE_MODE (b->type)))
- return 0;
+ return false;
switch (TREE_CODE (a->type))
{
@@ -6106,7 +6106,7 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
case POINTER_TYPE:
case REFERENCE_TYPE:
case NULLPTR_TYPE:
- return 1;
+ return true;
case VECTOR_TYPE:
return known_eq (TYPE_VECTOR_SUBPARTS (a->type),
@@ -6120,7 +6120,7 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
&& TREE_CODE (TYPE_VALUES (b->type)) == TREE_LIST
&& type_list_equal (TYPE_VALUES (a->type),
TYPE_VALUES (b->type))))
- return 0;
+ return false;
/* fall through */
@@ -6152,7 +6152,7 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
&& type_list_equal (TYPE_ARG_TYPES (a->type),
TYPE_ARG_TYPES (b->type)))))
break;
- return 0;
+ return false;
case ARRAY_TYPE:
/* Don't compare TYPE_TYPELESS_STORAGE flag on aggregates,
where the flag should be inherited from the element type
@@ -6187,16 +6187,16 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
&& type_list_equal (TYPE_ARG_TYPES (a->type),
TYPE_ARG_TYPES (b->type))))
break;
- return 0;
+ return false;
default:
- return 0;
+ return false;
}
if (lang_hooks.types.type_hash_eq != NULL)
return lang_hooks.types.type_hash_eq (a->type, b->type);
- return 1;
+ return true;
}
/* Given TYPE, and HASHCODE its hash code, return the canonical
@@ -6355,17 +6355,17 @@ type_argument_type (const_tree fntype, unsigned argno)
return NULL_TREE;
}
-/* Nonzero if integer constants T1 and T2
+/* True if integer constants T1 and T2
represent the same constant value. */
-int
+bool
tree_int_cst_equal (const_tree t1, const_tree t2)
{
if (t1 == t2)
- return 1;
+ return true;
if (t1 == 0 || t2 == 0)
- return 0;
+ return false;
STRIP_ANY_LOCATION_WRAPPER (t1);
STRIP_ANY_LOCATION_WRAPPER (t2);
@@ -6373,9 +6373,9 @@ tree_int_cst_equal (const_tree t1, const_tree t2)
if (TREE_CODE (t1) == INTEGER_CST
&& TREE_CODE (t2) == INTEGER_CST
&& wi::to_widest (t1) == wi::to_widest (t2))
- return 1;
+ return true;
- return 0;
+ return false;
}
/* Return true if T is an INTEGER_CST whose numerical value (extended
@@ -7978,7 +7978,7 @@ tree
get_narrower (tree op, int *unsignedp_ptr)
{
int uns = 0;
- int first = 1;
+ bool first = true;
tree win = op;
bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
@@ -8026,7 +8026,7 @@ get_narrower (tree op, int *unsignedp_ptr)
if a zero extension has been stripped, only zero-extensions. */
else if (uns != TYPE_UNSIGNED (TREE_TYPE (op)))
break;
- first = 0;
+ first = false;
}
else /* bitschange == 0 */
{
@@ -8034,7 +8034,7 @@ get_narrower (tree op, int *unsignedp_ptr)
preserve the unsignedness. */
if (first)
uns = TYPE_UNSIGNED (TREE_TYPE (op));
- first = 0;
+ first = false;
op = TREE_OPERAND (op, 0);
/* Keep trying to narrow, but don't assign op to win if it
would turn an integral type into something else. */
@@ -11194,19 +11194,19 @@ lower_bound_in_type (tree outer, tree inner)
}
}
-/* Return nonzero if two operands that are suitable for PHI nodes are
+/* Return true if two operands that are suitable for PHI nodes are
necessarily equal. Specifically, both ARG0 and ARG1 must be either
SSA_NAME or invariant. Note that this is strictly an optimization.
That is, callers of this function can directly call operand_equal_p
and get the same result, only slower. */
-int
+bool
operand_equal_for_phi_arg_p (const_tree arg0, const_tree arg1)
{
if (arg0 == arg1)
- return 1;
+ return true;
if (TREE_CODE (arg0) == SSA_NAME || TREE_CODE (arg1) == SSA_NAME)
- return 0;
+ return false;
return operand_equal_p (arg0, arg1, 0);
}
@@ -11825,7 +11825,7 @@ cl_option_hasher::equal (tree x, tree y)
const_tree const yt = y;
if (TREE_CODE (xt) != TREE_CODE (yt))
- return 0;
+ return false;
if (TREE_CODE (xt) == OPTIMIZATION_NODE)
return cl_optimization_option_eq (TREE_OPTIMIZATION (xt),
@@ -13423,7 +13423,7 @@ verify_type_variant (const_tree t, tree tv)
}
verify_variant_match (TYPE_NEEDS_CONSTRUCTING);
}
- verify_variant_match (TYPE_PRECISION);
+ verify_variant_match (TYPE_PRECISION_RAW);
if (RECORD_OR_UNION_TYPE_P (t))
verify_variant_match (TYPE_TRANSPARENT_AGGR);
else if (TREE_CODE (t) == ARRAY_TYPE)
@@ -13701,8 +13701,8 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2,
|| TREE_CODE (t1) == OFFSET_TYPE
|| POINTER_TYPE_P (t1))
{
- /* Can't be the same type if they have different recision. */
- if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
+ /* Can't be the same type if they have different precision. */
+ if (TYPE_PRECISION_RAW (t1) != TYPE_PRECISION_RAW (t2))
return false;
/* In some cases the signed and unsigned types are required to be
diff --git a/gcc/tree.def b/gcc/tree.def
index 1fc2ca7..be94b7e 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -565,13 +565,18 @@ DEFTREECODE (VEC_COND_EXPR, "vec_cond_expr", tcc_expression, 3)
N = length(mask)
foreach i in N:
- M = mask[i] % (2*N)
- A = M < N ? v0[M] : v1[M-N]
+ M = mask[i] % (length(v0) + length(v1))
+ A[i] = M < length(v0) ? v0[M] : v1[M - length(v0)]
- V0 and V1 are vectors of the same type. MASK is an integer-typed
- vector. The number of MASK elements must be the same with the
- number of elements in V0 and V1. The size of the inner type
- of the MASK and of the V0 and V1 must be the same.
+ V0 and V1 are vectors of the same type.
+
+ When MASK is not constant:
+ MASK is an integer-typed vector. The number of MASK elements must
+ be the same as the number of elements in V0 and V1. The size of
+ the inner type of the MASK and of the V0 and V1 must be the same.
+
+ When MASK is constant:
+ MASK is an integer-typed vector.
*/
DEFTREECODE (VEC_PERM_EXPR, "vec_perm_expr", tcc_expression, 3)
diff --git a/gcc/tree.h b/gcc/tree.h
index 1854fe4..fa02e29 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -807,7 +807,12 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
(...) prototype, where arguments can be accessed with va_start and
va_arg), as opposed to an unprototyped function. */
#define TYPE_NO_NAMED_ARGS_STDARG_P(NODE) \
- (TYPE_CHECK (NODE)->type_common.no_named_args_stdarg_p)
+ (FUNC_OR_METHOD_CHECK (NODE)->type_common.no_named_args_stdarg_p)
+
+/* True if this RECORD_TYPE or UNION_TYPE includes a flexible array member
+ as the last field recursively. */
+#define TYPE_INCLUDES_FLEXARRAY(NODE) \
+ (RECORD_OR_UNION_CHECK (NODE)->type_common.no_named_args_stdarg_p)
/* In an IDENTIFIER_NODE, this means that assemble_name was called with
this string as an argument. */
@@ -819,7 +824,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define TYPE_REF_CAN_ALIAS_ALL(NODE) \
(PTR_OR_REF_CHECK (NODE)->base.static_flag)
-/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST, this means
+/* In an INTEGER_CST, REAL_CST, or COMPLEX_CST, this means
there was an overflow in folding. */
#define TREE_OVERFLOW(NODE) (CST_CHECK (NODE)->base.public_flag)
@@ -2191,7 +2196,9 @@ class auto_suppress_location_wrappers
#define TYPE_SIZE_UNIT(NODE) (TYPE_CHECK (NODE)->type_common.size_unit)
#define TYPE_POINTER_TO(NODE) (TYPE_CHECK (NODE)->type_common.pointer_to)
#define TYPE_REFERENCE_TO(NODE) (TYPE_CHECK (NODE)->type_common.reference_to)
-#define TYPE_PRECISION(NODE) (TYPE_CHECK (NODE)->type_common.precision)
+#define TYPE_PRECISION(NODE) \
+ (TREE_NOT_CHECK (TYPE_CHECK (NODE), VECTOR_TYPE)->type_common.precision)
+#define TYPE_PRECISION_RAW(NODE) (TYPE_CHECK (NODE)->type_common.precision)
#define TYPE_NAME(NODE) (TYPE_CHECK (NODE)->type_common.name)
#define TYPE_NEXT_VARIANT(NODE) (TYPE_CHECK (NODE)->type_common.next_variant)
#define TYPE_MAIN_VARIANT(NODE) (TYPE_CHECK (NODE)->type_common.main_variant)
@@ -4803,7 +4810,7 @@ extern bool vec_member (const_tree, vec<tree, va_gc> *);
extern tree chain_index (int, tree);
/* Arguments may be null. */
-extern int tree_int_cst_equal (const_tree, const_tree);
+extern bool tree_int_cst_equal (const_tree, const_tree);
/* The following predicates are safe to call with a null argument. */
extern bool tree_fits_shwi_p (const_tree) ATTRIBUTE_PURE;
@@ -5411,7 +5418,7 @@ extern bool operation_can_overflow (enum tree_code);
extern bool operation_no_trapping_overflow (tree, enum tree_code);
extern tree upper_bound_in_type (tree, tree);
extern tree lower_bound_in_type (tree, tree);
-extern int operand_equal_for_phi_arg_p (const_tree, const_tree);
+extern bool operand_equal_for_phi_arg_p (const_tree, const_tree);
extern tree create_artificial_label (location_t);
extern const char *get_name (tree);
extern bool stdarg_p (const_tree);
@@ -5655,7 +5662,7 @@ extern tree component_ref_size (tree, special_array_member * = NULL);
extern int tree_map_base_eq (const void *, const void *);
extern unsigned int tree_map_base_hash (const void *);
-extern int tree_map_base_marked_p (const void *);
+extern bool tree_map_base_marked_p (const void *);
extern void DEBUG_FUNCTION verify_type (const_tree t);
extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
bool trust_type_canonical = true);
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 707b1f1..f5d4bf3 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -411,9 +411,6 @@ frange::set (tree type,
gcc_checking_assert (real_compare (LE_EXPR, &min, &max));
normalize_kind ();
-
- if (flag_checking)
- verify_range ();
}
// Setter for an frange defaulting the NAN possibility to +-NAN when
@@ -462,6 +459,8 @@ frange::normalize_kind ()
m_kind = VR_RANGE;
m_min = frange_val_min (m_type);
m_max = frange_val_max (m_type);
+ if (flag_checking)
+ verify_range ();
return true;
}
}
@@ -524,8 +523,6 @@ frange::union_nans (const frange &r)
m_pos_nan |= r.m_pos_nan;
m_neg_nan |= r.m_neg_nan;
normalize_kind ();
- if (flag_checking)
- verify_range ();
return true;
}
@@ -569,8 +566,6 @@ frange::union_ (const vrange &v)
changed |= combine_zeros (r, true);
changed |= normalize_kind ();
- if (flag_checking)
- verify_range ();
return changed;
}
@@ -648,8 +643,6 @@ frange::intersect (const vrange &v)
changed |= combine_zeros (r, false);
changed |= normalize_kind ();
- if (flag_checking)
- verify_range ();
return changed;
}
@@ -1197,7 +1190,12 @@ irange::irange_single_pair_union (const irange &r)
m_base[3] = r.m_base[1];
m_num_ranges = 2;
}
- union_nonzero_bits (r);
+ // The range has been altered, so normalize it even if nothing
+ // changed in the mask.
+ if (!union_nonzero_bits (r))
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
return true;
}
@@ -1221,7 +1219,12 @@ irange::irange_single_pair_union (const irange &r)
m_base[3] = m_base[1];
m_base[1] = r.m_base[1];
}
- union_nonzero_bits (r);
+ // The range has been altered, so normalize it even if nothing
+ // changed in the mask.
+ if (!union_nonzero_bits (r))
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
return true;
}
@@ -1351,7 +1354,12 @@ irange::union_ (const vrange &v)
m_num_ranges = i / 2;
m_kind = VR_RANGE;
- union_nonzero_bits (r);
+ // The range has been altered, so normalize it even if nothing
+ // changed in the mask.
+ if (!union_nonzero_bits (r))
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
return true;
}
@@ -1518,7 +1526,12 @@ irange::intersect (const vrange &v)
}
m_kind = VR_RANGE;
- intersect_nonzero_bits (r);
+ // The range has been altered, so normalize it even if nothing
+ // changed in the mask.
+ if (!intersect_nonzero_bits (r))
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
return true;
}
@@ -1585,10 +1598,7 @@ irange::intersect (const wide_int& lb, const wide_int& ub)
}
m_kind = VR_RANGE;
- // No need to call normalize_kind(), as the caller will do this
- // while intersecting the nonzero mask.
- if (flag_checking)
- verify_range ();
+ normalize_kind ();
return true;
}
@@ -1758,6 +1768,8 @@ irange::set_range_from_nonzero_bits ()
zero.set_zero (type ());
union_ (zero);
}
+ if (flag_checking)
+ verify_range ();
return true;
}
else if (popcount == 0)
@@ -1778,10 +1790,8 @@ irange::set_nonzero_bits (const wide_int &bits)
m_kind = VR_RANGE;
m_nonzero_mask = bits;
- if (set_range_from_nonzero_bits ())
- return;
-
- normalize_kind ();
+ if (!set_range_from_nonzero_bits ())
+ normalize_kind ();
if (flag_checking)
verify_range ();
}
@@ -1807,8 +1817,8 @@ irange::get_nonzero_bits () const
return m_nonzero_mask & get_nonzero_bits_from_range ();
}
-// Intersect the nonzero bits in R into THIS and normalize the range.
-// Return TRUE if the intersection changed anything.
+// Intersect the nonzero bits in R into THIS. Return TRUE and
+// normalize the range if anything changed.
bool
irange::intersect_nonzero_bits (const irange &r)
@@ -1816,14 +1826,8 @@ irange::intersect_nonzero_bits (const irange &r)
gcc_checking_assert (!undefined_p () && !r.undefined_p ());
if (m_nonzero_mask == -1 && r.m_nonzero_mask == -1)
- {
- normalize_kind ();
- if (flag_checking)
- verify_range ();
- return false;
- }
+ return false;
- bool changed = false;
if (m_nonzero_mask != r.m_nonzero_mask)
{
wide_int nz = get_nonzero_bits () & r.get_nonzero_bits ();
@@ -1832,18 +1836,17 @@ irange::intersect_nonzero_bits (const irange &r)
return false;
m_nonzero_mask = nz;
- if (set_range_from_nonzero_bits ())
- return true;
- changed = true;
+ if (!set_range_from_nonzero_bits ())
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
+ return true;
}
- normalize_kind ();
- if (flag_checking)
- verify_range ();
- return changed;
+ return false;
}
-// Union the nonzero bits in R into THIS and normalize the range.
-// Return TRUE if the union changed anything.
+// Union the nonzero bits in R into THIS. Return TRUE and normalize
+// the range if anything changed.
bool
irange::union_nonzero_bits (const irange &r)
@@ -1851,28 +1854,22 @@ irange::union_nonzero_bits (const irange &r)
gcc_checking_assert (!undefined_p () && !r.undefined_p ());
if (m_nonzero_mask == -1 && r.m_nonzero_mask == -1)
- {
- normalize_kind ();
- if (flag_checking)
- verify_range ();
- return false;
- }
+ return false;
- bool changed = false;
if (m_nonzero_mask != r.m_nonzero_mask)
{
wide_int save = get_nonzero_bits ();
m_nonzero_mask = save | r.get_nonzero_bits ();
+ if (m_nonzero_mask == save)
+ return false;
// No need to call set_range_from_nonzero_bits, because we'll
// never narrow the range. Besides, it would cause endless
// recursion because of the union_ in
// set_range_from_nonzero_bits.
- changed = m_nonzero_mask != save;
+ normalize_kind ();
+ return true;
}
- normalize_kind ();
- if (flag_checking)
- verify_range ();
- return changed;
+ return false;
}
void
@@ -1993,21 +1990,6 @@ gt_pch_nx (vrange *x, gt_pointer_operator op, void *cookie)
gcc_unreachable ();
}
-// ?? These stubs are for ipa-prop.cc which use a value_range in a
-// hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
-// instead of picking up the gt_ggc_mx (T *) version.
-void
-gt_pch_nx (int_range<2> *&x)
-{
- return gt_pch_nx ((irange *) x);
-}
-
-void
-gt_ggc_mx (int_range<2> *&x)
-{
- return gt_ggc_mx ((irange *) x);
-}
-
#define DEFINE_INT_RANGE_INSTANCE(N) \
template int_range<N>::int_range(tree_node *, \
const wide_int &, \
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 9103e9c..5d4eaf8 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -1002,6 +1002,8 @@ irange::normalize_kind ()
else if (m_kind == VR_ANTI_RANGE)
set_undefined ();
}
+ if (flag_checking)
+ verify_range ();
}
inline bool
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index dd84754..8ae0a25 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -102,13 +102,13 @@ bool first_function_block_is_cold;
static bool saw_no_split_stack;
static const char *strip_reg_name (const char *);
-static int contains_pointers_p (tree);
+static bool contains_pointers_p (tree);
#ifdef ASM_OUTPUT_EXTERNAL
static bool incorporeal_function_p (tree);
#endif
static void decode_addr_const (tree, class addr_const *);
static hashval_t const_hash_1 (const tree);
-static int compare_constant (const tree, const tree);
+static bool compare_constant (const tree, const tree);
static void output_constant_def_contents (rtx);
static void output_addressed_constants (tree, int);
static unsigned HOST_WIDE_INT output_constant (tree, unsigned HOST_WIDE_INT,
@@ -2419,9 +2419,9 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
}
}
-/* Return 1 if type TYPE contains any pointers. */
+/* Return true if type TYPE contains any pointers. */
-static int
+static bool
contains_pointers_p (tree type)
{
switch (TREE_CODE (type))
@@ -2431,7 +2431,7 @@ contains_pointers_p (tree type)
/* I'm not sure whether OFFSET_TYPE needs this treatment,
so I'll play safe and return 1. */
case OFFSET_TYPE:
- return 1;
+ return true;
case RECORD_TYPE:
case UNION_TYPE:
@@ -2442,8 +2442,8 @@ contains_pointers_p (tree type)
for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields))
if (TREE_CODE (fields) == FIELD_DECL
&& contains_pointers_p (TREE_TYPE (fields)))
- return 1;
- return 0;
+ return true;
+ return false;
}
case ARRAY_TYPE:
@@ -2451,7 +2451,7 @@ contains_pointers_p (tree type)
return contains_pointers_p (TREE_TYPE (type));
default:
- return 0;
+ return false;
}
}
@@ -3206,14 +3206,14 @@ tree_descriptor_hasher::equal (constant_descriptor_tree *c1,
constant_descriptor_tree *c2)
{
if (c1->hash != c2->hash)
- return 0;
+ return false;
return compare_constant (c1->value, c2->value);
}
-/* Compare t1 and t2, and return 1 only if they are known to result in
+/* Compare t1 and t2, and return true only if they are known to result in
the same bit pattern on output. */
-static int
+static bool
compare_constant (const tree t1, const tree t2)
{
enum tree_code typecode;
@@ -3221,19 +3221,19 @@ compare_constant (const tree t1, const tree t2)
if (t1 == NULL_TREE)
return t2 == NULL_TREE;
if (t2 == NULL_TREE)
- return 0;
+ return false;
if (TREE_CODE (t1) != TREE_CODE (t2))
- return 0;
+ return false;
switch (TREE_CODE (t1))
{
case INTEGER_CST:
/* Integer constants are the same only if the same width of type. */
if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
- return 0;
+ return false;
if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
- return 0;
+ return false;
return tree_int_cst_equal (t1, t2);
case REAL_CST:
@@ -3244,15 +3244,15 @@ compare_constant (const tree t1, const tree t2)
different 128-bit floating point types (IBM extended double and IEEE
128-bit floating point). */
if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
- return 0;
+ return false;
if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
- return 0;
+ return false;
return real_identical (&TREE_REAL_CST (t1), &TREE_REAL_CST (t2));
case FIXED_CST:
/* Fixed constants are the same only if the same width of type. */
if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
- return 0;
+ return false;
return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2));
@@ -3260,7 +3260,7 @@ compare_constant (const tree t1, const tree t2)
if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
|| int_size_in_bytes (TREE_TYPE (t1))
!= int_size_in_bytes (TREE_TYPE (t2)))
- return 0;
+ return false;
return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
&& ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
@@ -3274,19 +3274,19 @@ compare_constant (const tree t1, const tree t2)
{
if (VECTOR_CST_NPATTERNS (t1)
!= VECTOR_CST_NPATTERNS (t2))
- return 0;
+ return false;
if (VECTOR_CST_NELTS_PER_PATTERN (t1)
!= VECTOR_CST_NELTS_PER_PATTERN (t2))
- return 0;
+ return false;
unsigned int count = vector_cst_encoded_nelts (t1);
for (unsigned int i = 0; i < count; ++i)
if (!compare_constant (VECTOR_CST_ENCODED_ELT (t1, i),
VECTOR_CST_ENCODED_ELT (t2, i)))
- return 0;
+ return false;
- return 1;
+ return true;
}
case CONSTRUCTOR:
@@ -3296,7 +3296,7 @@ compare_constant (const tree t1, const tree t2)
typecode = TREE_CODE (TREE_TYPE (t1));
if (typecode != TREE_CODE (TREE_TYPE (t2)))
- return 0;
+ return false;
if (typecode == ARRAY_TYPE)
{
@@ -3307,20 +3307,20 @@ compare_constant (const tree t1, const tree t2)
|| size_1 != int_size_in_bytes (TREE_TYPE (t2))
|| TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (t1))
!= TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (t2)))
- return 0;
+ return false;
}
else
{
/* For record and union constructors, require exact type
equality. */
if (TREE_TYPE (t1) != TREE_TYPE (t2))
- return 0;
+ return false;
}
v1 = CONSTRUCTOR_ELTS (t1);
v2 = CONSTRUCTOR_ELTS (t2);
if (vec_safe_length (v1) != vec_safe_length (v2))
- return 0;
+ return false;
for (idx = 0; idx < vec_safe_length (v1); ++idx)
{
@@ -3329,21 +3329,21 @@ compare_constant (const tree t1, const tree t2)
/* Check that each value is the same... */
if (!compare_constant (c1->value, c2->value))
- return 0;
+ return false;
/* ... and that they apply to the same fields! */
if (typecode == ARRAY_TYPE)
{
if (!compare_constant (c1->index, c2->index))
- return 0;
+ return false;
}
else
{
if (c1->index != c2->index)
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
case ADDR_EXPR:
@@ -3351,17 +3351,17 @@ compare_constant (const tree t1, const tree t2)
{
class addr_const value1, value2;
enum rtx_code code;
- int ret;
+ bool ret;
decode_addr_const (t1, &value1);
decode_addr_const (t2, &value2);
if (maybe_ne (value1.offset, value2.offset))
- return 0;
+ return false;
code = GET_CODE (value1.base);
if (code != GET_CODE (value2.base))
- return 0;
+ return false;
switch (code)
{
@@ -3392,7 +3392,7 @@ compare_constant (const tree t1, const tree t2)
return compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
default:
- return 0;
+ return false;
}
}
@@ -3760,7 +3760,7 @@ const_rtx_desc_hasher::equal (constant_descriptor_rtx *x,
constant_descriptor_rtx *y)
{
if (x->mode != y->mode)
- return 0;
+ return false;
return rtx_equal_p (x->constant, y->constant);
}
@@ -4377,7 +4377,7 @@ const_rtx_data_hasher::equal (constant_descriptor_rtx_data *x,
constant_descriptor_rtx_data *y)
{
if (x->hash != y->hash || x->size != y->size)
- return 0;
+ return false;
unsigned int align1 = x->desc->align;
unsigned int align2 = y->desc->align;
unsigned int offset1 = (x->offset * BITS_PER_UNIT) & (align1 - 1);
@@ -4387,10 +4387,10 @@ const_rtx_data_hasher::equal (constant_descriptor_rtx_data *x,
if (offset2)
align2 = least_bit_hwi (offset2);
if (align2 > align1)
- return 0;
+ return false;
if (memcmp (x->bytes, y->bytes, x->size * sizeof (target_unit)) != 0)
- return 0;
- return 1;
+ return false;
+ return true;
}
/* Attempt to optimize constant pool POOL. If it contains both CONST_VECTOR
@@ -4885,7 +4885,8 @@ initializer_constant_valid_p_1 (tree value, tree endtype, tree *cache)
/* Allow length-preserving conversions between integer types and
floating-point types. */
if (((INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
- || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type)))
+ || (SCALAR_FLOAT_TYPE_P (dest_type)
+ && SCALAR_FLOAT_TYPE_P (src_type)))
&& (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type)))
return initializer_constant_valid_p_1 (src, endtype, cache);
@@ -4943,6 +4944,7 @@ initializer_constant_valid_p_1 (tree value, tree endtype, tree *cache)
if (cache && cache[0] == value)
return cache[1];
if (! INTEGRAL_TYPE_P (endtype)
+ || ! INTEGRAL_TYPE_P (TREE_TYPE (value))
|| TYPE_PRECISION (endtype) >= TYPE_PRECISION (TREE_TYPE (value)))
{
tree ncache[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
@@ -4979,6 +4981,7 @@ initializer_constant_valid_p_1 (tree value, tree endtype, tree *cache)
if (cache && cache[0] == value)
return cache[1];
if (! INTEGRAL_TYPE_P (endtype)
+ || ! INTEGRAL_TYPE_P (TREE_TYPE (value))
|| TYPE_PRECISION (endtype) >= TYPE_PRECISION (TREE_TYPE (value)))
{
tree ncache[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
@@ -6525,30 +6528,32 @@ default_assemble_visibility (tree decl ATTRIBUTE_UNUSED,
/* A helper function to call assemble_visibility when needed for a decl. */
-int
+bool
maybe_assemble_visibility (tree decl)
{
enum symbol_visibility vis = DECL_VISIBILITY (decl);
if (vis != VISIBILITY_DEFAULT)
{
targetm.asm_out.assemble_visibility (decl, vis);
- return 1;
+ return true;
}
else
- return 0;
+ return false;
}
-/* Returns 1 if the target configuration supports defining public symbols
+/* Returns true if the target configuration supports defining public symbols
so that one of them will be chosen at link time instead of generating a
multiply-defined symbol error, whether through the use of weak symbols or
a target-specific mechanism for having duplicates discarded. */
-int
+bool
supports_one_only (void)
{
if (SUPPORTS_ONE_ONLY)
- return 1;
- return TARGET_SUPPORTS_WEAK;
+ return true;
+ if (TARGET_SUPPORTS_WEAK)
+ return true;
+ return false;
}
/* Set up DECL as a public symbol that can be defined in multiple
diff --git a/gcc/varasm.h b/gcc/varasm.h
index e6190ca..ff302e8 100644
--- a/gcc/varasm.h
+++ b/gcc/varasm.h
@@ -31,7 +31,7 @@ extern tree tree_output_constant_def (tree);
extern void make_decl_rtl (tree);
extern rtx make_decl_rtl_for_debug (tree);
extern void make_decl_one_only (tree, tree);
-extern int supports_one_only (void);
+extern bool supports_one_only (void);
extern void resolve_unique_section (tree, int, int);
extern void mark_referenced (tree);
extern void mark_decl_referenced (tree);
diff --git a/gcc/vec.h b/gcc/vec.h
index 3691891..6f7b048 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1390,6 +1390,13 @@ gt_pch_nx (vec<T, A, vl_embed> *v)
gt_pch_nx ((*v)[i]);
}
+template<typename T>
+void
+gt_pch_nx (vec<T, va_gc_atomic, vl_embed> *)
+{
+ /* No pointers to note. */
+}
+
template<typename T, typename A>
void
gt_pch_nx (vec<T *, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
@@ -1407,6 +1414,13 @@ gt_pch_nx (vec<T, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
gt_pch_nx (&((*v)[i]), op, cookie);
}
+template<typename T>
+void
+gt_pch_nx (vec<T, va_gc_atomic, vl_embed> *, gt_pointer_operator, void *)
+{
+ /* No pointers to note. */
+}
+
/* Space efficient vector. These vectors can grow dynamically and are
allocated together with their control data. They are suited to be
@@ -2286,12 +2300,12 @@ public:
array_slice (vec<OtherT> &v)
: m_base (v.address ()), m_size (v.length ()) {}
- template<typename OtherT>
- array_slice (const vec<OtherT, va_gc> *v)
+ template<typename OtherT, typename A>
+ array_slice (const vec<OtherT, A, vl_embed> *v)
: m_base (v ? v->address () : nullptr), m_size (v ? v->length () : 0) {}
- template<typename OtherT>
- array_slice (vec<OtherT, va_gc> *v)
+ template<typename OtherT, typename A>
+ array_slice (vec<OtherT, A, vl_embed> *v)
: m_base (v ? v->address () : nullptr), m_size (v ? v->length () : 0) {}
iterator begin () { return m_base; }