aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@baylibre.com>2024-03-19 16:37:35 +0100
committerThomas Schwinge <tschwinge@baylibre.com>2024-03-19 16:37:35 +0100
commite8c161211f0c5bfac915979aebcd6a16b0bc49ab (patch)
tree5c6bfeac90f189d4f07b82337cea932083751727
parentf0fdff9b6da1a17d8e1c2d83347e84c5218b1b29 (diff)
parent061a82fa2b751b42d0d8ddfcd45367c848d3ee64 (diff)
downloadgcc-e8c161211f0c5bfac915979aebcd6a16b0bc49ab.zip
gcc-e8c161211f0c5bfac915979aebcd6a16b0bc49ab.tar.gz
gcc-e8c161211f0c5bfac915979aebcd6a16b0bc49ab.tar.bz2
Merge commit 'f7884f7673444b8a2c10ea0981d480f2e82dd16a^' into HEAD
-rw-r--r--ChangeLog13
-rw-r--r--MAINTAINERS2
-rw-r--r--contrib/regression/ChangeLog13
-rwxr-xr-xcontrib/regression/btest-gcc.sh31
-rw-r--r--fixincludes/ChangeLog4
-rwxr-xr-xfixincludes/configure1
-rw-r--r--gcc/ChangeLog1247
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog187
-rw-r--r--gcc/ada/adaint.c14
-rw-r--r--gcc/ada/adaint.h2
-rw-r--r--gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst11
-rw-r--r--gcc/ada/exp_aggr.adb118
-rw-r--r--gcc/ada/exp_ch5.adb42
-rw-r--r--gcc/ada/exp_ch7.adb78
-rw-r--r--gcc/ada/exp_spark.adb53
-rw-r--r--gcc/ada/exp_util.adb25
-rw-r--r--gcc/ada/exp_util.ads2
-rw-r--r--gcc/ada/gcc-interface/decl.cc12
-rw-r--r--gcc/ada/gcc-interface/trans.cc8
-rw-r--r--gcc/ada/gcc-interface/utils.cc19
-rw-r--r--gcc/ada/gen_il-fields.ads1
-rw-r--r--gcc/ada/gen_il-gen-gen_nodes.adb1
-rw-r--r--gcc/ada/gnat_ugn.texi28
-rw-r--r--gcc/ada/inline.adb2
-rw-r--r--gcc/ada/libgnat/g-catiio.adb4
-rw-r--r--gcc/ada/libgnat/i-cstrea.adb9
-rw-r--r--gcc/ada/libgnat/i-cstrea.ads3
-rw-r--r--gcc/ada/libgnat/libada.gpr13
-rw-r--r--gcc/ada/libgnat/libgnat_common.gpr2
-rw-r--r--gcc/ada/libgnat/s-crtl.ads3
-rw-r--r--gcc/ada/libgnat/s-fileio.adb3
-rw-r--r--gcc/ada/par-ch4.adb120
-rw-r--r--gcc/ada/par.adb22
-rw-r--r--gcc/ada/par_sco.adb7
-rw-r--r--gcc/ada/s-oscons-tmplt.c3
-rw-r--r--gcc/ada/sem_aggr.adb311
-rw-r--r--gcc/ada/sem_aggr.ads14
-rw-r--r--gcc/ada/sem_attr.adb10
-rw-r--r--gcc/ada/sem_ch12.adb12
-rw-r--r--gcc/ada/sem_ch5.adb23
-rw-r--r--gcc/ada/sem_res.adb14
-rw-r--r--gcc/ada/sem_util.adb36
-rw-r--r--gcc/ada/sem_util.ads7
-rw-r--r--gcc/ada/sem_warn.adb46
-rw-r--r--gcc/ada/sinfo.ads7
-rw-r--r--gcc/analyzer/ChangeLog43
-rw-r--r--gcc/attribs.cc45
-rw-r--r--gcc/builtins.cc3
-rw-r--r--gcc/c-family/ChangeLog44
-rw-r--r--gcc/c-family/c-common.cc113
-rw-r--r--gcc/c-family/c-common.h16
-rw-r--r--gcc/c-family/c-cppbuiltin.cc4
-rw-r--r--gcc/c-family/c-lex.cc40
-rw-r--r--gcc/c-family/c-opts.cc39
-rw-r--r--gcc/c-family/c-ppoutput.cc6
-rw-r--r--gcc/c-family/c.opt8
-rw-r--r--gcc/c/ChangeLog20
-rw-r--r--gcc/c/c-decl.cc3
-rw-r--r--gcc/c/c-lang.cc9
-rw-r--r--gcc/c/c-objc-common.cc33
-rw-r--r--gcc/c/c-objc-common.h3
-rw-r--r--gcc/c/c-parser.cc353
-rw-r--r--gcc/cgraph.cc48
-rw-r--r--gcc/cgraph.h4
-rw-r--r--gcc/common.md28
-rw-r--r--gcc/common.opt12
-rw-r--r--gcc/common/config/i386/cpuinfo.h33
-rw-r--r--gcc/common/config/i386/i386-common.cc55
-rw-r--r--gcc/common/config/i386/i386-cpuinfo.h2
-rw-r--r--gcc/common/config/i386/i386-isas.h3
-rw-r--r--gcc/common/config/riscv/riscv-common.cc8
-rw-r--r--gcc/config.gcc23
-rw-r--r--gcc/config.host23
-rw-r--r--gcc/config.in30
-rw-r--r--gcc/config/aarch64/aarch64-arches.def28
-rw-r--r--gcc/config/aarch64/aarch64-cores.def5
-rw-r--r--gcc/config/aarch64/aarch64-opts.h2
-rw-r--r--gcc/config/aarch64/aarch64-simd.md108
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/aarch64/aarch64.cc2468
-rw-r--r--gcc/config/aarch64/aarch64.h3
-rw-r--r--gcc/config/aarch64/tuning_models/a64fx.h169
-rw-r--r--gcc/config/aarch64/tuning_models/ampere1.h113
-rw-r--r--gcc/config/aarch64/tuning_models/ampere1a.h65
-rw-r--r--gcc/config/aarch64/tuning_models/cortexa35.h62
-rw-r--r--gcc/config/aarch64/tuning_models/cortexa53.h71
-rw-r--r--gcc/config/aarch64/tuning_models/cortexa57.h109
-rw-r--r--gcc/config/aarch64/tuning_models/cortexa72.h61
-rw-r--r--gcc/config/aarch64/tuning_models/cortexa73.h62
-rw-r--r--gcc/config/aarch64/tuning_models/emag.h60
-rw-r--r--gcc/config/aarch64/tuning_models/exynosm1.h144
-rw-r--r--gcc/config/aarch64/tuning_models/generic.h190
-rw-r--r--gcc/config/aarch64/tuning_models/generic_armv8_a.h191
-rw-r--r--gcc/config/aarch64/tuning_models/generic_armv9_a.h245
-rw-r--r--gcc/config/aarch64/tuning_models/neoverse512tvb.h164
-rw-r--r--gcc/config/aarch64/tuning_models/neoversen1.h60
-rw-r--r--gcc/config/aarch64/tuning_models/neoversen2.h245
-rw-r--r--gcc/config/aarch64/tuning_models/neoversev1.h237
-rw-r--r--gcc/config/aarch64/tuning_models/neoversev2.h245
-rw-r--r--gcc/config/aarch64/tuning_models/qdf24xx.h137
-rw-r--r--gcc/config/aarch64/tuning_models/saphira.h63
-rw-r--r--gcc/config/aarch64/tuning_models/thunderx.h117
-rw-r--r--gcc/config/aarch64/tuning_models/thunderx2t99.h137
-rw-r--r--gcc/config/aarch64/tuning_models/thunderx3t110.h136
-rw-r--r--gcc/config/aarch64/tuning_models/thunderxt88.h72
-rw-r--r--gcc/config/aarch64/tuning_models/tsv110.h137
-rw-r--r--gcc/config/aarch64/tuning_models/xgene1.h145
-rw-r--r--gcc/config/arm/arm-builtins.cc28
-rw-r--r--gcc/config/arm/arm-mve-builtins-base.cc58
-rw-r--r--gcc/config/arm/arm-mve-builtins-base.def4
-rw-r--r--gcc/config/arm/arm-mve-builtins-base.h4
-rw-r--r--gcc/config/arm/arm-mve-builtins-functions.h58
-rw-r--r--gcc/config/arm/arm-mve-builtins-shapes.cc92
-rw-r--r--gcc/config/arm/arm-mve-builtins-shapes.h2
-rw-r--r--gcc/config/arm/arm-mve-builtins.cc115
-rw-r--r--gcc/config/arm/arm-mve-builtins.def16
-rw-r--r--gcc/config/arm/arm-mve-builtins.h45
-rw-r--r--gcc/config/arm/arm_mve.h282
-rw-r--r--gcc/config/arm/mve.md8
-rw-r--r--gcc/config/avr/avr.cc6
-rw-r--r--gcc/config/bpf/bpf-helpers.h427
-rw-r--r--gcc/config/bpf/bpf.cc8
-rw-r--r--gcc/config/c6x/c6x.md2
-rw-r--r--gcc/config/gcn/gcn-valu.md8
-rw-r--r--gcc/config/gcn/gcn.cc4
-rw-r--r--gcc/config/i386/cpuid.h5
-rw-r--r--gcc/config/i386/driver-i386.cc42
-rw-r--r--gcc/config/i386/i386-builtin.def8
-rw-r--r--gcc/config/i386/i386-expand.cc4
-rw-r--r--gcc/config/i386/i386-expand.h4
-rw-r--r--gcc/config/i386/i386-isa.def3
-rw-r--r--gcc/config/i386/i386-options.cc151
-rw-r--r--gcc/config/i386/i386-opts.h3
-rw-r--r--gcc/config/i386/i386.cc160
-rw-r--r--gcc/config/i386/i386.h7
-rw-r--r--gcc/config/i386/i386.md59
-rw-r--r--gcc/config/i386/i386.opt33
-rw-r--r--gcc/config/i386/mmx.md31
-rw-r--r--gcc/config/i386/sse.md58
-rw-r--r--gcc/config/linux-protos.h1
-rw-r--r--gcc/config/linux.cc9
-rw-r--r--gcc/config/linux.h3
-rw-r--r--gcc/config/loongarch/gnu-user.h6
-rw-r--r--gcc/config/loongarch/loongarch-def.h10
-rw-r--r--gcc/config/loongarch/loongarch.cc42
-rw-r--r--gcc/config/loongarch/lsx.md2
-rw-r--r--gcc/config/mips/mips.md2
-rw-r--r--gcc/config/nvptx/nvptx.cc14
-rw-r--r--gcc/config/nvptx/nvptx.h4
-rw-r--r--gcc/config/pa/pa.cc8
-rw-r--r--gcc/config/pa/pa.h4
-rw-r--r--gcc/config/pa/predicates.md7
-rwxr-xr-xgcc/config/riscv/arch-canonicalize2
-rw-r--r--gcc/config/riscv/autovec.md44
-rw-r--r--gcc/config/riscv/predicates.md20
-rw-r--r--gcc/config/riscv/riscv-avlprop.cc25
-rw-r--r--gcc/config/riscv/riscv-c.cc3
-rw-r--r--gcc/config/riscv/riscv-d.cc1
-rw-r--r--gcc/config/riscv/riscv-opts.h13
-rw-r--r--gcc/config/riscv/riscv-protos.h7
-rw-r--r--gcc/config/riscv/riscv-string.cc7
-rw-r--r--gcc/config/riscv/riscv-v.cc214
-rw-r--r--gcc/config/riscv/riscv.cc668
-rw-r--r--gcc/config/riscv/riscv.h17
-rw-r--r--gcc/config/riscv/riscv.md149
-rw-r--r--gcc/config/riscv/riscv.opt27
-rw-r--r--gcc/config/riscv/thead.cc34
-rw-r--r--gcc/config/riscv/vector-iterators.md214
-rw-r--r--gcc/config/riscv/vector.md27
-rw-r--r--gcc/config/s390/s390-builtin-types.def8
-rw-r--r--gcc/config/s390/s390-builtins.def86
-rw-r--r--gcc/config/s390/s390-c.cc1
-rw-r--r--gcc/config/s390/s390.cc145
-rw-r--r--gcc/config/s390/s390.md28
-rw-r--r--gcc/config/s390/vector.md14
-rw-r--r--gcc/config/sh/sh.md2
-rw-r--r--gcc/config/vax/vax.cc9
-rwxr-xr-xgcc/configure171
-rw-r--r--gcc/configure.ac123
-rw-r--r--gcc/convert.cc6
-rw-r--r--gcc/cp/ChangeLog97
-rw-r--r--gcc/cp/cp-lang.cc9
-rw-r--r--gcc/cp/cp-objcp-common.cc144
-rw-r--r--gcc/cp/cp-objcp-common.h1
-rw-r--r--gcc/cp/cp-tree.h23
-rw-r--r--gcc/cp/decl.cc57
-rw-r--r--gcc/cp/lambda.cc2
-rw-r--r--gcc/cp/mangle.cc2
-rw-r--r--gcc/cp/module.cc38
-rw-r--r--gcc/cp/name-lookup.cc75
-rw-r--r--gcc/cp/parser.cc78
-rw-r--r--gcc/cp/pt.cc105
-rw-r--r--gcc/cp/semantics.cc166
-rw-r--r--gcc/d/ChangeLog14
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/aggregate.d2
-rw-r--r--gcc/d/dmd/aggregate.h2
-rw-r--r--gcc/d/dmd/arrayop.d2
-rw-r--r--gcc/d/dmd/astenums.d1
-rw-r--r--gcc/d/dmd/attrib.d111
-rw-r--r--gcc/d/dmd/attrib.h7
-rw-r--r--gcc/d/dmd/canthrow.d3
-rw-r--r--gcc/d/dmd/common/outbuffer.d6
-rw-r--r--gcc/d/dmd/compiler.d1
-rw-r--r--gcc/d/dmd/cond.d1
-rw-r--r--gcc/d/dmd/cparse.d31
-rw-r--r--gcc/d/dmd/ctfeexpr.d276
-rw-r--r--gcc/d/dmd/dcast.d8
-rw-r--r--gcc/d/dmd/dclass.d67
-rw-r--r--gcc/d/dmd/declaration.d12
-rw-r--r--gcc/d/dmd/declaration.h1
-rw-r--r--gcc/d/dmd/denum.d32
-rw-r--r--gcc/d/dmd/dimport.d40
-rw-r--r--gcc/d/dmd/dmangle.d1
-rw-r--r--gcc/d/dmd/dmodule.d67
-rw-r--r--gcc/d/dmd/dscope.d22
-rw-r--r--gcc/d/dmd/dstruct.d17
-rw-r--r--gcc/d/dmd/dsymbol.d475
-rw-r--r--gcc/d/dmd/dsymbol.h16
-rw-r--r--gcc/d/dmd/dsymbolsem.d997
-rw-r--r--gcc/d/dmd/dtemplate.d8
-rw-r--r--gcc/d/dmd/dtoh.d1
-rw-r--r--gcc/d/dmd/dversion.d75
-rw-r--r--gcc/d/dmd/enum.h2
-rw-r--r--gcc/d/dmd/escape.d22
-rw-r--r--gcc/d/dmd/expression.d1394
-rw-r--r--gcc/d/dmd/expression.h51
-rw-r--r--gcc/d/dmd/expressionsem.d1413
-rw-r--r--gcc/d/dmd/func.d61
-rw-r--r--gcc/d/dmd/globals.d6
-rw-r--r--gcc/d/dmd/hdrgen.d22
-rw-r--r--gcc/d/dmd/iasmgcc.d4
-rw-r--r--gcc/d/dmd/id.d3
-rw-r--r--gcc/d/dmd/import.h2
-rw-r--r--gcc/d/dmd/importc.d1
-rw-r--r--gcc/d/dmd/init.d29
-rw-r--r--gcc/d/dmd/init.h10
-rw-r--r--gcc/d/dmd/initsem.d20
-rw-r--r--gcc/d/dmd/lambdacomp.d1
-rw-r--r--gcc/d/dmd/lexer.d18
-rw-r--r--gcc/d/dmd/module.h2
-rw-r--r--gcc/d/dmd/nogc.d16
-rw-r--r--gcc/d/dmd/nspace.d43
-rw-r--r--gcc/d/dmd/nspace.h2
-rw-r--r--gcc/d/dmd/opover.d2
-rw-r--r--gcc/d/dmd/optimize.d28
-rw-r--r--gcc/d/dmd/parse.d67
-rw-r--r--gcc/d/dmd/parsetimevisitor.d1
-rw-r--r--gcc/d/dmd/scope.h5
-rw-r--r--gcc/d/dmd/semantic3.d3
-rw-r--r--gcc/d/dmd/statementsem.d7
-rw-r--r--gcc/d/dmd/staticassert.d5
-rw-r--r--gcc/d/dmd/staticassert.h1
-rw-r--r--gcc/d/dmd/staticcond.d1
-rw-r--r--gcc/d/dmd/traits.d99
-rw-r--r--gcc/d/dmd/typesem.d7
-rw-r--r--gcc/d/dmd/version.h2
-rw-r--r--gcc/d/dmd/visitor.h2
-rw-r--r--gcc/d/expr.cc99
-rw-r--r--gcc/d/runtime.def7
-rw-r--r--gcc/doc/cpp.texi41
-rw-r--r--gcc/doc/extend.texi149
-rw-r--r--gcc/doc/install.texi18
-rw-r--r--gcc/doc/invoke.texi102
-rw-r--r--gcc/doc/md.texi46
-rw-r--r--gcc/doc/sourcebuild.texi9
-rw-r--r--gcc/doc/standards.texi6
-rw-r--r--gcc/doc/tm.texi8
-rw-r--r--gcc/doc/tm.texi.in5
-rw-r--r--gcc/dse.cc9
-rw-r--r--gcc/expr.cc20
-rw-r--r--gcc/fortran/ChangeLog30
-rw-r--r--gcc/fortran/check.cc50
-rw-r--r--gcc/fortran/error.cc6
-rw-r--r--gcc/fortran/gfortran.texi10
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/fortran/libgfortran.h7
-rw-r--r--gcc/fortran/openmp.cc44
-rw-r--r--gcc/fortran/options.cc6
-rw-r--r--gcc/fortran/resolve.cc4
-rw-r--r--gcc/gcc.cc48
-rw-r--r--gcc/genconfig.cc2
-rw-r--r--gcc/genpreds.cc146
-rw-r--r--gcc/gensupport.cc48
-rw-r--r--gcc/gensupport.h3
-rw-r--r--gcc/gimple-iterator.h35
-rw-r--r--gcc/gimple-lower-bitint.cc93
-rw-r--r--gcc/gimple-range-fold.cc24
-rw-r--r--gcc/gimplify.cc4
-rw-r--r--gcc/ifcvt.cc38
-rw-r--r--gcc/internal-fn.cc81
-rw-r--r--gcc/internal-fn.def19
-rw-r--r--gcc/internal-fn.h1
-rw-r--r--gcc/ipa-prop.cc73
-rw-r--r--gcc/ipa-prop.h5
-rw-r--r--gcc/ipa-pure-const.cc9
-rw-r--r--gcc/ipa-utils.h1
-rw-r--r--gcc/ira-build.cc8
-rw-r--r--gcc/ira-color.cc10
-rw-r--r--gcc/ira-costs.cc73
-rw-r--r--gcc/ira-int.h14
-rw-r--r--gcc/ira-lives.cc61
-rw-r--r--gcc/lra-constraints.cc13
-rw-r--r--gcc/match.pd13
-rw-r--r--gcc/objc/objc-act.cc46
-rw-r--r--gcc/objc/objc-act.h3
-rw-r--r--gcc/objc/objc-lang.cc10
-rw-r--r--gcc/objcp/objcp-lang.cc10
-rw-r--r--gcc/omp-expand.cc11
-rw-r--r--gcc/omp-general.cc4
-rw-r--r--gcc/omp-low.cc29
-rw-r--r--gcc/omp-simd-clone.cc8
-rw-r--r--gcc/opts.cc68
-rw-r--r--gcc/opts.h1
-rw-r--r--gcc/recog.cc14
-rw-r--r--gcc/recog.h24
-rw-r--r--gcc/reginfo.cc5
-rw-r--r--gcc/rtl-ssa/access-utils.h40
-rw-r--r--gcc/rtl-ssa/accesses.cc24
-rw-r--r--gcc/rtl-ssa/accesses.h4
-rw-r--r--gcc/rtl-ssa/changes.cc86
-rw-r--r--gcc/rtl-ssa/changes.h2
-rw-r--r--gcc/rtl-ssa/functions.h14
-rw-r--r--gcc/rtl-ssa/insns.cc5
-rw-r--r--gcc/rtl-ssa/insns.h7
-rw-r--r--gcc/rtl-ssa/internals.inl1
-rw-r--r--gcc/rtl-ssa/member-fns.inl12
-rw-r--r--gcc/rtl-ssa/movement.h8
-rw-r--r--gcc/rtl.def6
-rw-r--r--gcc/rust/ChangeLog4
-rw-r--r--gcc/sort.cc6
-rw-r--r--gcc/symbol-summary.h2
-rw-r--r--gcc/system.h23
-rw-r--r--gcc/target-globals.cc6
-rw-r--r--gcc/target-globals.h3
-rw-r--r--gcc/target.def7
-rw-r--r--gcc/targhooks.cc8
-rw-r--r--gcc/targhooks.h1
-rw-r--r--gcc/testsuite/ChangeLog1410
-rw-r--r--gcc/testsuite/c-c++-common/Wattributes.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c2
-rw-r--r--gcc/testsuite/c-c++-common/builtin-classify-type-1.c12
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-1.S6
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-1.c14
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-10.c12
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-11.c10
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-12.c11
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-13.c6
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-14.c6
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-15.c5
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-2.c12
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-3.c14
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-4.c4
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-5.c11
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-6.c12
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-7.c7
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-8.c7
-rw-r--r--gcc/testsuite/c-c++-common/fhardened-9.c9
-rw-r--r--gcc/testsuite/c-c++-common/gomp/depobj-3.c47
-rw-r--r--gcc/testsuite/c-c++-common/has-feature-common.c73
-rw-r--r--gcc/testsuite/c-c++-common/has-feature-pedantic.c20
-rw-r--r--gcc/testsuite/c-c++-common/pr111309-2.c4
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-75.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-const1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/udlit-error1.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp26/feat-cxx26.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp26/static_assert1.C309
-rw-r--r--gcc/testsuite/g++.dg/eh/pr112619.C15
-rw-r--r--gcc/testsuite/g++.dg/ext/has-feature.C206
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-2.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-7.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ipa-icf-2.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ipa-icf-3.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-1.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-3.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-5.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-8.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/nothrow-1.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/pure-const-1.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/pure-const-2.C2
-rw-r--r--gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C2
-rw-r--r--gcc/testsuite/g++.dg/modules/bad-mapper-1.C4
-rw-r--r--gcc/testsuite/g++.dg/modules/export-1.C20
-rw-r--r--gcc/testsuite/g++.dg/modules/export-2_a.C14
-rw-r--r--gcc/testsuite/g++.dg/modules/export-2_b.C7
-rw-r--r--gcc/testsuite/g++.dg/modules/lambda-6_a.C16
-rw-r--r--gcc/testsuite/g++.dg/modules/lambda-6_b.C9
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99187.C10
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99232_a.C12
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99232_b.C13
-rw-r--r--gcc/testsuite/g++.dg/modules/using-10.C71
-rw-r--r--gcc/testsuite/g++.dg/modules/using-enum-2.C23
-rw-r--r--gcc/testsuite/g++.dg/opt/pr110879.C2
-rw-r--r--gcc/testsuite/g++.dg/pch/pr112319.C5
-rw-r--r--gcc/testsuite/g++.dg/pch/pr112319.Hs1
-rw-r--r--gcc/testsuite/g++.dg/pr104869.C3
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr109849.C31
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/sra-eh-1.C187
-rw-r--r--gcc/testsuite/g++.dg/vect/pr36648.cc2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstringop-overflow-4.C2
-rw-r--r--gcc/testsuite/g++.target/i386/pr89316.C6
-rw-r--r--gcc/testsuite/g++.target/riscv/rvv/base/bug-14.C4
-rw-r--r--gcc/testsuite/g++.target/riscv/rvv/base/bug-9.C4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr106433.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/frame-address.c8
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr111408.c26
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/strndup-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/asan/has-feature-asan.c6
-rw-r--r--gcc/testsuite/gcc.dg/bitint-40.c29
-rw-r--r--gcc/testsuite/gcc.dg/bitint-41.c36
-rw-r--r--gcc/testsuite/gcc.dg/bitint-42.c9
-rw-r--r--gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c927
-rw-r--r--gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c150
-rw-r--r--gcc/testsuite/gcc.dg/has-feature.c62
-rw-r--r--gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pure-const-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/remref-0.c2
-rw-r--r--gcc/testsuite/gcc.dg/nonnull-7.c10
-rw-r--r--gcc/testsuite/gcc.dg/pch/pr112319.c5
-rw-r--r--gcc/testsuite/gcc.dg/pch/pr112319.hs1
-rw-r--r--gcc/testsuite/gcc.dg/pr109977.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr110279-1.c65
-rw-r--r--gcc/testsuite/gcc.dg/pr112618.c26
-rw-r--r--gcc/testsuite/gcc.dg/pr112622.c5
-rw-r--r--gcc/testsuite/gcc.dg/pr112673.c10
-rw-r--r--gcc/testsuite/gcc.dg/simd-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/addieq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addifeq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addifge.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addifgt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addifle.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addiflt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addifne.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addige.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addigeu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addigt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addigtu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addile.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addileu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addilt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addiltu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addine.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addleq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlfeq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlfge.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlfgt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlfle.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlflt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlfne.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlge.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlgeu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlgt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlgtu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlle.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlleu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addllt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlltu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/addlne.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movieq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movifeq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movifge.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movifgt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movifle.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/moviflt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movifne.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movige.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movigeu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movigt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movigtu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movile.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movileu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movilt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/moviltu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movine.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movleq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlfeq.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlfge.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlfgt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlfle.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlflt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlfne.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlge.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlgeu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlgt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlgtu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlle.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlleu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movllt.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlltu.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/movlne.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr111815.c26
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr112281-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr112281-2.c18
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr112344.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr112639.c34
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr109849.c60
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr110269.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr112706.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr20701.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/return-value-range-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/scev-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/scev-4.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/scev-5.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-longjmp-1.c87
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp05.c2
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/has-feature-ubsan.c6
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pred-9_b.c7
-rw-r--r--gcc/testsuite/gcc.dg/vla-1.c2
-rw-r--r--gcc/testsuite/gcc.misc-tests/help.exp2
-rw-r--r--gcc/testsuite/gcc.misc-tests/linkage-y.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_1.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_2.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ccmp_1.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/movk.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr112406-2.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/vmulx.x4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_asrd_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_4.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/target_attr_13.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/target_attr_15.c2
-rwxr-xr-xgcc/testsuite/gcc.target/aarch64/uxtl-combine-1.c20
-rwxr-xr-xgcc/testsuite/gcc.target/aarch64/uxtl-combine-2.c20
-rwxr-xr-xgcc/testsuite/gcc.target/aarch64/uxtl-combine-3.c20
-rwxr-xr-xgcc/testsuite/gcc.target/aarch64/uxtl-combine-4.c20
-rwxr-xr-xgcc/testsuite/gcc.target/aarch64/uxtl-combine-5.c20
-rwxr-xr-xgcc/testsuite/gcc.target/aarch64/uxtl-combine-6.c20
-rw-r--r--gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c8
-rw-r--r--gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c8
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f16.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f32.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s16.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s32.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s8.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u16.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u32.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u8.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/pr53447-5.c8
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-bind.c4
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-csum-diff.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-csum-update.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-current-task.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-stack.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-get-stackid.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-getsockopt.c19
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c14
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-override-return.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-probe-read.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-redirect-map.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-set-hash.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-setsockopt.c20
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c21
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c21
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-release.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c19
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c (renamed from gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c)6
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c19
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c19
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c20
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c19
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-spin-lock.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-strtol.c20
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-strtoul.c20
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c19
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c18
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-tail-call.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c19
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c15
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-trace-printk.c16
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c17
-rw-r--r--gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-interrupt-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-ppx-1.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-push2pop2_force_drap-1.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-push2pop2_interrupt-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-1.c22
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-10.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-11.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-12.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-13.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-14.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-15.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-16.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-17.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-18.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-19.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-2.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-20.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-21.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-22.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-23.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-3.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-4.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-5.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-6.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-7.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-8.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_1-9.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/bmi2-pr112518.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/cf_check-6.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112325-1.c116
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112325-2.c38
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112325-mmx-1.c40
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112605-1.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112605-2.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112605.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112623.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112672.c23
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112686.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr90693.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4-pr112681.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c8
-rw-r--r--gcc/testsuite/gcc.target/loongarch/imm-load1.c3
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vect-shuf-fp.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibfeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibfge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibfgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibfle.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibflt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibfne.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibgeu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibgtu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddible.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibleu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddiblt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibltu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddibne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddieq.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddifeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddifge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddifgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddifle.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddiflt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddifne.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddige.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddigeu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddigt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddigtu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddile.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddileu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddilt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddiltu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/adddine.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibfeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibfge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibfgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibfle.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibflt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibfne.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibgeu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibgtu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsible.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibleu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsiblt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibltu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsibne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsieq.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsifeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsifge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsifgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsifle.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsiflt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsifne.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsige.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsigeu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsigt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsigtu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsile.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsileu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsilt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsiltu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/addsine.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibeq-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibeq-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibeq-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfeq-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfeq-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfeq.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfge.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfgt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfle.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibflt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibfne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibge-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibge-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibge-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgeu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgeu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgt-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgtu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgtu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgtu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibgtu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdible-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdible-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdible-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdible.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibleu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibleu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiblt-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiblt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibltu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibltu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibltu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibltu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibne-thead.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibne-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibne-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdibne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdieq-sfb.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdieq-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdieq-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdieq-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdieq.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifeq-sfb.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifeq-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifeq-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifeq-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifeq.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifge-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifge-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifge-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifge-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifge.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifgt-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifgt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifle-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifle-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifle-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifle-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifle.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiflt-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiflt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifne-sfb.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifne-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifne-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifne-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdifne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdige-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdige-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdige-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdige-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdige.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigeu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigeu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigt-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigtu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdigtu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdile-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdile-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdile-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdile-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdile.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdileu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdileu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdileu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdileu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdileu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdilt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdilt-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdilt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdilt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdilt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiltu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdiltu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdine-sfb.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdine-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdine-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdine-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movdine.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibeq-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibeq-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibeq-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibeq.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfeq-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfeq-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfeq.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfge.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfgt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfle.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibflt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibfne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibge-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibge-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibge-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibge.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgeu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgeu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgt-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgtu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgtu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgtu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibgtu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsible-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsible-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsible-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsible.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibleu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibleu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiblt-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiblt.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibltu-thead.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibltu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibltu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibltu.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibne-thead.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibne-ventana.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibne-zicond.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsibne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsieq-sfb.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsieq-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsieq-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsieq-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsieq.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifeq-sfb.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifeq-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifeq-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifeq-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifeq.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifge-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifge-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifge-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifge-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifge.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifgt-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifgt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifle-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifle-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifle-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifle-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifle.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiflt-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiflt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifne-sfb.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifne-thead.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifne-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifne-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsifne.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsige-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsige-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsige-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsige-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsige.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigeu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigeu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigt-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigtu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsigtu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsile-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsile-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsile-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsile-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsile.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsileu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsileu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsileu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsileu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsileu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsilt-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsilt-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsilt-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsilt-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsilt.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiltu-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsiltu.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsine-sfb.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsine-thead.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsine-ventana.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsine-zicond.c28
-rw-r--r--gcc/testsuite/gcc.target/riscv/movsine.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-1.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-2.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-3.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-4.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-5.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-6.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-7.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-8.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/predef-9.c66
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c40
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c34
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c)0
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c40
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-1.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-10.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-11.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-12.c110
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-2.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-3.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-4.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-5.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-6.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-7.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-8.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-9.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c)0
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-1.c39
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-10.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-11.c114
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-2.c39
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-3.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-4.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-5.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-6.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-7.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-8.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-9.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c41
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c41
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c43
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c40
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c (renamed from gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c)2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/post-ra-avl.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112438.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112597-1.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-1.c56
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-2.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-3.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-1.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-2.c51
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-3.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112694-1.c41
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-1.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-2.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-3.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-4.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-5.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy.h12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c15
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/vf_avl-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/rvv.exp9
-rw-r--r--gcc/testsuite/gcc.target/riscv/smax-ieee.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/smaxf-ieee.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/smin-ieee.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/sminf-ieee.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-bext-02.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c4
-rw-r--r--gcc/testsuite/gcc.target/s390/ccor.c88
-rw-r--r--gcc/testsuite/gcc.target/s390/int128load.c14
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp16-convert.c6
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp32-convert-1.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec_convert_from_fp16.c4
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec_convert_to_fp16.c4
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_hi.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_lo.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec_round_from_fp32.c2
-rw-r--r--gcc/testsuite/gdc.dg/asm1.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/issue16020.d7
-rw-r--r--gcc/testsuite/gdc.test/compilable/nogc.d9
-rw-r--r--gcc/testsuite/gdc.test/compilable/previewin.d6
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/b20011.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/const_ctor.d26
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ctor_attr.d29
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag10415.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag10862.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag10926.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag14102.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag4596.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag8101b.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d56
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail10299.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail13116.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail13336a.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail13336b.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail17491.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail212.d6
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail21243.d18
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail217.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail24224.d22
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail6795.d12
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7424d.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7424e.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7424f.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7424i.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7603a.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7603b.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7603c.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail9537.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail9773.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail9891.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d12
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail_scope.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice10419.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice12841.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice13459.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice20264.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice9284.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/immutable_ctor.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/issue16020.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/issue20704.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test16381.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test22048.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test24157.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test24159.d14
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/tolvalue.d48
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/vector_cast.d13
-rw-r--r--gcc/testsuite/gdc.test/runnable/previewin.d20
-rw-r--r--gcc/testsuite/gdc.test/runnable/staticaa.d15
-rw-r--r--gcc/testsuite/gdc.test/runnable/test24184.d30
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_rank_10.f906
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_rank_8.f904
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/depobj-3.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/pr111880.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/pr112406.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/pr43984.f902
-rw-r--r--gcc/testsuite/gfortran.dg/system_clock_1.f901
-rw-r--r--gcc/testsuite/gfortran.dg/system_clock_3.f081
-rw-r--r--gcc/testsuite/gfortran.dg/system_clock_4.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/vect/pr107254.f902
-rw-r--r--gcc/testsuite/gfortran.dg/vect/pr85853.f901
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect-alias-check-1.F901
-rw-r--r--gcc/testsuite/gnat.dg/warn25.adb1
-rw-r--r--gcc/testsuite/lib/plugin-support.exp2
-rw-r--r--gcc/testsuite/lib/scanasm.exp45
-rw-r--r--gcc/testsuite/lib/target-supports.exp23
-rw-r--r--gcc/testsuite/obj-c++.dg/has-feature.mm21
-rw-r--r--gcc/testsuite/objc.dg/has-feature.m26
-rw-r--r--gcc/toplev.cc25
-rw-r--r--gcc/tree-chrec.cc44
-rw-r--r--gcc/tree-loop-distribution.cc18
-rw-r--r--gcc/tree-profile.cc35
-rw-r--r--gcc/tree-sra.cc287
-rw-r--r--gcc/tree-ssa-forwprop.cc13
-rw-r--r--gcc/tree-ssa-math-opts.cc85
-rw-r--r--gcc/tree-ssa-reassoc.cc77
-rw-r--r--gcc/tree-vect-loop.cc38
-rw-r--r--gcc/tree-vect-patterns.cc26
-rw-r--r--gcc/tree-vect-slp.cc56
-rw-r--r--gcc/tree-vect-stmts.cc6
-rw-r--r--gcc/tree-vrp.cc51
-rw-r--r--gcc/tree.cc18
-rw-r--r--gcc/typeclass.h2
-rw-r--r--libcpp/ChangeLog26
-rw-r--r--libcpp/config.in15
-rwxr-xr-xlibcpp/configure70
-rw-r--r--libcpp/configure.ac51
-rw-r--r--libcpp/include/cpplib.h7
-rw-r--r--libcpp/init.cc2
-rw-r--r--libcpp/lex.cc4
-rw-r--r--libcpp/macro.cc26
-rw-r--r--libgcc/ChangeLog20
-rw-r--r--libgcc/config.host2
-rw-r--r--libgcc/config/arm/lib1funcs.S72
-rw-r--r--libgcc/config/arm/sync-cp15dmb.specs4
-rw-r--r--libgcc/config/arm/sync-dmb.specs4
-rw-r--r--libgcc/config/arm/sync-none.specs4
-rw-r--r--libgcc/config/arm/t-sync13
-rw-r--r--libgcc/hardcfr.c4
-rw-r--r--libgcc/libgcov.h6
-rw-r--r--libgomp/ChangeLog12
-rw-r--r--libgomp/libgomp.texi2
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-3.h8
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4.h7
-rw-r--r--libphobos/ChangeLog9
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/cpuid.d23
-rw-r--r--libphobos/libdruntime/core/internal/array/appending.d83
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d108
-rw-r--r--libphobos/libdruntime/core/internal/atomic.d5
-rw-r--r--libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d6
-rw-r--r--libphobos/libdruntime/core/internal/newaa.d31
-rw-r--r--libphobos/libdruntime/core/stdc/fenv.d8
-rw-r--r--libphobos/libdruntime/core/stdc/stdarg.d6
-rw-r--r--libphobos/libdruntime/core/sync/event.d12
-rw-r--r--libphobos/libdruntime/core/sys/elf/package.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/auxv.d17
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/mman.d1
-rw-r--r--libphobos/libdruntime/core/thread/fiber.d44
-rw-r--r--libphobos/libdruntime/core/vararg.d7
-rw-r--r--libphobos/libdruntime/object.d14
-rw-r--r--libphobos/libdruntime/rt/aaA.d25
-rw-r--r--libphobos/libdruntime/rt/lifetime.d92
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/algorithm/iteration.d58
-rw-r--r--libphobos/src/std/algorithm/searching.d210
-rw-r--r--libphobos/src/std/array.d4
-rw-r--r--libphobos/src/std/container/array.d11
-rw-r--r--libphobos/src/std/logger/package.d1
-rw-r--r--libphobos/src/std/math/hardware.d58
-rw-r--r--libphobos/src/std/range/primitives.d15
-rw-r--r--libsanitizer/ChangeLog7
-rw-r--r--libsanitizer/interception/interception.h8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_asm.h6
-rw-r--r--libstdc++-v3/ChangeLog103
-rw-r--r--libstdc++-v3/doc/html/faq.html5
-rw-r--r--libstdc++-v3/doc/html/manual/test.html4
-rw-r--r--libstdc++-v3/doc/xml/faq.xml5
-rw-r--r--libstdc++-v3/doc/xml/manual/test.xml4
-rw-r--r--libstdc++-v3/include/bits/ranges_base.h8
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h4
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h10
-rw-r--r--libstdc++-v3/include/bits/vector.tcc125
-rw-r--r--libstdc++-v3/include/bits/version.def105
-rw-r--r--libstdc++-v3/include/bits/version.h281
-rw-r--r--libstdc++-v3/include/c_compatibility/string.h2
-rw-r--r--libstdc++-v3/include/c_global/cstring5
-rw-r--r--libstdc++-v3/include/std/algorithm1
-rw-r--r--libstdc++-v3/include/std/array1
-rw-r--r--libstdc++-v3/include/std/expected1
-rw-r--r--libstdc++-v3/include/std/optional1
-rw-r--r--libstdc++-v3/include/std/ranges361
-rw-r--r--libstdc++-v3/include/std/span10
-rw-r--r--libstdc++-v3/include/std/string_view3
-rw-r--r--libstdc++-v3/include/std/variant1
-rw-r--r--libstdc++-v3/include/tr2/dynamic_bitset2
-rw-r--r--libstdc++-v3/testsuite/20_util/expected/version.cc22
-rw-r--r--libstdc++-v3/testsuite/20_util/optional/version.cc20
-rw-r--r--libstdc++-v3/testsuite/20_util/variant/version.cc20
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/requirements/version.cc19
-rw-r--r--libstdc++-v3/testsuite/21_strings/headers/cstring/version.cc19
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/requirements/version.cc19
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/span/1.cc27
-rw-r--r--libstdc++-v3/testsuite/23_containers/span/at.cc36
-rw-r--r--libstdc++-v3/testsuite/23_containers/span/version.cc (renamed from libstdc++-v3/testsuite/23_containers/span/2.cc)15
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/fill_n/requirements/version.cc19
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/swap_ranges/requirements/version.cc19
-rw-r--r--libstdc++-v3/testsuite/std/ranges/conv/1.cc369
-rw-r--r--libstdc++-v3/testsuite/std/ranges/conv/2_neg.cc24
-rw-r--r--libstdc++-v3/testsuite/std/ranges/conv/version.cc19
-rw-r--r--libstdc++-v3/testsuite/tr2/dynamic_bitset/string.cc36
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_allocator.h2
-rw-r--r--libtool.m41
1412 files changed, 37261 insertions, 10414 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b146c5..c9a1e91 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-11-23 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ * MAINTAINERS: Add myself to write after approval and DCO
+
+2023-11-22 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * libtool.m4: Fix stray call
+
+2023-11-19 Lewis Hyatt <lhyatt@gmail.com>
+
+ * Makefile.in: Regenerate.
+ * Makefile.tpl: Add dependency on site.exp to check-gcc-* targets
+
2023-11-18 Petter Tomner <tomner@bahnhof.se>
* MAINTAINERS: Update my email address.
diff --git a/MAINTAINERS b/MAINTAINERS
index 2e26db8..e1e66b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -654,6 +654,7 @@ Svein Seldal <svein@dev.seldal.com>
Senthil Kumar Selvaraj <saaadhu@gcc.gnu.org>
Thiemo Seufer <ths@networkno.de>
Bill Seurer <seurer@linux.vnet.ibm.com>
+Nathaniel Shead <nathanieloshead@gmail.com>
Tim Shen <timshen@google.com>
David Sherwood <david.sherwood@arm.com>
Sharad Singhai <singhai@google.com>
@@ -768,6 +769,7 @@ Navid Rahimi <navidrahimi@microsoft.com>
Rishi Raj <rishiraj45035@gmail.com>
Trevor Saunders <tbsaunde+gcc@tbsaunde.org>
Bill Schmidt <bill.schmidt@fastmail.com>
+Nathaniel Shead <nathanieloshead@gmail.org>
Nathan Sidwell <nathan@acm.org>
Edward Smith-Rowland <esmithrowland@gmail.com>
Petter Tomner <tomner@bahnhof.se>
diff --git a/contrib/regression/ChangeLog b/contrib/regression/ChangeLog
index 27dccac..82abb1f 100644
--- a/contrib/regression/ChangeLog
+++ b/contrib/regression/ChangeLog
@@ -1,3 +1,16 @@
+2023-11-23 Hans-Peter Nilsson <hp@axis.com>
+
+ * btest-gcc.sh (--handle-xpass-as-fail): New option.
+
+2023-11-23 Hans-Peter Nilsson <hp@axis.com>
+
+ * btest-gcc.sh (Option handling): Break out shifts from each
+ option alternative.
+
+2023-11-23 Hans-Peter Nilsson <hp@axis.com>
+
+ * btest-gcc.sh (Option handling): Handle multiple options.
+
2023-02-16 Hans-Peter Nilsson <hp@axis.com>
* objs-gcc.sh: Only bootstrap if source-directory contains gcc.
diff --git a/contrib/regression/btest-gcc.sh b/contrib/regression/btest-gcc.sh
index 1808fcc..684019f 100755
--- a/contrib/regression/btest-gcc.sh
+++ b/contrib/regression/btest-gcc.sh
@@ -22,20 +22,29 @@
add_passes_despite_regression=0
dashj=''
+handle_xpass_as_fail=false
# <options> can be
# --add-passes-despite-regression:
# Add new "PASSes" despite there being some regressions.
# -j<n>:
# Pass '-j<n>' to make.
-
-case "$1" in
- --add-passes-despite-regression)
- add_passes_despite_regression=1; shift;;
- -j*)
- dashj=$1; shift;;
- -*) echo "Invalid option: $1"; exit 2;;
-esac
+# --handle-xpass-as-fail:
+# Count XPASS as a FAIL (default ignored).
+
+while : ; do
+ case "$1" in
+ --add-passes-despite-regression)
+ add_passes_despite_regression=1;;
+ --handle-xpass-as-fail)
+ handle_xpass_as_fail=true;;
+ -j*)
+ dashj=$1;;
+ -*) echo "Invalid option: $1"; exit 2;;
+ *) break;;
+ esac
+ shift
+done
# TARGET is the target triplet. It should be the same one as used in
# constructing PREFIX. Or it can be the keyword 'native', indicating
@@ -199,7 +208,11 @@ done
# Work out what failed
for LOG in $TESTLOGS ; do
L=`basename $LOG`
- awk '/^FAIL: / { print "'$L'",$2; }' $LOG || exit 1
+ if $handle_xpass_as_fail ; then
+ awk '/^(FAIL|XPASS): / { print "'$L'",$2; }' $LOG || exit 1
+ else
+ awk '/^FAIL: / { print "'$L'",$2; }' $LOG || exit 1
+ fi
done | sort | uniq > $FAILED || exit 1
comm -12 $FAILED $PASSES >> $REGRESS || exit 1
NUMREGRESS=`wc -l < $REGRESS | tr -d ' '`
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index 3d5b2d2..7fbb611 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,7 @@
+2023-11-22 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * configure: Regenerated.
+
2023-10-30 Iain Sandoe <iain@sandoe.co.uk>
* configure: Regenerate.
diff --git a/fixincludes/configure b/fixincludes/configure
index 1bb547a..662c94d 100755
--- a/fixincludes/configure
+++ b/fixincludes/configure
@@ -3027,7 +3027,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# ---------------------------
# _LT_COMPILER_PIC
-enable_darwin_at_rpath_$1=no
# _LT_LINKER_SHLIBS([TAGNAME])
# ----------------------------
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 67906ac..aad4c29 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,1250 @@
+2023-11-26 Alexander Monakov <amonakov@ispras.ru>
+
+ * sort.cc: Use 'sorting networks' in comments.
+
+2023-11-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112599
+ * config/riscv/riscv-avlprop.cc (avl_can_be_propagated_p): Add slidedown.
+ (vlmax_ta_p): Ditto.
+ (pass_avlprop::get_vlmax_ta_preferred_avl): Ditto.
+
+2023-11-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-avlprop.cc (alv_can_be_propagated_p): Fix typo.
+ (avl_can_be_propagated_p): Ditto.
+ (vlmax_ta_p): Ditto.
+
+2023-11-25 Gerald Pfeifer <gerald@pfeifer.com>
+
+ PR other/69374
+ * doc/install.texi (Downloading the source): Sort the list of
+ front ends and add D, Go, and Modula-2.
+
+2023-11-25 Gerald Pfeifer <gerald@pfeifer.com>
+
+ PR target/69374
+ * doc/install.texi (Specific) <*-*-freebsd*>: Remove older
+ contents referencing GCC 4.x.
+
+2023-11-25 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/standards.texi (Standards): Update ISO C++ reference.
+
+2023-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/111408
+ * config/i386/i386.md (*jcc_bt<mode>_mask,
+ *jcc_bt<SWI48:mode>_mask_1): Add (const_int 0) as expected
+ second operand of bt_comparison_operator.
+
+2023-11-25 Andrew Pinski <pinskia@gmail.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/109977
+ * config/aarch64/aarch64-simd.md (aarch64_simd_stp<mode>): Use <vwcore>
+ rather than %<vw> for alternative with r constraint on input operand.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * doc/install.texi (amdgcn-*-amdhsa): Fix URL to ROCm;
+ change 'in the future' to 'in LLVM 18'.
+
+2023-11-24 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/pa.cc (pa_emit_move_sequence): Use INT14_OK_STRICT
+ in a couple of places.
+
+2023-11-24 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/109849
+ * tree-sra.cc (passed_by_ref_in_call): New.
+ (sra_initialize): Allocate passed_by_ref_in_call.
+ (sra_deinitialize): Free passed_by_ref_in_call.
+ (create_access): Add decl pool candidates only if they are not
+ already candidates.
+ (build_access_from_expr_1): Bail out on ADDR_EXPRs.
+ (build_access_from_call_arg): New function.
+ (asm_visit_addr): Rename to scan_visit_addr, change the
+ disqualification dump message.
+ (scan_function): Check taken addresses for all non-call statements,
+ including phi nodes. Process all call arguments, including the static
+ chain, build_access_from_call_arg.
+ (maybe_add_sra_candidate): Relax need_to_live_in_memory check to allow
+ non-escaped local variables.
+ (sort_and_splice_var_accesses): Disallow smaller-than-precision
+ replacements for aggregates passed by reference to functions.
+ (sra_modify_expr): Use a separate stmt iterator for adding satements
+ before the processed statement and after it.
+ (enum out_edge_check): New type.
+ (abnormal_edge_after_stmt_p): New function.
+ (sra_modify_call_arg): New function.
+ (sra_modify_assign): Adjust calls to sra_modify_expr.
+ (sra_modify_function_body): Likewise, use sra_modify_call_arg to
+ process call arguments, including the static chain.
+
+2023-11-24 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/112686
+ * config/i386/i386.cc (ix86_expand_split_stack_prologue): Load
+ function address to a register for ix86_cmodel == CM_LARGE.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * doc/invoke.texi (-Wopenmp): Add.
+ * gimplify.cc (gimplify_omp_for): Add OPT_Wopenmp to warning_at.
+ * omp-expand.cc (expand_omp_ordered_sink): Likewise.
+ * omp-general.cc (omp_check_context_selector): Likewise.
+ * omp-low.cc (scan_omp_for, check_omp_nesting_restrictions,
+ lower_omp_ordered_clauses): Likewise.
+ * omp-simd-clone.cc (simd_clone_clauses_extract): Likewise.
+
+2023-11-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112694
+ * config/riscv/riscv-v.cc (preferred_simd_mode): Allow poly_int (1,1) vectors.
+
+2023-11-24 Alexander Monakov <amonakov@ispras.ru>
+
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Delete manual checks for old Valgrind headers.
+ * system.h (VALGRIND_MAKE_MEM_NOACCESS): Delete.
+ (VALGRIND_MAKE_MEM_DEFINED): Delete.
+ (VALGRIND_MAKE_MEM_UNDEFINED): Delete.
+ (VALGRIND_MALLOCLIKE_BLOCK): Delete.
+ (VALGRIND_FREELIKE_BLOCK): Delete.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/112681
+ * config/i386/i386-expand.cc (ix86_expand_branch): Use
+ ix86_expand_vector_logical_operator to expand vector XOR rather than
+ gen_rtx_SET on gen_rtx_XOR.
+
+2023-11-24 Alex Coplan <alex.coplan@arm.com>
+
+ * rtl-ssa/access-utils.h (filter_accesses): New.
+ (remove_regno_access): New.
+ (check_remove_regno_access): New.
+ * rtl-ssa/accesses.cc (rtl_ssa::remove_note_accesses_base): Use
+ new filter_accesses helper.
+
+2023-11-24 Alex Coplan <alex.coplan@arm.com>
+
+ * rtl-ssa/accesses.cc (function_info::create_set): New.
+ * rtl-ssa/accesses.h (access_info::is_temporary): New.
+ * rtl-ssa/changes.cc (move_insn): Handle new (temporary) insns.
+ (function_info::finalize_new_accesses): Handle new/temporary
+ user-created accesses.
+ (function_info::apply_changes_to_insn): Ensure m_is_temp flag
+ on new insns gets cleared.
+ (function_info::change_insns): Handle new/temporary insns.
+ (function_info::create_insn): New.
+ * rtl-ssa/changes.h (class insn_change): Make function_info a
+ friend class.
+ * rtl-ssa/functions.h (function_info): Declare new entry points:
+ create_set, create_insn. Declare new change_alloc helper.
+ * rtl-ssa/insns.cc (insn_info::print_full): Identify temporary insns in
+ dump.
+ * rtl-ssa/insns.h (insn_info): Add new m_is_temp flag and accompanying
+ is_temporary accessor.
+ * rtl-ssa/internals.inl (insn_info::insn_info): Initialize m_is_temp to
+ false.
+ * rtl-ssa/member-fns.inl (function_info::change_alloc): New.
+ * rtl-ssa/movement.h (restrict_movement_for_defs_ignoring): Add
+ handling for temporary defs.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/112673
+ * match.pd (bit_field_ref (vce @0) -> bit_field_ref @0): Only simplify
+ if either @0 doesn't have scalar integral type or if it has mode
+ precision.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112679
+ * gimple-lower-bitint.cc (gimple_lower_bitint): Also stop first loop on
+ floating point SSA_NAME set in FLOAT_EXPR assignment from BITINT_TYPE
+ INTEGER_CST. Set has_large_huge for those if that BITINT_TYPE is large
+ or huge. Set kind to such FLOAT_EXPR assignment rhs1 BITINT_TYPE's kind.
+
+2023-11-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112677
+ * tree-vect-loop.cc (vectorizable_reduction): Use alloca
+ to allocate vectype_op.
+
+2023-11-24 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * expr.cc (by_pieces_ninsns): Include by pieces compare when
+ do the adjustment for overlap operations. Replace mov_optab
+ checks with gcc assertion.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112668
+ * gimple-iterator.h (gsi_end, gsi_end_bb): New inline functions.
+ * gimple-lower-bitint.cc (bitint_large_huge::handle_cast): After
+ temporarily adding statements after m_init_gsi, update m_init_gsi
+ such that later additions after it will be after the added statements.
+ (bitint_large_huge::handle_load): Likewise. When splitting
+ gsi_bb (m_init_gsi) basic block, update m_preheader_bb if needed
+ and update saved m_gsi as well if needed.
+ (bitint_large_huge::lower_mergeable_stmt,
+ bitint_large_huge::lower_comparison_stmt,
+ bitint_large_huge::lower_mul_overflow,
+ bitint_large_huge::lower_bit_query): Use gsi_end_bb.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/112619
+ * tree.cc (try_catch_may_fallthru): If second operand of
+ TRY_CATCH_EXPR is not a STATEMENT_LIST, handle it as if it was a
+ STATEMENT_LIST containing a single statement.
+
+2023-11-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112344
+ * tree-chrec.cc (chrec_apply): Only use an unsigned add
+ when the overall increment doesn't fit the signed type.
+
+2023-11-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112599
+ * config/riscv/riscv-v.cc (shuffle_extract_and_slide1up_patterns): New function.
+ (expand_vec_perm_const_1): Add new optimization.
+
+2023-11-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-v.cc (shuffle_bswap_pattern): Disable for NUNIT < 4.
+
+2023-11-24 Haochen Jiang <haochen.jiang@intel.com>
+
+ PR target/112643
+ * config/i386/driver-i386.cc (check_avx10_avx512_features):
+ Renamed to ...
+ (check_avx512_features): this and remove avx10 check.
+ (host_detect_local_cpu): Never append -mno-avx10.1-{256,512} to
+ avoid emitting warnings when building GCC with native arch.
+ * config/i386/i386-builtin.def (BDESC): Add missing AVX512VL for
+ 128/256 bit builtin for AVX512VP2INTERSECT.
+ * config/i386/i386-options.cc (ix86_option_override_internal):
+ Also check whether the AVX512 flags is set when trying to reset.
+ * config/i386/i386.h
+ (PTA_SKYLAKE_AVX512): Add missing PTA_EVEX512.
+ (PTA_ZNVER4): Ditto.
+
+2023-11-23 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/86776
+ * config/avr/avr.cc (TARGET_HAVE_SPECULATION_SAFE_VALUE): Define
+ to speculation_safe_value_not_needed.
+
+2023-11-23 Marek Polacek <polacek@redhat.com>
+
+ * common.opt (Whardened, fhardened): New options.
+ * config.in: Regenerate.
+ * config/bpf/bpf.cc: Include "opts.h".
+ (bpf_option_override): If flag_stack_protector_set_by_fhardened_p, do
+ not inform that -fstack-protector does not work.
+ * config/i386/i386-options.cc (ix86_option_override_internal): When
+ -fhardened, maybe enable -fcf-protection=full.
+ * config/linux-protos.h (linux_fortify_source_default_level): Declare.
+ * config/linux.cc (linux_fortify_source_default_level): New.
+ * config/linux.h (TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL): Redefine.
+ * configure: Regenerate.
+ * configure.ac: Check if the linker supports '-z now' and '-z relro'.
+ Check if -fhardened is supported on $target_os.
+ * doc/invoke.texi: Document -fhardened and -Whardened.
+ * doc/tm.texi: Regenerate.
+ * doc/tm.texi.in (TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL): Add.
+ * gcc.cc (driver_handle_option): Remember if any link options or -static
+ were specified on the command line.
+ (process_command): When -fhardened, maybe enable -pie and
+ -Wl,-z,relro,-z,now.
+ * opts.cc (flag_stack_protector_set_by_fhardened_p): New global.
+ (finish_options): When -fhardened, enable
+ -ftrivial-auto-var-init=zero and -fstack-protector-strong.
+ (print_help_hardened): New.
+ (print_help): Call it.
+ * opts.h (flag_stack_protector_set_by_fhardened_p): Declare.
+ * target.def (fortify_source_default_level): New target hook.
+ * targhooks.cc (default_fortify_source_default_level): New.
+ * targhooks.h (default_fortify_source_default_level): Declare.
+ * toplev.cc (process_options): When -fhardened, enable
+ -fstack-clash-protection. If flag_stack_protector_set_by_fhardened_p,
+ do not warn that -fstack-protector not supported for this target.
+ Don't enable -fhardened when !HAVE_FHARDENED_SUPPORT.
+
+2023-11-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm-mve-builtins-functions.h
+ (full_width_access::memory_vector_mode): Add default clause.
+
+2023-11-23 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/112672
+ * config/i386/i386.md (parityhi2):
+ Use temporary register in the call to gen_parityhi2_cmp.
+
+2023-11-23 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/89316
+ * config/i386/i386.cc (ix86_expand_split_stack_prologue): Obtain
+ scratch regno when flag_force_indirect_call is set. On 64-bit
+ targets, call __morestack_large_model when flag_force_indirect_call
+ is set and on 32-bit targets with -fpic, manually expand PIC sequence
+ to call __morestack. Move the function address to an indirect
+ call scratch register.
+
+2023-11-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ PR tree-optimization/112678
+ * tree-profile.cc (tree_profiling): Do not use atomic operations
+ for -fprofile-update=single.
+
+2023-11-23 Juergen Christ <jchrist@linux.ibm.com>
+
+ * config/s390/s390-c.cc (s390_cpu_cpp_builtins): Define
+ __GCC_ASM_FLAG_OUTPUTS__.
+ * config/s390/s390.cc (s390_canonicalize_comparison): More
+ UNSPEC_CC_TO_INT cases.
+ (s390_md_asm_adjust): Implement flags output.
+ * config/s390/s390.md (ccstore4): Allow mask operands.
+ * doc/extend.texi: Document flags output.
+
+2023-11-23 Juergen Christ <jchrist@linux.ibm.com>
+
+ * config/s390/s390.md: Split TImode loads.
+
+2023-11-23 Juergen Christ <jchrist@linux.ibm.com>
+
+ * config/s390/vector.md: (*vec_extract) Fix.
+
+2023-11-23 Di Zhao <dizhao@os.amperecomputing.com>
+
+ * tree-ssa-reassoc.cc (get_reassociation_width): check
+ for loop dependent FMAs.
+ (reassociate_bb): For 3 ops, refine the condition to call
+ swap_ops_for_binary_stmt.
+
+2023-11-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-protos.h (emit_vec_extract): New function.
+ * config/riscv/riscv-v.cc (emit_vec_extract): Ditto.
+ * config/riscv/riscv.cc (riscv_legitimize_move): Refine codes.
+
+2023-11-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112599
+ PR target/112670
+ * config/riscv/riscv-avlprop.cc (alv_can_be_propagated_p): New function.
+ (vlmax_ta_p): Disable vrgather AVL propagation.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112336
+ * expr.cc (EXTEND_BITINT): Don't call reduce_to_bit_field_precision
+ if modifier is EXPAND_INITIALIZER.
+
+2023-11-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-v.cc (emit_vlmax_gather_insn): Refine codes.
+ (emit_vlmax_masked_gather_mu_insn): Ditto.
+ (modulo_sel_indices): Ditto.
+ (expand_vec_perm): Ditto.
+ (shuffle_generic_patterns): Ditto.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * doc/extend.texi (__builtin_stdc_bit_ceil, __builtin_stdc_bit_floor,
+ __builtin_stdc_bit_width, __builtin_stdc_count_ones,
+ __builtin_stdc_count_zeros, __builtin_stdc_first_leading_one,
+ __builtin_stdc_first_leading_zero, __builtin_stdc_first_trailing_one,
+ __builtin_stdc_first_trailing_zero, __builtin_stdc_has_single_bit,
+ __builtin_stdc_leading_ones, __builtin_stdc_leading_zeros,
+ __builtin_stdc_trailing_ones, __builtin_stdc_trailing_zeros): Document.
+
+2023-11-23 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/32667
+ * doc/md.texi (cpymem): Document that exact overlap of source
+ and destination needs to work.
+ * doc/standards.texi (ffreestanding): Mention memcpy is required
+ to handle the exact overlap case.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/110348
+ * doc/invoke.texi (-Wno-c++26-extensions): Document.
+
+2023-11-23 Manolis Tsamis <manolis.tsamis@vrull.eu>
+
+ * ifcvt.cc (noce_convert_multiple_sets_1): Remove old code.
+
+2023-11-23 Pan Li <pan2.li@intel.com>
+
+ PR target/111720
+ * dse.cc (get_stored_val): Allow vector mode if read size is
+ less than or equal to stored size.
+
+2023-11-23 Costas Argyris <costas.argyris@gmail.com>
+
+ * configure.ac: Handle new --enable-win32-utf8-manifest
+ option.
+ * config.host: allow win32 utf8 manifest to be disabled
+ by user.
+ * configure: Regenerate.
+
+2023-11-22 John David Anglin <danglin@gcc.gnu.org>
+
+ PR target/112592
+ * config/pa/pa.h (MAX_FIXED_MODE_SIZE): Define.
+
+2023-11-22 John David Anglin <danglin@gcc.gnu.org>
+
+ PR target/112617
+ * config/pa/predicates.md (integer_store_memory_operand): Return
+ true for REG+D addresses when reload_in_progress is true.
+
+2023-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112344
+ * tree-chrec.cc (chrec_apply): Perform the overall increment
+ calculation and increment in an unsigned type.
+
+2023-11-22 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/gcn-valu.md (*mov<mode>_4reg): Disparage AVGPR use when a
+ reload is required.
+
+2023-11-22 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/112610
+ * ira-costs.cc: (find_costs_and_classes): Remove arg.
+ Use ira_dump_file for printing.
+ (print_allocno_costs, print_pseudo_costs): Ditto.
+ (ira_costs): Adjust call of find_costs_and_classes.
+ (ira_set_pseudo_classes): Set up and restore ira_dump_file.
+
+2023-11-22 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112598
+ * config/riscv/riscv-v.cc (shuffle_compress_patterns): Fix vcompress bug.
+
+2023-11-22 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64-simd.md
+ (aarch64_uaddw<mode>_<PERM_EXTEND:perm_hilo>_zip,
+ aarch64_usubw<mode>_<PERM_EXTEND:perm_hilo>_zip): Split into...
+ (aarch64_uaddw<mode>_lo_zip, aarch64_uaddw<mode>_hi_zip,
+ "aarch64_usubw<mode>_lo_zip, "aarch64_usubw<mode>_hi_zip): ... This.
+ * config/aarch64/iterators.md (PERM_EXTEND, perm_index): Remove.
+ (perm_hilo): Remove UNSPEC_ZIP1, UNSPEC_ZIP2.
+
+2023-11-22 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm-mve-builtins.cc
+ (function_resolver::infer_pointer_type): Remove spurious line.
+
+2023-11-22 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/lsx.md (vec_perm<mode:LSX>): Make the
+ selector VIMODE.
+ * config/loongarch/loongarch.cc (loongarch_expand_vec_perm):
+ Use the mode of the selector (instead of the shuffled vector)
+ for truncating it. Operate on subregs in the selector mode if
+ the shuffled vector has a different mode (i. e. it's a
+ floating-point vector).
+
+2023-11-22 Hongyu Wang <hongyu.wang@intel.com>
+
+ * config/i386/i386.md (push2_di): Adjust operand order for AT&T
+ syntax.
+ (pop2_di): Likewise.
+ (push2p_di): Likewise.
+ (pop2p_di): Likewise.
+
+2023-11-22 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112598
+ * config/riscv/riscv-v.cc (emit_vlmax_gather_insn): Adapt the priority.
+ (shuffle_generic_patterns): Fix permutation indice bug.
+ * config/riscv/vector-iterators.md: Fix VEI16 bug.
+
+2023-11-22 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/sse.md (cbranch<mode>4): Extend to Vector
+ HI/QImode.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ PR target/111815
+ * config/vax/vax.cc (index_term_p): Only accept the index scaler
+ as the RHS operand to ASHIFT.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/predicates.md (order_operator): Remove predicate.
+ * config/riscv/riscv.cc (riscv_rtx_costs): Update accordingly.
+ * config/riscv/riscv.md (*branch<mode>, *mov<GPR:mode><X:mode>cc)
+ (cstore<mode>4): Likewise.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv-protos.h (riscv_expand_float_scc): Add
+ `invert_ptr' parameter.
+ * config/riscv/riscv.cc (riscv_emit_float_compare): Add NE
+ inversion handling.
+ (riscv_expand_float_scc): Pass `invert_ptr' through to
+ `riscv_emit_float_compare'.
+ (riscv_expand_conditional_move): Pass `&invert' to
+ `riscv_expand_float_scc'.
+ * config/riscv/riscv.md (add<mode>cc): Likewise.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_emit_float_compare) <NE>: Handle
+ separately.
+ <EQ, LE, LT, GE, GT>: Return operands supplied as is.
+ (riscv_emit_binary): Call `riscv_emit_binary' directly rather
+ than going through a temporary register for word-mode targets.
+ (riscv_expand_conditional_branch): Canonicalize the comparison
+ if not against constant zero.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/predicates.md (ne_operator): New predicate.
+ * config/riscv/riscv.cc (riscv_insn_cost): Handle branches on a
+ floating-point condition.
+ * config/riscv/riscv.md (@cbranch<mode>4): Rename expander to...
+ (@cbranch<ANYF:mode>4): ... this. Only expand the RTX via
+ `riscv_expand_conditional_branch' for `!signed_order_operator'
+ operators, otherwise let it through.
+ (*cbranch<ANYF:mode>4, *cbranch<ANYF:mode>4): New insns and
+ splitters.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Don't
+ bail out in floating-point conditions.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_float_scc): Suppress the
+ use of SUBREG if the conditional-set target is word-mode.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.md (add<mode>cc): New expander.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/predicates.md (movcc_operand): New predicate.
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Handle
+ generic targets.
+ * config/riscv/riscv.md (mov<mode>cc): Likewise.
+ * config/riscv/riscv.opt (mmovcc): New option.
+ * doc/invoke.texi (Option Summary): Document it.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv-protos.h (riscv_emit_unary): New prototype.
+ * config/riscv/riscv.cc (riscv_emit_unary): New function.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Unify
+ conditional-move handling across all the relevant targets.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Also
+ accept constants for T-Head data input operands.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Also
+ accept constants for T-Head comparison operands.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Remove
+ the check for operand 1 being constant 0 in the Ventana/Zicond
+ case for equality comparisons.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Also
+ invert the condition for GEU and LEU.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_insn_cost): New function.
+ (riscv_max_noce_ifcvt_seq_cost): Likewise.
+ (riscv_noce_conversion_profitable_p): Likewise.
+ (TARGET_INSN_COST): New macro.
+ (TARGET_MAX_NOCE_IFCVT_SEQ_COST): New macro.
+ (TARGET_NOCE_CONVERSION_PROFITABLE_P): New macro.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Remove
+ extraneous variable for EQ vs NE operation selection.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Use
+ `nullptr' rather than 0 to initialize a pointer.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Use
+ `mode0' and `mode1' for `GET_MODE (op0)' and `GET_MODE (op1)'.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_expand_conditional_move): Use
+ `mode' for `GET_MODE (dest)' throughout.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_emit_int_compare): Bail out if
+ NEED_EQ_NE_P but the comparison is neither EQ nor NE.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.md (mov<mode>cc): Move comment on SFB
+ patterns over to...
+ (*mov<GPR:mode><X:mode>cc): ... here.
+
+2023-11-21 Robin Dapp <rdapp@ventanamicro.com>
+
+ PR middle-end/112406
+ * tree-vect-loop.cc (vectorize_fold_left_reduction): Allow
+ reduction index != 1.
+ (vect_transform_reduction): Handle reduction index != 1.
+
+2023-11-21 Richard Sandiford <richard.sandiford@arm.com>
+
+ * common.md (aligned_register_operand): New predicate.
+
+2023-11-21 Richard Sandiford <richard.sandiford@arm.com>
+
+ * ira-int.h (ira_allocno): Add a register_filters field.
+ (ALLOCNO_REGISTER_FILTERS): New macro.
+ (ALLOCNO_SET_REGISTER_FILTERS): Likewise.
+ * ira-build.cc (ira_create_allocno): Initialize register_filters.
+ (create_cap_allocno): Propagate register_filters.
+ (propagate_allocno_info): Likewise.
+ (propagate_some_info_from_allocno): Likewise.
+ * ira-lives.cc (process_register_constraint_filters): New function.
+ (process_bb_node_lives): Use it to record register filter
+ information.
+ * ira-color.cc (assign_hard_reg): Check register filters.
+ (improve_allocation, fast_allocation): Likewise.
+
+2023-11-21 Richard Sandiford <richard.sandiford@arm.com>
+
+ * lra-constraints.cc (process_alt_operands): Check register filters.
+
+2023-11-21 Richard Sandiford <richard.sandiford@arm.com>
+
+ * recog.h (operand_alternative): Add a register_filters field.
+ (alternative_register_filters): New function.
+ * recog.cc (preprocess_constraints): Calculate the filters field.
+ (constrain_operands): Check register filters.
+
+2023-11-21 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl.def (DEFINE_REGISTER_CONSTRAINT): Add an optional filter
+ operand.
+ * doc/md.texi (define_register_constraint): Document it.
+ * doc/tm.texi.in: Reference it in discussion about aligned registers.
+ * doc/tm.texi: Regenerate.
+ * gensupport.h (register_filters, get_register_filter_id): Declare.
+ * gensupport.cc (register_filter_map, register_filters): New variables.
+ (get_register_filter_id): New function.
+ (process_define_register_constraint): Likewise.
+ (process_rtx): Pass define_register_constraints to
+ process_define_register_constraint.
+ * genconfig.cc (main): Emit a definition of NUM_REGISTER_FILTERS.
+ * genpreds.cc (constraint_data): Add a filter field.
+ (add_constraint): Update accordingly.
+ (process_define_register_constraint): Pass the filter operand.
+ (write_init_reg_class_start_regs): New function.
+ (write_get_register_filter): Likewise.
+ (write_get_register_filter_id): Likewise.
+ (write_tm_preds_h): Write a definition of target_constraints,
+ plus helpers to test its contents. Write the get_register_filter*
+ functions.
+ (write_insn_preds_c): Write init_reg_class_start_regs.
+ * reginfo.cc (init_reg_class_start_regs): Declare.
+ (init_reg_sets): Call it.
+ * target-globals.h (this_target_constraints): Declare.
+ (target_globals): Add a constraints field.
+ (restore_target_globals): Update accordingly.
+ * target-globals.cc: Include tm_p.h.
+ (default_target_globals): Initialize the constraints field.
+ (save_target_globals): Handle the constraints field.
+ (target_globals::~target_globals): Likewise.
+
+2023-11-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112623
+ * tree-ssa-forwprop.cc (simplify_vector_constructor):
+ Check the source mode of the insn for vector pack/unpacks.
+
+2023-11-21 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-loop.cc (vect_analyze_loop_2): Move check
+ of VF against max_vf until VF is final.
+
+2023-11-21 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112598
+ * config/riscv/riscv.cc (riscv_const_insns): Disallow DI CONST_VECTOR on RV32.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_override_options): Rework warnings.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/111370
+ * config/aarch64/aarch64-arches.def (armv9-a, armv9.1-a, armv9.2-a,
+ armv9.3-a): Update to generic-armv9-a.
+ * config/aarch64/aarch64-cores.def (generic-armv9-a): New.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * config/aarch64/aarch64.cc: Include generic_armv9_a.h.
+ * config/aarch64/tuning_models/generic_armv9_a.h: New file.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/111370
+ * config/aarch64/aarch64-arches.def (armv8-9, armv8-a, armv8.1-a,
+ armv8.2-a, armv8.3-a, armv8.4-a, armv8.5-a, armv8.6-a, armv8.7-a,
+ armv8.8-a): Update to generic_armv8_a.
+ * config/aarch64/aarch64-cores.def (generic-armv8-a): New.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * config/aarch64/aarch64.cc: Include generic_armv8_a.h
+ * config/aarch64/aarch64.h (TARGET_CPU_DEFAULT): Change to
+ TARGET_CPU_generic_armv8_a.
+ * config/aarch64/tuning_models/generic_armv8_a.h: New file.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/111370
+ * config/aarch64/aarch64-cores.def: Add generic.
+ * config/aarch64/aarch64-opts.h (enum aarch64_proc): Remove generic.
+ * config/aarch64/aarch64-tune.md: Regenerate
+ * config/aarch64/aarch64.cc (all_cores): Remove generic
+ * config/aarch64/aarch64.h (enum target_cpus): Remove
+ TARGET_CPU_generic.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/111370
+ * config/aarch64/aarch64.cc (generic_addrcost_table,
+ exynosm1_addrcost_table,
+ xgene1_addrcost_table,
+ thunderx2t99_addrcost_table,
+ thunderx3t110_addrcost_table,
+ tsv110_addrcost_table,
+ qdf24xx_addrcost_table,
+ a64fx_addrcost_table,
+ neoversev1_addrcost_table,
+ neoversen2_addrcost_table,
+ neoversev2_addrcost_table,
+ generic_regmove_cost,
+ cortexa57_regmove_cost,
+ cortexa53_regmove_cost,
+ exynosm1_regmove_cost,
+ thunderx_regmove_cost,
+ xgene1_regmove_cost,
+ qdf24xx_regmove_cost,
+ thunderx2t99_regmove_cost,
+ thunderx3t110_regmove_cost,
+ tsv110_regmove_cost,
+ a64fx_regmove_cost,
+ neoversen2_regmove_cost,
+ neoversev1_regmove_cost,
+ neoversev2_regmove_cost,
+ generic_vector_cost,
+ a64fx_vector_cost,
+ qdf24xx_vector_cost,
+ thunderx_vector_cost,
+ tsv110_vector_cost,
+ cortexa57_vector_cost,
+ exynosm1_vector_cost,
+ xgene1_vector_cost,
+ thunderx2t99_vector_cost,
+ thunderx3t110_vector_cost,
+ ampere1_vector_cost,
+ generic_branch_cost,
+ generic_tunings,
+ cortexa35_tunings,
+ cortexa53_tunings,
+ cortexa57_tunings,
+ cortexa72_tunings,
+ cortexa73_tunings,
+ exynosm1_tunings,
+ thunderxt88_tunings,
+ thunderx_tunings,
+ tsv110_tunings,
+ xgene1_tunings,
+ emag_tunings,
+ qdf24xx_tunings,
+ saphira_tunings,
+ thunderx2t99_tunings,
+ thunderx3t110_tunings,
+ neoversen1_tunings,
+ ampere1_tunings,
+ ampere1a_tunings,
+ neoversev1_vector_cost,
+ neoversev1_tunings,
+ neoverse512tvb_vector_cost,
+ neoverse512tvb_tunings,
+ neoversen2_vector_cost,
+ neoversen2_tunings,
+ neoversev2_vector_cost,
+ neoversev2_tunings
+ a64fx_tunings): Split into own files.
+ * config/aarch64/tuning_models/a64fx.h: New file.
+ * config/aarch64/tuning_models/ampere1.h: New file.
+ * config/aarch64/tuning_models/ampere1a.h: New file.
+ * config/aarch64/tuning_models/cortexa35.h: New file.
+ * config/aarch64/tuning_models/cortexa53.h: New file.
+ * config/aarch64/tuning_models/cortexa57.h: New file.
+ * config/aarch64/tuning_models/cortexa72.h: New file.
+ * config/aarch64/tuning_models/cortexa73.h: New file.
+ * config/aarch64/tuning_models/emag.h: New file.
+ * config/aarch64/tuning_models/exynosm1.h: New file.
+ * config/aarch64/tuning_models/generic.h: New file.
+ * config/aarch64/tuning_models/neoverse512tvb.h: New file.
+ * config/aarch64/tuning_models/neoversen1.h: New file.
+ * config/aarch64/tuning_models/neoversen2.h: New file.
+ * config/aarch64/tuning_models/neoversev1.h: New file.
+ * config/aarch64/tuning_models/neoversev2.h: New file.
+ * config/aarch64/tuning_models/qdf24xx.h: New file.
+ * config/aarch64/tuning_models/saphira.h: New file.
+ * config/aarch64/tuning_models/thunderx.h: New file.
+ * config/aarch64/tuning_models/thunderx2t99.h: New file.
+ * config/aarch64/tuning_models/thunderx3t110.h: New file.
+ * config/aarch64/tuning_models/thunderxt88.h: New file.
+ * config/aarch64/tuning_models/tsv110.h: New file.
+ * config/aarch64/tuning_models/xgene1.h: New file.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64-simd.md (vec_unpack<su>_lo_<mode,
+ vec_unpack<su>_lo_<mode): Split into...
+ (vec_unpacku_lo_<mode, vec_unpacks_lo_<mode,
+ vec_unpacku_lo_<mode, vec_unpacks_lo_<mode): ...These.
+ (aarch64_usubw<mode>_<PERM_EXTEND:perm_hilo>_zip): New.
+ (aarch64_uaddw<mode>_<PERM_EXTEND:perm_hilo>_zip): New.
+ * config/aarch64/iterators.md (PERM_EXTEND, perm_index): New.
+ (perm_hilo): Add UNSPEC_ZIP1, UNSPEC_ZIP2.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_adjust_stmt_cost): Guard mla.
+ (aarch64_vector_costs::count_ops): Likewise.
+
+2023-11-21 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ PR middle-end/112634
+ * tree-profile.cc (gen_assign_counter_update): Cast the unsigned result type of
+ __atomic_add_fetch() to the signed counter type.
+ (gen_counter_update): Fix formatting.
+
+2023-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-profile.cc (gen_counter_update, tree_profiling): Formatting
+ fixes.
+
+2023-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112639
+ * builtins.cc (fold_builtin_bit_query): If arg0 has side-effects, arg1
+ is specified but cleared, call save_expr on arg0.
+
+2023-11-21 Hongyu Wang <hongyu.wang@intel.com>
+
+ * config/i386/i386-expand.h (gen_push): Add default bool
+ parameter.
+ (gen_pop): Likewise.
+ * config/i386/i386-opts.h (enum apx_features): Add apx_ppx, add
+ it to apx_all.
+ * config/i386/i386.cc (ix86_emit_restore_reg_using_pop): Add
+ ppx_p parameter for function declaration.
+ (gen_push2): Add ppx_p parameter, emit push2p if ppx_p is true.
+ (gen_push): Likewise.
+ (ix86_emit_restore_reg_using_pop2): Likewise for pop2p.
+ (ix86_emit_save_regs): Emit pushp/push2p under TARGET_APX_PPX.
+ (ix86_emit_restore_reg_using_pop): Add ppx_p, emit popp insn
+ and adjust cfi when ppx_p is ture.
+ (ix86_emit_restore_reg_using_pop2): Add ppx_p and parse to its
+ callee.
+ (ix86_emit_restore_regs_using_pop2): Likewise.
+ (ix86_expand_epilogue): Parse TARGET_APX_PPX to
+ ix86_emit_restore_reg_using_pop.
+ * config/i386/i386.h (TARGET_APX_PPX): New.
+ * config/i386/i386.md (UNSPEC_APX_PPX): New unspec.
+ (pushp_di): New define_insn.
+ (popp_di): Likewise.
+ (push2p_di): Likewise.
+ (pop2p_di): Likewise.
+ * config/i386/i386.opt: Add apx_ppx enum.
+
+2023-11-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/111970
+ * tree-vect-stmts.cc (vectorizable_load): Fix offset calculation
+ for SLP gather load.
+ (vectorizable_store): Likewise for SLP scatter store.
+
+2023-11-21 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch-def.h (stdint.h): Guard with #if to
+ exclude it for target libraries.
+ (loongarch_isa_base_features): Likewise.
+ (loongarch_isa): Likewise.
+ (loongarch_abi): Likewise.
+ (loongarch_target): Likewise.
+ (loongarch_cpu_default_isa): Likewise.
+
+2023-11-21 liuhongt <hongtao.liu@intel.com>
+
+ PR target/112325
+ * config/i386/i386-expand.cc (emit_reduc_half): Hanlde
+ V8QImode.
+ * config/i386/mmx.md (reduc_<code>_scal_<mode>): New expander.
+ (reduc_<code>_scal_v4qi): Ditto.
+
+2023-11-20 Marc Poulhiès <dkm@kataplop.net>
+
+ * config/nvptx/nvptx.h (struct machine_function): Fix typo in variadic.
+ * config/nvptx/nvptx.cc (nvptx_function_arg_advance): Adjust to use fixed name.
+ (nvptx_declare_function_name): Likewise.
+ (nvptx_call_args): Likewise.
+ (nvptx_expand_call): Likewise.
+
+2023-11-20 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * tree-profile.cc (gen_counter_update): Use unshare_expr() for the
+ counter expression in the second gimple_build_assign().
+
+2023-11-20 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.cc (add_detected_attribute_1): New function.
+ (cgraph_node::add_detected_attribute): Likewise.
+ * cgraph.h (cgraph_node::add_detected_attribute): Declare.
+ * common.opt: Add -Wsuggest-attribute=returns_nonnull.
+ * doc/invoke.texi: Document new flag.
+ * gimple-range-fold.cc (fold_using_range::range_of_call):
+ Use known reutrn value ranges.
+ * ipa-prop.cc (struct ipa_return_value_summary): New type.
+ (class ipa_return_value_sum_t): New type.
+ (ipa_return_value_sum): New summary.
+ (ipa_record_return_value_range): New function.
+ (ipa_return_value_range): New function.
+ * ipa-prop.h (ipa_return_value_range): Declare.
+ (ipa_record_return_value_range): Declare.
+ * ipa-pure-const.cc (warn_function_returns_nonnull): New funcion.
+ * ipa-utils.h (warn_function_returns_nonnull): Declare.
+ * symbol-summary.h: Fix comment.
+ * tree-vrp.cc (execute_ranger_vrp): Record return values.
+
+2023-11-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112618
+ * tree-vect-loop.cc (vect_transform_loop_stmt): For not
+ relevant and unused .MASK_CALL make sure we remove the
+ scalar stmt.
+
+2023-11-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112281
+ * tree-loop-distribution.cc
+ (loop_distribution::pg_add_dependence_edges): For = in the
+ innermost common loop record a partition conflict.
+
+2023-11-20 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/112622
+ * convert.cc (convert_to_real_1): Use element_precision
+ where a vector type might appear. Provide specific
+ diagnostic for unexpected vector argument.
+
+2023-11-20 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112597
+ * config/riscv/vector-iterators.md: Remove VDEMOTE and VMDEMOTE.
+ * config/riscv/vector.md: Fix slide1 intermediate mode bug.
+
+2023-11-20 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/riscv-v.cc (gather_scatter_valid_offset_mode_p):
+ Add check for XLEN == 32.
+ * config/riscv/vector-iterators.md: Change VLS part of the
+ demote iterator to 2x elements modes
+ * config/riscv/vector.md: Adjust iterators and insn conditions.
+
+2023-11-20 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm-mve-builtins-base.cc (vld1_impl, vld1q)
+ (vst1_impl, vst1q): New.
+ * config/arm/arm-mve-builtins-base.def (vld1q, vst1q): New.
+ * config/arm/arm-mve-builtins-base.h (vld1q, vst1q): New.
+ * config/arm/arm_mve.h
+ (vld1q): Delete.
+ (vst1q): Delete.
+ (vld1q_s8): Delete.
+ (vld1q_s32): Delete.
+ (vld1q_s16): Delete.
+ (vld1q_u8): Delete.
+ (vld1q_u32): Delete.
+ (vld1q_u16): Delete.
+ (vld1q_f32): Delete.
+ (vld1q_f16): Delete.
+ (vst1q_f32): Delete.
+ (vst1q_f16): Delete.
+ (vst1q_s8): Delete.
+ (vst1q_s32): Delete.
+ (vst1q_s16): Delete.
+ (vst1q_u8): Delete.
+ (vst1q_u32): Delete.
+ (vst1q_u16): Delete.
+ (__arm_vld1q_s8): Delete.
+ (__arm_vld1q_s32): Delete.
+ (__arm_vld1q_s16): Delete.
+ (__arm_vld1q_u8): Delete.
+ (__arm_vld1q_u32): Delete.
+ (__arm_vld1q_u16): Delete.
+ (__arm_vst1q_s8): Delete.
+ (__arm_vst1q_s32): Delete.
+ (__arm_vst1q_s16): Delete.
+ (__arm_vst1q_u8): Delete.
+ (__arm_vst1q_u32): Delete.
+ (__arm_vst1q_u16): Delete.
+ (__arm_vld1q_f32): Delete.
+ (__arm_vld1q_f16): Delete.
+ (__arm_vst1q_f32): Delete.
+ (__arm_vst1q_f16): Delete.
+ (__arm_vld1q): Delete.
+ (__arm_vst1q): Delete.
+ * config/arm/mve.md (mve_vld1q_f<mode>): Rename into ...
+ (@mve_vld1q_f<mode>): ... this.
+ (mve_vld1q_<supf><mode>): Rename into ...
+ (@mve_vld1q_<supf><mode>) ... this.
+ (mve_vst1q_f<mode>): Rename into ...
+ (@mve_vst1q_f<mode>): ... this.
+ (mve_vst1q_<supf><mode>): Rename into ...
+ (@mve_vst1q_<supf><mode>) ... this.
+
+2023-11-20 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm-mve-builtins-shapes.cc (load, store): New.
+ * config/arm/arm-mve-builtins-shapes.h (load, store): New.
+
+2023-11-20 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm-mve-builtins-functions.h (multi_vector_function)
+ (full_width_access): New classes.
+ * config/arm/arm-mve-builtins.cc
+ (find_type_suffix_for_scalar_type, infer_pointer_type)
+ (require_pointer_type, get_contiguous_base, add_mem_operand)
+ (add_fixed_operand, use_contiguous_load_insn)
+ (use_contiguous_store_insn): New.
+ * config/arm/arm-mve-builtins.h (memory_vector_mode)
+ (infer_pointer_type, require_pointer_type, get_contiguous_base)
+ (add_mem_operand)
+ (add_fixed_operand, use_contiguous_load_insn)
+ (use_contiguous_store_insn): New.
+
+2023-11-20 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm-mve-builtins-shapes.cc (build_const_pointer):
+ New.
+ (parse_type): Add support for '_', 'al' and 'as'.
+ * config/arm/arm-mve-builtins.h (function_instance): Add
+ memory_scalar_type.
+ (function_base): Likewise.
+
+2023-11-20 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm-builtins.cc (arm_init_simd_builtin_types): Fix
+ initialization of arm_simd_types[].eltype.
+ * config/arm/arm-mve-builtins.def (DEF_MVE_TYPE): Fix scalar
+ types.
+
+2023-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ * typeclass.h (enum type_class): Add vector_type_class.
+ * builtins.cc (type_to_class): Return vector_type_class for
+ VECTOR_TYPE.
+ * doc/extend.texi (__builtin_classify_type): Mention bit-precise
+ integer types and vector types.
+
+2023-11-20 Robin Dapp <rdapp@ventanamicro.com>
+
+ PR middle-end/112406
+ * tree-vect-patterns.cc (vect_recog_mask_conversion_pattern):
+ Convert masks for conditional operations as well.
+
+2023-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/90693
+ * tree-ssa-math-opts.cc (match_single_bit_test): Mark POPCOUNT with
+ result only used in equality comparison against 1 with direct optab
+ support as .POPCOUNT call with 2 arguments.
+ * internal-fn.h (expand_POPCOUNT): Declare.
+ * internal-fn.def (DEF_INTERNAL_INT_EXT_FN): New macro, document it,
+ undefine at the end.
+ (POPCOUNT): Use it instead of DEF_INTERNAL_INT_FN.
+ * internal-fn.cc (DEF_INTERNAL_INT_EXT_FN): Define to nothing before
+ inclusion to define expanders.
+ (expand_POPCOUNT): New function.
+
+2023-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/90693
+ * tree-ssa-math-opts.cc (match_single_bit_test): New function.
+ (math_opts_dom_walker::after_dom_children): Call it for EQ_EXPR
+ and NE_EXPR assignments and GIMPLE_CONDs.
+
+2023-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ * internal-fn.def: Document missing DEF_INTERNAL* macros and make sure
+ they are all undefined at the end.
+ * internal-fn.cc (lookup_hilo_internal_fn, lookup_evenodd_internal_fn,
+ widening_fn_p, get_len_internal_fn): Don't undef DEF_INTERNAL_*FN
+ macros after inclusion of internal-fn.def.
+
+2023-11-20 Haochen Jiang <haochen.jiang@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_available_features):
+ Add avx10_set and version and detect avx10.1.
+ (cpu_indicator_init): Handle avx10.1-512.
+ * common/config/i386/i386-common.cc
+ (OPTION_MASK_ISA2_AVX10_1_256_SET): New.
+ (OPTION_MASK_ISA2_AVX10_1_256_SET): Ditto.
+ (OPTION_MASK_ISA2_AVX10_1_512_UNSET): Ditto.
+ (OPTION_MASK_ISA2_AVX10_1_512_UNSET): Ditto.
+ (OPTION_MASK_ISA2_AVX2_UNSET): Modify for AVX10.1.
+ (ix86_handle_option): Handle -mavx10.1-256 and -mavx10.1-512.
+ Add indicator for explicit no-avx512 and no-avx10.1 options.
+ * common/config/i386/i386-cpuinfo.h (enum processor_features):
+ Add FEATURE_AVX10_1_256 and FEATURE_AVX10_1_512.
+ * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for
+ AVX10_1_256 and AVX10_1_512.
+ * config/i386/cpuid.h (bit_AVX10): New.
+ (bit_AVX10_256): Ditto.
+ (bit_AVX10_512): Ditto.
+ * config/i386/driver-i386.cc (check_avx10_avx512_features): New.
+ (host_detect_local_cpu): Do not append "-mno-" options under
+ specific scenarios to avoid emitting a warning.
+ * config/i386/i386-isa.def
+ (EVEX512): Add DEF_PTA(EVEX512).
+ (AVX10_1_256): Add DEF_PTA(AVX10_1_256).
+ (AVX10_1_512): Add DEF_PTA(AVX10_1_512).
+ * config/i386/i386-options.cc (isa2_opts): Add -mavx10.1-256 and
+ -mavx10.1-512.
+ (ix86_function_specific_save): Save explicit no indicator.
+ (ix86_function_specific_restore): Restore explicit no indicator.
+ (ix86_valid_target_attribute_inner_p): Handle avx10.1, avx10.1-256 and
+ avx10.1-512.
+ (ix86_valid_target_attribute_tree): Handle avx512 function
+ attributes with avx10.1 command line option.
+ (ix86_option_override_internal): Handle AVX10.1 options.
+ * config/i386/i386.h: Add PTA_EVEX512 for AVX512 target
+ machines.
+ * config/i386/i386.opt: Add variable ix86_no_avx512_explicit and
+ ix86_no_avx10_1_explicit, option -mavx10.1, -mavx10.1-256 and
+ -mavx10.1-512.
+ * doc/extend.texi: Document avx10.1, avx10.1-256 and avx10.1-512.
+ * doc/invoke.texi: Document -mavx10.1, -mavx10.1-256 and -mavx10.1-512.
+ * doc/sourcebuild.texi: Document target avx10.1, avx10.1-256
+ and avx10.1-512.
+
+2023-11-20 liuhongt <hongtao.liu@intel.com>
+
+ PR target/112325
+ * config/i386/sse.md (reduc_<code>_scal_<mode>): New expander.
+ (REDUC_ANY_LOGIC_MODE): New iterator.
+ (REDUC_PLUS_MODE): Extend to VxHI/SI/DImode.
+ (REDUC_SSE_PLUS_MODE): Ditto.
+
+2023-11-20 xuli <xuli1@eswincomputing.com>
+
+ PR target/112537
+ * config/riscv/riscv-opts.h (enum riscv_stringop_strategy_enum): Strategy enum.
+ * config/riscv/riscv-string.cc (riscv_expand_block_move): Disabled based on options.
+ (expand_block_move): Ditto.
+ * config/riscv/riscv.opt: Add -mmemcpy-strategy=.
+
+2023-11-20 Lulu Cheng <chenglulu@loongson.cn>
+
+ * config/loongarch/gnu-user.h (MUSL_ABI_SPEC): Modify suffix.
+
+2023-11-19 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-v.cc (emit_vlmax_insn_lra): Optimize constant AVL.
+
+2023-11-19 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv-protos.h (extract_base_offset_in_addr): Prototype.
+ * config/riscv/riscv.cc (riscv_fusion_pairs): New enum.
+ (riscv_tune_param): Add fusible_ops field.
+ (riscv_tune_param_rocket_tune_info): Initialize new field.
+ (riscv_tune_param_sifive_7_tune_info): Likewise.
+ (thead_c906_tune_info): Likewise.
+ (generic_oo_tune_info): Likewise.
+ (optimize_size_tune_info): Likewise.
+ (riscv_macro_fusion_p): New function.
+ (riscv_fusion_enabled_p): Likewise.
+ (riscv_macro_fusion_pair_p): Likewise.
+ (TARGET_SCHED_MACRO_FUSION_P): Define.
+ (TARGET_SCHED_MACRO_FUSION_PAIR_P): Likewise.
+ (extract_base_offset_in_addr): Moved into riscv.cc from...
+ * config/riscv/thead.cc: Here.
+ Co-authored-by: Raphael Zinsly <rzinsly@ventanamicro.com>
+ Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
+
+2023-11-19 Jeff Law <jlaw@ventanamicro.com>
+
+ * config/c6x/c6x.md (mvilc): Add mode to UNSPEC source.
+ * config/mips/mips.md (rdhwr_synci_step_<mode>): Likewise.
+ * config/riscv/riscv.md (riscv_frcsr, riscv_frflags): Likewise.
+ * config/s390/s390.md (@split_stack_call<mode>): Likewise.
+ (@split_stack_cond_call<mode>): Likewise.
+ * config/sh/sh.md (sp_switch_1): Likewise.
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic.h: Include "rich-location.h".
+ * edit-context.h (class fixit_hint): New forward decl.
+ * gcc-rich-location.h: Include "rich-location.h".
+ * genmatch.cc: Likewise.
+ * pretty-print.h: Likewise.
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (CPPLIB_H): Add libcpp/include/rich-location.h.
+ * coretypes.h (class rich_location): New forward decl.
+
+2023-11-19 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-v.cc (expand_tuple_move): Fix bug.
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107573
+ * doc/invoke.texi: Add -Wanalyzer-undefined-behavior-strtok.
+
2023-11-18 Xi Ruoyao <xry111@xry111.site>
* config/loongarch/predicates.md (const_call_insn_operand):
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 6ce2b65..2d1ad39 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20231119
+20231127
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 45c3f37..6fb7510 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,190 @@
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.cc (Loop_Statement_to_gnu): Always use the
+ simpler form for a loop with a boolean iteration variable.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Subtype>: Put
+ the alignment directly on the type in the constrained case too.
+ * gcc-interface/utils.cc (maybe_pad_type): For an array type, take
+ the alignment of the element type as the original alignment.
+
+2023-11-21 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_aggr.adb (Resolve_Container_Aggregate): In the case where Comp
+ is an N_Iterated_Component_Association, pick up Discrete_Choices rather
+ than Choices.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch7.adb (Build_Finalizer): For package specs and bodies, push
+ and pop the specs onto the scope stack only once.
+ * inline.adb (Cleanup_Scopes): Call Pop_Scope instead of End_Scope.
+
+2023-11-21 Steve Baird <baird@adacore.com>
+
+ * sem_aggr.adb (Resolve_Delta_Array_Aggregate): In the case of a
+ deep delta choice, the expected type for the expression will
+ typically not be the component type of the array type, so a call
+ to Analyze_And_Resolve that assumes otherwise would be an error.
+ It turns out that such a call, while wrong, is usually harmless
+ because the expression has already been marked as analyzed. This
+ doesn't work if the aggregate occurs in a postcondition and, in
+ any case, we don't want to rely on this. So do not perform the
+ call in the deep case.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_warn.adb (Check_References.Type_OK_For_No_Value_Assigned):
+ New predicate.
+ (Check_References): For Warn_On_No_Value_Assigned, use the same test
+ on the type in the address-not-taken and default cases.
+
+2023-11-21 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_ch5.adb (Expand_Iterator_Loop_Over_Container): Retrieve the
+ iteration type's iteration interface progenitor via
+ Iterator_Interface_Ancestor, in the case of both "in" and "of"
+ iterators. Narrow the scope of Pack, so it's declared and
+ initialized only within the code related to "of" iterators, and
+ change its name to Cont_Type_Pack. Adjust comments.
+ * sem_ch5.adb (Get_Cursor_Type): In the case of a derived type,
+ retrieve the iteration type's iterator interface progenitor (if it
+ exists) via Iterator_Interface_Ancestor rather than assuming that
+ the parent type is the interface progenitor.
+ * sem_util.ads (Iterator_Interface_Ancestor): New function.
+ * sem_util.adb (Iterator_Interface_Ancestor): New function
+ returning a type's associated iterator interface type, if any, by
+ collecting and traversing the type's interfaces.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_attr.adb (Resolve_Attribute) <Attribute_Address>: Remove the
+ bypass for prefixes with task type.
+
+2023-11-21 Viljar Indus <indus@adacore.com>
+
+ * par.adb: Restore Style_Checks after parsing each unit.
+
+2023-11-21 Yannick Moy <moy@adacore.com>
+
+ * exp_spark.adb (Expand_SPARK_Delta_Or_Aggregate): Fix type.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Analyze_Package_Instantiation): Test Expander_Active
+ to detect generic contexts for the generation of cleanup actions.
+
+2023-11-21 Justin Squirek <squirek@adacore.com>
+
+ * libgnat/g-catiio.adb (Value): Modify conditionals to use 'Last
+ instead of 'Length
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_util.adb (Null_Status): Deal with unchecked type conversions.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_aggr.adb (Convert_To_Assignments): Do not treat initialization
+ procedures specially when it comes to creating a transient scope.
+ * exp_ch7.adb (Build_Finalizer.Process_Declarations): Likewise.
+ * exp_util.adb (Requires_Cleanup_Actions): Likewise.
+
+2023-11-21 Doug Rupp <rupp@adacore.com>
+
+ * s-oscons-tmplt.c: #define CLOCK_RT_Ada "CLOCK_MONOTONIC" for
+ __vxworks
+
+2023-11-21 Steve Baird <baird@adacore.com>
+
+ * sem_aggr.adb: Replace "not Present (...)" call with "No (...)" call.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gen_il-fields.ads (Opt_Field_Enum): Remove Is_Finalization_Wrapper
+ * gen_il-gen-gen_nodes.adb (N_Block_Statement): Likewise.
+ * sinfo.ads (Is_Finalization_Wrapper): Delete.
+ * exp_ch7.adb (Build_Finalizer.Process_Declarations): Adjust comment
+ and remove obsolete code testing the Is_Finalization_Wrapper flag.
+ * exp_util.adb (Requires_Cleanup_Actions): Likewise.
+
+2023-11-21 Doug Rupp <rupp@adacore.com>
+
+ * libgnat/libada.gpr: Revise section 1
+
+2023-11-21 Steve Baird <baird@adacore.com>
+
+ * par.adb: Add new Boolean variable Inside_Delta_Aggregate.
+ * par-ch4.adb (P_Simple_Expression): Add support for a deep delta
+ aggregate choice. We turn a sequence of selectors into a peculiar
+ tree. We build a component (Indexed or Selected) whose prefix is
+ another such component, etc. The leftmost prefix at the bottom of
+ the tree has a "name" which is the first selector, without any
+ further prefix. For something like "with delta (1)(2) => 3" where
+ the type of the aggregate is an array of arrays of integers, we'll
+ build an N_Indexed_Component whose prefix is an integer literal 1.
+ This is consistent with the trees built for "regular"
+ (Ada-defined) delta aggregates.
+ * sem_aggr.adb (Is_Deep_Choice, Is_Root_Prefix_Of_Deep_Choice):
+ New queries.
+ (Resolve_Deep_Delta_Assoc): new procedure.
+ (Resolve_Delta_Array_Aggregate): call Resolve_Deep_Delta_Assoc in
+ deep case.
+ (Resolve_Delta_Record_Aggregate): call Resolve_Deep_Delta_Assoc in
+ deep case.
+ (Get_Component_Type): new function replaces old Get_Component
+ function.
+ * sem_aggr.ads (Is_Deep_Choice, Is_Root_Prefix_Of_Deep_Choice):
+ New queries.
+ * exp_aggr.adb (Expand_Delta_Array_Aggregate): add nested function
+ Make_Array_Delta_Assignment_LHS; call it instead of
+ Make_Indexed_Component.
+ (Expand_Delta_Record_Aggregate): add nested function
+ Make_Record_Delta_Assignment_LHS; call it instead of
+ Make_Selected_Component.
+ * exp_spark.adb (Expand_SPARK_Delta_Or_Update): Insert range
+ checks for indexes in deep delta aggregates.
+
+2023-11-21 Ronan Desplanques <desplanques@adacore.com>
+
+ * adaint.c (__gnat_unlink): Add new parameter and fix text
+ conversion on Windows. Remove unnecessary curly braces.
+ * adaint.h (__gnat_unlink): Add new parameter.
+ * libgnat/i-cstrea.ads (unlink): Adapt to __gnat_unlink signature
+ change.
+ * libgnat/i-cstrea.adb (unlink): New Subprogram definition.
+ * libgnat/s-crtl.ads (unlink): Adapt to __gnat_unlink signature
+ change.
+ * libgnat/s-fileio.adb (Delete): Pass encoding argument to unlink.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Save_Global_References.Set_Global_Type): Beef up
+ comment about the setting of the full view.
+ * sem_res.adb (Resolve_Actuals.Insert_Default): Add another bypass
+ for the case of a generic context.
+
+2023-11-21 Marc Poulhiès <poulhies@adacore.com>
+
+ * doc/gnat_ugn/the_gnat_compilation_model.rst: Move index
+ directives.
+ * gnat_ugn.texi: Regenerate.
+
+2023-11-21 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * par_sco.adb (Process_Decisions)<Process_Node>: Skip aspect
+ specifications.
+
+2023-11-21 Ronan Desplanques <desplanques@adacore.com>
+
+ * libgnat/libgnat_common.gpr: Unconditionally pass -gnatg.
+
+2023-11-21 Marc Poulhiès <poulhies@adacore.com>
+
+ * exp_util.ads: Typo fix.
+
2023-11-16 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.cc (gnat_to_gnu_subprog_type): Also create a
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index bb4ed26..4ab9565 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -747,15 +747,19 @@ __gnat_os_filename (char *filename ATTRIBUTE_UNUSED,
/* Delete a file. */
int
-__gnat_unlink (char *path)
+__gnat_unlink (char *path, int encoding ATTRIBUTE_UNUSED)
{
#if defined (__MINGW32__) && ! defined (__vxworks) && ! defined (IS_CROSS)
- {
- TCHAR wpath[GNAT_MAX_PATH_LEN];
+ TCHAR wpath[GNAT_MAX_PATH_LEN];
+ if (encoding == Encoding_Unspecified)
S2WSC (wpath, path, GNAT_MAX_PATH_LEN);
- return _tunlink (wpath);
- }
+ else if (encoding == Encoding_UTF8)
+ S2WSU (wpath, path, GNAT_MAX_PATH_LEN);
+ else
+ S2WS (wpath, path, GNAT_MAX_PATH_LEN);
+
+ return _tunlink (wpath);
#else
return unlink (path);
#endif
diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
index 987432c..298ea9e 100644
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -172,7 +172,7 @@ extern int __gnat_open_new_temp (char *, int);
extern int __gnat_mkdir (char *, int);
extern int __gnat_stat (char *,
GNAT_STRUCT_STAT *);
-extern int __gnat_unlink (char *);
+extern int __gnat_unlink (char *, int encoding);
extern int __gnat_rename (char *, char *);
extern int __gnat_chdir (char *);
extern int __gnat_rmdir (char *);
diff --git a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
index ed24fed..fd15459 100644
--- a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
+++ b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
@@ -226,9 +226,9 @@ possible encoding schemes:
``16#A345#``.
This scheme is compatible with use of the full Wide_Character set.
-*Upper-Half Coding*
- .. index:: Upper-Half Coding
+.. index:: Upper-Half Coding
+*Upper-Half Coding*
The wide character with encoding ``16#abcd#`` where the upper bit is on
(in other words, 'a' is in the range 8-F) is represented as two bytes,
``16#ab#`` and ``16#cd#``. The second byte cannot be a format control
@@ -236,9 +236,9 @@ possible encoding schemes:
be also used for shift-JIS or EUC, where the internal coding matches the
external coding.
-*Shift JIS Coding*
- .. index:: Shift JIS Coding
+.. index:: Shift JIS Coding
+*Shift JIS Coding*
A wide character is represented by a two-character sequence,
``16#ab#`` and
``16#cd#``, with the restrictions described for upper-half encoding as
@@ -247,10 +247,9 @@ possible encoding schemes:
conversion. Only characters defined in the JIS code set table can be
used with this encoding method.
+.. index:: EUC Coding
*EUC Coding*
- .. index:: EUC Coding
-
A wide character is represented by a two-character sequence
``16#ab#`` and
``16#cd#``, with both characters being in the upper half. The internal
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 319254d..691430a 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -4294,15 +4294,9 @@ package body Exp_Aggr is
return;
end if;
- -- Otherwise, if a transient scope is required, create it now. If we
- -- are within an initialization procedure do not create such, because
- -- the target of the assignment must not be declared within a local
- -- block, and because cleanup will take place on return from the
- -- initialization procedure.
+ -- Otherwise, if a transient scope is required, create it now
- -- Should the condition be more restrictive ???
-
- if Requires_Transient_Scope (Typ) and then not Inside_Init_Proc then
+ if Requires_Transient_Scope (Typ) then
Establish_Transient_Scope (N, Manage_Sec_Stack => False);
end if;
@@ -5243,7 +5237,7 @@ package body Exp_Aggr is
-- The bounds of the aggregate for this dimension
Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
- -- The index type for this dimension.xxx
+ -- The index type for this dimension.
Cond : Node_Id;
Assoc : Node_Id;
@@ -7344,6 +7338,12 @@ package body Exp_Aggr is
-- choices that are ranges, subtype indications, subtype names, and
-- iterated component associations.
+ function Make_Array_Delta_Assignment_LHS
+ (Choice : Node_Id; Temp : Entity_Id) return Node_Id;
+ -- Generate the LHS for the assignment associated with one
+ -- component association. This can be more complex than just an
+ -- indexed component in the case of a deep delta aggregate.
+
-------------------
-- Generate_Loop --
-------------------
@@ -7380,6 +7380,60 @@ package body Exp_Aggr is
End_Label => Empty);
end Generate_Loop;
+ function Make_Array_Delta_Assignment_LHS
+ (Choice : Node_Id; Temp : Entity_Id) return Node_Id
+ is
+ function Make_Delta_Choice_LHS
+ (Choice : Node_Id;
+ Deep_Choice : Boolean) return Node_Id;
+ -- Recursively (but recursion only in deep delta aggregate case)
+ -- build up the LHS by successively applying selectors.
+
+ ---------------------------
+ -- Make_Delta_Choice_LHS --
+ ---------------------------
+
+ function Make_Delta_Choice_LHS
+ (Choice : Node_Id;
+ Deep_Choice : Boolean) return Node_Id
+ is
+ begin
+ if not Deep_Choice
+ or else Is_Root_Prefix_Of_Deep_Choice (Choice)
+ then
+ return Make_Indexed_Component (Sloc (Choice),
+ Prefix => New_Occurrence_Of (Temp, Loc),
+ Expressions => New_List (New_Copy_Tree (Choice)));
+
+ else
+ -- a deep delta aggregate choice
+ pragma Assert (All_Extensions_Allowed);
+
+ declare
+ -- recursively get name for prefix
+ LHS_Prefix : constant Node_Id
+ := Make_Delta_Choice_LHS (Prefix (Choice), Deep_Choice);
+ begin
+ if Nkind (Choice) = N_Indexed_Component then
+ return Make_Indexed_Component (Sloc (Choice),
+ Prefix => LHS_Prefix,
+ Expressions => New_Copy_List (Expressions (Choice)));
+ else
+ return Make_Selected_Component (Sloc (Choice),
+ Prefix => LHS_Prefix,
+ Selector_Name =>
+ Make_Identifier
+ (Sloc (Choice),
+ Chars (Selector_Name (Choice))));
+ end if;
+ end;
+ end if;
+ end Make_Delta_Choice_LHS;
+ begin
+ return Make_Delta_Choice_LHS
+ (Choice, Is_Deep_Choice (Choice, Etype (N)));
+ end Make_Array_Delta_Assignment_LHS;
+
-- Local variables
Choice : Node_Id;
@@ -7416,9 +7470,7 @@ package body Exp_Aggr is
Append_To (Deltas,
Make_Assignment_Statement (Sloc (Choice),
Name =>
- Make_Indexed_Component (Sloc (Choice),
- Prefix => New_Occurrence_Of (Temp, Loc),
- Expressions => New_List (New_Copy_Tree (Choice))),
+ Make_Array_Delta_Assignment_LHS (Choice, Temp),
Expression => New_Copy_Tree (Expression (Assoc))));
end if;
@@ -7443,6 +7495,43 @@ package body Exp_Aggr is
Assoc : Node_Id;
Choice : Node_Id;
+ function Make_Record_Delta_Assignment_LHS
+ (Selector : Node_Id) return Node_Id;
+ -- Generate the LHS for an assignment to a component (or subcomponent
+ -- if -gnatX specified) of the result object.
+
+ --------------------------------------
+ -- Make_Record_Delta_Assignment_LHS --
+ --------------------------------------
+
+ function Make_Record_Delta_Assignment_LHS
+ (Selector : Node_Id) return Node_Id
+ is
+ begin
+ if Nkind (Selector) = N_Selected_Component then
+ -- a deep delta aggregate, requires -gnatX0
+ return
+ Make_Selected_Component
+ (Sloc (Choice),
+ Prefix => Make_Record_Delta_Assignment_LHS
+ (Prefix (Selector)),
+ Selector_Name =>
+ Make_Identifier (Loc, Chars (Selector_Name (Selector))));
+ elsif Nkind (Selector) = N_Indexed_Component then
+ -- a deep delta aggregate, requires -gnatX0
+ return
+ Make_Indexed_Component
+ (Sloc (Choice),
+ Prefix => Make_Record_Delta_Assignment_LHS
+ (Prefix (Selector)),
+ Expressions => Expressions (Selector));
+ else
+ return Make_Selected_Component
+ (Sloc (Choice),
+ Prefix => New_Occurrence_Of (Temp, Loc),
+ Selector_Name => Make_Identifier (Loc, Chars (Selector)));
+ end if;
+ end Make_Record_Delta_Assignment_LHS;
begin
Assoc := First (Component_Associations (N));
@@ -7451,10 +7540,7 @@ package body Exp_Aggr is
while Present (Choice) loop
Append_To (Deltas,
Make_Assignment_Statement (Sloc (Choice),
- Name =>
- Make_Selected_Component (Sloc (Choice),
- Prefix => New_Occurrence_Of (Temp, Loc),
- Selector_Name => Make_Identifier (Loc, Chars (Choice))),
+ Name => Make_Record_Delta_Assignment_LHS (Choice),
Expression => New_Copy_Tree (Expression (Assoc))));
Next (Choice);
end loop;
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index cd3b02b..d946f6d 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -5158,9 +5158,6 @@ package body Exp_Ch5 is
-- The package in which the iterator interface is instantiated. This is
-- typically an instance within the container package.
- Pack : Entity_Id;
- -- The package in which the container type is declared
-
begin
if Present (Iterator_Filter (I_Spec)) then
pragma Assert (Ada_Version >= Ada_2022);
@@ -5195,15 +5192,6 @@ package body Exp_Ch5 is
-- package Vector_Iterator_Interfaces is new
-- Ada.Iterator_Interfaces (Cursor, Has_Element);
- -- If the container type is a derived type, the cursor type is found in
- -- the package of the ultimate ancestor type.
-
- if Is_Derived_Type (Container_Typ) then
- Pack := Scope (Root_Type (Container_Typ));
- else
- Pack := Scope (Container_Typ);
- end if;
-
if Of_Present (I_Spec) then
Handle_Of : declare
Container_Arg : Node_Id;
@@ -5289,6 +5277,9 @@ package body Exp_Ch5 is
Default_Iter : Entity_Id;
Ent : Entity_Id;
+ Cont_Type_Pack : Entity_Id;
+ -- The package in which the container type is declared
+
Reference_Control_Type : Entity_Id := Empty;
Pseudo_Reference : Entity_Id := Empty;
@@ -5312,11 +5303,14 @@ package body Exp_Ch5 is
Iter_Type := Etype (Default_Iter);
- -- The iterator type, which is a class-wide type, may itself be
- -- derived locally, so the desired instantiation is the scope of
- -- the root type of the iterator type.
+ -- If the container type is a derived type, the cursor type is
+ -- found in the package of the ultimate ancestor type.
- Iter_Pack := Scope (Root_Type (Etype (Iter_Type)));
+ if Is_Derived_Type (Container_Typ) then
+ Cont_Type_Pack := Scope (Root_Type (Container_Typ));
+ else
+ Cont_Type_Pack := Scope (Container_Typ);
+ end if;
-- Find declarations needed for "for ... of" optimization.
-- These declarations come from GNAT sources or sources
@@ -5326,7 +5320,7 @@ package body Exp_Ch5 is
-- Note that we use _Next or _Previous to avoid picking up
-- some arbitrary user-defined Next or Previous.
- Ent := First_Entity (Pack);
+ Ent := First_Entity (Cont_Type_Pack);
while Present (Ent) loop
-- Get_Element_Access function with one parameter called
-- Position.
@@ -5400,6 +5394,11 @@ package body Exp_Ch5 is
Analyze_And_Resolve (Name (I_Spec));
+ -- The desired instantiation is the scope of an iterator interface
+ -- type that is an ancestor of the iterator type.
+
+ Iter_Pack := Scope (Iterator_Interface_Ancestor (Iter_Type));
+
-- Find cursor type in proper iterator package, which is an
-- instantiation of Iterator_Interfaces.
@@ -5469,11 +5468,12 @@ package body Exp_Ch5 is
else
Iter_Type := Etype (Name (I_Spec));
- -- The iterator type, which is a class-wide type, may itself be
- -- derived locally, so the desired instantiation is the scope of
- -- the root type of the iterator type, as in the "of" case.
+ -- The instantiation in which to locate the Has_Element function
+ -- is the scope containing an iterator interface type that is
+ -- an ancestor of the iterator type.
+
+ Iter_Pack := Scope (Iterator_Interface_Ancestor (Iter_Type));
- Iter_Pack := Scope (Root_Type (Etype (Iter_Type)));
Cursor := Id;
end if;
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 369f0b0..f8c12b7 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -1575,19 +1575,10 @@ package body Exp_Ch7 is
Prepend_To (Decls, Counter_Typ_Decl);
-- The counter and its associated type must be manually analyzed
- -- since N has already been analyzed. Use the scope of the spec
- -- when inserting in a package.
+ -- since N has already been analyzed.
- if For_Package then
- Push_Scope (Spec_Id);
- Analyze (Counter_Typ_Decl);
- Analyze (Counter_Decl);
- Pop_Scope;
-
- else
- Analyze (Counter_Typ_Decl);
- Analyze (Counter_Decl);
- end if;
+ Analyze (Counter_Typ_Decl);
+ Analyze (Counter_Decl);
Jump_Alts := New_List;
end if;
@@ -1933,12 +1924,8 @@ package body Exp_Ch7 is
Append_To (Decls, Fin_Body);
end if;
- -- Push the name of the package
-
- Push_Scope (Spec_Id);
Analyze (Fin_Spec);
Analyze (Fin_Body);
- Pop_Scope;
-- Non-package case
@@ -2248,8 +2235,8 @@ package body Exp_Ch7 is
-- Finalization of transient objects are treated separately in
-- order to handle sensitive cases. These include:
- -- * Aggregate expansion
- -- * If, case, and expression with actions expansion
+ -- * Conditional expressions
+ -- * Expressions with actions
-- * Transient scopes
-- If one of those contexts has marked the transient object as
@@ -2479,51 +2466,6 @@ package body Exp_Ch7 is
and then Present (Library_Unit (Decl))
then
Process_Package_Body (Proper_Body (Unit (Library_Unit (Decl))));
-
- -- Handle a rare case caused by a controlled transient object
- -- created as part of a record init proc. The variable is wrapped
- -- in a block, but the block is not associated with a transient
- -- scope.
-
- elsif Nkind (Decl) = N_Block_Statement
- and then Inside_Init_Proc
- then
- Old_Counter_Val := Counter_Val;
-
- if Present (Handled_Statement_Sequence (Decl)) then
- Process_Declarations
- (Statements (Handled_Statement_Sequence (Decl)),
- Preprocess);
- end if;
-
- Process_Declarations (Declarations (Decl), Preprocess);
-
- -- Either the declaration or statement list of the block has a
- -- controlled object.
-
- if Preprocess
- and then Top_Level
- and then No (Last_Top_Level_Ctrl_Construct)
- and then Counter_Val > Old_Counter_Val
- then
- Last_Top_Level_Ctrl_Construct := Decl;
- end if;
-
- -- Handle the case where the original context has been wrapped in
- -- a block to avoid interference between exception handlers and
- -- At_End handlers. Treat the block as transparent and process its
- -- contents.
-
- elsif Nkind (Decl) = N_Block_Statement
- and then Is_Finalization_Wrapper (Decl)
- then
- if Present (Handled_Statement_Sequence (Decl)) then
- Process_Declarations
- (Statements (Handled_Statement_Sequence (Decl)),
- Preprocess);
- end if;
-
- Process_Declarations (Declarations (Decl), Preprocess);
end if;
Prev_Non_Pragma (Decl);
@@ -3464,6 +3406,10 @@ package body Exp_Ch7 is
-- Step 2: Object [pre]processing
if For_Package then
+ -- For package specs and bodies, we are invoked from the Standard
+ -- scope, so we need to push the specs onto the scope stack first.
+
+ Push_Scope (Spec_Id);
-- Preprocess the visible declarations now in order to obtain the
-- correct number of controlled object by the time the private
@@ -3541,6 +3487,12 @@ package body Exp_Ch7 is
if Acts_As_Clean or Has_Ctrl_Objs or Has_Tagged_Types then
Create_Finalizer;
end if;
+
+ -- Pop the scope that was pushed above for package specs and bodies
+
+ if For_Package then
+ Pop_Scope;
+ end if;
end Build_Finalizer;
--------------------------
diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
index c344dc1..ae0e616 100644
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -43,6 +43,7 @@ with Restrict; use Restrict;
with Rident; use Rident;
with Rtsfind; use Rtsfind;
with Sem; use Sem;
+with Sem_Aggr; use Sem_Aggr;
with Sem_Aux; use Sem_Aux;
with Sem_Ch7; use Sem_Ch7;
with Sem_Ch8; use Sem_Ch8;
@@ -186,15 +187,47 @@ package body Exp_SPARK is
(Typ : Entity_Id;
Aggr : Node_Id)
is
+ procedure Apply_Range_Checks (Choice : Node_Id);
+ -- Apply range checks on indexes from a deep choice
+
+ ------------------------
+ -- Apply_Range_Checks --
+ ------------------------
+
+ procedure Apply_Range_Checks (Choice : Node_Id) is
+ Pref : Node_Id := Choice;
+ Index : N_Subexpr_Id;
+ begin
+ loop
+ if Nkind (Pref) = N_Indexed_Component then
+ Index := First (Expressions (Pref));
+ Apply_Scalar_Range_Check (Index, Etype (Index));
+
+ elsif Is_Array_Type (Typ)
+ and then Is_Root_Prefix_Of_Deep_Choice (Pref)
+ then
+ Index := Pref;
+ Apply_Scalar_Range_Check (Index, Etype (Index));
+ end if;
+
+ exit when Is_Root_Prefix_Of_Deep_Choice (Pref);
+
+ Pref := Prefix (Pref);
+ end loop;
+ end Apply_Range_Checks;
+
+ -- Local variables
+
Assoc : Node_Id;
Comp : Node_Id;
- Comp_Id : Entity_Id;
Comp_Type : Entity_Id;
Expr : Node_Id;
Index : Node_Id;
Index_Typ : Entity_Id;
New_Assoc : Node_Id;
+ -- Start of processing for Expand_SPARK_Delta_Or_Update
+
begin
-- Apply scalar range checks on the updated components, if needed
@@ -277,6 +310,9 @@ package body Exp_SPARK is
if Nkind (Index) in N_Range | N_Subtype_Indication then
null;
+ elsif Is_Deep_Choice (Index, Typ) then
+ Apply_Range_Checks (Index);
+
-- Otherwise the index denotes a single expression where
-- range checks need to be applied or a subtype name
-- (without range constraints) where applying checks is
@@ -346,15 +382,16 @@ package body Exp_SPARK is
Comp := First (Choices (Assoc));
while Present (Comp) loop
- Comp_Id := Entity (Comp);
- Comp_Type := Etype (Comp_Id);
+ if Is_Deep_Choice (Comp, Typ) then
+ Comp_Type := Etype (Comp);
+ else
+ Comp_Type := Etype (Entity (Comp));
+ end if;
New_Assoc :=
Make_Component_Association
(Sloc => Sloc (Assoc),
- Choices =>
- New_List
- (New_Occurrence_Of (Comp_Id, Sloc (Comp))),
+ Choices => New_List (New_Copy_Tree (Comp)),
Expression => New_Copy_Tree (Expr));
-- New association must be attached to the aggregate before we
@@ -364,6 +401,10 @@ package body Exp_SPARK is
Analyze_And_Resolve (Expression (New_Assoc), Comp_Type);
+ if Is_Deep_Choice (Comp, Typ) then
+ Apply_Range_Checks (First (Choices (New_Assoc)));
+ end if;
+
if Is_Scalar_Type (Comp_Type) then
Apply_Scalar_Range_Check
(Expression (New_Assoc), Comp_Type);
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 730889c..3952a16 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -13023,8 +13023,8 @@ package body Exp_Util is
-- Finalization of transient objects are treated separately in
-- order to handle sensitive cases. These include:
- -- * Aggregate expansion
- -- * If, case, and expression with actions expansion
+ -- * Conditional expressions
+ -- * Expressions with actions
-- * Transient scopes
-- If one of those contexts has marked the transient object as
@@ -13233,27 +13233,6 @@ package body Exp_Util is
then
return True;
end if;
-
- elsif Nkind (Decl) = N_Block_Statement
- and then
-
- -- Handle a rare case caused by a controlled transient object
- -- created as part of a record init proc. The variable is wrapped
- -- in a block, but the block is not associated with a transient
- -- scope.
-
- (Inside_Init_Proc
-
- -- Handle the case where the original context has been wrapped in
- -- a block to avoid interference between exception handlers and
- -- At_End handlers. Treat the block as transparent and process its
- -- contents.
-
- or else Is_Finalization_Wrapper (Decl))
- then
- if Requires_Cleanup_Actions (Decl, Lib_Level) then
- return True;
- end if;
end if;
Next (Decl);
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 95ea440..932bf3f 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -1070,7 +1070,7 @@ package Exp_Util is
-- call and is analyzed and resolved on return. Name_Req may only be set to
-- True if Exp has the form of a name, and the effect is to guarantee that
-- any replacement maintains the form of name. If Renaming_Req is set to
- -- True, the routine produces an object renaming reclaration capturing the
+ -- True, the routine produces an object renaming declaration capturing the
-- expression. If Variable_Ref is set to True, a variable is considered as
-- side effect (used in implementing Force_Evaluation). Note: after call to
-- Remove_Side_Effects, it is safe to call New_Copy_Tree to obtain a copy
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 9c7f684..c446b14 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -3010,6 +3010,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
TREE_TYPE (TYPE_FIELDS (gnu_type)) = gnu_inner;
}
}
+
+ /* Otherwise, if an alignment is specified, use it if valid and, if
+ the alignment was requested with an explicit clause, state so. */
+ else if (Known_Alignment (gnat_entity))
+ {
+ SET_TYPE_ALIGN (gnu_type,
+ validate_alignment (Alignment (gnat_entity),
+ gnat_entity,
+ TYPE_ALIGN (gnu_type)));
+ if (Present (Alignment_Clause (gnat_entity)))
+ TYPE_USER_ALIGN (gnu_type) = 1;
+ }
}
break;
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index c7d9162..9c418be 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -3021,7 +3021,9 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
}
/* We use two different strategies to translate the loop, depending on
- whether optimization is enabled.
+ whether optimization is enabled, except for the very peculiar case
+ of a loop running over a boolean type where we use the simpler form
+ in order to avoid manipulating negative values in a boolean context.
If it is, we generate the canonical loop form expected by the loop
optimizer and the loop vectorizer, which is the do-while form:
@@ -3067,7 +3069,9 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
which works in all cases. */
- if (optimize && !optimize_debug)
+ if (optimize
+ && !optimize_debug
+ && TREE_CODE (gnu_base_type) != BOOLEAN_TYPE)
{
/* We can use the do-while form directly if GNU_FIRST-1 doesn't
overflow. */
diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc
index 8b2c7f9..e7b5c77 100644
--- a/gcc/ada/gcc-interface/utils.cc
+++ b/gcc/ada/gcc-interface/utils.cc
@@ -1485,7 +1485,14 @@ canonicalize_pad_type (tree type)
IS_COMPONENT_TYPE is true if this is being done for the component type of
an array. DEFINITION is true if this type is being defined. SET_RM_SIZE
is true if the RM size of the resulting type is to be set to SIZE too; in
- this case, the padded type is canonicalized before being returned. */
+ this case, the padded type is canonicalized before being returned.
+
+ Note that, if TYPE is an array, then we pad it even if it has already got
+ an alignment of ALIGN, provided that it's larger than the alignment of the
+ element type. This ensures that the size of the type is a multiple of its
+ alignment as required by the GCC type system, and alleviates the oddity of
+ the larger alignment, which is used to implement alignment clauses present
+ on unconstrained array types. */
tree
maybe_pad_type (tree type, tree size, unsigned int align,
@@ -1493,7 +1500,10 @@ maybe_pad_type (tree type, tree size, unsigned int align,
bool definition, bool set_rm_size)
{
tree orig_size = TYPE_SIZE (type);
- unsigned int orig_align = TYPE_ALIGN (type);
+ unsigned int orig_align
+ = TREE_CODE (type) == ARRAY_TYPE
+ ? TYPE_ALIGN (TREE_TYPE (type))
+ : TYPE_ALIGN (type);
tree record, field;
/* If TYPE is a padded type, see if it agrees with any size and alignment
@@ -1515,7 +1525,10 @@ maybe_pad_type (tree type, tree size, unsigned int align,
type = TREE_TYPE (TYPE_FIELDS (type));
orig_size = TYPE_SIZE (type);
- orig_align = TYPE_ALIGN (type);
+ orig_align
+ = TREE_CODE (type) == ARRAY_TYPE
+ ? TYPE_ALIGN (TREE_TYPE (type))
+ : TYPE_ALIGN (type);
}
/* If the size is either not being changed or is being made smaller (which
diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads
index a0bfb39..c565e19 100644
--- a/gcc/ada/gen_il-fields.ads
+++ b/gcc/ada/gen_il-fields.ads
@@ -255,7 +255,6 @@ package Gen_IL.Fields is
Is_Entry_Barrier_Function,
Is_Expanded_Build_In_Place_Call,
Is_Expanded_Contract,
- Is_Finalization_Wrapper,
Is_Folded_In_Parser,
Is_Generic_Contract_Pragma,
Is_Homogeneous_Aggregate,
diff --git a/gcc/ada/gen_il-gen-gen_nodes.adb b/gcc/ada/gen_il-gen-gen_nodes.adb
index 996d8d7..087f785 100644
--- a/gcc/ada/gen_il-gen-gen_nodes.adb
+++ b/gcc/ada/gen_il-gen-gen_nodes.adb
@@ -1029,7 +1029,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sm (Cleanup_Actions, List_Id),
Sm (Exception_Junk, Flag),
Sm (Is_Abort_Block, Flag),
- Sm (Is_Finalization_Wrapper, Flag),
Sm (Is_Initialization_Block, Flag),
Sm (Is_Task_Master, Flag)));
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 78f8849..3859709 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 , Oct 26, 2023
+GNAT User's Guide for Native Platforms , Nov 10, 2023
AdaCore
@@ -1363,22 +1363,30 @@ characters (using uppercase letters) of the wide character code. For
example, ESC A345 is used to represent the wide character with code
@code{16#A345#}.
This scheme is compatible with use of the full Wide_Character set.
-
-@item `Upper-Half Coding'
+@end table
@geindex Upper-Half Coding
+
+@table @asis
+
+@item `Upper-Half Coding'
+
The wide character with encoding @code{16#abcd#} where the upper bit is on
(in other words, ‘a’ is in the range 8-F) is represented as two bytes,
@code{16#ab#} and @code{16#cd#}. The second byte cannot be a format control
character, but is not required to be in the upper half. This method can
be also used for shift-JIS or EUC, where the internal coding matches the
external coding.
-
-@item `Shift JIS Coding'
+@end table
@geindex Shift JIS Coding
+
+@table @asis
+
+@item `Shift JIS Coding'
+
A wide character is represented by a two-character sequence,
@code{16#ab#} and
@code{16#cd#}, with the restrictions described for upper-half encoding as
@@ -1386,11 +1394,15 @@ described above. The internal character code is the corresponding JIS
character according to the standard algorithm for Shift-JIS
conversion. Only characters defined in the JIS code set table can be
used with this encoding method.
-
-@item `EUC Coding'
+@end table
@geindex EUC Coding
+
+@table @asis
+
+@item `EUC Coding'
+
A wide character is represented by a two-character sequence
@code{16#ab#} and
@code{16#cd#}, with both characters being in the upper half. The internal
@@ -29568,8 +29580,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/inline.adb b/gcc/ada/inline.adb
index 5fff881..1fbbe6d 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -2908,7 +2908,7 @@ package body Inline is
else
Push_Scope (Scop);
Expand_Cleanup_Actions (Decl);
- End_Scope;
+ Pop_Scope;
end if;
Next_Elmt (Elmt);
diff --git a/gcc/ada/libgnat/g-catiio.adb b/gcc/ada/libgnat/g-catiio.adb
index 42b86cc..d80e6fc 100644
--- a/gcc/ada/libgnat/g-catiio.adb
+++ b/gcc/ada/libgnat/g-catiio.adb
@@ -849,7 +849,7 @@ package body GNAT.Calendar.Time_IO is
begin
Advance_Digits (Num_Digits => 1);
- while Index <= Date'Length and then Symbol in '0' .. '9' loop
+ while Index <= Date'Last and then Symbol in '0' .. '9' loop
Advance;
end loop;
@@ -1005,7 +1005,7 @@ package body GNAT.Calendar.Time_IO is
-- Check for trailing characters
- if Index /= Date'Length + 1 then
+ if Index /= Date'Last + 1 then
raise Wrong_Syntax;
end if;
diff --git a/gcc/ada/libgnat/i-cstrea.adb b/gcc/ada/libgnat/i-cstrea.adb
index f761f3f..fe668e1 100644
--- a/gcc/ada/libgnat/i-cstrea.adb
+++ b/gcc/ada/libgnat/i-cstrea.adb
@@ -130,4 +130,13 @@ package body Interfaces.C_Streams is
return C_setvbuf (stream, buffer, mode, size);
end setvbuf;
+ ------------
+ -- unlink --
+ ------------
+
+ function unlink (filename : chars) return int is
+ begin
+ return System.CRTL.unlink (filename);
+ end unlink;
+
end Interfaces.C_Streams;
diff --git a/gcc/ada/libgnat/i-cstrea.ads b/gcc/ada/libgnat/i-cstrea.ads
index 3911122..67f10cf 100644
--- a/gcc/ada/libgnat/i-cstrea.ads
+++ b/gcc/ada/libgnat/i-cstrea.ads
@@ -197,8 +197,7 @@ package Interfaces.C_Streams is
function ungetc (c : int; stream : FILEs) return int
renames System.CRTL.ungetc;
- function unlink (filename : chars) return int
- renames System.CRTL.unlink;
+ function unlink (filename : chars) return int;
---------------------
-- Extra functions --
diff --git a/gcc/ada/libgnat/libada.gpr b/gcc/ada/libgnat/libada.gpr
index 9453cae..2848c56 100644
--- a/gcc/ada/libgnat/libada.gpr
+++ b/gcc/ada/libgnat/libada.gpr
@@ -6,13 +6,14 @@
-- 1. Create a new directory (e.g. "rts-debug"), then copy the adainclude
-- directory from the reference runtime that you want to rebuild.
-- You can find the relevant adainclude directory by running the command
--- gprls [--target=<target>] [--RTS=<runtime>] and using the adainclude
+-- gprls -v [--target=<target>] [--RTS=<runtime>] and using the adainclude
-- directory listed. For example:
--- $ cd <reference directory>
--- $ mkdir rts-debug
--- $ cd rts-debug
--- $ cp -a `gprls -v | grep adainclude` .
--- $ cd adainclude
+-- $ cd <reference directory>
+-- $ mkdir rts-debug
+-- $ cd rts-debug
+-- $ cp -a `gprls -v \
+-- [--target=<target>] --RTS=native | grep adainclude` .
+-- $ cd adainclude
--
-- or under Windows:
--
diff --git a/gcc/ada/libgnat/libgnat_common.gpr b/gcc/ada/libgnat/libgnat_common.gpr
index 6303928..a634033 100644
--- a/gcc/ada/libgnat/libgnat_common.gpr
+++ b/gcc/ada/libgnat/libgnat_common.gpr
@@ -5,7 +5,7 @@ abstract project Libgnat_Common is
("-I../include", "-DIN_RTS=1", "-fexceptions",
"-DSTANDALONE") &
External_As_List ("EXTRALIBFLAGS", " ");
- Ada_Flags := Common_Flags & ("-nostdinc", "-I../adainclude")
+ Ada_Flags := Common_Flags & ("-nostdinc", "-I../adainclude", "-gnatg")
& Split (External ("ADAFLAGS", "-gnatpg"), " ");
Library_Kind := External ("LIBRARY_KIND", "static");
diff --git a/gcc/ada/libgnat/s-crtl.ads b/gcc/ada/libgnat/s-crtl.ads
index c3a3b64..56900a8 100644
--- a/gcc/ada/libgnat/s-crtl.ads
+++ b/gcc/ada/libgnat/s-crtl.ads
@@ -220,7 +220,8 @@ package System.CRTL is
function ungetc (c : int; stream : FILEs) return int;
pragma Import (C, ungetc, "ungetc");
- function unlink (filename : chars) return int;
+ function unlink (filename : chars;
+ encoding : Filename_Encoding := Unspecified) return int;
pragma Import (C, unlink, "__gnat_unlink");
function open (filename : chars; oflag : int) return int;
diff --git a/gcc/ada/libgnat/s-fileio.adb b/gcc/ada/libgnat/s-fileio.adb
index 931b68a..f55cdc7 100644
--- a/gcc/ada/libgnat/s-fileio.adb
+++ b/gcc/ada/libgnat/s-fileio.adb
@@ -350,6 +350,7 @@ package body System.File_IO is
declare
Filename : aliased constant String := File.Name.all;
Is_Temporary_File : constant Boolean := File.Is_Temporary_File;
+ Encoding : constant CRTL.Filename_Encoding := File.Encoding;
begin
Close (File_Ptr);
@@ -360,7 +361,7 @@ package body System.File_IO is
-- it's a temporary file, then closing it already unlinked it.
if not Is_Temporary_File then
- if unlink (Filename'Address) = -1 then
+ if System.CRTL.unlink (Filename'Address, Encoding) = -1 then
raise Use_Error with OS_Lib.Errno_Message;
end if;
end if;
diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
index 52f2b02..2ff6e00 100644
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -1393,6 +1393,8 @@ package body Ch4 is
Start_Token : constant Token_Type := Token;
-- Used to prevent mismatches (...] and [...)
+ Saved_Delta_Aggregate_Flag : constant Boolean := Inside_Delta_Aggregate;
+
-- Start of processing for P_Aggregate_Or_Paren_Expr
begin
@@ -1497,6 +1499,7 @@ package body Ch4 is
Scan; -- past WITH
if Token = Tok_Delta then
Scan; -- past DELTA
+ Inside_Delta_Aggregate := True;
Aggregate_Node := New_Node (N_Delta_Aggregate, Lparen_Sloc);
Set_Expression (Aggregate_Node, Expr_Node);
Expr_Node := Empty;
@@ -1707,6 +1710,16 @@ package body Ch4 is
end if;
Set_Component_Associations (Aggregate_Node, Assoc_List);
+
+ -- Inside_Delta_Aggregate is only tested if Serious_Errors = 0, so
+ -- it is ok if we fail to restore the saved I_D_A value in an error
+ -- path. In particular, it is ok that we do not restore it if
+ -- Error_Resync is propagated. Earlier return statements (which return
+ -- without restoring the saved I_D_A value) should either be in error
+ -- paths or in paths where I_D_A could not have been modified.
+
+ Inside_Delta_Aggregate := Saved_Delta_Aggregate_Flag;
+
return Aggregate_Node;
end P_Aggregate_Or_Paren_Expr;
@@ -2519,6 +2532,109 @@ package body Ch4 is
Expr_Form := EF_Simple;
end if;
+ -- If all extensions are enabled and we have a deep delta aggregate
+ -- whose type is an array type with an element type that is a
+ -- record type, then we can encounter legal things like
+ -- with delta (Some_Index_Expression).Some_Component
+ -- where a parenthesized expression precedes a dot.
+ -- Similarly, if the element type is an array type then we can see
+ -- with delta (Some_Index_Expression)(Another_Index_Expression)
+ -- where a parenthesized expression precedes a left parenthesis.
+
+ if Token in Tok_Dot | Tok_Left_Paren
+ and then Prev_Token = Tok_Right_Paren
+ and then Serious_Errors_Detected = 0
+ and then Inside_Delta_Aggregate
+ and then All_Extensions_Allowed
+ then
+ if Token = Tok_Dot then
+ Node2 := New_Node (N_Selected_Component, Token_Ptr);
+ Scan; -- past dot
+ declare
+ Tail : constant Node_Id := P_Simple_Expression;
+ -- remaining selectors occurring after the dot
+
+ Rover : Node_Id := Tail;
+ Prev : Node_Id := Empty;
+ begin
+ -- If Tail already has a prefix, then we want to prepend
+ -- Node1 onto that prefix and then return Tail.
+ -- Otherwise, Tail should simply be an identifier so
+ -- we want to build a Selected_Component with Tail as the
+ -- selector name and return that.
+
+ Set_Prefix (Node2, Node1);
+
+ while Nkind (Rover)
+ in N_Indexed_Component | N_Selected_Component loop
+ Prev := Rover;
+ Rover := Prefix (Rover);
+ end loop;
+
+ case Nkind (Prev) is
+ when N_Selected_Component | N_Indexed_Component =>
+ -- We've scanned a dot, so an identifier should follow
+ if Nkind (Prefix (Prev)) = N_Identifier then
+ Set_Selector_Name (Node2, Prefix (Prev));
+ Set_Prefix (Prev, Node2);
+ return Tail;
+ end if;
+
+ when N_Empty =>
+ -- We've scanned a dot, so an identifier should follow
+ if Nkind (Tail) = N_Identifier then
+ Set_Selector_Name (Node2, Tail);
+ return Node2;
+ end if;
+
+ when others =>
+ null;
+ end case;
+
+ -- fall through to error case
+ end;
+ else
+ Node2 := New_Node (N_Indexed_Component, Token_Ptr);
+ declare
+ Tail : constant Node_Id := P_Simple_Expression;
+ -- remaining selectors
+
+ Rover : Node_Id := Tail;
+ Prev : Node_Id := Empty;
+ begin
+ -- If Tail already has a prefix, then we want to prepend
+ -- Node1 onto that prefix and then return Tail.
+ -- Otherwise, Tail should be an index expression and
+ -- we want to build an Indexed_Component with Tail as the
+ -- index value and return that.
+
+ Set_Prefix (Node2, Node1);
+
+ while Nkind (Rover)
+ in N_Indexed_Component | N_Selected_Component loop
+ Prev := Rover;
+ Rover := Prefix (Rover);
+ end loop;
+
+ case Nkind (Prev) is
+ when N_Selected_Component | N_Indexed_Component =>
+ Set_Expressions (Node2, New_List (Prefix (Prev)));
+ Set_Prefix (Prev, Node2);
+ return Tail;
+
+ when N_Empty =>
+ Set_Expressions (Node2, New_List (Tail));
+ return Node2;
+
+ when others =>
+ null;
+ end case;
+
+ -- fall through to error case
+ end;
+ end if;
+ end if;
+
-- Come here at end of simple expression, where we do a couple of
-- special checks to improve error recovery.
@@ -2529,8 +2645,8 @@ package body Ch4 is
if Token = Tok_Dot then
Error_Msg_SC ("prefix for selection is not a name");
- -- If qualified expression, comment and continue, otherwise something
- -- is pretty nasty so do an Error_Resync call.
+ -- If qualified expression, comment and continue, otherwise
+ -- something is pretty nasty so do an Error_Resync call.
if Ada_Version < Ada_2012
and then Nkind (Node1) = N_Qualified_Expression
diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb
index 5206899..4e10dd9 100644
--- a/gcc/ada/par.adb
+++ b/gcc/ada/par.adb
@@ -76,6 +76,15 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
-- Variable used to save values of config switches while we parse the
-- new unit, to be restored on exit for proper recursive behavior.
+ Inside_Delta_Aggregate : Boolean := False;
+ -- True within a delta aggregate (but only after the "delta" token has
+ -- been scanned). Used to distinguish syntax errors from syntactically
+ -- correct "deep" delta aggregates (enabled via -gnatX0).
+ Save_Style_Checks : Style_Check_Options;
+ Save_Style_Check : Boolean;
+ -- Variables for storing the original state of whether style checks should
+ -- be active in general and which particular ones should be checked.
+
--------------------
-- Error Recovery --
--------------------
@@ -1596,6 +1605,11 @@ begin
else
Save_Config_Attrs := Save_Config_Switches;
+ -- Store the state of Style_Checks pragamas
+
+ Save_Style_Check := Style_Check;
+ Save_Style_Check_Options (Save_Style_Checks);
+
-- The following loop runs more than once in syntax check mode
-- where we allow multiple compilation units in the same file
-- and in Multiple_Unit_Per_file mode where we skip units till
@@ -1653,6 +1667,7 @@ begin
-- syntax mode we are interested in all units in the file.
else
+
declare
Comp_Unit_Node : constant Node_Id := P_Compilation_Unit;
@@ -1739,6 +1754,13 @@ begin
Restore_Config_Switches (Save_Config_Attrs);
end loop;
+ -- Restore the state of Style_Checks after parsing the unit to
+ -- avoid parsed pragmas affecting other units.
+
+ Reset_Style_Check_Options;
+ Set_Style_Check_Options (Save_Style_Checks);
+ Style_Check := Save_Style_Check;
+
-- Now that we have completely parsed the source file, we can complete
-- the source file table entry.
diff --git a/gcc/ada/par_sco.adb b/gcc/ada/par_sco.adb
index 0639ca6..84af8bf 100644
--- a/gcc/ada/par_sco.adb
+++ b/gcc/ada/par_sco.adb
@@ -751,6 +751,13 @@ package body Par_SCO is
begin
case Nkind (N) is
+ -- Aspect specifications have dedicated processings (see
+ -- Traverse_Aspects) so ignore them here, so that they are
+ -- processed only once.
+
+ when N_Aspect_Specification =>
+ return Skip;
+
-- Logical operators, output table entries and then process
-- operands recursively to deal with nested conditions.
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index fb6bb0f..f1140d5 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -1975,7 +1975,8 @@ CND(CLOCK_THREAD_CPUTIME_ID, "Thread CPU clock")
#if defined(__linux__) || defined(__FreeBSD__) \
|| (defined(_AIX) && defined(_AIXVERSION_530)) \
- || defined(__DragonFly__) || defined(__QNX__)
+ || defined(__DragonFly__) || defined(__QNX__) \
+ || defined (__vxworks)
/** On these platforms use system provided monotonic clock instead of
** the default CLOCK_REALTIME. We then need to set up cond var attributes
** appropriately (see thread.c).
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 36db798..bc03a07 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -27,7 +27,6 @@ with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
with Einfo; use Einfo;
-with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils; use Einfo.Utils;
with Elists; use Elists;
with Errout; use Errout;
@@ -423,6 +422,9 @@ package body Sem_Aggr is
procedure Resolve_Delta_Array_Aggregate (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Delta_Record_Aggregate (N : Node_Id; Typ : Entity_Id);
+ procedure Resolve_Deep_Delta_Assoc (N : Node_Id; Typ : Entity_Id);
+ -- Resolve the names/expressions in a component association for
+ -- a deep delta aggregate. Typ is the type of the enclosing object.
------------------------
-- Array_Aggr_Subtype --
@@ -759,6 +761,28 @@ package body Sem_Aggr is
end if;
end Check_Expr_OK_In_Limited_Aggregate;
+ --------------------
+ -- Is_Deep_Choice --
+ --------------------
+
+ function Is_Deep_Choice
+ (Choice : Node_Id;
+ Aggr_Type : Type_Kind_Id) return Boolean
+ is
+ Pref : Node_Id := Choice;
+ begin
+ while not Is_Root_Prefix_Of_Deep_Choice (Pref) loop
+ Pref := Prefix (Pref);
+ end loop;
+
+ if Is_Array_Type (Aggr_Type) then
+ return Paren_Count (Pref) > 0
+ and then Pref /= Choice;
+ else
+ return Pref /= Choice;
+ end if;
+ end Is_Deep_Choice;
+
-------------------------
-- Is_Others_Aggregate --
-------------------------
@@ -771,6 +795,17 @@ package body Sem_Aggr is
and then Nkind (First (Choice_List (First (Assoc)))) = N_Others_Choice;
end Is_Others_Aggregate;
+ -----------------------------------
+ -- Is_Root_Prefix_Of_Deep_Choice --
+ -----------------------------------
+
+ function Is_Root_Prefix_Of_Deep_Choice (Pref : Node_Id) return Boolean is
+ begin
+ return Paren_Count (Pref) > 0
+ or else Nkind (Pref) not in N_Indexed_Component
+ | N_Selected_Component;
+ end Is_Root_Prefix_Of_Deep_Choice;
+
-------------------------
-- Is_Single_Aggregate --
-------------------------
@@ -3540,7 +3575,23 @@ package body Sem_Aggr is
end if;
end if;
else
- Choice := First (Choices (Comp));
+
+ -- If Nkind is N_Iterated_Component_Association,
+ -- this corresponds to an iterator_specification
+ -- with a loop_parameter_specification, and we
+ -- have to pick up Discrete_Choices. In this case
+ -- there will be just one "choice", which will
+ -- typically be a range.
+
+ if Nkind (Comp) = N_Iterated_Component_Association
+ then
+ Choice := First (Discrete_Choices (Comp));
+
+ -- Case where there's a list of choices
+
+ else
+ Choice := First (Choices (Comp));
+ end if;
while Present (Choice) loop
Get_Index_Bounds (Choice, Lo, Hi);
@@ -3661,6 +3712,8 @@ package body Sem_Aggr is
Choice : Node_Id;
Expr : Node_Id;
+ Deep_Choice_Seen : Boolean := False;
+
begin
Assoc := First (Deltas);
while Present (Assoc) loop
@@ -3713,31 +3766,39 @@ package body Sem_Aggr is
else
Choice := First (Choice_List (Assoc));
while Present (Choice) loop
- Analyze (Choice);
+ if Is_Deep_Choice (Choice, Typ) then
+ pragma Assert (All_Extensions_Allowed);
+ Deep_Choice_Seen := True;
- if Nkind (Choice) = N_Others_Choice then
- Error_Msg_N
- ("OTHERS not allowed in delta aggregate", Choice);
+ -- a deep delta aggregate
+ Resolve_Deep_Delta_Assoc (Assoc, Typ);
+ else
+ Analyze (Choice);
- elsif Is_Entity_Name (Choice)
- and then Is_Type (Entity (Choice))
- then
- -- Choice covers a range of values
+ if Nkind (Choice) = N_Others_Choice then
+ Error_Msg_N
+ ("OTHERS not allowed in delta aggregate", Choice);
- if Base_Type (Entity (Choice)) /=
- Base_Type (Index_Type)
+ elsif Is_Entity_Name (Choice)
+ and then Is_Type (Entity (Choice))
then
- Error_Msg_NE
- ("choice does not match index type of &",
- Choice, Typ);
- end if;
+ -- Choice covers a range of values
- elsif Nkind (Choice) = N_Subtype_Indication then
- Resolve_Discrete_Subtype_Indication
- (Choice, Base_Type (Index_Type));
+ if Base_Type (Entity (Choice)) /=
+ Base_Type (Index_Type)
+ then
+ Error_Msg_NE
+ ("choice does not match index type of &",
+ Choice, Typ);
+ end if;
- else
- Resolve (Choice, Index_Type);
+ elsif Nkind (Choice) = N_Subtype_Indication then
+ Resolve_Discrete_Subtype_Indication
+ (Choice, Base_Type (Index_Type));
+
+ else
+ Resolve (Choice, Index_Type);
+ end if;
end if;
Next (Choice);
@@ -3752,7 +3813,7 @@ package body Sem_Aggr is
if Box_Present (Assoc) then
Error_Msg_N
("'<'> in array delta aggregate is not allowed", Assoc);
- else
+ elsif not Deep_Choice_Seen then
Analyze_And_Resolve (Expression (Assoc), Component_Type (Typ));
end if;
end if;
@@ -3773,14 +3834,15 @@ package body Sem_Aggr is
Comp_Ref : Entity_Id := Empty; -- init to avoid warning
Variant : Node_Id;
- procedure Check_Variant (Id : Entity_Id);
+ procedure Check_Variant (Id : Node_Id);
-- If a given component of the delta aggregate appears in a variant
-- part, verify that it is within the same variant as that of previous
-- specified variant components of the delta.
- function Get_Component (Nam : Node_Id) return Entity_Id;
- -- Locate component with a given name and return it. If none found then
- -- report error and return Empty.
+ function Get_Component_Type
+ (Selector : Node_Id; Enclosing_Type : Entity_Id) return Entity_Id;
+ -- Locate component with a given name and return its type.
+ -- If none found then report error and return Empty.
function Nested_In (V1 : Node_Id; V2 : Node_Id) return Boolean;
-- Determine whether variant V1 is within variant V2
@@ -3792,7 +3854,7 @@ package body Sem_Aggr is
-- Check_Variant --
--------------------
- procedure Check_Variant (Id : Entity_Id) is
+ procedure Check_Variant (Id : Node_Id) is
Comp : Entity_Id;
Comp_Variant : Node_Id;
@@ -3843,30 +3905,80 @@ package body Sem_Aggr is
end if;
end Check_Variant;
- -------------------
- -- Get_Component --
- -------------------
+ ------------------------
+ -- Get_Component_Type --
+ ------------------------
- function Get_Component (Nam : Node_Id) return Entity_Id is
+ function Get_Component_Type
+ (Selector : Node_Id; Enclosing_Type : Entity_Id) return Entity_Id
+ is
Comp : Entity_Id;
-
begin
- Comp := First_Entity (Typ);
+ case Nkind (Selector) is
+ when N_Selected_Component | N_Indexed_Component =>
+ -- a deep delta aggregate choice
+
+ declare
+ Prefix_Type : constant Entity_Id :=
+ Get_Component_Type (Prefix (Selector), Enclosing_Type);
+ begin
+ if No (Prefix_Type) then
+ pragma Assert (Serious_Errors_Detected > 0);
+ return Empty;
+ end if;
+
+ -- Set the type of the prefix for GNATprove
+
+ Set_Etype (Prefix (Selector), Prefix_Type);
+
+ if Nkind (Selector) = N_Selected_Component then
+ return Get_Component_Type
+ (Selector_Name (Selector),
+ Enclosing_Type => Prefix_Type);
+ elsif not Is_Array_Type (Prefix_Type) then
+ Error_Msg_NE
+ ("type& is not an array type",
+ Selector, Prefix_Type);
+ elsif Number_Dimensions (Prefix_Type) /= 1 then
+ Error_Msg_NE
+ ("array type& not one-dimensional",
+ Selector, Prefix_Type);
+ elsif List_Length (Expressions (Selector)) /= 1 then
+ Error_Msg_NE
+ ("wrong number of indices for array type&",
+ Selector, Prefix_Type);
+ else
+ Analyze_And_Resolve
+ (First (Expressions (Selector)),
+ Etype (First_Index (Prefix_Type)));
+ return Component_Type (Prefix_Type);
+ end if;
+ end;
+
+ when others =>
+ null;
+ end case;
+
+ Comp := First_Entity (Enclosing_Type);
while Present (Comp) loop
- if Chars (Comp) = Chars (Nam) then
+ if Chars (Comp) = Chars (Selector) then
if Ekind (Comp) = E_Discriminant then
- Error_Msg_N ("delta cannot apply to discriminant", Nam);
+ Error_Msg_N ("delta cannot apply to discriminant", Selector);
end if;
- return Comp;
+ Set_Entity (Selector, Comp);
+ Set_Etype (Selector, Etype (Comp));
+
+ return Etype (Comp);
end if;
Next_Entity (Comp);
end loop;
- Error_Msg_NE ("type& has no component with this name", Nam, Typ);
+ Error_Msg_NE
+ ("type& has no component with this name", Selector, Enclosing_Type);
return Empty;
- end Get_Component;
+ end Get_Component_Type;
---------------
-- Nested_In --
@@ -3911,10 +4023,10 @@ package body Sem_Aggr is
Deltas : constant List_Id := Component_Associations (N);
- Assoc : Node_Id;
- Choice : Node_Id;
- Comp : Entity_Id;
- Comp_Type : Entity_Id := Empty; -- init to avoid warning
+ Assoc : Node_Id;
+ Choice : Node_Id;
+ Comp_Type : Entity_Id := Empty; -- init to avoid warning
+ Deep_Choice : Boolean;
-- Start of processing for Resolve_Delta_Record_Aggregate
@@ -3925,19 +4037,27 @@ package body Sem_Aggr is
while Present (Assoc) loop
Choice := First (Choice_List (Assoc));
while Present (Choice) loop
- Comp := Get_Component (Choice);
+ Deep_Choice := Nkind (Choice) /= N_Identifier;
+ if Deep_Choice then
+ Error_Msg_GNAT_Extension
+ ("deep delta aggregate", Sloc (Choice));
+ end if;
- if Present (Comp) then
- Check_Variant (Choice);
+ Comp_Type := Get_Component_Type
+ (Selector => Choice, Enclosing_Type => Typ);
- Comp_Type := Etype (Comp);
+ -- Set the type of the choice for GNATprove
- -- Decorate the component reference by setting its entity and
- -- type, as otherwise backends like GNATprove would have to
- -- rediscover this information by themselves.
+ if Deep_Choice then
+ Set_Etype (Choice, Comp_Type);
+ end if;
- Set_Entity (Choice, Comp);
- Set_Etype (Choice, Comp_Type);
+ if Present (Comp_Type) then
+ if not Deep_Choice then
+ -- ??? Not clear yet how RM 4.3.1(17.7) applies to a
+ -- deep delta aggregate.
+ Check_Variant (Choice);
+ end if;
else
Comp_Type := Any_Type;
end if;
@@ -3973,6 +4093,95 @@ package body Sem_Aggr is
end loop;
end Resolve_Delta_Record_Aggregate;
+ ------------------------------
+ -- Resolve_Deep_Delta_Assoc --
+ ------------------------------
+
+ procedure Resolve_Deep_Delta_Assoc (N : Node_Id; Typ : Entity_Id) is
+ Choice : constant Node_Id := First (Choice_List (N));
+ Enclosing_Type : Entity_Id := Typ;
+
+ procedure Resolve_Choice_Prefix
+ (Choice_Prefix : Node_Id; Enclosing_Type : in out Entity_Id);
+ -- Recursively analyze selectors. Enclosing_Type is set to
+ -- type of the last component.
+
+ ---------------------------
+ -- Resolve_Choice_Prefix --
+ ---------------------------
+
+ procedure Resolve_Choice_Prefix
+ (Choice_Prefix : Node_Id; Enclosing_Type : in out Entity_Id)
+ is
+ Selector : Node_Id := Choice_Prefix;
+ begin
+ if not Is_Root_Prefix_Of_Deep_Choice (Choice_Prefix) then
+ Resolve_Choice_Prefix (Prefix (Choice_Prefix), Enclosing_Type);
+
+ if Nkind (Choice_Prefix) = N_Selected_Component then
+ Selector := Selector_Name (Choice_Prefix);
+ else
+ pragma Assert (Nkind (Choice_Prefix) = N_Indexed_Component);
+ Selector := First (Expressions (Choice_Prefix));
+ end if;
+ end if;
+
+ if Is_Array_Type (Enclosing_Type) then
+ Analyze_And_Resolve (Selector,
+ Etype (First_Index (Enclosing_Type)));
+ Enclosing_Type := Component_Type (Enclosing_Type);
+ else
+ declare
+ Comp : Entity_Id := First_Entity (Enclosing_Type);
+ Found : Boolean := False;
+ begin
+ while Present (Comp) and not Found loop
+ if Chars (Comp) = Chars (Selector) then
+ if Ekind (Comp) = E_Discriminant then
+ Error_Msg_N ("delta cannot apply to discriminant",
+ Selector);
+ end if;
+ Found := True;
+ Set_Entity (Selector, Comp);
+ Set_Etype (Selector, Etype (Comp));
+ Set_Analyzed (Selector);
+ Enclosing_Type := Etype (Comp);
+ else
+ Next_Entity (Comp);
+ end if;
+ end loop;
+ if not Found then
+ Error_Msg_NE
+ ("type& has no component with this name",
+ Selector, Enclosing_Type);
+ end if;
+ end;
+ end if;
+
+ -- Set the type of the prefix for GNATprove, except for the root
+ -- prefix, whose type is already the expected one for a record
+ -- delta aggregate, or the type of the array index for an
+ -- array delta aggregate (the only case here really since
+ -- Resolve_Deep_Delta_Assoc is only called for array delta
+ -- aggregates).
+
+ if Selector /= Choice_Prefix then
+ Set_Etype (Choice_Prefix, Enclosing_Type);
+ end if;
+ end Resolve_Choice_Prefix;
+ begin
+ declare
+ Unimplemented : exception; -- TEMPORARY
+ begin
+ if Present (Next (Choice)) then
+ raise Unimplemented;
+ end if;
+ end;
+
+ Resolve_Choice_Prefix (Choice, Enclosing_Type);
+ Analyze_And_Resolve (Expression (N), Enclosing_Type);
+ end Resolve_Deep_Delta_Assoc;
+
---------------------------------
-- Resolve_Extension_Aggregate --
---------------------------------
diff --git a/gcc/ada/sem_aggr.ads b/gcc/ada/sem_aggr.ads
index 46d28ae..386a161 100644
--- a/gcc/ada/sem_aggr.ads
+++ b/gcc/ada/sem_aggr.ads
@@ -26,7 +26,8 @@
-- This package contains the resolution code for aggregates. It is logically
-- part of Sem_Res, but is split off since the aggregate code is so complex.
-with Types; use Types;
+with Einfo.Entities; use Einfo.Entities;
+with Types; use Types;
package Sem_Aggr is
@@ -50,4 +51,15 @@ package Sem_Aggr is
function Is_Null_Array_Aggregate_High_Bound (N : Node_Id) return Boolean;
-- Returns True for the high bound of a null array aggregate.
+ function Is_Deep_Choice
+ (Choice : Node_Id;
+ Aggr_Type : Type_Kind_Id) return Boolean;
+ -- Returns whether Choice from a delta aggregate of type Aggr_Type is a
+ -- deep choice.
+
+ function Is_Root_Prefix_Of_Deep_Choice (Pref : Node_Id) return Boolean;
+ -- Returns whether prefix Pref of a deep choice is its root prefix. Except
+ -- for its use in Is_Deep_Choice, this function should only be called on
+ -- prefixes of a deep choice as identified by Is_Deep_Choice.
+
end Sem_Aggr;
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index 531bc11..000253e 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -12119,9 +12119,7 @@ package body Sem_Attr is
Note_Possible_Modification (P, Sure => False);
end if;
- if Nkind (P) in N_Subexpr
- and then Is_Overloaded (P)
- then
+ if Nkind (P) in N_Subexpr and then Is_Overloaded (P) then
Get_First_Interp (P, Index, It);
Get_Next_Interp (Index, It);
@@ -12135,11 +12133,7 @@ package body Sem_Attr is
if not Is_Entity_Name (P)
or else not Is_Overloadable (Entity (P))
then
- if not Is_Task_Type (Etype (P))
- or else Nkind (P) = N_Explicit_Dereference
- then
- Resolve (P);
- end if;
+ Resolve (P);
end if;
-- If this is the name of a derived subprogram, or that of a
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index f73e1b5..7c645c4 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -4824,10 +4824,7 @@ package body Sem_Ch12 is
-- Cleanup actions are not generated within generic units
-- or in the formal part of generic units.
- if Inside_A_Generic
- or else Is_Generic_Unit (S)
- or else Ekind (S) = E_Void
- then
+ if not Expander_Active then
exit;
-- For package scopes, cleanup actions are generated only
@@ -16938,8 +16935,11 @@ package body Sem_Ch12 is
elsif No (Full_View (Typ)) and then Typ /= Etype (Typ) then
null;
- -- Otherwise mark the type for flipping and use the full view when
- -- available.
+ -- Otherwise mark the type for flipping and set the full view on N2
+ -- when available, which is necessary for Check_Private_View to swap
+ -- back the views in case the full declaration of Typ is visible in
+ -- the instantiation context. Note that this will be problematic if
+ -- N2 is re-analyzed later, e.g. if it's a default value in a call.
else
Set_Has_Private_View (N);
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 72e7d18..de38ddf 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -2113,11 +2113,28 @@ package body Sem_Ch5 is
Ent : Entity_Id;
begin
- -- If iterator type is derived, the cursor is declared in the scope
- -- of the parent type.
+ -- If the iterator type is derived and it has an iterator interface
+ -- type as an ancestor, then the cursor type is declared in the scope
+ -- of that interface type.
if Is_Derived_Type (Typ) then
- Ent := First_Entity (Scope (Etype (Typ)));
+ declare
+ Iter_Iface : constant Entity_Id :=
+ Iterator_Interface_Ancestor (Typ);
+
+ begin
+ if Present (Iter_Iface) then
+ Ent := First_Entity (Scope (Iter_Iface));
+
+ -- If there's not an iterator interface, then retrieve the
+ -- scope associated with the parent type and start from its
+ -- first entity.
+
+ else
+ Ent := First_Entity (Scope (Etype (Typ)));
+ end if;
+ end;
+
else
Ent := First_Entity (Scope (Typ));
end if;
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 42f7c10..70a8417 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -4017,13 +4017,21 @@ package body Sem_Res is
Analyze_And_Resolve (Actval, Base_Type (Etype (Actval)));
-- Resolve entities with their own type, which may differ from
- -- the type of a reference in a generic context (the view
- -- swapping mechanism did not anticipate the re-analysis of
- -- default values in calls).
+ -- the type of a reference in a generic context because of the
+ -- trick used in Save_Global_References.Set_Global_Type to set
+ -- full views forcefully, which did not anticipate the need to
+ -- re-analyze default values in calls.
elsif Is_Entity_Name (Actval) then
Analyze_And_Resolve (Actval, Etype (Entity (Actval)));
+ -- Ditto for calls whose name is an entity, for the same reason
+
+ elsif Nkind (Actval) = N_Function_Call
+ and then Is_Entity_Name (Name (Actval))
+ then
+ Analyze_And_Resolve (Actval, Etype (Entity (Name (Actval))));
+
else
Analyze_And_Resolve (Actval, Etype (Actval));
end if;
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 3d870b1..423b8d3 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -21496,6 +21496,40 @@ package body Sem_Util is
pragma Assert (No (Actual));
end Iterate_Call_Parameters;
+ --------------------------------
+ -- Iterate_Interface_Ancestor --
+ --------------------------------
+
+ function Iterator_Interface_Ancestor (Typ : Entity_Id) return Entity_Id is
+ begin
+ if Has_Interfaces (Typ) then
+ declare
+ Iface_Elmt : Elmt_Id;
+ Ifaces : Elist_Id;
+ Root_Iface : Entity_Id;
+
+ begin
+ Collect_Interfaces (Typ, Ifaces);
+
+ Iface_Elmt := First_Elmt (Ifaces);
+ while Present (Iface_Elmt) loop
+ Root_Iface := Root_Type (Node (Iface_Elmt));
+
+ if Chars (Root_Iface)
+ in Name_Forward_Iterator | Name_Reversible_Iterator
+ and then In_Predefined_Unit (Root_Iface)
+ then
+ return Root_Iface;
+ end if;
+
+ Next_Elmt (Iface_Elmt);
+ end loop;
+ end;
+ end if;
+
+ return Empty;
+ end Iterator_Interface_Ancestor;
+
-------------------------
-- Kill_Current_Values --
-------------------------
@@ -25429,7 +25463,7 @@ package body Sem_Util is
-- Check the status of the operand of a type conversion
- elsif Nkind (N) = N_Type_Conversion then
+ elsif Nkind (N) in N_Type_Conversion | N_Unchecked_Type_Conversion then
return Null_Status (Expression (N));
-- The input denotes a reference to an entity. Determine whether the
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index caf6a66..96b4730 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -2480,6 +2480,13 @@ package Sem_Util is
-- Calls Handle_Parameter for each pair of formal and actual parameters of
-- a function, procedure, or entry call.
+ function Iterator_Interface_Ancestor (Typ : Entity_Id) return Entity_Id;
+ -- If Typ has an ancestor that is an iterator interface type declared in
+ -- an instance of Ada.Iterator_Interfaces, then returns that interface
+ -- type. Otherwise returns Empty. (It's not clear what it means if there
+ -- is more than one such ancestor, perhaps coming from multiple instances,
+ -- but this function returns the first such ancestor it finds. ???)
+
procedure Kill_Current_Values (Last_Assignment_Only : Boolean := False);
-- This procedure is called to clear all constant indications from all
-- entities in the current scope and in any parent scopes if the current
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 7ecb4d9..125f5c7 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -857,6 +857,10 @@ package body Sem_Warn is
-- from another unit. This is true for entities in packages that are at
-- the library level.
+ function Type_OK_For_No_Value_Assigned (T : Entity_Id) return Boolean;
+ -- Return True if it is OK for an object of type T to be referenced
+ -- without having been assigned a value in the source.
+
function Warnings_Off_E1 return Boolean;
-- Return True if Warnings_Off is set for E1, or for its Etype (E1T),
-- or for the base type of E1T.
@@ -1121,6 +1125,37 @@ package body Sem_Warn is
end loop;
end Publicly_Referenceable;
+ -----------------------------------
+ -- Type_OK_For_No_Value_Assigned --
+ -----------------------------------
+
+ function Type_OK_For_No_Value_Assigned (T : Entity_Id) return Boolean is
+ begin
+ -- No information for generic types, so be conservative
+
+ if Is_Generic_Type (T) then
+ return False;
+ end if;
+
+ -- Even if objects of access types are implicitly initialized to null
+
+ if Is_Access_Type (T) then
+ return False;
+ end if;
+
+ -- The criterion is whether the type is (partially) initialized in
+ -- the source, in other words we disregard implicit default values.
+ -- But we do not require full initialization for by-reference types
+ -- because they are complex and it may not be possible to have it.
+
+ if Is_By_Reference_Type (T) then
+ return
+ Is_Partially_Initialized_Type (T, Include_Implicit => False);
+ else
+ return Is_Fully_Initialized_Type (T);
+ end if;
+ end Type_OK_For_No_Value_Assigned;
+
---------------------
-- Warnings_Off_E1 --
---------------------
@@ -1414,10 +1449,7 @@ package body Sem_Warn is
and then not Warnings_Off_E1
and then not Has_Junk_Name (E1)
then
- if Is_Access_Type (E1T)
- or else
- not Is_Partially_Initialized_Type (E1T, False)
- then
+ if not Type_OK_For_No_Value_Assigned (E1T) then
Output_Reference_Error
("?v?variable& is read but never assigned!");
end if;
@@ -1456,14 +1488,12 @@ package body Sem_Warn is
goto Continue;
end if;
- -- Check for unset reference. If type of object has
- -- preelaborable initialization, warning is misleading.
+ -- Check for unset reference
if Warn_On_No_Value_Assigned
and then Present (UR)
- and then not Known_To_Have_Preelab_Init (Etype (E1))
+ and then not Type_OK_For_No_Value_Assigned (E1T)
then
-
-- Don't issue warning if appearing inside Initial_Condition
-- pragma or aspect, since that expression is not evaluated
-- at the point where it occurs in the source.
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 8f96260..1a63170 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -1723,12 +1723,6 @@ package Sinfo is
-- Present in N_Contract nodes. Set if the contract has already undergone
-- expansion activities.
- -- Is_Finalization_Wrapper
- -- This flag is present in N_Block_Statement nodes. It is set when the
- -- block acts as a wrapper of a handled construct which has controlled
- -- objects. The wrapper prevents interference between exception handlers
- -- and At_End handlers.
-
-- Is_Generic_Contract_Pragma
-- This flag is present in N_Pragma nodes. It is set when the pragma is
-- a source construct, applies to a generic unit or its body, and denotes
@@ -5238,7 +5232,6 @@ package Sinfo is
-- Is_Task_Allocation_Block
-- Exception_Junk
-- Is_Abort_Block
- -- Is_Finalization_Wrapper
-- Is_Initialization_Block
-- Is_Task_Master
-- At_End_Proc (set to Empty if no clean up procedure)
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index e92c518..bab9e54 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,46 @@
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h: Include "rich-location.h".
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107573
+ * analyzer.h (register_known_functions): Add region_model_manager
+ param.
+ * analyzer.opt (Wanalyzer-undefined-behavior-strtok): New.
+ * call-summary.cc
+ (call_summary_replay::convert_region_from_summary_1): Handle
+ RK_PRIVATE.
+ * engine.cc (impl_run_checkers): Pass model manager to
+ register_known_functions.
+ * kf.cc (class undefined_function_behavior): New.
+ (class kf_strtok): New.
+ (register_known_functions): Add region_model_manager param.
+ Use it to register "strtok".
+ * region-model-manager.cc
+ (region_model_manager::get_or_create_conjured_svalue): Add "idx"
+ param.
+ * region-model-manager.h
+ (region_model_manager::get_or_create_conjured_svalue): Add "idx"
+ param.
+ (region_model_manager::get_root_region): New accessor.
+ * region-model.cc (region_model::scan_for_null_terminator): Handle
+ "expr" being null.
+ (region_model::get_representative_path_var_1): Handle RK_PRIVATE.
+ * region-model.h (region_model::called_from_main_p): Make public.
+ * region.cc (region::get_memory_space): Handle RK_PRIVATE.
+ (region::can_have_initial_svalue_p): Handle MEMSPACE_PRIVATE.
+ (private_region::dump_to_pp): New.
+ * region.h (MEMSPACE_PRIVATE): New.
+ (RK_PRIVATE): New.
+ (class private_region): New.
+ (is_a_helper <const private_region *>::test): New.
+ * store.cc (store::replay_call_summary_cluster): Handle
+ RK_PRIVATE.
+ * svalue.h (struct conjured_svalue::key_t): Add "idx" param to
+ ctor and "m_idx" field.
+ (class conjured_svalue::conjured_svalue): Likewise.
+
2023-11-18 David Malcolm <dmalcolm@redhat.com>
PR analyzer/106147
diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index f9fd258..c7209c2 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -2649,47 +2649,6 @@ namespace selftest
typedef std::pair<const char *, const char *> excl_pair;
-struct excl_hash_traits: typed_noop_remove<excl_pair>
-{
- typedef excl_pair value_type;
- typedef value_type compare_type;
-
- static hashval_t hash (const value_type &x)
- {
- hashval_t h1 = htab_hash_string (x.first);
- hashval_t h2 = htab_hash_string (x.second);
- return h1 ^ h2;
- }
-
- static bool equal (const value_type &x, const value_type &y)
- {
- return !strcmp (x.first, y.first) && !strcmp (x.second, y.second);
- }
-
- static void mark_deleted (value_type &x)
- {
- x = value_type (NULL, NULL);
- }
-
- static const bool empty_zero_p = false;
-
- static void mark_empty (value_type &x)
- {
- x = value_type ("", "");
- }
-
- static bool is_deleted (const value_type &x)
- {
- return !x.first && !x.second;
- }
-
- static bool is_empty (const value_type &x)
- {
- return !*x.first && !*x.second;
- }
-};
-
-
/* Self-test to verify that each attribute exclusion is symmetric,
meaning that if attribute A is encoded as incompatible with
attribute B then the opposite relationship is also encoded.
@@ -2699,13 +2658,15 @@ struct excl_hash_traits: typed_noop_remove<excl_pair>
static void
test_attribute_exclusions ()
{
+ using excl_hash_traits = pair_hash<nofree_string_hash, nofree_string_hash>;
+
/* Iterate over the array of attribute tables first (with TI0 as
the index) and over the array of attribute_spec in each table
(with SI0 as the index). */
const size_t ntables = ARRAY_SIZE (attribute_tables);
/* Set of pairs of mutually exclusive attributes. */
- typedef hash_set<excl_pair, false, excl_hash_traits> exclusion_set;
+ typedef hash_set<excl_hash_traits> exclusion_set;
exclusion_set excl_set;
for (size_t ti0 = 0; ti0 != ntables; ++ti0)
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 5ece0d2..6af2a0b 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -1859,6 +1859,7 @@ type_to_class (tree type)
case LANG_TYPE: return lang_type_class;
case OPAQUE_TYPE: return opaque_type_class;
case BITINT_TYPE: return bitint_type_class;
+ case VECTOR_TYPE: return vector_type_class;
default: return no_type_class;
}
}
@@ -9818,6 +9819,8 @@ fold_builtin_bit_query (location_t loc, enum built_in_function fcode,
if (!direct_internal_fn_supported_p (ifn, arg0_type,
OPTIMIZE_FOR_BOTH))
arg2 = NULL_TREE;
+ if (arg2 == NULL_TREE)
+ arg0 = save_expr (arg0);
}
if (fcodei == END_BUILTINS || arg2)
call = build_call_expr_internal_loc (loc, ifn, integer_type_node,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index ed26f97..25ab676 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,47 @@
+2023-11-24 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR pch/112319
+ * c-ppoutput.cc (cb_read_pch): Reinitialize the frontend parser
+ after loading a PCH.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * c.opt (-Wopenmp): Add missing tailing '.'.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * c.opt (Wopenmp): Add, enable by default.
+
+2023-11-23 Marek Polacek <polacek@redhat.com>
+
+ * c-opts.cc: Include "target.h".
+ (c_finish_options): Maybe cpp_define _FORTIFY_SOURCE
+ and _GLIBCXX_ASSERTIONS.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * c-common.h (enum rid): Add RID_BUILTIN_STDC: New.
+ * c-common.cc (c_common_reswords): Add __builtin_stdc_bit_ceil,
+ __builtin_stdc_bit_floor, __builtin_stdc_bit_width,
+ __builtin_stdc_count_ones, __builtin_stdc_count_zeros,
+ __builtin_stdc_first_leading_one, __builtin_stdc_first_leading_zero,
+ __builtin_stdc_first_trailing_one, __builtin_stdc_first_trailing_zero,
+ __builtin_stdc_has_single_bit, __builtin_stdc_leading_ones,
+ __builtin_stdc_leading_zeros, __builtin_stdc_trailing_ones and
+ __builtin_stdc_trailing_zeros. Move __builtin_assoc_barrier
+ alphabetically earlier.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/110348
+ * c.opt (Wc++26-extensions): New option.
+ * c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine
+ __cpp_static_assert to 202306L rather than 201411L.
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * c-lex.cc: Include "rich-location.h".
+
2023-11-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
* c-cppbuiltin.cc (c_cpp_builtins): Define
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 0ea0c4f..ca7557c 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -311,6 +311,44 @@ const struct fname_var_t fname_vars[] =
{NULL, 0, 0},
};
+/* Flags to restrict availability of generic features that
+ are known to __has_{feature,extension}. */
+
+enum
+{
+ HF_FLAG_NONE = 0,
+ HF_FLAG_EXT = 1, /* Available only as an extension. */
+ HF_FLAG_SANITIZE = 2, /* Availability depends on sanitizer flags. */
+};
+
+/* Info for generic features which can be queried through
+ __has_{feature,extension}. */
+
+struct hf_feature_info
+{
+ const char *ident;
+ unsigned flags;
+ unsigned mask;
+};
+
+/* Table of generic features which can be queried through
+ __has_{feature,extension}. */
+
+static constexpr hf_feature_info has_feature_table[] =
+{
+ { "address_sanitizer", HF_FLAG_SANITIZE, SANITIZE_ADDRESS },
+ { "thread_sanitizer", HF_FLAG_SANITIZE, SANITIZE_THREAD },
+ { "leak_sanitizer", HF_FLAG_SANITIZE, SANITIZE_LEAK },
+ { "hwaddress_sanitizer", HF_FLAG_SANITIZE, SANITIZE_HWADDRESS },
+ { "undefined_behavior_sanitizer", HF_FLAG_SANITIZE, SANITIZE_UNDEFINED },
+ { "attribute_deprecated_with_message", HF_FLAG_NONE, 0 },
+ { "attribute_unavailable_with_message", HF_FLAG_NONE, 0 },
+ { "enumerator_attributes", HF_FLAG_NONE, 0 },
+ { "tls", HF_FLAG_NONE, 0 },
+ { "gnu_asm_goto_with_outputs", HF_FLAG_EXT, 0 },
+ { "gnu_asm_goto_with_outputs_full", HF_FLAG_EXT, 0 }
+};
+
/* Global visibility options. */
struct visibility_flags visibility_options;
@@ -380,6 +418,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__auto_type", RID_AUTO_TYPE, D_CONLY },
{ "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY },
+ { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 },
{ "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY },
{ "__builtin_call_with_static_chain",
RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY },
@@ -388,9 +427,22 @@ const struct c_common_resword c_common_reswords[] =
{ "__builtin_convertvector", RID_BUILTIN_CONVERTVECTOR, 0 },
{ "__builtin_has_attribute", RID_BUILTIN_HAS_ATTRIBUTE, 0 },
{ "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY },
- { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 },
{ "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 },
{ "__builtin_shufflevector", RID_BUILTIN_SHUFFLEVECTOR, 0 },
+ { "__builtin_stdc_bit_ceil", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_bit_floor", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_bit_width", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_count_ones", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_count_zeros", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_first_leading_one", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_first_leading_zero", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_first_trailing_one", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_first_trailing_zero", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_has_single_bit", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_leading_ones", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_leading_zeros", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_trailing_ones", RID_BUILTIN_STDC, D_CONLY },
+ { "__builtin_stdc_trailing_zeros", RID_BUILTIN_STDC, D_CONLY },
{ "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
{ "__builtin_offsetof", RID_OFFSETOF, 0 },
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
@@ -9877,4 +9929,63 @@ c_strict_flex_array_level_of (tree array_field)
return strict_flex_array_level;
}
+/* Map from identifiers to booleans. Value is true for features, and
+ false for extensions. Used to implement __has_{feature,extension}. */
+
+using feature_map_t = hash_map <tree, bool>;
+static feature_map_t *feature_map;
+
+/* Register a feature for __has_{feature,extension}. FEATURE_P is true
+ if the feature identified by NAME is a feature (as opposed to an
+ extension). */
+
+void
+c_common_register_feature (const char *name, bool feature_p)
+{
+ bool dup = feature_map->put (get_identifier (name), feature_p);
+ gcc_checking_assert (!dup);
+}
+
+/* Lazily initialize hash table for __has_{feature,extension},
+ dispatching to the appropriate front end to register language-specific
+ features. */
+
+static void
+init_has_feature ()
+{
+ gcc_checking_assert (!feature_map);
+ feature_map = new feature_map_t;
+
+ for (unsigned i = 0; i < ARRAY_SIZE (has_feature_table); i++)
+ {
+ const hf_feature_info *info = has_feature_table + i;
+
+ if ((info->flags & HF_FLAG_SANITIZE) && !(flag_sanitize & info->mask))
+ continue;
+
+ const bool feature_p = !(info->flags & HF_FLAG_EXT);
+ c_common_register_feature (info->ident, feature_p);
+ }
+
+ /* Register language-specific features. */
+ c_family_register_lang_features ();
+}
+
+/* If STRICT_P is true, evaluate __has_feature (IDENT).
+ Otherwise, evaluate __has_extension (IDENT). */
+
+bool
+has_feature_p (const char *ident, bool strict_p)
+{
+ if (!feature_map)
+ init_has_feature ();
+
+ tree name = canonicalize_attr_name (get_identifier (ident));
+ bool *feat_p = feature_map->get (name);
+ if (!feat_p)
+ return false;
+
+ return !strict_p || *feat_p;
+}
+
#include "gt-c-family-c-common.h"
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index b57e83d..dd4fe3a 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -106,10 +106,10 @@ enum rid
/* C extensions */
RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE,
RID_VA_ARG,
- RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
- RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE,
- RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH,
- RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER,
+ RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
+ RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE,
+ RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH,
+ RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, RID_BUILTIN_STDC,
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
/* TS 18661-3 keywords, in the same sequence as the TI_* values. */
@@ -1126,6 +1126,14 @@ extern bool c_cpp_diagnostic (cpp_reader *, enum cpp_diagnostic_level,
ATTRIBUTE_GCC_DIAG(5,0);
extern int c_common_has_attribute (cpp_reader *, bool);
extern int c_common_has_builtin (cpp_reader *);
+extern int c_common_has_feature (cpp_reader *, bool);
+
+/* Implemented by each front end in *-lang.cc. */
+extern void c_family_register_lang_features ();
+
+/* Implemented in c-family/c-common.cc. */
+extern void c_common_register_feature (const char *, bool);
+extern bool has_feature_p (const char *, bool);
extern bool parse_optimize_options (tree, bool);
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 8d2f07a..56c4d63 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1023,7 +1023,8 @@ c_cpp_builtins (cpp_reader *pfile)
{
/* Set feature test macros for C++17. */
cpp_define (pfile, "__cpp_unicode_characters=201411L");
- cpp_define (pfile, "__cpp_static_assert=201411L");
+ if (cxx_dialect <= cxx23)
+ cpp_define (pfile, "__cpp_static_assert=201411L");
cpp_define (pfile, "__cpp_namespace_attributes=201411L");
cpp_define (pfile, "__cpp_enumerator_attributes=201411L");
cpp_define (pfile, "__cpp_nested_namespace_definitions=201411L");
@@ -1086,6 +1087,7 @@ c_cpp_builtins (cpp_reader *pfile)
{
/* Set feature test macros for C++26. */
cpp_define (pfile, "__cpp_constexpr=202306L");
+ cpp_define (pfile, "__cpp_static_assert=202306L");
}
if (flag_concepts)
{
diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc
index 86ec679..cc0af7e 100644
--- a/gcc/c-family/c-lex.cc
+++ b/gcc/c-family/c-lex.cc
@@ -83,6 +83,7 @@ init_c_lex (void)
cb->read_pch = c_common_read_pch;
cb->has_attribute = c_common_has_attribute;
cb->has_builtin = c_common_has_builtin;
+ cb->has_feature = c_common_has_feature;
cb->get_source_date_epoch = cb_get_source_date_epoch;
cb->get_suggestion = cb_get_suggestion;
cb->remap_filename = remap_macro_filename;
@@ -452,16 +453,16 @@ c_common_has_attribute (cpp_reader *pfile, bool std_syntax)
return result;
}
-/* Callback for has_builtin. */
+/* Helper for __has_{builtin,feature,extension}. */
-int
-c_common_has_builtin (cpp_reader *pfile)
+static const char *
+c_common_lex_availability_macro (cpp_reader *pfile, const char *builtin)
{
const cpp_token *token = get_token_no_padding (pfile);
if (token->type != CPP_OPEN_PAREN)
{
cpp_error (pfile, CPP_DL_ERROR,
- "missing '(' after \"__has_builtin\"");
+ "missing '(' after \"__has_%s\"", builtin);
return 0;
}
@@ -481,7 +482,7 @@ c_common_has_builtin (cpp_reader *pfile)
else
{
cpp_error (pfile, CPP_DL_ERROR,
- "macro \"__has_builtin\" requires an identifier");
+ "macro \"__has_%s\" requires an identifier", builtin);
if (token->type == CPP_CLOSE_PAREN)
return 0;
}
@@ -500,9 +501,38 @@ c_common_has_builtin (cpp_reader *pfile)
break;
}
+ return name;
+}
+
+/* Callback for has_builtin. */
+
+int
+c_common_has_builtin (cpp_reader *pfile)
+{
+ const char *name = c_common_lex_availability_macro (pfile, "builtin");
+ if (!name)
+ return 0;
+
return names_builtin_p (name);
}
+/* Callback for has_feature. STRICT_P is true for has_feature and false
+ for has_extension. */
+
+int
+c_common_has_feature (cpp_reader *pfile, bool strict_p)
+{
+ const char *builtin = strict_p ? "feature" : "extension";
+ const char *name = c_common_lex_availability_macro (pfile, builtin);
+ if (!name)
+ return 0;
+
+ /* If -pedantic-errors is given, __has_extension is equivalent to
+ __has_feature. */
+ strict_p |= flag_pedantic_errors;
+ return has_feature_p (name, strict_p);
+}
+
/* Read a token and return its type. Fill *VALUE with its value, if
applicable. Fill *CPP_FLAGS with the token's flags, if it is
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index 10403c0..d7faff1 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "target.h"
#include "c-target.h"
#include "c-common.h"
#include "memmodel.h"
@@ -1573,6 +1574,9 @@ c_finish_options (void)
cb_file_change (parse_in, cmd_map);
linemap_line_start (line_table, 0, 1);
+ bool fortify_seen_p = false;
+ bool cxx_assert_seen_p = false;
+
/* All command line defines must have the same location. */
cpp_force_token_locations (parse_in, line_table->highest_line);
for (size_t i = 0; i < deferred_count; i++)
@@ -1590,6 +1594,41 @@ c_finish_options (void)
else
cpp_assert (parse_in, opt->arg);
}
+
+ if (UNLIKELY (flag_hardened)
+ && (opt->code == OPT_D || opt->code == OPT_U))
+ {
+ if (!fortify_seen_p)
+ fortify_seen_p
+ = (!strncmp (opt->arg, "_FORTIFY_SOURCE", 15)
+ && (opt->arg[15] == '\0' || opt->arg[15] == '='));
+ if (!cxx_assert_seen_p)
+ cxx_assert_seen_p
+ = (!strncmp (opt->arg, "_GLIBCXX_ASSERTIONS", 19)
+ && (opt->arg[19] == '\0' || opt->arg[19] == '='));
+ }
+ }
+
+ if (flag_hardened)
+ {
+ if (!fortify_seen_p && optimize > 0)
+ cpp_define_formatted (parse_in, "_FORTIFY_SOURCE=%u",
+ targetm.fortify_source_default_level ());
+ else if (optimize == 0)
+ warning_at (UNKNOWN_LOCATION, OPT_Whardened,
+ "%<_FORTIFY_SOURCE%> is not enabled by %<-fhardened%> "
+ "because optimizations are turned off");
+ else
+ warning_at (UNKNOWN_LOCATION, OPT_Whardened,
+ "%<_FORTIFY_SOURCE%> is not enabled by %<-fhardened%> "
+ "because it was specified in %<-D%> or %<-U%>");
+ if (!cxx_assert_seen_p)
+ cpp_define (parse_in, "_GLIBCXX_ASSERTIONS");
+ else
+ warning_at (UNKNOWN_LOCATION, OPT_Whardened,
+ "%<_GLIBCXX_ASSERTIONS%> is not enabled by "
+ "%<-fhardened%> because it was specified in %<-D%> "
+ "or %<-U%>");
}
cpp_stop_forcing_token_locations (parse_in);
diff --git a/gcc/c-family/c-ppoutput.cc b/gcc/c-family/c-ppoutput.cc
index 4aa2bef..4805085b 100644
--- a/gcc/c-family/c-ppoutput.cc
+++ b/gcc/c-family/c-ppoutput.cc
@@ -162,6 +162,7 @@ init_pp_output (FILE *out_stream)
cb->has_attribute = c_common_has_attribute;
cb->has_builtin = c_common_has_builtin;
+ cb->has_feature = c_common_has_feature;
cb->get_source_date_epoch = cb_get_source_date_epoch;
cb->remap_filename = remap_macro_filename;
@@ -862,4 +863,9 @@ cb_read_pch (cpp_reader *pfile, const char *name,
fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name);
print.src_line++;
+
+ /* The process of reading the PCH has destroyed the frontend parser,
+ so ask the frontend to reinitialize it, in case we need it to
+ process any #pragma directives encountered while preprocessing. */
+ c_init_preprocess ();
}
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index b10c605..a2c8cef 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -498,6 +498,10 @@ Wc++23-extensions
C++ ObjC++ Var(warn_cxx23_extensions) Warning Init(1)
Warn about C++23 constructs in code compiled with an older standard.
+Wc++26-extensions
+C++ ObjC++ Var(warn_cxx26_extensions) Warning Init(1)
+Warn about C++26 constructs in code compiled with an older standard.
+
Wcast-function-type
C ObjC C++ ObjC++ Var(warn_cast_function_type) Warning EnabledBy(Wextra)
Warn about casts between incompatible function types.
@@ -1171,6 +1175,10 @@ Wopenacc-parallelism
C C++ Var(warn_openacc_parallelism) Warning
Warn about potentially suboptimal choices related to OpenACC parallelism.
+Wopenmp
+C ObjC C++ ObjC++ Warning Var(warn_openmp) Init(1)
+Warn about suspicious OpenMP code.
+
Wopenmp-simd
C C++ Var(warn_openmp_simd) Warning LangEnabledBy(C C++,Wall)
Warn if a simd directive is overridden by the vectorizer cost model.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 64fd993..46d8c59 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,23 @@
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * c-parser.cc (c_parser_omp_clause_num_threads,
+ c_parser_omp_clause_num_tasks, c_parser_omp_clause_grainsize,
+ c_parser_omp_clause_priority, c_parser_omp_clause_schedule,
+ c_parser_omp_clause_num_teams, c_parser_omp_clause_thread_limit,
+ c_parser_omp_clause_dist_schedule, c_parser_omp_depobj,
+ c_parser_omp_scan_loop_body, c_parser_omp_assumption_clauses):
+ Add OPT_Wopenmp to warning_at.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * c-parser.cc (c_parser_omp_depobj): Accept optionally an argument
+ to the destroy clause.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.cc (c_parser_postfix_expression): Handle RID_BUILTIN_STDC.
+ * c-decl.cc (names_builtin_p): Likewise.
+
2023-11-14 Jakub Jelinek <jakub@redhat.com>
PR c/111309
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 64d3a94..439a312 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -11370,11 +11370,12 @@ names_builtin_p (const char *name)
functions. */
switch (C_RID_CODE (id))
{
+ case RID_BUILTIN_ASSOC_BARRIER:
case RID_BUILTIN_CONVERTVECTOR:
case RID_BUILTIN_HAS_ATTRIBUTE:
case RID_BUILTIN_SHUFFLE:
case RID_BUILTIN_SHUFFLEVECTOR:
- case RID_BUILTIN_ASSOC_BARRIER:
+ case RID_BUILTIN_STDC:
case RID_CHOOSE_EXPR:
case RID_OFFSETOF:
case RID_TYPES_COMPATIBLE_P:
diff --git a/gcc/c/c-lang.cc b/gcc/c/c-lang.cc
index ddfd3e8..ff6633e 100644
--- a/gcc/c/c-lang.cc
+++ b/gcc/c/c-lang.cc
@@ -63,6 +63,15 @@ c_get_sarif_source_language (const char *)
return "c";
}
+/* Implement c-family hook to register language-specific features for
+ __has_{feature,extension}. */
+
+void
+c_family_register_lang_features ()
+{
+ c_register_features ();
+}
+
#if CHECKING_P
namespace selftest {
diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc
index c8f49aa..53eda7f 100644
--- a/gcc/c/c-objc-common.cc
+++ b/gcc/c/c-objc-common.cc
@@ -34,6 +34,39 @@ along with GCC; see the file COPYING3. If not see
static bool c_tree_printer (pretty_printer *, text_info *, const char *,
int, bool, bool, bool, bool *, const char **);
+/* Info for C language features which can be queried through
+ __has_{feature,extension}. */
+
+struct c_feature_info
+{
+ const char *ident;
+ const int *enable_flag;
+};
+
+static const c_feature_info c_feature_table[] =
+{
+ { "c_alignas", &flag_isoc11 },
+ { "c_alignof", &flag_isoc11 },
+ { "c_atomic", &flag_isoc11 },
+ { "c_generic_selections", &flag_isoc11 },
+ { "c_static_assert", &flag_isoc11 },
+ { "c_thread_local", &flag_isoc11 },
+ { "cxx_binary_literals", &flag_isoc23 }
+};
+
+/* Register features specific to the C language. */
+
+void
+c_register_features ()
+{
+ for (unsigned i = 0; i < ARRAY_SIZE (c_feature_table); i++)
+ {
+ const c_feature_info *info = c_feature_table + i;
+ const bool feat_p = !info->enable_flag || *info->enable_flag;
+ c_common_register_feature (info->ident, feat_p);
+ }
+}
+
bool
c_missing_noreturn_ok_p (tree decl)
{
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index ede451c..63aff70 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_C_OBJC_COMMON
#define GCC_C_OBJC_COMMON
+/* Implemented in c-objc-common.cc. */
+extern void c_register_features ();
+
/* Lang hooks that are shared between C and ObjC are defined here. Hooks
specific to C or ObjC go in c-lang.cc and objc/objc-lang.cc, respectively. */
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 703f957..df9a079 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -11743,6 +11743,297 @@ c_parser_postfix_expression (c_parser *parser)
set_c_expr_source_range (&expr, start_loc, end_loc);
}
break;
+ case RID_BUILTIN_STDC:
+ {
+ vec<c_expr_t, va_gc> *cexpr_list;
+ c_expr_t *arg_p;
+ location_t close_paren_loc;
+ enum c_builtin_stdc {
+ C_BUILTIN_STDC_BIT_CEIL,
+ C_BUILTIN_STDC_BIT_FLOOR,
+ C_BUILTIN_STDC_BIT_WIDTH,
+ C_BUILTIN_STDC_COUNT_ONES,
+ C_BUILTIN_STDC_COUNT_ZEROS,
+ C_BUILTIN_STDC_FIRST_LEADING_ONE,
+ C_BUILTIN_STDC_FIRST_LEADING_ZERO,
+ C_BUILTIN_STDC_FIRST_TRAILING_ONE,
+ C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
+ C_BUILTIN_STDC_HAS_SINGLE_BIT,
+ C_BUILTIN_STDC_LEADING_ONES,
+ C_BUILTIN_STDC_LEADING_ZEROS,
+ C_BUILTIN_STDC_TRAILING_ONES,
+ C_BUILTIN_STDC_TRAILING_ZEROS,
+ C_BUILTIN_STDC_MAX
+ } stdc_rid = C_BUILTIN_STDC_MAX;
+ const char *name
+ = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ switch (name[sizeof ("__builtin_stdc_") - 1])
+ {
+ case 'b':
+ switch (name[sizeof ("__builtin_stdc_bit_") - 1])
+ {
+ case 'c':
+ stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
+ break;
+ case 'f':
+ stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
+ break;
+ default:
+ stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
+ break;
+ }
+ break;
+ case 'c':
+ if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
+ stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
+ else
+ stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
+ break;
+ case 'f':
+ switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
+ {
+ case 'n':
+ stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
+ break;
+ case 'e':
+ stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
+ break;
+ case 'o':
+ stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
+ break;
+ default:
+ stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
+ break;
+ }
+ break;
+ case 'h':
+ stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
+ break;
+ case 'l':
+ if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
+ stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
+ else
+ stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
+ break;
+ case 't':
+ if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
+ stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
+ else
+ stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
+ break;
+ }
+ gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
+
+ c_parser_consume_token (parser);
+ if (!c_parser_get_builtin_args (parser, name,
+ &cexpr_list, false,
+ &close_paren_loc))
+ {
+ expr.set_error ();
+ break;
+ }
+
+ if (vec_safe_length (cexpr_list) != 1)
+ {
+ error_at (loc, "wrong number of arguments to %qs", name);
+ expr.set_error ();
+ break;
+ }
+
+ arg_p = &(*cexpr_list)[0];
+ *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
+ {
+ error_at (loc, "%qs operand not an integral type", name);
+ expr.set_error ();
+ break;
+ }
+ tree arg = arg_p->value;
+ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
+ /* Expand:
+ __builtin_stdc_leading_zeros (arg) as
+ (unsigned int) __builtin_clzg (arg, prec)
+ __builtin_stdc_leading_ones (arg) as
+ (unsigned int) __builtin_clzg ((type) ~arg, prec)
+ __builtin_stdc_trailing_zeros (arg) as
+ (unsigned int) __builtin_ctzg (arg, prec)
+ __builtin_stdc_trailing_ones (arg) as
+ (unsigned int) __builtin_ctzg ((type) ~arg, prec)
+ __builtin_stdc_first_leading_zero (arg) as
+ __builtin_clzg ((type) ~arg, -1) + 1U
+ __builtin_stdc_first_leading_one (arg) as
+ __builtin_clzg (arg, -1) + 1U
+ __builtin_stdc_first_trailing_zero (arg) as
+ __builtin_ctzg ((type) ~arg, -1) + 1U
+ __builtin_stdc_first_trailing_one (arg) as
+ __builtin_ctzg (arg, -1) + 1U
+ __builtin_stdc_count_zeros (arg) as
+ (unsigned int) __builtin_popcountg ((type) ~arg)
+ __builtin_stdc_count_ones (arg) as
+ (unsigned int) __builtin_popcountg (arg)
+ __builtin_stdc_has_single_bit (arg) as
+ (_Bool) (__builtin_popcountg (arg) == 1)
+ __builtin_stdc_bit_width (arg) as
+ (unsigned int) (prec - __builtin_clzg (arg, prec))
+ __builtin_stdc_bit_floor (arg) as
+ arg == 0 ? (type) 0
+ : (type) 1 << (prec - 1 - __builtin_clzg (arg))
+ __builtin_stdc_bit_ceil (arg) as
+ arg <= 1 ? (type) 1
+ : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
+ without evaluating arg multiple times, type being
+ __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
+ int prec = TYPE_PRECISION (type);
+ tree barg1 = arg;
+ switch (stdc_rid)
+ {
+ case C_BUILTIN_STDC_BIT_CEIL:
+ arg = save_expr (arg);
+ barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
+ build_int_cst (type, -1));
+ break;
+ case C_BUILTIN_STDC_BIT_FLOOR:
+ barg1 = arg = save_expr (arg);
+ break;
+ case C_BUILTIN_STDC_COUNT_ZEROS:
+ case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+ case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+ case C_BUILTIN_STDC_LEADING_ONES:
+ case C_BUILTIN_STDC_TRAILING_ONES:
+ barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
+ break;
+ default:
+ break;
+ }
+ tree barg2 = NULL_TREE;
+ switch (stdc_rid)
+ {
+ case C_BUILTIN_STDC_BIT_WIDTH:
+ case C_BUILTIN_STDC_LEADING_ONES:
+ case C_BUILTIN_STDC_LEADING_ZEROS:
+ case C_BUILTIN_STDC_TRAILING_ONES:
+ case C_BUILTIN_STDC_TRAILING_ZEROS:
+ barg2 = build_int_cst (integer_type_node, prec);
+ break;
+ case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+ case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+ case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+ case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+ barg2 = integer_minus_one_node;
+ break;
+ default:
+ break;
+ }
+ tree fndecl = NULL_TREE;
+ switch (stdc_rid)
+ {
+ case C_BUILTIN_STDC_BIT_CEIL:
+ case C_BUILTIN_STDC_BIT_FLOOR:
+ case C_BUILTIN_STDC_BIT_WIDTH:
+ case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+ case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+ case C_BUILTIN_STDC_LEADING_ONES:
+ case C_BUILTIN_STDC_LEADING_ZEROS:
+ fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
+ break;
+ case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+ case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+ case C_BUILTIN_STDC_TRAILING_ONES:
+ case C_BUILTIN_STDC_TRAILING_ZEROS:
+ fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
+ break;
+ case C_BUILTIN_STDC_COUNT_ONES:
+ case C_BUILTIN_STDC_COUNT_ZEROS:
+ case C_BUILTIN_STDC_HAS_SINGLE_BIT:
+ fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ /* Construct a call to __builtin_{clz,ctz,popcount}g. */
+ int nargs = barg2 != NULL_TREE ? 2 : 1;
+ vec<tree, va_gc> *args;
+ vec_alloc (args, nargs);
+ vec<tree, va_gc> *origtypes;
+ vec_alloc (origtypes, nargs);
+ auto_vec<location_t> arg_loc (nargs);
+ args->quick_push (barg1);
+ arg_loc.quick_push (arg_p->get_location ());
+ origtypes->quick_push (arg_p->original_type);
+ if (nargs == 2)
+ {
+ args->quick_push (barg2);
+ arg_loc.quick_push (loc);
+ origtypes->quick_push (integer_type_node);
+ }
+ expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
+ args, origtypes);
+ set_c_expr_source_range (&expr, loc, close_paren_loc);
+ if (expr.value == error_mark_node)
+ break;
+ switch (stdc_rid)
+ {
+ case C_BUILTIN_STDC_BIT_CEIL:
+ case C_BUILTIN_STDC_BIT_FLOOR:
+ --prec;
+ /* FALLTHRU */
+ case C_BUILTIN_STDC_BIT_WIDTH:
+ expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
+ build_int_cst (integer_type_node,
+ prec), expr.value);
+ break;
+ case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+ case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+ case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+ case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+ expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
+ expr.value, integer_one_node);
+ break;
+ case C_BUILTIN_STDC_HAS_SINGLE_BIT:
+ expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
+ expr.value, integer_one_node);
+ break;
+ default:
+ break;
+ }
+
+ if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
+ && stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
+ {
+ if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
+ expr.value = fold_convert_loc (loc, unsigned_type_node,
+ expr.value);
+ break;
+ }
+ /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
+ or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
+ warnings. The LSHIFT_EXPR is in dead code in that case. */
+ if (integer_zerop (arg)
+ || (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
+ expr.value = build_int_cst (type, 0);
+ else
+ expr.value
+ = build2_loc (loc, LSHIFT_EXPR, type,
+ build_int_cst (type,
+ (stdc_rid
+ == C_BUILTIN_STDC_BIT_CEIL
+ ? 2 : 1)), expr.value);
+ if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
+ expr.value = build3_loc (loc, COND_EXPR, type,
+ build2_loc (loc, LE_EXPR,
+ boolean_type_node, arg,
+ build_int_cst (type, 1)),
+ build_int_cst (type, 1),
+ expr.value);
+ else
+ expr.value = build3_loc (loc, COND_EXPR, type,
+ build2_loc (loc, EQ_EXPR,
+ boolean_type_node, arg,
+ build_int_cst (type, 0)),
+ build_int_cst (type, 0),
+ expr.value);
+ break;
+ }
case RID_AT_SELECTOR:
{
gcc_assert (c_dialect_objc ());
@@ -15780,7 +16071,7 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list)
protected_set_expr_location (c, expr_loc);
if (c == boolean_true_node)
{
- warning_at (expr_loc, 0,
+ warning_at (expr_loc, OPT_Wopenmp,
"%<num_threads%> value must be positive");
t = integer_one_node;
}
@@ -15841,7 +16132,8 @@ c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
SET_EXPR_LOCATION (c, expr_loc);
if (c == boolean_true_node)
{
- warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
+ warning_at (expr_loc, OPT_Wopenmp,
+ "%<num_tasks%> value must be positive");
t = integer_one_node;
}
@@ -15902,7 +16194,8 @@ c_parser_omp_clause_grainsize (c_parser *parser, tree list)
SET_EXPR_LOCATION (c, expr_loc);
if (c == boolean_true_node)
{
- warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
+ warning_at (expr_loc, OPT_Wopenmp,
+ "%<grainsize%> value must be positive");
t = integer_one_node;
}
@@ -15950,7 +16243,8 @@ c_parser_omp_clause_priority (c_parser *parser, tree list)
SET_EXPR_LOCATION (c, expr_loc);
if (c == boolean_true_node)
{
- warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
+ warning_at (expr_loc, OPT_Wopenmp,
+ "%<priority%> value must be non-negative");
t = integer_one_node;
}
@@ -17092,7 +17386,7 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list)
protected_set_expr_location (s, loc);
if (s == boolean_true_node)
{
- warning_at (loc, 0,
+ warning_at (loc, OPT_Wopenmp,
"chunk size value must be positive");
t = integer_one_node;
}
@@ -17254,7 +17548,8 @@ c_parser_omp_clause_num_teams (c_parser *parser, tree list)
protected_set_expr_location (c, upper_loc);
if (c == boolean_true_node)
{
- warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
+ warning_at (upper_loc, OPT_Wopenmp,
+ "%<num_teams%> value must be positive");
upper = integer_one_node;
}
if (lower)
@@ -17264,15 +17559,17 @@ c_parser_omp_clause_num_teams (c_parser *parser, tree list)
protected_set_expr_location (c, lower_loc);
if (c == boolean_true_node)
{
- warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
+ warning_at (lower_loc, OPT_Wopenmp,
+ "%<num_teams%> value must be positive");
lower = NULL_TREE;
}
else if (TREE_CODE (lower) == INTEGER_CST
&& TREE_CODE (upper) == INTEGER_CST
&& tree_int_cst_lt (upper, lower))
{
- warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
- "than upper bound %qE", lower, upper);
+ warning_at (lower_loc, OPT_Wopenmp,
+ "%<num_teams%> lower bound %qE bigger than upper "
+ "bound %qE", lower, upper);
lower = NULL_TREE;
}
}
@@ -17319,7 +17616,8 @@ c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
protected_set_expr_location (c, expr_loc);
if (c == boolean_true_node)
{
- warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
+ warning_at (expr_loc, OPT_Wopenmp,
+ "%<thread_limit%> value must be positive");
t = integer_one_node;
}
@@ -18549,7 +18847,7 @@ c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
/* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
"dist_schedule"); */
if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
- warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
+ warning_at (loc, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
if (t == error_mark_node)
return list;
@@ -21314,6 +21612,9 @@ c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
destroy
update (dependence-type)
+ OpenMP 5.2 additionally:
+ destroy ( depobj )
+
dependence-type:
in
out
@@ -21372,7 +21673,26 @@ c_parser_omp_depobj (c_parser *parser)
clause = error_mark_node;
}
else if (!strcmp ("destroy", p))
- kind = OMP_CLAUSE_DEPEND_LAST;
+ {
+ matching_parens c_parens;
+ kind = OMP_CLAUSE_DEPEND_LAST;
+ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
+ && c_parens.require_open (parser))
+ {
+ tree destobj = c_parser_expr_no_commas (parser, NULL).value;
+ if (!lvalue_p (destobj))
+ error_at (EXPR_LOC_OR_LOC (destobj, c_loc),
+ "%<destroy%> expression is not lvalue expression");
+ else if (depobj != error_mark_node
+ && !operand_equal_p (destobj, depobj,
+ OEP_MATCH_SIDE_EFFECTS
+ | OEP_LEXICOGRAPHIC))
+ warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
+ "the %<destroy%> expression %qE should be the same "
+ "as the %<depobj%> argument %qE", destobj, depobj);
+ c_parens.skip_until_found_close (parser);
+ }
+ }
else if (!strcmp ("update", p))
{
matching_parens c_parens;
@@ -21602,7 +21922,7 @@ c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
else
{
- warning_at (c_parser_peek_token (parser)->location, 0,
+ warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
"%<#pragma omp scan%> with zero preceding executable "
"statements");
substmt = build_empty_stmt (loc);
@@ -21650,8 +21970,9 @@ c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
else
{
if (found_scan)
- warning_at (loc, 0, "%<#pragma omp scan%> with zero succeeding "
- "executable statements");
+ warning_at (loc, OPT_Wopenmp,
+ "%<#pragma omp scan%> with zero succeeding executable "
+ "statements");
substmt = build_empty_stmt (loc);
}
substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
@@ -25957,7 +26278,7 @@ c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
}
else if (startswith (p, "ext_"))
{
- warning_at (cloc, 0, "unknown assumption clause %qs", p);
+ warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad..f93259a 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -2629,6 +2629,54 @@ cgraph_node::set_malloc_flag (bool malloc_p)
return changed;
}
+/* Worker to set malloc flag. */
+static void
+add_detected_attribute_1 (cgraph_node *node, const char *attr, bool *changed)
+{
+ if (!lookup_attribute (attr, DECL_ATTRIBUTES (node->decl)))
+ {
+ DECL_ATTRIBUTES (node->decl) = tree_cons (get_identifier (attr),
+ NULL_TREE, DECL_ATTRIBUTES (node->decl));
+ *changed = true;
+ }
+
+ ipa_ref *ref;
+ FOR_EACH_ALIAS (node, ref)
+ {
+ cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
+ if (alias->get_availability () > AVAIL_INTERPOSABLE)
+ add_detected_attribute_1 (alias, attr, changed);
+ }
+
+ for (cgraph_edge *e = node->callers; e; e = e->next_caller)
+ if (e->caller->thunk
+ && (e->caller->get_availability () > AVAIL_INTERPOSABLE))
+ add_detected_attribute_1 (e->caller, attr, changed);
+}
+
+/* Add attribyte ATTR to function and its aliases. */
+
+bool
+cgraph_node::add_detected_attribute (const char *attr)
+{
+ bool changed = false;
+
+ if (get_availability () > AVAIL_INTERPOSABLE)
+ add_detected_attribute_1 (this, attr, &changed);
+ else
+ {
+ ipa_ref *ref;
+
+ FOR_EACH_ALIAS (this, ref)
+ {
+ cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
+ if (alias->get_availability () > AVAIL_INTERPOSABLE)
+ add_detected_attribute_1 (alias, attr, &changed);
+ }
+ }
+ return changed;
+}
+
/* Worker to set noreturng flag. */
static void
set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed)
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac..cfdd9f6 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1190,6 +1190,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
bool set_pure_flag (bool pure, bool looping);
+ /* Add attribute ATTR to cgraph_node's decl and on aliases of the node
+ if any. */
+ bool add_detected_attribute (const char *attr);
+
/* Call callback on function and aliases associated to the function.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */
diff --git a/gcc/common.md b/gcc/common.md
index 51ecd79..91a72bd 100644
--- a/gcc/common.md
+++ b/gcc/common.md
@@ -17,6 +17,34 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>. */
+;; This predicate is intended to be paired with register constraints that use
+;; register filters to impose an alignment. Operands that are aligned via
+;; TARGET_HARD_REGNO_MODE_OK should use normal register_operands instead.
+(define_predicate "aligned_register_operand"
+ (match_code "reg,subreg")
+{
+ /* Require the offset in a non-paradoxical subreg to be naturally aligned.
+ For example, if we have a subreg of something that is double the size of
+ this operand, the offset must select the first or second half of it. */
+ if (SUBREG_P (op)
+ && multiple_p (SUBREG_BYTE (op), GET_MODE_SIZE (GET_MODE (op))))
+ op = SUBREG_REG (op);
+ if (!REG_P (op))
+ return false;
+
+ if (HARD_REGISTER_P (op))
+ {
+ if (!in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)))
+ return false;
+
+ /* Reject hard registers that would need reloading, so that the reload
+ is visible to IRA and to pre-RA optimizers. */
+ if (REGNO (op) % REG_NREGS (op) != 0)
+ return false;
+ }
+ return true;
+})
+
(define_register_constraint "r" "GENERAL_REGS"
"Matches any general register.")
diff --git a/gcc/common.opt b/gcc/common.opt
index d21db5d..736a465 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -634,6 +634,10 @@ Wfree-nonheap-object
Common Var(warn_free_nonheap_object) Init(1) Warning
Warn when attempting to free a non-heap object.
+Whardened
+Common Var(warn_hardened) Init(1) Warning
+Warn when -fhardened did not enable an option from its set.
+
Whsa
Common Ignore Warning
Does nothing. Preserved for backward compatibility.
@@ -781,6 +785,10 @@ Wsuggest-attribute=malloc
Common Var(warn_suggest_attribute_malloc) Warning
Warn about functions which might be candidates for __attribute__((malloc)).
+Wsuggest-attribute=returns_nonnull
+Common Var(warn_suggest_attribute_returns_nonnull) Warning
+Warn about functions which might be candidates for __attribute__((returns_nonnull)).
+
Wsuggest-final-types
Common Var(warn_suggest_final_types) Warning
Warn about C++ polymorphic types where adding final keyword would improve code quality.
@@ -1819,6 +1827,10 @@ fguess-branch-probability
Common Var(flag_guess_branch_prob) Optimization
Enable guessing of branch probabilities.
+fhardened
+Common Driver Var(flag_hardened)
+Enable various security-relevant flags.
+
fharden-compares
Common Var(flag_harden_compares) Optimization
Harden conditionals not used in branches, checking reversed conditions.
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 7d25479..f90fb4d 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -715,6 +715,9 @@ get_available_features (struct __processor_model *cpu_model,
int apx_usable = 0;
/* Check if KL is usable. */
int has_kl = 0;
+ /* Record AVX10 version. */
+ int avx10_set = 0;
+ int version = 0;
if ((ecx & bit_OSXSAVE))
{
/* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
@@ -941,6 +944,9 @@ get_available_features (struct __processor_model *cpu_model,
{
if (eax & bit_AVX512BF16)
set_feature (FEATURE_AVX512BF16);
+ /* AVX10 has the same XSTATE with AVX512. */
+ if (edx & bit_AVX10)
+ avx10_set = 1;
}
if (amx_usable)
{
@@ -992,6 +998,33 @@ get_available_features (struct __processor_model *cpu_model,
}
}
+ /* Get Advanced Features at level 0x24 (eax = 0x24). */
+ if (avx10_set && max_cpuid_level >= 0x24)
+ {
+ __cpuid (0x24, eax, ebx, ecx, edx);
+ version = ebx & 0xff;
+ if (ebx & bit_AVX10_256)
+ switch (version)
+ {
+ case 1:
+ set_feature (FEATURE_AVX10_1_256);
+ break;
+ default:
+ set_feature (FEATURE_AVX10_1_256);
+ break;
+ }
+ if (ebx & bit_AVX10_512)
+ switch (version)
+ {
+ case 1:
+ set_feature (FEATURE_AVX10_1_512);
+ break;
+ default:
+ set_feature (FEATURE_AVX10_1_512);
+ break;
+ }
+ }
+
/* Check cpuid level of extended features. */
__cpuid (0x80000000, ext_level, ebx, ecx, edx);
diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc
index 1b09499..f101e4d 100644
--- a/gcc/common/config/i386/i386-common.cc
+++ b/gcc/common/config/i386/i386-common.cc
@@ -126,6 +126,9 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_APX_F_SET OPTION_MASK_ISA2_APX_F
#define OPTION_MASK_ISA2_EVEX512_SET OPTION_MASK_ISA2_EVEX512
#define OPTION_MASK_ISA2_USER_MSR_SET OPTION_MASK_ISA2_USER_MSR
+#define OPTION_MASK_ISA2_AVX10_1_256_SET OPTION_MASK_ISA2_AVX10_1_256
+#define OPTION_MASK_ISA2_AVX10_1_512_SET \
+ (OPTION_MASK_ISA2_AVX10_1_256_SET | OPTION_MASK_ISA2_AVX10_1_512)
/* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same
as -msse4.2. */
@@ -235,7 +238,8 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_AVX2_UNSET \
(OPTION_MASK_ISA2_AVXIFMA_UNSET | OPTION_MASK_ISA2_AVXVNNI_UNSET \
| OPTION_MASK_ISA2_AVXVNNIINT8_UNSET | OPTION_MASK_ISA2_AVXNECONVERT_UNSET \
- | OPTION_MASK_ISA2_AVXVNNIINT16_UNSET | OPTION_MASK_ISA2_AVX512F_UNSET)
+ | OPTION_MASK_ISA2_AVXVNNIINT16_UNSET | OPTION_MASK_ISA2_AVX512F_UNSET \
+ | OPTION_MASK_ISA2_AVX10_1_256_UNSET)
#define OPTION_MASK_ISA_AVX512F_UNSET \
(OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX512CD_UNSET \
| OPTION_MASK_ISA_AVX512PF_UNSET | OPTION_MASK_ISA_AVX512ER_UNSET \
@@ -315,6 +319,9 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_APX_F_UNSET OPTION_MASK_ISA2_APX_F
#define OPTION_MASK_ISA2_EVEX512_UNSET OPTION_MASK_ISA2_EVEX512
#define OPTION_MASK_ISA2_USER_MSR_UNSET OPTION_MASK_ISA2_USER_MSR
+#define OPTION_MASK_ISA2_AVX10_1_256_UNSET \
+ (OPTION_MASK_ISA2_AVX10_1_256 | OPTION_MASK_ISA2_AVX10_1_512_UNSET)
+#define OPTION_MASK_ISA2_AVX10_1_512_UNSET OPTION_MASK_ISA2_AVX10_1_512
/* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same
as -mno-sse4.1. */
@@ -616,6 +623,7 @@ ix86_handle_option (struct gcc_options *opts,
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512F_UNSET;
opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET;
opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -629,6 +637,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512CD_UNSET;
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512CD_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -903,6 +912,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512VBMI2_UNSET;
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512VBMI2_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -918,6 +928,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512FP16_UNSET;
opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512FP16_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -931,6 +942,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512VNNI_UNSET;
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512VNNI_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -946,6 +958,7 @@ ix86_handle_option (struct gcc_options *opts,
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512VPOPCNTDQ_UNSET;
opts->x_ix86_isa_flags_explicit
|= OPTION_MASK_ISA_AVX512VPOPCNTDQ_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -960,6 +973,7 @@ ix86_handle_option (struct gcc_options *opts,
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512BITALG_UNSET;
opts->x_ix86_isa_flags_explicit
|= OPTION_MASK_ISA_AVX512BITALG_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -975,6 +989,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512BF16_UNSET;
opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512BF16_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -1042,6 +1057,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512DQ_UNSET;
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512DQ_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -1057,6 +1073,7 @@ ix86_handle_option (struct gcc_options *opts,
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512BW_UNSET;
opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512BW_UNSET;
opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512BW_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -1070,6 +1087,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512VL_UNSET;
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512VL_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -1083,6 +1101,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512IFMA_UNSET;
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512IFMA_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -1096,6 +1115,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512VBMI_UNSET;
opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512VBMI_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -1372,6 +1392,7 @@ ix86_handle_option (struct gcc_options *opts,
{
opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_EVEX512_UNSET;
opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_EVEX512_UNSET;
+ opts->x_ix86_no_avx512_explicit = 1;
}
return true;
@@ -1388,6 +1409,38 @@ ix86_handle_option (struct gcc_options *opts,
}
return true;
+ case OPT_mavx10_1_256:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AVX10_1_256_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX10_1_256_SET;
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX2_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX2_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX10_1_256_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX10_1_256_UNSET;
+ opts->x_ix86_no_avx10_1_explicit = 1;
+ }
+ return true;
+
+ case OPT_mavx10_1_512:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AVX10_1_512_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX10_1_512_SET;
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX2_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX2_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX10_1_512_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX10_1_512_UNSET;
+ opts->x_ix86_no_avx10_1_explicit = 1;
+ }
+ return true;
+
case OPT_mfma:
if (value)
{
diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h
index a0552ef..38fa765 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -266,6 +266,8 @@ enum processor_features
FEATURE_SM4,
FEATURE_APX_F,
FEATURE_USER_MSR,
+ FEATURE_AVX10_1_256,
+ FEATURE_AVX10_1_512,
CPU_FEATURE_MAX
};
diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h
index 6875924..a7b7c52 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -193,4 +193,7 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("sm4", FEATURE_SM4, P_NONE, "-msm4")
ISA_NAMES_TABLE_ENTRY("apxf", FEATURE_APX_F, P_NONE, "-mapxf")
ISA_NAMES_TABLE_ENTRY("usermsr", FEATURE_USER_MSR, P_NONE, "-musermsr")
+ ISA_NAMES_TABLE_ENTRY("avx10.1", FEATURE_AVX10_1_256, P_NONE, "-mavx10.1")
+ ISA_NAMES_TABLE_ENTRY("avx10.1-256", FEATURE_AVX10_1_256, P_NONE, "-mavx10.1-256")
+ ISA_NAMES_TABLE_ENTRY("avx10.1-512", FEATURE_AVX10_1_512, P_NONE, "-mavx10.1-512")
ISA_NAMES_TABLE_END
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 5111626..ded85b4 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -169,9 +169,9 @@ struct riscv_ext_version
static const struct riscv_ext_version riscv_ext_version_table[] =
{
/* name, ISA spec, major version, minor_version. */
- {"e", ISA_SPEC_CLASS_20191213, 1, 9},
- {"e", ISA_SPEC_CLASS_20190608, 1, 9},
- {"e", ISA_SPEC_CLASS_2P2, 1, 9},
+ {"e", ISA_SPEC_CLASS_20191213, 2, 0},
+ {"e", ISA_SPEC_CLASS_20190608, 2, 0},
+ {"e", ISA_SPEC_CLASS_2P2, 2, 0},
{"i", ISA_SPEC_CLASS_20191213, 2, 1},
{"i", ISA_SPEC_CLASS_20190608, 2, 1},
@@ -963,7 +963,7 @@ riscv_subset_list::parse_std_ext (const char *p)
add ("e", major_version, minor_version, explicit_version_p, false);
- if (m_xlen > 32)
+ if (m_xlen > 64)
{
error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
m_arch, m_xlen);
diff --git a/gcc/config.gcc b/gcc/config.gcc
index b88591b..3000379 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1651,7 +1651,6 @@ bpf-*-*)
tm_file="elfos.h ${tm_file}"
tmake_file="${tmake_file} bpf/t-bpf"
use_collect2=no
- extra_headers="bpf-helpers.h"
use_gcc_stdint=provide
extra_objs="coreout.o core-builtins.o"
target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc \$(srcdir)/config/bpf/core-builtins.cc"
@@ -2682,22 +2681,22 @@ mips*-sde-elf*)
esac
case ${target} in
mipsisa32r6*)
- tm_defines="MIPS_ISA_DEFAULT=MIPS_ISA_MIPS32R6 MIPS_ABI_DEFAULT=ABI_32"
+ tm_defines="${tm_defines} MIPS_ISA_DEFAULT=MIPS_ISA_MIPS32R6 MIPS_ABI_DEFAULT=ABI_32"
;;
mipsisa32r2*)
- tm_defines="MIPS_ISA_DEFAULT=MIPS_ISA_MIPS32R2 MIPS_ABI_DEFAULT=ABI_32"
+ tm_defines="${tm_defines} MIPS_ISA_DEFAULT=MIPS_ISA_MIPS32R2 MIPS_ABI_DEFAULT=ABI_32"
;;
mipsisa32*)
- tm_defines="MIPS_ISA_DEFAULT=MIPS_ISA_MIPS32 MIPS_ABI_DEFAULT=ABI_32"
+ tm_defines="${tm_defines} MIPS_ISA_DEFAULT=MIPS_ISA_MIPS32 MIPS_ABI_DEFAULT=ABI_32"
;;
mipsisa64r6*)
- tm_defines="MIPS_ISA_DEFAULT=MIPS_ISA_MIPS64R6 MIPS_ABI_DEFAULT=ABI_N32"
+ tm_defines="${tm_defines} MIPS_ISA_DEFAULT=MIPS_ISA_MIPS64R6 MIPS_ABI_DEFAULT=ABI_N32"
;;
mipsisa64r2*)
- tm_defines="MIPS_ISA_DEFAULT=MIPS_ISA_MIPS64R2 MIPS_ABI_DEFAULT=ABI_N32"
+ tm_defines="${tm_defines} MIPS_ISA_DEFAULT=MIPS_ISA_MIPS64R2 MIPS_ABI_DEFAULT=ABI_N32"
;;
mipsisa64*)
- tm_defines="MIPS_ISA_DEFAULT=MIPS_ISA_MIPS64 MIPS_ABI_DEFAULT=ABI_N32"
+ tm_defines="${tm_defines} MIPS_ISA_DEFAULT=MIPS_ISA_MIPS64 MIPS_ABI_DEFAULT=ABI_N32"
;;
esac
;;
@@ -4704,7 +4703,7 @@ case "${target}" in
# Infer arch from --with-arch, --target, and --with-abi.
case "${with_arch}" in
- rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
+ rv32e* | rv32i* | rv32g* | rv64e* | rv64i* | rv64g*)
# OK.
;;
"")
@@ -4713,11 +4712,12 @@ case "${target}" in
ilp32e) with_arch="rv32e" ;;
ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
+ lp64e) with_arch="rv64e" ;;
*) with_arch="rv${xlen}gc" ;;
esac
;;
*)
- echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64i, or rv64g." 1>&2
+ echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64e, rv64i, or rv64g." 1>&2
exit 1
;;
esac
@@ -4731,7 +4731,7 @@ case "${target}" in
# pick a default based on the ISA, preferring soft-float
# unless the D extension is present.
case "${with_abi}" in
- ilp32 | ilp32e | ilp32f | ilp32d | lp64 | lp64f | lp64d)
+ ilp32 | ilp32e | ilp32f | ilp32d | lp64 | lp64e | lp64f | lp64d)
;;
"")
case "${with_arch}" in
@@ -4739,6 +4739,7 @@ case "${target}" in
rv32e*) with_abi=ilp32e ;;
rv32*) with_abi=ilp32 ;;
rv64*d* | rv64g*) with_abi=lp64d ;;
+ rv64e*) with_abi=lp64e ;;
rv64*) with_abi=lp64 ;;
esac
;;
@@ -4754,7 +4755,7 @@ case "${target}" in
ilp32,rv32* | ilp32e,rv32e* \
| ilp32f,rv32*f* | ilp32f,rv32g* \
| ilp32d,rv32*d* | ilp32d,rv32g* \
- | lp64,rv64* \
+ | lp64,rv64* | lp64e,rv64e* \
| lp64f,rv64*f* | lp64f,rv64g* \
| lp64d,rv64*d* | lp64d,rv64g*)
;;
diff --git a/gcc/config.host b/gcc/config.host
index 5df8575..21a988e 100644
--- a/gcc/config.host
+++ b/gcc/config.host
@@ -230,24 +230,19 @@ case ${host} in
host_exeext=.exe
host_lto_plugin_soname=cyglto_plugin.dll
;;
- i[34567]86-*-mingw32*)
+ i[34567]86-*-mingw32* | x86_64-*-mingw*)
host_xm_file=i386/xm-mingw32.h
- host_xmake_file="${host_xmake_file} i386/x-mingw32 i386/x-mingw32-utf8"
+ host_xmake_file="${host_xmake_file} ${host_xmake_mingw} i386/x-mingw32"
+ host_extra_gcc_objs="${host_extra_gcc_objs} ${host_extra_gcc_objs_mingw} driver-mingw32.o"
+ host_extra_objs="${host_extra_objs} ${host_extra_objs_mingw}"
host_exeext=.exe
out_host_hook_obj=host-mingw32.o
- host_extra_objs="${host_extra_objs} utf8-mingw32.o"
- host_extra_gcc_objs="${host_extra_gcc_objs} driver-mingw32.o utf8rc-mingw32.o"
- host_lto_plugin_soname=liblto_plugin.dll
- ;;
- x86_64-*-mingw*)
- use_long_long_for_widest_fast_int=yes
- host_xm_file=i386/xm-mingw32.h
- host_xmake_file="${host_xmake_file} i386/x-mingw32 i386/x-mingw32-utf8"
- host_exeext=.exe
- out_host_hook_obj=host-mingw32.o
- host_extra_objs="${host_extra_objs} utf8-mingw32.o"
- host_extra_gcc_objs="${host_extra_gcc_objs} driver-mingw32.o utf8rc-mingw32.o"
host_lto_plugin_soname=liblto_plugin.dll
+ case ${host} in
+ x86_64-*-*)
+ use_long_long_for_widest_fast_int=yes
+ ;;
+ esac
;;
aarch64*-*-darwin*)
out_host_hook_obj="${out_host_hook_obj} host-aarch64-darwin.o"
diff --git a/gcc/config.in b/gcc/config.in
index e100c20..fa40825 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1332,6 +1332,12 @@
#endif
+/* Define 0/1 if -fhardened is supported */
+#ifndef USED_FOR_TARGET
+#undef HAVE_FHARDENED_SUPPORT
+#endif
+
+
/* Define to 1 if you have the `fileno_unlocked' function. */
#ifndef USED_FOR_TARGET
#undef HAVE_FILENO_UNLOCKED
@@ -1740,6 +1746,12 @@
#endif
+/* Define 0/1 if your linker supports -z now */
+#ifndef USED_FOR_TARGET
+#undef HAVE_LD_NOW_SUPPORT
+#endif
+
+
/* Define if your PowerPC64 linker only needs function descriptor syms. */
#ifndef USED_FOR_TARGET
#undef HAVE_LD_NO_DOT_SYMS
@@ -1783,6 +1795,12 @@
#endif
+/* Define 0/1 if your linker supports -z relro */
+#ifndef USED_FOR_TARGET
+#undef HAVE_LD_RELRO_SUPPORT
+#endif
+
+
/* Define if your linker links a mix of read-only and read-write sections into
a read-write section. */
#ifndef USED_FOR_TARGET
@@ -1868,12 +1886,6 @@
#endif
-/* Define if valgrind's memcheck.h header is installed. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_MEMCHECK_H
-#endif
-
-
/* Define to 1 if you have the <memory.h> header file. */
#ifndef USED_FOR_TARGET
#undef HAVE_MEMORY_H
@@ -2136,12 +2148,6 @@
#endif
-/* Define if valgrind's valgrind/memcheck.h header is installed. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_VALGRIND_MEMCHECK_H
-#endif
-
-
/* Define to 1 if you have the `vfork' function. */
#ifndef USED_FOR_TARGET
#undef HAVE_VFORK
diff --git a/gcc/config/aarch64/aarch64-arches.def b/gcc/config/aarch64/aarch64-arches.def
index 7ae92aa..6b9a19c 100644
--- a/gcc/config/aarch64/aarch64-arches.def
+++ b/gcc/config/aarch64/aarch64-arches.def
@@ -30,19 +30,19 @@
Due to the assumptions about the positions of these fields in config.gcc,
NAME should be kept as the first argument. */
-AARCH64_ARCH("armv8-a", generic, V8A, 8, (SIMD))
-AARCH64_ARCH("armv8.1-a", generic, V8_1A, 8, (V8A, LSE, CRC, RDMA))
-AARCH64_ARCH("armv8.2-a", generic, V8_2A, 8, (V8_1A))
-AARCH64_ARCH("armv8.3-a", generic, V8_3A, 8, (V8_2A, PAUTH, RCPC))
-AARCH64_ARCH("armv8.4-a", generic, V8_4A, 8, (V8_3A, F16FML, DOTPROD, FLAGM))
-AARCH64_ARCH("armv8.5-a", generic, V8_5A, 8, (V8_4A, SB, SSBS, PREDRES))
-AARCH64_ARCH("armv8.6-a", generic, V8_6A, 8, (V8_5A, I8MM, BF16))
-AARCH64_ARCH("armv8.7-a", generic, V8_7A, 8, (V8_6A, LS64))
-AARCH64_ARCH("armv8.8-a", generic, V8_8A, 8, (V8_7A, MOPS))
-AARCH64_ARCH("armv8-r", generic, V8R , 8, (V8_4A))
-AARCH64_ARCH("armv9-a", generic, V9A , 9, (V8_5A, SVE2))
-AARCH64_ARCH("armv9.1-a", generic, V9_1A, 9, (V8_6A, V9A))
-AARCH64_ARCH("armv9.2-a", generic, V9_2A, 9, (V8_7A, V9_1A))
-AARCH64_ARCH("armv9.3-a", generic, V9_3A, 9, (V8_8A, V9_2A))
+AARCH64_ARCH("armv8-a", generic_armv8_a, V8A, 8, (SIMD))
+AARCH64_ARCH("armv8.1-a", generic_armv8_a, V8_1A, 8, (V8A, LSE, CRC, RDMA))
+AARCH64_ARCH("armv8.2-a", generic_armv8_a, V8_2A, 8, (V8_1A))
+AARCH64_ARCH("armv8.3-a", generic_armv8_a, V8_3A, 8, (V8_2A, PAUTH, RCPC))
+AARCH64_ARCH("armv8.4-a", generic_armv8_a, V8_4A, 8, (V8_3A, F16FML, DOTPROD, FLAGM))
+AARCH64_ARCH("armv8.5-a", generic_armv8_a, V8_5A, 8, (V8_4A, SB, SSBS, PREDRES))
+AARCH64_ARCH("armv8.6-a", generic_armv8_a, V8_6A, 8, (V8_5A, I8MM, BF16))
+AARCH64_ARCH("armv8.7-a", generic_armv8_a, V8_7A, 8, (V8_6A, LS64))
+AARCH64_ARCH("armv8.8-a", generic_armv8_a, V8_8A, 8, (V8_7A, MOPS))
+AARCH64_ARCH("armv8-r", generic_armv8_a, V8R , 8, (V8_4A))
+AARCH64_ARCH("armv9-a", generic_armv9_a, V9A , 9, (V8_5A, SVE2))
+AARCH64_ARCH("armv9.1-a", generic_armv9_a, V9_1A, 9, (V8_6A, V9A))
+AARCH64_ARCH("armv9.2-a", generic_armv9_a, V9_2A, 9, (V8_7A, V9_1A))
+AARCH64_ARCH("armv9.3-a", generic_armv9_a, V9_3A, 9, (V8_8A, V9_2A))
#undef AARCH64_ARCH
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index eae40b2..16752b7 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -189,4 +189,9 @@ AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPER
AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
+/* Generic Architecture Processors. */
+AARCH64_CORE("generic", generic, cortexa53, V8A, (), generic, 0x0, 0x0, -1)
+AARCH64_CORE("generic-armv8-a", generic_armv8_a, cortexa53, V8A, (), generic_armv8_a, 0x0, 0x0, -1)
+AARCH64_CORE("generic-armv9-a", generic_armv9_a, cortexa53, V9A, (), generic_armv9_a, 0x0, 0x0, -1)
+
#undef AARCH64_CORE
diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h
index 831e28a..01151e9 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -32,8 +32,6 @@ enum aarch64_processor
#define AARCH64_CORE(NAME, INTERNAL_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \
INTERNAL_IDENT,
#include "aarch64-cores.def"
- /* Used to indicate that no processor has been specified. */
- generic,
/* Used to mark the end of the processor table. */
aarch64_none
};
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index c6f2d58..ad79a81 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -269,7 +269,7 @@
"TARGET_SIMD"
{@ [ cons: =0 , 1 ; attrs: type ]
[ Umn , w ; neon_stp ] stp\t%<Vetype>1, %<Vetype>1, %y0
- [ Umn , r ; store_<ldpstp_vel_sz> ] stp\t%<vw>1, %<vw>1, %y0
+ [ Umn , r ; store_<ldpstp_vel_sz> ] stp\t%<vwcore>1, %<vwcore>1, %y0
}
)
@@ -2029,26 +2029,60 @@
[(set_attr "type" "neon_shift_imm_long")]
)
-(define_expand "vec_unpack<su>_hi_<mode>"
+(define_expand "vec_unpacku_hi_<mode>"
[(match_operand:<VWIDE> 0 "register_operand")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
+ (match_operand:VQW 1 "register_operand")]
+ "TARGET_SIMD"
+ {
+ rtx res = gen_reg_rtx (<MODE>mode);
+ rtx tmp = aarch64_gen_shareable_zero (<MODE>mode);
+ if (BYTES_BIG_ENDIAN)
+ emit_insn (gen_aarch64_zip2<mode> (res, tmp, operands[1]));
+ else
+ emit_insn (gen_aarch64_zip2<mode> (res, operands[1], tmp));
+ emit_move_insn (operands[0],
+ simplify_gen_subreg (<VWIDE>mode, res, <MODE>mode, 0));
+ DONE;
+ }
+)
+
+(define_expand "vec_unpacks_hi_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQW 1 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
- emit_insn (gen_aarch64_simd_vec_unpack<su>_hi_<mode> (operands[0],
- operands[1], p));
+ emit_insn (gen_aarch64_simd_vec_unpacks_hi_<mode> (operands[0],
+ operands[1], p));
DONE;
}
)
-(define_expand "vec_unpack<su>_lo_<mode>"
+(define_expand "vec_unpacku_lo_<mode>"
[(match_operand:<VWIDE> 0 "register_operand")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
+ (match_operand:VQW 1 "register_operand")]
+ "TARGET_SIMD"
+ {
+ rtx res = gen_reg_rtx (<MODE>mode);
+ rtx tmp = aarch64_gen_shareable_zero (<MODE>mode);
+ if (BYTES_BIG_ENDIAN)
+ emit_insn (gen_aarch64_zip1<mode> (res, tmp, operands[1]));
+ else
+ emit_insn (gen_aarch64_zip1<mode> (res, operands[1], tmp));
+ emit_move_insn (operands[0],
+ simplify_gen_subreg (<VWIDE>mode, res, <MODE>mode, 0));
+ DONE;
+ }
+)
+
+(define_expand "vec_unpacks_lo_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQW 1 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
- emit_insn (gen_aarch64_simd_vec_unpack<su>_lo_<mode> (operands[0],
- operands[1], p));
+ emit_insn (gen_aarch64_simd_vec_unpacks_lo_<mode> (operands[0],
+ operands[1], p));
DONE;
}
)
@@ -4776,6 +4810,62 @@
[(set_attr "type" "neon_sub_widen")]
)
+(define_insn "aarch64_usubw<mode>_lo_zip"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (minus:<VWIDE>
+ (match_operand:<VWIDE> 1 "register_operand" "w")
+ (subreg:<VWIDE>
+ (unspec:<MODE> [
+ (match_operand:VQW 2 "register_operand" "w")
+ (match_operand:VQW 3 "aarch64_simd_imm_zero")
+ ] UNSPEC_ZIP1) 0)))]
+ "TARGET_SIMD"
+ "usubw\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vhalftype>"
+ [(set_attr "type" "neon_sub_widen")]
+)
+
+(define_insn "aarch64_uaddw<mode>_lo_zip"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (plus:<VWIDE>
+ (subreg:<VWIDE>
+ (unspec:<MODE> [
+ (match_operand:VQW 2 "register_operand" "w")
+ (match_operand:VQW 3 "aarch64_simd_imm_zero")
+ ] UNSPEC_ZIP1) 0)
+ (match_operand:<VWIDE> 1 "register_operand" "w")))]
+ "TARGET_SIMD"
+ "uaddw\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vhalftype>"
+ [(set_attr "type" "neon_add_widen")]
+)
+
+(define_insn "aarch64_usubw<mode>_hi_zip"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (minus:<VWIDE>
+ (match_operand:<VWIDE> 1 "register_operand" "w")
+ (subreg:<VWIDE>
+ (unspec:<MODE> [
+ (match_operand:VQW 2 "register_operand" "w")
+ (match_operand:VQW 3 "aarch64_simd_imm_zero")
+ ] UNSPEC_ZIP2) 0)))]
+ "TARGET_SIMD"
+ "usubw2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
+ [(set_attr "type" "neon_sub_widen")]
+)
+
+(define_insn "aarch64_uaddw<mode>_hi_zip"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (plus:<VWIDE>
+ (subreg:<VWIDE>
+ (unspec:<MODE> [
+ (match_operand:VQW 2 "register_operand" "w")
+ (match_operand:VQW 3 "aarch64_simd_imm_zero")
+ ] UNSPEC_ZIP2) 0)
+ (match_operand:<VWIDE> 1 "register_operand" "w")))]
+ "TARGET_SIMD"
+ "uaddw2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
+ [(set_attr "type" "neon_add_widen")]
+)
+
(define_insn "aarch64_<ANY_EXTEND:su>addw<mode>"
[(set (match_operand:<VWIDE> 0 "register_operand" "=w")
(plus:<VWIDE>
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
index c969277..61bb852 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically by gentune.sh from aarch64-cores.def
(define_attr "tune"
- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa520,cortexa710,cortexa715,cortexa720,cortexx2,cortexx3,cortexx4,neoversen2,neoversev2,demeter"
+ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa520,cortexa710,cortexa715,cortexa720,cortexx2,cortexx3,cortexx4,neoversen2,neoversev2,demeter,generic,generic_armv8_a,generic_armv9_a"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 800a8b0..f6f6f94 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -354,2405 +354,32 @@ static const struct aarch64_flag_desc aarch64_tuning_flags[] =
};
/* Tuning parameters. */
-
-static const struct cpu_addrcost_table generic_addrcost_table =
-{
- {
- 1, /* hi */
- 0, /* si */
- 0, /* di */
- 1, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 0, /* post_modify_ld3_st3 */
- 0, /* post_modify_ld4_st4 */
- 0, /* register_offset */
- 0, /* register_sextend */
- 0, /* register_zextend */
- 0 /* imm_offset */
-};
-
-static const struct cpu_addrcost_table exynosm1_addrcost_table =
-{
- {
- 0, /* hi */
- 0, /* si */
- 0, /* di */
- 2, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 0, /* post_modify_ld3_st3 */
- 0, /* post_modify_ld4_st4 */
- 1, /* register_offset */
- 1, /* register_sextend */
- 2, /* register_zextend */
- 0, /* imm_offset */
-};
-
-static const struct cpu_addrcost_table xgene1_addrcost_table =
-{
- {
- 1, /* hi */
- 0, /* si */
- 0, /* di */
- 1, /* ti */
- },
- 1, /* pre_modify */
- 1, /* post_modify */
- 1, /* post_modify_ld3_st3 */
- 1, /* post_modify_ld4_st4 */
- 0, /* register_offset */
- 1, /* register_sextend */
- 1, /* register_zextend */
- 0, /* imm_offset */
-};
-
-static const struct cpu_addrcost_table thunderx2t99_addrcost_table =
-{
- {
- 1, /* hi */
- 1, /* si */
- 1, /* di */
- 2, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 0, /* post_modify_ld3_st3 */
- 0, /* post_modify_ld4_st4 */
- 2, /* register_offset */
- 3, /* register_sextend */
- 3, /* register_zextend */
- 0, /* imm_offset */
-};
-
-static const struct cpu_addrcost_table thunderx3t110_addrcost_table =
-{
- {
- 1, /* hi */
- 1, /* si */
- 1, /* di */
- 2, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 0, /* post_modify_ld3_st3 */
- 0, /* post_modify_ld4_st4 */
- 2, /* register_offset */
- 3, /* register_sextend */
- 3, /* register_zextend */
- 0, /* imm_offset */
-};
-
-static const struct cpu_addrcost_table tsv110_addrcost_table =
-{
- {
- 1, /* hi */
- 0, /* si */
- 0, /* di */
- 1, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 0, /* post_modify_ld3_st3 */
- 0, /* post_modify_ld4_st4 */
- 0, /* register_offset */
- 1, /* register_sextend */
- 1, /* register_zextend */
- 0, /* imm_offset */
-};
-
-static const struct cpu_addrcost_table qdf24xx_addrcost_table =
-{
- {
- 1, /* hi */
- 1, /* si */
- 1, /* di */
- 2, /* ti */
- },
- 1, /* pre_modify */
- 1, /* post_modify */
- 1, /* post_modify_ld3_st3 */
- 1, /* post_modify_ld4_st4 */
- 3, /* register_offset */
- 3, /* register_sextend */
- 3, /* register_zextend */
- 2, /* imm_offset */
-};
-
-static const struct cpu_addrcost_table a64fx_addrcost_table =
-{
- {
- 1, /* hi */
- 1, /* si */
- 1, /* di */
- 2, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 0, /* post_modify_ld3_st3 */
- 0, /* post_modify_ld4_st4 */
- 2, /* register_offset */
- 3, /* register_sextend */
- 3, /* register_zextend */
- 0, /* imm_offset */
-};
-
-static const struct cpu_addrcost_table neoversev1_addrcost_table =
-{
- {
- 1, /* hi */
- 0, /* si */
- 0, /* di */
- 1, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 3, /* post_modify_ld3_st3 */
- 3, /* post_modify_ld4_st4 */
- 0, /* register_offset */
- 0, /* register_sextend */
- 0, /* register_zextend */
- 0 /* imm_offset */
-};
-
-static const struct cpu_addrcost_table neoversen2_addrcost_table =
-{
- {
- 1, /* hi */
- 0, /* si */
- 0, /* di */
- 1, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 2, /* post_modify_ld3_st3 */
- 2, /* post_modify_ld4_st4 */
- 0, /* register_offset */
- 0, /* register_sextend */
- 0, /* register_zextend */
- 0 /* imm_offset */
-};
-
-static const struct cpu_addrcost_table neoversev2_addrcost_table =
-{
- {
- 1, /* hi */
- 0, /* si */
- 0, /* di */
- 1, /* ti */
- },
- 0, /* pre_modify */
- 0, /* post_modify */
- 2, /* post_modify_ld3_st3 */
- 2, /* post_modify_ld4_st4 */
- 0, /* register_offset */
- 0, /* register_sextend */
- 0, /* register_zextend */
- 0 /* imm_offset */
-};
-
-static const struct cpu_regmove_cost generic_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of slow int<->fp moves for spilling by setting
- their cost higher than memmov_cost. */
- 5, /* GP2FP */
- 5, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost cortexa57_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of slow int<->fp moves for spilling by setting
- their cost higher than memmov_cost. */
- 5, /* GP2FP */
- 5, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost cortexa53_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of slow int<->fp moves for spilling by setting
- their cost higher than memmov_cost. */
- 5, /* GP2FP */
- 5, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost exynosm1_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of slow int<->fp moves for spilling by setting
- their cost higher than memmov_cost (actual, 4 and 9). */
- 9, /* GP2FP */
- 9, /* FP2GP */
- 1 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost thunderx_regmove_cost =
-{
- 2, /* GP2GP */
- 2, /* GP2FP */
- 6, /* FP2GP */
- 4 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost xgene1_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of slow int<->fp moves for spilling by setting
- their cost higher than memmov_cost. */
- 8, /* GP2FP */
- 8, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost qdf24xx_regmove_cost =
-{
- 2, /* GP2GP */
- /* Avoid the use of int<->fp moves for spilling. */
- 6, /* GP2FP */
- 6, /* FP2GP */
- 4 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost thunderx2t99_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of int<->fp moves for spilling. */
- 5, /* GP2FP */
- 6, /* FP2GP */
- 3, /* FP2FP */
-};
-
-static const struct cpu_regmove_cost thunderx3t110_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of int<->fp moves for spilling. */
- 4, /* GP2FP */
- 5, /* FP2GP */
- 4 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost tsv110_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of slow int<->fp moves for spilling by setting
- their cost higher than memmov_cost. */
- 2, /* GP2FP */
- 3, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost a64fx_regmove_cost =
-{
- 1, /* GP2GP */
- /* Avoid the use of slow int<->fp moves for spilling by setting
- their cost higher than memmov_cost. */
- 5, /* GP2FP */
- 7, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost neoversen2_regmove_cost =
-{
- 1, /* GP2GP */
- /* Spilling to int<->fp instead of memory is recommended so set
- realistic costs compared to memmov_cost. */
- 3, /* GP2FP */
- 2, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost neoversev1_regmove_cost =
-{
- 1, /* GP2GP */
- /* Spilling to int<->fp instead of memory is recommended so set
- realistic costs compared to memmov_cost. */
- 3, /* GP2FP */
- 2, /* FP2GP */
- 2 /* FP2FP */
-};
-
-static const struct cpu_regmove_cost neoversev2_regmove_cost =
-{
- 1, /* GP2GP */
- /* Spilling to int<->fp instead of memory is recommended so set
- realistic costs compared to memmov_cost. */
- 3, /* GP2FP */
- 2, /* FP2GP */
- 2 /* FP2FP */
-};
-
-/* Generic costs for Advanced SIMD vector operations. */
-static const advsimd_vec_cost generic_advsimd_vector_cost =
-{
- 1, /* int_stmt_cost */
- 1, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 2, /* permute_cost */
- 2, /* reduc_i8_cost */
- 2, /* reduc_i16_cost */
- 2, /* reduc_i32_cost */
- 2, /* reduc_i64_cost */
- 2, /* reduc_f16_cost */
- 2, /* reduc_f32_cost */
- 2, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- 2, /* vec_to_scalar_cost */
- 1, /* scalar_to_vec_cost */
- 1, /* align_load_cost */
- 1, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-/* Generic costs for SVE vector operations. */
-static const sve_vec_cost generic_sve_vector_cost =
-{
- {
- 1, /* int_stmt_cost */
- 1, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 2, /* permute_cost */
- 2, /* reduc_i8_cost */
- 2, /* reduc_i16_cost */
- 2, /* reduc_i32_cost */
- 2, /* reduc_i64_cost */
- 2, /* reduc_f16_cost */
- 2, /* reduc_f32_cost */
- 2, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- 2, /* vec_to_scalar_cost */
- 1, /* scalar_to_vec_cost */
- 1, /* align_load_cost */
- 1, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
- },
- 2, /* clast_cost */
- 2, /* fadda_f16_cost */
- 2, /* fadda_f32_cost */
- 2, /* fadda_f64_cost */
- 4, /* gather_load_x32_cost */
- 2, /* gather_load_x64_cost */
- 1 /* scatter_store_elt_cost */
-};
-
-/* Generic costs for vector insn classes. */
-static const struct cpu_vector_cost generic_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 1, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 3, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &generic_advsimd_vector_cost, /* advsimd */
- &generic_sve_vector_cost, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost a64fx_advsimd_vector_cost =
-{
- 2, /* int_stmt_cost */
- 5, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- 13, /* reduc_i8_cost */
- 13, /* reduc_i16_cost */
- 13, /* reduc_i32_cost */
- 13, /* reduc_i64_cost */
- 13, /* reduc_f16_cost */
- 13, /* reduc_f32_cost */
- 13, /* reduc_f64_cost */
- 13, /* store_elt_extra_cost */
- 13, /* vec_to_scalar_cost */
- 4, /* scalar_to_vec_cost */
- 6, /* align_load_cost */
- 6, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-static const sve_vec_cost a64fx_sve_vector_cost =
-{
- {
- 2, /* int_stmt_cost */
- 5, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- 13, /* reduc_i8_cost */
- 13, /* reduc_i16_cost */
- 13, /* reduc_i32_cost */
- 13, /* reduc_i64_cost */
- 13, /* reduc_f16_cost */
- 13, /* reduc_f32_cost */
- 13, /* reduc_f64_cost */
- 13, /* store_elt_extra_cost */
- 13, /* vec_to_scalar_cost */
- 4, /* scalar_to_vec_cost */
- 6, /* align_load_cost */
- 6, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
- },
- 13, /* clast_cost */
- 13, /* fadda_f16_cost */
- 13, /* fadda_f32_cost */
- 13, /* fadda_f64_cost */
- 64, /* gather_load_x32_cost */
- 32, /* gather_load_x64_cost */
- 1 /* scatter_store_elt_cost */
-};
-
-static const struct cpu_vector_cost a64fx_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 5, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 3, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &a64fx_advsimd_vector_cost, /* advsimd */
- &a64fx_sve_vector_cost, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost qdf24xx_advsimd_vector_cost =
-{
- 1, /* int_stmt_cost */
- 3, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 2, /* permute_cost */
- 1, /* reduc_i8_cost */
- 1, /* reduc_i16_cost */
- 1, /* reduc_i32_cost */
- 1, /* reduc_i64_cost */
- 1, /* reduc_f16_cost */
- 1, /* reduc_f32_cost */
- 1, /* reduc_f64_cost */
- 1, /* store_elt_extra_cost */
- 1, /* vec_to_scalar_cost */
- 1, /* scalar_to_vec_cost */
- 1, /* align_load_cost */
- 1, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-/* QDF24XX costs for vector insn classes. */
-static const struct cpu_vector_cost qdf24xx_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 1, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 3, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &qdf24xx_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-
-static const advsimd_vec_cost thunderx_advsimd_vector_cost =
-{
- 4, /* int_stmt_cost */
- 1, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 4, /* permute_cost */
- 2, /* reduc_i8_cost */
- 2, /* reduc_i16_cost */
- 2, /* reduc_i32_cost */
- 2, /* reduc_i64_cost */
- 2, /* reduc_f16_cost */
- 2, /* reduc_f32_cost */
- 2, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- 2, /* vec_to_scalar_cost */
- 2, /* scalar_to_vec_cost */
- 3, /* align_load_cost */
- 5, /* unalign_load_cost */
- 5, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-/* ThunderX costs for vector insn classes. */
-static const struct cpu_vector_cost thunderx_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 3, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 3, /* cond_taken_branch_cost */
- 3, /* cond_not_taken_branch_cost */
- &thunderx_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost tsv110_advsimd_vector_cost =
-{
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 2, /* permute_cost */
- 3, /* reduc_i8_cost */
- 3, /* reduc_i16_cost */
- 3, /* reduc_i32_cost */
- 3, /* reduc_i64_cost */
- 3, /* reduc_f16_cost */
- 3, /* reduc_f32_cost */
- 3, /* reduc_f64_cost */
- 3, /* store_elt_extra_cost */
- 3, /* vec_to_scalar_cost */
- 2, /* scalar_to_vec_cost */
- 5, /* align_load_cost */
- 5, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-static const struct cpu_vector_cost tsv110_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 5, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &tsv110_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost cortexa57_advsimd_vector_cost =
-{
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- 8, /* reduc_i8_cost */
- 8, /* reduc_i16_cost */
- 8, /* reduc_i32_cost */
- 8, /* reduc_i64_cost */
- 8, /* reduc_f16_cost */
- 8, /* reduc_f32_cost */
- 8, /* reduc_f64_cost */
- 8, /* store_elt_extra_cost */
- 8, /* vec_to_scalar_cost */
- 8, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-/* Cortex-A57 costs for vector insn classes. */
-static const struct cpu_vector_cost cortexa57_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &cortexa57_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost exynosm1_advsimd_vector_cost =
-{
- 3, /* int_stmt_cost */
- 3, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- 3, /* reduc_i8_cost */
- 3, /* reduc_i16_cost */
- 3, /* reduc_i32_cost */
- 3, /* reduc_i64_cost */
- 3, /* reduc_f16_cost */
- 3, /* reduc_f32_cost */
- 3, /* reduc_f64_cost */
- 3, /* store_elt_extra_cost */
- 3, /* vec_to_scalar_cost */
- 3, /* scalar_to_vec_cost */
- 5, /* align_load_cost */
- 5, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-static const struct cpu_vector_cost exynosm1_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 5, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &exynosm1_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost xgene1_advsimd_vector_cost =
-{
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 2, /* permute_cost */
- 4, /* reduc_i8_cost */
- 4, /* reduc_i16_cost */
- 4, /* reduc_i32_cost */
- 4, /* reduc_i64_cost */
- 4, /* reduc_f16_cost */
- 4, /* reduc_f32_cost */
- 4, /* reduc_f64_cost */
- 4, /* store_elt_extra_cost */
- 4, /* vec_to_scalar_cost */
- 4, /* scalar_to_vec_cost */
- 10, /* align_load_cost */
- 10, /* unalign_load_cost */
- 2, /* unalign_store_cost */
- 2 /* store_cost */
-};
-
-/* Generic costs for vector insn classes. */
-static const struct cpu_vector_cost xgene1_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 5, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 2, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &xgene1_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost thunderx2t99_advsimd_vector_cost =
-{
- 4, /* int_stmt_cost */
- 5, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 10, /* permute_cost */
- 6, /* reduc_i8_cost */
- 6, /* reduc_i16_cost */
- 6, /* reduc_i32_cost */
- 6, /* reduc_i64_cost */
- 6, /* reduc_f16_cost */
- 6, /* reduc_f32_cost */
- 6, /* reduc_f64_cost */
- 6, /* store_elt_extra_cost */
- 6, /* vec_to_scalar_cost */
- 5, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-/* Costs for vector insn classes for Vulcan. */
-static const struct cpu_vector_cost thunderx2t99_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 6, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 2, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &thunderx2t99_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost thunderx3t110_advsimd_vector_cost =
-{
- 5, /* int_stmt_cost */
- 5, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 10, /* permute_cost */
- 5, /* reduc_i8_cost */
- 5, /* reduc_i16_cost */
- 5, /* reduc_i32_cost */
- 5, /* reduc_i64_cost */
- 5, /* reduc_f16_cost */
- 5, /* reduc_f32_cost */
- 5, /* reduc_f64_cost */
- 5, /* store_elt_extra_cost */
- 5, /* vec_to_scalar_cost */
- 5, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- 4, /* unalign_store_cost */
- 4 /* store_cost */
-};
-
-static const struct cpu_vector_cost thunderx3t110_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 5, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 2, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &thunderx3t110_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-static const advsimd_vec_cost ampere1_advsimd_vector_cost =
-{
- 1, /* int_stmt_cost */
- 3, /* fp_stmt_cost */
- 0, /* ld2_st2_permute_cost */
- 0, /* ld3_st3_permute_cost */
- 0, /* ld4_st4_permute_cost */
- 2, /* permute_cost */
- 12, /* reduc_i8_cost */
- 9, /* reduc_i16_cost */
- 6, /* reduc_i32_cost */
- 5, /* reduc_i64_cost */
- 9, /* reduc_f16_cost */
- 6, /* reduc_f32_cost */
- 5, /* reduc_f64_cost */
- 8, /* store_elt_extra_cost */
- 6, /* vec_to_scalar_cost */
- 7, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-/* Ampere-1 costs for vector insn classes. */
-static const struct cpu_vector_cost ampere1_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 3, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &ampere1_advsimd_vector_cost, /* advsimd */
- nullptr, /* sve */
- nullptr /* issue_info */
-};
-
-/* Generic costs for branch instructions. */
-static const struct cpu_branch_cost generic_branch_cost =
-{
- 1, /* Predictable. */
- 3 /* Unpredictable. */
-};
-
-/* Generic approximation modes. */
-static const cpu_approx_modes generic_approx_modes =
-{
- AARCH64_APPROX_NONE, /* division */
- AARCH64_APPROX_NONE, /* sqrt */
- AARCH64_APPROX_NONE /* recip_sqrt */
-};
-
-/* Approximation modes for Exynos M1. */
-static const cpu_approx_modes exynosm1_approx_modes =
-{
- AARCH64_APPROX_NONE, /* division */
- AARCH64_APPROX_ALL, /* sqrt */
- AARCH64_APPROX_ALL /* recip_sqrt */
-};
-
-/* Approximation modes for X-Gene 1. */
-static const cpu_approx_modes xgene1_approx_modes =
-{
- AARCH64_APPROX_NONE, /* division */
- AARCH64_APPROX_NONE, /* sqrt */
- AARCH64_APPROX_ALL /* recip_sqrt */
-};
-
-/* Generic prefetch settings (which disable prefetch). */
-static const cpu_prefetch_tune generic_prefetch_tune =
-{
- 0, /* num_slots */
- -1, /* l1_cache_size */
- -1, /* l1_cache_line_size */
- -1, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune exynosm1_prefetch_tune =
-{
- 0, /* num_slots */
- -1, /* l1_cache_size */
- 64, /* l1_cache_line_size */
- -1, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune qdf24xx_prefetch_tune =
-{
- 4, /* num_slots */
- 32, /* l1_cache_size */
- 64, /* l1_cache_line_size */
- 512, /* l2_cache_size */
- false, /* prefetch_dynamic_strides */
- 2048, /* minimum_stride */
- 3 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune thunderxt88_prefetch_tune =
-{
- 8, /* num_slots */
- 32, /* l1_cache_size */
- 128, /* l1_cache_line_size */
- 16*1024, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- 3 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune thunderx_prefetch_tune =
-{
- 8, /* num_slots */
- 32, /* l1_cache_size */
- 128, /* l1_cache_line_size */
- -1, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune thunderx2t99_prefetch_tune =
-{
- 8, /* num_slots */
- 32, /* l1_cache_size */
- 64, /* l1_cache_line_size */
- 256, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune thunderx3t110_prefetch_tune =
-{
- 8, /* num_slots */
- 32, /* l1_cache_size */
- 64, /* l1_cache_line_size */
- 256, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune tsv110_prefetch_tune =
-{
- 0, /* num_slots */
- 64, /* l1_cache_size */
- 64, /* l1_cache_line_size */
- 512, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune xgene1_prefetch_tune =
-{
- 8, /* num_slots */
- 32, /* l1_cache_size */
- 64, /* l1_cache_line_size */
- 256, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune a64fx_prefetch_tune =
-{
- 8, /* num_slots */
- 64, /* l1_cache_size */
- 256, /* l1_cache_line_size */
- 32768, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const cpu_prefetch_tune ampere1_prefetch_tune =
-{
- 0, /* num_slots */
- 64, /* l1_cache_size */
- 64, /* l1_cache_line_size */
- 2048, /* l2_cache_size */
- true, /* prefetch_dynamic_strides */
- -1, /* minimum_stride */
- -1 /* default_opt_level */
-};
-
-static const struct tune_params generic_tunings =
-{
- &cortexa57_extra_costs,
- &generic_addrcost_table,
- &generic_regmove_cost,
- &generic_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 2, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
- "16:12", /* function_align. */
- "4", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- /* Enabling AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS significantly benefits
- Neoverse V1. It does not have a noticeable effect on A64FX and should
- have at most a very minor effect on SVE2 cores. */
- (AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params cortexa35_tunings =
-{
- &cortexa53_extra_costs,
- &generic_addrcost_table,
- &cortexa53_regmove_cost,
- &generic_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 1, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
- | AARCH64_FUSE_MOVK_MOVK | AARCH64_FUSE_ADRP_LDR), /* fusible_ops */
- "16", /* function_align. */
- "4", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params cortexa53_tunings =
-{
- &cortexa53_extra_costs,
- &generic_addrcost_table,
- &cortexa53_regmove_cost,
- &generic_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 2, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
- | AARCH64_FUSE_MOVK_MOVK | AARCH64_FUSE_ADRP_LDR), /* fusible_ops */
- "16", /* function_align. */
- "4", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params cortexa57_tunings =
-{
- &cortexa57_extra_costs,
- &generic_addrcost_table,
- &cortexa57_regmove_cost,
- &cortexa57_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 3, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
- | AARCH64_FUSE_MOVK_MOVK), /* fusible_ops */
- "16", /* function_align. */
- "4", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_RENAME_FMA_REGS), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params cortexa72_tunings =
-{
- &cortexa57_extra_costs,
- &generic_addrcost_table,
- &cortexa57_regmove_cost,
- &cortexa57_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 3, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
- | AARCH64_FUSE_MOVK_MOVK), /* fusible_ops */
- "16", /* function_align. */
- "4", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params cortexa73_tunings =
-{
- &cortexa57_extra_costs,
- &generic_addrcost_table,
- &cortexa57_regmove_cost,
- &cortexa57_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 2, /* issue_rate. */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
- | AARCH64_FUSE_MOVK_MOVK | AARCH64_FUSE_ADRP_LDR), /* fusible_ops */
- "16", /* function_align. */
- "4", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params exynosm1_tunings =
-{
- &exynosm1_extra_costs,
- &exynosm1_addrcost_table,
- &exynosm1_regmove_cost,
- &exynosm1_vector_cost,
- &generic_branch_cost,
- &exynosm1_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 3, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC), /* fusible_ops */
- "4", /* function_align. */
- "4", /* jump_align. */
- "4", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 48, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &exynosm1_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params thunderxt88_tunings =
-{
- &thunderx_extra_costs,
- &generic_addrcost_table,
- &thunderx_regmove_cost,
- &thunderx_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 6, /* load_int. */
- 6, /* store_int. */
- 6, /* load_fp. */
- 6, /* store_fp. */
- 6, /* load_pred. */
- 6 /* store_pred. */
- }, /* memmov_cost. */
- 2, /* issue_rate */
- AARCH64_FUSE_ALU_BRANCH, /* fusible_ops */
- "8", /* function_align. */
- "8", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &thunderxt88_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
-};
-
-static const struct tune_params thunderx_tunings =
-{
- &thunderx_extra_costs,
- &generic_addrcost_table,
- &thunderx_regmove_cost,
- &thunderx_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 6, /* load_int. */
- 6, /* store_int. */
- 6, /* load_fp. */
- 6, /* store_fp. */
- 6, /* load_pred. */
- 6 /* store_pred. */
- }, /* memmov_cost. */
- 2, /* issue_rate */
- AARCH64_FUSE_ALU_BRANCH, /* fusible_ops */
- "8", /* function_align. */
- "8", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND), /* tune_flags. */
- &thunderx_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
-};
-
-static const struct tune_params tsv110_tunings =
-{
- &tsv110_extra_costs,
- &tsv110_addrcost_table,
- &tsv110_regmove_cost,
- &tsv110_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_ALU_BRANCH
- | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */
- "16", /* function_align. */
- "4", /* jump_align. */
- "8", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &tsv110_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params xgene1_tunings =
-{
- &xgene1_extra_costs,
- &xgene1_addrcost_table,
- &xgene1_regmove_cost,
- &xgene1_vector_cost,
- &generic_branch_cost,
- &xgene1_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 6, /* load_int. */
- 6, /* store_int. */
- 6, /* load_fp. */
- 6, /* store_fp. */
- 6, /* load_pred. */
- 6 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate */
- AARCH64_FUSE_NOTHING, /* fusible_ops */
- "16", /* function_align. */
- "16", /* jump_align. */
- "16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 17, /* max_case_values. */
- tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS), /* tune_flags. */
- &xgene1_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params emag_tunings =
-{
- &xgene1_extra_costs,
- &xgene1_addrcost_table,
- &xgene1_regmove_cost,
- &xgene1_vector_cost,
- &generic_branch_cost,
- &xgene1_approx_modes,
- SVE_NOT_IMPLEMENTED,
- { 6, /* load_int. */
- 6, /* store_int. */
- 6, /* load_fp. */
- 6, /* store_fp. */
- 6, /* load_pred. */
- 6 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate */
- AARCH64_FUSE_NOTHING, /* fusible_ops */
- "16", /* function_align. */
- "16", /* jump_align. */
- "16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 17, /* max_case_values. */
- tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS), /* tune_flags. */
- &xgene1_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params qdf24xx_tunings =
-{
- &qdf24xx_extra_costs,
- &qdf24xx_addrcost_table,
- &qdf24xx_regmove_cost,
- &qdf24xx_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate */
- (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
- | AARCH64_FUSE_MOVK_MOVK), /* fuseable_ops */
- "16", /* function_align. */
- "8", /* jump_align. */
- "16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- AARCH64_EXTRA_TUNE_RENAME_LOAD_REGS, /* tune_flags. */
- &qdf24xx_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-/* Tuning structure for the Qualcomm Saphira core. Default to falkor values
- for now. */
-static const struct tune_params saphira_tunings =
-{
- &generic_extra_costs,
- &generic_addrcost_table,
- &generic_regmove_cost,
- &generic_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate */
- (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
- | AARCH64_FUSE_MOVK_MOVK), /* fuseable_ops */
- "16", /* function_align. */
- "8", /* jump_align. */
- "16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 1, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params thunderx2t99_tunings =
-{
- &thunderx2t99_extra_costs,
- &thunderx2t99_addrcost_table,
- &thunderx2t99_regmove_cost,
- &thunderx2t99_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate. */
- (AARCH64_FUSE_ALU_BRANCH | AARCH64_FUSE_AES_AESMC
- | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */
- "16", /* function_align. */
- "8", /* jump_align. */
- "16", /* loop_align. */
- 3, /* int_reassoc_width. */
- 2, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &thunderx2t99_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params thunderx3t110_tunings =
-{
- &thunderx3t110_extra_costs,
- &thunderx3t110_addrcost_table,
- &thunderx3t110_regmove_cost,
- &thunderx3t110_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 6, /* issue_rate. */
- (AARCH64_FUSE_ALU_BRANCH | AARCH64_FUSE_AES_AESMC
- | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */
- "16", /* function_align. */
- "8", /* jump_align. */
- "16", /* loop_align. */
- 3, /* int_reassoc_width. */
- 2, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &thunderx3t110_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params neoversen1_tunings =
-{
- &cortexa76_extra_costs,
- &generic_addrcost_table,
- &generic_regmove_cost,
- &cortexa57_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 2, /* store_int. */
- 5, /* load_fp. */
- 2, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 3, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
- "32:16", /* function_align. */
- "4", /* jump_align. */
- "32:16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params ampere1_tunings =
-{
- &ampere1_extra_costs,
- &generic_addrcost_table,
- &generic_regmove_cost,
- &ampere1_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate */
- (AARCH64_FUSE_ADRP_ADD | AARCH64_FUSE_AES_AESMC |
- AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_MOVK_MOVK |
- AARCH64_FUSE_ALU_BRANCH /* adds, ands, bics, ccmp, ccmn */ |
- AARCH64_FUSE_CMP_BRANCH),
- /* fusible_ops */
- "32", /* function_align. */
- "4", /* jump_align. */
- "32:16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 4, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &ampere1_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
-};
-
-static const struct tune_params ampere1a_tunings =
-{
- &ampere1a_extra_costs,
- &generic_addrcost_table,
- &generic_regmove_cost,
- &ampere1_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_NOT_IMPLEMENTED, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 4, /* issue_rate */
- (AARCH64_FUSE_ADRP_ADD | AARCH64_FUSE_AES_AESMC |
- AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_MOVK_MOVK |
- AARCH64_FUSE_ALU_BRANCH /* adds, ands, bics, ccmp, ccmn */ |
- AARCH64_FUSE_CMP_BRANCH | AARCH64_FUSE_ALU_CBZ |
- AARCH64_FUSE_ADDSUB_2REG_CONST1),
- /* fusible_ops */
- "32", /* function_align. */
- "4", /* jump_align. */
- "32:16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &ampere1_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
-};
-
-static const advsimd_vec_cost neoversev1_advsimd_vector_cost =
-{
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 4, /* ld2_st2_permute_cost */
- 4, /* ld3_st3_permute_cost */
- 5, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- 4, /* reduc_i8_cost */
- 4, /* reduc_i16_cost */
- 2, /* reduc_i32_cost */
- 2, /* reduc_i64_cost */
- 6, /* reduc_f16_cost */
- 3, /* reduc_f32_cost */
- 2, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- /* This value is just inherited from the Cortex-A57 table. */
- 8, /* vec_to_scalar_cost */
- /* This depends very much on what the scalar value is and
- where it comes from. E.g. some constants take two dependent
- instructions or a load, while others might be moved from a GPR.
- 4 seems to be a reasonable compromise in practice. */
- 4, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- /* Although stores have a latency of 2 and compete for the
- vector pipes, in practice it's better not to model that. */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-static const sve_vec_cost neoversev1_sve_vector_cost =
-{
- {
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 4, /* ld2_st2_permute_cost */
- 7, /* ld3_st3_permute_cost */
- 8, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- /* Theoretically, a reduction involving 31 scalar ADDs could
- complete in ~9 cycles and would have a cost of 31. [SU]ADDV
- completes in 14 cycles, so give it a cost of 31 + 5. */
- 36, /* reduc_i8_cost */
- /* Likewise for 15 scalar ADDs (~5 cycles) vs. 12: 15 + 7. */
- 22, /* reduc_i16_cost */
- /* Likewise for 7 scalar ADDs (~3 cycles) vs. 10: 7 + 7. */
- 14, /* reduc_i32_cost */
- /* Likewise for 3 scalar ADDs (~2 cycles) vs. 10: 3 + 8. */
- 11, /* reduc_i64_cost */
- /* Theoretically, a reduction involving 15 scalar FADDs could
- complete in ~9 cycles and would have a cost of 30. FADDV
- completes in 13 cycles, so give it a cost of 30 + 4. */
- 34, /* reduc_f16_cost */
- /* Likewise for 7 scalar FADDs (~6 cycles) vs. 11: 14 + 5. */
- 19, /* reduc_f32_cost */
- /* Likewise for 3 scalar FADDs (~4 cycles) vs. 9: 6 + 5. */
- 11, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- /* This value is just inherited from the Cortex-A57 table. */
- 8, /* vec_to_scalar_cost */
- /* See the comment above the Advanced SIMD versions. */
- 4, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- /* Although stores have a latency of 2 and compete for the
- vector pipes, in practice it's better not to model that. */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
- },
- 3, /* clast_cost */
- 19, /* fadda_f16_cost */
- 11, /* fadda_f32_cost */
- 8, /* fadda_f64_cost */
- 32, /* gather_load_x32_cost */
- 16, /* gather_load_x64_cost */
- 3 /* scatter_store_elt_cost */
-};
-
-static const aarch64_scalar_vec_issue_info neoversev1_scalar_issue_info =
-{
- 3, /* loads_stores_per_cycle */
- 2, /* stores_per_cycle */
- 4, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
-};
-
-static const aarch64_advsimd_vec_issue_info neoversev1_advsimd_issue_info =
-{
- {
- 3, /* loads_stores_per_cycle */
- 2, /* stores_per_cycle */
- 4, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
- },
- 2, /* ld2_st2_general_ops */
- 2, /* ld3_st3_general_ops */
- 3 /* ld4_st4_general_ops */
-};
-
-static const aarch64_sve_vec_issue_info neoversev1_sve_issue_info =
-{
- {
- {
- 2, /* loads_per_cycle */
- 2, /* stores_per_cycle */
- 2, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
- },
- 2, /* ld2_st2_general_ops */
- 2, /* ld3_st3_general_ops */
- 3 /* ld4_st4_general_ops */
- },
- 1, /* pred_ops_per_cycle */
- 2, /* while_pred_ops */
- 2, /* int_cmp_pred_ops */
- 1, /* fp_cmp_pred_ops */
- 1, /* gather_scatter_pair_general_ops */
- 1 /* gather_scatter_pair_pred_ops */
-};
-
-static const aarch64_vec_issue_info neoversev1_vec_issue_info =
-{
- &neoversev1_scalar_issue_info,
- &neoversev1_advsimd_issue_info,
- &neoversev1_sve_issue_info
-};
-
-/* Neoverse V1 costs for vector insn classes. */
-static const struct cpu_vector_cost neoversev1_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 2, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &neoversev1_advsimd_vector_cost, /* advsimd */
- &neoversev1_sve_vector_cost, /* sve */
- &neoversev1_vec_issue_info /* issue_info */
-};
-
-static const struct tune_params neoversev1_tunings =
-{
- &cortexa76_extra_costs,
- &neoversev1_addrcost_table,
- &neoversev1_regmove_cost,
- &neoversev1_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_256, /* sve_width */
- { 4, /* load_int. */
- 2, /* store_int. */
- 6, /* load_fp. */
- 2, /* store_fp. */
- 6, /* load_pred. */
- 1 /* store_pred. */
- }, /* memmov_cost. */
- 3, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
- "32:16", /* function_align. */
- "4", /* jump_align. */
- "32:16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 4, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
- | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
- | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT
- | AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const sve_vec_cost neoverse512tvb_sve_vector_cost =
-{
- {
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 4, /* ld2_st2_permute_cost */
- 5, /* ld3_st3_permute_cost */
- 5, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- /* Theoretically, a reduction involving 15 scalar ADDs could
- complete in ~5 cycles and would have a cost of 15. Assume that
- [SU]ADDV completes in 11 cycles and so give it a cost of 15 + 6. */
- 21, /* reduc_i8_cost */
- /* Likewise for 7 scalar ADDs (~3 cycles) vs. 9: 7 + 6. */
- 13, /* reduc_i16_cost */
- /* Likewise for 3 scalar ADDs (~2 cycles) vs. 8: 3 + 6. */
- 9, /* reduc_i32_cost */
- /* Likewise for 1 scalar ADD (1 cycle) vs. 8: 1 + 7. */
- 8, /* reduc_i64_cost */
- /* Theoretically, a reduction involving 7 scalar FADDs could
- complete in ~6 cycles and would have a cost of 14. Assume that
- FADDV completes in 8 cycles and so give it a cost of 14 + 2. */
- 16, /* reduc_f16_cost */
- /* Likewise for 3 scalar FADDs (~4 cycles) vs. 6: 6 + 2. */
- 8, /* reduc_f32_cost */
- /* Likewise for 1 scalar FADD (2 cycles) vs. 4: 2 + 2. */
- 4, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- /* This value is just inherited from the Cortex-A57 table. */
- 8, /* vec_to_scalar_cost */
- /* This depends very much on what the scalar value is and
- where it comes from. E.g. some constants take two dependent
- instructions or a load, while others might be moved from a GPR.
- 4 seems to be a reasonable compromise in practice. */
- 4, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- /* Although stores generally have a latency of 2 and compete for the
- vector pipes, in practice it's better not to model that. */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
- },
- 3, /* clast_cost */
- 10, /* fadda_f16_cost */
- 6, /* fadda_f32_cost */
- 4, /* fadda_f64_cost */
- /* A strided Advanced SIMD x64 load would take two parallel FP loads
- (6 cycles) plus an insertion (2 cycles). Assume a 64-bit SVE gather
- is 1 cycle more. The Advanced SIMD version is costed as 2 scalar loads
- (cost 8) and a vec_construct (cost 2). Add a full vector operation
- (cost 2) to that, to avoid the difference being lost in rounding.
-
- There is no easy comparison between a strided Advanced SIMD x32 load
- and an SVE 32-bit gather, but cost an SVE 32-bit gather as 1 vector
- operation more than a 64-bit gather. */
- 14, /* gather_load_x32_cost */
- 12, /* gather_load_x64_cost */
- 3 /* scatter_store_elt_cost */
-};
-
-static const aarch64_sve_vec_issue_info neoverse512tvb_sve_issue_info =
-{
- {
- {
- 3, /* loads_per_cycle */
- 2, /* stores_per_cycle */
- 4, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
- },
- 2, /* ld2_st2_general_ops */
- 2, /* ld3_st3_general_ops */
- 3 /* ld4_st4_general_ops */
- },
- 2, /* pred_ops_per_cycle */
- 2, /* while_pred_ops */
- 2, /* int_cmp_pred_ops */
- 1, /* fp_cmp_pred_ops */
- 1, /* gather_scatter_pair_general_ops */
- 1 /* gather_scatter_pair_pred_ops */
-};
-
-static const aarch64_vec_issue_info neoverse512tvb_vec_issue_info =
-{
- &neoversev1_scalar_issue_info,
- &neoversev1_advsimd_issue_info,
- &neoverse512tvb_sve_issue_info
-};
-
-static const struct cpu_vector_cost neoverse512tvb_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 2, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &neoversev1_advsimd_vector_cost, /* advsimd */
- &neoverse512tvb_sve_vector_cost, /* sve */
- &neoverse512tvb_vec_issue_info /* issue_info */
-};
-
-static const struct tune_params neoverse512tvb_tunings =
-{
- &cortexa76_extra_costs,
- &neoversev1_addrcost_table,
- &neoversev1_regmove_cost,
- &neoverse512tvb_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_128 | SVE_256, /* sve_width */
- { 4, /* load_int. */
- 2, /* store_int. */
- 6, /* load_fp. */
- 2, /* store_fp. */
- 6, /* load_pred. */
- 1 /* store_pred. */
- }, /* memmov_cost. */
- 3, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
- "32:16", /* function_align. */
- "4", /* jump_align. */
- "32:16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 4, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
- | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
- | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const advsimd_vec_cost neoversen2_advsimd_vector_cost =
-{
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 2, /* ld2_st2_permute_cost */
- 2, /* ld3_st3_permute_cost */
- 3, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- 4, /* reduc_i8_cost */
- 4, /* reduc_i16_cost */
- 2, /* reduc_i32_cost */
- 2, /* reduc_i64_cost */
- 6, /* reduc_f16_cost */
- 4, /* reduc_f32_cost */
- 2, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- /* This value is just inherited from the Cortex-A57 table. */
- 8, /* vec_to_scalar_cost */
- /* This depends very much on what the scalar value is and
- where it comes from. E.g. some constants take two dependent
- instructions or a load, while others might be moved from a GPR.
- 4 seems to be a reasonable compromise in practice. */
- 4, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- /* Although stores have a latency of 2 and compete for the
- vector pipes, in practice it's better not to model that. */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-static const sve_vec_cost neoversen2_sve_vector_cost =
-{
- {
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 3, /* ld2_st2_permute_cost */
- 4, /* ld3_st3_permute_cost */
- 4, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- /* Theoretically, a reduction involving 15 scalar ADDs could
- complete in ~5 cycles and would have a cost of 15. [SU]ADDV
- completes in 11 cycles, so give it a cost of 15 + 6. */
- 21, /* reduc_i8_cost */
- /* Likewise for 7 scalar ADDs (~3 cycles) vs. 9: 7 + 6. */
- 13, /* reduc_i16_cost */
- /* Likewise for 3 scalar ADDs (~2 cycles) vs. 8: 3 + 6. */
- 9, /* reduc_i32_cost */
- /* Likewise for 1 scalar ADD (~1 cycles) vs. 2: 1 + 1. */
- 2, /* reduc_i64_cost */
- /* Theoretically, a reduction involving 7 scalar FADDs could
- complete in ~8 cycles and would have a cost of 14. FADDV
- completes in 6 cycles, so give it a cost of 14 - 2. */
- 12, /* reduc_f16_cost */
- /* Likewise for 3 scalar FADDs (~4 cycles) vs. 4: 6 - 0. */
- 6, /* reduc_f32_cost */
- /* Likewise for 1 scalar FADD (~2 cycles) vs. 2: 2 - 0. */
- 2, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- /* This value is just inherited from the Cortex-A57 table. */
- 8, /* vec_to_scalar_cost */
- /* See the comment above the Advanced SIMD versions. */
- 4, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- /* Although stores have a latency of 2 and compete for the
- vector pipes, in practice it's better not to model that. */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
- },
- 3, /* clast_cost */
- 10, /* fadda_f16_cost */
- 6, /* fadda_f32_cost */
- 4, /* fadda_f64_cost */
- /* A strided Advanced SIMD x64 load would take two parallel FP loads
- (8 cycles) plus an insertion (2 cycles). Assume a 64-bit SVE gather
- is 1 cycle more. The Advanced SIMD version is costed as 2 scalar loads
- (cost 8) and a vec_construct (cost 2). Add a full vector operation
- (cost 2) to that, to avoid the difference being lost in rounding.
-
- There is no easy comparison between a strided Advanced SIMD x32 load
- and an SVE 32-bit gather, but cost an SVE 32-bit gather as 1 vector
- operation more than a 64-bit gather. */
- 14, /* gather_load_x32_cost */
- 12, /* gather_load_x64_cost */
- 3 /* scatter_store_elt_cost */
-};
-
-static const aarch64_scalar_vec_issue_info neoversen2_scalar_issue_info =
-{
- 3, /* loads_stores_per_cycle */
- 2, /* stores_per_cycle */
- 4, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
-};
-
-static const aarch64_advsimd_vec_issue_info neoversen2_advsimd_issue_info =
-{
- {
- 3, /* loads_stores_per_cycle */
- 2, /* stores_per_cycle */
- 2, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
- },
- 2, /* ld2_st2_general_ops */
- 2, /* ld3_st3_general_ops */
- 3 /* ld4_st4_general_ops */
-};
-
-static const aarch64_sve_vec_issue_info neoversen2_sve_issue_info =
-{
- {
- {
- 3, /* loads_per_cycle */
- 2, /* stores_per_cycle */
- 2, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
- },
- 2, /* ld2_st2_general_ops */
- 3, /* ld3_st3_general_ops */
- 3 /* ld4_st4_general_ops */
- },
- 2, /* pred_ops_per_cycle */
- 2, /* while_pred_ops */
- 2, /* int_cmp_pred_ops */
- 1, /* fp_cmp_pred_ops */
- 1, /* gather_scatter_pair_general_ops */
- 1 /* gather_scatter_pair_pred_ops */
-};
-
-static const aarch64_vec_issue_info neoversen2_vec_issue_info =
-{
- &neoversen2_scalar_issue_info,
- &neoversen2_advsimd_issue_info,
- &neoversen2_sve_issue_info
-};
-
-/* Neoverse N2 costs for vector insn classes. */
-static const struct cpu_vector_cost neoversen2_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 2, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &neoversen2_advsimd_vector_cost, /* advsimd */
- &neoversen2_sve_vector_cost, /* sve */
- &neoversen2_vec_issue_info /* issue_info */
-};
-
-static const struct tune_params neoversen2_tunings =
-{
- &cortexa76_extra_costs,
- &neoversen2_addrcost_table,
- &neoversen2_regmove_cost,
- &neoversen2_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_128, /* sve_width */
- { 4, /* load_int. */
- 1, /* store_int. */
- 6, /* load_fp. */
- 2, /* store_fp. */
- 6, /* load_pred. */
- 1 /* store_pred. */
- }, /* memmov_cost. */
- 3, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
- "32:16", /* function_align. */
- "4", /* jump_align. */
- "32:16", /* loop_align. */
- 2, /* int_reassoc_width. */
- 4, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND
- | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
- | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
- | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const advsimd_vec_cost neoversev2_advsimd_vector_cost =
-{
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 2, /* ld2_st2_permute_cost */
- 2, /* ld3_st3_permute_cost */
- 3, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- 4, /* reduc_i8_cost */
- 4, /* reduc_i16_cost */
- 2, /* reduc_i32_cost */
- 2, /* reduc_i64_cost */
- 6, /* reduc_f16_cost */
- 3, /* reduc_f32_cost */
- 2, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- /* This value is just inherited from the Cortex-A57 table. */
- 8, /* vec_to_scalar_cost */
- /* This depends very much on what the scalar value is and
- where it comes from. E.g. some constants take two dependent
- instructions or a load, while others might be moved from a GPR.
- 4 seems to be a reasonable compromise in practice. */
- 4, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- /* Although stores have a latency of 2 and compete for the
- vector pipes, in practice it's better not to model that. */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
-};
-
-static const sve_vec_cost neoversev2_sve_vector_cost =
-{
- {
- 2, /* int_stmt_cost */
- 2, /* fp_stmt_cost */
- 3, /* ld2_st2_permute_cost */
- 3, /* ld3_st3_permute_cost */
- 4, /* ld4_st4_permute_cost */
- 3, /* permute_cost */
- /* Theoretically, a reduction involving 15 scalar ADDs could
- complete in ~3 cycles and would have a cost of 15. [SU]ADDV
- completes in 11 cycles, so give it a cost of 15 + 8. */
- 21, /* reduc_i8_cost */
- /* Likewise for 7 scalar ADDs (~2 cycles) vs. 9: 7 + 7. */
- 14, /* reduc_i16_cost */
- /* Likewise for 3 scalar ADDs (~2 cycles) vs. 8: 3 + 4. */
- 7, /* reduc_i32_cost */
- /* Likewise for 1 scalar ADD (~1 cycles) vs. 2: 1 + 1. */
- 2, /* reduc_i64_cost */
- /* Theoretically, a reduction involving 7 scalar FADDs could
- complete in ~6 cycles and would have a cost of 14. FADDV
- completes in 8 cycles, so give it a cost of 14 + 2. */
- 16, /* reduc_f16_cost */
- /* Likewise for 3 scalar FADDs (~4 cycles) vs. 6: 6 + 2. */
- 8, /* reduc_f32_cost */
- /* Likewise for 1 scalar FADD (~2 cycles) vs. 4: 2 + 2. */
- 4, /* reduc_f64_cost */
- 2, /* store_elt_extra_cost */
- /* This value is just inherited from the Cortex-A57 table. */
- 8, /* vec_to_scalar_cost */
- /* See the comment above the Advanced SIMD versions. */
- 4, /* scalar_to_vec_cost */
- 4, /* align_load_cost */
- 4, /* unalign_load_cost */
- /* Although stores have a latency of 2 and compete for the
- vector pipes, in practice it's better not to model that. */
- 1, /* unalign_store_cost */
- 1 /* store_cost */
- },
- 3, /* clast_cost */
- 10, /* fadda_f16_cost */
- 6, /* fadda_f32_cost */
- 4, /* fadda_f64_cost */
- /* A strided Advanced SIMD x64 load would take two parallel FP loads
- (8 cycles) plus an insertion (2 cycles). Assume a 64-bit SVE gather
- is 1 cycle more. The Advanced SIMD version is costed as 2 scalar loads
- (cost 8) and a vec_construct (cost 2). Add a full vector operation
- (cost 2) to that, to avoid the difference being lost in rounding.
-
- There is no easy comparison between a strided Advanced SIMD x32 load
- and an SVE 32-bit gather, but cost an SVE 32-bit gather as 1 vector
- operation more than a 64-bit gather. */
- 14, /* gather_load_x32_cost */
- 12, /* gather_load_x64_cost */
- 3 /* scatter_store_elt_cost */
-};
-
-static const aarch64_scalar_vec_issue_info neoversev2_scalar_issue_info =
-{
- 3, /* loads_stores_per_cycle */
- 2, /* stores_per_cycle */
- 6, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
-};
-
-static const aarch64_advsimd_vec_issue_info neoversev2_advsimd_issue_info =
-{
- {
- 3, /* loads_stores_per_cycle */
- 2, /* stores_per_cycle */
- 4, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
- },
- 2, /* ld2_st2_general_ops */
- 2, /* ld3_st3_general_ops */
- 3 /* ld4_st4_general_ops */
-};
-
-static const aarch64_sve_vec_issue_info neoversev2_sve_issue_info =
-{
- {
- {
- 3, /* loads_per_cycle */
- 2, /* stores_per_cycle */
- 4, /* general_ops_per_cycle */
- 0, /* fp_simd_load_general_ops */
- 1 /* fp_simd_store_general_ops */
- },
- 2, /* ld2_st2_general_ops */
- 3, /* ld3_st3_general_ops */
- 3 /* ld4_st4_general_ops */
- },
- 2, /* pred_ops_per_cycle */
- 2, /* while_pred_ops */
- 2, /* int_cmp_pred_ops */
- 1, /* fp_cmp_pred_ops */
- 1, /* gather_scatter_pair_general_ops */
- 1 /* gather_scatter_pair_pred_ops */
-};
-
-static const aarch64_vec_issue_info neoversev2_vec_issue_info =
-{
- &neoversev2_scalar_issue_info,
- &neoversev2_advsimd_issue_info,
- &neoversev2_sve_issue_info
-};
-
-/* Demeter costs for vector insn classes. */
-static const struct cpu_vector_cost neoversev2_vector_cost =
-{
- 1, /* scalar_int_stmt_cost */
- 2, /* scalar_fp_stmt_cost */
- 4, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 1, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &neoversev2_advsimd_vector_cost, /* advsimd */
- &neoversev2_sve_vector_cost, /* sve */
- &neoversev2_vec_issue_info /* issue_info */
-};
-
-static const struct tune_params neoversev2_tunings =
-{
- &cortexa76_extra_costs,
- &neoversev2_addrcost_table,
- &neoversev2_regmove_cost,
- &neoversev2_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_128, /* sve_width */
- { 4, /* load_int. */
- 2, /* store_int. */
- 6, /* load_fp. */
- 1, /* store_fp. */
- 6, /* load_pred. */
- 2 /* store_pred. */
- }, /* memmov_cost. */
- 5, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
- "32:16", /* function_align. */
- "4", /* jump_align. */
- "32:16", /* loop_align. */
- 3, /* int_reassoc_width. */
- 6, /* fp_reassoc_width. */
- 4, /* fma_reassoc_width. */
- 3, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND
- | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
- | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
- | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
- &generic_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
-
-static const struct tune_params a64fx_tunings =
-{
- &a64fx_extra_costs,
- &a64fx_addrcost_table,
- &a64fx_regmove_cost,
- &a64fx_vector_cost,
- &generic_branch_cost,
- &generic_approx_modes,
- SVE_512, /* sve_width */
- { 4, /* load_int. */
- 4, /* store_int. */
- 4, /* load_fp. */
- 4, /* store_fp. */
- 4, /* load_pred. */
- 4 /* store_pred. */
- }, /* memmov_cost. */
- 7, /* issue_rate */
- (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
- "32", /* function_align. */
- "16", /* jump_align. */
- "32", /* loop_align. */
- 4, /* int_reassoc_width. */
- 2, /* fp_reassoc_width. */
- 1, /* fma_reassoc_width. */
- 2, /* vec_reassoc_width. */
- 2, /* min_div_recip_mul_sf. */
- 2, /* min_div_recip_mul_df. */
- 0, /* max_case_values. */
- tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
- &a64fx_prefetch_tune,
- AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
- AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
-};
+#include "tuning_models/generic.h"
+#include "tuning_models/generic_armv8_a.h"
+#include "tuning_models/generic_armv9_a.h"
+#include "tuning_models/cortexa35.h"
+#include "tuning_models/cortexa53.h"
+#include "tuning_models/cortexa57.h"
+#include "tuning_models/cortexa72.h"
+#include "tuning_models/cortexa73.h"
+#include "tuning_models/exynosm1.h"
+#include "tuning_models/thunderxt88.h"
+#include "tuning_models/thunderx.h"
+#include "tuning_models/tsv110.h"
+#include "tuning_models/xgene1.h"
+#include "tuning_models/emag.h"
+#include "tuning_models/qdf24xx.h"
+#include "tuning_models/saphira.h"
+#include "tuning_models/thunderx2t99.h"
+#include "tuning_models/thunderx3t110.h"
+#include "tuning_models/neoversen1.h"
+#include "tuning_models/ampere1.h"
+#include "tuning_models/ampere1a.h"
+#include "tuning_models/neoversev1.h"
+#include "tuning_models/neoverse512tvb.h"
+#include "tuning_models/neoversen2.h"
+#include "tuning_models/neoversev2.h"
+#include "tuning_models/a64fx.h"
/* Support for fine-grained override of the tuning structures. */
struct aarch64_tuning_override_function
@@ -2802,8 +429,6 @@ static const struct processor all_cores[] =
{NAME, IDENT, SCHED, AARCH64_ARCH_##ARCH, \
feature_deps::cpu_##IDENT, &COSTS##_tunings},
#include "aarch64-cores.def"
- {"generic", generic, cortexa53, AARCH64_ARCH_V8A,
- feature_deps::V8A ().enable, &generic_tunings},
{NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL}
};
@@ -17007,7 +14632,7 @@ aarch64_adjust_stmt_cost (vec_info *vinfo, vect_cost_for_stmt kind,
}
gassign *assign = dyn_cast<gassign *> (STMT_VINFO_STMT (stmt_info));
- if (assign)
+ if ((kind == scalar_stmt || kind == vector_stmt) && assign)
{
/* For MLA we need to reduce the cost since MLA is 1 instruction. */
if (!vect_is_reduction (stmt_info)
@@ -17088,15 +14713,18 @@ aarch64_vector_costs::count_ops (unsigned int count, vect_cost_for_stmt kind,
ops->reduction_latency = MAX (ops->reduction_latency, base);
}
- /* Assume that multiply-adds will become a single operation. */
- if (stmt_info && aarch64_multiply_add_p (m_vinfo, stmt_info, m_vec_flags))
- return;
+ if (stmt_info && (kind == scalar_stmt || kind == vector_stmt))
+ {
+ /* Assume that multiply-adds will become a single operation. */
+ if (aarch64_multiply_add_p (m_vinfo, stmt_info, m_vec_flags))
+ return;
+
+ /* Assume that bool AND with compare operands will become a single
+ operation. */
+ if (aarch64_bool_compound_p (m_vinfo, stmt_info, m_vec_flags))
+ return;
+ }
- /* Assume that bool AND with compare operands will become a single
- operation. */
- if (stmt_info
- && aarch64_bool_compound_p (m_vinfo, stmt_info, m_vec_flags))
- return;
/* Count the basic operation cost associated with KIND. */
switch (kind)
@@ -18808,12 +16436,22 @@ aarch64_override_options (void)
if (cpu && arch)
{
/* If both -mcpu and -march are specified, warn if they are not
- architecturally compatible and prefer the -march ISA flags. */
- if (arch->arch != cpu->arch)
- {
- warning (0, "switch %<-mcpu=%s%> conflicts with %<-march=%s%> switch",
+ feature compatible. feature compatible means that the inclusion of the
+ cpu features would end up disabling an achitecture feature. In
+ otherwords the cpu features need to be a strict superset of the arch
+ features and if so prefer the -march ISA flags. */
+ auto full_arch_flags = arch->flags | arch_isa;
+ auto full_cpu_flags = cpu->flags | cpu_isa;
+ if (~full_cpu_flags & full_arch_flags)
+ {
+ std::string ext_diff
+ = aarch64_get_extension_string_for_isa_flags (full_arch_flags,
+ full_cpu_flags);
+ warning (0, "switch %<-mcpu=%s%> conflicts with %<-march=%s%> switch "
+ "and resulted in options %<%s%> being added",
aarch64_cpu_string,
- aarch64_arch_string);
+ aarch64_arch_string,
+ ext_diff.c_str ());
}
selected_arch = arch->arch;
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 2f0777a..1ac2989 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -720,12 +720,11 @@ enum target_cpus
#define AARCH64_CORE(NAME, INTERNAL_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \
TARGET_CPU_##INTERNAL_IDENT,
#include "aarch64-cores.def"
- TARGET_CPU_generic
};
/* If there is no CPU defined at configure, use generic as default. */
#ifndef TARGET_CPU_DEFAULT
-# define TARGET_CPU_DEFAULT TARGET_CPU_generic
+# define TARGET_CPU_DEFAULT TARGET_CPU_generic_armv8_a
#endif
/* If inserting NOP before a mult-accumulate insn remember to adjust the
diff --git a/gcc/config/aarch64/tuning_models/a64fx.h b/gcc/config/aarch64/tuning_models/a64fx.h
new file mode 100644
index 0000000..7b06c27
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/a64fx.h
@@ -0,0 +1,169 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_A64FX
+#define GCC_AARCH64_H_A64FX
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table a64fx_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 1, /* si */
+ 1, /* di */
+ 2, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 0, /* post_modify_ld3_st3 */
+ 0, /* post_modify_ld4_st4 */
+ 2, /* register_offset */
+ 3, /* register_sextend */
+ 3, /* register_zextend */
+ 0, /* imm_offset */
+};
+
+static const struct cpu_regmove_cost a64fx_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ 5, /* GP2FP */
+ 7, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost a64fx_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 5, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 13, /* reduc_i8_cost */
+ 13, /* reduc_i16_cost */
+ 13, /* reduc_i32_cost */
+ 13, /* reduc_i64_cost */
+ 13, /* reduc_f16_cost */
+ 13, /* reduc_f32_cost */
+ 13, /* reduc_f64_cost */
+ 13, /* store_elt_extra_cost */
+ 13, /* vec_to_scalar_cost */
+ 4, /* scalar_to_vec_cost */
+ 6, /* align_load_cost */
+ 6, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+static const sve_vec_cost a64fx_sve_vector_cost =
+{
+ {
+ 2, /* int_stmt_cost */
+ 5, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 13, /* reduc_i8_cost */
+ 13, /* reduc_i16_cost */
+ 13, /* reduc_i32_cost */
+ 13, /* reduc_i64_cost */
+ 13, /* reduc_f16_cost */
+ 13, /* reduc_f32_cost */
+ 13, /* reduc_f64_cost */
+ 13, /* store_elt_extra_cost */
+ 13, /* vec_to_scalar_cost */
+ 4, /* scalar_to_vec_cost */
+ 6, /* align_load_cost */
+ 6, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 13, /* clast_cost */
+ 13, /* fadda_f16_cost */
+ 13, /* fadda_f32_cost */
+ 13, /* fadda_f64_cost */
+ 64, /* gather_load_x32_cost */
+ 32, /* gather_load_x64_cost */
+ 1 /* scatter_store_elt_cost */
+};
+
+static const struct cpu_vector_cost a64fx_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 5, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 3, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &a64fx_advsimd_vector_cost, /* advsimd */
+ &a64fx_sve_vector_cost, /* sve */
+ nullptr /* issue_info */
+};
+
+static const cpu_prefetch_tune a64fx_prefetch_tune =
+{
+ 8, /* num_slots */
+ 64, /* l1_cache_size */
+ 256, /* l1_cache_line_size */
+ 32768, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params a64fx_tunings =
+{
+ &a64fx_extra_costs,
+ &a64fx_addrcost_table,
+ &a64fx_regmove_cost,
+ &a64fx_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_512, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 7, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32", /* function_align. */
+ "16", /* jump_align. */
+ "32", /* loop_align. */
+ 4, /* int_reassoc_width. */
+ 2, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &a64fx_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_A64FX. */
diff --git a/gcc/config/aarch64/tuning_models/ampere1.h b/gcc/config/aarch64/tuning_models/ampere1.h
new file mode 100644
index 0000000..8d2a1c6
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/ampere1.h
@@ -0,0 +1,113 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_AMPERE1
+#define GCC_AARCH64_H_AMPERE1
+
+#include "generic.h"
+
+static const advsimd_vec_cost ampere1_advsimd_vector_cost =
+{
+ 1, /* int_stmt_cost */
+ 3, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 12, /* reduc_i8_cost */
+ 9, /* reduc_i16_cost */
+ 6, /* reduc_i32_cost */
+ 5, /* reduc_i64_cost */
+ 9, /* reduc_f16_cost */
+ 6, /* reduc_f32_cost */
+ 5, /* reduc_f64_cost */
+ 8, /* store_elt_extra_cost */
+ 6, /* vec_to_scalar_cost */
+ 7, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+/* Ampere-1 costs for vector insn classes. */
+static const struct cpu_vector_cost ampere1_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 3, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &ampere1_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+static const cpu_prefetch_tune ampere1_prefetch_tune =
+{
+ 0, /* num_slots */
+ 64, /* l1_cache_size */
+ 64, /* l1_cache_line_size */
+ 2048, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params ampere1_tunings =
+{
+ &ampere1_extra_costs,
+ &generic_addrcost_table,
+ &generic_regmove_cost,
+ &ampere1_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ (AARCH64_FUSE_ADRP_ADD | AARCH64_FUSE_AES_AESMC |
+ AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_MOVK_MOVK |
+ AARCH64_FUSE_ALU_BRANCH /* adds, ands, bics, ccmp, ccmn */ |
+ AARCH64_FUSE_CMP_BRANCH),
+ /* fusible_ops */
+ "32", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 4, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &ampere1_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_AMPERE1. */
diff --git a/gcc/config/aarch64/tuning_models/ampere1a.h b/gcc/config/aarch64/tuning_models/ampere1a.h
new file mode 100644
index 0000000..c419ffb
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/ampere1a.h
@@ -0,0 +1,65 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_AMPERE1A
+#define GCC_AARCH64_H_AMPERE1A
+
+#include "generic.h"
+
+static const struct tune_params ampere1a_tunings =
+{
+ &ampere1a_extra_costs,
+ &generic_addrcost_table,
+ &generic_regmove_cost,
+ &ampere1_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ (AARCH64_FUSE_ADRP_ADD | AARCH64_FUSE_AES_AESMC |
+ AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_MOVK_MOVK |
+ AARCH64_FUSE_ALU_BRANCH /* adds, ands, bics, ccmp, ccmn */ |
+ AARCH64_FUSE_CMP_BRANCH | AARCH64_FUSE_ALU_CBZ |
+ AARCH64_FUSE_ADDSUB_2REG_CONST1),
+ /* fusible_ops */
+ "32", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &ampere1_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_AMPERE1A. */
diff --git a/gcc/config/aarch64/tuning_models/cortexa35.h b/gcc/config/aarch64/tuning_models/cortexa35.h
new file mode 100644
index 0000000..5534335
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/cortexa35.h
@@ -0,0 +1,62 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_CORTEXA35
+#define GCC_AARCH64_H_CORTEXA35
+
+#include "generic.h"
+#include "cortexa53.h"
+
+static const struct tune_params cortexa35_tunings =
+{
+ &cortexa53_extra_costs,
+ &generic_addrcost_table,
+ &cortexa53_regmove_cost,
+ &generic_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 1, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+ | AARCH64_FUSE_MOVK_MOVK | AARCH64_FUSE_ADRP_LDR), /* fusible_ops */
+ "16", /* function_align. */
+ "4", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_CORTEXA35. */
diff --git a/gcc/config/aarch64/tuning_models/cortexa53.h b/gcc/config/aarch64/tuning_models/cortexa53.h
new file mode 100644
index 0000000..9dfdccc
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/cortexa53.h
@@ -0,0 +1,71 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_CORTEXA53
+#define GCC_AARCH64_H_CORTEXA53
+
+#include "generic.h"
+
+static const struct cpu_regmove_cost cortexa53_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ 5, /* GP2FP */
+ 5, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const struct tune_params cortexa53_tunings =
+{
+ &cortexa53_extra_costs,
+ &generic_addrcost_table,
+ &cortexa53_regmove_cost,
+ &generic_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 2, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+ | AARCH64_FUSE_MOVK_MOVK | AARCH64_FUSE_ADRP_LDR), /* fusible_ops */
+ "16", /* function_align. */
+ "4", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_CORTEXA53. */
diff --git a/gcc/config/aarch64/tuning_models/cortexa57.h b/gcc/config/aarch64/tuning_models/cortexa57.h
new file mode 100644
index 0000000..9c4789d
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/cortexa57.h
@@ -0,0 +1,109 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_CORTEXA57
+#define GCC_AARCH64_H_CORTEXA57
+
+#include "generic.h"
+
+static const struct cpu_regmove_cost cortexa57_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ 5, /* GP2FP */
+ 5, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost cortexa57_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 8, /* reduc_i8_cost */
+ 8, /* reduc_i16_cost */
+ 8, /* reduc_i32_cost */
+ 8, /* reduc_i64_cost */
+ 8, /* reduc_f16_cost */
+ 8, /* reduc_f32_cost */
+ 8, /* reduc_f64_cost */
+ 8, /* store_elt_extra_cost */
+ 8, /* vec_to_scalar_cost */
+ 8, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+/* Cortex-A57 costs for vector insn classes. */
+static const struct cpu_vector_cost cortexa57_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &cortexa57_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+static const struct tune_params cortexa57_tunings =
+{
+ &cortexa57_extra_costs,
+ &generic_addrcost_table,
+ &cortexa57_regmove_cost,
+ &cortexa57_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+ | AARCH64_FUSE_MOVK_MOVK), /* fusible_ops */
+ "16", /* function_align. */
+ "4", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_RENAME_FMA_REGS), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_CORTEXA57. */
diff --git a/gcc/config/aarch64/tuning_models/cortexa72.h b/gcc/config/aarch64/tuning_models/cortexa72.h
new file mode 100644
index 0000000..968171c
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/cortexa72.h
@@ -0,0 +1,61 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_CORTEXA72
+#define GCC_AARCH64_H_CORTEXA72
+
+#include "generic.h"
+
+static const struct tune_params cortexa72_tunings =
+{
+ &cortexa57_extra_costs,
+ &generic_addrcost_table,
+ &cortexa57_regmove_cost,
+ &cortexa57_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+ | AARCH64_FUSE_MOVK_MOVK), /* fusible_ops */
+ "16", /* function_align. */
+ "4", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_CORTEXA72. */
diff --git a/gcc/config/aarch64/tuning_models/cortexa73.h b/gcc/config/aarch64/tuning_models/cortexa73.h
new file mode 100644
index 0000000..8d1a504
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/cortexa73.h
@@ -0,0 +1,62 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_CORTEXA73
+#define GCC_AARCH64_H_CORTEXA73
+
+#include "generic.h"
+
+static const struct tune_params cortexa73_tunings =
+{
+ &cortexa57_extra_costs,
+ &generic_addrcost_table,
+ &cortexa57_regmove_cost,
+ &cortexa57_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 2, /* issue_rate. */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+ | AARCH64_FUSE_MOVK_MOVK | AARCH64_FUSE_ADRP_LDR), /* fusible_ops */
+ "16", /* function_align. */
+ "4", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+
+#endif /* GCC_AARCH64_H_CORTEXA73. */
diff --git a/gcc/config/aarch64/tuning_models/emag.h b/gcc/config/aarch64/tuning_models/emag.h
new file mode 100644
index 0000000..3f3402c
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/emag.h
@@ -0,0 +1,60 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_EMAG
+#define GCC_AARCH64_H_EMAG
+
+#include "generic.h"
+
+static const struct tune_params emag_tunings =
+{
+ &xgene1_extra_costs,
+ &xgene1_addrcost_table,
+ &xgene1_regmove_cost,
+ &xgene1_vector_cost,
+ &generic_branch_cost,
+ &xgene1_approx_modes,
+ SVE_NOT_IMPLEMENTED,
+ { 6, /* load_int. */
+ 6, /* store_int. */
+ 6, /* load_fp. */
+ 6, /* store_fp. */
+ 6, /* load_pred. */
+ 6 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ AARCH64_FUSE_NOTHING, /* fusible_ops */
+ "16", /* function_align. */
+ "16", /* jump_align. */
+ "16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 17, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS), /* tune_flags. */
+ &xgene1_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_EMAG. */
diff --git a/gcc/config/aarch64/tuning_models/exynosm1.h b/gcc/config/aarch64/tuning_models/exynosm1.h
new file mode 100644
index 0000000..a42ea4d
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/exynosm1.h
@@ -0,0 +1,144 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_EXYNOSM1
+#define GCC_AARCH64_H_EXYNOSM1
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table exynosm1_addrcost_table =
+{
+ {
+ 0, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 2, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 0, /* post_modify_ld3_st3 */
+ 0, /* post_modify_ld4_st4 */
+ 1, /* register_offset */
+ 1, /* register_sextend */
+ 2, /* register_zextend */
+ 0, /* imm_offset */
+};
+
+static const struct cpu_regmove_cost exynosm1_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost (actual, 4 and 9). */
+ 9, /* GP2FP */
+ 9, /* FP2GP */
+ 1 /* FP2FP */
+};
+
+static const advsimd_vec_cost exynosm1_advsimd_vector_cost =
+{
+ 3, /* int_stmt_cost */
+ 3, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 3, /* reduc_i8_cost */
+ 3, /* reduc_i16_cost */
+ 3, /* reduc_i32_cost */
+ 3, /* reduc_i64_cost */
+ 3, /* reduc_f16_cost */
+ 3, /* reduc_f32_cost */
+ 3, /* reduc_f64_cost */
+ 3, /* store_elt_extra_cost */
+ 3, /* vec_to_scalar_cost */
+ 3, /* scalar_to_vec_cost */
+ 5, /* align_load_cost */
+ 5, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+static const struct cpu_vector_cost exynosm1_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 5, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &exynosm1_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+/* Approximation modes for Exynos M1. */
+static const cpu_approx_modes exynosm1_approx_modes =
+{
+ AARCH64_APPROX_NONE, /* division */
+ AARCH64_APPROX_ALL, /* sqrt */
+ AARCH64_APPROX_ALL /* recip_sqrt */
+};
+
+static const cpu_prefetch_tune exynosm1_prefetch_tune =
+{
+ 0, /* num_slots */
+ -1, /* l1_cache_size */
+ 64, /* l1_cache_line_size */
+ -1, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params exynosm1_tunings =
+{
+ &exynosm1_extra_costs,
+ &exynosm1_addrcost_table,
+ &exynosm1_regmove_cost,
+ &exynosm1_vector_cost,
+ &generic_branch_cost,
+ &exynosm1_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC), /* fusible_ops */
+ "4", /* function_align. */
+ "4", /* jump_align. */
+ "4", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 48, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &exynosm1_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_EXYNOSM1. */
diff --git a/gcc/config/aarch64/tuning_models/generic.h b/gcc/config/aarch64/tuning_models/generic.h
new file mode 100644
index 0000000..deb2c1c
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/generic.h
@@ -0,0 +1,190 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_GENERIC
+#define GCC_AARCH64_H_GENERIC
+
+static const struct cpu_addrcost_table generic_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 0, /* post_modify_ld3_st3 */
+ 0, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 0, /* register_sextend */
+ 0, /* register_zextend */
+ 0 /* imm_offset */
+};
+
+static const struct cpu_regmove_cost generic_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ 5, /* GP2FP */
+ 5, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+/* Generic costs for Advanced SIMD vector operations. */
+static const advsimd_vec_cost generic_advsimd_vector_cost =
+{
+ 1, /* int_stmt_cost */
+ 1, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 2, /* reduc_i8_cost */
+ 2, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 2, /* reduc_f16_cost */
+ 2, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ 2, /* vec_to_scalar_cost */
+ 1, /* scalar_to_vec_cost */
+ 1, /* align_load_cost */
+ 1, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+/* Generic costs for SVE vector operations. */
+static const sve_vec_cost generic_sve_vector_cost =
+{
+ {
+ 1, /* int_stmt_cost */
+ 1, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 2, /* reduc_i8_cost */
+ 2, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 2, /* reduc_f16_cost */
+ 2, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ 2, /* vec_to_scalar_cost */
+ 1, /* scalar_to_vec_cost */
+ 1, /* align_load_cost */
+ 1, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 2, /* clast_cost */
+ 2, /* fadda_f16_cost */
+ 2, /* fadda_f32_cost */
+ 2, /* fadda_f64_cost */
+ 4, /* gather_load_x32_cost */
+ 2, /* gather_load_x64_cost */
+ 1 /* scatter_store_elt_cost */
+};
+
+/* Generic costs for vector insn classes. */
+static const struct cpu_vector_cost generic_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 1, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 3, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &generic_advsimd_vector_cost, /* advsimd */
+ &generic_sve_vector_cost, /* sve */
+ nullptr /* issue_info */
+};
+
+/* Generic costs for branch instructions. */
+static const struct cpu_branch_cost generic_branch_cost =
+{
+ 1, /* Predictable. */
+ 3 /* Unpredictable. */
+};
+
+/* Generic approximation modes. */
+static const cpu_approx_modes generic_approx_modes =
+{
+ AARCH64_APPROX_NONE, /* division */
+ AARCH64_APPROX_NONE, /* sqrt */
+ AARCH64_APPROX_NONE /* recip_sqrt */
+};
+
+/* Generic prefetch settings (which disable prefetch). */
+static const cpu_prefetch_tune generic_prefetch_tune =
+{
+ 0, /* num_slots */
+ -1, /* l1_cache_size */
+ -1, /* l1_cache_line_size */
+ -1, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params generic_tunings =
+{
+ &cortexa57_extra_costs,
+ &generic_addrcost_table,
+ &generic_regmove_cost,
+ &generic_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 2, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "16:12", /* function_align. */
+ "4", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ /* Enabling AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS significantly benefits
+ Neoverse V1. It does not have a noticeable effect on A64FX and should
+ have at most a very minor effect on SVE2 cores. */
+ (AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_GENERIC. */
diff --git a/gcc/config/aarch64/tuning_models/generic_armv8_a.h b/gcc/config/aarch64/tuning_models/generic_armv8_a.h
new file mode 100644
index 0000000..82abe17
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/generic_armv8_a.h
@@ -0,0 +1,191 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_GENERIC_ARMV8_A
+#define GCC_AARCH64_H_GENERIC_ARMV8_A
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table generic_armv8_a_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 0, /* post_modify_ld3_st3 */
+ 0, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 0, /* register_sextend */
+ 0, /* register_zextend */
+ 0 /* imm_offset */
+};
+
+static const struct cpu_regmove_cost generic_armv8_a_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ 5, /* GP2FP */
+ 5, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+/* Generic costs for Advanced SIMD vector operations. */
+static const advsimd_vec_cost generic_armv8_a_advsimd_vector_cost =
+{
+ 1, /* int_stmt_cost */
+ 1, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 2, /* reduc_i8_cost */
+ 2, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 2, /* reduc_f16_cost */
+ 2, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ 2, /* vec_to_scalar_cost */
+ 1, /* scalar_to_vec_cost */
+ 1, /* align_load_cost */
+ 1, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+/* Generic costs for SVE vector operations. */
+static const sve_vec_cost generic_armv8_a_sve_vector_cost =
+{
+ {
+ 1, /* int_stmt_cost */
+ 1, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 2, /* reduc_i8_cost */
+ 2, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 2, /* reduc_f16_cost */
+ 2, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ 2, /* vec_to_scalar_cost */
+ 1, /* scalar_to_vec_cost */
+ 1, /* align_load_cost */
+ 1, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 2, /* clast_cost */
+ 2, /* fadda_f16_cost */
+ 2, /* fadda_f32_cost */
+ 2, /* fadda_f64_cost */
+ 4, /* gather_load_x32_cost */
+ 2, /* gather_load_x64_cost */
+ 1 /* scatter_store_elt_cost */
+};
+
+/* Generic costs for vector insn classes. */
+static const struct cpu_vector_cost generic_armv8_a_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 1, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 3, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &generic_armv8_a_advsimd_vector_cost, /* advsimd */
+ &generic_armv8_a_sve_vector_cost, /* sve */
+ nullptr /* issue_info */
+};
+
+/* Generic costs for branch instructions. */
+static const struct cpu_branch_cost generic_armv8_a_branch_cost =
+{
+ 1, /* Predictable. */
+ 3 /* Unpredictable. */
+};
+
+/* Generic approximation modes. */
+static const cpu_approx_modes generic_armv8_a_approx_modes =
+{
+ AARCH64_APPROX_NONE, /* division */
+ AARCH64_APPROX_NONE, /* sqrt */
+ AARCH64_APPROX_NONE /* recip_sqrt */
+};
+
+/* Generic prefetch settings (which disable prefetch). */
+static const cpu_prefetch_tune generic_armv8_a_prefetch_tune =
+{
+ 0, /* num_slots */
+ -1, /* l1_cache_size */
+ -1, /* l1_cache_line_size */
+ -1, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params generic_armv8_a_tunings =
+{
+ &cortexa76_extra_costs,
+ &generic_armv8_a_addrcost_table,
+ &generic_armv8_a_regmove_cost,
+ &generic_armv8_a_vector_cost,
+ &generic_armv8_a_branch_cost,
+ &generic_armv8_a_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 2, /* store_int. */
+ 5, /* load_fp. */
+ 2, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32:16", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND
+ | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
+ | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
+ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_GENERIC_ARMV8_A. */
diff --git a/gcc/config/aarch64/tuning_models/generic_armv9_a.h b/gcc/config/aarch64/tuning_models/generic_armv9_a.h
new file mode 100644
index 0000000..c017468
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/generic_armv9_a.h
@@ -0,0 +1,245 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_GENERIC_ARMV9_A
+#define GCC_AARCH64_H_GENERIC_ARMV9_A
+
+#include "generic.h"
+#include "generic_armv8_a.h"
+
+static const struct cpu_addrcost_table generic_armv9_a_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 2, /* post_modify_ld3_st3 */
+ 2, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 0, /* register_sextend */
+ 0, /* register_zextend */
+ 0 /* imm_offset */
+};
+
+static const struct cpu_regmove_cost generic_armv9_a_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Spilling to int<->fp instead of memory is recommended so set
+ realistic costs compared to memmov_cost. */
+ 3, /* GP2FP */
+ 2, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost generic_armv9_a_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 2, /* ld2_st2_permute_cost */
+ 2, /* ld3_st3_permute_cost */
+ 3, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 4, /* reduc_i8_cost */
+ 4, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 6, /* reduc_f16_cost */
+ 4, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* This depends very much on what the scalar value is and
+ where it comes from. E.g. some constants take two dependent
+ instructions or a load, while others might be moved from a GPR.
+ 4 seems to be a reasonable compromise in practice. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+static const sve_vec_cost generic_armv9_a_sve_vector_cost =
+{
+ {
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 3, /* ld2_st2_permute_cost */
+ 4, /* ld3_st3_permute_cost */
+ 4, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ /* Theoretically, a reduction involving 15 scalar ADDs could
+ complete in ~5 cycles and would have a cost of 15. [SU]ADDV
+ completes in 11 cycles, so give it a cost of 15 + 6. */
+ 21, /* reduc_i8_cost */
+ /* Likewise for 7 scalar ADDs (~3 cycles) vs. 9: 7 + 6. */
+ 13, /* reduc_i16_cost */
+ /* Likewise for 3 scalar ADDs (~2 cycles) vs. 8: 3 + 6. */
+ 9, /* reduc_i32_cost */
+ /* Likewise for 1 scalar ADD (~1 cycles) vs. 2: 1 + 1. */
+ 2, /* reduc_i64_cost */
+ /* Theoretically, a reduction involving 7 scalar FADDs could
+ complete in ~8 cycles and would have a cost of 14. FADDV
+ completes in 6 cycles, so give it a cost of 14 - 2. */
+ 12, /* reduc_f16_cost */
+ /* Likewise for 3 scalar FADDs (~4 cycles) vs. 4: 6 - 0. */
+ 6, /* reduc_f32_cost */
+ /* Likewise for 1 scalar FADD (~2 cycles) vs. 2: 2 - 0. */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* See the comment above the Advanced SIMD versions. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 3, /* clast_cost */
+ 10, /* fadda_f16_cost */
+ 6, /* fadda_f32_cost */
+ 4, /* fadda_f64_cost */
+ /* A strided Advanced SIMD x64 load would take two parallel FP loads
+ (8 cycles) plus an insertion (2 cycles). Assume a 64-bit SVE gather
+ is 1 cycle more. The Advanced SIMD version is costed as 2 scalar loads
+ (cost 8) and a vec_construct (cost 2). Add a full vector operation
+ (cost 2) to that, to avoid the difference being lost in rounding.
+
+ There is no easy comparison between a strided Advanced SIMD x32 load
+ and an SVE 32-bit gather, but cost an SVE 32-bit gather as 1 vector
+ operation more than a 64-bit gather. */
+ 14, /* gather_load_x32_cost */
+ 12, /* gather_load_x64_cost */
+ 3 /* scatter_store_elt_cost */
+};
+
+static const aarch64_scalar_vec_issue_info generic_armv9_a_scalar_issue_info =
+{
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 4, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+};
+
+static const aarch64_advsimd_vec_issue_info generic_armv9_a_advsimd_issue_info =
+{
+ {
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 2, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 2, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+};
+
+static const aarch64_sve_vec_issue_info generic_armv9_a_sve_issue_info =
+{
+ {
+ {
+ 3, /* loads_per_cycle */
+ 2, /* stores_per_cycle */
+ 2, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 3, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+ },
+ 2, /* pred_ops_per_cycle */
+ 2, /* while_pred_ops */
+ 2, /* int_cmp_pred_ops */
+ 1, /* fp_cmp_pred_ops */
+ 1, /* gather_scatter_pair_general_ops */
+ 1 /* gather_scatter_pair_pred_ops */
+};
+
+static const aarch64_vec_issue_info generic_armv9_a_vec_issue_info =
+{
+ &generic_armv9_a_scalar_issue_info,
+ &generic_armv9_a_advsimd_issue_info,
+ &generic_armv9_a_sve_issue_info
+};
+
+/* Neoverse N2 costs for vector insn classes. */
+static const struct cpu_vector_cost generic_armv9_a_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 2, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &generic_armv9_a_advsimd_vector_cost, /* advsimd */
+ &generic_armv9_a_sve_vector_cost, /* sve */
+ &generic_armv9_a_vec_issue_info /* issue_info */
+};
+
+static const struct tune_params generic_armv9_a_tunings =
+{
+ &cortexa76_extra_costs,
+ &generic_armv9_a_addrcost_table,
+ &generic_armv9_a_regmove_cost,
+ &generic_armv9_a_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_SCALABLE, /* sve_width */
+ { 4, /* load_int. */
+ 1, /* store_int. */
+ 6, /* load_fp. */
+ 2, /* store_fp. */
+ 6, /* load_pred. */
+ 1 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32:16", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND
+ | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
+ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_GENERIC_ARMV9_A. */
diff --git a/gcc/config/aarch64/tuning_models/neoverse512tvb.h b/gcc/config/aarch64/tuning_models/neoverse512tvb.h
new file mode 100644
index 0000000..50d7b23
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/neoverse512tvb.h
@@ -0,0 +1,164 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_NEOVERSE512TVB
+#define GCC_AARCH64_H_NEOVERSE512TVB
+
+#include "generic.h"
+
+static const sve_vec_cost neoverse512tvb_sve_vector_cost =
+{
+ {
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 4, /* ld2_st2_permute_cost */
+ 5, /* ld3_st3_permute_cost */
+ 5, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ /* Theoretically, a reduction involving 15 scalar ADDs could
+ complete in ~5 cycles and would have a cost of 15. Assume that
+ [SU]ADDV completes in 11 cycles and so give it a cost of 15 + 6. */
+ 21, /* reduc_i8_cost */
+ /* Likewise for 7 scalar ADDs (~3 cycles) vs. 9: 7 + 6. */
+ 13, /* reduc_i16_cost */
+ /* Likewise for 3 scalar ADDs (~2 cycles) vs. 8: 3 + 6. */
+ 9, /* reduc_i32_cost */
+ /* Likewise for 1 scalar ADD (1 cycle) vs. 8: 1 + 7. */
+ 8, /* reduc_i64_cost */
+ /* Theoretically, a reduction involving 7 scalar FADDs could
+ complete in ~6 cycles and would have a cost of 14. Assume that
+ FADDV completes in 8 cycles and so give it a cost of 14 + 2. */
+ 16, /* reduc_f16_cost */
+ /* Likewise for 3 scalar FADDs (~4 cycles) vs. 6: 6 + 2. */
+ 8, /* reduc_f32_cost */
+ /* Likewise for 1 scalar FADD (2 cycles) vs. 4: 2 + 2. */
+ 4, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* This depends very much on what the scalar value is and
+ where it comes from. E.g. some constants take two dependent
+ instructions or a load, while others might be moved from a GPR.
+ 4 seems to be a reasonable compromise in practice. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores generally have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 3, /* clast_cost */
+ 10, /* fadda_f16_cost */
+ 6, /* fadda_f32_cost */
+ 4, /* fadda_f64_cost */
+ /* A strided Advanced SIMD x64 load would take two parallel FP loads
+ (6 cycles) plus an insertion (2 cycles). Assume a 64-bit SVE gather
+ is 1 cycle more. The Advanced SIMD version is costed as 2 scalar loads
+ (cost 8) and a vec_construct (cost 2). Add a full vector operation
+ (cost 2) to that, to avoid the difference being lost in rounding.
+
+ There is no easy comparison between a strided Advanced SIMD x32 load
+ and an SVE 32-bit gather, but cost an SVE 32-bit gather as 1 vector
+ operation more than a 64-bit gather. */
+ 14, /* gather_load_x32_cost */
+ 12, /* gather_load_x64_cost */
+ 3 /* scatter_store_elt_cost */
+};
+
+static const aarch64_sve_vec_issue_info neoverse512tvb_sve_issue_info =
+{
+ {
+ {
+ 3, /* loads_per_cycle */
+ 2, /* stores_per_cycle */
+ 4, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 2, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+ },
+ 2, /* pred_ops_per_cycle */
+ 2, /* while_pred_ops */
+ 2, /* int_cmp_pred_ops */
+ 1, /* fp_cmp_pred_ops */
+ 1, /* gather_scatter_pair_general_ops */
+ 1 /* gather_scatter_pair_pred_ops */
+};
+
+static const aarch64_vec_issue_info neoverse512tvb_vec_issue_info =
+{
+ &neoversev1_scalar_issue_info,
+ &neoversev1_advsimd_issue_info,
+ &neoverse512tvb_sve_issue_info
+};
+
+static const struct cpu_vector_cost neoverse512tvb_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 2, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &neoversev1_advsimd_vector_cost, /* advsimd */
+ &neoverse512tvb_sve_vector_cost, /* sve */
+ &neoverse512tvb_vec_issue_info /* issue_info */
+};
+
+static const struct tune_params neoverse512tvb_tunings =
+{
+ &cortexa76_extra_costs,
+ &neoversev1_addrcost_table,
+ &neoversev1_regmove_cost,
+ &neoverse512tvb_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_128 | SVE_256, /* sve_width */
+ { 4, /* load_int. */
+ 2, /* store_int. */
+ 6, /* load_fp. */
+ 2, /* store_fp. */
+ 6, /* load_pred. */
+ 1 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32:16", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 4, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
+ | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
+ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_NEOVERSE512TVB. */
diff --git a/gcc/config/aarch64/tuning_models/neoversen1.h b/gcc/config/aarch64/tuning_models/neoversen1.h
new file mode 100644
index 0000000..132166d
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/neoversen1.h
@@ -0,0 +1,60 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_NEOVERSEN1
+#define GCC_AARCH64_H_NEOVERSEN1
+
+#include "generic.h"
+
+static const struct tune_params neoversen1_tunings =
+{
+ &cortexa76_extra_costs,
+ &generic_addrcost_table,
+ &generic_regmove_cost,
+ &cortexa57_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 2, /* store_int. */
+ 5, /* load_fp. */
+ 2, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32:16", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_NEOVERSEN1. */
diff --git a/gcc/config/aarch64/tuning_models/neoversen2.h b/gcc/config/aarch64/tuning_models/neoversen2.h
new file mode 100644
index 0000000..395a6d8
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/neoversen2.h
@@ -0,0 +1,245 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_NEOVERSEN2
+#define GCC_AARCH64_H_NEOVERSEN2
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table neoversen2_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 2, /* post_modify_ld3_st3 */
+ 2, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 0, /* register_sextend */
+ 0, /* register_zextend */
+ 0 /* imm_offset */
+};
+
+static const struct cpu_regmove_cost neoversen2_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Spilling to int<->fp instead of memory is recommended so set
+ realistic costs compared to memmov_cost. */
+ 3, /* GP2FP */
+ 2, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost neoversen2_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 2, /* ld2_st2_permute_cost */
+ 2, /* ld3_st3_permute_cost */
+ 3, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 4, /* reduc_i8_cost */
+ 4, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 6, /* reduc_f16_cost */
+ 4, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* This depends very much on what the scalar value is and
+ where it comes from. E.g. some constants take two dependent
+ instructions or a load, while others might be moved from a GPR.
+ 4 seems to be a reasonable compromise in practice. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+static const sve_vec_cost neoversen2_sve_vector_cost =
+{
+ {
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 3, /* ld2_st2_permute_cost */
+ 4, /* ld3_st3_permute_cost */
+ 4, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ /* Theoretically, a reduction involving 15 scalar ADDs could
+ complete in ~5 cycles and would have a cost of 15. [SU]ADDV
+ completes in 11 cycles, so give it a cost of 15 + 6. */
+ 21, /* reduc_i8_cost */
+ /* Likewise for 7 scalar ADDs (~3 cycles) vs. 9: 7 + 6. */
+ 13, /* reduc_i16_cost */
+ /* Likewise for 3 scalar ADDs (~2 cycles) vs. 8: 3 + 6. */
+ 9, /* reduc_i32_cost */
+ /* Likewise for 1 scalar ADD (~1 cycles) vs. 2: 1 + 1. */
+ 2, /* reduc_i64_cost */
+ /* Theoretically, a reduction involving 7 scalar FADDs could
+ complete in ~8 cycles and would have a cost of 14. FADDV
+ completes in 6 cycles, so give it a cost of 14 - 2. */
+ 12, /* reduc_f16_cost */
+ /* Likewise for 3 scalar FADDs (~4 cycles) vs. 4: 6 - 0. */
+ 6, /* reduc_f32_cost */
+ /* Likewise for 1 scalar FADD (~2 cycles) vs. 2: 2 - 0. */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* See the comment above the Advanced SIMD versions. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 3, /* clast_cost */
+ 10, /* fadda_f16_cost */
+ 6, /* fadda_f32_cost */
+ 4, /* fadda_f64_cost */
+ /* A strided Advanced SIMD x64 load would take two parallel FP loads
+ (8 cycles) plus an insertion (2 cycles). Assume a 64-bit SVE gather
+ is 1 cycle more. The Advanced SIMD version is costed as 2 scalar loads
+ (cost 8) and a vec_construct (cost 2). Add a full vector operation
+ (cost 2) to that, to avoid the difference being lost in rounding.
+
+ There is no easy comparison between a strided Advanced SIMD x32 load
+ and an SVE 32-bit gather, but cost an SVE 32-bit gather as 1 vector
+ operation more than a 64-bit gather. */
+ 14, /* gather_load_x32_cost */
+ 12, /* gather_load_x64_cost */
+ 3 /* scatter_store_elt_cost */
+};
+
+static const aarch64_scalar_vec_issue_info neoversen2_scalar_issue_info =
+{
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 4, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+};
+
+static const aarch64_advsimd_vec_issue_info neoversen2_advsimd_issue_info =
+{
+ {
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 2, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 2, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+};
+
+static const aarch64_sve_vec_issue_info neoversen2_sve_issue_info =
+{
+ {
+ {
+ 3, /* loads_per_cycle */
+ 2, /* stores_per_cycle */
+ 2, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 3, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+ },
+ 2, /* pred_ops_per_cycle */
+ 2, /* while_pred_ops */
+ 2, /* int_cmp_pred_ops */
+ 1, /* fp_cmp_pred_ops */
+ 1, /* gather_scatter_pair_general_ops */
+ 1 /* gather_scatter_pair_pred_ops */
+};
+
+static const aarch64_vec_issue_info neoversen2_vec_issue_info =
+{
+ &neoversen2_scalar_issue_info,
+ &neoversen2_advsimd_issue_info,
+ &neoversen2_sve_issue_info
+};
+
+/* Neoverse N2 costs for vector insn classes. */
+static const struct cpu_vector_cost neoversen2_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 2, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &neoversen2_advsimd_vector_cost, /* advsimd */
+ &neoversen2_sve_vector_cost, /* sve */
+ &neoversen2_vec_issue_info /* issue_info */
+};
+
+static const struct tune_params neoversen2_tunings =
+{
+ &cortexa76_extra_costs,
+ &neoversen2_addrcost_table,
+ &neoversen2_regmove_cost,
+ &neoversen2_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_128, /* sve_width */
+ { 4, /* load_int. */
+ 1, /* store_int. */
+ 6, /* load_fp. */
+ 2, /* store_fp. */
+ 6, /* load_pred. */
+ 1 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32:16", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND
+ | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
+ | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
+ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_NEOVERSEN2. */
diff --git a/gcc/config/aarch64/tuning_models/neoversev1.h b/gcc/config/aarch64/tuning_models/neoversev1.h
new file mode 100644
index 0000000..584a500
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/neoversev1.h
@@ -0,0 +1,237 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_NEOVERSEV1
+#define GCC_AARCH64_H_NEOVERSEV1
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table neoversev1_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 3, /* post_modify_ld3_st3 */
+ 3, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 0, /* register_sextend */
+ 0, /* register_zextend */
+ 0 /* imm_offset */
+};
+
+static const struct cpu_regmove_cost neoversev1_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Spilling to int<->fp instead of memory is recommended so set
+ realistic costs compared to memmov_cost. */
+ 3, /* GP2FP */
+ 2, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost neoversev1_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 4, /* ld2_st2_permute_cost */
+ 4, /* ld3_st3_permute_cost */
+ 5, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 4, /* reduc_i8_cost */
+ 4, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 6, /* reduc_f16_cost */
+ 3, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* This depends very much on what the scalar value is and
+ where it comes from. E.g. some constants take two dependent
+ instructions or a load, while others might be moved from a GPR.
+ 4 seems to be a reasonable compromise in practice. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+static const sve_vec_cost neoversev1_sve_vector_cost =
+{
+ {
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 4, /* ld2_st2_permute_cost */
+ 7, /* ld3_st3_permute_cost */
+ 8, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ /* Theoretically, a reduction involving 31 scalar ADDs could
+ complete in ~9 cycles and would have a cost of 31. [SU]ADDV
+ completes in 14 cycles, so give it a cost of 31 + 5. */
+ 36, /* reduc_i8_cost */
+ /* Likewise for 15 scalar ADDs (~5 cycles) vs. 12: 15 + 7. */
+ 22, /* reduc_i16_cost */
+ /* Likewise for 7 scalar ADDs (~3 cycles) vs. 10: 7 + 7. */
+ 14, /* reduc_i32_cost */
+ /* Likewise for 3 scalar ADDs (~2 cycles) vs. 10: 3 + 8. */
+ 11, /* reduc_i64_cost */
+ /* Theoretically, a reduction involving 15 scalar FADDs could
+ complete in ~9 cycles and would have a cost of 30. FADDV
+ completes in 13 cycles, so give it a cost of 30 + 4. */
+ 34, /* reduc_f16_cost */
+ /* Likewise for 7 scalar FADDs (~6 cycles) vs. 11: 14 + 5. */
+ 19, /* reduc_f32_cost */
+ /* Likewise for 3 scalar FADDs (~4 cycles) vs. 9: 6 + 5. */
+ 11, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* See the comment above the Advanced SIMD versions. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 3, /* clast_cost */
+ 19, /* fadda_f16_cost */
+ 11, /* fadda_f32_cost */
+ 8, /* fadda_f64_cost */
+ 32, /* gather_load_x32_cost */
+ 16, /* gather_load_x64_cost */
+ 3 /* scatter_store_elt_cost */
+};
+
+static const aarch64_scalar_vec_issue_info neoversev1_scalar_issue_info =
+{
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 4, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+};
+
+static const aarch64_advsimd_vec_issue_info neoversev1_advsimd_issue_info =
+{
+ {
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 4, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 2, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+};
+
+static const aarch64_sve_vec_issue_info neoversev1_sve_issue_info =
+{
+ {
+ {
+ 2, /* loads_per_cycle */
+ 2, /* stores_per_cycle */
+ 2, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 2, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+ },
+ 1, /* pred_ops_per_cycle */
+ 2, /* while_pred_ops */
+ 2, /* int_cmp_pred_ops */
+ 1, /* fp_cmp_pred_ops */
+ 1, /* gather_scatter_pair_general_ops */
+ 1 /* gather_scatter_pair_pred_ops */
+};
+
+static const aarch64_vec_issue_info neoversev1_vec_issue_info =
+{
+ &neoversev1_scalar_issue_info,
+ &neoversev1_advsimd_issue_info,
+ &neoversev1_sve_issue_info
+};
+
+/* Neoverse V1 costs for vector insn classes. */
+static const struct cpu_vector_cost neoversev1_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 2, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &neoversev1_advsimd_vector_cost, /* advsimd */
+ &neoversev1_sve_vector_cost, /* sve */
+ &neoversev1_vec_issue_info /* issue_info */
+};
+
+static const struct tune_params neoversev1_tunings =
+{
+ &cortexa76_extra_costs,
+ &neoversev1_addrcost_table,
+ &neoversev1_regmove_cost,
+ &neoversev1_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_256, /* sve_width */
+ { 4, /* load_int. */
+ 2, /* store_int. */
+ 6, /* load_fp. */
+ 2, /* store_fp. */
+ 6, /* load_pred. */
+ 1 /* store_pred. */
+ }, /* memmov_cost. */
+ 3, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32:16", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 4, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
+ | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
+ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT
+ | AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+
+#endif /* GCC_AARCH64_H_NEOVERSEV1. */
diff --git a/gcc/config/aarch64/tuning_models/neoversev2.h b/gcc/config/aarch64/tuning_models/neoversev2.h
new file mode 100644
index 0000000..28d4244
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/neoversev2.h
@@ -0,0 +1,245 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_NEOVERSEV2
+#define GCC_AARCH64_H_NEOVERSEV2
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table neoversev2_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 2, /* post_modify_ld3_st3 */
+ 2, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 0, /* register_sextend */
+ 0, /* register_zextend */
+ 0 /* imm_offset */
+};
+
+static const struct cpu_regmove_cost neoversev2_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Spilling to int<->fp instead of memory is recommended so set
+ realistic costs compared to memmov_cost. */
+ 3, /* GP2FP */
+ 2, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost neoversev2_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 2, /* ld2_st2_permute_cost */
+ 2, /* ld3_st3_permute_cost */
+ 3, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ 4, /* reduc_i8_cost */
+ 4, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 6, /* reduc_f16_cost */
+ 3, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* This depends very much on what the scalar value is and
+ where it comes from. E.g. some constants take two dependent
+ instructions or a load, while others might be moved from a GPR.
+ 4 seems to be a reasonable compromise in practice. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+static const sve_vec_cost neoversev2_sve_vector_cost =
+{
+ {
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 3, /* ld2_st2_permute_cost */
+ 3, /* ld3_st3_permute_cost */
+ 4, /* ld4_st4_permute_cost */
+ 3, /* permute_cost */
+ /* Theoretically, a reduction involving 15 scalar ADDs could
+ complete in ~3 cycles and would have a cost of 15. [SU]ADDV
+ completes in 11 cycles, so give it a cost of 15 + 8. */
+ 21, /* reduc_i8_cost */
+ /* Likewise for 7 scalar ADDs (~2 cycles) vs. 9: 7 + 7. */
+ 14, /* reduc_i16_cost */
+ /* Likewise for 3 scalar ADDs (~2 cycles) vs. 8: 3 + 4. */
+ 7, /* reduc_i32_cost */
+ /* Likewise for 1 scalar ADD (~1 cycles) vs. 2: 1 + 1. */
+ 2, /* reduc_i64_cost */
+ /* Theoretically, a reduction involving 7 scalar FADDs could
+ complete in ~6 cycles and would have a cost of 14. FADDV
+ completes in 8 cycles, so give it a cost of 14 + 2. */
+ 16, /* reduc_f16_cost */
+ /* Likewise for 3 scalar FADDs (~4 cycles) vs. 6: 6 + 2. */
+ 8, /* reduc_f32_cost */
+ /* Likewise for 1 scalar FADD (~2 cycles) vs. 4: 2 + 2. */
+ 4, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ /* This value is just inherited from the Cortex-A57 table. */
+ 8, /* vec_to_scalar_cost */
+ /* See the comment above the Advanced SIMD versions. */
+ 4, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ /* Although stores have a latency of 2 and compete for the
+ vector pipes, in practice it's better not to model that. */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+ },
+ 3, /* clast_cost */
+ 10, /* fadda_f16_cost */
+ 6, /* fadda_f32_cost */
+ 4, /* fadda_f64_cost */
+ /* A strided Advanced SIMD x64 load would take two parallel FP loads
+ (8 cycles) plus an insertion (2 cycles). Assume a 64-bit SVE gather
+ is 1 cycle more. The Advanced SIMD version is costed as 2 scalar loads
+ (cost 8) and a vec_construct (cost 2). Add a full vector operation
+ (cost 2) to that, to avoid the difference being lost in rounding.
+
+ There is no easy comparison between a strided Advanced SIMD x32 load
+ and an SVE 32-bit gather, but cost an SVE 32-bit gather as 1 vector
+ operation more than a 64-bit gather. */
+ 14, /* gather_load_x32_cost */
+ 12, /* gather_load_x64_cost */
+ 3 /* scatter_store_elt_cost */
+};
+
+static const aarch64_scalar_vec_issue_info neoversev2_scalar_issue_info =
+{
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 6, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+};
+
+static const aarch64_advsimd_vec_issue_info neoversev2_advsimd_issue_info =
+{
+ {
+ 3, /* loads_stores_per_cycle */
+ 2, /* stores_per_cycle */
+ 4, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 2, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+};
+
+static const aarch64_sve_vec_issue_info neoversev2_sve_issue_info =
+{
+ {
+ {
+ 3, /* loads_per_cycle */
+ 2, /* stores_per_cycle */
+ 4, /* general_ops_per_cycle */
+ 0, /* fp_simd_load_general_ops */
+ 1 /* fp_simd_store_general_ops */
+ },
+ 2, /* ld2_st2_general_ops */
+ 3, /* ld3_st3_general_ops */
+ 3 /* ld4_st4_general_ops */
+ },
+ 2, /* pred_ops_per_cycle */
+ 2, /* while_pred_ops */
+ 2, /* int_cmp_pred_ops */
+ 1, /* fp_cmp_pred_ops */
+ 1, /* gather_scatter_pair_general_ops */
+ 1 /* gather_scatter_pair_pred_ops */
+};
+
+static const aarch64_vec_issue_info neoversev2_vec_issue_info =
+{
+ &neoversev2_scalar_issue_info,
+ &neoversev2_advsimd_issue_info,
+ &neoversev2_sve_issue_info
+};
+
+/* Demeter costs for vector insn classes. */
+static const struct cpu_vector_cost neoversev2_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 2, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &neoversev2_advsimd_vector_cost, /* advsimd */
+ &neoversev2_sve_vector_cost, /* sve */
+ &neoversev2_vec_issue_info /* issue_info */
+};
+
+static const struct tune_params neoversev2_tunings =
+{
+ &cortexa76_extra_costs,
+ &neoversev2_addrcost_table,
+ &neoversev2_regmove_cost,
+ &neoversev2_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_128, /* sve_width */
+ { 4, /* load_int. */
+ 2, /* store_int. */
+ 6, /* load_fp. */
+ 1, /* store_fp. */
+ 6, /* load_pred. */
+ 2 /* store_pred. */
+ }, /* memmov_cost. */
+ 5, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_CMP_BRANCH), /* fusible_ops */
+ "32:16", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 3, /* int_reassoc_width. */
+ 6, /* fp_reassoc_width. */
+ 4, /* fma_reassoc_width. */
+ 3, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND
+ | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
+ | AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS
+ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_NEOVERSEV2. */
diff --git a/gcc/config/aarch64/tuning_models/qdf24xx.h b/gcc/config/aarch64/tuning_models/qdf24xx.h
new file mode 100644
index 0000000..29c9b9f
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/qdf24xx.h
@@ -0,0 +1,137 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_QDF24XX
+#define GCC_AARCH64_H_QDF24XX
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table qdf24xx_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 1, /* si */
+ 1, /* di */
+ 2, /* ti */
+ },
+ 1, /* pre_modify */
+ 1, /* post_modify */
+ 1, /* post_modify_ld3_st3 */
+ 1, /* post_modify_ld4_st4 */
+ 3, /* register_offset */
+ 3, /* register_sextend */
+ 3, /* register_zextend */
+ 2, /* imm_offset */
+};
+
+static const struct cpu_regmove_cost qdf24xx_regmove_cost =
+{
+ 2, /* GP2GP */
+ /* Avoid the use of int<->fp moves for spilling. */
+ 6, /* GP2FP */
+ 6, /* FP2GP */
+ 4 /* FP2FP */
+};
+
+static const advsimd_vec_cost qdf24xx_advsimd_vector_cost =
+{
+ 1, /* int_stmt_cost */
+ 3, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 1, /* reduc_i8_cost */
+ 1, /* reduc_i16_cost */
+ 1, /* reduc_i32_cost */
+ 1, /* reduc_i64_cost */
+ 1, /* reduc_f16_cost */
+ 1, /* reduc_f32_cost */
+ 1, /* reduc_f64_cost */
+ 1, /* store_elt_extra_cost */
+ 1, /* vec_to_scalar_cost */
+ 1, /* scalar_to_vec_cost */
+ 1, /* align_load_cost */
+ 1, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+/* QDF24XX costs for vector insn classes. */
+static const struct cpu_vector_cost qdf24xx_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 1, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 3, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &qdf24xx_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+static const cpu_prefetch_tune qdf24xx_prefetch_tune =
+{
+ 4, /* num_slots */
+ 32, /* l1_cache_size */
+ 64, /* l1_cache_line_size */
+ 512, /* l2_cache_size */
+ false, /* prefetch_dynamic_strides */
+ 2048, /* minimum_stride */
+ 3 /* default_opt_level */
+};
+
+static const struct tune_params qdf24xx_tunings =
+{
+ &qdf24xx_extra_costs,
+ &qdf24xx_addrcost_table,
+ &qdf24xx_regmove_cost,
+ &qdf24xx_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+ | AARCH64_FUSE_MOVK_MOVK), /* fuseable_ops */
+ "16", /* function_align. */
+ "8", /* jump_align. */
+ "16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ AARCH64_EXTRA_TUNE_RENAME_LOAD_REGS, /* tune_flags. */
+ &qdf24xx_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_QDF24XX. */
diff --git a/gcc/config/aarch64/tuning_models/saphira.h b/gcc/config/aarch64/tuning_models/saphira.h
new file mode 100644
index 0000000..e584d31
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/saphira.h
@@ -0,0 +1,63 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_SAPHIRA
+#define GCC_AARCH64_H_SAPHIRA
+
+#include "generic.h"
+
+/* Tuning structure for the Qualcomm Saphira core. Default to falkor values
+ for now. */
+static const struct tune_params saphira_tunings =
+{
+ &generic_extra_costs,
+ &generic_addrcost_table,
+ &generic_regmove_cost,
+ &generic_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+ | AARCH64_FUSE_MOVK_MOVK), /* fuseable_ops */
+ "16", /* function_align. */
+ "8", /* jump_align. */
+ "16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &generic_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_SAPHIRA. */
diff --git a/gcc/config/aarch64/tuning_models/thunderx.h b/gcc/config/aarch64/tuning_models/thunderx.h
new file mode 100644
index 0000000..dd4b9d5
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/thunderx.h
@@ -0,0 +1,117 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_THUNDERX
+#define GCC_AARCH64_H_THUNDERX
+
+#include "generic.h"
+
+static const struct cpu_regmove_cost thunderx_regmove_cost =
+{
+ 2, /* GP2GP */
+ 2, /* GP2FP */
+ 6, /* FP2GP */
+ 4 /* FP2FP */
+};
+
+static const advsimd_vec_cost thunderx_advsimd_vector_cost =
+{
+ 4, /* int_stmt_cost */
+ 1, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 4, /* permute_cost */
+ 2, /* reduc_i8_cost */
+ 2, /* reduc_i16_cost */
+ 2, /* reduc_i32_cost */
+ 2, /* reduc_i64_cost */
+ 2, /* reduc_f16_cost */
+ 2, /* reduc_f32_cost */
+ 2, /* reduc_f64_cost */
+ 2, /* store_elt_extra_cost */
+ 2, /* vec_to_scalar_cost */
+ 2, /* scalar_to_vec_cost */
+ 3, /* align_load_cost */
+ 5, /* unalign_load_cost */
+ 5, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+/* ThunderX costs for vector insn classes. */
+static const struct cpu_vector_cost thunderx_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 3, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 3, /* cond_taken_branch_cost */
+ 3, /* cond_not_taken_branch_cost */
+ &thunderx_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+static const cpu_prefetch_tune thunderx_prefetch_tune =
+{
+ 8, /* num_slots */
+ 32, /* l1_cache_size */
+ 128, /* l1_cache_line_size */
+ -1, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params thunderx_tunings =
+{
+ &thunderx_extra_costs,
+ &generic_addrcost_table,
+ &thunderx_regmove_cost,
+ &thunderx_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 6, /* load_int. */
+ 6, /* store_int. */
+ 6, /* load_fp. */
+ 6, /* store_fp. */
+ 6, /* load_pred. */
+ 6 /* store_pred. */
+ }, /* memmov_cost. */
+ 2, /* issue_rate */
+ AARCH64_FUSE_ALU_BRANCH, /* fusible_ops */
+ "8", /* function_align. */
+ "8", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND), /* tune_flags. */
+ &thunderx_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_THUNDERX. */
diff --git a/gcc/config/aarch64/tuning_models/thunderx2t99.h b/gcc/config/aarch64/tuning_models/thunderx2t99.h
new file mode 100644
index 0000000..0a376e0
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/thunderx2t99.h
@@ -0,0 +1,137 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_THUNDERX2T99
+#define GCC_AARCH64_H_THUNDERX2T99
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table thunderx2t99_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 1, /* si */
+ 1, /* di */
+ 2, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 0, /* post_modify_ld3_st3 */
+ 0, /* post_modify_ld4_st4 */
+ 2, /* register_offset */
+ 3, /* register_sextend */
+ 3, /* register_zextend */
+ 0, /* imm_offset */
+};
+
+static const struct cpu_regmove_cost thunderx2t99_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of int<->fp moves for spilling. */
+ 5, /* GP2FP */
+ 6, /* FP2GP */
+ 3, /* FP2FP */
+};
+
+static const advsimd_vec_cost thunderx2t99_advsimd_vector_cost =
+{
+ 4, /* int_stmt_cost */
+ 5, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 10, /* permute_cost */
+ 6, /* reduc_i8_cost */
+ 6, /* reduc_i16_cost */
+ 6, /* reduc_i32_cost */
+ 6, /* reduc_i64_cost */
+ 6, /* reduc_f16_cost */
+ 6, /* reduc_f32_cost */
+ 6, /* reduc_f64_cost */
+ 6, /* store_elt_extra_cost */
+ 6, /* vec_to_scalar_cost */
+ 5, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+/* Costs for vector insn classes for Vulcan. */
+static const struct cpu_vector_cost thunderx2t99_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 6, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 2, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &thunderx2t99_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+static const cpu_prefetch_tune thunderx2t99_prefetch_tune =
+{
+ 8, /* num_slots */
+ 32, /* l1_cache_size */
+ 64, /* l1_cache_line_size */
+ 256, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params thunderx2t99_tunings =
+{
+ &thunderx2t99_extra_costs,
+ &thunderx2t99_addrcost_table,
+ &thunderx2t99_regmove_cost,
+ &thunderx2t99_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate. */
+ (AARCH64_FUSE_ALU_BRANCH | AARCH64_FUSE_AES_AESMC
+ | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */
+ "16", /* function_align. */
+ "8", /* jump_align. */
+ "16", /* loop_align. */
+ 3, /* int_reassoc_width. */
+ 2, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &thunderx2t99_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_THUNDERX2T99. */
diff --git a/gcc/config/aarch64/tuning_models/thunderx3t110.h b/gcc/config/aarch64/tuning_models/thunderx3t110.h
new file mode 100644
index 0000000..65203b4
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/thunderx3t110.h
@@ -0,0 +1,136 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_THUNDERX3T110
+#define GCC_AARCH64_H_THUNDERX3T110
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table thunderx3t110_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 1, /* si */
+ 1, /* di */
+ 2, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 0, /* post_modify_ld3_st3 */
+ 0, /* post_modify_ld4_st4 */
+ 2, /* register_offset */
+ 3, /* register_sextend */
+ 3, /* register_zextend */
+ 0, /* imm_offset */
+};
+
+static const struct cpu_regmove_cost thunderx3t110_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of int<->fp moves for spilling. */
+ 4, /* GP2FP */
+ 5, /* FP2GP */
+ 4 /* FP2FP */
+};
+
+static const advsimd_vec_cost thunderx3t110_advsimd_vector_cost =
+{
+ 5, /* int_stmt_cost */
+ 5, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 10, /* permute_cost */
+ 5, /* reduc_i8_cost */
+ 5, /* reduc_i16_cost */
+ 5, /* reduc_i32_cost */
+ 5, /* reduc_i64_cost */
+ 5, /* reduc_f16_cost */
+ 5, /* reduc_f32_cost */
+ 5, /* reduc_f64_cost */
+ 5, /* store_elt_extra_cost */
+ 5, /* vec_to_scalar_cost */
+ 5, /* scalar_to_vec_cost */
+ 4, /* align_load_cost */
+ 4, /* unalign_load_cost */
+ 4, /* unalign_store_cost */
+ 4 /* store_cost */
+};
+
+static const struct cpu_vector_cost thunderx3t110_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 5, /* scalar_fp_stmt_cost */
+ 4, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 2, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &thunderx3t110_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+static const cpu_prefetch_tune thunderx3t110_prefetch_tune =
+{
+ 8, /* num_slots */
+ 32, /* l1_cache_size */
+ 64, /* l1_cache_line_size */
+ 256, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params thunderx3t110_tunings =
+{
+ &thunderx3t110_extra_costs,
+ &thunderx3t110_addrcost_table,
+ &thunderx3t110_regmove_cost,
+ &thunderx3t110_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 6, /* issue_rate. */
+ (AARCH64_FUSE_ALU_BRANCH | AARCH64_FUSE_AES_AESMC
+ | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */
+ "16", /* function_align. */
+ "8", /* jump_align. */
+ "16", /* loop_align. */
+ 3, /* int_reassoc_width. */
+ 2, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &thunderx3t110_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_THUNDERX3T110. */
diff --git a/gcc/config/aarch64/tuning_models/thunderxt88.h b/gcc/config/aarch64/tuning_models/thunderxt88.h
new file mode 100644
index 0000000..dcc74d3
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/thunderxt88.h
@@ -0,0 +1,72 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_THUNDERXT88
+#define GCC_AARCH64_H_THUNDERXT88
+
+#include "generic.h"
+#include "thunderx.h"
+
+static const cpu_prefetch_tune thunderxt88_prefetch_tune =
+{
+ 8, /* num_slots */
+ 32, /* l1_cache_size */
+ 128, /* l1_cache_line_size */
+ 16*1024, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ 3 /* default_opt_level */
+};
+
+static const struct tune_params thunderxt88_tunings =
+{
+ &thunderx_extra_costs,
+ &generic_addrcost_table,
+ &thunderx_regmove_cost,
+ &thunderx_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 6, /* load_int. */
+ 6, /* store_int. */
+ 6, /* load_fp. */
+ 6, /* store_fp. */
+ 6, /* load_pred. */
+ 6 /* store_pred. */
+ }, /* memmov_cost. */
+ 2, /* issue_rate */
+ AARCH64_FUSE_ALU_BRANCH, /* fusible_ops */
+ "8", /* function_align. */
+ "8", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &thunderxt88_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALIGNED, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALIGNED /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_THUNDERXT88. */
diff --git a/gcc/config/aarch64/tuning_models/tsv110.h b/gcc/config/aarch64/tuning_models/tsv110.h
new file mode 100644
index 0000000..42aeafc
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/tsv110.h
@@ -0,0 +1,137 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_TSV110
+#define GCC_AARCH64_H_TSV110
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table tsv110_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 0, /* pre_modify */
+ 0, /* post_modify */
+ 0, /* post_modify_ld3_st3 */
+ 0, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 1, /* register_sextend */
+ 1, /* register_zextend */
+ 0, /* imm_offset */
+};
+
+static const struct cpu_regmove_cost tsv110_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ 2, /* GP2FP */
+ 3, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost tsv110_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 3, /* reduc_i8_cost */
+ 3, /* reduc_i16_cost */
+ 3, /* reduc_i32_cost */
+ 3, /* reduc_i64_cost */
+ 3, /* reduc_f16_cost */
+ 3, /* reduc_f32_cost */
+ 3, /* reduc_f64_cost */
+ 3, /* store_elt_extra_cost */
+ 3, /* vec_to_scalar_cost */
+ 2, /* scalar_to_vec_cost */
+ 5, /* align_load_cost */
+ 5, /* unalign_load_cost */
+ 1, /* unalign_store_cost */
+ 1 /* store_cost */
+};
+
+static const struct cpu_vector_cost tsv110_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 5, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 1, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &tsv110_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+static const cpu_prefetch_tune tsv110_prefetch_tune =
+{
+ 0, /* num_slots */
+ 64, /* l1_cache_size */
+ 64, /* l1_cache_line_size */
+ 512, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params tsv110_tunings =
+{
+ &tsv110_extra_costs,
+ &tsv110_addrcost_table,
+ &tsv110_regmove_cost,
+ &tsv110_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_ALU_BRANCH
+ | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */
+ "16", /* function_align. */
+ "4", /* jump_align. */
+ "8", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &tsv110_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_TSV110. */
diff --git a/gcc/config/aarch64/tuning_models/xgene1.h b/gcc/config/aarch64/tuning_models/xgene1.h
new file mode 100644
index 0000000..53a3eb0
--- /dev/null
+++ b/gcc/config/aarch64/tuning_models/xgene1.h
@@ -0,0 +1,145 @@
+/* Tuning model description for AArch64 architecture.
+ Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH64_H_XGENE1
+#define GCC_AARCH64_H_XGENE1
+
+#include "generic.h"
+
+static const struct cpu_addrcost_table xgene1_addrcost_table =
+{
+ {
+ 1, /* hi */
+ 0, /* si */
+ 0, /* di */
+ 1, /* ti */
+ },
+ 1, /* pre_modify */
+ 1, /* post_modify */
+ 1, /* post_modify_ld3_st3 */
+ 1, /* post_modify_ld4_st4 */
+ 0, /* register_offset */
+ 1, /* register_sextend */
+ 1, /* register_zextend */
+ 0, /* imm_offset */
+};
+
+static const struct cpu_regmove_cost xgene1_regmove_cost =
+{
+ 1, /* GP2GP */
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ 8, /* GP2FP */
+ 8, /* FP2GP */
+ 2 /* FP2FP */
+};
+
+static const advsimd_vec_cost xgene1_advsimd_vector_cost =
+{
+ 2, /* int_stmt_cost */
+ 2, /* fp_stmt_cost */
+ 0, /* ld2_st2_permute_cost */
+ 0, /* ld3_st3_permute_cost */
+ 0, /* ld4_st4_permute_cost */
+ 2, /* permute_cost */
+ 4, /* reduc_i8_cost */
+ 4, /* reduc_i16_cost */
+ 4, /* reduc_i32_cost */
+ 4, /* reduc_i64_cost */
+ 4, /* reduc_f16_cost */
+ 4, /* reduc_f32_cost */
+ 4, /* reduc_f64_cost */
+ 4, /* store_elt_extra_cost */
+ 4, /* vec_to_scalar_cost */
+ 4, /* scalar_to_vec_cost */
+ 10, /* align_load_cost */
+ 10, /* unalign_load_cost */
+ 2, /* unalign_store_cost */
+ 2 /* store_cost */
+};
+
+/* Generic costs for vector insn classes. */
+static const struct cpu_vector_cost xgene1_vector_cost =
+{
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 5, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 2, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &xgene1_advsimd_vector_cost, /* advsimd */
+ nullptr, /* sve */
+ nullptr /* issue_info */
+};
+
+/* Approximation modes for X-Gene 1. */
+static const cpu_approx_modes xgene1_approx_modes =
+{
+ AARCH64_APPROX_NONE, /* division */
+ AARCH64_APPROX_NONE, /* sqrt */
+ AARCH64_APPROX_ALL /* recip_sqrt */
+};
+
+static const cpu_prefetch_tune xgene1_prefetch_tune =
+{
+ 8, /* num_slots */
+ 32, /* l1_cache_size */
+ 64, /* l1_cache_line_size */
+ 256, /* l2_cache_size */
+ true, /* prefetch_dynamic_strides */
+ -1, /* minimum_stride */
+ -1 /* default_opt_level */
+};
+
+static const struct tune_params xgene1_tunings =
+{
+ &xgene1_extra_costs,
+ &xgene1_addrcost_table,
+ &xgene1_regmove_cost,
+ &xgene1_vector_cost,
+ &generic_branch_cost,
+ &xgene1_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 6, /* load_int. */
+ 6, /* store_int. */
+ 6, /* load_fp. */
+ 6, /* store_fp. */
+ 6, /* load_pred. */
+ 6 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ AARCH64_FUSE_NOTHING, /* fusible_ops */
+ "16", /* function_align. */
+ "16", /* jump_align. */
+ "16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 1, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 17, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS), /* tune_flags. */
+ &xgene1_prefetch_tune,
+ AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */
+ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */
+};
+
+#endif /* GCC_AARCH64_H_XGENE1. */
diff --git a/gcc/config/arm/arm-builtins.cc b/gcc/config/arm/arm-builtins.cc
index fca7dca..dd9c581 100644
--- a/gcc/config/arm/arm-builtins.cc
+++ b/gcc/config/arm/arm-builtins.cc
@@ -1580,20 +1580,20 @@ arm_init_simd_builtin_types (void)
TYPE_STRING_FLAG (arm_simd_polyHI_type_node) = false;
}
/* Init all the element types built by the front-end. */
- arm_simd_types[Int8x8_t].eltype = intQI_type_node;
- arm_simd_types[Int8x16_t].eltype = intQI_type_node;
- arm_simd_types[Int16x4_t].eltype = intHI_type_node;
- arm_simd_types[Int16x8_t].eltype = intHI_type_node;
- arm_simd_types[Int32x2_t].eltype = intSI_type_node;
- arm_simd_types[Int32x4_t].eltype = intSI_type_node;
- arm_simd_types[Int64x2_t].eltype = intDI_type_node;
- arm_simd_types[Uint8x8_t].eltype = unsigned_intQI_type_node;
- arm_simd_types[Uint8x16_t].eltype = unsigned_intQI_type_node;
- arm_simd_types[Uint16x4_t].eltype = unsigned_intHI_type_node;
- arm_simd_types[Uint16x8_t].eltype = unsigned_intHI_type_node;
- arm_simd_types[Uint32x2_t].eltype = unsigned_intSI_type_node;
- arm_simd_types[Uint32x4_t].eltype = unsigned_intSI_type_node;
- arm_simd_types[Uint64x2_t].eltype = unsigned_intDI_type_node;
+ arm_simd_types[Int8x8_t].eltype = get_typenode_from_name (INT8_TYPE);
+ arm_simd_types[Int8x16_t].eltype = get_typenode_from_name (INT8_TYPE);
+ arm_simd_types[Int16x4_t].eltype = get_typenode_from_name (INT16_TYPE);
+ arm_simd_types[Int16x8_t].eltype = get_typenode_from_name (INT16_TYPE);
+ arm_simd_types[Int32x2_t].eltype = get_typenode_from_name (INT32_TYPE);
+ arm_simd_types[Int32x4_t].eltype = get_typenode_from_name (INT32_TYPE);
+ arm_simd_types[Int64x2_t].eltype = get_typenode_from_name (INT64_TYPE);
+ arm_simd_types[Uint8x8_t].eltype = get_typenode_from_name (UINT8_TYPE);
+ arm_simd_types[Uint8x16_t].eltype = get_typenode_from_name (UINT8_TYPE);
+ arm_simd_types[Uint16x4_t].eltype = get_typenode_from_name (UINT16_TYPE);
+ arm_simd_types[Uint16x8_t].eltype = get_typenode_from_name (UINT16_TYPE);
+ arm_simd_types[Uint32x2_t].eltype = get_typenode_from_name (UINT32_TYPE);
+ arm_simd_types[Uint32x4_t].eltype = get_typenode_from_name (UINT32_TYPE);
+ arm_simd_types[Uint64x2_t].eltype = get_typenode_from_name (UINT64_TYPE);
/* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
mangling. */
diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm-mve-builtins-base.cc
index 5478cac..cfe1b95 100644
--- a/gcc/config/arm/arm-mve-builtins-base.cc
+++ b/gcc/config/arm/arm-mve-builtins-base.cc
@@ -83,6 +83,62 @@ class vuninitializedq_impl : public quiet<function_base>
}
};
+class vld1_impl : public full_width_access
+{
+public:
+ unsigned int
+ call_properties (const function_instance &) const override
+ {
+ return CP_READ_MEMORY;
+ }
+
+ rtx
+ expand (function_expander &e) const override
+ {
+ insn_code icode;
+ if (e.type_suffix (0).float_p)
+ icode = code_for_mve_vld1q_f(e.vector_mode (0));
+ else
+ {
+ if (e.type_suffix (0).unsigned_p)
+ icode = code_for_mve_vld1q(VLD1Q_U,
+ e.vector_mode (0));
+ else
+ icode = code_for_mve_vld1q(VLD1Q_S,
+ e.vector_mode (0));
+ }
+ return e.use_contiguous_load_insn (icode);
+ }
+};
+
+class vst1_impl : public full_width_access
+{
+public:
+ unsigned int
+ call_properties (const function_instance &) const override
+ {
+ return CP_WRITE_MEMORY;
+ }
+
+ rtx
+ expand (function_expander &e) const override
+ {
+ insn_code icode;
+ if (e.type_suffix (0).float_p)
+ icode = code_for_mve_vst1q_f(e.vector_mode (0));
+ else
+ {
+ if (e.type_suffix (0).unsigned_p)
+ icode = code_for_mve_vst1q(VST1Q_U,
+ e.vector_mode (0));
+ else
+ icode = code_for_mve_vst1q(VST1Q_S,
+ e.vector_mode (0));
+ }
+ return e.use_contiguous_store_insn (icode);
+ }
+};
+
} /* end anonymous namespace */
namespace arm_mve {
@@ -290,6 +346,7 @@ FUNCTION (vfmasq, unspec_mve_function_exact_insn, (-1, -1, -1, -1, -1, VFMASQ_N_
FUNCTION (vfmsq, unspec_mve_function_exact_insn, (-1, -1, VFMSQ_F, -1, -1, -1, -1, -1, VFMSQ_M_F, -1, -1, -1))
FUNCTION_WITH_M_N_NO_F (vhaddq, VHADDQ)
FUNCTION_WITH_M_N_NO_F (vhsubq, VHSUBQ)
+FUNCTION (vld1q, vld1_impl,)
FUNCTION_PRED_P_S (vmaxavq, VMAXAVQ)
FUNCTION_WITHOUT_N_NO_U_F (vmaxaq, VMAXAQ)
FUNCTION_ONLY_F (vmaxnmaq, VMAXNMAQ)
@@ -405,6 +462,7 @@ FUNCTION_ONLY_N_NO_F (vshrntq, VSHRNTQ)
FUNCTION_ONLY_N_NO_F (vshrq, VSHRQ)
FUNCTION_ONLY_N_NO_F (vsliq, VSLIQ)
FUNCTION_ONLY_N_NO_F (vsriq, VSRIQ)
+FUNCTION (vst1q, vst1_impl,)
FUNCTION_WITH_RTX_M_N (vsubq, MINUS, VSUBQ)
FUNCTION (vuninitializedq, vuninitializedq_impl,)
diff --git a/gcc/config/arm/arm-mve-builtins-base.def b/gcc/config/arm/arm-mve-builtins-base.def
index 01dfbde..1687924 100644
--- a/gcc/config/arm/arm-mve-builtins-base.def
+++ b/gcc/config/arm/arm-mve-builtins-base.def
@@ -47,6 +47,7 @@ DEF_MVE_FUNCTION (vhaddq, binary_opt_n, all_integer, mx_or_none)
DEF_MVE_FUNCTION (vhcaddq_rot90, binary, all_signed, mx_or_none)
DEF_MVE_FUNCTION (vhcaddq_rot270, binary, all_signed, mx_or_none)
DEF_MVE_FUNCTION (vhsubq, binary_opt_n, all_integer, mx_or_none)
+DEF_MVE_FUNCTION (vld1q, load, all_integer, none)
DEF_MVE_FUNCTION (vmaxaq, binary_maxamina, all_signed, m_or_none)
DEF_MVE_FUNCTION (vmaxavq, binary_maxavminav, all_signed, p_or_none)
DEF_MVE_FUNCTION (vmaxq, binary, all_integer, mx_or_none)
@@ -150,6 +151,7 @@ DEF_MVE_FUNCTION (vshrntq, binary_rshift_narrow, integer_16_32, m_or_none)
DEF_MVE_FUNCTION (vshrq, binary_rshift, all_integer, mx_or_none)
DEF_MVE_FUNCTION (vsliq, ternary_lshift, all_integer, m_or_none)
DEF_MVE_FUNCTION (vsriq, ternary_rshift, all_integer, m_or_none)
+DEF_MVE_FUNCTION (vst1q, store, all_integer, none)
DEF_MVE_FUNCTION (vsubq, binary_opt_n, all_integer, mx_or_none)
DEF_MVE_FUNCTION (vuninitializedq, inherent, all_integer_with_64, none)
#undef REQUIRES_FLOAT
@@ -182,6 +184,7 @@ DEF_MVE_FUNCTION (veorq, binary, all_float, mx_or_none)
DEF_MVE_FUNCTION (vfmaq, ternary_opt_n, all_float, m_or_none)
DEF_MVE_FUNCTION (vfmasq, ternary_n, all_float, m_or_none)
DEF_MVE_FUNCTION (vfmsq, ternary, all_float, m_or_none)
+DEF_MVE_FUNCTION (vld1q, load, all_float, none)
DEF_MVE_FUNCTION (vmaxnmaq, binary, all_float, m_or_none)
DEF_MVE_FUNCTION (vmaxnmavq, binary_maxvminv, all_float, p_or_none)
DEF_MVE_FUNCTION (vmaxnmq, binary, all_float, mx_or_none)
@@ -203,6 +206,7 @@ DEF_MVE_FUNCTION (vrndnq, unary, all_float, mx_or_none)
DEF_MVE_FUNCTION (vrndpq, unary, all_float, mx_or_none)
DEF_MVE_FUNCTION (vrndq, unary, all_float, mx_or_none)
DEF_MVE_FUNCTION (vrndxq, unary, all_float, mx_or_none)
+DEF_MVE_FUNCTION (vst1q, store, all_float, none)
DEF_MVE_FUNCTION (vsubq, binary_opt_n, all_float, mx_or_none)
DEF_MVE_FUNCTION (vuninitializedq, inherent, all_float, none)
#undef REQUIRES_FLOAT
diff --git a/gcc/config/arm/arm-mve-builtins-base.h b/gcc/config/arm/arm-mve-builtins-base.h
index c574c32..8c7e5fe 100644
--- a/gcc/config/arm/arm-mve-builtins-base.h
+++ b/gcc/config/arm/arm-mve-builtins-base.h
@@ -63,6 +63,7 @@ extern const function_base *const vhaddq;
extern const function_base *const vhcaddq_rot270;
extern const function_base *const vhcaddq_rot90;
extern const function_base *const vhsubq;
+extern const function_base *const vld1q;
extern const function_base *const vmaxaq;
extern const function_base *const vmaxavq;
extern const function_base *const vmaxnmaq;
@@ -103,8 +104,8 @@ extern const function_base *const vmovnbq;
extern const function_base *const vmovntq;
extern const function_base *const vmulhq;
extern const function_base *const vmullbq_int;
-extern const function_base *const vmulltq_int;
extern const function_base *const vmullbq_poly;
+extern const function_base *const vmulltq_int;
extern const function_base *const vmulltq_poly;
extern const function_base *const vmulq;
extern const function_base *const vmvnq;
@@ -178,6 +179,7 @@ extern const function_base *const vshrntq;
extern const function_base *const vshrq;
extern const function_base *const vsliq;
extern const function_base *const vsriq;
+extern const function_base *const vst1q;
extern const function_base *const vsubq;
extern const function_base *const vuninitializedq;
diff --git a/gcc/config/arm/arm-mve-builtins-functions.h b/gcc/config/arm/arm-mve-builtins-functions.h
index eba1f07..1c93e64 100644
--- a/gcc/config/arm/arm-mve-builtins-functions.h
+++ b/gcc/config/arm/arm-mve-builtins-functions.h
@@ -966,6 +966,64 @@ public:
}
};
+/* A function_base that sometimes or always operates on tuples of
+ vectors. */
+class multi_vector_function : public function_base
+{
+public:
+ CONSTEXPR multi_vector_function (unsigned int vectors_per_tuple)
+ : m_vectors_per_tuple (vectors_per_tuple) {}
+
+ unsigned int
+ vectors_per_tuple () const override
+ {
+ return m_vectors_per_tuple;
+ }
+
+ /* The number of vectors in a tuple, or 1 if the function only operates
+ on single vectors. */
+ unsigned int m_vectors_per_tuple;
+};
+
+/* A function_base that loads or stores contiguous memory elements
+ without extending or truncating them. */
+class full_width_access : public multi_vector_function
+{
+public:
+ CONSTEXPR full_width_access (unsigned int vectors_per_tuple = 1)
+ : multi_vector_function (vectors_per_tuple) {}
+
+ tree
+ memory_scalar_type (const function_instance &fi) const override
+ {
+ return fi.scalar_type (0);
+ }
+
+ machine_mode
+ memory_vector_mode (const function_instance &fi) const override
+ {
+ machine_mode mode = fi.vector_mode (0);
+ /* Vectors of floating-point are managed in memory as vectors of
+ integers. */
+ switch (mode)
+ {
+ case E_V4SFmode:
+ mode = E_V4SImode;
+ break;
+ case E_V8HFmode:
+ mode = E_V8HImode;
+ break;
+ default:
+ break;
+ }
+
+ if (m_vectors_per_tuple != 1)
+ mode = targetm.array_mode (mode, m_vectors_per_tuple).require ();
+
+ return mode;
+ }
+};
+
} /* end namespace arm_mve */
/* Declare the global function base NAME, creating it from an instance
diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc b/gcc/config/arm/arm-mve-builtins-shapes.cc
index 23eb9d0..fe983e7 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.cc
+++ b/gcc/config/arm/arm-mve-builtins-shapes.cc
@@ -39,6 +39,13 @@
namespace arm_mve {
+/* Return a representation of "const T *". */
+static tree
+build_const_pointer (tree t)
+{
+ return build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST));
+}
+
/* If INSTANCE has a predicate, add it to the list of argument types
in ARGUMENT_TYPES. RETURN_TYPE is the type returned by the
function. */
@@ -140,6 +147,9 @@ parse_element_type (const function_instance &instance, const char *&format)
/* Read and return a type from FORMAT for function INSTANCE. Advance
FORMAT beyond the type string. The format is:
+ _ - void
+ al - array pointer for loads
+ as - array pointer for stores
p - predicates with type mve_pred16_t
s<elt> - a scalar type with the given element suffix
t<elt> - a vector or tuple type with given element suffix [*1]
@@ -156,6 +166,21 @@ parse_type (const function_instance &instance, const char *&format)
{
int ch = *format++;
+
+ if (ch == '_')
+ return void_type_node;
+
+ if (ch == 'a')
+ {
+ ch = *format++;
+ if (ch == 'l')
+ return build_const_pointer (instance.memory_scalar_type ());
+ if (ch == 's') {
+ return build_pointer_type (instance.memory_scalar_type ());
+ }
+ gcc_unreachable ();
+ }
+
if (ch == 'p')
return get_mve_pred16_t ();
@@ -1403,6 +1428,38 @@ struct inherent_def : public nonoverloaded_base
};
SHAPE (inherent)
+/* sv<t0>_t svfoo[_t0](const <t0>_t *)
+
+ Example: vld1q.
+ int8x16_t [__arm_]vld1q[_s8](int8_t const *base)
+ int8x16_t [__arm_]vld1q_z[_s8](int8_t const *base, mve_pred16_t p) */
+struct load_def : public overloaded_base<0>
+{
+ void
+ build (function_builder &b, const function_group_info &group,
+ bool preserve_user_namespace) const override
+ {
+ b.add_overloaded_functions (group, MODE_none, preserve_user_namespace);
+ build_all (b, "t0,al", group, MODE_none, preserve_user_namespace);
+ }
+
+ /* Resolve a call based purely on a pointer argument. */
+ tree
+ resolve (function_resolver &r) const override
+ {
+ gcc_assert (r.mode_suffix_id == MODE_none);
+
+ unsigned int i, nargs;
+ type_suffix_index type;
+ if (!r.check_gp_argument (1, i, nargs)
+ || (type = r.infer_pointer_type (i)) == NUM_TYPE_SUFFIXES)
+ return error_mark_node;
+
+ return r.resolve_to (r.mode_suffix_id, type);
+ }
+};
+SHAPE (load)
+
/* <T0>_t vfoo[_t0](<T0>_t)
<T0>_t vfoo_n_t0(<sT0>_t)
@@ -1452,6 +1509,41 @@ struct mvn_def : public overloaded_base<0>
};
SHAPE (mvn)
+/* void vfoo[_t0](<X>_t *, v<t0>[xN]_t)
+
+ where <X> might be tied to <t0> (for non-truncating stores) or might
+ depend on the function base name (for truncating stores).
+
+ Example: vst1q.
+ void [__arm_]vst1q[_s8](int8_t *base, int8x16_t value)
+ void [__arm_]vst1q_p[_s8](int8_t *base, int8x16_t value, mve_pred16_t p) */
+struct store_def : public overloaded_base<0>
+{
+ void
+ build (function_builder &b, const function_group_info &group,
+ bool preserve_user_namespace) const override
+ {
+ b.add_overloaded_functions (group, MODE_none, preserve_user_namespace);
+ build_all (b, "_,as,v0", group, MODE_none, preserve_user_namespace);
+ }
+
+ tree
+ resolve (function_resolver &r) const override
+ {
+ gcc_assert (r.mode_suffix_id == MODE_none);
+
+ unsigned int i, nargs;
+ type_suffix_index type;
+ if (!r.check_gp_argument (2, i, nargs)
+ || !r.require_pointer_type (0)
+ || (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES)
+ return error_mark_node;
+
+ return r.resolve_to (r.mode_suffix_id, type);
+ }
+};
+SHAPE (store)
+
/* <T0>_t vfoo[_t0](<T0>_t, <T0>_t, <T0>_t)
i.e. the standard shape for ternary operations that operate on
diff --git a/gcc/config/arm/arm-mve-builtins-shapes.h b/gcc/config/arm/arm-mve-builtins-shapes.h
index a932453..aa9309d 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.h
+++ b/gcc/config/arm/arm-mve-builtins-shapes.h
@@ -61,7 +61,9 @@ namespace arm_mve
extern const function_shape *const cmp;
extern const function_shape *const create;
extern const function_shape *const inherent;
+ extern const function_shape *const load;
extern const function_shape *const mvn;
+ extern const function_shape *const store;
extern const function_shape *const ternary;
extern const function_shape *const ternary_lshift;
extern const function_shape *const ternary_n;
diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc
index 02dc8fa..dec163d 100644
--- a/gcc/config/arm/arm-mve-builtins.cc
+++ b/gcc/config/arm/arm-mve-builtins.cc
@@ -36,6 +36,7 @@
#include "fold-const.h"
#include "gimple.h"
#include "gimple-iterator.h"
+#include "explow.h"
#include "emit-rtl.h"
#include "langhooks.h"
#include "stringpool.h"
@@ -529,6 +530,22 @@ matches_type_p (const_tree model_type, const_tree candidate)
&& TYPE_MAIN_VARIANT (model_type) == TYPE_MAIN_VARIANT (candidate));
}
+/* If TYPE is a valid MVE element type, return the corresponding type
+ suffix, otherwise return NUM_TYPE_SUFFIXES. */
+static type_suffix_index
+find_type_suffix_for_scalar_type (const_tree type)
+{
+ /* A linear search should be OK here, since the code isn't hot and
+ the number of types is only small. */
+ for (unsigned int suffix_i = 0; suffix_i < NUM_TYPE_SUFFIXES; ++suffix_i)
+ {
+ vector_type_index vector_i = type_suffixes[suffix_i].vector_type;
+ if (matches_type_p (scalar_types[vector_i], type))
+ return type_suffix_index (suffix_i);
+ }
+ return NUM_TYPE_SUFFIXES;
+}
+
/* Report an error against LOCATION that the user has tried to use
a floating point function when the mve.fp extension is disabled. */
static void
@@ -1125,6 +1142,36 @@ function_resolver::resolve_to (mode_suffix_index mode,
return res;
}
+/* Require argument ARGNO to be a pointer to a scalar type that has a
+ corresponding type suffix. Return that type suffix on success,
+ otherwise report an error and return NUM_TYPE_SUFFIXES. */
+type_suffix_index
+function_resolver::infer_pointer_type (unsigned int argno)
+{
+ tree actual = get_argument_type (argno);
+ if (actual == error_mark_node)
+ return NUM_TYPE_SUFFIXES;
+
+ if (TREE_CODE (actual) != POINTER_TYPE)
+ {
+ error_at (location, "passing %qT to argument %d of %qE, which"
+ " expects a pointer type", actual, argno + 1, fndecl);
+ return NUM_TYPE_SUFFIXES;
+ }
+
+ tree target = TREE_TYPE (actual);
+ type_suffix_index type = find_type_suffix_for_scalar_type (target);
+ if (type == NUM_TYPE_SUFFIXES)
+ {
+ error_at (location, "passing %qT to argument %d of %qE, but %qT is not"
+ " a valid MVE element type", actual, argno + 1, fndecl,
+ build_qualified_type (target, 0));
+ return NUM_TYPE_SUFFIXES;
+ }
+
+ return type;
+}
+
/* Require argument ARGNO to be a single vector or a tuple of NUM_VECTORS
vectors; NUM_VECTORS is 1 for the former. Return the associated type
suffix on success, using TYPE_SUFFIX_b for predicates. Report an error
@@ -1498,6 +1545,22 @@ function_resolver::require_scalar_type (unsigned int argno,
return true;
}
+/* Require argument ARGNO to be some form of pointer, without being specific
+ about its target type. Return true if the argument has the right form,
+ otherwise report an appropriate error. */
+bool
+function_resolver::require_pointer_type (unsigned int argno)
+{
+ if (!scalar_argument_p (argno))
+ {
+ error_at (location, "passing %qT to argument %d of %qE, which"
+ " expects a scalar pointer", get_argument_type (argno),
+ argno + 1, fndecl);
+ return false;
+ }
+ return true;
+}
+
/* Require the function to have exactly EXPECTED arguments. Return true
if it does, otherwise report an appropriate error. */
bool
@@ -1955,6 +2018,14 @@ function_expander::direct_optab_handler (optab op, unsigned int suffix_i)
return ::direct_optab_handler (op, vector_mode (suffix_i));
}
+/* Return the base address for a contiguous load or store
+ function. */
+rtx
+function_expander::get_contiguous_base ()
+{
+ return args[0];
+}
+
/* For a function that does the equivalent of:
OUTPUT = COND ? FN (INPUTS) : FALLBACK;
@@ -2043,6 +2114,26 @@ function_expander::add_integer_operand (HOST_WIDE_INT x)
create_integer_operand (&m_ops.last (), x);
}
+/* Add a memory operand with mode MODE and address ADDR. */
+void
+function_expander::add_mem_operand (machine_mode mode, rtx addr)
+{
+ gcc_assert (VECTOR_MODE_P (mode));
+ rtx mem = gen_rtx_MEM (mode, memory_address (mode, addr));
+ /* The memory is only guaranteed to be element-aligned. */
+ set_mem_align (mem, GET_MODE_ALIGNMENT (GET_MODE_INNER (mode)));
+ add_fixed_operand (mem);
+}
+
+/* Add an operand that must be X. The only way of legitimizing an
+ invalid X is to reload the address of a MEM. */
+void
+function_expander::add_fixed_operand (rtx x)
+{
+ m_ops.safe_grow (m_ops.length () + 1, true);
+ create_fixed_operand (&m_ops.last (), x);
+}
+
/* Generate instruction ICODE, given that its operands have already
been added to M_OPS. Return the value of the first operand. */
rtx
@@ -2137,6 +2228,30 @@ function_expander::use_cond_insn (insn_code icode, unsigned int merge_argno)
return generate_insn (icode);
}
+/* Implement the call using instruction ICODE, which loads memory operand 1
+ into register operand 0. */
+rtx
+function_expander::use_contiguous_load_insn (insn_code icode)
+{
+ machine_mode mem_mode = memory_vector_mode ();
+
+ add_output_operand (icode);
+ add_mem_operand (mem_mode, get_contiguous_base ());
+ return generate_insn (icode);
+}
+
+/* Implement the call using instruction ICODE, which stores register operand 1
+ into memory operand 0. */
+rtx
+function_expander::use_contiguous_store_insn (insn_code icode)
+{
+ machine_mode mem_mode = memory_vector_mode ();
+
+ add_mem_operand (mem_mode, get_contiguous_base ());
+ add_input_operand (icode, args[1]);
+ return generate_insn (icode);
+}
+
/* Implement the call using a normal unpredicated optab for PRED_none.
<optab> corresponds to:
diff --git a/gcc/config/arm/arm-mve-builtins.def b/gcc/config/arm/arm-mve-builtins.def
index e2cf1ba..a901d82 100644
--- a/gcc/config/arm/arm-mve-builtins.def
+++ b/gcc/config/arm/arm-mve-builtins.def
@@ -39,14 +39,14 @@ DEF_MVE_MODE (r, none, none, none)
#define REQUIRES_FLOAT false
DEF_MVE_TYPE (mve_pred16_t, boolean_type_node)
-DEF_MVE_TYPE (uint8x16_t, unsigned_intQI_type_node)
-DEF_MVE_TYPE (uint16x8_t, unsigned_intHI_type_node)
-DEF_MVE_TYPE (uint32x4_t, unsigned_intSI_type_node)
-DEF_MVE_TYPE (uint64x2_t, unsigned_intDI_type_node)
-DEF_MVE_TYPE (int8x16_t, intQI_type_node)
-DEF_MVE_TYPE (int16x8_t, intHI_type_node)
-DEF_MVE_TYPE (int32x4_t, intSI_type_node)
-DEF_MVE_TYPE (int64x2_t, intDI_type_node)
+DEF_MVE_TYPE (uint8x16_t, get_typenode_from_name (UINT8_TYPE))
+DEF_MVE_TYPE (uint16x8_t, get_typenode_from_name (UINT16_TYPE))
+DEF_MVE_TYPE (uint32x4_t, get_typenode_from_name (UINT32_TYPE))
+DEF_MVE_TYPE (uint64x2_t, get_typenode_from_name (UINT64_TYPE))
+DEF_MVE_TYPE (int8x16_t, get_typenode_from_name (INT8_TYPE))
+DEF_MVE_TYPE (int16x8_t, get_typenode_from_name (INT16_TYPE))
+DEF_MVE_TYPE (int32x4_t, get_typenode_from_name (INT32_TYPE))
+DEF_MVE_TYPE (int64x2_t, get_typenode_from_name (INT64_TYPE))
#undef REQUIRES_FLOAT
#define REQUIRES_FLOAT true
diff --git a/gcc/config/arm/arm-mve-builtins.h b/gcc/config/arm/arm-mve-builtins.h
index 37b8223..9c219fa 100644
--- a/gcc/config/arm/arm-mve-builtins.h
+++ b/gcc/config/arm/arm-mve-builtins.h
@@ -277,6 +277,8 @@ public:
bool could_trap_p () const;
unsigned int vectors_per_tuple () const;
+ tree memory_scalar_type () const;
+ machine_mode memory_vector_mode () const;
const mode_suffix_info &mode_suffix () const;
@@ -382,6 +384,7 @@ public:
type_suffix_index = NUM_TYPE_SUFFIXES,
type_suffix_index = NUM_TYPE_SUFFIXES);
+ type_suffix_index infer_pointer_type (unsigned int);
type_suffix_index infer_vector_or_tuple_type (unsigned int, unsigned int);
type_suffix_index infer_vector_type (unsigned int);
@@ -393,8 +396,9 @@ public:
type_suffix_index,
type_class_index = SAME_TYPE_CLASS,
unsigned int = SAME_SIZE);
- bool require_integer_immediate (unsigned int);
bool require_scalar_type (unsigned int, const char *);
+ bool require_pointer_type (unsigned int);
+ bool require_integer_immediate (unsigned int);
bool require_derived_scalar_type (unsigned int, type_class_index,
unsigned int = SAME_SIZE);
@@ -475,18 +479,23 @@ public:
insn_code direct_optab_handler (optab, unsigned int = 0);
+ rtx get_contiguous_base ();
rtx get_fallback_value (machine_mode, unsigned int, unsigned int &);
rtx get_reg_target ();
void add_output_operand (insn_code);
void add_input_operand (insn_code, rtx);
void add_integer_operand (HOST_WIDE_INT);
+ void add_mem_operand (machine_mode, rtx);
+ void add_fixed_operand (rtx);
rtx generate_insn (insn_code);
rtx use_exact_insn (insn_code);
rtx use_unpred_insn (insn_code);
rtx use_pred_x_insn (insn_code);
rtx use_cond_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO);
+ rtx use_contiguous_load_insn (insn_code);
+ rtx use_contiguous_store_insn (insn_code);
rtx map_to_rtx_codes (rtx_code, rtx_code, rtx_code);
@@ -519,6 +528,23 @@ public:
of vectors in the tuples, otherwise return 1. */
virtual unsigned int vectors_per_tuple () const { return 1; }
+ /* If the function addresses memory, return the type of a single
+ scalar memory element. */
+ virtual tree
+ memory_scalar_type (const function_instance &) const
+ {
+ gcc_unreachable ();
+ }
+
+ /* If the function addresses memory, return a vector mode whose
+ GET_MODE_NUNITS is the number of elements addressed and whose
+ GET_MODE_INNER is the mode of a single scalar memory element. */
+ virtual machine_mode
+ memory_vector_mode (const function_instance &) const
+ {
+ gcc_unreachable ();
+ }
+
/* Try to fold the given gimple call. Return the new gimple statement
on success, otherwise return null. */
virtual gimple *fold (gimple_folder &) const { return NULL; }
@@ -644,6 +670,23 @@ function_instance::vectors_per_tuple () const
return base->vectors_per_tuple ();
}
+/* If the function addresses memory, return the type of a single
+ scalar memory element. */
+inline tree
+function_instance::memory_scalar_type () const
+{
+ return base->memory_scalar_type (*this);
+}
+
+/* If the function addresses memory, return a vector mode whose
+ GET_MODE_NUNITS is the number of elements addressed and whose
+ GET_MODE_INNER is the mode of a single scalar memory element. */
+inline machine_mode
+function_instance::memory_vector_mode () const
+{
+ return base->memory_vector_mode (*this);
+}
+
/* Return information about the function's mode suffix. */
inline const mode_suffix_info &
function_instance::mode_suffix () const
diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index b82d94e..cc027f9 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -56,7 +56,6 @@
#define vstrbq_scatter_offset_p(__base, __offset, __value, __p) __arm_vstrbq_scatter_offset_p(__base, __offset, __value, __p)
#define vstrwq_scatter_base_p(__addr, __offset, __value, __p) __arm_vstrwq_scatter_base_p(__addr, __offset, __value, __p)
#define vldrbq_gather_offset_z(__base, __offset, __p) __arm_vldrbq_gather_offset_z(__base, __offset, __p)
-#define vld1q(__base) __arm_vld1q(__base)
#define vldrhq_gather_offset(__base, __offset) __arm_vldrhq_gather_offset(__base, __offset)
#define vldrhq_gather_offset_z(__base, __offset, __p) __arm_vldrhq_gather_offset_z(__base, __offset, __p)
#define vldrhq_gather_shifted_offset(__base, __offset) __arm_vldrhq_gather_shifted_offset(__base, __offset)
@@ -69,7 +68,6 @@
#define vldrwq_gather_offset_z(__base, __offset, __p) __arm_vldrwq_gather_offset_z(__base, __offset, __p)
#define vldrwq_gather_shifted_offset(__base, __offset) __arm_vldrwq_gather_shifted_offset(__base, __offset)
#define vldrwq_gather_shifted_offset_z(__base, __offset, __p) __arm_vldrwq_gather_shifted_offset_z(__base, __offset, __p)
-#define vst1q(__addr, __value) __arm_vst1q(__addr, __value)
#define vstrhq_scatter_offset(__base, __offset, __value) __arm_vstrhq_scatter_offset(__base, __offset, __value)
#define vstrhq_scatter_offset_p(__base, __offset, __value, __p) __arm_vstrhq_scatter_offset_p(__base, __offset, __value, __p)
#define vstrhq_scatter_shifted_offset(__base, __offset, __value) __arm_vstrhq_scatter_shifted_offset(__base, __offset, __value)
@@ -346,12 +344,6 @@
#define vldrbq_z_u32(__base, __p) __arm_vldrbq_z_u32(__base, __p)
#define vldrwq_gather_base_z_u32(__addr, __offset, __p) __arm_vldrwq_gather_base_z_u32(__addr, __offset, __p)
#define vldrwq_gather_base_z_s32(__addr, __offset, __p) __arm_vldrwq_gather_base_z_s32(__addr, __offset, __p)
-#define vld1q_s8(__base) __arm_vld1q_s8(__base)
-#define vld1q_s32(__base) __arm_vld1q_s32(__base)
-#define vld1q_s16(__base) __arm_vld1q_s16(__base)
-#define vld1q_u8(__base) __arm_vld1q_u8(__base)
-#define vld1q_u32(__base) __arm_vld1q_u32(__base)
-#define vld1q_u16(__base) __arm_vld1q_u16(__base)
#define vldrhq_gather_offset_s32(__base, __offset) __arm_vldrhq_gather_offset_s32(__base, __offset)
#define vldrhq_gather_offset_s16(__base, __offset) __arm_vldrhq_gather_offset_s16(__base, __offset)
#define vldrhq_gather_offset_u32(__base, __offset) __arm_vldrhq_gather_offset_u32(__base, __offset)
@@ -380,8 +372,6 @@
#define vldrwq_u32(__base) __arm_vldrwq_u32(__base)
#define vldrwq_z_s32(__base, __p) __arm_vldrwq_z_s32(__base, __p)
#define vldrwq_z_u32(__base, __p) __arm_vldrwq_z_u32(__base, __p)
-#define vld1q_f32(__base) __arm_vld1q_f32(__base)
-#define vld1q_f16(__base) __arm_vld1q_f16(__base)
#define vldrhq_f16(__base) __arm_vldrhq_f16(__base)
#define vldrhq_z_f16(__base, __p) __arm_vldrhq_z_f16(__base, __p)
#define vldrwq_f32(__base) __arm_vldrwq_f32(__base)
@@ -416,14 +406,6 @@
#define vldrwq_gather_shifted_offset_z_f32(__base, __offset, __p) __arm_vldrwq_gather_shifted_offset_z_f32(__base, __offset, __p)
#define vldrwq_gather_shifted_offset_z_s32(__base, __offset, __p) __arm_vldrwq_gather_shifted_offset_z_s32(__base, __offset, __p)
#define vldrwq_gather_shifted_offset_z_u32(__base, __offset, __p) __arm_vldrwq_gather_shifted_offset_z_u32(__base, __offset, __p)
-#define vst1q_f32(__addr, __value) __arm_vst1q_f32(__addr, __value)
-#define vst1q_f16(__addr, __value) __arm_vst1q_f16(__addr, __value)
-#define vst1q_s8(__addr, __value) __arm_vst1q_s8(__addr, __value)
-#define vst1q_s32(__addr, __value) __arm_vst1q_s32(__addr, __value)
-#define vst1q_s16(__addr, __value) __arm_vst1q_s16(__addr, __value)
-#define vst1q_u8(__addr, __value) __arm_vst1q_u8(__addr, __value)
-#define vst1q_u32(__addr, __value) __arm_vst1q_u32(__addr, __value)
-#define vst1q_u16(__addr, __value) __arm_vst1q_u16(__addr, __value)
#define vstrhq_f16(__addr, __value) __arm_vstrhq_f16(__addr, __value)
#define vstrhq_scatter_offset_s32( __base, __offset, __value) __arm_vstrhq_scatter_offset_s32( __base, __offset, __value)
#define vstrhq_scatter_offset_s16( __base, __offset, __value) __arm_vstrhq_scatter_offset_s16( __base, __offset, __value)
@@ -1537,48 +1519,6 @@ __arm_vldrwq_gather_base_z_u32 (uint32x4_t __addr, const int __offset, mve_pred1
return __builtin_mve_vldrwq_gather_base_z_uv4si (__addr, __offset, __p);
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_s8 (int8_t const * __base)
-{
- return __builtin_mve_vld1q_sv16qi ((__builtin_neon_qi *) __base);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_s32 (int32_t const * __base)
-{
- return __builtin_mve_vld1q_sv4si ((__builtin_neon_si *) __base);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_s16 (int16_t const * __base)
-{
- return __builtin_mve_vld1q_sv8hi ((__builtin_neon_hi *) __base);
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_u8 (uint8_t const * __base)
-{
- return __builtin_mve_vld1q_uv16qi ((__builtin_neon_qi *) __base);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_u32 (uint32_t const * __base)
-{
- return __builtin_mve_vld1q_uv4si ((__builtin_neon_si *) __base);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_u16 (uint16_t const * __base)
-{
- return __builtin_mve_vld1q_uv8hi ((__builtin_neon_hi *) __base);
-}
-
__extension__ extern __inline int32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vldrhq_gather_offset_s32 (int16_t const * __base, uint32x4_t __offset)
@@ -1919,48 +1859,6 @@ __arm_vldrwq_gather_shifted_offset_z_u32 (uint32_t const * __base, uint32x4_t __
__extension__ extern __inline void
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_s8 (int8_t * __addr, int8x16_t __value)
-{
- __builtin_mve_vst1q_sv16qi ((__builtin_neon_qi *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_s32 (int32_t * __addr, int32x4_t __value)
-{
- __builtin_mve_vst1q_sv4si ((__builtin_neon_si *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_s16 (int16_t * __addr, int16x8_t __value)
-{
- __builtin_mve_vst1q_sv8hi ((__builtin_neon_hi *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_u8 (uint8_t * __addr, uint8x16_t __value)
-{
- __builtin_mve_vst1q_uv16qi ((__builtin_neon_qi *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_u32 (uint32_t * __addr, uint32x4_t __value)
-{
- __builtin_mve_vst1q_uv4si ((__builtin_neon_si *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_u16 (uint16_t * __addr, uint16x8_t __value)
-{
- __builtin_mve_vst1q_uv8hi ((__builtin_neon_hi *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vstrhq_scatter_offset_s32 (int16_t * __base, uint32x4_t __offset, int32x4_t __value)
{
__builtin_mve_vstrhq_scatter_offset_sv4si ((__builtin_neon_hi *) __base, __offset, __value);
@@ -4423,20 +4321,6 @@ __arm_vornq_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve
__extension__ extern __inline float32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_f32 (float32_t const * __base)
-{
- return __builtin_mve_vld1q_fv4sf((__builtin_neon_si *) __base);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q_f16 (float16_t const * __base)
-{
- return __builtin_mve_vld1q_fv8hf((__builtin_neon_hi *) __base);
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vldrwq_f32 (float32_t const * __base)
{
return __builtin_mve_vldrwq_fv4sf((__builtin_neon_si *) __base);
@@ -4549,20 +4433,6 @@ __arm_vstrwq_f32 (float32_t * __addr, float32x4_t __value)
__extension__ extern __inline void
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_f32 (float32_t * __addr, float32x4_t __value)
-{
- __builtin_mve_vst1q_fv4sf ((__builtin_neon_si *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q_f16 (float16_t * __addr, float16x8_t __value)
-{
- __builtin_mve_vst1q_fv8hf ((__builtin_neon_hi *) __addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vstrhq_f16 (float16_t * __addr, float16x8_t __value)
{
__builtin_mve_vstrhq_fv8hf ((__builtin_neon_hi *) __addr, __value);
@@ -5651,48 +5521,6 @@ __arm_vldrbq_gather_offset_z (uint8_t const * __base, uint16x8_t __offset, mve_p
return __arm_vldrbq_gather_offset_z_u16 (__base, __offset, __p);
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (int8_t const * __base)
-{
- return __arm_vld1q_s8 (__base);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (int32_t const * __base)
-{
- return __arm_vld1q_s32 (__base);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (int16_t const * __base)
-{
- return __arm_vld1q_s16 (__base);
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (uint8_t const * __base)
-{
- return __arm_vld1q_u8 (__base);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (uint32_t const * __base)
-{
- return __arm_vld1q_u32 (__base);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (uint16_t const * __base)
-{
- return __arm_vld1q_u16 (__base);
-}
-
__extension__ extern __inline int32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vldrhq_gather_offset (int16_t const * __base, uint32x4_t __offset)
@@ -5919,48 +5747,6 @@ __arm_vldrwq_gather_shifted_offset_z (uint32_t const * __base, uint32x4_t __offs
__extension__ extern __inline void
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (int8_t * __addr, int8x16_t __value)
-{
- __arm_vst1q_s8 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (int32_t * __addr, int32x4_t __value)
-{
- __arm_vst1q_s32 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (int16_t * __addr, int16x8_t __value)
-{
- __arm_vst1q_s16 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (uint8_t * __addr, uint8x16_t __value)
-{
- __arm_vst1q_u8 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (uint32_t * __addr, uint32x4_t __value)
-{
- __arm_vst1q_u32 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (uint16_t * __addr, uint16x8_t __value)
-{
- __arm_vst1q_u16 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vstrhq_scatter_offset (int16_t * __base, uint32x4_t __offset, int32x4_t __value)
{
__arm_vstrhq_scatter_offset_s32 (__base, __offset, __value);
@@ -7809,20 +7595,6 @@ __arm_vornq_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pre
return __arm_vornq_m_f16 (__inactive, __a, __b, __p);
}
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (float32_t const * __base)
-{
- return __arm_vld1q_f32 (__base);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vld1q (float16_t const * __base)
-{
- return __arm_vld1q_f16 (__base);
-}
-
__extension__ extern __inline float16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vldrhq_gather_offset (float16_t const * __base, uint16x8_t __offset)
@@ -7895,20 +7667,6 @@ __arm_vstrwq (float32_t * __addr, float32x4_t __value)
__extension__ extern __inline void
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (float32_t * __addr, float32x4_t __value)
-{
- __arm_vst1q_f32 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vst1q (float16_t * __addr, float16x8_t __value)
-{
- __arm_vst1q_f16 (__addr, __value);
-}
-
-__extension__ extern __inline void
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vstrhq (float16_t * __addr, float16x8_t __value)
{
__arm_vstrhq_f16 (__addr, __value);
@@ -8670,17 +8428,6 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vornq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vornq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));})
-#define __arm_vld1q(p0) (\
- _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \
- int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce_s8_ptr(p0, int8_t *)), \
- int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce_s16_ptr(p0, int16_t *)), \
- int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce_s32_ptr(p0, int32_t *)), \
- int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce_u8_ptr(p0, uint8_t *)), \
- int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce_u16_ptr(p0, uint16_t *)), \
- int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce_u32_ptr(p0, uint32_t *)), \
- int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_f16 (__ARM_mve_coerce_f16_ptr(p0, float16_t *)), \
- int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_f32 (__ARM_mve_coerce_f32_ptr(p0, float32_t *))))
-
#define __arm_vld1q_z(p0,p1) ( \
_Generic( (int (*)[__ARM_mve_typeid(p0)])0, \
int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_z_s8 (__ARM_mve_coerce_s8_ptr(p0, int8_t *), p1), \
@@ -8792,17 +8539,6 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_float16_t_ptr][__ARM_mve_type_float16x8x2_t]: __arm_vst2q_f16 (__ARM_mve_coerce_f16_ptr(p0, float16_t *), __ARM_mve_coerce(__p1, float16x8x2_t)), \
int (*)[__ARM_mve_type_float32_t_ptr][__ARM_mve_type_float32x4x2_t]: __arm_vst2q_f32 (__ARM_mve_coerce_f32_ptr(p0, float32_t *), __ARM_mve_coerce(__p1, float32x4x2_t)));})
-#define __arm_vst1q(p0,p1) ({ __typeof(p1) __p1 = (p1); \
- _Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_int8x16_t]: __arm_vst1q_s8 (__ARM_mve_coerce_s8_ptr(p0, int8_t *), __ARM_mve_coerce(__p1, int8x16_t)), \
- int (*)[__ARM_mve_type_int16_t_ptr][__ARM_mve_type_int16x8_t]: __arm_vst1q_s16 (__ARM_mve_coerce_s16_ptr(p0, int16_t *), __ARM_mve_coerce(__p1, int16x8_t)), \
- int (*)[__ARM_mve_type_int32_t_ptr][__ARM_mve_type_int32x4_t]: __arm_vst1q_s32 (__ARM_mve_coerce_s32_ptr(p0, int32_t *), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vst1q_u8 (__ARM_mve_coerce_u8_ptr(p0, uint8_t *), __ARM_mve_coerce(__p1, uint8x16_t)), \
- int (*)[__ARM_mve_type_uint16_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vst1q_u16 (__ARM_mve_coerce_u16_ptr(p0, uint16_t *), __ARM_mve_coerce(__p1, uint16x8_t)), \
- int (*)[__ARM_mve_type_uint32_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vst1q_u32 (__ARM_mve_coerce_u32_ptr(p0, uint32_t *), __ARM_mve_coerce(__p1, uint32x4_t)), \
- int (*)[__ARM_mve_type_float16_t_ptr][__ARM_mve_type_float16x8_t]: __arm_vst1q_f16 (__ARM_mve_coerce_f16_ptr(p0, float16_t *), __ARM_mve_coerce(__p1, float16x8_t)), \
- int (*)[__ARM_mve_type_float32_t_ptr][__ARM_mve_type_float32x4_t]: __arm_vst1q_f32 (__ARM_mve_coerce_f32_ptr(p0, float32_t *), __ARM_mve_coerce(__p1, float32x4_t)));})
-
#define __arm_vstrhq(p0,p1) ({ __typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \
int (*)[__ARM_mve_type_int16_t_ptr][__ARM_mve_type_int16x8_t]: __arm_vstrhq_s16 (__ARM_mve_coerce_s16_ptr(p0, int16_t *), __ARM_mve_coerce(__p1, int16x8_t)), \
@@ -9149,15 +8885,6 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int32x4_t]: __arm_vstrwq_scatter_base_p_s32 (p0, p1, __ARM_mve_coerce(__p2, int32x4_t), p3), \
int (*)[__ARM_mve_type_uint32x4_t]: __arm_vstrwq_scatter_base_p_u32 (p0, p1, __ARM_mve_coerce(__p2, uint32x4_t), p3));})
-#define __arm_vld1q(p0) (\
- _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \
- int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce_s8_ptr(p0, int8_t *)), \
- int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce_s16_ptr(p0, int16_t *)), \
- int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce_s32_ptr(p0, int32_t *)), \
- int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce_u8_ptr(p0, uint8_t *)), \
- int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce_u16_ptr(p0, uint16_t *)), \
- int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce_u32_ptr(p0, uint32_t *))))
-
#define __arm_vldrhq_gather_offset(p0,p1) ({ __typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \
int (*)[__ARM_mve_type_int16_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrhq_gather_offset_s16 (__ARM_mve_coerce_s16_ptr(p0, int16_t *), __ARM_mve_coerce(__p1, uint16x8_t)), \
@@ -9206,15 +8933,6 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vldrwq_gather_shifted_offset_z_s32 (__ARM_mve_coerce_s32_ptr(__p0, int32_t *), p1, p2), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vldrwq_gather_shifted_offset_z_u32 (__ARM_mve_coerce_u32_ptr(__p0, uint32_t *), p1, p2));})
-#define __arm_vst1q(p0,p1) ({ __typeof(p1) __p1 = (p1); \
- _Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_int8x16_t]: __arm_vst1q_s8 (__ARM_mve_coerce_s8_ptr(p0, int8_t *), __ARM_mve_coerce(__p1, int8x16_t)), \
- int (*)[__ARM_mve_type_int16_t_ptr][__ARM_mve_type_int16x8_t]: __arm_vst1q_s16 (__ARM_mve_coerce_s16_ptr(p0, int16_t *), __ARM_mve_coerce(__p1, int16x8_t)), \
- int (*)[__ARM_mve_type_int32_t_ptr][__ARM_mve_type_int32x4_t]: __arm_vst1q_s32 (__ARM_mve_coerce_s32_ptr(p0, int32_t *), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vst1q_u8 (__ARM_mve_coerce_u8_ptr(p0, uint8_t *), __ARM_mve_coerce(__p1, uint8x16_t)), \
- int (*)[__ARM_mve_type_uint16_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vst1q_u16 (__ARM_mve_coerce_u16_ptr(p0, uint16_t *), __ARM_mve_coerce(__p1, uint16x8_t)), \
- int (*)[__ARM_mve_type_uint32_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vst1q_u32 (__ARM_mve_coerce_u32_ptr(p0, uint32_t *), __ARM_mve_coerce(__p1, uint32x4_t)));})
-
#define __arm_vst1q_p(p0,p1,p2) ({ __typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \
int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_int8x16_t]: __arm_vst1q_p_s8 (__ARM_mve_coerce_s8_ptr(p0, int8_t *), __ARM_mve_coerce(__p1, int8x16_t), p2), \
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 366cec0..b0d3443 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -3690,7 +3690,7 @@
}
[(set_attr "length" "8")])
-(define_expand "mve_vld1q_f<mode>"
+(define_expand "@mve_vld1q_f<mode>"
[(match_operand:MVE_0 0 "s_register_operand")
(unspec:MVE_0 [(match_operand:<MVE_CNVT> 1 "mve_memory_operand")] VLD1Q_F)
]
@@ -3700,7 +3700,7 @@
DONE;
})
-(define_expand "mve_vld1q_<supf><mode>"
+(define_expand "@mve_vld1q_<supf><mode>"
[(match_operand:MVE_2 0 "s_register_operand")
(unspec:MVE_2 [(match_operand:MVE_2 1 "mve_memory_operand")] VLD1Q)
]
@@ -4408,7 +4408,7 @@
}
[(set_attr "length" "4")])
-(define_expand "mve_vst1q_f<mode>"
+(define_expand "@mve_vst1q_f<mode>"
[(match_operand:<MVE_CNVT> 0 "mve_memory_operand")
(unspec:<MVE_CNVT> [(match_operand:MVE_0 1 "s_register_operand")] VST1Q_F)
]
@@ -4418,7 +4418,7 @@
DONE;
})
-(define_expand "mve_vst1q_<supf><mode>"
+(define_expand "@mve_vst1q_<supf><mode>"
[(match_operand:MVE_2 0 "mve_memory_operand")
(unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand")] VST1Q)
]
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index c3e0995..a297f4e 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -15309,6 +15309,12 @@ avr_float_lib_compare_returns_bool (machine_mode mode, enum rtx_code)
#undef TARGET_CANONICALIZE_COMPARISON
#define TARGET_CANONICALIZE_COMPARISON avr_canonicalize_comparison
+/* According to the opening comment in PR86772, the following applies:
+ "If the port does not (and never will in the future) need to mitigate
+ against unsafe speculation." */
+#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
+#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/bpf/bpf-helpers.h b/gcc/config/bpf/bpf-helpers.h
deleted file mode 100644
index 4a6825c..0000000
--- a/gcc/config/bpf/bpf-helpers.h
+++ /dev/null
@@ -1,427 +0,0 @@
-/* Copyright (C) 2019-2023 Free Software Foundation, Inc.
-
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GCC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- Under Section 7 of GPL version 3, you are granted additional
- permissions described in the GCC Runtime Library Exception, version
- 3.1, as published by the Free Software Foundation.
-
- You should have received a copy of the GNU General Public License and
- a copy of the GCC Runtime Library Exception along with this program;
- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- <http://www.gnu.org/licenses/>. */
-
-/* The purpose of this file is to provide a compatiblity layer with
- the Linux kernel bpf_helpers.h header that is located in
- linux/tools/testing/selftests/bpf/bpf_helpers.h. That file is
- currently llvm-specific. */
-
-#ifndef __BPF_HELPERS_H
-#define __BPF_HELPERS_H
-
-#define SEC(NAME) __attribute__((section(NAME), used))
-#define KERNEL_HELPER(NUM) __attribute__((kernel_helper(NUM)))
-
-/* Flags used in some kernel helpers. */
-
-#define BPF_ANY 0
-#define BPF_NOEXIST 1
-#define BPF_EXIST 2
-
-#define BPF_F_LOCK 4
-#define BPF_F_NO_COMMON_LRU (1U << 1)
-#define BPF_F_NUMA_NODE (1U << 2)
-
-/* Prototypes of functions to call kernel helpers.
- Please keep these protoypes sorted by helper number. */
-
-void *bpf_map_lookup_elem (void *map, const void *key)
- KERNEL_HELPER (1);
-
-int bpf_map_update_elem (void *map, const void *key, const void *value,
- unsigned long long flags)
- KERNEL_HELPER (2);
-
-int bpf_map_delete_elem (void *map, const void *key)
- KERNEL_HELPER (3);
-
-int bpf_probe_read (void *dst, int size, const void *unsafe_ptr)
- KERNEL_HELPER (4);
-
-unsigned long long bpf_ktime_get_ns (void)
- KERNEL_HELPER (5);
-
-int bpf_trace_printk (const char *fmt, int fmt_size, ...)
- KERNEL_HELPER (6);
-
-unsigned long long bpf_get_prandom_u32 (void)
- KERNEL_HELPER (7);
-
-unsigned long long bpf_get_smp_processor_id (void)
- KERNEL_HELPER (8);
-
-int bpf_skb_store_bytes (void *ctx, int off, void *from, int len,
- unsigned int start_header)
- KERNEL_HELPER (9);
-
-int bpf_l3_csum_replace (void *ctx, int off, int from, int to, int flags)
- KERNEL_HELPER (10);
-
-int bpf_l4_csum_replace (void *ctx, int off, int from, int to, int flags)
- KERNEL_HELPER (11);
-
-int bpf_tail_call (void *ctx, void *map, unsigned int index)
- KERNEL_HELPER (12);
-
-int bpf_clone_redirect (void *ctx, int ifindex, int flags)
- KERNEL_HELPER (13);
-
-unsigned long long bpf_get_current_pid_tgid (void)
- KERNEL_HELPER (14);
-
-unsigned long long bpf_get_current_uid_gid (void)
- KERNEL_HELPER (15);
-
-int bpf_get_current_comm (void *buf, int buf_size)
- KERNEL_HELPER (16);
-
-unsigned int bpf_get_cgroup_classid (void *ctx)
- KERNEL_HELPER (17);
-
-int bpf_skb_vlan_push (void *ctx, short vlan_proto,
- unsigned short vlan_tci)
- KERNEL_HELPER (18);
-
-int bpf_skb_vlan_pop (void *ctx)
- KERNEL_HELPER (19);
-
-int bpf_skb_get_tunnel_key (void *ctx, void *key, int size, int flags)
- KERNEL_HELPER (20);
-
-int bpf_skb_set_tunnel_key (void *ctx, void *key, int size, int flags)
- KERNEL_HELPER (21);
-
-unsigned long long bpf_perf_event_read (void *map, unsigned long long flags)
- KERNEL_HELPER (22);
-
-int bpf_redirect (int ifindex, int flags)
- KERNEL_HELPER (23);
-
-unsigned int bpf_get_route_realm (void *ctx)
- KERNEL_HELPER (24);
-
-int bpf_perf_event_output (void *ctx, void *map, unsigned long long flags,
- void *data, int size)
- KERNEL_HELPER (25);
-
-int bpf_skb_load_bytes (void *ctx, int off, void *to, int len)
- KERNEL_HELPER (26);
-
-int bpf_get_stackid (void *ctx, void *map, int flags)
- KERNEL_HELPER (27);
-
-int bpf_csum_diff (void *from, int from_size, void *to, int to_size, int seed)
- KERNEL_HELPER (28);
-
-int bpf_skb_get_tunnel_opt (void *ctx, void *md, int size)
- KERNEL_HELPER (29);
-
-int bpf_skb_set_tunnel_opt (void *ctx, void *md, int size)
- KERNEL_HELPER (30);
-
-int bpf_skb_change_proto (void *ctx, short proto, unsigned long flags)
- KERNEL_HELPER (31);
-
-int bpf_skb_change_type (void *ctx, unsigned int type)
- KERNEL_HELPER (32);
-
-int bpf_skb_under_cgroup (void *ctx, void *map, int index)
- KERNEL_HELPER (33);
-
-unsigned int bpf_get_hash_recalc (void *ctx)
- KERNEL_HELPER (34);
-
-unsigned long long bpf_get_current_task (void)
- KERNEL_HELPER (35);
-
-int bpf_probe_write_user (void *dst, const void *src, int size)
- KERNEL_HELPER (36);
-
-int bpf_current_task_under_cgroup (void *map, int index)
- KERNEL_HELPER (37);
-
-int bpf_skb_change_tail (void *ctx, unsigned int len, unsigned long flags)
- KERNEL_HELPER (38);
-
-int bpf_skb_pull_data (void *, int len)
- KERNEL_HELPER (39);
-
-long long bpf_csum_update (void *ctx, unsigned int csum)
- KERNEL_HELPER (40);
-
-void bpf_set_hash_invalid (void *ctx)
- KERNEL_HELPER (41);
-
-int bpf_get_numa_node_id (void)
- KERNEL_HELPER (42);
-
-int bpf_skb_change_head (void *, int len, int flags)
- KERNEL_HELPER (43);
-
-int bpf_xdp_adjust_head (void *ctx, int offset)
- KERNEL_HELPER (44);
-
-int bpf_probe_read_str (void *ctx, unsigned int size, const void *unsafe_ptr)
- KERNEL_HELPER (45);
-
-int bpf_get_socket_cookie (void *ctx)
- KERNEL_HELPER (46);
-
-unsigned int bpf_get_socket_uid (void *ctx)
- KERNEL_HELPER (47);
-
-unsigned int bpf_set_hash (void *ctx, unsigned int hash)
- KERNEL_HELPER (48);
-
-int bpf_setsockopt (void *ctx, int level, int optname, void *optval, int optlen)
- KERNEL_HELPER (49);
-
-int bpf_skb_adjust_room (void *ctx, int len_diff, unsigned int mode,
- unsigned long long flags)
- KERNEL_HELPER (50);
-
-int bpf_redirect_map (void *map, int key, int flags)
- KERNEL_HELPER (51);
-
-int bpf_sk_redirect_map (void *ctx, void *map, int key, int flags)
- KERNEL_HELPER (52);
-
-int bpf_sock_map_update (void *map, void *key, void *value,
- unsigned long long flags)
- KERNEL_HELPER (53);
-
-int bpf_xdp_adjust_meta (void *ctx, int offset)
- KERNEL_HELPER (54);
-
-int bpf_perf_event_read_value (void *map, unsigned long long flags,
- void *buf, unsigned int buf_size)
- KERNEL_HELPER (55);
-
-int bpf_perf_prog_read_value (void *ctx, void *buf, unsigned int buf_size)
- KERNEL_HELPER (56);
-
-int bpf_getsockopt (void *ctx, int level, int optname, void *optval,
- int optlen)
- KERNEL_HELPER (57);
-
-int bpf_override_return (void *ctx, unsigned long rc)
- KERNEL_HELPER (58);
-
-int bpf_sock_ops_cb_flags_set (void *ctx, int flags)
- KERNEL_HELPER (59);
-
-int bpf_msg_redirect_map (void *ctx, void *map, int key, int flags)
- KERNEL_HELPER (60);
-
-int bpf_msg_apply_bytes (void *ctx, int len)
- KERNEL_HELPER (61);
-
-int bpf_msg_cork_bytes (void *ctx, int len)
- KERNEL_HELPER (62);
-
-int bpf_msg_pull_data (void *, int len)
- KERNEL_HELPER (63);
-
-int bpf_bind (void *ctx, void *addr, int addr_len)
- KERNEL_HELPER (64);
-
-int bpf_xdp_adjust_tail (struct xdp_md *xdp_md, int delta)
- KERNEL_HELPER (65);
-
-int bpf_skb_get_xfrm_state (void *ctx, int index, void *state,
- int size, int flags)
- KERNEL_HELPER (66);
-
-int bpf_get_stack (void *ctx, void *buf, int size, int flags)
- KERNEL_HELPER (67);
-
-int bpf_skb_load_bytes_relative (void *ctx, int off, void *to, int len,
- unsigned int start_header)
- KERNEL_HELPER (68);
-
-int bpf_fib_lookup (void *ctx, struct bpf_fib_lookup *params,
- int plen, unsigned int flags)
- KERNEL_HELPER (69);
-
-int bpf_sock_hash_update (void *map, void *key, void *value,
- unsigned long long flags)
- KERNEL_HELPER (70);
-
-int bpf_msg_redirect_hash (void *ctx, void *map, void *key, int flags)
- KERNEL_HELPER (71);
-
-int bpf_sk_redirect_hash (void *ctx, void *map, void *key, int flags)
- KERNEL_HELPER (72);
-
-int bpf_lwt_push_encap (void *ctx, unsigned int type, void *hdr,
- unsigned int len)
- KERNEL_HELPER (73);
-
-int bpf_lwt_seg6_store_bytes (void *ctx, unsigned int offset,
- void *from, unsigned int len)
- KERNEL_HELPER (74);
-
-int bpf_lwt_seg6_adjust_srh (void *ctx, unsigned int offset,
- unsigned int len)
- KERNEL_HELPER (75);
-
-int bpf_lwt_seg6_action (void *ctx, unsigned int action, void *param,
- unsigned int param_len)
- KERNEL_HELPER (76);
-
-int bpf_rc_repeat (void *ctx)
- KERNEL_HELPER (77);
-
-int bpf_rc_keydown (void *ctx, unsigned int protocol,
- unsigned long long scancode, unsigned int toggle)
- KERNEL_HELPER (78);
-
-unsigned bpf_skb_cgroup_id (void *ctx)
- KERNEL_HELPER (79);
-
-unsigned long long bpf_get_current_cgroup_id (void)
- KERNEL_HELPER (80);
-
-void *bpf_get_local_storage (void *map, unsigned long long flags)
- KERNEL_HELPER (81);
-
-int bpf_sk_select_reuseport (void *ctx, void *map, void *key, unsigned int flags)
- KERNEL_HELPER (82);
-
-unsigned long long bpf_skb_ancestor_cgroup_id (void *ctx, int level)
- KERNEL_HELPER (83);
-
-struct bpf_sock *bpf_sk_lookup_tcp (void *ctx, struct bpf_sock_tuple *tuple,
- int size, unsigned long long netns_id,
- unsigned long long flags)
- KERNEL_HELPER (84);
-
-struct bpf_sock *bpf_sk_lookup_udp (void *ctx, struct bpf_sock_tuple *tuple,
- int size, unsigned long long netns_id,
- unsigned long long flags)
- KERNEL_HELPER (85);
-
-int bpf_sk_release (struct bpf_sock *sk)
- KERNEL_HELPER (86);
-
-int bpf_map_push_elem (void *map, const void *value, unsigned long long flags)
- KERNEL_HELPER (87);
-
-int bpf_map_pop_elem (void *map, void *value)
- KERNEL_HELPER (88);
-
-int bpf_map_peek_elem (void *map, void *value)
- KERNEL_HELPER (89);
-
-int bpf_msg_push_data (void *ctx, int start, int cut, int flags)
- KERNEL_HELPER (90);
-
-int bpf_msg_pop_data (void *ctx, int start, int cut, int flags)
- KERNEL_HELPER (91);
-
-int bpf_rc_pointer_rel (void *ctx, int rel_x, int rel_y)
- KERNEL_HELPER (92);
-
-void bpf_spin_lock (struct bpf_spin_lock *lock)
- KERNEL_HELPER (93);
-
-void bpf_spin_unlock (struct bpf_spin_lock *lock)
- KERNEL_HELPER (94);
-
-struct bpf_sock *bpf_sk_fullsock (struct bpf_sock *sk)
- KERNEL_HELPER (95);
-
-struct bpf_sock *bpf_tcp_sock (struct bpf_sock *sk)
- KERNEL_HELPER (96);
-
-int bpf_skb_ecn_set_ce (void *ctx)
- KERNEL_HELPER (97);
-
-struct bpf_sock *bpf_get_listener_sock (struct bpf_sock *sk)
- KERNEL_HELPER (98);
-
-struct bpf_sock *bpf_skc_lookup_tcp (void *ctx,
- struct bpf_sock_tuple *tuple,
- unsigned int tuple_size,
- unsigned long netns,
- unsigned long flags)
- KERNEL_HELPER (99);
-
-int bpf_tcp_check_syncookie (struct bpf_sock *sk, void *iph,
- unsigned int iph_len,
- struct tcp_hdr *th,
- unsigned int th_len)
- KERNEL_HELPER (100);
-
-int bpf_sysctl_get_name (struct bpf_sysctl *ctx,
- char *buf, unsigned long buf_len,
- unsigned long flags)
- KERNEL_HELPER (101);
-
-int bpf_sysctl_get_current_value (struct bpf_sysctl *ctx,
- char *buf, unsigned long buf_len)
- KERNEL_HELPER (102);
-
-int bpf_sysctl_get_new_value (struct bpf_sysctl *ctx, char *buf,
- unsigned long buf_len)
- KERNEL_HELPER (103);
-
-int bpf_sysctl_set_new_value (struct bpf_sysctl *ctx, const char *buf,
- unsigned long buf_len)
- KERNEL_HELPER (104);
-
-int bpf_strtol (const char *buf, unsigned long buf_len,
- unsigned long flags, long *res)
- KERNEL_HELPER (105);
-
-int bpf_strtoul (const char *buf, unsigned long buf_len,
- unsigned long flags, unsigned long *res)
- KERNEL_HELPER (106);
-
-void *bpf_sk_storage_get (void *map, struct bpf_sock *sk,
- void *value, long flags)
- KERNEL_HELPER (107);
-
-int bpf_sk_storage_delete (void *map, struct bpf_sock *sk)
- KERNEL_HELPER (108);
-
-/* Functions to emit BPF_LD_ABS and BPF_LD_IND instructions. We
- provide the "standard" names as synonyms of the corresponding GCC
- builtins. Note how the SKB argument is ignored. */
-
-#define load_byte(SKB,OFF) __builtin_bpf_load_byte ((OFF))
-#define load_half(SKB,OFF) __builtin_bpf_load_half ((OFF))
-#define load_word(SKB,OFF) __builtin_bpf_load_word ((OFF))
-
-struct bpf_map_def
-{
- unsigned int type;
- unsigned int key_size;
- unsigned int value_size;
- unsigned int max_entries;
- unsigned int map_flags;
- unsigned int inner_map_idx;
- unsigned int numa_node;
-};
-
-#endif /* ! __BPF_HELPERS_H */
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index a0956a0..223a43c 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -70,6 +70,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify-me.h"
#include "core-builtins.h"
+#include "opts.h"
/* Per-function machine data. */
struct GTY(()) machine_function
@@ -250,9 +251,10 @@ bpf_option_override (void)
/* Disable -fstack-protector as it is not supported in BPF. */
if (flag_stack_protect)
{
- inform (input_location,
- "%<-fstack-protector%> does not work "
- "on this architecture");
+ if (!flag_stack_protector_set_by_fhardened_p)
+ inform (input_location,
+ "%<-fstack-protector%> does not work "
+ "on this architecture");
flag_stack_protect = 0;
}
diff --git a/gcc/config/c6x/c6x.md b/gcc/config/c6x/c6x.md
index 88b9291..906fdb3 100644
--- a/gcc/config/c6x/c6x.md
+++ b/gcc/config/c6x/c6x.md
@@ -1440,7 +1440,7 @@
(define_insn "mvilc"
[(set (reg:SI REG_ILC)
- (unspec [(match_operand:SI 0 "register_operand" "a,b")] UNSPEC_MVILC))]
+ (unspec:SI [(match_operand:SI 0 "register_operand" "a,b")] UNSPEC_MVILC))]
"TARGET_INSNS_64PLUS"
"%|%.\\tmvc\\t%$\\t%0, ILC"
[(set_attr "predicable" "no")
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index 23f2bbe..a928dec 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -566,10 +566,10 @@
(match_operand:V_4REG 1 "general_operand"))]
""
{@ [cons: =0, 1; attrs: type, length, gcn_version]
- [v,vDB;vmult,16,* ] v_mov_b32\t%L0, %L1\; v_mov_b32\t%H0, %H1\; v_mov_b32\t%J0, %J1\; v_mov_b32\t%K0, %K1
- [v,a ;vmult,32,* ] v_accvgpr_read_b32\t%L0, %L1\; v_accvgpr_read_b32\t%H0, %H1\; v_accvgpr_read_b32\t%J0, %J1\; v_accvgpr_read_b32\t%K0, %K1
- [a,v ;vmult,32,* ] v_accvgpr_write_b32\t%L0, %L1\;v_accvgpr_write_b32\t%H0, %H1\;v_accvgpr_write_b32\t%J0, %J1\;v_accvgpr_write_b32\t%K0, %K1
- [a,a ;vmult,32,cdna2] v_accvgpr_mov_b32\t%L0, %L1\; v_accvgpr_mov_b32\t%H0, %H1\; v_accvgpr_mov_b32\t%J0, %J1\; v_accvgpr_mov_b32\t%K0, %K1
+ [v ,vDB;vmult,16,* ] v_mov_b32\t%L0, %L1\; v_mov_b32\t%H0, %H1\; v_mov_b32\t%J0, %J1\; v_mov_b32\t%K0, %K1
+ [v ,a ;vmult,32,* ] v_accvgpr_read_b32\t%L0, %L1\; v_accvgpr_read_b32\t%H0, %H1\; v_accvgpr_read_b32\t%J0, %J1\; v_accvgpr_read_b32\t%K0, %K1
+ [$a,v ;vmult,32,* ] v_accvgpr_write_b32\t%L0, %L1\;v_accvgpr_write_b32\t%H0, %H1\;v_accvgpr_write_b32\t%J0, %J1\;v_accvgpr_write_b32\t%K0, %K1
+ [a ,a ;vmult,32,cdna2] v_accvgpr_mov_b32\t%L0, %L1\; v_accvgpr_mov_b32\t%H0, %H1\; v_accvgpr_mov_b32\t%J0, %J1\; v_accvgpr_mov_b32\t%K0, %K1
})
(define_insn "mov<mode>_exec"
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index 52c8a0e..22d2b6e 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -5050,7 +5050,9 @@ gcn_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
rtx dst, rtx src0, rtx src1,
const vec_perm_indices & sel)
{
- if (vmode != op_mode)
+ if (vmode != op_mode
+ || !VECTOR_MODE_P (vmode)
+ || GET_MODE_INNER (vmode) == TImode)
return false;
unsigned int nelt = GET_MODE_NUNITS (vmode);
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 75ef271..d1fc93e 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -150,6 +150,7 @@
#define bit_AVXVNNIINT16 (1 << 10)
#define bit_PREFETCHI (1 << 14)
#define bit_USER_MSR (1 << 15)
+#define bit_AVX10 (1 << 19)
#define bit_APX_F (1 << 21)
/* Extended State Enumeration Sub-leaf (%eax == 0xd, %ecx == 1) */
@@ -166,6 +167,10 @@
#define bit_AESKLE ( 1<<0 )
#define bit_WIDEKL ( 1<<2 )
+/* AVX10 sub leaf (%eax == 0x24) */
+/* %ebx */
+#define bit_AVX10_256 (1 << 17)
+#define bit_AVX10_512 (1 << 18)
/* Signatures for different CPU implementations as returned in uses
of cpuid with level 0. */
diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc
index 55d4045..204600e 100644
--- a/gcc/config/i386/driver-i386.cc
+++ b/gcc/config/i386/driver-i386.cc
@@ -369,6 +369,37 @@ detect_caches_intel (bool xeon_mp, unsigned max_level,
return describe_cache (level1, level2);
}
+/* Extended features */
+#define has_feature(f) \
+ has_cpu_feature (&cpu_model, cpu_features2, f)
+
+/* We will emit a warning when using AVX10.1 and AVX512 options with one
+ enabled and the other disabled. Add this function to avoid push "-mno-"
+ options under this scenario for -march=native. */
+
+bool check_avx512_features (__processor_model &cpu_model,
+ unsigned int (&cpu_features2)[SIZE_OF_CPU_FEATURES],
+ const enum processor_features feature)
+{
+ if (has_feature (FEATURE_AVX10_1_256)
+ && ((feature == FEATURE_AVX512F)
+ || (feature == FEATURE_AVX512CD)
+ || (feature == FEATURE_AVX512DQ)
+ || (feature == FEATURE_AVX512BW)
+ || (feature == FEATURE_AVX512VL)
+ || (feature == FEATURE_AVX512IFMA)
+ || (feature == FEATURE_AVX512VBMI)
+ || (feature == FEATURE_AVX512VBMI2)
+ || (feature == FEATURE_AVX512VNNI)
+ || (feature == FEATURE_AVX512VPOPCNTDQ)
+ || (feature == FEATURE_AVX512BITALG)
+ || (feature == FEATURE_AVX512FP16)
+ || (feature == FEATURE_AVX512BF16)))
+ return false;
+
+ return true;
+}
+
/* This will be called by the spec parser in gcc.cc when it sees
a %:local_cpu_detect(args) construct. Currently it will be
called with either "arch [32|64]" or "tune [32|64]" as argument
@@ -447,10 +478,6 @@ const char *host_detect_local_cpu (int argc, const char **argv)
}
}
- /* Extended features */
-#define has_feature(f) \
- has_cpu_feature (&cpu_model, cpu_features2, f)
-
if (vendor == VENDOR_AMD)
{
unsigned int name;
@@ -868,7 +895,12 @@ const char *host_detect_local_cpu (int argc, const char **argv)
options = concat (options, " ",
isa_names_table[i].option, NULL);
}
- else
+ /* Never push -mno-avx10.1-{256,512} under -march=native to
+ avoid unnecessary warnings when building librarys. */
+ else if ((isa_names_table[i].feature != FEATURE_AVX10_1_256)
+ && (isa_names_table[i].feature != FEATURE_AVX10_1_512)
+ && check_avx512_features (cpu_model, cpu_features2,
+ isa_names_table[i].feature))
options = concat (options, neg_option,
isa_names_table[i].option + 2, NULL);
}
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index 19fa5c1..7a5f267 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -301,10 +301,10 @@ BDESC (OPTION_MASK_ISA_AVX512BW, OPTION_MASK_ISA2_EVEX512, CODE_FOR_avx512bw_sto
/* AVX512VP2INTERSECT */
BDESC (0, OPTION_MASK_ISA2_AVX512VP2INTERSECT | OPTION_MASK_ISA2_EVEX512, CODE_FOR_nothing, "__builtin_ia32_2intersectd512", IX86_BUILTIN_2INTERSECTD512, UNKNOWN, (int) VOID_FTYPE_PUHI_PUHI_V16SI_V16SI)
BDESC (0, OPTION_MASK_ISA2_AVX512VP2INTERSECT | OPTION_MASK_ISA2_EVEX512, CODE_FOR_nothing, "__builtin_ia32_2intersectq512", IX86_BUILTIN_2INTERSECTQ512, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V8DI_V8DI)
-BDESC (0, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectd256", IX86_BUILTIN_2INTERSECTD256, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V8SI_V8SI)
-BDESC (0, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectq256", IX86_BUILTIN_2INTERSECTQ256, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V4DI_V4DI)
-BDESC (0, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectd128", IX86_BUILTIN_2INTERSECTD128, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V4SI_V4SI)
-BDESC (0, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectq128", IX86_BUILTIN_2INTERSECTQ128, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V2DI_V2DI)
+BDESC (OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectd256", IX86_BUILTIN_2INTERSECTD256, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V8SI_V8SI)
+BDESC (OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectq256", IX86_BUILTIN_2INTERSECTQ256, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V4DI_V4DI)
+BDESC (OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectd128", IX86_BUILTIN_2INTERSECTD128, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V4SI_V4SI)
+BDESC (OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVX512VP2INTERSECT, CODE_FOR_nothing, "__builtin_ia32_2intersectq128", IX86_BUILTIN_2INTERSECTQ128, UNKNOWN, (int) VOID_FTYPE_PUQI_PUQI_V2DI_V2DI)
/* AVX512VL */
BDESC (OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_avx512vl_loadv16hi_mask, "__builtin_ia32_loaddquhi256_mask", IX86_BUILTIN_LOADDQUHI256_MASK, UNKNOWN, (int) V16HI_FTYPE_PCSHORT_V16HI_UHI)
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index a8d871d..4bd7d4f 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -2453,7 +2453,8 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
/* Generate XOR since we can't check that one operand is zero
vector. */
tmp = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (tmp, gen_rtx_XOR (mode, op0, op1)));
+ rtx ops[3] = { tmp, op0, op1 };
+ ix86_expand_vector_logical_operator (XOR, mode, ops);
tmp = gen_lowpart (p_mode, tmp);
emit_insn (gen_rtx_SET (gen_rtx_REG (CCZmode, FLAGS_REG),
gen_rtx_UNSPEC (CCZmode,
@@ -17748,6 +17749,7 @@ emit_reduc_half (rtx dest, rtx src, int i)
tem = gen_mmx_lshrv1si3 (d, gen_lowpart (V1SImode, src),
GEN_INT (i / 2));
break;
+ case E_V8QImode:
case E_V4HImode:
d = gen_reg_rtx (V1DImode);
tem = gen_mmx_lshrv1di3 (d, gen_lowpart (V1DImode, src),
diff --git a/gcc/config/i386/i386-expand.h b/gcc/config/i386/i386-expand.h
index 1ea789c..997cb7d 100644
--- a/gcc/config/i386/i386-expand.h
+++ b/gcc/config/i386/i386-expand.h
@@ -44,9 +44,9 @@ void ix86_emit_binop (enum rtx_code code, machine_mode mode, rtx dst, rtx src);
enum calling_abi ix86_function_abi (const_tree fndecl);
bool ix86_function_ms_hook_prologue (const_tree fn);
void warn_once_call_ms2sysv_xlogues (const char *feature);
-rtx gen_push (rtx arg);
+rtx gen_push (rtx arg, bool = false);
rtx gen_pushfl (void);
-rtx gen_pop (rtx arg);
+rtx gen_pop (rtx arg, bool = false);
rtx gen_popfl (void);
rtx ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
machine_mode mode, int ignore);
diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def
index 991df5e..f730aa2 100644
--- a/gcc/config/i386/i386-isa.def
+++ b/gcc/config/i386/i386-isa.def
@@ -123,3 +123,6 @@ DEF_PTA(SHA512)
DEF_PTA(SM4)
DEF_PTA(APX_F)
DEF_PTA(USER_MSR)
+DEF_PTA(EVEX512)
+DEF_PTA(AVX10_1_256)
+DEF_PTA(AVX10_1_512)
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index df7d243..fb8638a 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -258,7 +258,9 @@ static struct ix86_target_opts isa2_opts[] =
{ "-msha512", OPTION_MASK_ISA2_SHA512 },
{ "-msm4", OPTION_MASK_ISA2_SM4 },
{ "-mevex512", OPTION_MASK_ISA2_EVEX512 },
- { "-musermsr", OPTION_MASK_ISA2_USER_MSR }
+ { "-musermsr", OPTION_MASK_ISA2_USER_MSR },
+ { "-mavx10.1-256", OPTION_MASK_ISA2_AVX10_1_256 },
+ { "-mavx10.1-512", OPTION_MASK_ISA2_AVX10_1_512 }
};
static struct ix86_target_opts isa_opts[] =
{
@@ -705,6 +707,8 @@ ix86_function_specific_save (struct cl_target_option *ptr,
ptr->x_ix86_apx_features = opts->x_ix86_apx_features;
ptr->x_ix86_isa_flags_explicit = opts->x_ix86_isa_flags_explicit;
ptr->x_ix86_isa_flags2_explicit = opts->x_ix86_isa_flags2_explicit;
+ ptr->x_ix86_no_avx512_explicit = opts->x_ix86_no_avx512_explicit;
+ ptr->x_ix86_no_avx10_1_explicit = opts->x_ix86_no_avx10_1_explicit;
ptr->x_recip_mask_explicit = opts->x_recip_mask_explicit;
ptr->x_ix86_arch_string = opts->x_ix86_arch_string;
ptr->x_ix86_tune_string = opts->x_ix86_tune_string;
@@ -847,6 +851,8 @@ ix86_function_specific_restore (struct gcc_options *opts,
opts->x_ix86_apx_features = ptr->x_ix86_apx_features;
opts->x_ix86_isa_flags_explicit = ptr->x_ix86_isa_flags_explicit;
opts->x_ix86_isa_flags2_explicit = ptr->x_ix86_isa_flags2_explicit;
+ opts->x_ix86_no_avx512_explicit = ptr->x_ix86_no_avx512_explicit;
+ opts->x_ix86_no_avx10_1_explicit = ptr->x_ix86_no_avx10_1_explicit;
opts->x_recip_mask_explicit = ptr->x_recip_mask_explicit;
opts->x_ix86_arch_string = ptr->x_ix86_arch_string;
opts->x_ix86_tune_string = ptr->x_ix86_tune_string;
@@ -1125,6 +1131,9 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
IX86_ATTR_ISA ("apxf", OPT_mapxf),
IX86_ATTR_ISA ("evex512", OPT_mevex512),
IX86_ATTR_ISA ("usermsr", OPT_musermsr),
+ IX86_ATTR_ISA ("avx10.1", OPT_mavx10_1_256),
+ IX86_ATTR_ISA ("avx10.1-256", OPT_mavx10_1_256),
+ IX86_ATTR_ISA ("avx10.1-512", OPT_mavx10_1_512),
/* enum options */
IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
@@ -1411,6 +1420,17 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args,
target_clone_attr))
return error_mark_node;
+ /* AVX10.1-256 will enable only 256 bit AVX512F features by setting all
+ AVX512 related ISA flags and not setting EVEX512. When it is used
+ with avx512 related function attribute, we need to enable 512 bit to
+ align with the command line behavior. Manually set EVEX512 for this
+ scenario. */
+ if ((def->x_ix86_isa_flags2 & OPTION_MASK_ISA2_AVX10_1_256)
+ && (opts->x_ix86_isa_flags & OPTION_MASK_ISA_AVX512F)
+ && !(def->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_EVEX512)
+ && !(opts->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_EVEX512))
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_EVEX512;
+
/* If the changed options are different from the default, rerun
ix86_option_override_internal, and then save the options away.
The string options are attribute options, and will be undone
@@ -1421,7 +1441,10 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args,
|| option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
|| option_strings[IX86_FUNCTION_SPECIFIC_TUNE]
|| enum_opts_set.x_ix86_fpmath
- || enum_opts_set.x_prefer_vector_width_type)
+ || enum_opts_set.x_prefer_vector_width_type
+ || (!(def->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_AVX10_1_256)
+ && (opts->x_ix86_isa_flags2_explicit
+ & OPTION_MASK_ISA2_AVX10_1_256)))
{
/* If we are using the default tune= or arch=, undo the string assigned,
and use the default. */
@@ -1963,7 +1986,7 @@ ix86_option_override_internal (bool main_args_p,
struct gcc_options *opts_set)
{
unsigned int i;
- unsigned HOST_WIDE_INT ix86_arch_mask;
+ unsigned HOST_WIDE_INT ix86_arch_mask, avx512_isa_flags, avx512_isa_flags2;
const bool ix86_tune_specified = (opts->x_ix86_tune_string != NULL);
/* -mrecip options. */
@@ -1982,6 +2005,14 @@ ix86_option_override_internal (bool main_args_p,
{ "vec-sqrt", RECIP_MASK_VEC_SQRT },
};
+ avx512_isa_flags = OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX512CD
+ | OPTION_MASK_ISA_AVX512DQ | OPTION_MASK_ISA_AVX512BW
+ | OPTION_MASK_ISA_AVX512VL | OPTION_MASK_ISA_AVX512IFMA
+ | OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VBMI2
+ | OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VPOPCNTDQ
+ | OPTION_MASK_ISA_AVX512BITALG;
+ avx512_isa_flags2 = OPTION_MASK_ISA2_AVX512FP16
+ | OPTION_MASK_ISA2_AVX512BF16;
/* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
TARGET_64BIT_DEFAULT is true and TARGET_64BIT is false. */
@@ -2590,12 +2621,101 @@ ix86_option_override_internal (bool main_args_p,
&= ~((OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_BMI2 | OPTION_MASK_ISA_TBM)
& ~opts->x_ix86_isa_flags_explicit);
- /* Set EVEX512 target if it is not explicitly set
- when AVX512 is enabled. */
- if (TARGET_AVX512F_P(opts->x_ix86_isa_flags)
- && !(opts->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_EVEX512))
+ /* Emit a warning if AVX10.1 options is used with AVX512/EVEX512 options except
+ for the following option combinations:
+ 1. Both AVX10.1-512 and AVX512 with 512 bit vector width are enabled with no
+ explicit disable on other AVX512 features.
+ 2. Both AVX10.1-256 and AVX512 w/o 512 bit vector width are enabled with no
+ explicit disable on other AVX512 features.
+ 3. Both AVX10.1 and AVX512 are disabled. */
+ if (TARGET_AVX10_1_512_P (opts->x_ix86_isa_flags2))
+ {
+ if (opts->x_ix86_no_avx512_explicit
+ && (((~(avx512_isa_flags & opts->x_ix86_isa_flags)
+ & (avx512_isa_flags & opts->x_ix86_isa_flags_explicit)))
+ || ((~((avx512_isa_flags2 | OPTION_MASK_ISA2_EVEX512)
+ & opts->x_ix86_isa_flags2)
+ & ((avx512_isa_flags2 | OPTION_MASK_ISA2_EVEX512)
+ & opts->x_ix86_isa_flags2_explicit)))))
+ warning (0, "%<-mno-evex512%> or %<-mno-avx512XXX%> cannot disable "
+ "AVX10 instructions when AVX10.1-512 is available");
+ }
+ else if (TARGET_AVX10_1_256_P (opts->x_ix86_isa_flags2))
+ {
+ if (TARGET_EVEX512_P (opts->x_ix86_isa_flags2)
+ && (OPTION_MASK_ISA2_EVEX512 & opts->x_ix86_isa_flags2_explicit))
+ {
+ if (!TARGET_AVX512F_P (opts->x_ix86_isa_flags)
+ || !(OPTION_MASK_ISA_AVX512F & opts->x_ix86_isa_flags_explicit))
+ {
+ /* We should not emit 512 bit instructions under AVX10.1-256
+ when EVEX512 is enabled w/o any AVX512 features enabled.
+ Disable EVEX512 bit for this. */
+ warning (0, "Using %<-mevex512%> without any AVX512 features "
+ "enabled together with AVX10.1 only will not enable "
+ "any AVX512 or AVX10.1-512 features, using 256 as "
+ "max vector size");
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_EVEX512;
+ }
+ else
+ warning (0, "Vector size conflicts between AVX10.1 and AVX512, "
+ "using 512 as max vector size");
+ }
+ else if (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
+ && !(OPTION_MASK_ISA2_EVEX512
+ & opts->x_ix86_isa_flags2_explicit))
+ warning (0, "Vector size conflicts between AVX10.1 and AVX512, using "
+ "512 as max vector size");
+ else if (opts->x_ix86_no_avx512_explicit
+ && (((~(avx512_isa_flags & opts->x_ix86_isa_flags)
+ & (avx512_isa_flags & opts->x_ix86_isa_flags_explicit)))
+ || ((~(avx512_isa_flags2 & opts->x_ix86_isa_flags2)
+ & (avx512_isa_flags2
+ & opts->x_ix86_isa_flags2_explicit)))))
+ warning (0, "%<-mno-avx512XXX%> cannot disable AVX10 instructions "
+ "when AVX10 is available");
+ }
+ else if (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
+ && (OPTION_MASK_ISA_AVX512F & opts->x_ix86_isa_flags_explicit))
+ {
+ if (opts->x_ix86_no_avx10_1_explicit
+ && ((OPTION_MASK_ISA2_AVX10_1_256 | OPTION_MASK_ISA2_AVX10_1_512)
+ & opts->x_ix86_isa_flags2_explicit))
+ {
+ warning (0, "%<-mno-avx10.1, -mno-avx10.1-256, -mno-avx10.1-512%> "
+ "cannot disable AVX512 instructions when "
+ "%<-mavx512XXX%>");
+ /* Reset those unset AVX512 flags set by AVX10 options when AVX10 is
+ disabled. */
+ if (OPTION_MASK_ISA2_AVX10_1_256 & opts->x_ix86_isa_flags2_explicit)
+ {
+ opts->x_ix86_isa_flags = (~avx512_isa_flags
+ & opts->x_ix86_isa_flags)
+ | (avx512_isa_flags & opts->x_ix86_isa_flags
+ & opts->x_ix86_isa_flags_explicit);
+ opts->x_ix86_isa_flags2 = (~avx512_isa_flags2
+ & opts->x_ix86_isa_flags2)
+ | (avx512_isa_flags2 & opts->x_ix86_isa_flags2
+ & opts->x_ix86_isa_flags2_explicit);
+ }
+ }
+ }
+
+ /* Set EVEX512 if one of the following conditions meets:
+ 1. AVX512 is enabled while EVEX512 is not explicitly set/unset.
+ 2. AVX10.1-512 is enabled. */
+ if (TARGET_AVX10_1_512_P (opts->x_ix86_isa_flags2)
+ || (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
+ && !(opts->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_EVEX512)))
opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_EVEX512;
+ /* Enable all AVX512 related ISAs when AVX10.1 is enabled. */
+ if (TARGET_AVX10_1_256_P (opts->x_ix86_isa_flags2))
+ {
+ opts->x_ix86_isa_flags |= avx512_isa_flags;
+ opts->x_ix86_isa_flags2 |= avx512_isa_flags2;
+ }
+
/* Disable AVX512{PF,ER,4VNNIW,4FAMPS} for -mno-evex512. */
if (!TARGET_EVEX512_P(opts->x_ix86_isa_flags2))
{
@@ -3072,10 +3192,25 @@ ix86_option_override_internal (bool main_args_p,
= build_target_option_node (opts, opts_set);
}
+ const bool cf_okay_p = (TARGET_64BIT || TARGET_CMOV);
+ /* When -fhardened, enable -fcf-protection=full, but only when it's
+ compatible with this target, and when it wasn't already specified
+ on the command line. */
+ if (opts->x_flag_hardened && cf_okay_p)
+ {
+ if (opts->x_flag_cf_protection == CF_NONE)
+ opts->x_flag_cf_protection = CF_FULL;
+ else if (opts->x_flag_cf_protection != CF_FULL)
+ warning_at (UNKNOWN_LOCATION, OPT_Whardened,
+ "%<-fcf-protection=full%> is not enabled by "
+ "%<-fhardened%> because it was specified on the command "
+ "line");
+ }
+
if (opts->x_flag_cf_protection != CF_NONE)
{
if ((opts->x_flag_cf_protection & CF_BRANCH) == CF_BRANCH
- && !TARGET_64BIT && !TARGET_CMOV)
+ && !cf_okay_p)
error ("%<-fcf-protection%> is not compatible with this target");
opts->x_flag_cf_protection
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
index 2ec76a1..4d293ed 100644
--- a/gcc/config/i386/i386-opts.h
+++ b/gcc/config/i386/i386-opts.h
@@ -139,7 +139,8 @@ enum apx_features {
apx_egpr = 1 << 0,
apx_push2pop2 = 1 << 1,
apx_ndd = 1 << 2,
- apx_all = apx_egpr | apx_push2pop2 | apx_ndd,
+ apx_ppx = 1 << 3,
+ apx_all = apx_egpr | apx_push2pop2 | apx_ndd | apx_ppx,
};
#endif
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 683ac64..9390f52 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -105,7 +105,7 @@ along with GCC; see the file COPYING3. If not see
static rtx legitimize_dllimport_symbol (rtx, bool);
static rtx legitimize_pe_coff_extern_decl (rtx, bool);
static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
-static void ix86_emit_restore_reg_using_pop (rtx);
+static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
#ifndef CHECK_STACK_LIMIT
@@ -6448,7 +6448,7 @@ output_set_got (rtx dest, rtx label)
/* Generate an "push" pattern for input ARG. */
rtx
-gen_push (rtx arg)
+gen_push (rtx arg, bool ppx_p)
{
struct machine_function *m = cfun->machine;
@@ -6459,10 +6459,10 @@ gen_push (rtx arg)
if (REG_P (arg) && GET_MODE (arg) != word_mode)
arg = gen_rtx_REG (word_mode, REGNO (arg));
- return gen_rtx_SET (gen_rtx_MEM (word_mode,
- gen_rtx_PRE_DEC (Pmode,
- stack_pointer_rtx)),
- arg);
+ rtx stack = gen_rtx_MEM (word_mode,
+ gen_rtx_PRE_DEC (Pmode,
+ stack_pointer_rtx));
+ return ppx_p ? gen_pushp_di (stack, arg) : gen_rtx_SET (stack, arg);
}
rtx
@@ -6486,15 +6486,16 @@ gen_pushfl (void)
/* Generate an "pop" pattern for input ARG. */
rtx
-gen_pop (rtx arg)
+gen_pop (rtx arg, bool ppx_p)
{
if (REG_P (arg) && GET_MODE (arg) != word_mode)
arg = gen_rtx_REG (word_mode, REGNO (arg));
- return gen_rtx_SET (arg,
- gen_rtx_MEM (word_mode,
- gen_rtx_POST_INC (Pmode,
- stack_pointer_rtx)));
+ rtx stack = gen_rtx_MEM (word_mode,
+ gen_rtx_POST_INC (Pmode,
+ stack_pointer_rtx));
+
+ return ppx_p ? gen_popp_di (arg, stack) : gen_rtx_SET (arg, stack);
}
rtx
@@ -6512,7 +6513,7 @@ gen_popfl (void)
/* Generate a "push2" pattern for input ARG. */
rtx
-gen_push2 (rtx mem, rtx reg1, rtx reg2)
+gen_push2 (rtx mem, rtx reg1, rtx reg2, bool ppx_p = false)
{
struct machine_function *m = cfun->machine;
const int offset = UNITS_PER_WORD * 2;
@@ -6527,7 +6528,8 @@ gen_push2 (rtx mem, rtx reg1, rtx reg2)
if (REG_P (reg2) && GET_MODE (reg2) != word_mode)
reg2 = gen_rtx_REG (word_mode, REGNO (reg2));
- return gen_push2_di (mem, reg1, reg2);
+ return ppx_p ? gen_push2p_di (mem, reg1, reg2):
+ gen_push2_di (mem, reg1, reg2);
}
/* Return >= 0 if there is an unused call-clobbered register available
@@ -7369,7 +7371,8 @@ ix86_emit_save_regs (void)
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
{
- insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno)));
+ insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
+ TARGET_APX_PPX));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
@@ -7399,7 +7402,8 @@ ix86_emit_save_regs (void)
gen_rtx_REG (word_mode,
regno_list[0]),
gen_rtx_REG (word_mode,
- regno_list[1])));
+ regno_list[1]),
+ TARGET_APX_PPX));
RTX_FRAME_RELATED_P (insn) = 1;
rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
@@ -7431,7 +7435,8 @@ ix86_emit_save_regs (void)
}
else
{
- insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno)));
+ insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
+ TARGET_APX_PPX));
RTX_FRAME_RELATED_P (insn) = 1;
aligned = true;
}
@@ -7439,7 +7444,8 @@ ix86_emit_save_regs (void)
if (loaded_regnum == 1)
{
insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
- regno_list[0])));
+ regno_list[0]),
+ TARGET_APX_PPX));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
@@ -9268,13 +9274,13 @@ ix86_expand_prologue (void)
emit_insn (gen_prologue_use (stack_pointer_rtx));
}
-/* Emit code to restore REG using a POP insn. */
+/* Emit code to restore REG using a POP or POPP insn. */
static void
-ix86_emit_restore_reg_using_pop (rtx reg)
+ix86_emit_restore_reg_using_pop (rtx reg, bool ppx_p)
{
struct machine_function *m = cfun->machine;
- rtx_insn *insn = emit_insn (gen_pop (reg));
+ rtx_insn *insn = emit_insn (gen_pop (reg, ppx_p));
ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
m->fs.sp_offset -= UNITS_PER_WORD;
@@ -9328,14 +9334,19 @@ ix86_emit_restore_reg_using_pop (rtx reg)
/* Emit code to restore REG using a POP2 insn. */
static void
-ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2)
+ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2, bool ppx_p = false)
{
struct machine_function *m = cfun->machine;
const int offset = UNITS_PER_WORD * 2;
+ rtx_insn *insn;
rtx mem = gen_rtx_MEM (TImode, gen_rtx_POST_INC (Pmode,
stack_pointer_rtx));
- rtx_insn *insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
+
+ if (ppx_p)
+ insn = emit_insn (gen_pop2p_di (reg1, mem, reg2));
+ else
+ insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
RTX_FRAME_RELATED_P (insn) = 1;
@@ -9397,13 +9408,13 @@ ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2)
/* Emit code to restore saved registers using POP insns. */
static void
-ix86_emit_restore_regs_using_pop (void)
+ix86_emit_restore_regs_using_pop (bool ppx_p)
{
unsigned int regno;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
- ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno));
+ ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno), ppx_p);
}
/* Emit code to restore saved registers using POP2 insns. */
@@ -9432,20 +9443,23 @@ ix86_emit_restore_regs_using_pop2 (void)
ix86_emit_restore_reg_using_pop2 (gen_rtx_REG (word_mode,
regno_list[0]),
gen_rtx_REG (word_mode,
- regno_list[1]));
+ regno_list[1]),
+ TARGET_APX_PPX);
loaded_regnum = 0;
regno_list[0] = regno_list[1] = -1;
}
}
else
{
- ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno));
+ ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno),
+ TARGET_APX_PPX);
aligned = true;
}
}
if (loaded_regnum == 1)
- ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]));
+ ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]),
+ TARGET_APX_PPX);
}
/* Emit code and notes for the LEAVE instruction. If insn is non-null,
@@ -9990,7 +10004,7 @@ ix86_expand_epilogue (int style)
if (TARGET_APX_PUSH2POP2 && m->func_type == TYPE_NORMAL)
ix86_emit_restore_regs_using_pop2 ();
else
- ix86_emit_restore_regs_using_pop ();
+ ix86_emit_restore_regs_using_pop (TARGET_APX_PPX);
}
/* If we used a stack pointer and haven't already got rid of it,
@@ -10353,6 +10367,7 @@ ix86_expand_split_stack_prologue (void)
rtx_code_label *label;
rtx limit, current, allocate_rtx, call_fusage;
rtx_insn *call_insn;
+ unsigned int scratch_regno = INVALID_REGNUM;
rtx scratch_reg = NULL_RTX;
rtx_code_label *varargs_label = NULL;
rtx fn;
@@ -10375,11 +10390,16 @@ ix86_expand_split_stack_prologue (void)
limit = ix86_split_stack_guard ();
- if (allocate < SPLIT_STACK_AVAILABLE)
- current = stack_pointer_rtx;
- else
+ if (allocate >= SPLIT_STACK_AVAILABLE
+ || flag_force_indirect_call)
+ {
+ scratch_regno = split_stack_prologue_scratch_regno ();
+ if (scratch_regno == INVALID_REGNUM)
+ return;
+ }
+
+ if (allocate >= SPLIT_STACK_AVAILABLE)
{
- unsigned int scratch_regno;
rtx offset;
/* We need a scratch register to hold the stack pointer minus
@@ -10387,9 +10407,7 @@ ix86_expand_split_stack_prologue (void)
function, the scratch register can be any caller-saved
register which is not used for parameters. */
offset = GEN_INT (- allocate);
- scratch_regno = split_stack_prologue_scratch_regno ();
- if (scratch_regno == INVALID_REGNUM)
- return;
+
scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
{
@@ -10407,6 +10425,8 @@ ix86_expand_split_stack_prologue (void)
}
current = scratch_reg;
}
+ else
+ current = stack_pointer_rtx;
ix86_expand_branch (GEU, current, limit, label);
rtx_insn *jump_insn = get_last_insn ();
@@ -10435,8 +10455,8 @@ ix86_expand_split_stack_prologue (void)
{
rtx reg10, reg11;
- reg10 = gen_rtx_REG (Pmode, R10_REG);
- reg11 = gen_rtx_REG (Pmode, R11_REG);
+ reg10 = gen_rtx_REG (DImode, R10_REG);
+ reg11 = gen_rtx_REG (DImode, R11_REG);
/* If this function uses a static chain, it will be in %r10.
Preserve it across the call to __morestack. */
@@ -10449,50 +10469,51 @@ ix86_expand_split_stack_prologue (void)
use_reg (&call_fusage, rax);
}
- if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
- && !TARGET_PECOFF)
+ if (flag_force_indirect_call
+ || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
{
HOST_WIDE_INT argval;
- gcc_assert (Pmode == DImode);
- /* When using the large model we need to load the address
- into a register, and we've run out of registers. So we
- switch to a different calling convention, and we call a
- different function: __morestack_large. We pass the
- argument size in the upper 32 bits of r10 and pass the
- frame size in the lower 32 bits. */
- gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
- gcc_assert ((args_size & 0xffffffff) == args_size);
-
if (split_stack_fn_large == NULL_RTX)
{
split_stack_fn_large
= gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
}
+
+ fn = split_stack_fn_large;
+
if (ix86_cmodel == CM_LARGE_PIC)
{
rtx_code_label *label;
rtx x;
+ gcc_assert (Pmode == DImode);
+
label = gen_label_rtx ();
emit_label (label);
LABEL_PRESERVE_P (label) = 1;
emit_insn (gen_set_rip_rex64 (reg10, label));
emit_insn (gen_set_got_offset_rex64 (reg11, label));
emit_insn (gen_add2_insn (reg10, reg11));
- x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn_large),
- UNSPEC_GOT);
+ x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fn), UNSPEC_GOT);
x = gen_rtx_CONST (Pmode, x);
emit_move_insn (reg11, x);
x = gen_rtx_PLUS (Pmode, reg10, reg11);
x = gen_const_mem (Pmode, x);
- emit_move_insn (reg11, x);
+ fn = copy_to_suggested_reg (x, reg11, Pmode);
}
- else
- emit_move_insn (reg11, split_stack_fn_large);
+ else if (ix86_cmodel == CM_LARGE)
+ fn = copy_to_suggested_reg (fn, reg11, Pmode);
- fn = reg11;
+ /* When using the large model we need to load the address
+ into a register, and we've run out of registers. So we
+ switch to a different calling convention, and we call a
+ different function: __morestack_large. We pass the
+ argument size in the upper 32 bits of r10 and pass the
+ frame size in the lower 32 bits. */
+ gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
+ gcc_assert ((args_size & 0xffffffff) == args_size);
argval = ((args_size << 16) << 16) + allocate;
emit_move_insn (reg10, GEN_INT (argval));
@@ -10508,12 +10529,40 @@ ix86_expand_split_stack_prologue (void)
}
else
{
+ if (flag_force_indirect_call && flag_pic)
+ {
+ rtx x;
+
+ gcc_assert (Pmode == SImode);
+
+ scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
+
+ emit_insn (gen_set_got (scratch_reg));
+ x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn),
+ UNSPEC_GOT);
+ x = gen_rtx_CONST (Pmode, x);
+ x = gen_rtx_PLUS (Pmode, scratch_reg, x);
+ x = gen_const_mem (Pmode, x);
+ fn = copy_to_suggested_reg (x, scratch_reg, Pmode);
+ }
+
rtx_insn *insn = emit_insn (gen_push (GEN_INT (args_size)));
add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (UNITS_PER_WORD));
insn = emit_insn (gen_push (allocate_rtx));
add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (2 * UNITS_PER_WORD));
pop = GEN_INT (2 * UNITS_PER_WORD);
}
+
+ if (flag_force_indirect_call && !register_operand (fn, VOIDmode))
+ {
+ scratch_reg = gen_rtx_REG (word_mode, scratch_regno);
+
+ if (GET_MODE (fn) != word_mode)
+ fn = gen_rtx_ZERO_EXTEND (word_mode, fn);
+
+ fn = copy_to_suggested_reg (fn, scratch_reg, word_mode);
+ }
+
call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
GEN_INT (UNITS_PER_WORD), constm1_rtx,
pop, false);
@@ -10558,7 +10607,6 @@ ix86_expand_split_stack_prologue (void)
slot. */
if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
{
- unsigned int scratch_regno;
rtx frame_reg;
int words;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 0370747..47340c6 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -54,6 +54,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_APX_EGPR (ix86_apx_features & apx_egpr)
#define TARGET_APX_PUSH2POP2 (ix86_apx_features & apx_push2pop2)
#define TARGET_APX_NDD (ix86_apx_features & apx_ndd)
+#define TARGET_APX_PPX (ix86_apx_features & apx_ppx)
#include "config/vxworks-dummy.h"
@@ -2374,13 +2375,13 @@ constexpr wide_int_bitmask PTA_SKYLAKE = PTA_BROADWELL | PTA_AES
| PTA_CLFLUSHOPT | PTA_XSAVEC | PTA_XSAVES | PTA_SGX;
constexpr wide_int_bitmask PTA_SKYLAKE_AVX512 = PTA_SKYLAKE | PTA_AVX512F
| PTA_AVX512CD | PTA_AVX512VL | PTA_AVX512BW | PTA_AVX512DQ | PTA_PKU
- | PTA_CLWB;
+ | PTA_CLWB | PTA_EVEX512;
constexpr wide_int_bitmask PTA_CASCADELAKE = PTA_SKYLAKE_AVX512
| PTA_AVX512VNNI;
constexpr wide_int_bitmask PTA_COOPERLAKE = PTA_CASCADELAKE | PTA_AVX512BF16;
constexpr wide_int_bitmask PTA_CANNONLAKE = PTA_SKYLAKE | PTA_AVX512F
| PTA_AVX512CD | PTA_AVX512VL | PTA_AVX512BW | PTA_AVX512DQ | PTA_PKU
- | PTA_AVX512VBMI | PTA_AVX512IFMA | PTA_SHA;
+ | PTA_AVX512VBMI | PTA_AVX512IFMA | PTA_SHA | PTA_EVEX512;
constexpr wide_int_bitmask PTA_ICELAKE_CLIENT = PTA_CANNONLAKE | PTA_AVX512VNNI
| PTA_GFNI | PTA_VAES | PTA_AVX512VBMI2 | PTA_VPCLMULQDQ | PTA_AVX512BITALG
| PTA_RDPID | PTA_AVX512VPOPCNTDQ;
@@ -2440,7 +2441,7 @@ constexpr wide_int_bitmask PTA_ZNVER3 = PTA_ZNVER2 | PTA_VAES | PTA_VPCLMULQDQ
constexpr wide_int_bitmask PTA_ZNVER4 = PTA_ZNVER3 | PTA_AVX512F | PTA_AVX512DQ
| PTA_AVX512IFMA | PTA_AVX512CD | PTA_AVX512BW | PTA_AVX512VL
| PTA_AVX512BF16 | PTA_AVX512VBMI | PTA_AVX512VBMI2 | PTA_GFNI
- | PTA_AVX512VNNI | PTA_AVX512BITALG | PTA_AVX512VPOPCNTDQ;
+ | PTA_AVX512VNNI | PTA_AVX512BITALG | PTA_AVX512VPOPCNTDQ | PTA_EVEX512;
constexpr wide_int_bitmask PTA_LUJIAZUI = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2
| PTA_SSE3 | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1b5a794..cb32de7 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -210,10 +210,13 @@
;; For insn_callee_abi:
UNSPEC_CALLEE_ABI
- ;; For PUSH2/POP2 support
+ ;; For APX PUSH2/POP2 support
UNSPEC_APXPUSH2
UNSPEC_APXPOP2_LOW
UNSPEC_APXPOP2_HIGH
+
+ ;; For APX PPX support
+ UNSPEC_APX_PPX
])
(define_c_enum "unspecv" [
@@ -3769,7 +3772,7 @@
(match_operand:DI 2 "register_operand" "r")]
UNSPEC_APXPUSH2))]
"TARGET_APX_PUSH2POP2"
- "push2\t%1, %2"
+ "push2\t{%2, %1|%1, %2}"
[(set_attr "mode" "TI")
(set_attr "type" "multi")
(set_attr "prefix" "evex")])
@@ -3781,7 +3784,47 @@
(set (match_operand:DI 2 "register_operand" "=r")
(unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
"TARGET_APX_PUSH2POP2"
- "pop2\t%0, %2"
+ "pop2\t{%2, %0|%0, %2}"
+ [(set_attr "mode" "TI")
+ (set_attr "prefix" "evex")])
+
+(define_insn "pushp_di"
+ [(set (match_operand:DI 0 "push_operand" "=<")
+ (match_operand:DI 1 "register_operand" "r"))
+ (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
+ "TARGET_64BIT"
+ "pushp\t%1"
+ [(set_attr "mode" "DI")])
+
+(define_insn "popp_di"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (match_operand:DI 1 "pop_operand" ">"))
+ (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
+ "TARGET_APX_PPX"
+ "popp\t%0"
+ [(set_attr "mode" "DI")])
+
+(define_insn "push2p_di"
+ [(set (match_operand:TI 0 "push_operand" "=<")
+ (unspec:TI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "register_operand" "r")]
+ UNSPEC_APXPUSH2))
+ (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
+ "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
+ "push2p\t{%2, %1|%1, %2}"
+ [(set_attr "mode" "TI")
+ (set_attr "type" "multi")
+ (set_attr "prefix" "evex")])
+
+(define_insn "pop2p_di"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
+ UNSPEC_APXPOP2_LOW))
+ (set (match_operand:DI 2 "register_operand" "=r")
+ (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))
+ (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)])]
+ "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
+ "pop2p\t{%2, %0|%0, %2}"
[(set_attr "mode" "TI")
(set_attr "prefix" "evex")])
@@ -16836,7 +16879,8 @@
(const_int 1)
(and:QI
(match_operand:QI 2 "register_operand")
- (match_operand 3 "const_int_operand")))])
+ (match_operand 3 "const_int_operand")))
+ (const_int 0)])
(label_ref (match_operand 4))
(pc)))
(clobber (reg:CC FLAGS_REG))]
@@ -16872,7 +16916,8 @@
(subreg:QI
(and:SWI248
(match_operand:SWI248 2 "register_operand")
- (match_operand 3 "const_int_operand")) 0))])
+ (match_operand 3 "const_int_operand")) 0))
+ (const_int 0)])
(label_ref (match_operand 4))
(pc)))
(clobber (reg:CC FLAGS_REG))]
@@ -19988,8 +20033,10 @@
"! TARGET_POPCNT"
{
rtx scratch = gen_reg_rtx (QImode);
+ rtx tmp = gen_reg_rtx (HImode);
- emit_insn (gen_parityhi2_cmp (operands[1]));
+ emit_move_insn (tmp, operands[1]);
+ emit_insn (gen_parityhi2_cmp (tmp));
ix86_expand_setcc (scratch, ORDERED,
gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 0c3b8f4..b2edfac 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -36,6 +36,13 @@ HOST_WIDE_INT ix86_isa_flags_explicit
Variable
HOST_WIDE_INT ix86_isa_flags2_explicit
+; Indicate if AVX512 and AVX10.1 are explicitly set no.
+Variable
+int ix86_no_avx512_explicit = 0
+
+Variable
+int ix86_no_avx10_1_explicit = 0
+
; Additional target flags
Variable
int ix86_target_flags
@@ -96,6 +103,14 @@ HOST_WIDE_INT x_ix86_isa_flags2_explicit
TargetSave
HOST_WIDE_INT x_ix86_isa_flags_explicit
+;; which flags were passed by the user
+TargetSave
+HOST_WIDE_INT x_ix86_no_avx512_explicit
+
+;; which flags were passed by the user
+TargetSave
+HOST_WIDE_INT x_ix86_no_avx10_1_explicit
+
;; whether -mtune was not specified
TargetSave
unsigned char tune_defaulted
@@ -1334,6 +1349,9 @@ EnumValue
Enum(apx_features) String(ndd) Value(apx_ndd) Set(4)
EnumValue
+Enum(apx_features) String(ppx) Value(apx_ppx) Set(5)
+
+EnumValue
Enum(apx_features) String(all) Value(apx_all) Set(1)
mapx-inline-asm-use-gpr32
@@ -1348,3 +1366,18 @@ Support 512 bit vector built-in functions and code generation.
musermsr
Target Mask(ISA2_USER_MSR) Var(ix86_isa_flags2) Save
Support USER_MSR built-in functions and code generation.
+
+mavx10.1-256
+Target Mask(ISA2_AVX10_1_256) Var(ix86_isa_flags2) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2,
+and AVX10.1 built-in functions and code generation.
+
+mavx10.1-512
+Target Mask(ISA2_AVX10_1_512) Var(ix86_isa_flags2) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2,
+and AVX10.1-512 built-in functions and code generation.
+
+mavx10.1
+Target Alias(mavx10.1-256)
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2,
+and AVX10.1 built-in functions and code generation.
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 0f16d2a..a07a921 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -120,13 +120,15 @@
[(V2SI "SI") (V2SF "SF")
(V4HF "HF") (V4BF "BF")
(V2HF "HF") (V2BF "BF")
- (V4HI "HI") (V2HI "HI")])
+ (V4HI "HI") (V2HI "HI")
+ (V8QI "QI")])
(define_mode_attr mmxscalarmodelower
[(V2SI "si") (V2SF "sf")
(V4HF "hf") (V4BF "bf")
(V2HF "hf") (V2BF "bf")
- (V4HI "hi") (V2HI "hi")])
+ (V4HI "hi") (V2HI "hi")
+ (V8QI "qi")])
(define_mode_attr Yv_Yw
[(V8QI "Yw") (V4HI "Yw") (V2SI "Yv") (V1DI "Yv") (V2SF "Yv")])
@@ -6094,6 +6096,31 @@
(set_attr "type" "mmxshft,sseiadd,sseiadd")
(set_attr "mode" "DI,TI,TI")])
+(define_expand "reduc_<code>_scal_<mode>"
+ [(any_logic:MMXMODE12
+ (match_operand:<mmxscalarmode> 0 "register_operand")
+ (match_operand:MMXMODE12 1 "register_operand"))]
+ "TARGET_MMX_WITH_SSE"
+{
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ ix86_expand_reduc (gen_<code><mode>3, tmp, operands[1]);
+ emit_insn (gen_vec_extract<mode><mmxscalarmodelower> (operands[0],
+ tmp, const0_rtx));
+ DONE;
+})
+
+(define_expand "reduc_<code>_scal_v4qi"
+ [(any_logic:V4QI
+ (match_operand:QI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand"))]
+ "TARGET_SSE2"
+{
+ rtx tmp = gen_reg_rtx (V4QImode);
+ ix86_expand_reduc (gen_<code>v4qi3, tmp, operands[1]);
+ emit_insn (gen_vec_extractv4qiqi (operands[0], tmp, const0_rtx));
+ DONE;
+})
+
(define_expand "reduc_plus_scal_v8qi"
[(plus:V8QI
(match_operand:QI 0 "register_operand")
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index d250a6c..4f51169 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -514,6 +514,12 @@
(V16SI "TARGET_AVX512F && TARGET_EVEX512") (V8SI "TARGET_AVX2") V4SI
(V8DI "TARGET_AVX512F && TARGET_EVEX512") (V4DI "TARGET_AVX2") V2DI])
+(define_mode_iterator VI_AVX_AVX512F
+ [(V64QI "TARGET_AVX512F && TARGET_EVEX512") (V32QI "TARGET_AVX") V16QI
+ (V32HI "TARGET_AVX512F && TARGET_EVEX512") (V16HI "TARGET_AVX") V8HI
+ (V16SI "TARGET_AVX512F && TARGET_EVEX512") (V8SI "TARGET_AVX") V4SI
+ (V8DI "TARGET_AVX512F && TARGET_EVEX512") (V4DI "TARGET_AVX") V2DI])
+
;; All QImode vector integer modes
(define_mode_iterator VI1
[(V32QI "TARGET_AVX") V16QI])
@@ -3417,7 +3423,9 @@
(define_mode_iterator REDUC_SSE_PLUS_MODE
[(V2DF "TARGET_SSE") (V4SF "TARGET_SSE")
- (V8HF "TARGET_AVX512FP16 && TARGET_AVX512VL")])
+ (V8HF "TARGET_AVX512FP16 && TARGET_AVX512VL")
+ (V8HI "TARGET_SSE2") (V4SI "TARGET_SSE2")
+ (V2DI "TARGET_SSE2")])
(define_expand "reduc_plus_scal_<mode>"
[(plus:REDUC_SSE_PLUS_MODE
@@ -3458,8 +3466,12 @@
(V8DF "TARGET_AVX512F && TARGET_EVEX512")
(V16SF "TARGET_AVX512F && TARGET_EVEX512")
(V32HF "TARGET_AVX512FP16 && TARGET_AVX512VL && TARGET_EVEX512")
- (V32QI "TARGET_AVX")
- (V64QI "TARGET_AVX512F && TARGET_EVEX512")])
+ (V32QI "TARGET_AVX") (V16HI "TARGET_AVX")
+ (V8SI "TARGET_AVX") (V4DI "TARGET_AVX")
+ (V64QI "TARGET_AVX512F && TARGET_EVEX512")
+ (V32HI "TARGET_AVX512F && TARGET_EVEX512")
+ (V16SI "TARGET_AVX512F && TARGET_EVEX512")
+ (V8DI "TARGET_AVX512F && TARGET_EVEX512")])
(define_expand "reduc_plus_scal_<mode>"
[(plus:REDUC_PLUS_MODE
@@ -3597,6 +3609,42 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
+(define_expand "reduc_<code>_scal_<mode>"
+ [(any_logic:VI_128
+ (match_operand:<ssescalarmode> 0 "register_operand")
+ (match_operand:VI_128 1 "register_operand"))]
+ "TARGET_SSE2"
+{
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ ix86_expand_reduc (gen_<code><mode>3, tmp, operands[1]);
+ emit_insn (gen_vec_extract<mode><ssescalarmodelower> (operands[0],
+ tmp, const0_rtx));
+ DONE;
+})
+
+(define_mode_iterator REDUC_ANY_LOGIC_MODE
+ [(V32QI "TARGET_AVX") (V16HI "TARGET_AVX")
+ (V8SI "TARGET_AVX") (V4DI "TARGET_AVX")
+ (V64QI "TARGET_AVX512F && TARGET_EVEX512")
+ (V32HI "TARGET_AVX512F && TARGET_EVEX512")
+ (V16SI "TARGET_AVX512F && TARGET_EVEX512")
+ (V8DI "TARGET_AVX512F && TARGET_EVEX512")])
+
+(define_expand "reduc_<code>_scal_<mode>"
+ [(any_logic:REDUC_ANY_LOGIC_MODE
+ (match_operand:<ssescalarmode> 0 "register_operand")
+ (match_operand:REDUC_ANY_LOGIC_MODE 1 "register_operand"))]
+ ""
+{
+ rtx tmp = gen_reg_rtx (<ssehalfvecmode>mode);
+ emit_insn (gen_vec_extract_hi_<mode> (tmp, operands[1]));
+ rtx tmp2 = gen_reg_rtx (<ssehalfvecmode>mode);
+ rtx tmp3 = gen_lowpart (<ssehalfvecmode>mode, operands[1]);
+ emit_insn (gen_<code><ssehalfvecmodelower>3 (tmp2, tmp, tmp3));
+ emit_insn (gen_reduc_<code>_scal_<ssehalfvecmodelower> (operands[0], tmp2));
+ DONE;
+})
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Parallel floating point comparisons
@@ -27868,8 +27916,8 @@
(define_expand "cbranch<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:VI48_AVX_AVX512F 1 "register_operand")
- (match_operand:VI48_AVX_AVX512F 2 "nonimmediate_operand")))
+ (compare:CC (match_operand:VI_AVX_AVX512F 1 "register_operand")
+ (match_operand:VI_AVX_AVX512F 2 "nonimmediate_operand")))
(set (pc) (if_then_else
(match_operator 0 "bt_comparison_operator"
[(reg:CC FLAGS_REG) (const_int 0)])
diff --git a/gcc/config/linux-protos.h b/gcc/config/linux-protos.h
index f2ea930..8342498 100644
--- a/gcc/config/linux-protos.h
+++ b/gcc/config/linux-protos.h
@@ -22,3 +22,4 @@ extern bool linux_has_ifunc_p (void);
extern bool linux_libc_has_function (enum function_class fn_class, tree);
extern unsigned linux_libm_function_max_error (unsigned, machine_mode, bool);
+extern unsigned linux_fortify_source_default_level ();
diff --git a/gcc/config/linux.cc b/gcc/config/linux.cc
index 9114e55..c8df6c7 100644
--- a/gcc/config/linux.cc
+++ b/gcc/config/linux.cc
@@ -49,3 +49,12 @@ linux_libm_function_max_error (unsigned cfn, machine_mode mode,
return glibc_linux_libm_function_max_error (cfn, mode, boundary_p);
return default_libm_function_max_error (cfn, mode, boundary_p);
}
+
+unsigned
+linux_fortify_source_default_level ()
+{
+ if (OPTION_GLIBC && TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 35)
+ return 3;
+
+ return 2;
+}
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index ac56816..79b6537 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -216,3 +216,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# define TARGET_LIBM_FUNCTION_MAX_ERROR linux_libm_function_max_error
#endif
+
+#undef TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL
+#define TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL linux_fortify_source_default_level
diff --git a/gcc/config/loongarch/gnu-user.h b/gcc/config/loongarch/gnu-user.h
index 9616d6e..e9f4bce 100644
--- a/gcc/config/loongarch/gnu-user.h
+++ b/gcc/config/loongarch/gnu-user.h
@@ -34,9 +34,9 @@ along with GCC; see the file COPYING3. If not see
"/lib" ABI_GRLEN_SPEC "/ld-linux-loongarch-" ABI_SPEC ".so.1"
#define MUSL_ABI_SPEC \
- "%{mabi=lp64d:-lp64d}" \
- "%{mabi=lp64f:-lp64f}" \
- "%{mabi=lp64s:-lp64s}"
+ "%{mabi=lp64d:}" \
+ "%{mabi=lp64f:-sp}" \
+ "%{mabi=lp64s:-sf}"
#undef MUSL_DYNAMIC_LINKER
#define MUSL_DYNAMIC_LINKER \
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index af7bd63..851ff86 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -46,7 +46,10 @@ along with GCC; see the file COPYING3. If not see
#ifndef LOONGARCH_DEF_H
#define LOONGARCH_DEF_H
+#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
#include <stdint.h>
+#endif
+
#include "loongarch-tune.h"
#ifdef __cplusplus
@@ -62,9 +65,11 @@ extern const char* loongarch_isa_base_strings[];
#define ISA_BASE_LA64V110 1
#define N_ISA_BASE_TYPES 2
+#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
/* Unlike other arrays, this is defined in loongarch-cpu.cc. The problem is
we cannot use the C++ header options.h in loongarch-def.c. */
extern int64_t loongarch_isa_base_features[];
+#endif
/* enum isa_ext_* */
extern const char* loongarch_isa_ext_strings[];
@@ -121,6 +126,7 @@ extern const char* loongarch_cmodel_strings[];
#define M_OPT_ABSENT(opt_enum) ((opt_enum) == M_OPT_UNSET)
+#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
/* Internal representation of the target. */
struct loongarch_isa
{
@@ -150,6 +156,9 @@ struct loongarch_target
int cmodel; /* CMODEL_ */
};
+extern struct loongarch_isa loongarch_cpu_default_isa[];
+#endif
+
/* CPU properties. */
/* index */
#define CPU_NATIVE 0
@@ -162,7 +171,6 @@ struct loongarch_target
/* parallel tables. */
extern const char* loongarch_cpu_strings[];
-extern struct loongarch_isa loongarch_cpu_default_isa[];
extern int loongarch_cpu_issue_rate[];
extern int loongarch_cpu_multipass_dfa_lookahead[];
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index ce601a3..d3896d7 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -142,12 +142,16 @@ struct loongarch_address_info
METHOD_LU52I:
Load 52-63 bit of the immediate number.
+
+ METHOD_MIRROR:
+ Copy 0-31 bit of the immediate number to 32-63bit.
*/
enum loongarch_load_imm_method
{
METHOD_NORMAL,
METHOD_LU32I,
- METHOD_LU52I
+ METHOD_LU52I,
+ METHOD_MIRROR
};
struct loongarch_integer_op
@@ -1556,11 +1560,23 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
int sign31 = (value & (HOST_WIDE_INT_1U << 31)) >> 31;
int sign51 = (value & (HOST_WIDE_INT_1U << 51)) >> 51;
+
+ uint32_t hival = (uint32_t) (value >> 32);
+ uint32_t loval = (uint32_t) value;
+
/* Determine whether the upper 32 bits are sign-extended from the lower
32 bits. If it is, the instructions to load the high order can be
ommitted. */
if (lu32i[sign31] && lu52i[sign31])
return cost;
+ /* If the lower 32 bits are the same as the upper 32 bits, just copy
+ the lower 32 bits to the upper 32 bits. */
+ else if (loval == hival)
+ {
+ codes[cost].method = METHOD_MIRROR;
+ codes[cost].curr_value = value;
+ return cost + 1;
+ }
/* Determine whether bits 32-51 are sign-extended from the lower 32
bits. If so, directly load 52-63 bits. */
else if (lu32i[sign31])
@@ -3234,6 +3250,10 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
gen_rtx_AND (DImode, x, GEN_INT (0xfffffffffffff)),
GEN_INT (codes[i].value));
break;
+ case METHOD_MIRROR:
+ gcc_assert (mode == DImode);
+ emit_insn (gen_insvdi (x, GEN_INT (32), GEN_INT (32), x));
+ break;
default:
gcc_unreachable ();
}
@@ -4249,7 +4269,7 @@ loongarch_split_plus_constant (rtx *op, machine_mode mode)
else if (loongarch_addu16i_imm12_operand_p (v, mode))
a = (v & ~HWIT_UC_0xFFF) + ((v & 0x800) << 1);
else if (mode == DImode && DUAL_ADDU16I_OPERAND (v))
- a = (v > 0 ? 0x7fff : -0x8000) << 16;
+ a = (v > 0 ? 0x7fff0000 : ~0x7fffffff);
else
gcc_unreachable ();
@@ -8607,8 +8627,9 @@ void
loongarch_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
{
machine_mode vmode = GET_MODE (target);
+ machine_mode vimode = GET_MODE (sel);
auto nelt = GET_MODE_NUNITS (vmode);
- auto round_reg = gen_reg_rtx (vmode);
+ auto round_reg = gen_reg_rtx (vimode);
rtx round_data[MAX_VECT_LEN];
for (int i = 0; i < nelt; i += 1)
@@ -8616,9 +8637,16 @@ loongarch_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
round_data[i] = GEN_INT (0x1f);
}
- rtx round_data_rtx = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, round_data));
+ rtx round_data_rtx = gen_rtx_CONST_VECTOR (vimode, gen_rtvec_v (nelt, round_data));
emit_move_insn (round_reg, round_data_rtx);
+ if (vmode != vimode)
+ {
+ target = lowpart_subreg (vimode, target, vmode);
+ op0 = lowpart_subreg (vimode, op0, vmode);
+ op1 = lowpart_subreg (vimode, op1, vmode);
+ }
+
switch (vmode)
{
case E_V16QImode:
@@ -8626,17 +8654,11 @@ loongarch_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
emit_insn (gen_lsx_vshuf_b (target, op1, op0, sel));
break;
case E_V2DFmode:
- emit_insn (gen_andv2di3 (sel, sel, round_reg));
- emit_insn (gen_lsx_vshuf_d_f (target, sel, op1, op0));
- break;
case E_V2DImode:
emit_insn (gen_andv2di3 (sel, sel, round_reg));
emit_insn (gen_lsx_vshuf_d (target, sel, op1, op0));
break;
case E_V4SFmode:
- emit_insn (gen_andv4si3 (sel, sel, round_reg));
- emit_insn (gen_lsx_vshuf_w_f (target, sel, op1, op0));
- break;
case E_V4SImode:
emit_insn (gen_andv4si3 (sel, sel, round_reg));
emit_insn (gen_lsx_vshuf_w (target, sel, op1, op0));
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 8ea41c8..5e8d8d7 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -837,7 +837,7 @@
[(match_operand:LSX 0 "register_operand")
(match_operand:LSX 1 "register_operand")
(match_operand:LSX 2 "register_operand")
- (match_operand:LSX 3 "register_operand")]
+ (match_operand:<VIMODE> 3 "register_operand")]
"ISA_HAS_LSX"
{
loongarch_expand_vec_perm (operands[0], operands[1],
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index a254547..0666310 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -5732,7 +5732,7 @@
(define_insn "rdhwr_synci_step_<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
- (unspec_volatile [(const_int 1)]
+ (unspec_volatile:P [(const_int 1)]
UNSPEC_RDHWR))]
"ISA_HAS_SYNCI"
"rdhwr\t%0,$1")
diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index 0eeff95..570bcc7 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -721,7 +721,7 @@ nvptx_function_arg_advance (cumulative_args_t cum_v, const function_arg_info &)
/* Implement TARGET_FUNCTION_ARG_BOUNDARY.
- For nvptx This is only used for varadic args. The type has already
+ For nvptx This is only used for variadic args. The type has already
been promoted and/or converted to invisible reference. */
static unsigned
@@ -1549,7 +1549,7 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl)
if (!TARGET_SOFT_STACK)
{
/* Declare a local var for outgoing varargs. */
- if (cfun->machine->has_varadic)
+ if (cfun->machine->has_variadic)
init_frame (file, STACK_POINTER_REGNUM,
UNITS_PER_WORD, crtl->outgoing_args_size);
@@ -1559,7 +1559,7 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl)
init_frame (file, FRAME_POINTER_REGNUM, alignment,
ROUND_UP (sz, GET_MODE_SIZE (DImode)));
}
- else if (need_frameptr || cfun->machine->has_varadic || cfun->calls_alloca
+ else if (need_frameptr || cfun->machine->has_variadic || cfun->calls_alloca
|| (cfun->machine->has_simtreg && !crtl->is_leaf))
init_softstack_frame (file, alignment, sz);
@@ -1796,13 +1796,13 @@ nvptx_call_args (rtx arg, tree fntype)
if (!cfun->machine->doing_call)
{
cfun->machine->doing_call = true;
- cfun->machine->is_varadic = false;
+ cfun->machine->is_variadic = false;
cfun->machine->num_args = 0;
if (fntype && stdarg_p (fntype))
{
- cfun->machine->is_varadic = true;
- cfun->machine->has_varadic = true;
+ cfun->machine->is_variadic = true;
+ cfun->machine->has_variadic = true;
cfun->machine->num_args++;
}
}
@@ -1872,7 +1872,7 @@ nvptx_expand_call (rtx retval, rtx address)
}
unsigned nargs = cfun->machine->num_args;
- if (cfun->machine->is_varadic)
+ if (cfun->machine->is_variadic)
{
varargs = gen_reg_rtx (Pmode);
emit_move_insn (varargs, stack_pointer_rtx);
diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index 407fd70..71cab66 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -209,8 +209,8 @@ struct GTY(()) machine_function
{
rtx_expr_list *call_args; /* Arg list for the current call. */
bool doing_call; /* Within a CALL_ARGS ... CALL_ARGS_END sequence. */
- bool is_varadic; /* This call is varadic */
- bool has_varadic; /* Current function has a varadic call. */
+ bool is_variadic; /* This call is variadic */
+ bool has_variadic; /* Current function has a variadic call. */
bool has_chain; /* Current function has outgoing static chain. */
bool has_softstack; /* Current function has a soft stack frame. */
bool has_simtreg; /* Current function has an OpenMP SIMD region. */
diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index 565c948..2ee9877 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -1872,9 +1872,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
if (reg_plus_base_memory_operand (op1, GET_MODE (op1)))
{
- if (!(TARGET_PA_20
- && !TARGET_ELF32
- && INT_14_BITS (XEXP (XEXP (op1, 0), 1)))
+ if (!(INT14_OK_STRICT && INT_14_BITS (XEXP (XEXP (op1, 0), 1)))
&& !INT_5_BITS (XEXP (XEXP (op1, 0), 1)))
{
/* SCRATCH_REG will hold an address and maybe the actual data.
@@ -1923,9 +1921,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
if (reg_plus_base_memory_operand (op0, GET_MODE (op0)))
{
- if (!(TARGET_PA_20
- && !TARGET_ELF32
- && INT_14_BITS (XEXP (XEXP (op0, 0), 1)))
+ if (!(INT14_OK_STRICT && INT_14_BITS (XEXP (XEXP (op0, 0), 1)))
&& !INT_5_BITS (XEXP (XEXP (op0, 0), 1)))
{
/* SCRATCH_REG will hold an address and maybe the actual data.
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index aba2cec..d734286 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1310,3 +1310,7 @@ do { \
/* Output default function prologue for hpux. */
#define TARGET_ASM_FUNCTION_PROLOGUE pa_output_function_prologue
+
+/* An integer expression for the size in bits of the largest integer machine
+ mode that should actually be used. We allow pairs of registers. */
+#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode)
diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md
index 1b50020..4c07c0a 100644
--- a/gcc/config/pa/predicates.md
+++ b/gcc/config/pa/predicates.md
@@ -308,6 +308,13 @@
if (reg_plus_base_memory_operand (op, mode))
{
+ /* There is no support for handling secondary reloads of integer
+ REG+D instructions in pa_emit_move_sequence. Further, the Q
+ constraint is used in more than simple move instructions. So,
+ we must return true and let reload handle the reload. */
+ if (reload_in_progress)
+ return true;
+
/* Extract CONST_INT operand. */
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
index bbb9261..ea2f67a 100755
--- a/gcc/config/riscv/arch-canonicalize
+++ b/gcc/config/riscv/arch-canonicalize
@@ -83,7 +83,7 @@ def arch_canonicalize(arch, isa_spec):
new_arch = ""
extra_long_ext = []
std_exts = []
- if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
+ if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64e', 'rv64i', 'rv64g']:
new_arch = arch[:5].replace("g", "i")
if arch[:5] in ['rv32g', 'rv64g']:
std_exts = ['m', 'a', 'f', 'd']
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 80e41af..2d727c2 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -59,7 +59,7 @@
(match_operand:<RATIO64:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO64:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, true);
DONE;
@@ -74,7 +74,7 @@
(match_operand:<RATIO32:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO32:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, true);
DONE;
@@ -89,7 +89,7 @@
(match_operand:<RATIO16:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO16:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, true);
DONE;
@@ -104,7 +104,7 @@
(match_operand:<RATIO8:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO8:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, true);
DONE;
@@ -119,7 +119,7 @@
(match_operand:<RATIO4:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO4:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, true);
DONE;
@@ -134,7 +134,7 @@
(match_operand:<RATIO2:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO2:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, true);
DONE;
@@ -144,16 +144,16 @@
;; larger SEW. Since RVV indexed load/store support zero extend
;; implicitly and not support scaling, we should only allow
;; operands[3] and operands[4] to be const_1_operand.
-(define_expand "mask_len_gather_load<RATIO1:mode><RATIO1:mode>"
+(define_expand "mask_len_gather_load<mode><mode>"
[(match_operand:RATIO1 0 "register_operand")
(match_operand 1 "pmode_reg_or_0_operand")
(match_operand:RATIO1 2 "register_operand")
- (match_operand 3 "<RATIO1:gs_extension>")
- (match_operand 4 "<RATIO1:gs_scale>")
- (match_operand:<RATIO1:VM> 5 "vector_mask_operand")
+ (match_operand 3 "<gs_extension>")
+ (match_operand 4 "<gs_scale>")
+ (match_operand:<VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO1:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, true);
DONE;
@@ -172,7 +172,7 @@
(match_operand:<RATIO64:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO64:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, false);
DONE;
@@ -187,7 +187,7 @@
(match_operand:<RATIO32:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO32:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, false);
DONE;
@@ -202,7 +202,7 @@
(match_operand:<RATIO16:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO16:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, false);
DONE;
@@ -217,7 +217,7 @@
(match_operand:<RATIO8:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO8:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, false);
DONE;
@@ -232,7 +232,7 @@
(match_operand:<RATIO4:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO4:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, false);
DONE;
@@ -247,7 +247,7 @@
(match_operand:<RATIO2:VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO2:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, false);
DONE;
@@ -257,16 +257,16 @@
;; larger SEW. Since RVV indexed load/store support zero extend
;; implicitly and not support scaling, we should only allow
;; operands[3] and operands[4] to be const_1_operand.
-(define_expand "mask_len_scatter_store<RATIO1:mode><RATIO1:mode>"
+(define_expand "mask_len_scatter_store<mode><mode>"
[(match_operand 0 "pmode_reg_or_0_operand")
(match_operand:RATIO1 1 "register_operand")
- (match_operand 2 "<RATIO1:gs_extension>")
- (match_operand 3 "<RATIO1:gs_scale>")
+ (match_operand 2 "<gs_extension>")
+ (match_operand 3 "<gs_scale>")
(match_operand:RATIO1 4 "register_operand")
- (match_operand:<RATIO1:VM> 5 "vector_mask_operand")
+ (match_operand:<VM> 5 "vector_mask_operand")
(match_operand 6 "autovec_length_operand")
(match_operand 7 "const_0_operand")]
- "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_mode_p (<RATIO1:MODE>mode)"
+ "TARGET_VECTOR"
{
riscv_vector::expand_gather_scatter (operands, false);
DONE;
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 90567a8..525455f 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -41,6 +41,12 @@
(ior (match_operand 0 "arith_operand")
(match_operand 0 "lui_operand")))
+(define_predicate "movcc_operand"
+ (if_then_else (match_test "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV
+ || TARGET_ZICOND_LIKE")
+ (match_operand 0 "sfb_alu_operand")
+ (match_operand 0 "arith_operand")))
+
(define_predicate "const_csr_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 31)")))
@@ -78,6 +84,10 @@
(and (match_code "const_int")
(match_test "INTVAL (op) == 1 || INTVAL (op) == 4")))
+(define_predicate "const_1_or_8_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) == 1 || INTVAL (op) == 8")))
+
(define_predicate "reg_or_0_operand"
(ior (match_operand 0 "const_0_operand")
(match_operand 0 "register_operand")))
@@ -327,12 +337,12 @@
(define_predicate "modular_operator"
(match_code "plus,minus,mult,ashift"))
+(define_predicate "ne_operator"
+ (match_code "ne"))
+
(define_predicate "equality_operator"
(match_code "eq,ne"))
-(define_predicate "order_operator"
- (match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu"))
-
(define_predicate "signed_order_operator"
(match_code "eq,ne,lt,le,ge,gt"))
@@ -480,10 +490,6 @@
(ior (match_operand 0 "register_operand")
(match_code "const_vector")))
-(define_predicate "vector_gs_scale_operand_64"
- (and (match_code "const_int")
- (match_test "INTVAL (op) == 1 || (INTVAL (op) == 8 && Pmode == DImode)")))
-
(define_predicate "vector_gs_extension_operand"
(ior (match_operand 0 "const_1_operand")
(and (match_operand 0 "const_0_operand")
diff --git a/gcc/config/riscv/riscv-avlprop.cc b/gcc/config/riscv/riscv-avlprop.cc
index 1f6ba40..d298f0e 100644
--- a/gcc/config/riscv/riscv-avlprop.cc
+++ b/gcc/config/riscv/riscv-avlprop.cc
@@ -104,6 +104,29 @@ avlprop_type_to_str (enum avlprop_type type)
}
}
+/* Return true if the AVL of the INSN can be propagated. */
+static bool
+avl_can_be_propagated_p (rtx_insn *rinsn)
+{
+ /* We can't do AVL propagation when the instruction is potentially
+ touching the element with i > AVL. So, we don't do AVL propagation
+ on these following situations:
+
+ - The index of "vrgather dest, source, index" may pick up the
+ element which has index >= AVL, so we can't strip the elements
+ that has index >= AVL of source register.
+ - The last element of vslide1down is AVL + 1 according to RVV ISA:
+ vstart <= i < vl-1 vd[i] = vs2[i+1] if v0.mask[i] enabled
+ - The last multiple elements of vslidedown can be the element
+ has index >= AVL according to RVV ISA:
+ 0 <= i+OFFSET < VLMAX src[i] = vs2[i+OFFSET]
+ vstart <= i < vl vd[i] = src[i] if v0.mask[i] enabled. */
+ return get_attr_type (rinsn) != TYPE_VGATHER
+ && get_attr_type (rinsn) != TYPE_VSLIDEDOWN
+ && get_attr_type (rinsn) != TYPE_VISLIDE1DOWN
+ && get_attr_type (rinsn) != TYPE_VFSLIDE1DOWN;
+}
+
static bool
vlmax_ta_p (rtx_insn *rinsn)
{
@@ -260,6 +283,8 @@ pass_avlprop::get_preferred_avl (
rtx
pass_avlprop::get_vlmax_ta_preferred_avl (insn_info *insn) const
{
+ if (!avl_can_be_propagated_p (insn->rtl ()))
+ return NULL_RTX;
int sew = get_sew (insn->rtl ());
enum vlmul_type vlmul = get_vlmul (insn->rtl ());
int ratio = calculate_ratio (sew, vlmul);
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index dd1bd05..d70eb8e 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -51,7 +51,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
builtin_define ("__riscv_compressed");
if (TARGET_RVE)
- builtin_define ("__riscv_32e");
+ builtin_define (TARGET_64BIT ? "__riscv_64e" : "__riscv_32e");
if (TARGET_ATOMIC)
builtin_define ("__riscv_atomic");
@@ -76,6 +76,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
switch (riscv_abi)
{
case ABI_ILP32E:
+ case ABI_LP64E:
builtin_define ("__riscv_abi_rve");
gcc_fallthrough ();
diff --git a/gcc/config/riscv/riscv-d.cc b/gcc/config/riscv/riscv-d.cc
index cfeafa8..3ba3470 100644
--- a/gcc/config/riscv/riscv-d.cc
+++ b/gcc/config/riscv/riscv-d.cc
@@ -52,6 +52,7 @@ riscv_d_handle_target_float_abi (void)
{
case ABI_ILP32E:
case ABI_ILP32:
+ case ABI_LP64E:
case ABI_LP64:
abi = "soft";
break;
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 532b1b6..e6e55ad 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -27,6 +27,7 @@ enum riscv_abi_type {
ABI_ILP32F,
ABI_ILP32D,
ABI_LP64,
+ ABI_LP64E,
ABI_LP64F,
ABI_LP64D
};
@@ -102,6 +103,18 @@ enum riscv_entity
MAX_RISCV_ENTITIES
};
+/* RISC-V stringop strategy. */
+enum riscv_stringop_strategy_enum {
+ /* Use scalar or vector instructions. */
+ USE_AUTO,
+ /* Always use a library call. */
+ USE_LIBCALL,
+ /* Only use scalar instructions. */
+ USE_SCALAR,
+ /* Only use vector instructions. */
+ USE_VECTOR
+};
+
#define TARGET_ZICOND_LIKE (TARGET_ZICOND || (TARGET_XVENTANACONDOPS && TARGET_64BIT))
/* Bit of riscv_zvl_flags will set contintuly, N-1 bit will set if N-bit is
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 196b53f..695ee24 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -132,8 +132,10 @@ riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT, int);
#ifdef RTX_CODE
extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx, bool *invert_ptr = 0);
-extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
+extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx,
+ bool *invert_ptr = nullptr);
extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
+extern rtx riscv_emit_unary (enum rtx_code code, rtx dest, rtx x);
extern rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y);
#endif
extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
@@ -556,6 +558,7 @@ void expand_cond_binop (unsigned, rtx *);
void expand_cond_ternop (unsigned, rtx *);
void expand_popcount (rtx *);
void expand_rawmemchr (machine_mode, rtx, rtx, rtx);
+void emit_vec_extract (rtx, rtx, poly_int64);
/* Rounding mode bitfield for fixed point VXRM. */
enum fixed_point_rounding_mode
@@ -591,7 +594,6 @@ opt_machine_mode vectorize_related_mode (machine_mode, scalar_mode,
unsigned int autovectorize_vector_modes (vec<machine_mode> *, bool);
bool cmp_lmul_le_one (machine_mode);
bool cmp_lmul_gt_one (machine_mode);
-bool gather_scatter_valid_offset_mode_p (machine_mode);
bool vls_mode_valid_p (machine_mode);
bool vlmax_avl_type_p (rtx_insn *);
bool has_vl_op (rtx_insn *);
@@ -626,6 +628,7 @@ extern bool riscv_expand_strcmp (rtx, rtx, rtx, rtx, rtx);
extern bool riscv_expand_strlen (rtx, rtx, rtx, rtx);
/* Routines implemented in thead.cc. */
+extern bool extract_base_offset_in_addr (rtx, rtx *, rtx *);
extern bool th_mempair_operands_p (rtx[4], bool, machine_mode);
extern void th_mempair_order_operands (rtx[4], bool, machine_mode);
extern void th_mempair_prepare_save_restore_operands (rtx[4], bool,
diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 57e8ad6..3b5e05e 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -710,6 +710,10 @@ riscv_block_move_loop (rtx dest, rtx src, unsigned HOST_WIDE_INT length,
bool
riscv_expand_block_move (rtx dest, rtx src, rtx length)
{
+ if (riscv_memcpy_strategy == USE_LIBCALL
+ || riscv_memcpy_strategy == USE_VECTOR)
+ return false;
+
if (CONST_INT_P (length))
{
unsigned HOST_WIDE_INT hwi_length = UINTVAL (length);
@@ -773,7 +777,8 @@ expand_block_move (rtx dst_in, rtx src_in, rtx length_in)
bnez a2, loop # Any more?
ret # Return
*/
- if (!TARGET_VECTOR)
+ if (!TARGET_VECTOR || riscv_memcpy_strategy == USE_LIBCALL
+ || riscv_memcpy_strategy == USE_SCALAR)
return false;
HOST_WIDE_INT potential_ew
= (MIN (MIN (MEM_ALIGN (src_in), MEM_ALIGN (dst_in)), BITS_PER_WORD)
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 291f3c7..983c037 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -294,8 +294,6 @@ public:
"vsetvl zero, rs1/imm". */
poly_uint64 nunits = GET_MODE_NUNITS (vtype_mode);
len = gen_int_mode (nunits, Pmode);
- if (!satisfies_constraint_K (len))
- len = force_reg (Pmode, len);
vls_p = true;
}
else if (can_create_pseudo_p ())
@@ -374,10 +372,24 @@ void
emit_vlmax_insn_lra (unsigned icode, unsigned insn_flags, rtx *ops, rtx vl)
{
gcc_assert (!can_create_pseudo_p ());
+ machine_mode mode = GET_MODE (ops[0]);
- insn_expander<RVV_INSN_OPERANDS_MAX> e (insn_flags, true);
- e.set_vl (vl);
- e.emit_insn ((enum insn_code) icode, ops);
+ if (imm_avl_p (mode))
+ {
+ /* Even though VL is a real hardreg already allocated since
+ it is post-RA now, we still gain benefits that we emit
+ vsetivli zero, imm instead of vsetvli VL, zero which is
+ we can be more flexible in post-RA instruction scheduling. */
+ insn_expander<RVV_INSN_OPERANDS_MAX> e (insn_flags, false);
+ e.set_vl (gen_int_mode (GET_MODE_NUNITS (mode), Pmode));
+ e.emit_insn ((enum insn_code) icode, ops);
+ }
+ else
+ {
+ insn_expander<RVV_INSN_OPERANDS_MAX> e (insn_flags, true);
+ e.set_vl (vl);
+ e.emit_insn ((enum insn_code) icode, ops);
+ }
}
/* Emit an RVV insn with a predefined vector length. Contrary to
@@ -825,31 +837,13 @@ emit_vlmax_gather_insn (rtx target, rtx op, rtx sel)
insn_code icode;
machine_mode data_mode = GET_MODE (target);
machine_mode sel_mode = GET_MODE (sel);
- if (maybe_ne (GET_MODE_SIZE (data_mode), GET_MODE_SIZE (sel_mode)))
- icode = code_for_pred_gatherei16 (data_mode);
- else if (const_vec_duplicate_p (sel, &elt))
+ if (const_vec_duplicate_p (sel, &elt))
{
icode = code_for_pred_gather_scalar (data_mode);
sel = elt;
}
- else if (CONST_VECTOR_P (sel)
- && GET_MODE_BITSIZE (GET_MODE_INNER (sel_mode)) > 16
- && riscv_get_v_regno_alignment (data_mode) > 1)
- {
- /* If the inner mode of data is not QI or HI and data_lmul > 1,
- emitting vrgatherei16.vv instruction will lower register
- pressure.
- data_mode sel_mode ei16
- RVVM1QI RVVM1QI RVVM2HI not needed
- RVVM2QI RVVM2QI RVVM4HI not needed
- RVVM2HI RVVM2HI RVVM2HI not needed
- RVVM2SI RVVM2SI RVVM1HI need
- RVVM4SI RVVM4SI RVVM2HI need
- RVVM8DI RVVM8DI RVVM2HI need */
- PUT_MODE (sel, get_vector_mode (HImode,
- GET_MODE_NUNITS (data_mode)).require ());
- icode = code_for_pred_gatherei16 (data_mode);
- }
+ else if (maybe_ne (GET_MODE_SIZE (data_mode), GET_MODE_SIZE (sel_mode)))
+ icode = code_for_pred_gatherei16 (data_mode);
else
icode = code_for_pred_gather (data_mode);
rtx ops[] = {target, op, sel};
@@ -863,13 +857,13 @@ emit_vlmax_masked_gather_mu_insn (rtx target, rtx op, rtx sel, rtx mask)
insn_code icode;
machine_mode data_mode = GET_MODE (target);
machine_mode sel_mode = GET_MODE (sel);
- if (maybe_ne (GET_MODE_SIZE (data_mode), GET_MODE_SIZE (sel_mode)))
- icode = code_for_pred_gatherei16 (data_mode);
- else if (const_vec_duplicate_p (sel, &elt))
+ if (const_vec_duplicate_p (sel, &elt))
{
icode = code_for_pred_gather_scalar (data_mode);
sel = elt;
}
+ else if (maybe_ne (GET_MODE_SIZE (data_mode), GET_MODE_SIZE (sel_mode)))
+ icode = code_for_pred_gatherei16 (data_mode);
else
icode = code_for_pred_gather (data_mode);
rtx ops[] = {target, mask, target, op, sel};
@@ -2094,32 +2088,23 @@ expand_tuple_move (rtx *ops)
machine_mode
preferred_simd_mode (scalar_mode mode)
{
- /* We will disable auto-vectorization when TARGET_MIN_VLEN < 128 &&
- riscv_autovec_lmul < RVV_M2. Since GCC loop vectorizer report ICE when we
- enable -march=rv64gc_zve32* and -march=rv32gc_zve64*. in the
- 'can_duplicate_and_interleave_p' of tree-vect-slp.cc. Since both
- RVVM1SImode in -march=*zve32*_zvl32b and RVVM1DImode in
- -march=*zve64*_zvl64b are NUNITS = poly (1, 1), they will cause ICE in loop
- vectorizer when we enable them in this target hook. Currently, we can
- support auto-vectorization in -march=rv32_zve32x_zvl128b. Wheras,
- -march=rv32_zve32x_zvl32b or -march=rv32_zve32x_zvl64b are disabled. */
if (autovec_use_vlmax_p ())
{
- if (TARGET_MIN_VLEN < 128 && TARGET_MAX_LMUL < RVV_M2)
- return word_mode;
/* We use LMUL = 1 as base bytesize which is BYTES_PER_RISCV_VECTOR and
riscv_autovec_lmul as multiply factor to calculate the the NUNITS to
get the auto-vectorization mode. */
poly_uint64 nunits;
poly_uint64 vector_size = BYTES_PER_RISCV_VECTOR * TARGET_MAX_LMUL;
poly_uint64 scalar_size = GET_MODE_SIZE (mode);
- gcc_assert (multiple_p (vector_size, scalar_size, &nunits));
+ /* Disable vectorization when we can't find a RVV mode for it.
+ E.g. -march=rv64gc_zve32x doesn't have a vector mode to vectorize
+ a double (DFmode) type. */
+ if (!multiple_p (vector_size, scalar_size, &nunits))
+ return word_mode;
machine_mode rvv_mode;
if (get_vector_mode (mode, nunits).exists (&rvv_mode))
return rvv_mode;
}
- /* TODO: We will support minimum length VLS auto-vectorization in
- the future. */
return word_mode;
}
@@ -2689,15 +2674,21 @@ expand_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1,
return false;
}
-/* Modulo all SEL indices to ensure they are all in range if [0, MAX_SEL]. */
+/* Modulo all SEL indices to ensure they are all in range if [0, MAX_SEL].
+ MAX_SEL is nunits - 1 if rtx_equal_p (op0, op1). Otherwise, it is
+ 2 * nunits - 1. */
static rtx
-modulo_sel_indices (rtx sel, poly_uint64 max_sel)
+modulo_sel_indices (rtx op0, rtx op1, rtx sel)
{
rtx sel_mod;
machine_mode sel_mode = GET_MODE (sel);
poly_uint64 nunits = GET_MODE_NUNITS (sel_mode);
- /* If SEL is variable-length CONST_VECTOR, we don't need to modulo it. */
- if (!nunits.is_constant () && CONST_VECTOR_P (sel))
+ poly_uint64 max_sel = rtx_equal_p (op0, op1) ? nunits - 1 : 2 * nunits - 1;
+ /* If SEL is variable-length CONST_VECTOR, we don't need to modulo it.
+ Or if SEL is constant-length within [0, MAX_SEL], no need to modulo the
+ indice. */
+ if (CONST_VECTOR_P (sel)
+ && (!nunits.is_constant () || const_vec_all_in_range_p (sel, 0, max_sel)))
sel_mod = sel;
else
{
@@ -2747,9 +2738,7 @@ expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
out-of-range indices, so we need to modulo all the vec_perm indices
to ensure they are all in range of [0, nunits - 1] when op0 == op1
or all in range of [0, 2 * nunits - 1] when op0 != op1. */
- rtx sel_mod
- = modulo_sel_indices (sel,
- rtx_equal_p (op0, op1) ? nunits - 1 : 2 * nunits - 1);
+ rtx sel_mod = modulo_sel_indices (op0, op1, sel);
/* Check if the two values vectors are the same. */
if (rtx_equal_p (op0, op1))
@@ -2758,15 +2747,13 @@ expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
return;
}
- rtx max_sel = gen_const_vector_dup (sel_mode, 2 * nunits - 1);
-
/* This following sequence is handling the case that:
__builtin_shufflevector (vec1, vec2, index...), the index can be any
value in range of [0, 2 * nunits - 1]. */
machine_mode mask_mode;
mask_mode = get_mask_mode (data_mode);
rtx mask = gen_reg_rtx (mask_mode);
- max_sel = gen_const_vector_dup (sel_mode, nunits);
+ rtx max_sel = gen_const_vector_dup (sel_mode, nunits);
/* Step 1: generate a mask that should select everything >= nunits into the
* mask. */
@@ -2991,14 +2978,15 @@ shuffle_compress_patterns (struct expand_vec_perm_d *d)
if (compress_point < 0)
return false;
- /* It must be series increasing from compress point. */
- if (!d->perm.series_p (compress_point, 1, d->perm[compress_point], 1))
- return false;
-
/* We can only apply compress approach when all index values from 0 to
compress point are increasing. */
for (int i = 1; i < compress_point; i++)
- if (known_le (d->perm[i], d->perm[i - 1]))
+ if (maybe_le (d->perm[i], d->perm[i - 1]))
+ return false;
+
+ /* It must be series increasing from compress point. */
+ for (int i = 1 + compress_point; i < vlen; i++)
+ if (maybe_ne (d->perm[i], d->perm[i - 1] + 1))
return false;
/* Success! */
@@ -3066,10 +3054,10 @@ shuffle_compress_patterns (struct expand_vec_perm_d *d)
if (need_slideup_p)
{
int slideup_cnt = vlen - (d->perm[vlen - 1].to_constant () % vlen) - 1;
- rtx ops[] = {d->target, d->op1, gen_int_mode (slideup_cnt, Pmode)};
+ merge = gen_reg_rtx (vmode);
+ rtx ops[] = {merge, d->op1, gen_int_mode (slideup_cnt, Pmode)};
insn_code icode = code_for_pred_slide (UNSPEC_VSLIDEUP, vmode);
emit_vlmax_insn (icode, BINARY_OP, ops);
- merge = d->target;
}
insn_code icode = code_for_pred_compress (vmode);
@@ -3204,6 +3192,11 @@ shuffle_bswap_pattern (struct expand_vec_perm_d *d)
if (!d->perm.series_p (i, step, diff - i, step))
return false;
+ /* Disable when nunits < 4 since the later generic approach
+ is more profitable on BSWAP. */
+ if (!known_gt (GET_MODE_NUNITS (d->vmode), 2))
+ return false;
+
if (d->testing_p)
return true;
@@ -3235,6 +3228,42 @@ shuffle_bswap_pattern (struct expand_vec_perm_d *d)
return true;
}
+/* Recognize the pattern that can be shuffled by vec_extract and slide1up
+ approach. */
+
+static bool
+shuffle_extract_and_slide1up_patterns (struct expand_vec_perm_d *d)
+{
+ poly_int64 nunits = GET_MODE_NUNITS (d->vmode);
+
+ /* Recognize { nunits - 1, nunits, nunits + 1, ... }. */
+ if (!d->perm.series_p (0, 2, nunits - 1, 2)
+ || !d->perm.series_p (1, 2, nunits, 2))
+ return false;
+
+ /* Disable when nunits < 4 since the later generic approach
+ is more profitable on indice = { nunits - 1, nunits }. */
+ if (!known_gt (nunits, 2))
+ return false;
+
+ /* Success! */
+ if (d->testing_p)
+ return true;
+
+ /* Extract the last element of the first vector. */
+ scalar_mode smode = GET_MODE_INNER (d->vmode);
+ rtx tmp = gen_reg_rtx (smode);
+ emit_vec_extract (tmp, d->op0, nunits - 1);
+
+ /* Insert the scalar into element 0. */
+ unsigned int unspec
+ = FLOAT_MODE_P (d->vmode) ? UNSPEC_VFSLIDE1UP : UNSPEC_VSLIDE1UP;
+ insn_code icode = code_for_pred_slide (unspec, d->vmode);
+ rtx ops[] = {d->target, d->op1, tmp};
+ emit_vlmax_insn (icode, BINARY_OP, ops);
+ return true;
+}
+
/* Recognize the pattern that can be shuffled by generic approach. */
static bool
@@ -3247,20 +3276,35 @@ shuffle_generic_patterns (struct expand_vec_perm_d *d)
if (!pow2p_hwi (d->perm.encoding().npatterns ()))
return false;
- /* Permuting two SEW8 variable-length vectors need vrgatherei16.vv.
- Otherwise, it could overflow the index range. */
- if (!nunits.is_constant () && GET_MODE_INNER (d->vmode) == QImode
- && !get_vector_mode (HImode, nunits).exists (&sel_mode))
- return false;
+ if (GET_MODE_INNER (d->vmode) == QImode)
+ {
+ if (nunits.is_constant ())
+ {
+ /* If indice is LMUL8 CONST_VECTOR and any element value
+ exceed the range of 0 ~ 255, Forbid such permutation
+ since we need vector HI mode to hold such indice and
+ we don't have it. */
+ if (!d->perm.all_in_range_p (0, 255)
+ && !get_vector_mode (HImode, nunits).exists (&sel_mode))
+ return false;
+ }
+ else
+ {
+ /* Permuting two SEW8 variable-length vectors need vrgatherei16.vv.
+ Otherwise, it could overflow the index range. */
+ if (!get_vector_mode (HImode, nunits).exists (&sel_mode))
+ return false;
+ }
+ }
+ else if (riscv_get_v_regno_alignment (sel_mode) > 1
+ && GET_MODE_INNER (sel_mode) != HImode)
+ sel_mode = get_vector_mode (HImode, nunits).require ();
/* Success! */
if (d->testing_p)
return true;
rtx sel = vec_perm_indices_to_rtx (sel_mode, d->perm);
- /* 'mov<mode>' generte interleave vector. */
- if (!nunits.is_constant ())
- sel = force_reg (sel_mode, sel);
/* Some FIXED-VLMAX/VLS vector permutation situations call targethook
instead of expand vec_perm<mode>, we handle it directly. */
expand_vec_perm (d->target, d->op0, d->op1, sel);
@@ -3298,6 +3342,8 @@ expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
return true;
if (shuffle_bswap_pattern (d))
return true;
+ if (shuffle_extract_and_slide1up_patterns (d))
+ return true;
if (shuffle_generic_patterns (d))
return true;
return false;
@@ -3630,7 +3676,7 @@ expand_gather_scatter (rtx *ops, bool is_load)
offset elements.
RVV spec only refers to the scale_log == 0 case. */
- if (!zero_extend_p || (zero_extend_p && scale_log2 != 0))
+ if (!zero_extend_p || scale_log2 != 0)
{
if (zero_extend_p)
inner_idx_mode
@@ -4005,14 +4051,6 @@ vls_mode_valid_p (machine_mode vls_mode)
return false;
}
-/* Return true if the gather/scatter offset mode is valid. */
-bool
-gather_scatter_valid_offset_mode_p (machine_mode mode)
-{
- machine_mode new_mode;
- return get_vector_mode (Pmode, GET_MODE_NUNITS (mode)).exists (&new_mode);
-}
-
/* We don't have to convert the floating point to integer when the
mantissa is zero. Thus, ther will be a limitation for both the
single and double precision floating point. There will be no
@@ -4617,4 +4655,26 @@ can_be_broadcasted_p (rtx op)
return can_create_pseudo_p () && nonmemory_operand (op, mode);
}
+/* Helper function to emit vec_extract_optab. */
+void
+emit_vec_extract (rtx target, rtx src, poly_int64 index)
+{
+ machine_mode vmode = GET_MODE (src);
+ machine_mode smode = GET_MODE (target);
+ class expand_operand ops[3];
+ enum insn_code icode
+ = convert_optab_handler (vec_extract_optab, vmode, smode);
+ gcc_assert (icode != CODE_FOR_nothing);
+ create_output_operand (&ops[0], target, smode);
+ ops[0].target = 1;
+ create_input_operand (&ops[1], src, vmode);
+ if (index.is_constant ())
+ create_integer_operand (&ops[2], index);
+ else
+ create_input_operand (&ops[2], gen_int_mode (index, Pmode), Pmode);
+ expand_insn (icode, 3, ops);
+ if (ops[0].value != target)
+ emit_move_insn (target, ops[0].value);
+}
+
} // namespace riscv_vector
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index c2bd1c2..a4fc858 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "calls.h"
#include "function.h"
#include "explow.h"
+#include "ifcvt.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "reload.h"
@@ -249,6 +250,21 @@ struct riscv_integer_op {
The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */
#define RISCV_MAX_INTEGER_OPS 8
+enum riscv_fusion_pairs
+{
+ RISCV_FUSE_NOTHING = 0,
+ RISCV_FUSE_ZEXTW = (1 << 0),
+ RISCV_FUSE_ZEXTH = (1 << 1),
+ RISCV_FUSE_ZEXTWS = (1 << 2),
+ RISCV_FUSE_LDINDEXED = (1 << 3),
+ RISCV_FUSE_LUI_ADDI = (1 << 4),
+ RISCV_FUSE_AUIPC_ADDI = (1 << 5),
+ RISCV_FUSE_LUI_LD = (1 << 6),
+ RISCV_FUSE_AUIPC_LD = (1 << 7),
+ RISCV_FUSE_LDPREINCREMENT = (1 << 8),
+ RISCV_FUSE_ALIGNED_STD = (1 << 9),
+};
+
/* Costs of various operations on the different architectures. */
struct riscv_tune_param
@@ -264,6 +280,7 @@ struct riscv_tune_param
unsigned short fmv_cost;
bool slow_unaligned_access;
bool use_divmod_expansion;
+ unsigned int fusible_ops;
};
@@ -344,6 +361,7 @@ static const struct riscv_tune_param rocket_tune_info = {
8, /* fmv_cost */
true, /* slow_unaligned_access */
false, /* use_divmod_expansion */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
};
/* Costs to use when optimizing for Sifive 7 Series. */
@@ -359,6 +377,7 @@ static const struct riscv_tune_param sifive_7_tune_info = {
8, /* fmv_cost */
true, /* slow_unaligned_access */
false, /* use_divmod_expansion */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
};
/* Costs to use when optimizing for T-HEAD c906. */
@@ -373,7 +392,8 @@ static const struct riscv_tune_param thead_c906_tune_info = {
5, /* memory_cost */
8, /* fmv_cost */
false, /* slow_unaligned_access */
- false /* use_divmod_expansion */
+ false, /* use_divmod_expansion */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
};
/* Costs to use when optimizing for a generic ooo profile. */
@@ -389,6 +409,7 @@ static const struct riscv_tune_param generic_ooo_tune_info = {
4, /* fmv_cost */
false, /* slow_unaligned_access */
false, /* use_divmod_expansion */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
};
/* Costs to use when optimizing for size. */
@@ -404,6 +425,7 @@ static const struct riscv_tune_param optimize_size_tune_info = {
8, /* fmv_cost */
false, /* slow_unaligned_access */
false, /* use_divmod_expansion */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
};
static bool riscv_avoid_shrink_wrapping_separate ();
@@ -1577,6 +1599,14 @@ riscv_const_insns (rtx x)
rtx elt;
if (const_vec_duplicate_p (x, &elt))
{
+ /* We don't allow CONST_VECTOR for DI vector on RV32
+ system since the ELT constant value can not held
+ within a single register to disable reload a DI
+ register vec_duplicate into vmv.v.x. */
+ scalar_mode smode = GET_MODE_INNER (GET_MODE (x));
+ if (maybe_gt (GET_MODE_SIZE (smode), UNITS_PER_WORD)
+ && !immediate_operand (elt, Pmode))
+ return 0;
/* Constants from -16 to 15 can be loaded with vmv.v.i.
The Wc0, Wc1 constraints are already covered by the
vi constraint so we do not need to check them here
@@ -1702,6 +1732,14 @@ riscv_emit_set (rtx target, rtx src)
return target;
}
+/* Emit an instruction of the form (set DEST (CODE X)). */
+
+rtx
+riscv_emit_unary (enum rtx_code code, rtx dest, rtx x)
+{
+ return riscv_emit_set (dest, gen_rtx_fmt_e (code, GET_MODE (dest), x));
+}
+
/* Emit an instruction of the form (set DEST (CODE X Y)). */
rtx
@@ -2578,14 +2616,10 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
nunits = nunits * 2;
}
vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
- enum insn_code icode
- = convert_optab_handler (vec_extract_optab, vmode, smode);
- gcc_assert (icode != CODE_FOR_nothing);
rtx v = gen_lowpart (vmode, SUBREG_REG (src));
for (unsigned int i = 0; i < num; i++)
{
- class expand_operand ops[3];
rtx result;
if (num == 1)
result = dest;
@@ -2593,13 +2627,7 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
result = gen_lowpart (smode, dest);
else
result = gen_reg_rtx (smode);
- create_output_operand (&ops[0], result, smode);
- ops[0].target = 1;
- create_input_operand (&ops[1], v, vmode);
- create_integer_operand (&ops[2], index + i);
- expand_insn (icode, 3, ops);
- if (ops[0].value != result)
- emit_move_insn (result, ops[0].value);
+ riscv_vector::emit_vec_extract (result, v, index + i);
if (i == 1)
{
@@ -2905,7 +2933,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (SINGLE_SHIFT_COST + 1);
return true;
}
- if (order_operator (XEXP (x, 0), mode))
+ if (ordered_comparison_operator (XEXP (x, 0), mode))
{
*total = COSTS_N_INSNS (1);
return true;
@@ -3295,6 +3323,128 @@ riscv_address_cost (rtx addr, machine_mode mode,
return riscv_address_insns (addr, mode, false);
}
+/* Implement TARGET_INSN_COST. We factor in the branch cost in the cost
+ calculation for conditional branches: one unit is considered the cost
+ of microarchitecture-dependent actual branch execution and therefore
+ multiplied by BRANCH_COST and any remaining units are considered fixed
+ branch overhead. Branches on a floating-point condition incur an extra
+ instruction cost as they will be split into an FCMP operation followed
+ by a branch on an integer condition. */
+
+static int
+riscv_insn_cost (rtx_insn *insn, bool speed)
+{
+ rtx x = PATTERN (insn);
+ int cost = pattern_cost (x, speed);
+
+ if (JUMP_P (insn))
+ {
+ if (GET_CODE (x) == PARALLEL)
+ x = XVECEXP (x, 0, 0);
+ if (GET_CODE (x) == SET
+ && GET_CODE (SET_DEST (x)) == PC
+ && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
+ {
+ cost += COSTS_N_INSNS (BRANCH_COST (speed, false) - 1);
+ if (FLOAT_MODE_P (GET_MODE (XEXP (XEXP (SET_SRC (x), 0), 0))))
+ cost += COSTS_N_INSNS (1);
+ }
+ }
+ return cost;
+}
+
+/* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST. Like the default implementation,
+ but we consider cost units of branch instructions equal to cost units of
+ other instructions. */
+
+static unsigned int
+riscv_max_noce_ifcvt_seq_cost (edge e)
+{
+ bool predictable_p = predictable_edge_p (e);
+
+ if (predictable_p)
+ {
+ if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
+ return param_max_rtl_if_conversion_predictable_cost;
+ }
+ else
+ {
+ if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
+ return param_max_rtl_if_conversion_unpredictable_cost;
+ }
+
+ return COSTS_N_INSNS (BRANCH_COST (true, predictable_p));
+}
+
+/* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We replace the cost of a
+ conditional branch assumed by `noce_find_if_block' at `COSTS_N_INSNS (2)'
+ by our actual conditional branch cost, observing that our branches test
+ conditions directly, so there is no preparatory extra condition-set
+ instruction. */
+
+static bool
+riscv_noce_conversion_profitable_p (rtx_insn *seq,
+ struct noce_if_info *if_info)
+{
+ struct noce_if_info riscv_if_info = *if_info;
+
+ riscv_if_info.original_cost -= COSTS_N_INSNS (2);
+ riscv_if_info.original_cost += insn_cost (if_info->jump, if_info->speed_p);
+
+ /* Hack alert! When `noce_try_store_flag_mask' uses `cstore<mode>4'
+ to emit a conditional set operation on DImode output it comes up
+ with a sequence such as:
+
+ (insn 26 0 27 (set (reg:SI 140)
+ (eq:SI (reg/v:DI 137 [ c ])
+ (const_int 0 [0]))) 302 {*seq_zero_disi}
+ (nil))
+ (insn 27 26 28 (set (reg:DI 139)
+ (zero_extend:DI (reg:SI 140))) 116 {*zero_extendsidi2_internal}
+ (nil))
+
+ because our `cstore<mode>4' pattern expands to an insn that gives
+ a SImode output. The output of conditional set is 0 or 1 boolean,
+ so it is valid for input in any scalar integer mode and therefore
+ combine later folds the zero extend operation into an equivalent
+ conditional set operation that produces a DImode output, however
+ this redundant zero extend operation counts towards the cost of
+ the replacement sequence. Compensate for that by incrementing the
+ cost of the original sequence as well as the maximum sequence cost
+ accordingly. */
+ rtx last_dest = NULL_RTX;
+ for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
+ {
+ if (!NONDEBUG_INSN_P (insn))
+ continue;
+
+ rtx x = PATTERN (insn);
+ if (NONJUMP_INSN_P (insn)
+ && GET_CODE (x) == SET)
+ {
+ rtx src = SET_SRC (x);
+ if (last_dest != NULL_RTX
+ && GET_CODE (src) == ZERO_EXTEND
+ && REG_P (XEXP (src, 0))
+ && REGNO (XEXP (src, 0)) == REGNO (last_dest))
+ {
+ riscv_if_info.original_cost += COSTS_N_INSNS (1);
+ riscv_if_info.max_seq_cost += COSTS_N_INSNS (1);
+ }
+ last_dest = NULL_RTX;
+ rtx dest = SET_DEST (x);
+ if (COMPARISON_P (src)
+ && REG_P (dest)
+ && GET_MODE (dest) == SImode)
+ last_dest = dest;
+ }
+ else
+ last_dest = NULL_RTX;
+ }
+
+ return default_noce_conversion_profitable_p (seq, &riscv_if_info);
+}
+
/* Return one word of double-word value OP. HIGH_P is true to select the
high part or false to select the low part. */
@@ -3779,6 +3929,7 @@ riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1,
*op1 = const0_rtx;
return;
}
+ gcc_unreachable ();
}
if (splittable_const_int_operand (*op1, VOIDmode))
@@ -3833,7 +3984,8 @@ riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1,
/* Like riscv_emit_int_compare, but for floating-point comparisons. */
static void
-riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
+riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1,
+ bool *invert_ptr = nullptr)
{
rtx tmp0, tmp1, cmp_op0 = *op0, cmp_op1 = *op1;
enum rtx_code fp_code = *code;
@@ -3898,8 +4050,14 @@ riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
case NE:
fp_code = EQ;
- *code = EQ;
- /* Fall through. */
+ if (invert_ptr != nullptr)
+ *invert_ptr = !*invert_ptr;
+ else
+ {
+ cmp_op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
+ cmp_op1 = const0_rtx;
+ }
+ gcc_fallthrough ();
case EQ:
case LE:
@@ -3907,8 +4065,9 @@ riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
case GE:
case GT:
/* We have instructions for these cases. */
- *op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
- *op1 = const0_rtx;
+ *code = fp_code;
+ *op0 = cmp_op0;
+ *op1 = cmp_op1;
break;
case LTGT:
@@ -3944,12 +4103,19 @@ riscv_expand_int_scc (rtx target, enum rtx_code code, rtx op0, rtx op1, bool *in
/* Like riscv_expand_int_scc, but for floating-point comparisons. */
void
-riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
+riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1,
+ bool *invert_ptr)
{
- riscv_emit_float_compare (&code, &op0, &op1);
+ riscv_emit_float_compare (&code, &op0, &op1, invert_ptr);
- rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
- riscv_emit_set (target, lowpart_subreg (SImode, cmp, word_mode));
+ machine_mode mode = GET_MODE (target);
+ if (mode != word_mode)
+ {
+ rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
+ riscv_emit_set (target, lowpart_subreg (mode, cmp, word_mode));
+ }
+ else
+ riscv_emit_binary (code, target, op0, op1);
}
/* Jump to LABEL if (CODE OP0 OP1) holds. */
@@ -3962,6 +4128,13 @@ riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1)
else
riscv_emit_int_compare (&code, &op0, &op1);
+ if (FLOAT_MODE_P (GET_MODE (op0)))
+ {
+ op0 = riscv_force_binary (word_mode, code, op0, op1);
+ op1 = const0_rtx;
+ code = NE;
+ }
+
rtx condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
emit_jump_insn (gen_condjump (condition, label));
}
@@ -3976,87 +4149,105 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
rtx_code code = GET_CODE (op);
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
- bool need_eq_ne_p = false;
-
- if (TARGET_XTHEADCONDMOV
- && GET_MODE_CLASS (mode) == MODE_INT
- && reg_or_0_operand (cons, mode)
- && reg_or_0_operand (alt, mode)
- && (GET_MODE (op) == mode || GET_MODE (op) == E_VOIDmode)
- && GET_MODE (op0) == mode
- && GET_MODE (op1) == mode
- && (code == EQ || code == NE))
- need_eq_ne_p = true;
-
- if (need_eq_ne_p
- || (TARGET_SFB_ALU && GET_MODE (op0) == word_mode))
- {
- riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
- rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
-
- /* The expander is a bit loose in its specification of the true
- arm of the conditional move. That allows us to support more
- cases for extensions which are more general than SFB. But
- does mean we need to force CONS into a register at this point. */
- cons = force_reg (GET_MODE (dest), cons);
- emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
- cond, cons, alt)));
- return true;
- }
- else if (TARGET_ZICOND_LIKE
- && GET_MODE_CLASS (mode) == MODE_INT)
+
+ if (((TARGET_ZICOND_LIKE
+ || (arith_operand (cons, mode) && arith_operand (alt, mode)))
+ && (GET_MODE_CLASS (mode) == MODE_INT))
+ || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
{
- /* The comparison must be comparing WORD_MODE objects. We must
- enforce that so that we don't strip away a sign_extension
+ machine_mode mode0 = GET_MODE (op0);
+ machine_mode mode1 = GET_MODE (op1);
+
+ /* An integer comparison must be comparing WORD_MODE objects. We
+ must enforce that so that we don't strip away a sign_extension
thinking it is unnecessary. We might consider using
riscv_extend_operands if they are not already properly extended. */
- if ((GET_MODE (op0) != word_mode && GET_MODE (op0) != VOIDmode)
- || (GET_MODE (op1) != word_mode && GET_MODE (op1) != VOIDmode))
+ if ((INTEGRAL_MODE_P (mode0) && mode0 != word_mode)
+ || (INTEGRAL_MODE_P (mode1) && mode1 != word_mode))
return false;
+ /* In the fallback generic case use MODE rather than WORD_MODE for
+ the output of the SCC instruction, to match the mode of the NEG
+ operation below. The output of SCC is 0 or 1 boolean, so it is
+ valid for input in any scalar integer mode. */
+ rtx tmp = gen_reg_rtx ((TARGET_ZICOND_LIKE
+ || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+ ? word_mode : mode);
+ bool invert = false;
+
/* Canonicalize the comparison. It must be an equality comparison
- against 0. If it isn't, then emit an SCC instruction so that
- we can then use an equality comparison against zero. */
- if (!equality_operator (op, VOIDmode) || op1 != CONST0_RTX (mode))
+ of integer operands, or with SFB it can be any comparison of
+ integer operands. If it isn't, then emit an SCC instruction
+ so that we can then use an equality comparison against zero. */
+ if ((!TARGET_SFB_ALU && !equality_operator (op, VOIDmode))
+ || !INTEGRAL_MODE_P (mode0))
{
- enum rtx_code new_code = NE;
- bool *invert_ptr = 0;
- bool invert = false;
+ bool *invert_ptr = nullptr;
- if (code == LE || code == GE)
+ /* If riscv_expand_int_scc inverts the condition, then it will
+ flip the value of INVERT. We need to know where so that
+ we can adjust it for our needs. */
+ if (code == LE || code == LEU || code == GE || code == GEU)
invert_ptr = &invert;
- /* Emit an scc like instruction into a temporary
- so that we can use an EQ/NE comparison. */
- rtx tmp = gen_reg_rtx (word_mode);
-
- /* We can support both FP and integer conditional moves. */
- if (INTEGRAL_MODE_P (GET_MODE (XEXP (op, 0))))
+ /* Emit an SCC-like instruction into a temporary so that we can
+ use an EQ/NE comparison. We can support both FP and integer
+ conditional moves. */
+ if (INTEGRAL_MODE_P (mode0))
riscv_expand_int_scc (tmp, code, op0, op1, invert_ptr);
- else if (FLOAT_MODE_P (GET_MODE (XEXP (op, 0)))
+ else if (FLOAT_MODE_P (mode0)
&& fp_scc_comparison (op, GET_MODE (op)))
- riscv_expand_float_scc (tmp, code, op0, op1);
+ riscv_expand_float_scc (tmp, code, op0, op1, &invert);
else
return false;
- /* If riscv_expand_int_scc inverts the condition, then it will
- flip the value of INVERT. We need to know where so that
- we can adjust it for our needs. */
- if (invert)
- new_code = EQ;
-
- op = gen_rtx_fmt_ee (new_code, mode, tmp, const0_rtx);
+ op = gen_rtx_fmt_ee (invert ? EQ : NE, mode, tmp, const0_rtx);
/* We've generated a new comparison. Update the local variables. */
code = GET_CODE (op);
op0 = XEXP (op, 0);
op1 = XEXP (op, 1);
}
+ else if (!TARGET_ZICOND_LIKE && !TARGET_SFB_ALU && !TARGET_XTHEADCONDMOV)
+ riscv_expand_int_scc (tmp, code, op0, op1, &invert);
+
+ if (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+
+ /* The expander is a bit loose in its specification of the true
+ arm of the conditional move. That allows us to support more
+ cases for extensions which are more general than SFB. But
+ does mean we need to force CONS into a register at this point. */
+ cons = force_reg (mode, cons);
+ /* With XTheadCondMov we need to force ALT into a register too. */
+ alt = force_reg (mode, alt);
+ emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
+ else if (!TARGET_ZICOND_LIKE)
+ {
+ if (invert)
+ std::swap (cons, alt);
+ rtx reg1 = gen_reg_rtx (mode);
+ rtx reg2 = gen_reg_rtx (mode);
+ rtx reg3 = gen_reg_rtx (mode);
+ rtx reg4 = gen_reg_rtx (mode);
+
+ riscv_emit_unary (NEG, reg1, tmp);
+ riscv_emit_binary (AND, reg2, reg1, cons);
+ riscv_emit_unary (NOT, reg3, reg1);
+ riscv_emit_binary (AND, reg4, reg3, alt);
+ riscv_emit_binary (IOR, dest, reg2, reg4);
+ return true;
+ }
/* 0, reg or 0, imm */
- if (cons == CONST0_RTX (mode)
- && (REG_P (alt)
- || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
+ else if (cons == CONST0_RTX (mode)
+ && (REG_P (alt)
+ || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
{
riscv_emit_int_compare (&code, &op0, &op1, true);
rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
@@ -7794,6 +7985,259 @@ riscv_sched_variable_issue (FILE *, int, rtx_insn *insn, int more)
return more - 1;
}
+/* Implement TARGET_SCHED_MACRO_FUSION_P. Return true if target supports
+ instruction fusion of some sort. */
+
+static bool
+riscv_macro_fusion_p (void)
+{
+ return tune_param->fusible_ops != RISCV_FUSE_NOTHING;
+}
+
+/* Return true iff the instruction fusion described by OP is enabled. */
+
+static bool
+riscv_fusion_enabled_p(enum riscv_fusion_pairs op)
+{
+ return tune_param->fusible_ops & op;
+}
+
+/* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR
+ should be kept together during scheduling. */
+
+static bool
+riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
+{
+ rtx prev_set = single_set (prev);
+ rtx curr_set = single_set (curr);
+ /* prev and curr are simple SET insns i.e. no flag setting or branching. */
+ bool simple_sets_p = prev_set && curr_set && !any_condjump_p (curr);
+
+ if (!riscv_macro_fusion_p ())
+ return false;
+
+ if (simple_sets_p && (riscv_fusion_enabled_p (RISCV_FUSE_ZEXTW) ||
+ riscv_fusion_enabled_p (RISCV_FUSE_ZEXTH)))
+ {
+ /* We are trying to match the following:
+ prev (slli) == (set (reg:DI rD)
+ (ashift:DI (reg:DI rS) (const_int 32)))
+ curr (slri) == (set (reg:DI rD)
+ (lshiftrt:DI (reg:DI rD) (const_int <shift>)))
+ with <shift> being either 32 for FUSE_ZEXTW, or
+ `less than 32 for FUSE_ZEXTWS. */
+
+ if (GET_CODE (SET_SRC (prev_set)) == ASHIFT
+ && GET_CODE (SET_SRC (curr_set)) == LSHIFTRT
+ && REG_P (SET_DEST (prev_set))
+ && REG_P (SET_DEST (curr_set))
+ && REGNO (SET_DEST (prev_set)) == REGNO (SET_DEST (curr_set))
+ && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO(SET_DEST (curr_set))
+ && CONST_INT_P (XEXP (SET_SRC (prev_set), 1))
+ && CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
+ && INTVAL (XEXP (SET_SRC (prev_set), 1)) == 32
+ && (( INTVAL (XEXP (SET_SRC (curr_set), 1)) == 32
+ && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTW) )
+ || ( INTVAL (XEXP (SET_SRC (curr_set), 1)) < 32
+ && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTWS))))
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ZEXTH))
+ {
+ /* We are trying to match the following:
+ prev (slli) == (set (reg:DI rD)
+ (ashift:DI (reg:DI rS) (const_int 48)))
+ curr (slri) == (set (reg:DI rD)
+ (lshiftrt:DI (reg:DI rD) (const_int 48))) */
+
+ if (GET_CODE (SET_SRC (prev_set)) == ASHIFT
+ && GET_CODE (SET_SRC (curr_set)) == LSHIFTRT
+ && REG_P (SET_DEST (prev_set))
+ && REG_P (SET_DEST (curr_set))
+ && REGNO (SET_DEST (prev_set)) == REGNO (SET_DEST (curr_set))
+ && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO(SET_DEST (curr_set))
+ && CONST_INT_P (XEXP (SET_SRC (prev_set), 1))
+ && CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
+ && INTVAL (XEXP (SET_SRC (prev_set), 1)) == 48
+ && INTVAL (XEXP (SET_SRC (curr_set), 1)) == 48)
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDINDEXED))
+ {
+ /* We are trying to match the following:
+ prev (add) == (set (reg:DI rD)
+ (plus:DI (reg:DI rS1) (reg:DI rS2))
+ curr (ld) == (set (reg:DI rD)
+ (mem:DI (reg:DI rD))) */
+
+ if (MEM_P (SET_SRC (curr_set))
+ && REG_P (XEXP (SET_SRC (curr_set), 0))
+ && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO (SET_DEST (prev_set))
+ && GET_CODE (SET_SRC (prev_set)) == PLUS
+ && REG_P (XEXP (SET_SRC (prev_set), 0))
+ && REG_P (XEXP (SET_SRC (prev_set), 1)))
+ return true;
+
+ /* We are trying to match the following:
+ prev (add) == (set (reg:DI rD)
+ (plus:DI (reg:DI rS1) (reg:DI rS2)))
+ curr (lw) == (set (any_extend:DI (mem:SUBX (reg:DI rD)))) */
+
+ if ((GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND
+ || (GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND))
+ && MEM_P (XEXP (SET_SRC (curr_set), 0))
+ && REG_P (XEXP (XEXP (SET_SRC (curr_set), 0), 0))
+ && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == REGNO (SET_DEST (prev_set))
+ && GET_CODE (SET_SRC (prev_set)) == PLUS
+ && REG_P (XEXP (SET_SRC (prev_set), 0))
+ && REG_P (XEXP (SET_SRC (prev_set), 1)))
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDPREINCREMENT))
+ {
+ /* We are trying to match the following:
+ prev (add) == (set (reg:DI rS)
+ (plus:DI (reg:DI rS) (const_int))
+ curr (ld) == (set (reg:DI rD)
+ (mem:DI (reg:DI rS))) */
+
+ if (MEM_P (SET_SRC (curr_set))
+ && REG_P (XEXP (SET_SRC (curr_set), 0))
+ && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO (SET_DEST (prev_set))
+ && GET_CODE (SET_SRC (prev_set)) == PLUS
+ && REG_P (XEXP (SET_SRC (prev_set), 0))
+ && CONST_INT_P (XEXP (SET_SRC (prev_set), 1)))
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_ADDI))
+ {
+ /* We are trying to match the following:
+ prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20))
+ curr (addi) == (set (reg:DI rD)
+ (plus:DI (reg:DI rD) (const_int IMM12))) */
+
+ if ((GET_CODE (SET_SRC (curr_set)) == LO_SUM
+ || (GET_CODE (SET_SRC (curr_set)) == PLUS
+ && CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
+ && SMALL_OPERAND (INTVAL (XEXP (SET_SRC (curr_set), 1)))))
+ && (GET_CODE (SET_SRC (prev_set)) == HIGH
+ || (CONST_INT_P (SET_SRC (prev_set))
+ && LUI_OPERAND (INTVAL (SET_SRC (prev_set))))))
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_ADDI))
+ {
+ /* We are trying to match the following:
+ prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
+ curr (addi) == (set (reg:DI rD)
+ (plus:DI (reg:DI rD) (const_int IMM12)))
+ and
+ prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
+ curr (addi) == (set (reg:DI rD)
+ (lo_sum:DI (reg:DI rD) (const_int IMM12))) */
+
+ if (GET_CODE (SET_SRC (prev_set)) == UNSPEC
+ && XINT (prev_set, 1) == UNSPEC_AUIPC
+ && (GET_CODE (SET_SRC (curr_set)) == LO_SUM
+ || (GET_CODE (SET_SRC (curr_set)) == PLUS
+ && SMALL_OPERAND (INTVAL (XEXP (SET_SRC (curr_set), 1))))))
+
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_LD))
+ {
+ /* We are trying to match the following:
+ prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20))
+ curr (ld) == (set (reg:DI rD)
+ (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */
+
+ if (CONST_INT_P (SET_SRC (prev_set))
+ && LUI_OPERAND (INTVAL (SET_SRC (prev_set)))
+ && MEM_P (SET_SRC (curr_set))
+ && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS)
+ return true;
+
+ if (GET_CODE (SET_SRC (prev_set)) == HIGH
+ && MEM_P (SET_SRC (curr_set))
+ && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == LO_SUM
+ && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)))
+ return true;
+
+ if (GET_CODE (SET_SRC (prev_set)) == HIGH
+ && (GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND
+ || GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND)
+ && MEM_P (XEXP (SET_SRC (curr_set), 0))
+ && (GET_CODE (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == LO_SUM
+ && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (XEXP (XEXP (SET_SRC (curr_set), 0), 0), 0))))
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_LD))
+ {
+ /* We are trying to match the following:
+ prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
+ curr (ld) == (set (reg:DI rD)
+ (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */
+
+ if (GET_CODE (SET_SRC (prev_set)) == UNSPEC
+ && XINT (prev_set, 1) == UNSPEC_AUIPC
+ && MEM_P (SET_SRC (curr_set))
+ && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS)
+ return true;
+ }
+
+ if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ALIGNED_STD))
+ {
+ /* We are trying to match the following:
+ prev (sd) == (set (mem (plus (reg sp|fp) (const_int)))
+ (reg rS1))
+ curr (sd) == (set (mem (plus (reg sp|fp) (const_int)))
+ (reg rS2)) */
+
+ if (MEM_P (SET_DEST (prev_set))
+ && MEM_P (SET_DEST (curr_set))
+ /* We can probably relax this condition. The documentation is a bit
+ unclear about sub-word cases. So we just model DImode for now. */
+ && GET_MODE (SET_DEST (curr_set)) == DImode
+ && GET_MODE (SET_DEST (prev_set)) == DImode)
+ {
+ rtx base_prev, base_curr, offset_prev, offset_curr;
+
+ extract_base_offset_in_addr (SET_DEST (prev_set), &base_prev, &offset_prev);
+ extract_base_offset_in_addr (SET_DEST (curr_set), &base_curr, &offset_curr);
+
+ /* The two stores must be contained within opposite halves of the same
+ 16 byte aligned block of memory. We know that the stack pointer and
+ the frame pointer have suitable alignment. So we just need to check
+ the offsets of the two stores for suitable alignment.
+
+ Originally the thought was to check MEM_ALIGN, but that was reporting
+ incorrect alignments, even for SP/FP accesses, so we gave up on that
+ approach. */
+ if (base_prev != NULL_RTX
+ && base_curr != NULL_RTX
+ && REG_P (base_prev)
+ && REG_P (base_curr)
+ && REGNO (base_prev) == REGNO (base_curr)
+ && (REGNO (base_prev) == STACK_POINTER_REGNUM
+ || REGNO (base_prev) == HARD_FRAME_POINTER_REGNUM)
+ && ((INTVAL (offset_prev) == INTVAL (offset_curr) + 8
+ && (INTVAL (offset_prev) % 16) == 0)
+ || ((INTVAL (offset_curr) == INTVAL (offset_prev) + 8)
+ && (INTVAL (offset_curr) % 16) == 0)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Adjust the cost/latency of instructions for scheduling.
For now this is just used to change the latency of vector instructions
according to their LMUL. We assume that an insn with LMUL == 8 requires
@@ -8225,13 +8669,18 @@ riscv_option_override (void)
error ("requested ABI requires %<-march%> to subsume the %qc extension",
UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
- if (TARGET_RVE && riscv_abi != ABI_ILP32E)
- error ("rv32e requires ilp32e ABI");
+ /* RVE requires specific ABI. */
+ if (TARGET_RVE)
+ if (!TARGET_64BIT && riscv_abi != ABI_ILP32E)
+ error ("rv32e requires ilp32e ABI");
+ else if (TARGET_64BIT && riscv_abi != ABI_LP64E)
+ error ("rv64e requires lp64e ABI");
- // Zfinx require abi ilp32,ilp32e or lp64.
- if (TARGET_ZFINX && riscv_abi != ABI_ILP32
- && riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
- error ("z*inx requires ABI ilp32, ilp32e or lp64");
+ /* Zfinx require abi ilp32, ilp32e, lp64 or lp64e. */
+ if (TARGET_ZFINX
+ && riscv_abi != ABI_ILP32 && riscv_abi != ABI_LP64
+ && riscv_abi != ABI_ILP32E && riscv_abi != ABI_LP64E)
+ error ("z*inx requires ABI ilp32, ilp32e, lp64 or lp64e");
/* We do not yet support ILP32 on RV64. */
if (BITS_PER_WORD != POINTER_SIZE)
@@ -8357,7 +8806,7 @@ static GTY (()) tree riscv_previous_fndecl;
static void
riscv_conditional_register_usage (void)
{
- /* We have only x0~x15 on RV32E. */
+ /* We have only x0~x15 on RV32E/RV64E. */
if (TARGET_RVE)
{
for (int r = 16; r <= 31; r++)
@@ -9780,6 +10229,40 @@ riscv_preferred_else_value (unsigned ifn, tree vectype, unsigned int nops,
return default_preferred_else_value (ifn, vectype, nops, ops);
}
+/* If MEM is in the form of "base+offset", extract the two parts
+ of address and set to BASE and OFFSET, otherwise return false
+ after clearing BASE and OFFSET. */
+
+bool
+extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset)
+{
+ rtx addr;
+
+ gcc_assert (MEM_P (mem));
+
+ addr = XEXP (mem, 0);
+
+ if (REG_P (addr))
+ {
+ *base = addr;
+ *offset = const0_rtx;
+ return true;
+ }
+
+ if (GET_CODE (addr) == PLUS
+ && REG_P (XEXP (addr, 0)) && CONST_INT_P (XEXP (addr, 1)))
+ {
+ *base = XEXP (addr, 0);
+ *offset = XEXP (addr, 1);
+ return true;
+ }
+
+ *base = NULL_RTX;
+ *offset = NULL_RTX;
+
+ return false;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -9802,6 +10285,10 @@ riscv_preferred_else_value (unsigned ifn, tree vectype, unsigned int nops,
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
+#undef TARGET_SCHED_MACRO_FUSION_P
+#define TARGET_SCHED_MACRO_FUSION_P riscv_macro_fusion_p
+#undef TARGET_SCHED_MACRO_FUSION_PAIR_P
+#define TARGET_SCHED_MACRO_FUSION_PAIR_P riscv_macro_fusion_pair_p
#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE riscv_sched_variable_issue
@@ -9823,6 +10310,13 @@ riscv_preferred_else_value (unsigned ifn, tree vectype, unsigned int nops,
#define TARGET_RTX_COSTS riscv_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST riscv_address_cost
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST riscv_insn_cost
+
+#undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
+#define TARGET_MAX_NOCE_IFCVT_SEQ_COST riscv_max_noce_ifcvt_seq_cost
+#undef TARGET_NOCE_CONVERSION_PROFITABLE_P
+#define TARGET_NOCE_CONVERSION_PROFITABLE_P riscv_noce_conversion_profitable_p
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START riscv_file_start
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 6205d75..6df9ec7 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -170,7 +170,7 @@ ASM_MISA_SPEC
/* The largest type that can be passed in floating-point registers. */
#define UNITS_PER_FP_ARG \
((riscv_abi == ABI_ILP32 || riscv_abi == ABI_ILP32E \
- || riscv_abi == ABI_LP64) \
+ || riscv_abi == ABI_LP64 || riscv_abi == ABI_LP64E) \
? 0 \
: ((riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F) ? 4 : 8))
@@ -193,10 +193,15 @@ ASM_MISA_SPEC
/* The smallest supported stack boundary the calling convention supports. */
#define STACK_BOUNDARY \
- (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 2 * BITS_PER_WORD)
+ (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
+ ? BITS_PER_WORD \
+ : 2 * BITS_PER_WORD)
/* The ABI stack alignment. */
-#define ABI_STACK_BOUNDARY (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 128)
+#define ABI_STACK_BOUNDARY \
+ (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
+ ? BITS_PER_WORD \
+ : 128)
/* There is no point aligning anything to a rounder boundary than this. */
#define BIGGEST_ALIGNMENT 128
@@ -669,7 +674,10 @@ enum reg_class
#define GP_RETURN GP_ARG_FIRST
#define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST)
-#define MAX_ARGS_IN_REGISTERS (riscv_abi == ABI_ILP32E ? 6 : 8)
+#define MAX_ARGS_IN_REGISTERS \
+ (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
+ ? 6 \
+ : 8)
#define MAX_ARGS_IN_VECTOR_REGISTERS (16)
#define MAX_ARGS_IN_MASK_REGISTERS (1)
@@ -1138,6 +1146,7 @@ extern poly_int64 riscv_v_adjust_bytesize (enum machine_mode, int);
"%{mabi=ilp32f:ilp32f}" \
"%{mabi=ilp32d:ilp32d}" \
"%{mabi=lp64:lp64}" \
+ "%{mabi=lp64e:lp64e}" \
"%{mabi=lp64f:lp64f}" \
"%{mabi=lp64d:lp64d}" \
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 8f28e8e..935eeb7 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2640,7 +2640,7 @@
(define_insn "*branch<mode>"
[(set (pc)
(if_then_else
- (match_operator 1 "order_operator"
+ (match_operator 1 "ordered_comparison_operator"
[(match_operand:X 2 "register_operand" "r")
(match_operand:X 3 "reg_or_0_operand" "rJ")])
(label_ref (match_operand 0 "" ""))
@@ -2655,14 +2655,15 @@
[(set_attr "type" "branch")
(set_attr "mode" "none")])
-;; Patterns for implementations that optimize short forward branches.
+;; Conditional move and add patterns.
(define_expand "mov<mode>cc"
[(set (match_operand:GPR 0 "register_operand")
(if_then_else:GPR (match_operand 1 "comparison_operator")
- (match_operand:GPR 2 "sfb_alu_operand")
- (match_operand:GPR 3 "sfb_alu_operand")))]
- "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE"
+ (match_operand:GPR 2 "movcc_operand")
+ (match_operand:GPR 3 "movcc_operand")))]
+ "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE
+ || TARGET_MOVCC"
{
if (riscv_expand_conditional_move (operands[0], operands[1],
operands[2], operands[3]))
@@ -2671,10 +2672,51 @@
FAIL;
})
+(define_expand "add<mode>cc"
+ [(match_operand:GPR 0 "register_operand")
+ (match_operand 1 "comparison_operator")
+ (match_operand:GPR 2 "arith_operand")
+ (match_operand:GPR 3 "arith_operand")]
+ "TARGET_MOVCC"
+{
+ rtx cmp = operands[1];
+ rtx cmp0 = XEXP (cmp, 0);
+ rtx cmp1 = XEXP (cmp, 1);
+ machine_mode mode0 = GET_MODE (cmp0);
+
+ /* We only handle word mode integer compares for now. */
+ if (INTEGRAL_MODE_P (mode0) && mode0 != word_mode)
+ FAIL;
+
+ enum rtx_code code = GET_CODE (cmp);
+ rtx reg0 = gen_reg_rtx (<MODE>mode);
+ rtx reg1 = gen_reg_rtx (<MODE>mode);
+ rtx reg2 = gen_reg_rtx (<MODE>mode);
+ bool invert = false;
+
+ if (INTEGRAL_MODE_P (mode0))
+ riscv_expand_int_scc (reg0, code, cmp0, cmp1, &invert);
+ else if (FLOAT_MODE_P (mode0) && fp_scc_comparison (cmp, GET_MODE (cmp)))
+ riscv_expand_float_scc (reg0, code, cmp0, cmp1, &invert);
+ else
+ FAIL;
+
+ if (invert)
+ riscv_emit_binary (PLUS, reg1, reg0, constm1_rtx);
+ else
+ riscv_emit_unary (NEG, reg1, reg0);
+ riscv_emit_binary (AND, reg2, reg1, operands[3]);
+ riscv_emit_binary (PLUS, operands[0], reg2, operands[2]);
+
+ DONE;
+})
+
+;; Patterns for implementations that optimize short forward branches.
+
(define_insn "*mov<GPR:mode><X:mode>cc"
[(set (match_operand:GPR 0 "register_operand" "=r,r")
(if_then_else:GPR
- (match_operator 5 "order_operator"
+ (match_operator 5 "ordered_comparison_operator"
[(match_operand:X 1 "register_operand" "r,r")
(match_operand:X 2 "reg_or_0_operand" "rJ,rJ")])
(match_operand:GPR 3 "register_operand" "0,0")
@@ -2708,20 +2750,89 @@
DONE;
})
-(define_expand "@cbranch<mode>4"
- [(set (pc)
- (if_then_else (match_operator 0 "fp_branch_comparison"
- [(match_operand:ANYF 1 "register_operand")
- (match_operand:ANYF 2 "register_operand")])
- (label_ref (match_operand 3 ""))
- (pc)))]
+(define_expand "@cbranch<ANYF:mode>4"
+ [(parallel [(set (pc)
+ (if_then_else (match_operator 0 "fp_branch_comparison"
+ [(match_operand:ANYF 1 "register_operand")
+ (match_operand:ANYF 2 "register_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))
+ (clobber (match_operand 4 ""))])]
"TARGET_HARD_FLOAT || TARGET_ZFINX"
{
- riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
- operands[1], operands[2]);
- DONE;
+ if (!signed_order_operator (operands[0], GET_MODE (operands[0])))
+ {
+ riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ DONE;
+ }
+ operands[4] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
})
+(define_insn_and_split "*cbranch<ANYF:mode>4"
+ [(set (pc)
+ (if_then_else (match_operator 1 "fp_native_comparison"
+ [(match_operand:ANYF 2 "register_operand" "f")
+ (match_operand:ANYF 3 "register_operand" "f")])
+ (label_ref (match_operand 0 ""))
+ (pc)))
+ (clobber (match_operand:X 4 "register_operand" "=r"))]
+ "TARGET_HARD_FLOAT || TARGET_ZFINX"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_op_dup:X 1 [(match_dup 2) (match_dup 3)]))
+ (set (pc)
+ (if_then_else (ne:X (match_dup 4) (const_int 0))
+ (label_ref (match_operand 0))
+ (pc)))]
+ ""
+ [(set_attr "type" "branch")
+ (set (attr "length")
+ (if_then_else (and (le (minus (match_dup 0) (pc))
+ (const_int 4084))
+ (le (minus (pc) (match_dup 0))
+ (const_int 4096)))
+ (const_int 8)
+ (if_then_else (and (le (minus (match_dup 0) (pc))
+ (const_int 1048564))
+ (le (minus (pc) (match_dup 0))
+ (const_int 1048576)))
+ (const_int 12)
+ (const_int 16))))])
+
+(define_insn_and_split "*cbranch<ANYF:mode>4"
+ [(set (pc)
+ (if_then_else (match_operator 1 "ne_operator"
+ [(match_operand:ANYF 2 "register_operand" "f")
+ (match_operand:ANYF 3 "register_operand" "f")])
+ (label_ref (match_operand 0 ""))
+ (pc)))
+ (clobber (match_operand:X 4 "register_operand" "=r"))]
+ "TARGET_HARD_FLOAT || TARGET_ZFINX"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (eq:X (match_dup 2) (match_dup 3)))
+ (set (pc)
+ (if_then_else (eq:X (match_dup 4) (const_int 0))
+ (label_ref (match_operand 0))
+ (pc)))]
+ ""
+ [(set_attr "type" "branch")
+ (set (attr "length")
+ (if_then_else (and (le (minus (match_dup 0) (pc))
+ (const_int 4084))
+ (le (minus (pc) (match_dup 0))
+ (const_int 4096)))
+ (const_int 8)
+ (if_then_else (and (le (minus (match_dup 0) (pc))
+ (const_int 1048564))
+ (le (minus (pc) (match_dup 0))
+ (const_int 1048576)))
+ (const_int 12)
+ (const_int 16))))])
+
(define_insn_and_split "*branch_on_bit<X:mode>"
[(set (pc)
(if_then_else
@@ -2791,7 +2902,7 @@
(define_expand "cstore<mode>4"
[(set (match_operand:SI 0 "register_operand")
- (match_operator:SI 1 "order_operator"
+ (match_operator:SI 1 "ordered_comparison_operator"
[(match_operand:GPR 2 "register_operand")
(match_operand:GPR 3 "nonmemory_operand")]))]
""
@@ -3301,7 +3412,7 @@
(define_insn "riscv_frcsr"
[(set (match_operand:SI 0 "register_operand" "=r")
- (unspec_volatile [(const_int 0)] UNSPECV_FRCSR))]
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_FRCSR))]
"TARGET_HARD_FLOAT || TARGET_ZFINX"
"frcsr\t%0"
[(set_attr "type" "fmove")])
@@ -3314,7 +3425,7 @@
(define_insn "riscv_frflags"
[(set (match_operand:SI 0 "register_operand" "=r")
- (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_FRFLAGS))]
"TARGET_HARD_FLOAT || TARGET_ZFINX"
"frflags\t%0"
[(set_attr "type" "fmove")])
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 1bd661a..0c6517b 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -65,6 +65,9 @@ EnumValue
Enum(abi_type) String(lp64) Value(ABI_LP64)
EnumValue
+Enum(abi_type) String(lp64e) Value(ABI_LP64E)
+
+EnumValue
Enum(abi_type) String(lp64f) Value(ABI_LP64F)
EnumValue
@@ -460,6 +463,10 @@ misa-spec=
Target RejectNegative Joined Enum(isa_spec_class) Var(riscv_isa_spec) Init(TARGET_DEFAULT_ISA_SPEC)
Set the version of RISC-V ISA spec.
+mmovcc
+Target Var(TARGET_MOVCC)
+Enable conditional moves unconditionally.
+
minline-atomics
Target Var(TARGET_INLINE_SUBWORD_ATOMIC) Init(1)
Always inline subword atomic operations.
@@ -527,3 +534,23 @@ Target Var(TARGET_ADJUST_LMUL_COST) Init(0)
Target Undocumented Bool Var(riscv_vector_abi) Init(0)
Enable the use of vector registers for function arguments and return value.
This is an experimental switch and may be subject to change in the future.
+
+Enum
+Name(riscv_stringop_strategy) Type(enum riscv_stringop_strategy_enum)
+Valid arguments to -mmemcpy-strategy=:
+
+EnumValue
+Enum(riscv_stringop_strategy) String(auto) Value(USE_AUTO)
+
+EnumValue
+Enum(riscv_stringop_strategy) String(libcall) Value(USE_LIBCALL)
+
+EnumValue
+Enum(riscv_stringop_strategy) String(scalar) Value(USE_SCALAR)
+
+EnumValue
+Enum(riscv_stringop_strategy) String(vector) Value(USE_VECTOR)
+
+mmemcpy-strategy=
+Target RejectNegative Joined Enum(riscv_stringop_strategy) Var(riscv_memcpy_strategy) Init(USE_AUTO)
+Specify memcpy expansion strategy.
diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index a485fb1..bd9af7e 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -36,40 +36,6 @@
#include "regs.h"
#include "riscv-protos.h"
-/* If MEM is in the form of "base+offset", extract the two parts
- of address and set to BASE and OFFSET, otherwise return false
- after clearing BASE and OFFSET. */
-
-static bool
-extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset)
-{
- rtx addr;
-
- gcc_assert (MEM_P (mem));
-
- addr = XEXP (mem, 0);
-
- if (REG_P (addr))
- {
- *base = addr;
- *offset = const0_rtx;
- return true;
- }
-
- if (GET_CODE (addr) == PLUS
- && REG_P (XEXP (addr, 0)) && CONST_INT_P (XEXP (addr, 1)))
- {
- *base = XEXP (addr, 0);
- *offset = XEXP (addr, 1);
- return true;
- }
-
- *base = NULL_RTX;
- *offset = NULL_RTX;
-
- return false;
-}
-
/* If X is a PLUS of a CONST_INT, return the two terms in *BASE_PTR
and *OFFSET_PTR. Return X in *BASE_PTR and 0 in *OFFSET_PTR otherwise. */
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 469875c..56080ed 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -319,23 +319,36 @@
(RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16")
(RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32")
- RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32")
+ (RVVM4SI "TARGET_64BIT")
+ (RVVM2SI "TARGET_64BIT")
+ (RVVM1SI "TARGET_64BIT")
+ (RVVMF2SI "TARGET_MIN_VLEN > 32 && TARGET_64BIT")
- (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32")
- (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
+ (RVVM4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_64BIT")
+ (RVVM2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_64BIT")
+ (RVVM1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_64BIT")
+ (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32 && TARGET_64BIT")
])
(define_mode_iterator VEEWTRUNC4 [
RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
- RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32")
+ (RVVM2HI "TARGET_64BIT")
+ (RVVM1HI "TARGET_64BIT")
+ (RVVMF2HI "TARGET_64BIT")
+ (RVVMF4HI "TARGET_MIN_VLEN > 32 && TARGET_64BIT")
- (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16")
- (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32")
+ (RVVM2HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_64BIT")
+ (RVVM1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_64BIT")
+ (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_64BIT")
+ (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32 && TARGET_64BIT")
])
(define_mode_iterator VEEWTRUNC8 [
- RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
+ (RVVM1QI "TARGET_64BIT")
+ (RVVMF2QI "TARGET_64BIT")
+ (RVVMF4QI "TARGET_64BIT")
+ (RVVMF8QI "TARGET_MIN_VLEN > 32 && TARGET_64BIT")
])
(define_mode_iterator VEI16 [
@@ -363,13 +376,13 @@
(V4QI "riscv_vector::vls_mode_valid_p (V4QImode)")
(V8QI "riscv_vector::vls_mode_valid_p (V8QImode)")
(V16QI "riscv_vector::vls_mode_valid_p (V16QImode)")
- (V32QI "riscv_vector::vls_mode_valid_p (V32QImode)")
- (V64QI "riscv_vector::vls_mode_valid_p (V64QImode) && TARGET_MIN_VLEN >= 64")
- (V128QI "riscv_vector::vls_mode_valid_p (V128QImode) && TARGET_MIN_VLEN >= 128")
- (V256QI "riscv_vector::vls_mode_valid_p (V256QImode) && TARGET_MIN_VLEN >= 256")
- (V512QI "riscv_vector::vls_mode_valid_p (V512QImode) && TARGET_MIN_VLEN >= 512")
- (V1024QI "riscv_vector::vls_mode_valid_p (V1024QImode) && TARGET_MIN_VLEN >= 1024")
- (V2048QI "riscv_vector::vls_mode_valid_p (V2048QImode) && TARGET_MIN_VLEN >= 2048")
+ (V32QI "riscv_vector::vls_mode_valid_p (V32QImode) && TARGET_MIN_VLEN >= 64")
+ (V64QI "riscv_vector::vls_mode_valid_p (V64QImode) && TARGET_MIN_VLEN >= 128")
+ (V128QI "riscv_vector::vls_mode_valid_p (V128QImode) && TARGET_MIN_VLEN >= 256")
+ (V256QI "riscv_vector::vls_mode_valid_p (V256QImode) && TARGET_MIN_VLEN >= 512")
+ (V512QI "riscv_vector::vls_mode_valid_p (V512QImode) && TARGET_MIN_VLEN >= 1024")
+ (V1024QI "riscv_vector::vls_mode_valid_p (V1024QImode) && TARGET_MIN_VLEN >= 2048")
+ (V2048QI "riscv_vector::vls_mode_valid_p (V2048QImode) && TARGET_MIN_VLEN >= 4096")
(V1HI "riscv_vector::vls_mode_valid_p (V1HImode)")
(V2HI "riscv_vector::vls_mode_valid_p (V2HImode)")
(V4HI "riscv_vector::vls_mode_valid_p (V4HImode)")
@@ -731,6 +744,17 @@
(RVVM2DI "TARGET_FULL_V") (RVVM1DI "TARGET_FULL_V")
])
+;; All RATIO mode iterators are used on gather/scatter vectorization.
+;; RISC-V V Spec 18.3:
+;; The V extension supports all vector load and store instructions (Section
+;; Vector Loads and Stores), except the V extension does not support EEW=64
+;; for index values when XLEN=32.
+;; According to RVV ISA description above, all RATIO index DI mode need TARGET_64BIT.
+;;
+;; In gather/scatter expand, we need to sign/zero extend the index mode into vector
+;; Pmode, so we need to check whether vector Pmode is available.
+;; E.g. when index mode = RVVM8QImde and Pmode = SImode, if it is not zero_extend or
+;; scalar != 1, such gather/scatter is not allowed since we don't have RVVM32SImode.
(define_mode_iterator RATIO64 [
(RVVMF8QI "TARGET_MIN_VLEN > 32")
(RVVMF4HI "TARGET_MIN_VLEN > 32")
@@ -793,28 +817,28 @@
(RVVMF8QI "TARGET_MIN_VLEN > 32")
(RVVMF4HI "TARGET_MIN_VLEN > 32")
(RVVMF2SI "TARGET_MIN_VLEN > 32")
- (RVVM1DI "TARGET_VECTOR_ELEN_64")
+ (RVVM1DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
])
(define_mode_iterator RATIO32I [
RVVMF4QI
RVVMF2HI
RVVM1SI
- (RVVM2DI "TARGET_VECTOR_ELEN_64")
+ (RVVM2DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
])
(define_mode_iterator RATIO16I [
RVVMF2QI
RVVM1HI
RVVM2SI
- (RVVM4DI "TARGET_VECTOR_ELEN_64")
+ (RVVM4DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
])
(define_mode_iterator RATIO8I [
RVVM1QI
RVVM2HI
RVVM4SI
- (RVVM8DI "TARGET_VECTOR_ELEN_64")
+ (RVVM8DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
])
(define_mode_iterator RATIO4I [
@@ -1421,11 +1445,123 @@
(V1024BI "riscv_vector::vls_mode_valid_p (V1024BImode) && TARGET_MIN_VLEN >= 1024")
(V2048BI "riscv_vector::vls_mode_valid_p (V2048BImode) && TARGET_MIN_VLEN >= 2048")
(V4096BI "riscv_vector::vls_mode_valid_p (V4096BImode) && TARGET_MIN_VLEN >= 4096")])
-
+
(define_mode_iterator VB [
(RVVMF64BI "TARGET_MIN_VLEN > 32") RVVMF32BI RVVMF16BI RVVMF8BI RVVMF4BI RVVMF2BI RVVM1BI
])
+;; Iterator for indexed loads and stores. We must disallow 64-bit indices on
+;; XLEN=32 targets. TODO: Split iterators so more of them can be reused, i.e.
+;; VI8, VI16, VI32, VI64 and then use
+;; VINDEXED [VI8 VI16 VI32 (VI64 "TARGET_64BIT")].
+
+(define_mode_iterator VINDEXED [
+ RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
+
+ RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32")
+
+ RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32")
+
+ (RVVM8DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
+ (RVVM4DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
+ (RVVM2DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
+ (RVVM1DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
+
+ (RVVM8HF "TARGET_ZVFH") (RVVM4HF "TARGET_ZVFH") (RVVM2HF "TARGET_ZVFH")
+ (RVVM1HF "TARGET_ZVFH") (RVVMF2HF "TARGET_ZVFH")
+ (RVVMF4HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
+
+ (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32")
+ (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") (RVVM1SF "TARGET_VECTOR_ELEN_FP_32")
+ (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
+
+ (RVVM8DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_64BIT")
+ (RVVM4DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_64BIT")
+ (RVVM2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_64BIT")
+ (RVVM1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_64BIT")
+
+ (V1QI "riscv_vector::vls_mode_valid_p (V1QImode)")
+ (V2QI "riscv_vector::vls_mode_valid_p (V2QImode)")
+ (V4QI "riscv_vector::vls_mode_valid_p (V4QImode)")
+ (V8QI "riscv_vector::vls_mode_valid_p (V8QImode)")
+ (V16QI "riscv_vector::vls_mode_valid_p (V16QImode)")
+ (V32QI "riscv_vector::vls_mode_valid_p (V32QImode)")
+ (V64QI "riscv_vector::vls_mode_valid_p (V64QImode) && TARGET_MIN_VLEN >= 64")
+ (V128QI "riscv_vector::vls_mode_valid_p (V128QImode) && TARGET_MIN_VLEN >= 128")
+ (V256QI "riscv_vector::vls_mode_valid_p (V256QImode) && TARGET_MIN_VLEN >= 256")
+ (V512QI "riscv_vector::vls_mode_valid_p (V512QImode) && TARGET_MIN_VLEN >= 512")
+ (V1024QI "riscv_vector::vls_mode_valid_p (V1024QImode) && TARGET_MIN_VLEN >= 1024")
+ (V2048QI "riscv_vector::vls_mode_valid_p (V2048QImode) && TARGET_MIN_VLEN >= 2048")
+ (V4096QI "riscv_vector::vls_mode_valid_p (V4096QImode) && TARGET_MIN_VLEN >= 4096")
+ (V1HI "riscv_vector::vls_mode_valid_p (V1HImode)")
+ (V2HI "riscv_vector::vls_mode_valid_p (V2HImode)")
+ (V4HI "riscv_vector::vls_mode_valid_p (V4HImode)")
+ (V8HI "riscv_vector::vls_mode_valid_p (V8HImode)")
+ (V16HI "riscv_vector::vls_mode_valid_p (V16HImode)")
+ (V32HI "riscv_vector::vls_mode_valid_p (V32HImode) && TARGET_MIN_VLEN >= 64")
+ (V64HI "riscv_vector::vls_mode_valid_p (V64HImode) && TARGET_MIN_VLEN >= 128")
+ (V128HI "riscv_vector::vls_mode_valid_p (V128HImode) && TARGET_MIN_VLEN >= 256")
+ (V256HI "riscv_vector::vls_mode_valid_p (V256HImode) && TARGET_MIN_VLEN >= 512")
+ (V512HI "riscv_vector::vls_mode_valid_p (V512HImode) && TARGET_MIN_VLEN >= 1024")
+ (V1024HI "riscv_vector::vls_mode_valid_p (V1024HImode) && TARGET_MIN_VLEN >= 2048")
+ (V2048HI "riscv_vector::vls_mode_valid_p (V2048HImode) && TARGET_MIN_VLEN >= 4096")
+ (V1SI "riscv_vector::vls_mode_valid_p (V1SImode)")
+ (V2SI "riscv_vector::vls_mode_valid_p (V2SImode)")
+ (V4SI "riscv_vector::vls_mode_valid_p (V4SImode)")
+ (V8SI "riscv_vector::vls_mode_valid_p (V8SImode)")
+ (V16SI "riscv_vector::vls_mode_valid_p (V16SImode) && TARGET_MIN_VLEN >= 64")
+ (V32SI "riscv_vector::vls_mode_valid_p (V32SImode) && TARGET_MIN_VLEN >= 128")
+ (V64SI "riscv_vector::vls_mode_valid_p (V64SImode) && TARGET_MIN_VLEN >= 256")
+ (V128SI "riscv_vector::vls_mode_valid_p (V128SImode) && TARGET_MIN_VLEN >= 512")
+ (V256SI "riscv_vector::vls_mode_valid_p (V256SImode) && TARGET_MIN_VLEN >= 1024")
+ (V512SI "riscv_vector::vls_mode_valid_p (V512SImode) && TARGET_MIN_VLEN >= 2048")
+ (V1024SI "riscv_vector::vls_mode_valid_p (V1024SImode) && TARGET_MIN_VLEN >= 4096")
+ (V1DI "riscv_vector::vls_mode_valid_p (V1DImode) && TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
+ (V2DI "riscv_vector::vls_mode_valid_p (V2DImode) && TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
+ (V4DI "riscv_vector::vls_mode_valid_p (V4DImode) && TARGET_VECTOR_ELEN_64 && TARGET_64BIT")
+ (V8DI "riscv_vector::vls_mode_valid_p (V8DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 64 && TARGET_64BIT")
+ (V16DI "riscv_vector::vls_mode_valid_p (V16DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128 && TARGET_64BIT")
+ (V32DI "riscv_vector::vls_mode_valid_p (V32DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 256 && TARGET_64BIT")
+ (V64DI "riscv_vector::vls_mode_valid_p (V64DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 512 && TARGET_64BIT")
+ (V128DI "riscv_vector::vls_mode_valid_p (V128DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 1024 && TARGET_64BIT")
+ (V256DI "riscv_vector::vls_mode_valid_p (V256DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 2048 && TARGET_64BIT")
+ (V512DI "riscv_vector::vls_mode_valid_p (V512DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096 && TARGET_64BIT")
+
+ (V1HF "riscv_vector::vls_mode_valid_p (V1HFmode) && TARGET_ZVFH")
+ (V2HF "riscv_vector::vls_mode_valid_p (V2HFmode) && TARGET_ZVFH")
+ (V4HF "riscv_vector::vls_mode_valid_p (V4HFmode) && TARGET_ZVFH")
+ (V8HF "riscv_vector::vls_mode_valid_p (V8HFmode) && TARGET_ZVFH")
+ (V16HF "riscv_vector::vls_mode_valid_p (V16HFmode) && TARGET_ZVFH")
+ (V32HF "riscv_vector::vls_mode_valid_p (V32HFmode) && TARGET_ZVFH && TARGET_MIN_VLEN >= 64")
+ (V64HF "riscv_vector::vls_mode_valid_p (V64HFmode) && TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
+ (V128HF "riscv_vector::vls_mode_valid_p (V128HFmode) && TARGET_ZVFH && TARGET_MIN_VLEN >= 256")
+ (V256HF "riscv_vector::vls_mode_valid_p (V256HFmode) && TARGET_ZVFH && TARGET_MIN_VLEN >= 512")
+ (V512HF "riscv_vector::vls_mode_valid_p (V512HFmode) && TARGET_ZVFH && TARGET_MIN_VLEN >= 1024")
+ (V1024HF "riscv_vector::vls_mode_valid_p (V1024HFmode) && TARGET_ZVFH && TARGET_MIN_VLEN >= 2048")
+ (V2048HF "riscv_vector::vls_mode_valid_p (V2048HFmode) && TARGET_ZVFH && TARGET_MIN_VLEN >= 4096")
+ (V1SF "riscv_vector::vls_mode_valid_p (V1SFmode) && TARGET_VECTOR_ELEN_FP_32")
+ (V2SF "riscv_vector::vls_mode_valid_p (V2SFmode) && TARGET_VECTOR_ELEN_FP_32")
+ (V4SF "riscv_vector::vls_mode_valid_p (V4SFmode) && TARGET_VECTOR_ELEN_FP_32")
+ (V8SF "riscv_vector::vls_mode_valid_p (V8SFmode) && TARGET_VECTOR_ELEN_FP_32")
+ (V16SF "riscv_vector::vls_mode_valid_p (V16SFmode) && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64")
+ (V32SF "riscv_vector::vls_mode_valid_p (V32SFmode) && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128")
+ (V64SF "riscv_vector::vls_mode_valid_p (V64SFmode) && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 256")
+ (V128SF "riscv_vector::vls_mode_valid_p (V128SFmode) && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 512")
+ (V256SF "riscv_vector::vls_mode_valid_p (V256SFmode) && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 1024")
+ (V512SF "riscv_vector::vls_mode_valid_p (V512SFmode) && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 2048")
+ (V1024SF "riscv_vector::vls_mode_valid_p (V1024SFmode) && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 4096")
+ (V1DF "riscv_vector::vls_mode_valid_p (V1DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_64BIT")
+ (V2DF "riscv_vector::vls_mode_valid_p (V2DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_64BIT")
+ (V4DF "riscv_vector::vls_mode_valid_p (V4DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_64BIT")
+ (V8DF "riscv_vector::vls_mode_valid_p (V8DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 64 && TARGET_64BIT")
+ (V16DF "riscv_vector::vls_mode_valid_p (V16DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128 && TARGET_64BIT")
+ (V32DF "riscv_vector::vls_mode_valid_p (V32DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 256 && TARGET_64BIT")
+ (V64DF "riscv_vector::vls_mode_valid_p (V64DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 512 && TARGET_64BIT")
+ (V128DF "riscv_vector::vls_mode_valid_p (V128DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 1024 && TARGET_64BIT")
+ (V256DF "riscv_vector::vls_mode_valid_p (V256DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 2048 && TARGET_64BIT")
+ (V512DF "riscv_vector::vls_mode_valid_p (V512DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096 && TARGET_64BIT")
+])
+
(define_mode_iterator VB_VLS [VB VLSB])
(define_mode_iterator VLS [VLSI VLSF_ZVFHMIN])
@@ -3198,34 +3334,6 @@
(V512DF "riscv_vector::vls_mode_valid_p (V512DFmode) && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096")
])
-(define_mode_attr VDEMOTE [
- (RVVM8DI "RVVM8SI") (RVVM4DI "RVVM4SI") (RVVM2DI "RVVM2SI") (RVVM1DI "RVVM1SI")
- (V1DI "V1SI")
- (V2DI "V2SI")
- (V4DI "V4SI")
- (V8DI "V8SI")
- (V16DI "V16SI")
- (V32DI "V32SI")
- (V64DI "V64SI")
- (V128DI "V128SI")
- (V256DI "V256SI")
- (V512DI "V512SI")
-])
-
-(define_mode_attr VMDEMOTE [
- (RVVM8DI "RVVMF4BI") (RVVM4DI "RVVMF8BI") (RVVM2DI "RVVMF16BI") (RVVM1DI "RVVMF32BI")
- (V1DI "V1BI")
- (V2DI "V2BI")
- (V4DI "V4BI")
- (V8DI "V8BI")
- (V16DI "V16BI")
- (V32DI "V32BI")
- (V64DI "V64BI")
- (V128DI "V128BI")
- (V256DI "V256BI")
- (V512DI "V512BI")
-])
-
(define_mode_attr stride_predicate [
(RVVM8QI "vector_eew8_stride_operand") (RVVM4QI "vector_eew8_stride_operand")
(RVVM2QI "vector_eew8_stride_operand") (RVVM1QI "vector_eew8_stride_operand")
@@ -3314,8 +3422,8 @@
])
(define_mode_attr gs_extension [
- (RVVM8QI "const_1_operand") (RVVM4QI "vector_gs_extension_operand")
- (RVVM2QI "immediate_operand") (RVVM1QI "immediate_operand") (RVVMF2QI "immediate_operand")
+ (RVVM8QI "const_1_operand") (RVVM4QI "const_1_operand")
+ (RVVM2QI "vector_gs_extension_operand") (RVVM1QI "immediate_operand") (RVVMF2QI "immediate_operand")
(RVVMF4QI "immediate_operand") (RVVMF8QI "immediate_operand")
(RVVM8HI "const_1_operand") (RVVM4HI "vector_gs_extension_operand")
@@ -3358,11 +3466,11 @@
(RVVM8SF "vector_gs_scale_operand_32_rv32") (RVVM4SF "const_1_or_4_operand") (RVVM2SF "const_1_or_4_operand")
(RVVM1SF "const_1_or_4_operand") (RVVMF2SF "const_1_or_4_operand")
- (RVVM8DI "vector_gs_scale_operand_64") (RVVM4DI "vector_gs_scale_operand_64")
- (RVVM2DI "vector_gs_scale_operand_64") (RVVM1DI "vector_gs_scale_operand_64")
+ (RVVM8DI "const_1_or_8_operand") (RVVM4DI "const_1_or_8_operand")
+ (RVVM2DI "const_1_or_8_operand") (RVVM1DI "const_1_or_8_operand")
- (RVVM8DF "vector_gs_scale_operand_64") (RVVM4DF "vector_gs_scale_operand_64")
- (RVVM2DF "vector_gs_scale_operand_64") (RVVM1DF "vector_gs_scale_operand_64")
+ (RVVM8DF "const_1_or_8_operand") (RVVM4DF "const_1_or_8_operand")
+ (RVVM2DF "const_1_or_8_operand") (RVVM1DF "const_1_or_8_operand")
])
(define_int_iterator ORDER [UNSPEC_ORDERED UNSPEC_UNORDERED])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index d1499d3..ba9c9e5 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -2201,21 +2201,21 @@
;; DEST eew is same as SOURCE eew, DEST register can overlap SOURCE.
(define_insn "@pred_indexed_<order>load<mode>_same_eew"
- [(set (match_operand:V 0 "register_operand" "=vd, vr,vd, vr")
- (if_then_else:V
+ [(set (match_operand:VINDEXED 0 "register_operand" "=vd, vr,vd, vr")
+ (if_then_else:VINDEXED
(unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,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")
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,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)
- (unspec:V
- [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ,rJ, rJ")
+ (unspec:VINDEXED
+ [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ,rJ, rJ")
(mem:BLK (scratch))
- (match_operand:<VINDEX> 4 "register_operand" " vr, vr,vr, vr")] ORDER)
- (match_operand:V 2 "vector_merge_operand" " vu, vu, 0, 0")))]
+ (match_operand:<VINDEX> 4 "register_operand" " vr, vr,vr, vr")] ORDER)
+ (match_operand:VINDEXED 2 "vector_merge_operand" " vu, vu, 0, 0")))]
"TARGET_VECTOR"
"vl<order>xei<sew>.v\t%0,(%z3),%4%p1"
[(set_attr "type" "vld<order>x")
@@ -8096,8 +8096,11 @@
(match_operand:<VEL> 4 "reg_or_int_operand")] VSLIDES1))]
"TARGET_VECTOR"
{
+ poly_uint64 nunits = GET_MODE_NUNITS (<MODE>mode) * 2;
+ machine_mode vsimode = riscv_vector::get_vector_mode (SImode, nunits).require ();
+ machine_mode vbimode = riscv_vector::get_vector_mode (BImode, nunits).require ();
if (riscv_vector::slide1_sew64_helper (<UNSPEC>, <MODE>mode,
- <VDEMOTE>mode, <VMDEMOTE>mode,
+ vsimode, vbimode,
operands))
DONE;
})
diff --git a/gcc/config/s390/s390-builtin-types.def b/gcc/config/s390/s390-builtin-types.def
index 22ee348..5057f34 100644
--- a/gcc/config/s390/s390-builtin-types.def
+++ b/gcc/config/s390/s390-builtin-types.def
@@ -216,7 +216,6 @@ DEF_FN_TYPE_2 (BT_FN_UV16QI_UCHAR_INT, BT_UV16QI, BT_UCHAR, BT_INT)
DEF_FN_TYPE_2 (BT_FN_UV16QI_UCHAR_UCHAR, BT_UV16QI, BT_UCHAR, BT_UCHAR)
DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_INTPTR, BT_UV16QI, BT_UV16QI, BT_INTPTR)
DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_UCHAR, BT_UV16QI, BT_UV16QI, BT_UCHAR)
-DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_UINT, BT_UV16QI, BT_UV16QI, BT_UINT)
DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_UV16QI, BT_UV16QI, BT_UV16QI, BT_UV16QI)
DEF_FN_TYPE_2 (BT_FN_UV16QI_UV2DI_UV2DI, BT_UV16QI, BT_UV2DI, BT_UV2DI)
DEF_FN_TYPE_2 (BT_FN_UV16QI_UV4SI_UV4SI, BT_UV16QI, BT_UV4SI, BT_UV4SI)
@@ -225,7 +224,6 @@ DEF_FN_TYPE_2 (BT_FN_UV2DI_UCHAR_UCHAR, BT_UV2DI, BT_UCHAR, BT_UCHAR)
DEF_FN_TYPE_2 (BT_FN_UV2DI_ULONGLONG_INT, BT_UV2DI, BT_ULONGLONG, BT_INT)
DEF_FN_TYPE_2 (BT_FN_UV2DI_UV16QI_UV16QI, BT_UV2DI, BT_UV16QI, BT_UV16QI)
DEF_FN_TYPE_2 (BT_FN_UV2DI_UV2DI_UCHAR, BT_UV2DI, BT_UV2DI, BT_UCHAR)
-DEF_FN_TYPE_2 (BT_FN_UV2DI_UV2DI_UINT, BT_UV2DI, BT_UV2DI, BT_UINT)
DEF_FN_TYPE_2 (BT_FN_UV2DI_UV2DI_UV2DI, BT_UV2DI, BT_UV2DI, BT_UV2DI)
DEF_FN_TYPE_2 (BT_FN_UV2DI_UV4SI_UV4SI, BT_UV2DI, BT_UV4SI, BT_UV4SI)
DEF_FN_TYPE_2 (BT_FN_UV2DI_UV8HI_UV8HI, BT_UV2DI, BT_UV8HI, BT_UV8HI)
@@ -236,7 +234,6 @@ DEF_FN_TYPE_2 (BT_FN_UV4SI_UV16QI_UV16QI, BT_UV4SI, BT_UV16QI, BT_UV16QI)
DEF_FN_TYPE_2 (BT_FN_UV4SI_UV2DI_UV2DI, BT_UV4SI, BT_UV2DI, BT_UV2DI)
DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_INTPTR, BT_UV4SI, BT_UV4SI, BT_INTPTR)
DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_UCHAR, BT_UV4SI, BT_UV4SI, BT_UCHAR)
-DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_UINT, BT_UV4SI, BT_UV4SI, BT_UINT)
DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_UV4SI, BT_UV4SI, BT_UV4SI, BT_UV4SI)
DEF_FN_TYPE_2 (BT_FN_UV4SI_UV8HI_UV8HI, BT_UV4SI, BT_UV8HI, BT_UV8HI)
DEF_FN_TYPE_2 (BT_FN_UV8HI_UCHAR_UCHAR, BT_UV8HI, BT_UCHAR, BT_UCHAR)
@@ -265,9 +262,9 @@ DEF_FN_TYPE_2 (BT_FN_V2DI_V2DF_V2DF, BT_V2DI, BT_V2DF, BT_V2DF)
DEF_FN_TYPE_2 (BT_FN_V2DI_V2DI_V2DI, BT_V2DI, BT_V2DI, BT_V2DI)
DEF_FN_TYPE_2 (BT_FN_V2DI_V4SI_V4SI, BT_V2DI, BT_V4SI, BT_V4SI)
DEF_FN_TYPE_2 (BT_FN_V4SF_FLT_INT, BT_V4SF, BT_FLT, BT_INT)
+DEF_FN_TYPE_2 (BT_FN_V4SF_UV8HI_UINT, BT_V4SF, BT_UV8HI, BT_UINT)
DEF_FN_TYPE_2 (BT_FN_V4SF_V4SF_UCHAR, BT_V4SF, BT_V4SF, BT_UCHAR)
DEF_FN_TYPE_2 (BT_FN_V4SF_V4SF_V4SF, BT_V4SF, BT_V4SF, BT_V4SF)
-DEF_FN_TYPE_2 (BT_FN_V4SF_V8HI_UINT, BT_V4SF, BT_V8HI, BT_UINT)
DEF_FN_TYPE_2 (BT_FN_V4SI_BV4SI_V4SI, BT_V4SI, BT_BV4SI, BT_V4SI)
DEF_FN_TYPE_2 (BT_FN_V4SI_INT_VOIDCONSTPTR, BT_V4SI, BT_INT, BT_VOIDCONSTPTR)
DEF_FN_TYPE_2 (BT_FN_V4SI_UV4SI_UV4SI, BT_V4SI, BT_UV4SI, BT_UV4SI)
@@ -279,7 +276,6 @@ DEF_FN_TYPE_2 (BT_FN_V8HI_BV8HI_V8HI, BT_V8HI, BT_BV8HI, BT_V8HI)
DEF_FN_TYPE_2 (BT_FN_V8HI_UV8HI_UV8HI, BT_V8HI, BT_UV8HI, BT_UV8HI)
DEF_FN_TYPE_2 (BT_FN_V8HI_V16QI_V16QI, BT_V8HI, BT_V16QI, BT_V16QI)
DEF_FN_TYPE_2 (BT_FN_V8HI_V4SI_V4SI, BT_V8HI, BT_V4SI, BT_V4SI)
-DEF_FN_TYPE_2 (BT_FN_V8HI_V8HI_UINT, BT_V8HI, BT_V8HI, BT_UINT)
DEF_FN_TYPE_2 (BT_FN_V8HI_V8HI_V8HI, BT_V8HI, BT_V8HI, BT_V8HI)
DEF_FN_TYPE_2 (BT_FN_VOID_UINT64PTR_UINT64, BT_VOID, BT_UINT64PTR, BT_UINT64)
DEF_FN_TYPE_2 (BT_FN_VOID_V2DF_FLTPTR, BT_VOID, BT_V2DF, BT_FLTPTR)
@@ -317,6 +313,7 @@ DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_USHORT_INT, BT_UV8HI, BT_UV8HI, BT_USHORT, BT_I
DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UV8HI_INT, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT)
DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UV8HI_INTPTR, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INTPTR)
DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UV8HI_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI)
+DEF_FN_TYPE_3 (BT_FN_UV8HI_V4SF_V4SF_UINT, BT_UV8HI, BT_V4SF, BT_V4SF, BT_UINT)
DEF_FN_TYPE_3 (BT_FN_V16QI_UV16QI_UV16QI_INTPTR, BT_V16QI, BT_UV16QI, BT_UV16QI, BT_INTPTR)
DEF_FN_TYPE_3 (BT_FN_V16QI_V16QI_V16QI_INTPTR, BT_V16QI, BT_V16QI, BT_V16QI, BT_INTPTR)
DEF_FN_TYPE_3 (BT_FN_V16QI_V16QI_V16QI_V16QI, BT_V16QI, BT_V16QI, BT_V16QI, BT_V16QI)
@@ -347,7 +344,6 @@ DEF_FN_TYPE_3 (BT_FN_V4SI_V4SI_V4SI_V4SI, BT_V4SI, BT_V4SI, BT_V4SI, BT_V4SI)
DEF_FN_TYPE_3 (BT_FN_V4SI_V8HI_V8HI_V4SI, BT_V4SI, BT_V8HI, BT_V8HI, BT_V4SI)
DEF_FN_TYPE_3 (BT_FN_V8HI_UV8HI_UV8HI_INTPTR, BT_V8HI, BT_UV8HI, BT_UV8HI, BT_INTPTR)
DEF_FN_TYPE_3 (BT_FN_V8HI_V16QI_V16QI_V8HI, BT_V8HI, BT_V16QI, BT_V16QI, BT_V8HI)
-DEF_FN_TYPE_3 (BT_FN_V8HI_V4SF_V4SF_UINT, BT_V8HI, BT_V4SF, BT_V4SF, BT_UINT)
DEF_FN_TYPE_3 (BT_FN_V8HI_V4SI_V4SI_INTPTR, BT_V8HI, BT_V4SI, BT_V4SI, BT_INTPTR)
DEF_FN_TYPE_3 (BT_FN_V8HI_V8HI_V8HI_INTPTR, BT_V8HI, BT_V8HI, BT_V8HI, BT_INTPTR)
DEF_FN_TYPE_3 (BT_FN_V8HI_V8HI_V8HI_V8HI, BT_V8HI, BT_V8HI, BT_V8HI, BT_V8HI)
diff --git a/gcc/config/s390/s390-builtins.def b/gcc/config/s390/s390-builtins.def
index b59fa09..b09c303 100644
--- a/gcc/config/s390/s390-builtins.def
+++ b/gcc/config/s390/s390-builtins.def
@@ -28,7 +28,6 @@
#undef O_U12
#undef O_U16
#undef O_U32
-#undef O_U64
#undef O_M12
@@ -89,11 +88,6 @@
#undef O3_U32
#undef O4_U32
-#undef O1_U64
-#undef O2_U64
-#undef O3_U64
-#undef O4_U64
-
#undef O1_M12
#undef O2_M12
#undef O3_M12
@@ -163,21 +157,20 @@
#define O_U12 7 /* unsigned 16 bit literal */
#define O_U16 8 /* unsigned 16 bit literal */
#define O_U32 9 /* unsigned 32 bit literal */
-#define O_U64 10 /* unsigned 64 bit literal */
-#define O_M12 11 /* matches bitmask of 12 */
+#define O_M12 10 /* matches bitmask of 12 */
-#define O_S2 12 /* signed 2 bit literal */
-#define O_S3 13 /* signed 3 bit literal */
-#define O_S4 14 /* signed 4 bit literal */
-#define O_S5 15 /* signed 5 bit literal */
-#define O_S8 16 /* signed 8 bit literal */
-#define O_S12 17 /* signed 12 bit literal */
-#define O_S16 18 /* signed 16 bit literal */
-#define O_S32 19 /* signed 32 bit literal */
+#define O_S2 11 /* signed 2 bit literal */
+#define O_S3 12 /* signed 3 bit literal */
+#define O_S4 13 /* signed 4 bit literal */
+#define O_S5 14 /* signed 5 bit literal */
+#define O_S8 15 /* signed 8 bit literal */
+#define O_S12 16 /* signed 12 bit literal */
+#define O_S16 17 /* signed 16 bit literal */
+#define O_S32 18 /* signed 32 bit literal */
-#define O_ELEM 20 /* Element selector requiring modulo arithmetic. */
-#define O_LIT 21 /* Operand must be a literal fitting the target type. */
+#define O_ELEM 19 /* Element selector requiring modulo arithmetic. */
+#define O_LIT 20 /* Operand must be a literal fitting the target type. */
#define O_SHIFT 5
@@ -230,11 +223,6 @@
#define O3_U32 (O_U32 << (2 * O_SHIFT))
#define O4_U32 (O_U32 << (3 * O_SHIFT))
-#define O1_U64 O_U64
-#define O2_U64 (O_U64 << O_SHIFT)
-#define O3_U64 (O_U64 << (2 * O_SHIFT))
-#define O4_U64 (O_U64 << (3 * O_SHIFT))
-
#define O1_M12 O_M12
#define O2_M12 (O_M12 << O_SHIFT)
#define O3_M12 (O_M12 << (2 * O_SHIFT))
@@ -2001,19 +1989,19 @@ B_DEF (s390_verllvf, vrotlv4si3, 0,
B_DEF (s390_verllvg, vrotlv2di3, 0, B_VX, 0, BT_FN_UV2DI_UV2DI_UV2DI)
OB_DEF (s390_vec_rli, s390_vec_rli_u8, s390_vec_rli_s64, B_VX, BT_FN_OV4SI_OV4SI_ULONG)
-OB_DEF_VAR (s390_vec_rli_u8, s390_verllb, 0, O2_U64, BT_OV_UV16QI_UV16QI_ULONG)
-OB_DEF_VAR (s390_vec_rli_s8, s390_verllb, 0, O2_U64, BT_OV_V16QI_V16QI_ULONG)
-OB_DEF_VAR (s390_vec_rli_u16, s390_verllh, 0, O2_U64, BT_OV_UV8HI_UV8HI_ULONG)
-OB_DEF_VAR (s390_vec_rli_s16, s390_verllh, 0, O2_U64, BT_OV_V8HI_V8HI_ULONG)
-OB_DEF_VAR (s390_vec_rli_u32, s390_verllf, 0, O2_U64, BT_OV_UV4SI_UV4SI_ULONG)
-OB_DEF_VAR (s390_vec_rli_s32, s390_verllf, 0, O2_U64, BT_OV_V4SI_V4SI_ULONG)
-OB_DEF_VAR (s390_vec_rli_u64, s390_verllg, 0, O2_U64, BT_OV_UV2DI_UV2DI_ULONG)
-OB_DEF_VAR (s390_vec_rli_s64, s390_verllg, 0, O2_U64, BT_OV_V2DI_V2DI_ULONG)
-
-B_DEF (s390_verllb, rotlv16qi3, 0, B_VX, O2_U32, BT_FN_UV16QI_UV16QI_UINT)
-B_DEF (s390_verllh, rotlv8hi3, 0, B_VX, O2_U32, BT_FN_UV8HI_UV8HI_UINT)
-B_DEF (s390_verllf, rotlv4si3, 0, B_VX, O2_U32, BT_FN_UV4SI_UV4SI_UINT)
-B_DEF (s390_verllg, rotlv2di3, 0, B_VX, O2_U32, BT_FN_UV2DI_UV2DI_UINT)
+OB_DEF_VAR (s390_vec_rli_u8, s390_verllb, 0, 0, BT_OV_UV16QI_UV16QI_ULONG)
+OB_DEF_VAR (s390_vec_rli_s8, s390_verllb, 0, 0, BT_OV_V16QI_V16QI_ULONG)
+OB_DEF_VAR (s390_vec_rli_u16, s390_verllh, 0, 0, BT_OV_UV8HI_UV8HI_ULONG)
+OB_DEF_VAR (s390_vec_rli_s16, s390_verllh, 0, 0, BT_OV_V8HI_V8HI_ULONG)
+OB_DEF_VAR (s390_vec_rli_u32, s390_verllf, 0, 0, BT_OV_UV4SI_UV4SI_ULONG)
+OB_DEF_VAR (s390_vec_rli_s32, s390_verllf, 0, 0, BT_OV_V4SI_V4SI_ULONG)
+OB_DEF_VAR (s390_vec_rli_u64, s390_verllg, 0, 0, BT_OV_UV2DI_UV2DI_ULONG)
+OB_DEF_VAR (s390_vec_rli_s64, s390_verllg, 0, 0, BT_OV_V2DI_V2DI_ULONG)
+
+B_DEF (s390_verllb, rotlv16qi3, 0, B_VX, 0, BT_FN_UV16QI_UV16QI_UCHAR)
+B_DEF (s390_verllh, rotlv8hi3, 0, B_VX, 0, BT_FN_UV8HI_UV8HI_UCHAR)
+B_DEF (s390_verllf, rotlv4si3, 0, B_VX, 0, BT_FN_UV4SI_UV4SI_UCHAR)
+B_DEF (s390_verllg, rotlv2di3, 0, B_VX, 0, BT_FN_UV2DI_UV2DI_UCHAR)
OB_DEF (s390_vec_rl_mask, s390_vec_rl_mask_s8,s390_vec_rl_mask_u64,B_VX, BT_FN_OV4SI_OV4SI_OV4SI_UCHAR)
OB_DEF_VAR (s390_vec_rl_mask_s8, s390_verimb, 0, O3_U8, BT_OV_V16QI_V16QI_UV16QI_UCHAR)
@@ -2840,10 +2828,10 @@ OB_DEF (s390_vec_double, s390_vec_double_s64,s390_vec_double_u64,
OB_DEF_VAR (s390_vec_double_s64, s390_vcdgb, 0, 0, BT_OV_V2DF_V2DI)
OB_DEF_VAR (s390_vec_double_u64, s390_vcdlgb, 0, 0, BT_OV_V2DF_UV2DI)
-B_DEF (s390_vcefb, floatv4siv4sf2, 0, B_VXE2, O2_U4 | O3_U3, BT_FN_V4SF_V4SI)
-B_DEF (s390_vcdgb, floatv2div2df2, 0, B_VX, O2_U4 | O3_U3, BT_FN_V2DF_V2DI)
-B_DEF (s390_vcelfb, floatunsv4siv4sf2, 0, B_VXE2, O2_U4 | O3_U3, BT_FN_V4SF_UV4SI)
-B_DEF (s390_vcdlgb, floatunsv2div2df2, 0, B_VX, O2_U4 | O3_U3, BT_FN_V2DF_UV2DI)
+B_DEF (s390_vcefb, floatv4siv4sf2, 0, B_VXE2, 0, BT_FN_V4SF_V4SI)
+B_DEF (s390_vcdgb, floatv2div2df2, 0, B_VX, 0, BT_FN_V2DF_V2DI)
+B_DEF (s390_vcelfb, floatunsv4siv4sf2, 0, B_VXE2, 0, BT_FN_V4SF_UV4SI)
+B_DEF (s390_vcdlgb, floatunsv2div2df2, 0, B_VX, 0, BT_FN_V2DF_UV2DI)
OB_DEF (s390_vec_signed, s390_vec_signed_flt,s390_vec_signed_dbl,B_VX, BT_FN_OV4SI_OV4SI)
OB_DEF_VAR (s390_vec_signed_flt, s390_vcfeb, B_VXE2, 0, BT_OV_V4SI_V4SF)
@@ -2853,10 +2841,10 @@ OB_DEF (s390_vec_unsigned, s390_vec_unsigned_flt,s390_vec_unsigned_
OB_DEF_VAR (s390_vec_unsigned_flt, s390_vclfeb, B_VXE2, 0, BT_OV_UV4SI_V4SF)
OB_DEF_VAR (s390_vec_unsigned_dbl, s390_vclgdb, 0, 0, BT_OV_UV2DI_V2DF)
-B_DEF (s390_vcfeb, fix_truncv4sfv4si2, 0, B_VXE2, O2_U4 | O3_U3, BT_FN_V4SI_V4SF)
-B_DEF (s390_vcgdb, fix_truncv2dfv2di2, 0, B_VX, O2_U4 | O3_U3, BT_FN_V2DI_V2DF)
-B_DEF (s390_vclfeb, fixuns_truncv4sfv4si2, 0, B_VXE2, O2_U4 | O3_U3, BT_FN_UV4SI_V4SF)
-B_DEF (s390_vclgdb, fixuns_truncv2dfv2di2, 0, B_VX, O2_U4 | O3_U3, BT_FN_UV2DI_V2DF)
+B_DEF (s390_vcfeb, fix_truncv4sfv4si2, 0, B_VXE2, 0, BT_FN_V4SI_V4SF)
+B_DEF (s390_vcgdb, fix_truncv2dfv2di2, 0, B_VX, 0, BT_FN_V2DI_V2DF)
+B_DEF (s390_vclfeb, fixuns_truncv4sfv4si2, 0, B_VXE2, 0, BT_FN_UV4SI_V4SF)
+B_DEF (s390_vclgdb, fixuns_truncv2dfv2di2, 0, B_VX, 0, BT_FN_UV2DI_V2DF)
B_DEF (s390_vfisb, vec_fpintv4sf, 0, B_VXE, O2_U4 | O3_U3, BT_FN_V4SF_V4SF_UCHAR_UCHAR)
B_DEF (s390_vfidb, vec_fpintv2df, 0, B_VX, O2_U4 | O3_U3, BT_FN_V2DF_V2DF_UCHAR_UCHAR)
@@ -3037,10 +3025,10 @@ B_DEF (s390_vstrszf, vstrszv4si, 0,
/* arch 14 builtins */
-B_DEF (s390_vclfnhs, vclfnhs_v8hi, 0, B_NNPA, O2_U4, BT_FN_V4SF_V8HI_UINT)
-B_DEF (s390_vclfnls, vclfnls_v8hi, 0, B_NNPA, O2_U4, BT_FN_V4SF_V8HI_UINT)
+B_DEF (s390_vclfnhs, vclfnhs_v8hi, 0, B_NNPA, O2_U4, BT_FN_V4SF_UV8HI_UINT)
+B_DEF (s390_vclfnls, vclfnls_v8hi, 0, B_NNPA, O2_U4, BT_FN_V4SF_UV8HI_UINT)
-B_DEF (s390_vcrnfs, vcrnfs_v8hi, 0, B_NNPA, O3_U4, BT_FN_V8HI_V4SF_V4SF_UINT)
+B_DEF (s390_vcrnfs, vcrnfs_v8hi, 0, B_NNPA, O3_U4, BT_FN_UV8HI_V4SF_V4SF_UINT)
-B_DEF (s390_vcfn, vcfn_v8hi, 0, B_NNPA, O2_U4, BT_FN_V8HI_V8HI_UINT)
-B_DEF (s390_vcnf, vcnf_v8hi, 0, B_NNPA, O2_U4, BT_FN_V8HI_V8HI_UINT)
+B_DEF (s390_vcfn, vcfn_v8hi, 0, B_NNPA, O2_U4, BT_FN_UV8HI_UV8HI_UINT)
+B_DEF (s390_vcnf, vcnf_v8hi, 0, B_NNPA, O2_U4, BT_FN_UV8HI_UV8HI_UINT)
diff --git a/gcc/config/s390/s390-c.cc b/gcc/config/s390/s390-c.cc
index fce56934..7e455ab 100644
--- a/gcc/config/s390/s390-c.cc
+++ b/gcc/config/s390/s390-c.cc
@@ -409,6 +409,7 @@ s390_cpu_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__LONG_DOUBLE_128__");
cl_target_option_save (&opts, &global_options, &global_options_set);
s390_cpu_cpp_builtins_internal (pfile, &opts, NULL);
+ cpp_define (pfile, "__GCC_ASM_FLAG_OUTPUTS__");
}
#if S390_USE_TARGET_ATTRIBUTE
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index e36efec..29b5dc9 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -815,8 +815,8 @@ s390_const_operand_ok (tree arg, int argnum, int op_flags, tree decl)
{
if (O_UIMM_P (op_flags))
{
- unsigned HOST_WIDE_INT bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32, 64, 4 };
- unsigned HOST_WIDE_INT bitmasks[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12 };
+ unsigned HOST_WIDE_INT bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32, 4 };
+ unsigned HOST_WIDE_INT bitmasks[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 12 };
unsigned HOST_WIDE_INT bitwidth = bitwidths[op_flags - O_U1];
unsigned HOST_WIDE_INT bitmask = bitmasks[op_flags - O_U1];
@@ -824,7 +824,7 @@ s390_const_operand_ok (tree arg, int argnum, int op_flags, tree decl)
gcc_assert(ARRAY_SIZE(bitmasks) == (O_M12 - O_U1 + 1));
if (!tree_fits_uhwi_p (arg)
- || tree_to_uhwi (arg) > ((HOST_WIDE_INT_1U << (bitwidth - 1) << 1) - 1)
+ || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1
|| (bitmask && tree_to_uhwi (arg) & ~bitmask))
{
if (bitmask)
@@ -1874,6 +1874,97 @@ s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
*code = new_code;
}
}
+ /* Remove UNSPEC_CC_TO_INT from connectives. This happens for
+ checks against multiple condition codes. */
+ if (GET_CODE (*op0) == AND
+ && GET_CODE (XEXP (*op0, 0)) == UNSPEC
+ && XINT (XEXP (*op0, 0), 1) == UNSPEC_CC_TO_INT
+ && XVECLEN (XEXP (*op0, 0), 0) == 1
+ && REGNO (XVECEXP (XEXP (*op0, 0), 0, 0)) == CC_REGNUM
+ && CONST_INT_P (XEXP (*op0, 1))
+ && CONST_INT_P (*op1)
+ && INTVAL (XEXP (*op0, 1)) == -3
+ && *code == EQ)
+ {
+ if (INTVAL (*op1) == 0)
+ {
+ /* case cc == 0 || cc = 2 => mask = 0xa */
+ *op0 = XVECEXP (XEXP (*op0, 0), 0, 0);
+ *op1 = gen_rtx_CONST_INT (VOIDmode, 0xa);
+ }
+ else if (INTVAL (*op1) == 1)
+ {
+ /* case cc == 1 || cc == 3 => mask = 0x5 */
+ *op0 = XVECEXP (XEXP (*op0, 0), 0, 0);
+ *op1 = gen_rtx_CONST_INT (VOIDmode, 0x5);
+ }
+ }
+ if (GET_CODE (*op0) == PLUS
+ && GET_CODE (XEXP (*op0, 0)) == UNSPEC
+ && XINT (XEXP (*op0, 0), 1) == UNSPEC_CC_TO_INT
+ && XVECLEN (XEXP (*op0, 0), 0) == 1
+ && REGNO (XVECEXP (XEXP (*op0, 0), 0, 0)) == CC_REGNUM
+ && CONST_INT_P (XEXP (*op0, 1))
+ && CONST_INT_P (*op1)
+ && (*code == LEU || *code == GTU))
+ {
+ if (INTVAL (*op1) == 1)
+ {
+ if (INTVAL (XEXP (*op0, 1)) == -1)
+ {
+ /* case cc == 1 || cc == 2 => mask = 0x6 */
+ *op0 = XVECEXP (XEXP (*op0, 0), 0, 0);
+ *op1 = gen_rtx_CONST_INT (VOIDmode, 0x6);
+ *code = *code == GTU ? NE : EQ;
+ }
+ else if (INTVAL (XEXP (*op0, 1)) == -2)
+ {
+ /* case cc == 2 || cc == 3 => mask = 0x3 */
+ *op0 = XVECEXP (XEXP (*op0, 0), 0, 0);
+ *op1 = gen_rtx_CONST_INT (VOIDmode, 0x3);
+ *code = *code == GTU ? NE : EQ;
+ }
+ }
+ else if (INTVAL (*op1) == 2
+ && INTVAL (XEXP (*op0, 1)) == -1)
+ {
+ /* case cc == 1 || cc == 2 || cc == 3 => mask = 0x7 */
+ *op0 = XVECEXP (XEXP (*op0, 0), 0, 0);
+ *op1 = gen_rtx_CONST_INT (VOIDmode, 0x7);
+ *code = *code == GTU ? NE : EQ;
+ }
+ }
+ else if (*code == LEU || *code == GTU)
+ {
+ if (GET_CODE (*op0) == UNSPEC
+ && XINT (*op0, 1) == UNSPEC_CC_TO_INT
+ && XVECLEN (*op0, 0) == 1
+ && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
+ && CONST_INT_P (*op1))
+ {
+ if (INTVAL (*op1) == 1)
+ {
+ /* case cc == 0 || cc == 1 => mask = 0xc */
+ *op0 = XVECEXP (*op0, 0, 0);
+ *op1 = gen_rtx_CONST_INT (VOIDmode, 0xc);
+ *code = *code == GTU ? NE : EQ;
+ }
+ else if (INTVAL (*op1) == 2)
+ {
+ /* case cc == 0 || cc == 1 || cc == 2 => mask = 0xd */
+ *op0 = XVECEXP (*op0, 0, 0);
+ *op1 = gen_rtx_CONST_INT (VOIDmode, 0xd);
+ *code = *code == GTU ? NE : EQ;
+ }
+ else if (INTVAL (*op1) == 3)
+ {
+ /* always true */
+ *op0 = const0_rtx;
+ *op1 = const0_rtx;
+ *code = *code == GTU ? NE : EQ;
+ }
+ }
+ }
/* Simplify cascaded EQ, NE with const0_rtx. */
if ((*code == NE || *code == EQ)
@@ -17425,22 +17516,60 @@ static rtx_insn *
s390_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs,
vec<machine_mode> &input_modes,
vec<const char *> &constraints, vec<rtx> & /*clobbers*/,
- HARD_REG_SET & /*clobbered_regs*/, location_t /*loc*/)
+ HARD_REG_SET &clobbered_regs, location_t loc)
{
- if (!TARGET_VXE)
- /* Long doubles are stored in FPR pairs - nothing to do. */
- return NULL;
rtx_insn *after_md_seq = NULL, *after_md_end = NULL;
+ bool saw_cc = false;
unsigned ninputs = inputs.length ();
unsigned noutputs = outputs.length ();
for (unsigned i = 0; i < noutputs; i++)
{
+ const char *constraint = constraints[i];
+ if (strncmp (constraint, "=@cc", 4) == 0)
+ {
+ if (constraint[4] != 0)
+ {
+ error_at (loc, "invalid cc output constraint: %qs", constraint);
+ continue;
+ }
+ if (saw_cc)
+ {
+ error_at (loc, "multiple cc output constraints not supported");
+ continue;
+ }
+ if (TEST_HARD_REG_BIT (clobbered_regs, CC_REGNUM))
+ {
+ error_at (loc, "%<asm%> specifier for cc output conflicts with %<asm%> clobber list");
+ continue;
+ }
+ rtx dest = outputs[i];
+ if (GET_MODE (dest) != SImode)
+ {
+ error ("invalid type for cc output constraint");
+ continue;
+ }
+ saw_cc = true;
+ constraints[i] = "=c";
+ outputs[i] = gen_rtx_REG (CCRAWmode, CC_REGNUM);
+
+ push_to_sequence2 (after_md_seq, after_md_end);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_UNSPEC (SImode,
+ gen_rtvec (1, outputs[i]),
+ UNSPEC_CC_TO_INT)));
+ after_md_seq = get_insns ();
+ after_md_end = get_last_insn ();
+ end_sequence ();
+ continue;
+ }
+ if (!TARGET_VXE)
+ /* Long doubles are stored in FPR pairs - nothing to do. */
+ continue;
if (GET_MODE (outputs[i]) != TFmode)
/* Not a long double - nothing to do. */
continue;
- const char *constraint = constraints[i];
bool allows_mem, allows_reg, is_inout;
bool ok = parse_output_constraint (&constraint, i, ninputs, noutputs,
&allows_mem, &allows_reg, &is_inout);
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 4bdb679..685bb28 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -1356,13 +1356,13 @@
(define_insn "*cmphi_ccu"
[(set (reg CC_REGNUM)
(compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
- (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
+ (match_operand:HI 1 "general_operand" "Q,S,n,BQ,Q")))]
"s390_match_ccmode (insn, CCUmode)
&& !register_operand (operands[1], HImode)"
"@
clm\t%0,3,%S1
clmy\t%0,3,%S1
- clhhsi\t%0,%1
+ clhhsi\t%0,%x1
#
#"
[(set_attr "op_type" "RS,RSY,SIL,SS,SS")
@@ -1688,8 +1688,6 @@
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(match_operand:TI 1 "general_operand" ""))]
"TARGET_ZARCH && reload_completed
- && !s_operand (operands[0], TImode)
- && !s_operand (operands[1], TImode)
&& s390_split_ok_p (operands[0], operands[1], TImode, 0)"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
@@ -1704,8 +1702,6 @@
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(match_operand:TI 1 "general_operand" ""))]
"TARGET_ZARCH && reload_completed
- && !s_operand (operands[0], TImode)
- && !s_operand (operands[1], TImode)
&& s390_split_ok_p (operands[0], operands[1], TImode, 1)"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
@@ -6932,7 +6928,7 @@
[(set (match_operand:SI 0 "register_operand" "")
(match_operator:SI 1 "s390_eqne_operator"
[(match_operand 2 "cc_reg_operand")
- (match_operand 3 "const0_operand")]))
+ (match_operand 3 "const_mask_operand")]))
(clobber (reg:CC CC_REGNUM))])]
""
"machine_mode mode = GET_MODE (operands[2]);
@@ -6941,15 +6937,15 @@
rtx cond, ite;
if (GET_CODE (operands[1]) == NE)
- cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx);
+ cond = gen_rtx_NE (VOIDmode, operands[2], operands[3]);
else
- cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx);
+ cond = gen_rtx_EQ (VOIDmode, operands[2], operands[3]);
ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
emit_insn (gen_rtx_SET (operands[0], ite));
}
else
{
- if (mode != CCZ1mode)
+ if (mode != CCZ1mode || operands[3] != const0_rtx)
FAIL;
emit_insn (gen_sne (operands[0], operands[2]));
if (GET_CODE (operands[1]) == EQ)
@@ -12252,9 +12248,9 @@
(define_insn "@split_stack_call<mode>"
[(set (pc) (label_ref (match_operand 2 "" ""))) ; call done label
- (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
- (reg:P 1)]
- UNSPECV_SPLIT_STACK_CALL))
+ (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X")
+ (reg:P 1)]
+ UNSPECV_SPLIT_STACK_CALL))
(use (label_ref (match_operand 1 "" "X"))) ; parm block label
(use (match_operand 3 "const_int_operand" "X")) ; frame size
(use (match_operand 4 "const_int_operand" "X"))] ; arg size
@@ -12274,9 +12270,9 @@
(match_operand 5 "" "") ; condition
(label_ref (match_operand 2 "" "")) ; call done label
(pc)))
- (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
- (reg:P 1)]
- UNSPECV_SPLIT_STACK_CALL))
+ (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X")
+ (reg:P 1)]
+ UNSPECV_SPLIT_STACK_CALL))
(use (label_ref (match_operand 1 "" "X"))) ; parm block label
(use (match_operand 3 "const_int_operand" "X")) ; frame size
(use (match_operand 4 "const_int_operand" "X"))] ; arg size
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 4f4c9d9..626ec11 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -531,12 +531,14 @@
(match_operand:V 1 "nonmemory_operand" "v,v")
(parallel
[(match_operand:SI 2 "nonmemory_operand" "an,I")])))]
- "TARGET_VX
- && (!CONST_INT_P (operands[2])
- || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
- "@
- vlgv<bhfgq>\t%0,%v1,%Y2
- vste<bhfgq>\t%v1,%0,%2"
+ "TARGET_VX"
+ {
+ if (CONST_INT_P (operands[2]))
+ operands[2] = GEN_INT (UINTVAL (operands[2]) & (GET_MODE_NUNITS (<V:MODE>mode) - 1));
+ if (which_alternative == 0)
+ return "vlgv<bhfgq>\t%0,%v1,%Y2";
+ return "vste<bhfgq>\t%v1,%0,%2";
+ }
[(set_attr "op_type" "VRS,VRX")])
; vlgvb, vlgvh, vlgvf, vlgvg
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 193f40d..8321d9f 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -10936,7 +10936,7 @@
;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
(define_insn "sp_switch_1"
- [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
+ [(set (reg:SI SP_REG) (unspec_volatile:SI [(match_operand:SI 0 "" "")]
UNSPECV_SP_SWITCH_B))]
"TARGET_SH1"
{
diff --git a/gcc/config/vax/vax.cc b/gcc/config/vax/vax.cc
index df9478d..032de71 100644
--- a/gcc/config/vax/vax.cc
+++ b/gcc/config/vax/vax.cc
@@ -1831,7 +1831,9 @@ nonindexed_address_p (rtx x, bool strict)
}
/* True if PROD is either a reg times size of mode MODE and MODE is less
- than or equal 8 bytes, or just a reg if MODE is one byte. */
+ than or equal 8 bytes, or just a reg if MODE is one byte. For a MULT
+ RTX we accept its operands in either order, however ASHIFT is not
+ commutative, so in that case reg has to be the left operand. */
static bool
index_term_p (rtx prod, machine_mode mode, bool strict)
@@ -1850,8 +1852,9 @@ index_term_p (rtx prod, machine_mode mode, bool strict)
xfoo0 = XEXP (prod, 0);
xfoo1 = XEXP (prod, 1);
- if (CONST_INT_P (xfoo0)
- && GET_MODE_SIZE (mode) == (log_p ? 1 << INTVAL (xfoo0) : INTVAL (xfoo0))
+ if (!log_p
+ && CONST_INT_P (xfoo0)
+ && GET_MODE_SIZE (mode) == INTVAL (xfoo0)
&& INDEX_REGISTER_P (xfoo1, strict))
return true;
diff --git a/gcc/configure b/gcc/configure
index cc0c3aa..de72cb1 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -1009,6 +1009,7 @@ enable_rpath
with_libiconv_prefix
with_libiconv_type
enable_sjlj_exceptions
+enable_win32_utf8_manifest
with_gcc_major_version_only
enable_nls
with_libintl_prefix
@@ -1740,6 +1741,11 @@ Optional Features:
--disable-rpath do not hardcode runtime library paths
--enable-sjlj-exceptions
arrange to use setjmp/longjmp exception handling
+ --disable-win32-utf8-manifest
+ disable embedding a utf8 manifest on mingw hosts
+ --enable-win32-utf8-manifest
+ enable embedding a utf8 manifest on mingw hosts
+ (default)
--disable-nls do not use Native Language Support
--enable-secureplt enable -msecure-plt by default for PowerPC
--enable-mingw-wildcard Set whether to expand wildcard on command-line.
@@ -7679,63 +7685,6 @@ $as_echo "#define ENABLE_FOLD_CHECKING 1" >>confdefs.h
fi
valgrind_path_defines=
valgrind_command=
-
-ac_fn_cxx_check_header_mongrel "$LINENO" "valgrind.h" "ac_cv_header_valgrind_h" "$ac_includes_default"
-if test "x$ac_cv_header_valgrind_h" = xyes; then :
- have_valgrind_h=yes
-else
- have_valgrind_h=no
-fi
-
-
-
-# It is certainly possible that there's valgrind but no valgrind.h.
-# GCC relies on making annotations so we must have both.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <valgrind/memcheck.h>" >&5
-$as_echo_n "checking for VALGRIND_DISCARD in <valgrind/memcheck.h>... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <valgrind/memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- gcc_cv_header_valgrind_memcheck_h=yes
-else
- gcc_cv_header_valgrind_memcheck_h=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_valgrind_memcheck_h" >&5
-$as_echo "$gcc_cv_header_valgrind_memcheck_h" >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <memcheck.h>" >&5
-$as_echo_n "checking for VALGRIND_DISCARD in <memcheck.h>... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- gcc_cv_header_memcheck_h=yes
-else
- gcc_cv_header_memcheck_h=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_memcheck_h" >&5
-$as_echo "$gcc_cv_header_memcheck_h" >&6; }
-if test $gcc_cv_header_valgrind_memcheck_h = yes; then
-
-$as_echo "#define HAVE_VALGRIND_MEMCHECK_H 1" >>confdefs.h
-
-fi
-if test $gcc_cv_header_memcheck_h = yes; then
-
-$as_echo "#define HAVE_MEMCHECK_H 1" >>confdefs.h
-
-fi
-
if test x$ac_valgrind_checking != x ; then
# Prepare PATH_SEPARATOR.
@@ -7804,11 +7753,8 @@ else
$as_echo "no" >&6; }
fi
- if test "x$valgrind_path" = "x" \
- || (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- as_fn_error $? "*** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5
+ if test "x$valgrind_path" = "x"; then
+ as_fn_error $? "*** Cannot find valgrind" "$LINENO" 5
fi
valgrind_path_defines=-DVALGRIND_PATH='\"'$valgrind_path'\"'
valgrind_command="$valgrind_path -q"
@@ -7864,12 +7810,16 @@ else
enable_valgrind_annotations=no
fi
+ac_fn_cxx_check_header_mongrel "$LINENO" "valgrind/memcheck.h" "ac_cv_header_valgrind_memcheck_h" "$ac_includes_default"
+if test "x$ac_cv_header_valgrind_memcheck_h" = xyes; then :
+
+fi
+
+
if test x$enable_valgrind_annotations != xno \
|| test x$ac_valgrind_checking != x; then
- if (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- as_fn_error $? "*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5
+ if test $ac_cv_header_valgrind_memcheck_h = no; then
+ as_fn_error $? "*** Cannot find valgrind/memcheck.h" "$LINENO" 5
fi
$as_echo "#define ENABLE_VALGRIND_ANNOTATIONS 1" >>confdefs.h
@@ -13046,6 +12996,23 @@ _ACEOF
fi
+# Windows32 UTF-8 manifest support for running the driver and compiler
+# executables with the UTF-8 active code page on mingw hosts.
+# Non-mingw hosts ignore this option.
+# The shell variables this sets are picked up from the mingw branches
+# of config.host so they have to be set before it gets sourced.
+# Check whether --enable-win32-utf8-manifest was given.
+if test "${enable_win32_utf8_manifest+set}" = set; then :
+ enableval=$enable_win32_utf8_manifest;
+fi
+
+
+if test "x$enable_win32_utf8_manifest" != xno; then
+ host_xmake_mingw=i386/x-mingw32-utf8
+ host_extra_gcc_objs_mingw=utf8rc-mingw32.o
+ host_extra_objs_mingw=utf8-mingw32.o
+fi
+
# --------------------------------------------------------
# Build, host, and target specific configuration fragments
# --------------------------------------------------------
@@ -21602,7 +21569,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 21605 "configure"
+#line 21572 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -21708,7 +21675,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 21711 "configure"
+#line 21678 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -34615,7 +34582,7 @@ if test x"$ld_is_gold" = xno; then
ld_bndplt_support=yes
fi
elif test x$gcc_cv_ld != x; then
- # Check if linker supports -a bndplt option
+ # Check if linker supports -z bndplt option
if $gcc_cv_ld --help 2>&1 | grep -- '-z bndplt' > /dev/null; then
ld_bndplt_support=yes
fi
@@ -34744,6 +34711,72 @@ $as_echo "#define ENABLE_S390_EXCESS_FLOAT_PRECISION 1" >>confdefs.h
;;
esac
+# Check if the linker supports '-z now'
+ld_now_support=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z now option" >&5
+$as_echo_n "checking linker -z now option... " >&6; }
+if test x"$ld_is_gold" = xyes; then
+ ld_now_support=yes
+elif test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then
+ ld_now_support=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z now
+ if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then
+ ld_now_support=yes
+ fi
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LD_NOW_SUPPORT `if test x"$ld_now_support" = xyes; then echo 1; else echo 0; fi`
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_now_support" >&5
+$as_echo "$ld_now_support" >&6; }
+
+# Check if the linker supports '-z relro'
+ld_relro_support=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z relro option" >&5
+$as_echo_n "checking linker -z relro option... " >&6; }
+if test x"$ld_is_gold" = xyes; then
+ ld_relro_support=yes
+elif test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then
+ ld_relro_support=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z relro
+ if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then
+ ld_relro_support=yes
+ fi
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LD_RELRO_SUPPORT `if test x"$ld_relro_support" = xyes; then echo 1; else echo 0; fi`
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_relro_support" >&5
+$as_echo "$ld_relro_support" >&6; }
+
+case $target_os in
+linux* | gnu*)
+ # -fhardened is only supported on GNU/Linux.
+ fhardened_support=yes
+ ;;
+*)
+ fhardened_support=no
+ ;;
+esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FHARDENED_SUPPORT `if test x"$fhardened_support" = xyes; then echo 1; else echo 0; fi`
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $fhardened_support" >&5
+$as_echo "$fhardened_support" >&6; }
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d9a3506..21ba631 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -778,49 +778,11 @@ if test x$ac_fold_checking != x ; then
fi
valgrind_path_defines=
valgrind_command=
-
-dnl # This check AC_REQUIREs various stuff, so it *must not* be inside
-dnl # an if statement. This was the source of very frustrating bugs
-dnl # in converting to autoconf 2.5x!
-AC_CHECK_HEADER(valgrind.h, have_valgrind_h=yes, have_valgrind_h=no)
-
-# It is certainly possible that there's valgrind but no valgrind.h.
-# GCC relies on making annotations so we must have both.
-AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
-AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <valgrind/memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif]])],
- [gcc_cv_header_valgrind_memcheck_h=yes],
- [gcc_cv_header_valgrind_memcheck_h=no])
-AC_MSG_RESULT($gcc_cv_header_valgrind_memcheck_h)
-AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
-AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif]])],
- [gcc_cv_header_memcheck_h=yes],
- [gcc_cv_header_memcheck_h=no])
-AC_MSG_RESULT($gcc_cv_header_memcheck_h)
-if test $gcc_cv_header_valgrind_memcheck_h = yes; then
- AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
- [Define if valgrind's valgrind/memcheck.h header is installed.])
-fi
-if test $gcc_cv_header_memcheck_h = yes; then
- AC_DEFINE(HAVE_MEMCHECK_H, 1,
- [Define if valgrind's memcheck.h header is installed.])
-fi
-
if test x$ac_valgrind_checking != x ; then
AM_PATH_PROG_WITH_TEST(valgrind_path, valgrind,
[$ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1])
- if test "x$valgrind_path" = "x" \
- || (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- AC_MSG_ERROR([*** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h])
+ if test "x$valgrind_path" = "x"; then
+ AC_MSG_ERROR([*** Cannot find valgrind])
fi
valgrind_path_defines=-DVALGRIND_PATH='\"'$valgrind_path'\"'
valgrind_command="$valgrind_path -q"
@@ -869,12 +831,11 @@ AC_ARG_ENABLE(valgrind-annotations,
[AS_HELP_STRING([--enable-valgrind-annotations],
[enable valgrind runtime interaction])], [],
[enable_valgrind_annotations=no])
+AC_CHECK_HEADER(valgrind/memcheck.h)
if test x$enable_valgrind_annotations != xno \
|| test x$ac_valgrind_checking != x; then
- if (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- AC_MSG_ERROR([*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h])
+ if test $ac_cv_header_valgrind_memcheck_h = no; then
+ AC_MSG_ERROR([*** Cannot find valgrind/memcheck.h])
fi
AC_DEFINE(ENABLE_VALGRIND_ANNOTATIONS, 1,
[Define to get calls to the valgrind runtime enabled.])
@@ -1894,6 +1855,23 @@ if test $force_sjlj_exceptions = yes; then
[Define 0/1 to force the choice for exception handling model.])
fi
+# Windows32 UTF-8 manifest support for running the driver and compiler
+# executables with the UTF-8 active code page on mingw hosts.
+# Non-mingw hosts ignore this option.
+# The shell variables this sets are picked up from the mingw branches
+# of config.host so they have to be set before it gets sourced.
+AC_ARG_ENABLE(win32-utf8-manifest,
+[AS_HELP_STRING([--disable-win32-utf8-manifest],
+ [disable embedding a utf8 manifest on mingw hosts])
+AS_HELP_STRING([--enable-win32-utf8-manifest],
+ [enable embedding a utf8 manifest on mingw hosts (default)])],,)
+
+if test "x$enable_win32_utf8_manifest" != xno; then
+ host_xmake_mingw=i386/x-mingw32-utf8
+ host_extra_gcc_objs_mingw=utf8rc-mingw32.o
+ host_extra_objs_mingw=utf8-mingw32.o
+fi
+
# --------------------------------------------------------
# Build, host, and target specific configuration fragments
# --------------------------------------------------------
@@ -7747,7 +7725,7 @@ if test x"$ld_is_gold" = xno; then
ld_bndplt_support=yes
fi
elif test x$gcc_cv_ld != x; then
- # Check if linker supports -a bndplt option
+ # Check if linker supports -z bndplt option
if $gcc_cv_ld --help 2>&1 | grep -- '-z bndplt' > /dev/null; then
ld_bndplt_support=yes
fi
@@ -7848,6 +7826,61 @@ standards-compatible mode on s390 targets.])
;;
esac
+# Check if the linker supports '-z now'
+ld_now_support=no
+AC_MSG_CHECKING(linker -z now option)
+if test x"$ld_is_gold" = xyes; then
+ ld_now_support=yes
+elif test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then
+ ld_now_support=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z now
+ if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then
+ ld_now_support=yes
+ fi
+fi
+AC_DEFINE_UNQUOTED(HAVE_LD_NOW_SUPPORT,
+ [`if test x"$ld_now_support" = xyes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if your linker supports -z now])
+AC_MSG_RESULT($ld_now_support)
+
+# Check if the linker supports '-z relro'
+ld_relro_support=no
+AC_MSG_CHECKING(linker -z relro option)
+if test x"$ld_is_gold" = xyes; then
+ ld_relro_support=yes
+elif test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then
+ ld_relro_support=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z relro
+ if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then
+ ld_relro_support=yes
+ fi
+fi
+AC_DEFINE_UNQUOTED(HAVE_LD_RELRO_SUPPORT,
+ [`if test x"$ld_relro_support" = xyes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if your linker supports -z relro])
+AC_MSG_RESULT($ld_relro_support)
+
+case $target_os in
+linux* | gnu*)
+ # -fhardened is only supported on GNU/Linux.
+ fhardened_support=yes
+ ;;
+*)
+ fhardened_support=no
+ ;;
+esac
+
+AC_DEFINE_UNQUOTED(HAVE_FHARDENED_SUPPORT,
+ [`if test x"$fhardened_support" = xyes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if -fhardened is supported])
+AC_MSG_RESULT($fhardened_support)
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
diff --git a/gcc/convert.cc b/gcc/convert.cc
index ac6af70..46c8bcb 100644
--- a/gcc/convert.cc
+++ b/gcc/convert.cc
@@ -292,7 +292,7 @@ convert_to_real_1 (tree type, tree expr, bool fold_p)
case NEGATE_EXPR:
if (!flag_rounding_math
&& FLOAT_TYPE_P (itype)
- && TYPE_PRECISION (type) < TYPE_PRECISION (itype))
+ && element_precision (type) < element_precision (itype))
{
tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
fold_p);
@@ -334,6 +334,10 @@ convert_to_real_1 (tree type, tree expr, bool fold_p)
error ("pointer value used where a floating-point was expected");
return error_mark_node;
+ case VECTOR_TYPE:
+ error ("vector value used where a floating-point was expected");
+ return error_mark_node;
+
default:
error ("aggregate value used where a floating-point was expected");
return error_mark_node;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1feb5b3..fb257ad 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,100 @@
+2023-11-25 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ * name-lookup.cc (check_can_export_using_decl): New.
+ (do_nonmember_using_decl): Use above to check if names can be
+ exported.
+
+2023-11-25 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/102341
+ * decl.cc (duplicate_decls): Allow exporting a redeclaration of
+ a typedef.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * parser.cc (cp_parser_omp_clause_dist_schedule,
+ cp_parser_omp_scan_loop_body, cp_parser_omp_assumption_clauses,
+ cp_parser_omp_depobj): Add OPT_Wopenmp to warning_at.
+ * semantics.cc (finish_omp_clauses): Likewise.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * parser.cc (cp_parser_omp_depobj): Accept optionally an argument
+ to the destroy clause.
+
+2023-11-24 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/99232
+ * decl.cc (grokvardecl): Don't mark variables attached to
+ modules as internal.
+
+2023-11-24 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/107398
+ * module.cc (trees_out::get_merge_kind): Handle lambdas in class
+ scope.
+ (maybe_key_decl): Remove assertion and fix whitespace.
+
+2023-11-24 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/98885
+ * decl.cc (duplicate_decls): Adjust error message.
+ (xref_tag): Adjust error message. Check exporting decl that is
+ already declared as non-exporting.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/110348
+ * parser.cc: Implement C++26 P2741R3 - user-generated static_assert
+ messages.
+ (cp_parser_static_assert): Parse message argument as
+ conditional-expression if it is not a pure string literal or
+ several of them concatenated followed by closing paren.
+ * semantics.cc (finish_static_assert): Handle message which is not
+ STRING_CST. For condition with bare parameter packs return early.
+ * pt.cc (tsubst_expr) <case STATIC_ASSERT>: Also tsubst_expr
+ message and make sure that if it wasn't originally STRING_CST, it
+ isn't after tsubst_expr either.
+
+2023-11-22 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/112633
+ * pt.cc (tsubst_aggr_type): Handle empty TYPE_TEMPLATE_INFO
+ in the entering_scope adjustment.
+
+2023-11-22 Jason Merrill <jason@redhat.com>
+
+ * decl.cc (start_preparsed_function): Clarify ctype logic.
+
+2023-11-20 Marc Poulhiès <dkm@kataplop.net>
+
+ * lambda.cc (compare_lambda_sig): Fix typo in variadic.
+
+2023-11-20 Jason Merrill <jason@redhat.com>
+
+ * pt.cc (comp_template_parms): Just one level.
+ (template_parameter_lists_equivalent_p): Likewise.
+
+2023-11-20 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_TEMPLATE_PARM_CHECK): New.
+ (DECL_IMPLICIT_TEMPLATE_PARM_P): New.
+ (decl_template_parm_check): New.
+ * mangle.cc (write_closure_template_head): Use it.
+ * parser.cc (synthesize_implicit_template_parm): Likewise.
+ * pt.cc (template_parameters_equivalent_p): Likewise.
+
+2023-11-19 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/99187
+ * cp-tree.h (enum cp_tree_index): Add CPTI_THREAD_ATEXIT.
+ (thread_atexit_node): New.
+ * decl.cc (get_thread_atexit_node): Cache in thread_atexit_node.
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * mapper-client.cc: Include "rich-location.h".
+
2023-11-16 Jakub Jelinek <jakub@redhat.com>
PR c++/112365
diff --git a/gcc/cp/cp-lang.cc b/gcc/cp/cp-lang.cc
index f2ed83d..bdc25dd 100644
--- a/gcc/cp/cp-lang.cc
+++ b/gcc/cp/cp-lang.cc
@@ -119,6 +119,15 @@ objcp_tsubst_expr (tree /*t*/, tree /*args*/, tsubst_flags_t /*complain*/,
return NULL_TREE;
}
+/* Implement c-family hook to add language-specific features
+ for __has_{feature,extension}. */
+
+void
+c_family_register_lang_features ()
+{
+ cp_register_features ();
+}
+
static const char *
cxx_dwarf_name (tree t, int verbosity)
{
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 2093ae0..70f9e4a 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -23,10 +23,154 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "cp-tree.h"
#include "cp-objcp-common.h"
+#include "c-family/c-common.h"
#include "dwarf2.h"
#include "stringpool.h"
#include "contracts.h"
+/* Class to determine whether a given C++ language feature is available.
+ Used to implement __has_{feature,extension}. */
+
+struct cp_feature_selector
+{
+ enum
+ {
+ DIALECT,
+ FLAG
+ } kind;
+
+ enum class result
+ {
+ NONE,
+ EXT,
+ FEAT
+ };
+
+ union
+ {
+ const int *enable_flag;
+ struct {
+ enum cxx_dialect feat;
+ enum cxx_dialect ext;
+ } dialect;
+ };
+
+ constexpr cp_feature_selector (const int *flag)
+ : kind (FLAG), enable_flag (flag) {}
+ constexpr cp_feature_selector (enum cxx_dialect feat,
+ enum cxx_dialect ext)
+ : kind (DIALECT), dialect{feat, ext} {}
+ constexpr cp_feature_selector (enum cxx_dialect feat)
+ : cp_feature_selector (feat, feat) {}
+
+ inline result has_feature () const;
+};
+
+/* Check whether this language feature is available as a feature,
+ extension, or not at all. */
+
+cp_feature_selector::result
+cp_feature_selector::has_feature () const
+{
+ switch (kind)
+ {
+ case DIALECT:
+ if (cxx_dialect >= dialect.feat)
+ return result::FEAT;
+ else if (cxx_dialect >= dialect.ext)
+ return result::EXT;
+ else
+ return result::NONE;
+ case FLAG:
+ return *enable_flag ? result::FEAT : result::NONE;
+ }
+
+ gcc_unreachable ();
+}
+
+/* Information about a C++ language feature which can be queried
+ through __has_{feature,extension}. IDENT is the name of the feature,
+ and SELECTOR encodes how to compute whether the feature is available. */
+
+struct cp_feature_info
+{
+ const char *ident;
+ cp_feature_selector selector;
+};
+
+/* Table of features for __has_{feature,extension}. */
+
+static constexpr cp_feature_info cp_feature_table[] =
+{
+ { "cxx_exceptions", &flag_exceptions },
+ { "cxx_rtti", &flag_rtti },
+ { "cxx_access_control_sfinae", { cxx11, cxx98 } },
+ { "cxx_alias_templates", cxx11 },
+ { "cxx_alignas", cxx11 },
+ { "cxx_alignof", cxx11 },
+ { "cxx_attributes", cxx11 },
+ { "cxx_constexpr", cxx11 },
+ { "cxx_constexpr_string_builtins", cxx11 },
+ { "cxx_decltype", cxx11 },
+ { "cxx_decltype_incomplete_return_types", cxx11 },
+ { "cxx_default_function_template_args", cxx11 },
+ { "cxx_defaulted_functions", cxx11 },
+ { "cxx_delegating_constructors", cxx11 },
+ { "cxx_deleted_functions", cxx11 },
+ { "cxx_explicit_conversions", cxx11 },
+ { "cxx_generalized_initializers", cxx11 },
+ { "cxx_implicit_moves", cxx11 },
+ { "cxx_inheriting_constructors", cxx11 },
+ { "cxx_inline_namespaces", { cxx11, cxx98 } },
+ { "cxx_lambdas", cxx11 },
+ { "cxx_local_type_template_args", cxx11 },
+ { "cxx_noexcept", cxx11 },
+ { "cxx_nonstatic_member_init", cxx11 },
+ { "cxx_nullptr", cxx11 },
+ { "cxx_override_control", cxx11 },
+ { "cxx_reference_qualified_functions", cxx11 },
+ { "cxx_range_for", cxx11 },
+ { "cxx_raw_string_literals", cxx11 },
+ { "cxx_rvalue_references", cxx11 },
+ { "cxx_static_assert", cxx11 },
+ { "cxx_thread_local", cxx11 },
+ { "cxx_auto_type", cxx11 },
+ { "cxx_strong_enums", cxx11 },
+ { "cxx_trailing_return", cxx11 },
+ { "cxx_unicode_literals", cxx11 },
+ { "cxx_unrestricted_unions", cxx11 },
+ { "cxx_user_literals", cxx11 },
+ { "cxx_variadic_templates", { cxx11, cxx98 } },
+ { "cxx_binary_literals", { cxx14, cxx98 } },
+ { "cxx_contextual_conversions", { cxx14, cxx98 } },
+ { "cxx_decltype_auto", cxx14 },
+ { "cxx_aggregate_nsdmi", cxx14 },
+ { "cxx_init_captures", cxx14 },
+ { "cxx_generic_lambdas", cxx14 },
+ { "cxx_relaxed_constexpr", cxx14 },
+ { "cxx_return_type_deduction", cxx14 },
+ { "cxx_variable_templates", cxx14 },
+ { "modules", &flag_modules },
+};
+
+/* Register C++ language features for __has_{feature,extension}. */
+
+void
+cp_register_features ()
+{
+ using result = cp_feature_selector::result;
+
+ for (unsigned i = 0; i < ARRAY_SIZE (cp_feature_table); i++)
+ {
+ const cp_feature_info *info = cp_feature_table + i;
+ const auto res = info->selector.has_feature ();
+ if (res == result::NONE)
+ continue;
+
+ c_common_register_feature (info->ident, res == result::FEAT);
+ }
+}
+
/* Special routine to get the alias set for C++. */
alias_set_type
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 1408301..5b175b0 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -34,6 +34,7 @@ extern tree cp_classtype_as_base (const_tree);
extern tree cp_get_global_decls ();
extern tree cp_pushdecl (tree);
extern void cp_register_dumps (gcc::dump_manager *);
+extern void cp_register_features ();
extern bool cp_handle_option (size_t, const char *, HOST_WIDE_INT, int,
location_t, const struct cl_option_handlers *);
extern tree cxx_make_type_hook (tree_code);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1fa710d..7b0b7c6 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -231,6 +231,7 @@ enum cp_tree_index
CPTI_RETHROW_FN,
CPTI_ATEXIT_FN_PTR_TYPE,
CPTI_ATEXIT,
+ CPTI_THREAD_ATEXIT,
CPTI_DSO_HANDLE,
CPTI_DCAST,
@@ -375,6 +376,9 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
/* A pointer to `std::atexit'. */
#define atexit_node cp_global_trees[CPTI_ATEXIT]
+/* A pointer to `__cxa_thread_atexit'. */
+#define thread_atexit_node cp_global_trees[CPTI_THREAD_ATEXIT]
+
/* A pointer to `__dso_handle'. */
#define dso_handle_node cp_global_trees[CPTI_DSO_HANDLE]
@@ -673,10 +677,14 @@ template_info_decl_check (const_tree t, const char* f, int l, const char* fn)
tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0); \
__t; })
+#define DECL_TEMPLATE_PARM_CHECK(NODE) \
+ decl_template_parm_check ((NODE), __FILE__, __LINE__, __FUNCTION__)
+
#else /* ENABLE_TREE_CHECKING */
#define TEMPLATE_INFO_DECL_CHECK(NODE) (NODE)
#define THUNK_FUNCTION_CHECK(NODE) (NODE)
+#define DECL_TEMPLATE_PARM_CHECK(NODE) (NODE)
#endif /* ENABLE_TREE_CHECKING */
@@ -3573,6 +3581,11 @@ struct GTY(()) lang_decl {
need. But we want a more descriptive name. */
#define DECL_VTABLE_OR_VTT_P(NODE) DECL_VIRTUAL_P (VAR_DECL_CHECK (NODE))
+/* 1 iff a _DECL for a template parameter came from
+ synthesize_implicit_template_parm. */
+#define DECL_IMPLICIT_TEMPLATE_PARM_P(NODE) \
+ DECL_VIRTUAL_P (DECL_TEMPLATE_PARM_CHECK (NODE))
+
/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */
#define FUNCTION_REF_QUALIFIED(NODE) \
TREE_LANG_FLAG_4 (FUNC_OR_METHOD_CHECK (NODE))
@@ -5053,6 +5066,16 @@ get_vec_init_expr (tree t)
|| TREE_CODE (NODE) == TYPE_DECL \
|| TREE_CODE (NODE) == TEMPLATE_DECL))
+#if ENABLE_TREE_CHECKING
+inline tree
+decl_template_parm_check (const_tree t, const char *f, int l, const char *fn)
+{
+ if (!DECL_TEMPLATE_PARM_P (t))
+ tree_check_failed (t, f, l, fn, 0);
+ return const_cast<tree>(t);
+}
+#endif
+
/* Nonzero for a raw template parameter node. */
#define TEMPLATE_PARM_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_TYPE_PARM \
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index b8e1098..e269f68 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2231,13 +2231,19 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
}
tree not_tmpl = STRIP_TEMPLATE (olddecl);
- if (DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_ATTACH_P (not_tmpl))
+ if (DECL_LANG_SPECIFIC (not_tmpl)
+ && DECL_MODULE_ATTACH_P (not_tmpl)
+ /* Typedefs are not entities and so are OK to be redeclared
+ as exported: see [module.interface]/p6. */
+ && TREE_CODE (olddecl) != TYPE_DECL)
{
if (DECL_MODULE_EXPORT_P (STRIP_TEMPLATE (newdecl))
&& !DECL_MODULE_EXPORT_P (not_tmpl))
{
- error ("conflicting exporting declaration %qD", newdecl);
- inform (olddecl_loc, "previous declaration %q#D here", olddecl);
+ auto_diagnostic_group d;
+ error ("conflicting exporting for declaration %qD", newdecl);
+ inform (olddecl_loc,
+ "previously declared here without exporting");
}
}
else if (DECL_MODULE_EXPORT_P (newdecl))
@@ -9593,6 +9599,9 @@ get_atexit_node (void)
static tree
get_thread_atexit_node (void)
{
+ if (thread_atexit_node)
+ return thread_atexit_node;
+
/* The declaration for `__cxa_thread_atexit' is:
int __cxa_thread_atexit (void (*)(void *), void *, void *) */
@@ -9601,10 +9610,18 @@ get_thread_atexit_node (void)
ptr_type_node, ptr_type_node,
NULL_TREE);
- /* Now, build the function declaration. */
+ /* Now, build the function declaration, as with __cxa_atexit. */
+ unsigned flags = push_abi_namespace ();
tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
ECF_LEAF | ECF_NOTHROW);
- return decay_conversion (atexit_fndecl, tf_warning_or_error);
+ DECL_CONTEXT (atexit_fndecl) = FROB_CONTEXT (current_namespace);
+ DECL_SOURCE_LOCATION (atexit_fndecl) = BUILTINS_LOCATION;
+ atexit_fndecl = pushdecl (atexit_fndecl, /*hiding=*/true);
+ pop_abi_namespace (flags);
+ mark_used (atexit_fndecl);
+ thread_atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
+
+ return thread_atexit_node;
}
/* Returns the __dso_handle VAR_DECL. */
@@ -10993,7 +11010,8 @@ grokvardecl (tree type,
&& (DECL_THIS_EXTERN (decl)
|| ! constp
|| volatilep
- || inlinep));
+ || inlinep
+ || module_attach_p ()));
TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
}
/* Not at top level, only `static' makes a static definition. */
@@ -16250,11 +16268,24 @@ xref_tag (enum tag_types tag_code, tree name,
tree decl = TYPE_NAME (t);
if (!module_may_redeclare (decl))
{
+ auto_diagnostic_group d;
error ("cannot declare %qD in a different module", decl);
- inform (DECL_SOURCE_LOCATION (decl), "declared here");
+ inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
return error_mark_node;
}
+ tree not_tmpl = STRIP_TEMPLATE (decl);
+ if (DECL_LANG_SPECIFIC (not_tmpl)
+ && DECL_MODULE_ATTACH_P (not_tmpl)
+ && !DECL_MODULE_EXPORT_P (not_tmpl)
+ && module_exporting_p ())
+ {
+ auto_diagnostic_group d;
+ error ("conflicting exporting for declaration %qD", decl);
+ inform (DECL_SOURCE_LOCATION (decl),
+ "previously declared here without exporting");
+ }
+
tree maybe_tmpl = decl;
if (CLASS_TYPE_P (t) && CLASSTYPE_IS_TEMPLATE (t))
maybe_tmpl = CLASSTYPE_TI_TEMPLATE (t);
@@ -17381,8 +17412,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
gcc_assert (TREE_CHAIN (void_list_node) == NULL_TREE);
tree fntype = TREE_TYPE (decl1);
- if (TREE_CODE (fntype) == METHOD_TYPE)
- ctype = TYPE_METHOD_BASETYPE (fntype);
+ if (DECL_CLASS_SCOPE_P (decl1))
+ ctype = DECL_CONTEXT (decl1);
else
{
ctype = DECL_FRIEND_CONTEXT (decl1);
@@ -17413,15 +17444,13 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
/* Sometimes we don't notice that a function is a static member, and
build a METHOD_TYPE for it. Fix that up now. */
- gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
+ gcc_assert (!(DECL_STATIC_FUNCTION_P (decl1)
&& TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));
/* Set up current_class_type, and enter the scope of the class, if
appropriate. */
if (ctype)
push_nested_class (ctype);
- else if (DECL_STATIC_FUNCTION_P (decl1))
- push_nested_class (DECL_CONTEXT (decl1));
/* Now that we have entered the scope of the class, we must restore
the bindings for any template parameters surrounding DECL1, if it
@@ -17458,7 +17487,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
tree newdecl1 = push_template_decl (decl1, doing_friend);
if (newdecl1 == error_mark_node)
{
- if (ctype || DECL_STATIC_FUNCTION_P (decl1))
+ if (ctype)
pop_nested_class ();
return false;
}
@@ -17610,7 +17639,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
/* Start the statement-tree, start the tree now. */
DECL_SAVED_TREE (decl1) = push_stmt_list ();
- if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1))
{
/* We know that this was set up by `grokclassfn'. We do not
wait until `store_parm_decls', since evil parse errors may
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index a359bc6..34d0190 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1619,7 +1619,7 @@ compare_lambda_sig (tree fn_a, tree fn_b)
{
if (!args_a || !args_b)
return false;
- // This check also deals with differing varadicness
+ // This check also deals with differing variadicness
if (!same_type_p (TREE_VALUE (args_a), TREE_VALUE (args_b)))
return false;
}
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index afa68da..5137305 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -1744,7 +1744,7 @@ write_closure_template_head (tree tmpl)
continue;
parm = TREE_VALUE (parm);
- if (DECL_VIRTUAL_P (parm))
+ if (DECL_IMPLICIT_TEMPLATE_PARM_P (parm))
// A synthetic parm, we're done.
break;
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 4f5b6e2..33fcf39 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -10418,13 +10418,16 @@ trees_out::get_merge_kind (tree decl, depset *dep)
case RECORD_TYPE:
case UNION_TYPE:
+ case NAMESPACE_DECL:
if (DECL_NAME (decl) == as_base_identifier)
- mk = MK_as_base;
- else if (IDENTIFIER_ANON_P (DECL_NAME (decl)))
- mk = MK_field;
- break;
+ {
+ mk = MK_as_base;
+ break;
+ }
- case NAMESPACE_DECL:
+ /* A lambda may have a class as its context, even though it
+ isn't a member in the traditional sense; see the test
+ g++.dg/modules/lambda-6_a.C. */
if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl))
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
if (tree scope
@@ -10437,6 +10440,13 @@ trees_out::get_merge_kind (tree decl, depset *dep)
break;
}
+ if (RECORD_OR_UNION_TYPE_P (ctx))
+ {
+ if (IDENTIFIER_ANON_P (DECL_NAME (decl)))
+ mk = MK_field;
+ break;
+ }
+
if (TREE_CODE (decl) == TEMPLATE_DECL
&& DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
mk = MK_local_friend;
@@ -18893,18 +18903,16 @@ maybe_key_decl (tree ctx, tree decl)
if (TREE_CODE (ctx) != VAR_DECL)
return;
- gcc_checking_assert (DECL_NAMESPACE_SCOPE_P (ctx));
-
- if (!keyed_table)
+ if (!keyed_table)
keyed_table = new keyed_map_t (EXPERIMENT (1, 400));
- auto &vec = keyed_table->get_or_insert (ctx);
- if (!vec.length ())
- {
- retrofit_lang_decl (ctx);
- DECL_MODULE_KEYED_DECLS_P (ctx) = true;
- }
- vec.safe_push (decl);
+ auto &vec = keyed_table->get_or_insert (ctx);
+ if (!vec.length ())
+ {
+ retrofit_lang_decl (ctx);
+ DECL_MODULE_KEYED_DECLS_P (ctx) = true;
+ }
+ vec.safe_push (decl);
}
/* Create the flat name string. It is simplest to have it handy. */
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 50aeb77..d19ea5d 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -4802,6 +4802,49 @@ pushdecl_outermost_localscope (tree x)
return b ? do_pushdecl_with_scope (x, b) : error_mark_node;
}
+/* Checks if BINDING is a binding that we can export. */
+
+static bool
+check_can_export_using_decl (tree binding)
+{
+ tree decl = STRIP_TEMPLATE (binding);
+
+ /* Linkage is determined by the owner of an enumerator. */
+ if (TREE_CODE (decl) == CONST_DECL)
+ decl = TYPE_NAME (DECL_CONTEXT (decl));
+
+ /* If the using decl is exported, the things it refers
+ to must also be exported (or not have module attachment). */
+ if (!DECL_MODULE_EXPORT_P (decl)
+ && (DECL_LANG_SPECIFIC (decl)
+ && DECL_MODULE_ATTACH_P (decl)))
+ {
+ bool internal_p = !TREE_PUBLIC (decl);
+
+ /* A template in an anonymous namespace doesn't constrain TREE_PUBLIC
+ until it's instantiated, so double-check its context. */
+ if (!internal_p && TREE_CODE (binding) == TEMPLATE_DECL)
+ internal_p = decl_internal_context_p (decl);
+
+ auto_diagnostic_group d;
+ error ("exporting %q#D that does not have external linkage",
+ binding);
+ if (TREE_CODE (decl) == TYPE_DECL && !DECL_IMPLICIT_TYPEDEF_P (decl))
+ /* An un-exported explicit type alias has no linkage. */
+ inform (DECL_SOURCE_LOCATION (binding),
+ "%q#D declared here with no linkage", binding);
+ else if (internal_p)
+ inform (DECL_SOURCE_LOCATION (binding),
+ "%q#D declared here with internal linkage", binding);
+ else
+ inform (DECL_SOURCE_LOCATION (binding),
+ "%q#D declared here with module linkage", binding);
+ return false;
+ }
+
+ return true;
+}
+
/* Process a local-scope or namespace-scope using declaration. LOOKUP
is the result of qualified lookup (both value & type are
significant). FN_SCOPE_P indicates if we're at function-scope (as
@@ -4845,23 +4888,7 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p,
tree new_fn = *usings;
bool exporting = revealing_p && module_exporting_p ();
if (exporting)
- {
- /* Module flags for templates are on the template_result. */
- tree decl = STRIP_TEMPLATE (new_fn);
-
- /* If the using decl is exported, the things it refers
- to must also be exported (or not have module attachment). */
- if (!DECL_MODULE_EXPORT_P (decl)
- && (DECL_LANG_SPECIFIC (decl)
- && DECL_MODULE_ATTACH_P (decl)))
- {
- auto_diagnostic_group d;
- error ("%q#D does not have external linkage", new_fn);
- inform (DECL_SOURCE_LOCATION (new_fn),
- "%q#D declared here", new_fn);
- exporting = false;
- }
- }
+ exporting = check_can_export_using_decl (new_fn);
/* [namespace.udecl]
@@ -4939,20 +4966,26 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p,
failed = true;
}
else if (insert_p)
- // FIXME:what if we're newly exporting lookup.value
- value = lookup.value;
+ {
+ value = lookup.value;
+ if (revealing_p && module_exporting_p ())
+ check_can_export_using_decl (value);
+ }
/* Now the type binding. */
if (lookup.type && lookup.type != type)
{
- // FIXME: What if we're exporting lookup.type?
if (type && !decls_match (lookup.type, type))
{
diagnose_name_conflict (lookup.type, type);
failed = true;
}
else if (insert_p)
- type = lookup.type;
+ {
+ type = lookup.type;
+ if (revealing_p && module_exporting_p ())
+ check_can_export_using_decl (type);
+ }
}
if (insert_p)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index d110433..2464d1a 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -16616,6 +16616,7 @@ cp_parser_linkage_specification (cp_parser* parser, tree prefix_attr)
static_assert-declaration:
static_assert ( constant-expression , string-literal ) ;
static_assert ( constant-expression ) ; (C++17)
+ static_assert ( constant-expression, conditional-expression ) ; (C++26)
If MEMBER_P, this static_assert is a class member. */
@@ -16646,10 +16647,10 @@ cp_parser_static_assert (cp_parser *parser, bool member_p)
/* Parse the constant-expression. Allow a non-constant expression
here in order to give better diagnostics in finish_static_assert. */
- condition =
- cp_parser_constant_expression (parser,
- /*allow_non_constant_p=*/true,
- /*non_constant_p=*/nullptr);
+ condition
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/true,
+ /*non_constant_p=*/nullptr);
if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
{
@@ -16668,8 +16669,32 @@ cp_parser_static_assert (cp_parser *parser, bool member_p)
/* Parse the separating `,'. */
cp_parser_require (parser, CPP_COMMA, RT_COMMA);
- /* Parse the string-literal message. */
- if (cxx_dialect >= cxx26)
+ /* Parse the message expression. */
+ bool string_lit = true;
+ for (unsigned int i = 1; ; ++i)
+ {
+ cp_token *tok = cp_lexer_peek_nth_token (parser->lexer, i);
+ if (cp_parser_is_pure_string_literal (tok))
+ continue;
+ else if (tok->type == CPP_CLOSE_PAREN)
+ break;
+ string_lit = false;
+ break;
+ }
+ if (!string_lit)
+ {
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ if (cxx_dialect < cxx26)
+ pedwarn (loc, OPT_Wc__26_extensions,
+ "%<static_assert%> with non-string message only "
+ "available with %<-std=c++2c%> or %<-std=gnu++2c%>");
+
+ message = cp_parser_conditional_expression (parser);
+ if (TREE_CODE (message) == STRING_CST)
+ message = build1_loc (loc, PAREN_EXPR, TREE_TYPE (message),
+ message);
+ }
+ else if (cxx_dialect >= cxx26)
message = cp_parser_unevaluated_string_literal (parser);
else
message = cp_parser_string_literal (parser, /*translate=*/false,
@@ -41136,7 +41161,7 @@ cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
/* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
"dist_schedule", location); */
if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
- warning_at (location, 0, "too many %qs clauses", "dist_schedule");
+ warning_at (location, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
OMP_CLAUSE_CHAIN (c) = list;
return c;
@@ -43148,6 +43173,9 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
destroy
update (dependence-type)
+ OpenMP 5.2 additionally:
+ destroy ( depobj )
+
dependence-type:
in
out
@@ -43194,7 +43222,27 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
clause = error_mark_node;
}
else if (!strcmp ("destroy", p))
- kind = OMP_CLAUSE_DEPEND_LAST;
+ {
+ kind = OMP_CLAUSE_DEPEND_LAST;
+ matching_parens c_parens;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ && c_parens.require_open (parser))
+ {
+ tree destobj = cp_parser_assignment_expression (parser);
+ if (depobj != error_mark_node
+ && destobj != error_mark_node
+ && !operand_equal_p (destobj, depobj, OEP_MATCH_SIDE_EFFECTS
+ | OEP_LEXICOGRAPHIC))
+ warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
+ "the %<destroy%> expression %qE should be the same "
+ "as the %<depobj%> argument %qE", destobj, depobj);
+ if (!c_parens.require_close (parser))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ }
+ }
else if (!strcmp ("update", p))
{
matching_parens c_parens;
@@ -44058,8 +44106,9 @@ cp_parser_omp_scan_loop_body (cp_parser *parser)
substmt = cp_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
else
{
- warning_at (tok->location, 0, "%<#pragma omp scan%> with zero preceding "
- "executable statements");
+ warning_at (tok->location, OPT_Wopenmp,
+ "%<#pragma omp scan%> with zero preceding executable "
+ "statements");
substmt = build_empty_stmt (tok->location);
}
substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
@@ -44105,8 +44154,9 @@ cp_parser_omp_scan_loop_body (cp_parser *parser)
else
{
if (found_scan)
- warning_at (tok->location, 0, "%<#pragma omp scan%> with zero "
- "succeeding executable statements");
+ warning_at (tok->location, OPT_Wopenmp,
+ "%<#pragma omp scan%> with zero succeeding executable "
+ "statements");
substmt = build_empty_stmt (tok->location);
}
substmt = build2_loc (tok->location, OMP_SCAN, void_type_node, substmt,
@@ -47803,7 +47853,7 @@ cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
}
else if (startswith (p, "ext_"))
{
- warning_at (cloc, 0, "unknown assumption clause %qs", p);
+ warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
cp_lexer_consume_token (parser->lexer);
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1;
@@ -50895,7 +50945,7 @@ synthesize_implicit_template_parm (cp_parser *parser, tree constr)
Note that DECL_ARTIFICIAL is used elsewhere for template
parameters. */
if (TREE_VALUE (new_parm) != error_mark_node)
- DECL_VIRTUAL_P (TREE_VALUE (new_parm)) = true;
+ DECL_IMPLICIT_TEMPLATE_PARM_P (TREE_VALUE (new_parm)) = true;
tree new_decl = get_local_decls ();
if (non_type)
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 324f6f0..092e6fd 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -3274,53 +3274,40 @@ check_explicit_specialization (tree declarator,
int
comp_template_parms (const_tree parms1, const_tree parms2)
{
- const_tree p1;
- const_tree p2;
-
if (parms1 == parms2)
return 1;
- for (p1 = parms1, p2 = parms2;
- p1 != NULL_TREE && p2 != NULL_TREE;
- p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2))
- {
- tree t1 = TREE_VALUE (p1);
- tree t2 = TREE_VALUE (p2);
- int i;
+ tree t1 = TREE_VALUE (parms1);
+ tree t2 = TREE_VALUE (parms2);
+ int i;
- gcc_assert (TREE_CODE (t1) == TREE_VEC);
- gcc_assert (TREE_CODE (t2) == TREE_VEC);
+ gcc_assert (TREE_CODE (t1) == TREE_VEC);
+ gcc_assert (TREE_CODE (t2) == TREE_VEC);
- if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
- return 0;
+ if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
+ return 0;
- for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
- {
- tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
- tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
+ for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
+ {
+ tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+ tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
- /* If either of the template parameters are invalid, assume
- they match for the sake of error recovery. */
- if (error_operand_p (parm1) || error_operand_p (parm2))
- return 1;
+ /* If either of the template parameters are invalid, assume
+ they match for the sake of error recovery. */
+ if (error_operand_p (parm1) || error_operand_p (parm2))
+ return 1;
- if (TREE_CODE (parm1) != TREE_CODE (parm2))
- return 0;
+ if (TREE_CODE (parm1) != TREE_CODE (parm2))
+ return 0;
- if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM
- && (TEMPLATE_TYPE_PARAMETER_PACK (parm1)
- == TEMPLATE_TYPE_PARAMETER_PACK (parm2)))
- continue;
- else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2)))
- return 0;
- }
+ if (TREE_CODE (parm1) == TYPE_DECL
+ && (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm1))
+ == TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm2))))
+ continue;
+ else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2)))
+ return 0;
}
- if ((p1 != NULL_TREE) != (p2 != NULL_TREE))
- /* One set of parameters has more parameters lists than the
- other. */
- return 0;
-
return 1;
}
@@ -3359,7 +3346,8 @@ template_parameters_equivalent_p (const_tree parm1, const_tree parm2)
/* ... one parameter was introduced by a parameter declaration, then
both are. This case arises as a result of eagerly rewriting declarations
during parsing. */
- if (DECL_VIRTUAL_P (decl1) != DECL_VIRTUAL_P (decl2))
+ if (DECL_IMPLICIT_TEMPLATE_PARM_P (decl1)
+ != DECL_IMPLICIT_TEMPLATE_PARM_P (decl2))
return false;
/* ... if either declares a pack, they both do. */
@@ -3402,31 +3390,20 @@ template_parameter_lists_equivalent_p (const_tree parms1, const_tree parms2)
if (parms1 == parms2)
return true;
- const_tree p1 = parms1;
- const_tree p2 = parms2;
- while (p1 != NULL_TREE && p2 != NULL_TREE)
- {
- tree list1 = TREE_VALUE (p1);
- tree list2 = TREE_VALUE (p2);
-
- if (TREE_VEC_LENGTH (list1) != TREE_VEC_LENGTH (list2))
- return 0;
+ tree list1 = TREE_VALUE (parms1);
+ tree list2 = TREE_VALUE (parms2);
- for (int i = 0; i < TREE_VEC_LENGTH (list2); ++i)
- {
- tree parm1 = TREE_VEC_ELT (list1, i);
- tree parm2 = TREE_VEC_ELT (list2, i);
- if (!template_parameters_equivalent_p (parm1, parm2))
- return false;
- }
+ if (TREE_VEC_LENGTH (list1) != TREE_VEC_LENGTH (list2))
+ return 0;
- p1 = TREE_CHAIN (p1);
- p2 = TREE_CHAIN (p2);
+ for (int i = 0; i < TREE_VEC_LENGTH (list2); ++i)
+ {
+ tree parm1 = TREE_VEC_ELT (list1, i);
+ tree parm2 = TREE_VEC_ELT (list2, i);
+ if (!template_parameters_equivalent_p (parm1, parm2))
+ return false;
}
- if ((p1 != NULL_TREE) != (p2 != NULL_TREE))
- return false;
-
return true;
}
@@ -13999,6 +13976,7 @@ tsubst_aggr_type (tree t,
if (entering_scope
&& CLASS_TYPE_P (t)
&& dependent_type_p (t)
+ && TYPE_TEMPLATE_INFO (t)
&& TYPE_CANONICAL (t) == TREE_TYPE (TYPE_TI_TEMPLATE (t)))
t = TYPE_CANONICAL (t);
@@ -18724,15 +18702,20 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case STATIC_ASSERT:
{
- tree condition;
+ tree condition, message;
++c_inhibit_evaluation_warnings;
condition = tsubst_expr (STATIC_ASSERT_CONDITION (t), args,
complain, in_decl);
+ message = tsubst_expr (STATIC_ASSERT_MESSAGE (t), args,
+ complain, in_decl);
+ if (TREE_CODE (STATIC_ASSERT_MESSAGE (t)) != STRING_CST
+ && TREE_CODE (message) == STRING_CST)
+ message = build1_loc (STATIC_ASSERT_SOURCE_LOCATION (t),
+ PAREN_EXPR, TREE_TYPE (message), message);
--c_inhibit_evaluation_warnings;
- finish_static_assert (condition,
- STATIC_ASSERT_MESSAGE (t),
+ finish_static_assert (condition, message,
STATIC_ASSERT_SOURCE_LOCATION (t),
/*member_p=*/false, /*show_expr_p=*/true);
}
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8090c71..3bf5864 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -7561,7 +7561,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
"positive");
break;
default:
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c),
+ (flag_openmp || flag_openmp_simd)
+ ? OPT_Wopenmp : 0,
"%qs value must be positive",
omp_clause_code_name
[OMP_CLAUSE_CODE (c)]);
@@ -7596,7 +7598,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (TREE_CODE (t) == INTEGER_CST
&& tree_int_cst_sgn (t) != 1)
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
"%qs value must be positive",
omp_clause_code_name
[OMP_CLAUSE_CODE (c)]);
@@ -7610,7 +7612,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
&& TREE_CODE (upper) == INTEGER_CST
&& tree_int_cst_lt (upper, t))
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
"%<num_teams%> lower bound %qE bigger "
"than upper bound %qE", t, upper);
t = NULL_TREE;
@@ -7643,7 +7645,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (TREE_CODE (t) == INTEGER_CST
&& tree_int_cst_sgn (t) != 1)
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
"chunk size value must be positive");
t = integer_one_node;
}
@@ -7739,7 +7741,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (TREE_CODE (t) == INTEGER_CST
&& tree_int_cst_sgn (t) != 1)
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
"%<thread_limit%> value must be positive");
t = integer_one_node;
}
@@ -7935,7 +7937,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
"%qD appears more than once in %<allocate%> clauses",
t);
remove = true;
@@ -8707,7 +8709,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (TREE_CODE (t) == INTEGER_CST
&& tree_int_cst_sgn (t) != 1)
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
"%<grainsize%> value must be positive");
t = integer_one_node;
}
@@ -8737,7 +8739,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (TREE_CODE (t) == INTEGER_CST
&& tree_int_cst_sgn (t) == -1)
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
"%<priority%> value must be non-negative");
t = integer_one_node;
}
@@ -11434,6 +11436,7 @@ finish_static_assert (tree condition, tree message, location_t location,
bool member_p, bool show_expr_p)
{
tsubst_flags_t complain = tf_warning_or_error;
+ tree message_sz = NULL_TREE, message_data = NULL_TREE;
if (message == NULL_TREE
|| message == error_mark_node
@@ -11441,13 +11444,61 @@ finish_static_assert (tree condition, tree message, location_t location,
|| condition == error_mark_node)
return;
- if (check_for_bare_parameter_packs (condition))
- condition = error_mark_node;
+ if (check_for_bare_parameter_packs (condition)
+ || check_for_bare_parameter_packs (message))
+ return;
+
+ if (TREE_CODE (message) != STRING_CST
+ && !type_dependent_expression_p (message))
+ {
+ message_sz
+ = finish_class_member_access_expr (message,
+ get_identifier ("size"),
+ false, complain);
+ if (message_sz != error_mark_node)
+ message_data
+ = finish_class_member_access_expr (message,
+ get_identifier ("data"),
+ false, complain);
+ if (message_sz == error_mark_node || message_data == error_mark_node)
+ {
+ error_at (location, "%<static_assert%> message must be a string "
+ "literal or object with %<size%> and "
+ "%<data%> members");
+ return;
+ }
+ releasing_vec size_args, data_args;
+ message_sz = finish_call_expr (message_sz, &size_args, false, false,
+ complain);
+ message_data = finish_call_expr (message_data, &data_args, false, false,
+ complain);
+ if (message_sz == error_mark_node || message_data == error_mark_node)
+ return;
+ message_sz = build_converted_constant_expr (size_type_node, message_sz,
+ complain);
+ if (message_sz == error_mark_node)
+ {
+ error_at (location, "%<static_assert%> message %<size()%> "
+ "must be implicitly convertible to "
+ "%<std::size_t%>");
+ return;
+ }
+ message_data = build_converted_constant_expr (const_string_type_node,
+ message_data, complain);
+ if (message_data == error_mark_node)
+ {
+ error_at (location, "%<static_assert%> message %<data()%> "
+ "must be implicitly convertible to "
+ "%<const char*%>");
+ return;
+ }
+ }
/* Save the condition in case it was a concept check. */
tree orig_condition = condition;
- if (instantiation_dependent_expression_p (condition))
+ if (instantiation_dependent_expression_p (condition)
+ || instantiation_dependent_expression_p (message))
{
/* We're in a template; build a STATIC_ASSERT and put it in
the right place. */
@@ -11485,9 +11536,89 @@ finish_static_assert (tree condition, tree message, location_t location,
if (processing_template_decl)
goto defer;
- int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
- (TREE_TYPE (TREE_TYPE (message))));
- int len = TREE_STRING_LENGTH (message) / sz - 1;
+ int len;
+ const char *msg = NULL;
+ char *buf = NULL;
+ if (message_sz && message_data)
+ {
+ tree msz = cxx_constant_value (message_sz, NULL_TREE, complain);
+ if (!tree_fits_uhwi_p (msz))
+ {
+ error_at (location,
+ "%<static_assert%> message %<size()%> "
+ "must be a constant expression");
+ return;
+ }
+ else if ((unsigned HOST_WIDE_INT) (int) tree_to_uhwi (msz)
+ != tree_to_uhwi (msz))
+ {
+ error_at (location,
+ "%<static_assert%> message %<size()%> "
+ "%qE too large", msz);
+ return;
+ }
+ len = tree_to_uhwi (msz);
+ tree data = maybe_constant_value (message_data, NULL_TREE,
+ mce_true);
+ if (!reduced_constant_expression_p (data))
+ data = NULL_TREE;
+ if (len)
+ {
+ if (data)
+ msg = c_getstr (data);
+ if (msg == NULL)
+ buf = XNEWVEC (char, len);
+ for (int i = 0; i < len; ++i)
+ {
+ tree t = message_data;
+ if (i)
+ t = build2 (POINTER_PLUS_EXPR,
+ TREE_TYPE (message_data), message_data,
+ size_int (i));
+ t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
+ tree t2 = cxx_constant_value (t, NULL_TREE, complain);
+ if (!tree_fits_shwi_p (t2))
+ {
+ error_at (location,
+ "%<static_assert%> message %<data()[%d]%> "
+ "must be a constant expression", i);
+ return;
+ }
+ if (msg == NULL)
+ buf[i] = tree_to_shwi (t2);
+ /* If c_getstr worked, just verify the first and
+ last characters using constant evaluation. */
+ else if (len > 2 && i == 0)
+ i = len - 2;
+ }
+ if (msg == NULL)
+ msg = buf;
+ }
+ else if (!data)
+ {
+ /* We don't have any function to test whether some
+ expression is a core constant expression. So, instead
+ test whether (message.data (), 0) is a constant
+ expression. */
+ data = build2 (COMPOUND_EXPR, integer_type_node,
+ message_data, integer_zero_node);
+ tree t = cxx_constant_value (data, NULL_TREE, complain);
+ if (!integer_zerop (t))
+ {
+ error_at (location,
+ "%<static_assert%> message %<data()%> "
+ "must be a core constant expression");
+ return;
+ }
+ }
+ }
+ else
+ {
+ tree eltype = TREE_TYPE (TREE_TYPE (message));
+ int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (eltype));
+ msg = TREE_STRING_POINTER (message);
+ len = TREE_STRING_LENGTH (message) / sz - 1;
+ }
/* See if we can find which clause was failing (for logical AND). */
tree bad = find_failing_clause (NULL, orig_condition);
@@ -11497,12 +11628,13 @@ finish_static_assert (tree condition, tree message, location_t location,
auto_diagnostic_group d;
- /* Report the error. */
+ /* Report the error. */
if (len == 0)
error_at (cloc, "static assertion failed");
else
- error_at (cloc, "static assertion failed: %s",
- TREE_STRING_POINTER (message));
+ error_at (cloc, "static assertion failed: %.*s", len, msg);
+
+ XDELETEVEC (buf);
diagnose_failing_condition (bad, cloc, show_expr_p);
}
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index cef86f2..2454da4 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,17 @@
+2023-11-21 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd ff57fec515.
+ * dmd/VERSION: Bump version to v2.106.0-rc.1.
+ * expr.cc (ExprVisitor::visit (CatAssignExp *)): Update for new
+ front-end interface.
+ (ExprVisitor::visit (NewExp *)): Likewise.
+ * runtime.def (NEWARRAYMTX): Remove.
+ (NEWARRAYMITX): Remove.
+
+2023-11-21 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd 65a3da148c.
+
2023-11-02 Iain Buclaw <ibuclaw@gdcproject.org>
* dmd/MERGE: Merge upstream dmd 643b1261bb.
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 235db4b..aa0062c 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-643b1261bba0757d97efa3ff1f63e461271eb000
+ff57fec51558013b25cadb7e83da9f4675915d56
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 b272d4b..41fdc65 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.106.0-beta.1
+v2.106.0-rc.1
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index d42ef95..307bb01 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -663,7 +663,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
*/
extern (D) final Dsymbol searchCtor()
{
- auto s = search(Loc.initial, Id.ctor);
+ auto s = this.search(Loc.initial, Id.ctor);
if (s)
{
if (!(s.isCtorDeclaration() ||
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index 58a0126..cd8f1a1 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -167,7 +167,6 @@ private:
public:
static StructDeclaration *create(const Loc &loc, Identifier *id, bool inObject);
StructDeclaration *syntaxCopy(Dsymbol *s) override;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
const char *kind() const override;
void finalizeSize() override final;
bool isPOD();
@@ -285,7 +284,6 @@ public:
virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);
bool isBaseInfoComplete();
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
void finalizeSize() override;
bool hasMonitor();
bool isFuncHidden(FuncDeclaration *fd);
diff --git a/gcc/d/dmd/arrayop.d b/gcc/d/dmd/arrayop.d
index 25bbb3f..c3b8526 100644
--- a/gcc/d/dmd/arrayop.d
+++ b/gcc/d/dmd/arrayop.d
@@ -172,7 +172,7 @@ Expression arrayOp(BinAssignExp e, Scope* sc)
}
if (e.e1.op == EXP.arrayLiteral)
{
- return e.e1.modifiableLvalue(sc, e.e1);
+ return e.e1.modifiableLvalue(sc);
}
return arrayOp(e.isBinExp(), sc);
diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d
index 77f36f3..6a9c010 100644
--- a/gcc/d/dmd/astenums.d
+++ b/gcc/d/dmd/astenums.d
@@ -383,6 +383,7 @@ enum STMT : ubyte
enum InitKind : ubyte
{
void_,
+ default_,
error,
struct_,
array,
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 49fc308..251e2e8 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -32,7 +32,7 @@ import dmd.declaration;
import dmd.dmodule;
import dmd.dscope;
import dmd.dsymbol;
-import dmd.dsymbolsem : dsymbolSemantic;
+import dmd.dsymbolsem;
import dmd.errors;
import dmd.expression;
import dmd.expressionsem;
@@ -123,18 +123,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol
return sc;
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- Dsymbols* d = include(sc);
- if (d)
- {
- Scope* sc2 = newScope(sc);
- d.foreachDsymbol( s => s.addMember(sc2, sds) );
- if (sc2 != sc)
- sc2.pop();
- }
- }
-
override void setScope(Scope* sc)
{
Dsymbols* d = include(sc);
@@ -295,34 +283,6 @@ extern (C++) class StorageClassDeclaration : AttribDeclaration
return t;
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- Dsymbols* d = include(sc);
- if (d)
- {
- Scope* sc2 = newScope(sc);
-
- d.foreachDsymbol( (s)
- {
- //printf("\taddMember %s to %s\n", s.toChars(), sds.toChars());
- // STC.local needs to be attached before the member is added to the scope (because it influences the parent symbol)
- if (auto decl = s.isDeclaration())
- {
- decl.storage_class |= stc & STC.local;
- if (auto sdecl = s.isStorageClassDeclaration()) // TODO: why is this not enough to deal with the nested case?
- {
- sdecl.stc |= stc & STC.local;
- }
- }
- s.addMember(sc2, sds);
- });
-
- if (sc2 != sc)
- sc2.pop();
- }
-
- }
-
override inout(StorageClassDeclaration) isStorageClassDeclaration() inout
{
return this;
@@ -640,37 +600,6 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration
return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, this.visibility, 1, sc.aligndecl, sc.inlining);
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- if (pkg_identifiers)
- {
- Dsymbol tmp;
- Package.resolve(pkg_identifiers, &tmp, null);
- visibility.pkg = tmp ? tmp.isPackage() : null;
- pkg_identifiers = null;
- }
- if (visibility.kind == Visibility.Kind.package_ && visibility.pkg && sc._module)
- {
- Module m = sc._module;
-
- // https://issues.dlang.org/show_bug.cgi?id=17441
- // While isAncestorPackageOf does an equality check, the fix for the issue adds a check to see if
- // each package's .isModule() properites are equal.
- //
- // Properties generated from `package(foo)` i.e. visibility.pkg have .isModule() == null.
- // This breaks package declarations of the package in question if they are declared in
- // the same package.d file, which _do_ have a module associated with them, and hence a non-null
- // isModule()
- if (!m.isPackage() || !visibility.pkg.ident.equals(m.isPackage().ident))
- {
- Package pkg = m.parent ? m.parent.isPackage() : null;
- if (!pkg || !visibility.pkg.isAncestorPackageOf(pkg))
- .error(loc, "%s `%s` does not bind to one of ancestor packages of module `%s`", kind(), toPrettyChars(false), m.toPrettyChars(true));
- }
- }
- return AttribDeclaration.addMember(sc, sds);
- }
-
override const(char)* kind() const
{
return "visibility attribute";
@@ -1054,23 +983,6 @@ extern (C++) final class StaticIfDeclaration : ConditionalDeclaration
}
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- //printf("StaticIfDeclaration::addMember() '%s'\n", toChars());
- /* This is deferred until the condition evaluated later (by the include() call),
- * so that expressions in the condition can refer to declarations
- * in the same scope, such as:
- *
- * template Foo(int i)
- * {
- * const int j = i + 1;
- * static if (j == 3)
- * const int k;
- * }
- */
- this.scopesym = sds;
- }
-
override void setScope(Scope* sc)
{
// do not evaluate condition before semantic pass
@@ -1186,12 +1098,6 @@ extern (C++) final class StaticForeachDeclaration : AttribDeclaration
return d;
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- // used only for caching the enclosing symbol
- this.scopesym = sds;
- }
-
override void addComment(const(char)* comment)
{
// do nothing
@@ -1266,15 +1172,6 @@ extern(C++) final class ForwardingAttribDeclaration : AttribDeclaration
return sc.push(sym);
}
- /***************************************
- * Lazily initializes the scope to forward to.
- */
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- sym.parent = sds;
- return super.addMember(sc, sym);
- }
-
override inout(ForwardingAttribDeclaration) isForwardingAttribDeclaration() inout
{
return this;
@@ -1312,12 +1209,6 @@ extern (C++) final class MixinDeclaration : AttribDeclaration
return new MixinDeclaration(loc, Expression.arraySyntaxCopy(exps));
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- //printf("MixinDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\n", sc, sds, memnum);
- this.scopesym = sds;
- }
-
override void setScope(Scope* sc)
{
Dsymbol.setScope(sc);
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index f47a1f6..efea9af 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -26,7 +26,6 @@ public:
virtual Dsymbols *include(Scope *sc);
virtual Scope *newScope(Scope *sc);
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
void setScope(Scope *sc) override;
void importAll(Scope *sc) override;
void addComment(const utf8_t *comment) override;
@@ -49,7 +48,6 @@ public:
StorageClassDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
bool oneMember(Dsymbol **ps, Identifier *ident) override final;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
StorageClassDeclaration *isStorageClassDeclaration() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
@@ -110,7 +108,6 @@ public:
VisibilityDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
const char *kind() const override;
const char *toPrettyChars(bool unused) override;
VisibilityDeclaration *isVisibilityDeclaration() override { return this; }
@@ -179,7 +176,6 @@ public:
StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
Dsymbols *include(Scope *sc) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
void setScope(Scope *sc) override;
void importAll(Scope *sc) override;
StaticIfDeclaration *isStaticIfDeclaration() override { return this; }
@@ -199,7 +195,6 @@ public:
StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
bool oneMember(Dsymbol **ps, Identifier *ident) override;
Dsymbols *include(Scope *sc) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
void addComment(const utf8_t *comment) override;
void setScope(Scope *sc) override;
void importAll(Scope *sc) override;
@@ -213,7 +208,6 @@ public:
ForwardingScopeDsymbol *sym;
Scope *newScope(Scope *sc) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
ForwardingAttribDeclaration *isForwardingAttribDeclaration() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
};
@@ -229,7 +223,6 @@ public:
d_bool compiled;
MixinDeclaration *syntaxCopy(Dsymbol *s) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
void setScope(Scope *sc) override;
const char *kind() const override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index 8aece3b..6730592 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -22,6 +22,7 @@ import dmd.declaration;
import dmd.dsymbol;
import dmd.errorsink;
import dmd.expression;
+import dmd.expressionsem;
import dmd.func;
import dmd.globals;
import dmd.init;
@@ -80,7 +81,7 @@ CT canThrow(Expression e, FuncDeclaration func, ErrorSink eSink)
if (!f.isDtorDeclaration())
errorSupplementalInferredAttr(f, 10, false, STC.nothrow_);
- e.checkOverriddenDtor(null, f, dd => dd.type.toTypeFunction().isnothrow, "not nothrow");
+ f.checkOverriddenDtor(null, e.loc, dd => dd.type.toTypeFunction().isnothrow, "not nothrow");
}
else if (func)
{
diff --git a/gcc/d/dmd/common/outbuffer.d b/gcc/d/dmd/common/outbuffer.d
index b8ad785..4e7a82f 100644
--- a/gcc/d/dmd/common/outbuffer.d
+++ b/gcc/d/dmd/common/outbuffer.d
@@ -281,7 +281,7 @@ struct OutBuffer
write(&v, v.sizeof);
}
- /// NOT zero-terminated
+ /// Buffer will NOT be zero-terminated
extern (C++) void writestring(const(char)* s) pure nothrow @system
{
if (!s)
@@ -302,14 +302,14 @@ struct OutBuffer
write(s);
}
- /// NOT zero-terminated, followed by newline
+ /// Buffer will NOT be zero-terminated, followed by newline
void writestringln(const(char)[] s) pure nothrow @safe
{
writestring(s);
writenl();
}
- /** Write string to buffer, ensure it is zero terminated
+ /** Write C string AND null byte
*/
void writeStringz(const(char)* s) pure nothrow @system
{
diff --git a/gcc/d/dmd/compiler.d b/gcc/d/dmd/compiler.d
index e85cc20..8b8a453 100644
--- a/gcc/d/dmd/compiler.d
+++ b/gcc/d/dmd/compiler.d
@@ -12,6 +12,7 @@
module dmd.compiler;
import dmd.arraytypes;
+import dmd.ctfeexpr;
import dmd.dmodule;
import dmd.expression;
import dmd.mtype;
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index a8d0994..568b639 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -29,6 +29,7 @@ import dmd.globals;
import dmd.identifier;
import dmd.location;
import dmd.mtype;
+import dmd.optimize;
import dmd.typesem;
import dmd.common.outbuffer;
import dmd.rootobject;
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index b8e8052..ed5f1f8 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -2023,6 +2023,9 @@ final class CParser(AST) : Parser!AST
}
symbols.push(s);
}
+ if (level == LVL.global && !id)
+ error("expected identifier for declaration");
+
first = false;
switch (token.value)
@@ -2165,6 +2168,7 @@ final class CParser(AST) : Parser!AST
* C11 Initialization
* initializer:
* assignment-expression
+ * { } // C23 6.7.10 addition
* { initializer-list }
* { initializer-list , }
*
@@ -2195,6 +2199,12 @@ final class CParser(AST) : Parser!AST
nextToken();
const loc = token.loc;
+ if (token.value == TOK.rightCurly) // { }
+ {
+ nextToken();
+ return new AST.DefaultInitializer(loc);
+ }
+
/* Collect one or more `designation (opt) initializer`
* into ci.initializerList, but lazily create ci
*/
@@ -2736,7 +2746,7 @@ final class CParser(AST) : Parser!AST
private AST.Type cparseDeclarator(DTR declarator, AST.Type tbase,
out Identifier pident, ref Specifier specifier)
{
- //printf("cparseDeclarator(%d, %p)\n", declarator, t);
+ //printf("cparseDeclarator(%d, %s)\n", declarator, tbase.toChars());
AST.Types constTypes; // all the Types that will need `const` applied to them
/* Insert tx -> t into
@@ -2755,6 +2765,7 @@ final class CParser(AST) : Parser!AST
AST.Type parseDecl(AST.Type t)
{
+ //printf("parseDecl() t: %s\n", t.toChars());
AST.Type ts;
while (1)
{
@@ -2770,9 +2781,18 @@ final class CParser(AST) : Parser!AST
break;
case TOK.leftParenthesis: // ( declarator )
+ //printf("leftParen\n");
/* like: T (*fp)();
* T ((*fp))();
*/
+ auto tk = &token;
+ if (!isCDeclarator(tk, declarator))
+ {
+ /* Not ( declarator ), might be parameter-list
+ */
+ ts = t;
+ break;
+ }
nextToken();
if (token.value == TOK.__stdcall) // T (__stdcall*fp)();
@@ -2786,6 +2806,7 @@ final class CParser(AST) : Parser!AST
break;
case TOK.mul: // pointer
+ //printf("star\n");
t = new AST.TypePointer(t);
nextToken();
// add post fixes const/volatile/restrict/_Atomic
@@ -2797,6 +2818,7 @@ final class CParser(AST) : Parser!AST
continue;
default:
+ //printf("default %s\n", token.toChars());
if (declarator == DTR.xdirect)
{
if (!t || t.isTypeIdentifier())
@@ -2914,7 +2936,7 @@ final class CParser(AST) : Parser!AST
if (specifier._pure)
stc |= STC.pure_;
AST.Type tf = new AST.TypeFunction(parameterList, t, lkg, stc);
- // tf = tf.addSTC(storageClass); // TODO
+ //tf = tf.addSTC(storageClass); // TODO
insertTx(ts, tf, t); // ts -> ... -> tf -> t
if (ts != tf)
@@ -2927,6 +2949,8 @@ final class CParser(AST) : Parser!AST
}
break;
}
+ if (declarator == DTR.xdirect && !pident)
+ error("expected identifier for declarator");
return ts;
}
@@ -4556,6 +4580,7 @@ final class CParser(AST) : Parser!AST
*/
private bool isCDeclarator(ref Token* pt, DTR declarator)
{
+ //printf("isCDeclarator()\n");
auto t = pt;
while (1)
{
@@ -4578,6 +4603,8 @@ final class CParser(AST) : Parser!AST
else if (t.value == TOK.leftParenthesis)
{
t = peek(t);
+ if (t.value == TOK.__stdcall)
+ t = peek(t);
if (!isCDeclarator(t, declarator))
return false;
if (t.value != TOK.rightParenthesis)
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index ddfb57d..43efc05 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -28,6 +28,7 @@ import dmd.func;
import dmd.globals;
import dmd.location;
import dmd.mtype;
+import dmd.root.bitarray;
import dmd.root.complex;
import dmd.root.ctfloat;
import dmd.root.port;
@@ -35,75 +36,98 @@ import dmd.root.rmem;
import dmd.tokens;
import dmd.visitor;
-
-/***********************************************************
- * A reference to a class, or an interface. We need this when we
- * point to a base class (we must record what the type is).
+/****************************************************************/
+/* A type meant as a union of all the Expression types,
+ * to serve essentially as a Variant that will sit on the stack
+ * during CTFE to reduce memory consumption.
*/
-extern (C++) final class ClassReferenceExp : Expression
+extern (D) struct UnionExp
{
- StructLiteralExp value;
-
- extern (D) this(const ref Loc loc, StructLiteralExp lit, Type type) @safe
+ // yes, default constructor does nothing
+ extern (D) this(Expression e) nothrow
{
- super(loc, EXP.classReference);
- assert(lit && lit.sd && lit.sd.isClassDeclaration());
- this.value = lit;
- this.type = type;
+ memcpy(&this, cast(void*)e, e.size);
}
- ClassDeclaration originalClass()
+ /* Extract pointer to Expression
+ */
+ extern (D) Expression exp() return nothrow
{
- return value.sd.isClassDeclaration();
+ return cast(Expression)&u;
}
- // Return index of the field, or -1 if not found
- private int getFieldIndex(Type fieldtype, uint fieldoffset)
+ /* Convert to an allocated Expression
+ */
+ extern (D) Expression copy()
{
- ClassDeclaration cd = originalClass();
- uint fieldsSoFar = 0;
- for (size_t j = 0; j < value.elements.length; j++)
+ Expression e = exp();
+ //if (e.size > sizeof(u)) printf("%s\n", EXPtoString(e.op).ptr);
+ assert(e.size <= u.sizeof);
+ switch (e.op)
{
- while (j - fieldsSoFar >= cd.fields.length)
- {
- fieldsSoFar += cd.fields.length;
- cd = cd.baseClass;
- }
- VarDeclaration v2 = cd.fields[j - fieldsSoFar];
- if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())
- {
- return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
- }
+ case EXP.cantExpression: return CTFEExp.cantexp;
+ case EXP.voidExpression: return CTFEExp.voidexp;
+ case EXP.break_: return CTFEExp.breakexp;
+ case EXP.continue_: return CTFEExp.continueexp;
+ case EXP.goto_: return CTFEExp.gotoexp;
+ default: return e.copy();
}
- return -1;
}
- // Return index of the field, or -1 if not found
- // Same as getFieldIndex, but checks for a direct match with the VarDeclaration
- int findFieldIndexByName(VarDeclaration v)
- {
- ClassDeclaration cd = originalClass();
- size_t fieldsSoFar = 0;
- for (size_t j = 0; j < value.elements.length; j++)
- {
- while (j - fieldsSoFar >= cd.fields.length)
- {
- fieldsSoFar += cd.fields.length;
- cd = cd.baseClass;
- }
- VarDeclaration v2 = cd.fields[j - fieldsSoFar];
- if (v == v2)
- {
- return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
- }
- }
- return -1;
- }
+private:
+ // Ensure that the union is suitably aligned.
+ align(8) union _AnonStruct_u
+ {
+ char[__traits(classInstanceSize, Expression)] exp;
+ char[__traits(classInstanceSize, IntegerExp)] integerexp;
+ char[__traits(classInstanceSize, ErrorExp)] errorexp;
+ char[__traits(classInstanceSize, RealExp)] realexp;
+ char[__traits(classInstanceSize, ComplexExp)] complexexp;
+ char[__traits(classInstanceSize, SymOffExp)] symoffexp;
+ char[__traits(classInstanceSize, StringExp)] stringexp;
+ char[__traits(classInstanceSize, ArrayLiteralExp)] arrayliteralexp;
+ char[__traits(classInstanceSize, AssocArrayLiteralExp)] assocarrayliteralexp;
+ char[__traits(classInstanceSize, StructLiteralExp)] structliteralexp;
+ char[__traits(classInstanceSize, CompoundLiteralExp)] compoundliteralexp;
+ char[__traits(classInstanceSize, NullExp)] nullexp;
+ char[__traits(classInstanceSize, DotVarExp)] dotvarexp;
+ char[__traits(classInstanceSize, AddrExp)] addrexp;
+ char[__traits(classInstanceSize, IndexExp)] indexexp;
+ char[__traits(classInstanceSize, SliceExp)] sliceexp;
+ char[__traits(classInstanceSize, VectorExp)] vectorexp;
+ }
+
+ _AnonStruct_u u;
+}
- override void accept(Visitor v)
- {
- v.visit(this);
- }
+void emplaceExp(T : Expression, Args...)(void* p, Args args)
+{
+ static if (__VERSION__ < 2099)
+ const init = typeid(T).initializer;
+ else
+ const init = __traits(initSymbol, T);
+ p[0 .. __traits(classInstanceSize, T)] = init[];
+ (cast(T)p).__ctor(args);
+}
+
+void emplaceExp(T : UnionExp)(T* p, Expression e) nothrow
+{
+ memcpy(p, cast(void*)e, e.size);
+}
+
+// Generate an error message when this exception is not caught
+void generateUncaughtError(ThrownExceptionExp tee)
+{
+ UnionExp ue = void;
+ Expression e = resolveSlice((*tee.thrown.value.elements)[0], &ue);
+ StringExp se = e.toStringExp();
+ error(tee.thrown.loc, "uncaught CTFE exception `%s(%s)`", tee.thrown.type.toChars(), se ? se.toChars() : e.toChars());
+ /* Also give the line where the throw statement was. We won't have it
+ * in the case where the ThrowStatement is generated internally
+ * (eg, in ScopeStatement)
+ */
+ if (tee.loc.isValid() && !tee.loc.equals(tee.thrown.loc))
+ .errorSupplemental(tee.loc, "thrown from here");
}
/*************************
@@ -111,7 +135,7 @@ extern (C++) final class ClassReferenceExp : Expression
* Returns:
* index of the field, or -1 if not found
*/
-int findFieldIndexByName(const StructDeclaration sd, const VarDeclaration v) pure @safe
+int findFieldIndexByName(const StructDeclaration sd, const VarDeclaration v) pure @safe nothrow
{
foreach (i, field; sd.fields)
{
@@ -121,102 +145,8 @@ int findFieldIndexByName(const StructDeclaration sd, const VarDeclaration v) pur
return -1;
}
-/***********************************************************
- * Fake class which holds the thrown exception.
- * Used for implementing exception handling.
- */
-extern (C++) final class ThrownExceptionExp : Expression
-{
- ClassReferenceExp thrown; // the thing being tossed
-
- extern (D) this(const ref Loc loc, ClassReferenceExp victim) @safe
- {
- super(loc, EXP.thrownException);
- this.thrown = victim;
- this.type = victim.type;
- }
-
- override const(char)* toChars() const
- {
- return "CTFE ThrownException";
- }
-
- // Generate an error message when this exception is not caught
- extern (D) void generateUncaughtError()
- {
- UnionExp ue = void;
- Expression e = resolveSlice((*thrown.value.elements)[0], &ue);
- StringExp se = e.toStringExp();
- error(thrown.loc, "uncaught CTFE exception `%s(%s)`", thrown.type.toChars(), se ? se.toChars() : e.toChars());
- /* Also give the line where the throw statement was. We won't have it
- * in the case where the ThrowStatement is generated internally
- * (eg, in ScopeStatement)
- */
- if (loc.isValid() && !loc.equals(thrown.loc))
- .errorSupplemental(loc, "thrown from here");
- }
-
- override void accept(Visitor v)
- {
- v.visit(this);
- }
-}
-
-/***********************************************************
- * This type is only used by the interpreter.
- */
-extern (C++) final class CTFEExp : Expression
-{
- extern (D) this(EXP tok)
- {
- super(Loc.initial, tok);
- type = Type.tvoid;
- }
-
- override const(char)* toChars() const
- {
- switch (op)
- {
- case EXP.cantExpression:
- return "<cant>";
- case EXP.voidExpression:
- return "cast(void)0";
- case EXP.showCtfeContext:
- return "<error>";
- case EXP.break_:
- return "<break>";
- case EXP.continue_:
- return "<continue>";
- case EXP.goto_:
- return "<goto>";
- default:
- assert(0);
- }
- }
-
- extern (D) __gshared CTFEExp cantexp;
- extern (D) __gshared CTFEExp voidexp;
- extern (D) __gshared CTFEExp breakexp;
- extern (D) __gshared CTFEExp continueexp;
- extern (D) __gshared CTFEExp gotoexp;
- /* Used when additional information is needed regarding
- * a ctfe error.
- */
- extern (D) __gshared CTFEExp showcontext;
-
- extern (D) static bool isCantExp(const Expression e) @safe
- {
- return e && e.op == EXP.cantExpression;
- }
-
- extern (D) static bool isGotoExp(const Expression e) @safe
- {
- return e && e.op == EXP.goto_;
- }
-}
-
// True if 'e' is CTFEExp::cantexp, or an exception
-bool exceptionOrCantInterpret(const Expression e) @safe
+bool exceptionOrCantInterpret(const Expression e) @safe nothrow
{
return e && (e.op == EXP.cantExpression || e.op == EXP.thrownException || e.op == EXP.showCtfeContext);
}
@@ -224,7 +154,7 @@ bool exceptionOrCantInterpret(const Expression e) @safe
/************** Aggregate literals (AA/string/array/struct) ******************/
// Given expr, which evaluates to an array/AA/string literal,
// return true if it needs to be copied
-bool needToCopyLiteral(const Expression expr)
+bool needToCopyLiteral(const Expression expr) nothrow
{
Expression e = cast()expr;
for (;;)
@@ -664,7 +594,7 @@ TypeAArray toBuiltinAAType(Type t)
/************** TypeInfo operations ************************************/
// Return true if type is TypeInfo_Class
-bool isTypeInfo_Class(const Type type)
+bool isTypeInfo_Class(const Type type) nothrow
{
auto tc = cast()type.isTypeClass();
return tc && (Type.dtypeinfo == tc.sym || Type.dtypeinfo.isBaseOf(tc.sym, null));
@@ -812,14 +742,14 @@ Expression pointerDifference(UnionExp* pue, const ref Loc loc, Type type, Expres
Expression agg2 = getAggregateFromPointer(e2, &ofs2);
if (agg1 == agg2)
{
- Type pointee = (cast(TypePointer)agg1.type).next;
+ Type pointee = agg1.type.nextOf();
const sz = pointee.size();
emplaceExp!(IntegerExp)(pue, loc, (ofs1 - ofs2) * sz, type);
}
else if (agg1.op == EXP.string_ && agg2.op == EXP.string_ &&
agg1.isStringExp().peekString().ptr == agg2.isStringExp().peekString().ptr)
{
- Type pointee = (cast(TypePointer)agg1.type).next;
+ Type pointee = agg1.type.nextOf();
const sz = pointee.size();
emplaceExp!(IntegerExp)(pue, loc, (ofs1 - ofs2) * sz, type);
}
@@ -865,14 +795,14 @@ Expression pointerArithmetic(UnionExp* pue, const ref Loc loc, EXP op, Type type
goto Lcant;
}
dinteger_t ofs2 = e2.toInteger();
- Type pointee = (cast(TypeNext)agg1.type.toBasetype()).next;
+ Type pointee = agg1.type.toBasetype().nextOf();
dinteger_t sz = pointee.size();
sinteger_t indx;
dinteger_t len;
- if (agg1.op == EXP.symbolOffset)
+ if (auto soe = agg1.isSymOffExp())
{
indx = ofs1 / sz;
- len = (cast(TypeSArray)agg1.isSymOffExp().var.type).dim.toInteger();
+ len = soe.var.type.isTypeSArray().dim.toInteger();
}
else
{
@@ -907,9 +837,9 @@ Expression pointerArithmetic(UnionExp* pue, const ref Loc loc, EXP op, Type type
error(loc, "CTFE internal error: pointer arithmetic `%s`", agg1.toChars());
goto Lcant;
}
- if (eptr.type.toBasetype().ty == Tsarray)
+ if (auto tsa = eptr.type.toBasetype().isTypeSArray())
{
- dinteger_t dim = (cast(TypeSArray)eptr.type.toBasetype()).dim.toInteger();
+ dinteger_t dim = tsa.dim.toInteger();
// Create a CTFE pointer &agg1[indx .. indx+dim]
auto se = ctfeEmplaceExp!SliceExp(loc, agg1,
ctfeEmplaceExp!IntegerExp(loc, indx, Type.tsize_t),
@@ -1049,7 +979,7 @@ bool isCtfeComparable(Expression e)
}
/// Map EXP comparison ops
-private bool numCmp(N)(EXP op, N n1, N n2)
+private bool numCmp(N)(EXP op, N n1, N n2) nothrow
{
switch (op)
{
@@ -1068,25 +998,25 @@ private bool numCmp(N)(EXP op, N n1, N n2)
}
/// Returns cmp OP 0; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-bool specificCmp(EXP op, int rawCmp) @safe
+bool specificCmp(EXP op, int rawCmp) @safe nothrow
{
return numCmp!int(op, rawCmp, 0);
}
/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-bool intUnsignedCmp(EXP op, dinteger_t n1, dinteger_t n2) @safe
+bool intUnsignedCmp(EXP op, dinteger_t n1, dinteger_t n2) @safe nothrow
{
return numCmp!dinteger_t(op, n1, n2);
}
/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-bool intSignedCmp(EXP op, sinteger_t n1, sinteger_t n2) @safe
+bool intSignedCmp(EXP op, sinteger_t n1, sinteger_t n2) @safe nothrow
{
return numCmp!sinteger_t(op, n1, n2);
}
/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-bool realCmp(EXP op, real_t r1, real_t r2) @safe
+bool realCmp(EXP op, real_t r1, real_t r2) @safe nothrow
{
// Don't rely on compiler, handle NAN arguments separately
if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered
@@ -1176,7 +1106,7 @@ private int ctfeCmpArrays(const ref Loc loc, Expression e1, Expression e2, uinte
/* Given a delegate expression e, return .funcptr.
* If e is NullExp, return NULL.
*/
-private FuncDeclaration funcptrOf(Expression e) @safe
+private FuncDeclaration funcptrOf(Expression e) @safe nothrow
{
assert(e.type.ty == Tdelegate);
if (auto de = e.isDelegateExp())
@@ -1187,7 +1117,7 @@ private FuncDeclaration funcptrOf(Expression e) @safe
return null;
}
-private bool isArray(const Expression e) @safe
+private bool isArray(const Expression e) @safe nothrow
{
return e.op == EXP.arrayLiteral || e.op == EXP.string_ || e.op == EXP.slice || e.op == EXP.null_;
}
@@ -1341,8 +1271,8 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
size_t dim = es1.keys.length;
if (es2.keys.length != dim)
return 1;
- bool* used = cast(bool*)mem.xmalloc(bool.sizeof * dim);
- memset(used, 0, bool.sizeof * dim);
+ BitArray used;
+ used.length = dim;
foreach (size_t i; 0 .. dim)
{
Expression k1 = (*es1.keys)[i];
@@ -1361,11 +1291,9 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
}
if (!v2 || ctfeRawCmp(loc, v1, v2, identity))
{
- mem.xfree(used);
return 1;
}
}
- mem.xfree(used);
return 0;
}
else if (e1.op == EXP.assocArrayLiteral && e2.op == EXP.null_)
@@ -2071,9 +1999,8 @@ void showCtfeExpr(Expression e, int level = 0)
UnionExp voidInitLiteral(Type t, VarDeclaration var)
{
UnionExp ue;
- if (t.ty == Tsarray)
+ if (auto tsa = t.isTypeSArray())
{
- TypeSArray tsa = cast(TypeSArray)t;
Expression elem = voidInitLiteral(tsa.next, var).copy();
// For aggregate value types (structs, static arrays) we must
// create an a separate copy for each element.
@@ -2090,9 +2017,8 @@ UnionExp voidInitLiteral(Type t, VarDeclaration var)
ArrayLiteralExp ae = ue.exp().isArrayLiteralExp();
ae.ownedByCtfe = OwnedBy.ctfe;
}
- else if (t.ty == Tstruct)
+ else if (auto ts = t.isTypeStruct())
{
- TypeStruct ts = cast(TypeStruct)t;
auto exps = new Expressions(ts.sym.fields.length);
foreach (size_t i; 0 .. ts.sym.fields.length)
{
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index f769473..14c67f0 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -38,6 +38,7 @@ import dmd.init;
import dmd.intrange;
import dmd.mtype;
import dmd.opover;
+import dmd.optimize;
import dmd.root.ctfloat;
import dmd.common.outbuffer;
import dmd.root.rmem;
@@ -1630,6 +1631,13 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
}
else if (tob.ty == Tvector && t1b.ty != Tvector)
{
+ if (t1b.ty == Tsarray)
+ {
+ // Casting static array to vector with same size, e.g. `cast(int4) int[4]`
+ if (t1b.size(e.loc) != tob.size(e.loc))
+ goto Lfail;
+ return new VectorExp(e.loc, e, tob).expressionSemantic(sc);
+ }
//printf("test1 e = %s, e.type = %s, tob = %s\n", e.toChars(), e.type.toChars(), tob.toChars());
TypeVector tv = tob.isTypeVector();
Expression result = new CastExp(e.loc, e, tv.elementType());
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index bae942c..72b85cf 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -180,7 +180,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
int cppDtorVtblIndex = -1;
/// to prevent recursive attempts
- private bool inuse;
+ bool inuse;
ThreeState isabstract;
@@ -367,7 +367,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
baseok = Baseok.none;
}
- extern (D) private void classError(const(char)* fmt, const(char)* arg)
+ extern (D) final void classError(const(char)* fmt, const(char)* arg)
{
.error(loc, fmt, kind, toPrettyChars, arg);
}
@@ -468,67 +468,6 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
return baseok >= Baseok.done;
}
- override final Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("%s.ClassDeclaration.search('%s', flags=x%x)\n", toChars(), ident.toChars(), flags);
- //if (_scope) printf("%s baseok = %d\n", toChars(), baseok);
- if (_scope && baseok < Baseok.semanticdone)
- {
- if (!inuse)
- {
- // must semantic on base class/interfaces
- inuse = true;
- dsymbolSemantic(this, null);
- inuse = false;
- }
- }
-
- if (!members || !symtab) // opaque or addMember is not yet done
- {
- // .stringof is always defined (but may be hidden by some other symbol)
- if (ident != Id.stringof && !(flags & IgnoreErrors) && semanticRun < PASS.semanticdone)
- classError("%s `%s` is forward referenced when looking for `%s`", ident.toChars());
- //*(char*)0=0;
- return null;
- }
-
- auto s = ScopeDsymbol.search(loc, ident, flags);
-
- // don't search imports of base classes
- if (flags & SearchImportsOnly)
- return s;
-
- if (s)
- return s;
-
- // Search bases classes in depth-first, left to right order
- foreach (b; (*baseclasses)[])
- {
- if (!b.sym)
- continue;
-
- if (!b.sym.symtab)
- {
- classError("%s `%s` base `%s` is forward referenced", b.sym.ident.toChars());
- continue;
- }
-
- import dmd.access : symbolIsVisible;
-
- s = b.sym.search(loc, ident, flags);
- if (!s)
- continue;
- else if (s == this) // happens if s is nested in this and derives from this
- s = null;
- else if (!(flags & IgnoreSymbolVisibility) && !(s.visible().kind == Visibility.Kind.protected_) && !symbolIsVisible(this, s))
- s = null;
- else
- break;
- }
-
- return s;
- }
-
/************************************
* Search base classes in depth-first, left-to-right order for
* a class or interface named 'ident'.
@@ -675,7 +614,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
final bool isFuncHidden(FuncDeclaration fd)
{
//printf("ClassDeclaration.isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toPrettyChars());
- Dsymbol s = search(Loc.initial, fd.ident, IgnoreAmbiguous | IgnoreErrors);
+ Dsymbol s = this.search(Loc.initial, fd.ident, IgnoreAmbiguous | IgnoreErrors);
if (!s)
{
//printf("not found\n");
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 76a31f4..0e125fd 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -421,18 +421,6 @@ extern (C++) abstract class Declaration : Dsymbol
return Modifiable.yes;
}
- override final Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- Dsymbol s = Dsymbol.search(loc, ident, flags);
- if (!s && type)
- {
- s = type.toDsymbol(_scope);
- if (s)
- s = s.search(loc, ident, flags);
- }
- return s;
- }
-
final bool isStatic() const pure nothrow @nogc @safe
{
return (storage_class & STC.static_) != 0;
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 8cd295f..a65fb44 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -124,7 +124,6 @@ public:
const char *kind() const override;
uinteger_t size(const Loc &loc) override final;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
bool isStatic() const { return (storage_class & STCstatic) != 0; }
LINK resolvedLinkage() const; // returns the linkage, resolving the target-specific `System` one
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index f33b5fd..797f6ee 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -83,25 +83,6 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
return ed;
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- version (none)
- {
- printf("EnumDeclaration::addMember() %s\n", toChars());
- for (size_t i = 0; i < members.length; i++)
- {
- EnumMember em = (*members)[i].isEnumMember();
- printf(" member %s\n", em.toChars());
- }
- }
- if (!isAnonymous())
- {
- ScopeDsymbol.addMember(sc, sds);
- }
-
- addEnumMembersToSymtab(this, sc, sds);
- }
-
override void setScope(Scope* sc)
{
if (semanticRun > PASS.initial)
@@ -126,19 +107,6 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
return "enum";
}
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident.toChars());
- if (_scope)
- {
- // Try one last time to resolve this enum
- dsymbolSemantic(this, _scope);
- }
-
- Dsymbol s = ScopeDsymbol.search(loc, ident, flags);
- return s;
- }
-
// is Dsymbol deprecated?
override bool isDeprecated() const
{
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index d74c860..0132e49 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -305,33 +305,6 @@ extern (C++) final class Import : Dsymbol
return this;
}
- /*****************************
- * Add import to sd's symbol table.
- */
- override void addMember(Scope* sc, ScopeDsymbol sd)
- {
- //printf("Import.addMember(this=%s, sd=%s, sc=%p)\n", toChars(), sd.toChars(), sc);
- if (names.length == 0)
- return Dsymbol.addMember(sc, sd);
- if (aliasId)
- Dsymbol.addMember(sc, sd);
- /* Instead of adding the import to sd's symbol table,
- * add each of the alias=name pairs
- */
- for (size_t i = 0; i < names.length; i++)
- {
- Identifier name = names[i];
- Identifier _alias = aliases[i];
- if (!_alias)
- _alias = name;
- auto tname = new TypeIdentifier(loc, name);
- auto ad = new AliasDeclaration(loc, _alias, tname);
- ad._import = this;
- ad.addMember(sc, sd);
- aliasdecls.push(ad);
- }
- }
-
override void setScope(Scope* sc)
{
Dsymbol.setScope(sc);
@@ -348,19 +321,6 @@ extern (C++) final class Import : Dsymbol
}
}
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("%s.Import.search(ident = '%s', flags = x%x)\n", toChars(), ident.toChars(), flags);
- if (!pkg)
- {
- load(null);
- mod.importAll(null);
- mod.dsymbolSemantic(null);
- }
- // Forward it to the package/module
- return pkg.search(loc, ident, flags);
- }
-
override bool overloadInsert(Dsymbol s)
{
/* Allow multiple imports with the same package base, but disallow
diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d
index c58b585..2bedccb 100644
--- a/gcc/d/dmd/dmangle.d
+++ b/gcc/d/dmd/dmangle.d
@@ -152,6 +152,7 @@ import dmd.identifier;
import dmd.mtype;
import dmd.root.ctfloat;
import dmd.common.outbuffer;
+import dmd.optimize;
import dmd.root.aav;
import dmd.root.string;
import dmd.root.stringtable;
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 548928a..5f5de63 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -268,22 +268,6 @@ extern (C++) class Package : ScopeDsymbol
return isAncestorPackageOf(pkg.parent.isPackage());
}
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("%s Package.search('%s', flags = x%x)\n", toChars(), ident.toChars(), flags);
- flags &= ~SearchLocalsOnly; // searching an import is always transitive
- if (!isModule() && mod)
- {
- // Prefer full package name.
- Dsymbol s = symtab ? symtab.lookup(ident) : null;
- if (s)
- return s;
- //printf("[%s] through pkdmod: %s\n", loc.toChars(), toChars());
- return mod.search(loc, ident, flags);
- }
- return ScopeDsymbol.search(loc, ident, flags);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -414,10 +398,10 @@ extern (C++) final class Module : Package
return rootimports == ThreeState.yes;
}
- private Identifier searchCacheIdent;
- private Dsymbol searchCacheSymbol; // cached value of search
- private int searchCacheFlags; // cached flags
- private bool insearch;
+ Identifier searchCacheIdent;
+ Dsymbol searchCacheSymbol; // cached value of search
+ int searchCacheFlags; // cached flags
+ bool insearch;
/**
* A root module is one that will be compiled all the way to
@@ -793,7 +777,7 @@ extern (C++) final class Module : Package
}
else
{
- const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput;
+ const bool doUnittests = global.params.parsingUnittestsRequired();
scope p = new Parser!AST(this, buf, cast(bool) docfile, global.errorSink, &global.compileEnv, doUnittests);
p.transitionIn = global.params.v.vin;
p.nextToken();
@@ -1036,47 +1020,6 @@ extern (C++) final class Module : Package
}
}
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- /* Since modules can be circularly referenced,
- * need to stop infinite recursive searches.
- * This is done with the cache.
- */
- //printf("%s Module.search('%s', flags = x%x) insearch = %d\n", toChars(), ident.toChars(), flags, insearch);
- if (insearch)
- return null;
-
- /* Qualified module searches always search their imports,
- * even if SearchLocalsOnly
- */
- if (!(flags & SearchUnqualifiedModule))
- flags &= ~(SearchUnqualifiedModule | SearchLocalsOnly);
-
- if (searchCacheIdent == ident && searchCacheFlags == flags)
- {
- //printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n",
- // toChars(), ident.toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol.toChars() : "null");
- return searchCacheSymbol;
- }
-
- uint errors = global.errors;
-
- insearch = true;
- Dsymbol s = ScopeDsymbol.search(loc, ident, flags);
- insearch = false;
-
- if (errors == global.errors)
- {
- // https://issues.dlang.org/show_bug.cgi?id=10752
- // Can cache the result only when it does not cause
- // access error so the side-effect should be reproduced in later search.
- searchCacheIdent = ident;
- searchCacheSymbol = s;
- searchCacheFlags = flags;
- }
- return s;
- }
-
override bool isPackageAccessible(Package p, Visibility visibility, int flags = 0)
{
if (insearch) // don't follow import cycles
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index 3853512..d68bcda 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -66,13 +66,15 @@ enum SCOPE
fullinst = 0x10000, /// fully instantiate templates
ctfeBlock = 0x20000, /// inside a `if (__ctfe)` block
+ dip1000 = 0x40000, /// dip1000 errors enabled for this scope
+ dip25 = 0x80000, /// dip25 errors enabled for this scope
}
/// Flags that are carried along with a scope push()
private enum PersistentFlags =
SCOPE.contract | SCOPE.debug_ | SCOPE.ctfe | SCOPE.compile | SCOPE.constraint |
SCOPE.noaccesscheck | SCOPE.ignoresymbolvisibility |
- SCOPE.Cfile | SCOPE.ctfeBlock;
+ SCOPE.Cfile | SCOPE.ctfeBlock | SCOPE.dip1000 | SCOPE.dip25;
extern (C++) struct Scope
{
@@ -176,6 +178,10 @@ extern (C++) struct Scope
m = m.parent;
m.addMember(null, sc.scopesym);
m.parent = null; // got changed by addMember()
+ if (global.params.useDIP1000 == FeatureState.enabled)
+ sc.flags |= SCOPE.dip1000;
+ if (global.params.useDIP25 == FeatureState.enabled)
+ sc.flags |= SCOPE.dip25;
if (_module.filetype == FileType.c)
sc.flags |= SCOPE.Cfile;
// Create the module scope underneath the global scope
@@ -344,7 +350,7 @@ extern (C++) struct Scope
* Returns:
* symbol if found, null if not
*/
- extern (D) Dsymbol search(const ref Loc loc, Identifier ident, Dsymbol* pscopesym, int flags = IgnoreNone)
+ extern (C++) Dsymbol search(const ref Loc loc, Identifier ident, Dsymbol* pscopesym, int flags = IgnoreNone)
{
version (LOGSEARCH)
{
@@ -821,4 +827,16 @@ extern (C++) struct Scope
{
return (flags & (SCOPE.ctfe | SCOPE.ctfeBlock | SCOPE.compile)) == 0;
}
+
+ /// Returns: whether to raise DIP1000 warnings (FeatureStabe.default) or errors (FeatureState.enabled)
+ extern (D) FeatureState useDIP1000()
+ {
+ return (flags & SCOPE.dip1000) ? FeatureState.enabled : FeatureState.disabled;
+ }
+
+ /// Returns: whether to raise DIP25 warnings (FeatureStabe.default) or errors (FeatureState.enabled)
+ extern (D) FeatureState useDIP25()
+ {
+ return (flags & SCOPE.dip25) ? FeatureState.enabled : FeatureState.disabled;
+ }
}
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index f77a263..36e847c 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -263,23 +263,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration
return sd;
}
- override final Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("%s.StructDeclaration::search('%s', flags = x%x)\n", toChars(), ident.toChars(), flags);
- if (_scope && !symtab)
- dsymbolSemantic(this, _scope);
-
- if (!members || !symtab) // opaque or semantic() is not yet called
- {
- // .stringof is always defined (but may be hidden by some other symbol)
- if(ident != Id.stringof && !(flags & IgnoreErrors) && semanticRun < PASS.semanticdone)
- .error(loc, "%s `%s` is forward referenced when looking for `%s`", kind, toPrettyChars, ident.toChars());
- return null;
- }
-
- return ScopeDsymbol.search(loc, ident, flags);
- }
-
override const(char)* kind() const
{
return "struct";
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 914213c..a52745f 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -35,7 +35,6 @@ import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
-import dmd.expressionsem;
import dmd.func;
import dmd.globals;
import dmd.id;
@@ -750,67 +749,6 @@ extern (C++) class Dsymbol : ASTNode
return toAlias();
}
- void addMember(Scope* sc, ScopeDsymbol sds)
- {
- //printf("Dsymbol::addMember('%s')\n", toChars());
- //printf("Dsymbol::addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sds.toChars());
- //printf("Dsymbol::addMember(this = %p, '%s' sds = %p, sds.symtab = %p)\n", this, toChars(), sds, sds.symtab);
- parent = sds;
- if (isAnonymous()) // no name, so can't add it to symbol table
- return;
-
- if (!sds.symtabInsert(this)) // if name is already defined
- {
- if (isAliasDeclaration() && !_scope)
- setScope(sc);
- Dsymbol s2 = sds.symtabLookup(this,ident);
- /* https://issues.dlang.org/show_bug.cgi?id=17434
- *
- * If we are trying to add an import to the symbol table
- * that has already been introduced, then keep the one with
- * larger visibility. This is fine for imports because if
- * we have multiple imports of the same file, if a single one
- * is public then the symbol is reachable.
- */
- if (auto i1 = isImport())
- {
- if (auto i2 = s2.isImport())
- {
- if (sc.explicitVisibility && sc.visibility > i2.visibility)
- sds.symtab.update(this);
- }
- }
-
- // If using C tag/prototype/forward declaration rules
- if (sc.flags & SCOPE.Cfile && !this.isImport())
- {
- if (handleTagSymbols(*sc, this, s2, sds))
- return;
- if (handleSymbolRedeclarations(*sc, this, s2, sds))
- return;
-
- sds.multiplyDefined(Loc.initial, this, s2); // ImportC doesn't allow overloading
- errors = true;
- return;
- }
-
- if (!s2.overloadInsert(this))
- {
- sds.multiplyDefined(Loc.initial, this, s2);
- errors = true;
- }
- }
- if (sds.isAggregateDeclaration() || sds.isEnumDeclaration())
- {
- if (ident == Id.__sizeof ||
- !(sc && sc.flags & SCOPE.Cfile) && (ident == Id.__xalignof || ident == Id._mangleof))
- {
- .error(loc, "%s `%s` `.%s` property cannot be redefined", kind, toPrettyChars, ident.toChars());
- errors = true;
- }
- }
- }
-
/*************************************
* Set scope for future semantic analysis so we can
* deal better with forward references.
@@ -831,21 +769,6 @@ extern (C++) class Dsymbol : ASTNode
{
}
- /*********************************************
- * Search for ident as member of s.
- * Params:
- * loc = location to print for error messages
- * ident = identifier to search for
- * flags = IgnoreXXXX
- * Returns:
- * null if not found
- */
- Dsymbol search(const ref Loc loc, Identifier ident, int flags = IgnoreNone)
- {
- //printf("Dsymbol::search(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars());
- return null;
- }
-
extern (D) final Dsymbol search_correct(Identifier ident)
{
/***************************************************
@@ -870,7 +793,7 @@ extern (C++) class Dsymbol : ASTNode
if (global.gag)
return null; // don't do it for speculative compiles; too time consuming
// search for exact name first
- if (auto s = search(Loc.initial, ident, IgnoreErrors))
+ if (auto s = this.search(Loc.initial, ident, IgnoreErrors))
return s;
return speller!symbol_search_fp(ident.toString());
}
@@ -1339,12 +1262,12 @@ extern (C++) class ScopeDsymbol : Dsymbol
Dsymbols* members; // all Dsymbol's in this scope
DsymbolTable symtab; // members[] sorted into table
uint endlinnum; // the linnumber of the statement after the scope (0 if unknown)
-
-private:
/// symbols whose members have been imported, i.e. imported modules and template mixins
Dsymbols* importedScopes;
Visibility.Kind* visibilities; // array of Visibility.Kind, one for each import
+private:
+
import dmd.root.bitarray;
BitArray accessiblePackages, privateAccessiblePackages;// whitelists of accessible (imported) packages
@@ -1373,166 +1296,7 @@ public:
return sds;
}
- /*****************************************
- * This function is #1 on the list of functions that eat cpu time.
- * Be very, very careful about slowing it down.
- */
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("%s.ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident.toChars(), flags);
- //if (strcmp(ident.toChars(),"c") == 0) *(char*)0=0;
-
- // Look in symbols declared in this module
- if (symtab && !(flags & SearchImportsOnly))
- {
- //printf(" look in locals\n");
- auto s1 = symtab.lookup(ident);
- if (s1)
- {
- //printf("\tfound in locals = '%s.%s'\n",toChars(),s1.toChars());
- return s1;
- }
- }
- //printf(" not found in locals\n");
-
- // Look in imported scopes
- if (!importedScopes)
- return null;
-
- //printf(" look in imports\n");
- Dsymbol s = null;
- OverloadSet a = null;
- // Look in imported modules
- for (size_t i = 0; i < importedScopes.length; i++)
- {
- // If private import, don't search it
- if ((flags & IgnorePrivateImports) && visibilities[i] == Visibility.Kind.private_)
- continue;
- int sflags = flags & (IgnoreErrors | IgnoreAmbiguous); // remember these in recursive searches
- Dsymbol ss = (*importedScopes)[i];
- //printf("\tscanning import '%s', visibilities = %d, isModule = %p, isImport = %p\n", ss.toChars(), visibilities[i], ss.isModule(), ss.isImport());
-
- if (ss.isModule())
- {
- if (flags & SearchLocalsOnly)
- continue;
- }
- else // mixin template
- {
- if (flags & SearchImportsOnly)
- continue;
-
- sflags |= SearchLocalsOnly;
- }
-
- /* Don't find private members if ss is a module
- */
- Dsymbol s2 = ss.search(loc, ident, sflags | (ss.isModule() ? IgnorePrivateImports : IgnoreNone));
- import dmd.access : symbolIsVisible;
- if (!s2 || !(flags & IgnoreSymbolVisibility) && !symbolIsVisible(this, s2))
- continue;
- if (!s)
- {
- s = s2;
- if (s && s.isOverloadSet())
- a = mergeOverloadSet(ident, a, s);
- }
- else if (s2 && s != s2)
- {
- if (s.toAlias() == s2.toAlias() || s.getType() == s2.getType() && s.getType())
- {
- /* After following aliases, we found the same
- * symbol, so it's not an ambiguity. But if one
- * alias is deprecated or less accessible, prefer
- * the other.
- */
- if (s.isDeprecated() || s.visible() < s2.visible() && s2.visible().kind != Visibility.Kind.none)
- s = s2;
- }
- else
- {
- /* Two imports of the same module should be regarded as
- * the same.
- */
- Import i1 = s.isImport();
- Import i2 = s2.isImport();
- if (!(i1 && i2 && (i1.mod == i2.mod || (!i1.parent.isImport() && !i2.parent.isImport() && i1.ident.equals(i2.ident)))))
- {
- /* https://issues.dlang.org/show_bug.cgi?id=8668
- * Public selective import adds AliasDeclaration in module.
- * To make an overload set, resolve aliases in here and
- * get actual overload roots which accessible via s and s2.
- */
- s = s.toAlias();
- s2 = s2.toAlias();
- /* If both s2 and s are overloadable (though we only
- * need to check s once)
- */
-
- auto so2 = s2.isOverloadSet();
- if ((so2 || s2.isOverloadable()) && (a || s.isOverloadable()))
- {
- if (symbolIsVisible(this, s2))
- {
- a = mergeOverloadSet(ident, a, s2);
- }
- if (!symbolIsVisible(this, s))
- s = s2;
- continue;
- }
-
- /* Two different overflow sets can have the same members
- * https://issues.dlang.org/show_bug.cgi?id=16709
- */
- auto so = s.isOverloadSet();
- if (so && so2)
- {
- if (so.a.length == so2.a.length)
- {
- foreach (j; 0 .. so.a.length)
- {
- if (so.a[j] !is so2.a[j])
- goto L1;
- }
- continue; // the same
- L1:
- { } // different
- }
- }
-
- if (flags & IgnoreAmbiguous) // if return NULL on ambiguity
- return null;
-
- /* If two imports from C import files, pick first one, as C has global name space
- */
- if (s.isCsymbol() && s2.isCsymbol())
- continue;
-
- if (!(flags & IgnoreErrors))
- ScopeDsymbol.multiplyDefined(loc, s, s2);
- break;
- }
- }
- }
- }
- if (s)
- {
- /* Build special symbol if we had multiple finds
- */
- if (a)
- {
- if (!s.isOverloadSet())
- a = mergeOverloadSet(ident, a, s);
- s = a;
- }
- //printf("\tfound in imports %s.%s\n", toChars(), s.toChars());
- return s;
- }
- //printf(" not found in imports\n");
- return null;
- }
-
- extern (D) private OverloadSet mergeOverloadSet(Identifier ident, OverloadSet os, Dsymbol s)
+ extern (D) final OverloadSet mergeOverloadSet(Identifier ident, OverloadSet os, Dsymbol s)
{
if (!os)
{
@@ -1844,40 +1608,6 @@ extern (C++) final class WithScopeSymbol : ScopeDsymbol
this.withstate = withstate;
}
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("WithScopeSymbol.search(%s)\n", ident.toChars());
- if (flags & SearchImportsOnly)
- return null;
- // Acts as proxy to the with class declaration
- Dsymbol s = null;
- Expression eold = null;
- for (Expression e = withstate.exp; e && e != eold; e = resolveAliasThis(_scope, e, true))
- {
- if (auto se = e.isScopeExp())
- {
- s = se.sds;
- }
- else if (e.isTypeExp())
- {
- s = e.type.toDsymbol(null);
- }
- else
- {
- Type t = e.type.toBasetype();
- s = t.toDsymbol(null);
- }
- if (s)
- {
- s = s.search(loc, ident, flags);
- if (s)
- return s;
- }
- eold = e;
- }
- return null;
- }
-
override inout(WithScopeSymbol) isWithScopeSymbol() inout
{
return this;
@@ -1896,217 +1626,28 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
{
// either a SliceExp, an IndexExp, an ArrayExp, a TypeTuple or a TupleDeclaration.
// Discriminated using DYNCAST and, for expressions, also EXP
- private RootObject arrayContent;
- Scope* sc;
+ RootObject arrayContent;
extern (D) this(Scope* sc, Expression exp) nothrow @safe
{
super(exp.loc, null);
assert(exp.op == EXP.index || exp.op == EXP.slice || exp.op == EXP.array);
- this.sc = sc;
+ this._scope = sc;
this.arrayContent = exp;
}
extern (D) this(Scope* sc, TypeTuple type) nothrow @safe
{
- this.sc = sc;
+ this._scope = sc;
this.arrayContent = type;
}
extern (D) this(Scope* sc, TupleDeclaration td) nothrow @safe
{
- this.sc = sc;
+ this._scope = sc;
this.arrayContent = td;
}
- /// This override is used to solve `$`
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = IgnoreNone)
- {
- //printf("ArrayScopeSymbol::search('%s', flags = %d)\n", ident.toChars(), flags);
- if (ident != Id.dollar)
- return null;
-
- VarDeclaration* pvar;
- Expression ce;
-
- static Dsymbol dollarFromTypeTuple(const ref Loc loc, TypeTuple tt, Scope* sc)
- {
-
- /* $ gives the number of type entries in the type tuple
- */
- auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
- Expression e = new IntegerExp(Loc.initial, tt.arguments.length, Type.tsize_t);
- v._init = new ExpInitializer(Loc.initial, e);
- v.storage_class |= STC.temp | STC.static_ | STC.const_;
- v.dsymbolSemantic(sc);
- return v;
- }
-
- const DYNCAST kind = arrayContent.dyncast();
- switch (kind) with (DYNCAST)
- {
- case dsymbol:
- TupleDeclaration td = cast(TupleDeclaration) arrayContent;
- /* $ gives the number of elements in the tuple
- */
- auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
- Expression e = new IntegerExp(Loc.initial, td.objects.length, Type.tsize_t);
- v._init = new ExpInitializer(Loc.initial, e);
- v.storage_class |= STC.temp | STC.static_ | STC.const_;
- v.dsymbolSemantic(sc);
- return v;
- case type:
- return dollarFromTypeTuple(loc, cast(TypeTuple) arrayContent, sc);
- default:
- break;
- }
- Expression exp = cast(Expression) arrayContent;
- if (auto ie = exp.isIndexExp())
- {
- /* array[index] where index is some function of $
- */
- pvar = &ie.lengthVar;
- ce = ie.e1;
- }
- else if (auto se = exp.isSliceExp())
- {
- /* array[lwr .. upr] where lwr or upr is some function of $
- */
- pvar = &se.lengthVar;
- ce = se.e1;
- }
- else if (auto ae = exp.isArrayExp())
- {
- /* array[e0, e1, e2, e3] where e0, e1, e2 are some function of $
- * $ is a opDollar!(dim)() where dim is the dimension(0,1,2,...)
- */
- pvar = &ae.lengthVar;
- ce = ae.e1;
- }
- else
- {
- /* Didn't find $, look in enclosing scope(s).
- */
- return null;
- }
- ce = ce.lastComma();
- /* If we are indexing into an array that is really a type
- * tuple, rewrite this as an index into a type tuple and
- * try again.
- */
- if (auto te = ce.isTypeExp())
- {
- if (auto ttp = te.type.isTypeTuple())
- return dollarFromTypeTuple(loc, ttp, sc);
- }
- /* *pvar is lazily initialized, so if we refer to $
- * multiple times, it gets set only once.
- */
- if (!*pvar) // if not already initialized
- {
- /* Create variable v and set it to the value of $
- */
- VarDeclaration v;
- Type t;
- if (auto tupexp = ce.isTupleExp())
- {
- /* It is for an expression tuple, so the
- * length will be a const.
- */
- Expression e = new IntegerExp(Loc.initial, tupexp.exps.length, Type.tsize_t);
- v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, new ExpInitializer(Loc.initial, e));
- v.storage_class |= STC.temp | STC.static_ | STC.const_;
- }
- else if (ce.type && (t = ce.type.toBasetype()) !is null && (t.ty == Tstruct || t.ty == Tclass))
- {
- // Look for opDollar
- assert(exp.op == EXP.array || exp.op == EXP.slice);
- AggregateDeclaration ad = isAggregate(t);
- assert(ad);
- Dsymbol s = ad.search(loc, Id.opDollar);
- if (!s) // no dollar exists -- search in higher scope
- return null;
- s = s.toAlias();
- Expression e = null;
- // Check for multi-dimensional opDollar(dim) template.
- if (TemplateDeclaration td = s.isTemplateDeclaration())
- {
- dinteger_t dim = 0;
- if (auto ae = exp.isArrayExp())
- {
- dim = ae.currentDimension;
- }
- else if (exp.isSliceExp())
- {
- dim = 0; // slices are currently always one-dimensional
- }
- else
- {
- assert(0);
- }
- auto tiargs = new Objects();
- Expression edim = new IntegerExp(Loc.initial, dim, Type.tsize_t);
- edim = edim.expressionSemantic(sc);
- tiargs.push(edim);
- e = new DotTemplateInstanceExp(loc, ce, td.ident, tiargs);
- }
- else
- {
- /* opDollar exists, but it's not a template.
- * This is acceptable ONLY for single-dimension indexing.
- * Note that it's impossible to have both template & function opDollar,
- * because both take no arguments.
- */
- auto ae = exp.isArrayExp();
- if (ae && ae.arguments.length != 1)
- {
- error(exp.loc, "`%s` only defines opDollar for one dimension", ad.toChars());
- return null;
- }
- Declaration d = s.isDeclaration();
- assert(d);
- e = new DotVarExp(loc, ce, d);
- }
- e = e.expressionSemantic(sc);
- if (!e.type)
- error(exp.loc, "`%s` has no value", e.toChars());
- t = e.type.toBasetype();
- if (t && t.ty == Tfunction)
- e = new CallExp(e.loc, e);
- v = new VarDeclaration(loc, null, Id.dollar, new ExpInitializer(Loc.initial, e));
- v.storage_class |= STC.temp | STC.ctfe | STC.rvalue;
- }
- else
- {
- /* For arrays, $ will either be a compile-time constant
- * (in which case its value in set during constant-folding),
- * or a variable (in which case an expression is created in
- * toir.c).
- */
-
- // https://issues.dlang.org/show_bug.cgi?id=16213
- // For static arrays $ is known at compile time,
- // so declare it as a manifest constant.
- auto tsa = ce.type ? ce.type.isTypeSArray() : null;
- if (tsa)
- {
- auto e = new ExpInitializer(loc, tsa.dim);
- v = new VarDeclaration(loc, tsa.dim.type, Id.dollar, e, STC.manifest);
- }
- else
- {
- auto e = new VoidInitializer(Loc.initial);
- e.type = Type.tsize_t;
- v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e);
- v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable
- }
- }
- *pvar = v;
- }
- (*pvar).dsymbolSemantic(sc);
- return (*pvar);
- }
-
override inout(ArrayScopeSymbol) isArrayScopeSymbol() inout
{
return this;
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 0278975..e0c2046 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -228,10 +228,8 @@ public:
virtual const char *kind() const;
virtual Dsymbol *toAlias(); // resolve real symbol
virtual Dsymbol *toAlias2();
- virtual void addMember(Scope *sc, ScopeDsymbol *sds);
virtual void setScope(Scope *sc);
virtual void importAll(Scope *sc);
- virtual Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone);
virtual bool overloadInsert(Dsymbol *s);
virtual uinteger_t size(const Loc &loc);
virtual bool isforwardRef();
@@ -331,16 +329,14 @@ public:
Dsymbols *members; // all Dsymbol's in this scope
DsymbolTable *symtab; // members[] sorted into table
unsigned endlinnum; // the linnumber of the statement after the scope (0 if unknown)
-
-private:
Dsymbols *importedScopes; // imported Dsymbol's
Visibility::Kind *visibilities; // array of `Visibility.Kind`, one for each import
+private:
BitArray accessiblePackages, privateAccessiblePackages;
public:
ScopeDsymbol *syntaxCopy(Dsymbol *s) override;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
virtual void importScope(Dsymbol *s, Visibility visibility);
virtual bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0);
bool isforwardRef() override final;
@@ -362,7 +358,6 @@ class WithScopeSymbol final : public ScopeDsymbol
public:
WithStatement *withstate;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
WithScopeSymbol *isWithScopeSymbol() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
@@ -372,12 +367,8 @@ public:
class ArrayScopeSymbol final : public ScopeDsymbol
{
-private:
- RootObject *arrayContent;
public:
- Scope *sc;
-
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone) override;
+ RootObject *arrayContent;
ArrayScopeSymbol *isArrayScopeSymbol() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
@@ -437,3 +428,6 @@ public:
// Number of symbols in symbol table
size_t length() const;
};
+
+void addMember(Dsymbol *dsym, Scope *sc, ScopeDsymbol *sds);
+Dsymbol *search(Dsymbol *d, const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 397c5e5..430377f 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -23,6 +23,7 @@ import dmd.astenums;
import dmd.attrib;
import dmd.blockexit;
import dmd.clone;
+import dmd.cond;
import dmd.compiler;
import dmd.dcast;
import dmd.dclass;
@@ -57,6 +58,7 @@ import dmd.nogc;
import dmd.nspace;
import dmd.objc;
import dmd.opover;
+import dmd.optimize;
import dmd.parse;
import dmd.root.array;
import dmd.root.filename;
@@ -1140,7 +1142,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else if (auto ale = ex.isArrayLiteralExp())
{
// or an array literal assigned to a `scope` variable
- if (global.params.useDIP1000 == FeatureState.enabled
+ if (sc.useDIP1000 == FeatureState.enabled
&& !dsym.type.nextOf().needsDestruction())
ale.onstack = true;
}
@@ -1169,10 +1171,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// https://issues.dlang.org/show_bug.cgi?id=14166
// Don't run CTFE for the temporary variables inside typeof
dsym._init = dsym._init.initializerSemantic(sc, dsym.type, sc.intypeof == 1 ? INITnointerpret : INITinterpret);
+ import dmd.semantic2 : lowerStaticAAs;
+ lowerStaticAAs(dsym, sc);
const init_err = dsym._init.isExpInitializer();
if (init_err && init_err.exp.op == EXP.showCtfeContext)
{
- errorSupplemental(dsym.loc, "compile time context created here");
+ errorSupplemental(dsym.loc, "compile time context created here");
}
}
}
@@ -1951,7 +1955,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
const len = buf.length;
buf.writeByte(0);
const str = buf.extractSlice()[0 .. len];
- const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput;
+ const bool doUnittests = global.params.parsingUnittestsRequired();
auto loc = adjustLocForMixin(str, cd.loc, global.params.mixinOut);
scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests);
p.transitionIn = global.params.v.vin;
@@ -1978,7 +1982,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (!cd.compiled)
{
cd.decl = compileIt(cd);
- cd.AttribDeclaration.addMember(sc, cd.scopesym);
+ attribAddMember(cd, sc, cd.scopesym);
cd.compiled = true;
if (cd._scope && cd.decl)
@@ -3384,9 +3388,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
{
- OutBuffer buf;
- MODtoBuffer(buf, tf.mod);
- .error(funcdecl.loc, "%s `%s` without `this` cannot be `%s`", funcdecl.kind, funcdecl.toPrettyChars, buf.peekChars());
+ import core.bitop : popcnt;
+ auto mods = MODtoChars(tf.mod);
+ .error(funcdecl.loc, "%s `%s` without `this` cannot be `%s`", funcdecl.kind, funcdecl.toPrettyChars, mods);
+ if (tf.next && tf.next.ty != Tvoid && popcnt(tf.mod) == 1)
+ .errorSupplemental(funcdecl.loc,
+ "did you mean to use `%s(%s)` as the return type?", mods, tf.next.toChars());
+
tf.mod = 0; // remove qualifiers
}
@@ -5826,6 +5834,365 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
}
+/*
+Adds dsym as a member of scope sds.
+
+Params:
+ dsym = dsymbol to inserted
+ sc = scope where the dsymbol is declared
+ sds = ScopeDsymbol where dsym is inserted
+*/
+extern(C++) void addMember(Dsymbol dsym, Scope* sc, ScopeDsymbol sds)
+{
+ auto addMemberVisitor = new AddMemberVisitor(sc, sds);
+ dsym.accept(addMemberVisitor);
+}
+
+private void attribAddMember(AttribDeclaration atb, Scope* sc, ScopeDsymbol sds)
+{
+ Dsymbols* d = atb.include(sc);
+ if (d)
+ {
+ Scope* sc2 = atb.newScope(sc);
+ d.foreachDsymbol( s => s.addMember(sc2, sds) );
+ if (sc2 != sc)
+ sc2.pop();
+ }
+}
+
+private extern(C++) class AddMemberVisitor : Visitor
+{
+ alias visit = Visitor.visit;
+
+ Scope* sc;
+ ScopeDsymbol sds;
+
+ this(Scope* sc, ScopeDsymbol sds)
+ {
+ this.sc = sc;
+ this.sds = sds;
+ }
+
+ override void visit(Dsymbol dsym)
+ {
+ //printf("Dsymbol::addMember('%s')\n", toChars());
+ //printf("Dsymbol::addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sds.toChars());
+ //printf("Dsymbol::addMember(this = %p, '%s' sds = %p, sds.symtab = %p)\n", this, toChars(), sds, sds.symtab);
+ dsym.parent = sds;
+ if (dsym.isAnonymous()) // no name, so can't add it to symbol table
+ return;
+
+ if (!sds.symtabInsert(dsym)) // if name is already defined
+ {
+ if (dsym.isAliasDeclaration() && !dsym._scope)
+ dsym.setScope(sc);
+ Dsymbol s2 = sds.symtabLookup(dsym, dsym.ident);
+ /* https://issues.dlang.org/show_bug.cgi?id=17434
+ *
+ * If we are trying to add an import to the symbol table
+ * that has already been introduced, then keep the one with
+ * larger visibility. This is fine for imports because if
+ * we have multiple imports of the same file, if a single one
+ * is public then the symbol is reachable.
+ */
+ if (auto i1 = dsym.isImport())
+ {
+ if (auto i2 = s2.isImport())
+ {
+ if (sc.explicitVisibility && sc.visibility > i2.visibility)
+ sds.symtab.update(dsym);
+ }
+ }
+
+ // If using C tag/prototype/forward declaration rules
+ if (sc.flags & SCOPE.Cfile && !dsym.isImport())
+ {
+ if (handleTagSymbols(*sc, dsym, s2, sds))
+ return;
+ if (handleSymbolRedeclarations(*sc, dsym, s2, sds))
+ return;
+
+ sds.multiplyDefined(Loc.initial, dsym, s2); // ImportC doesn't allow overloading
+ dsym.errors = true;
+ return;
+ }
+
+ if (!s2.overloadInsert(dsym))
+ {
+ sds.multiplyDefined(Loc.initial, dsym, s2);
+ dsym.errors = true;
+ }
+ }
+ if (sds.isAggregateDeclaration() || sds.isEnumDeclaration())
+ {
+ if (dsym.ident == Id.__sizeof ||
+ !(sc && sc.flags & SCOPE.Cfile) && (dsym.ident == Id.__xalignof || dsym.ident == Id._mangleof))
+ {
+ .error(dsym.loc, "%s `%s` `.%s` property cannot be redefined", dsym.kind, dsym.toPrettyChars, dsym.ident.toChars());
+ dsym.errors = true;
+ }
+ }
+ }
+
+
+ override void visit(StaticAssert _)
+ {
+ // we didn't add anything
+ }
+
+ /*****************************
+ * Add import to sd's symbol table.
+ */
+ override void visit(Import imp)
+ {
+ //printf("Import.addMember(this=%s, sds=%s, sc=%p)\n", imp.toChars(), sds.toChars(), sc);
+ if (imp.names.length == 0)
+ return visit(cast(Dsymbol)imp);
+ if (imp.aliasId)
+ visit(cast(Dsymbol)imp);
+
+ /* Instead of adding the import to sds's symbol table,
+ * add each of the alias=name pairs
+ */
+ for (size_t i = 0; i < imp.names.length; i++)
+ {
+ Identifier name = imp.names[i];
+ Identifier _alias = imp.aliases[i];
+ if (!_alias)
+ _alias = name;
+ auto tname = new TypeIdentifier(imp.loc, name);
+ auto ad = new AliasDeclaration(imp.loc, _alias, tname);
+ ad._import = imp;
+ addMember(ad, sc, sds);
+ imp.aliasdecls.push(ad);
+ }
+ }
+
+ override void visit(AttribDeclaration atb)
+ {
+ attribAddMember(atb, sc, sds);
+ }
+
+ override void visit(StorageClassDeclaration stcd)
+ {
+ Dsymbols* d = stcd.include(sc);
+ if (d)
+ {
+ Scope* sc2 = stcd.newScope(sc);
+
+ d.foreachDsymbol( (s)
+ {
+ //printf("\taddMember %s to %s\n", s.toChars(), sds.toChars());
+ // STC.local needs to be attached before the member is added to the scope (because it influences the parent symbol)
+ if (auto decl = s.isDeclaration())
+ {
+ decl.storage_class |= stcd.stc & STC.local;
+ if (auto sdecl = s.isStorageClassDeclaration()) // TODO: why is this not enough to deal with the nested case?
+ {
+ sdecl.stc |= stcd.stc & STC.local;
+ }
+ }
+ s.addMember(sc2, sds);
+ });
+
+ if (sc2 != sc)
+ sc2.pop();
+ }
+ }
+
+ override void visit(VisibilityDeclaration visd)
+ {
+ if (visd.pkg_identifiers)
+ {
+ Dsymbol tmp;
+ Package.resolve(visd.pkg_identifiers, &tmp, null);
+ visd.visibility.pkg = tmp ? tmp.isPackage() : null;
+ visd.pkg_identifiers = null;
+ }
+ if (visd.visibility.kind == Visibility.Kind.package_ && visd.visibility.pkg && sc._module)
+ {
+ Module m = sc._module;
+
+ // https://issues.dlang.org/show_bug.cgi?id=17441
+ // While isAncestorPackageOf does an equality check, the fix for the issue adds a check to see if
+ // each package's .isModule() properites are equal.
+ //
+ // Properties generated from `package(foo)` i.e. visibility.pkg have .isModule() == null.
+ // This breaks package declarations of the package in question if they are declared in
+ // the same package.d file, which _do_ have a module associated with them, and hence a non-null
+ // isModule()
+ if (!m.isPackage() || !visd.visibility.pkg.ident.equals(m.isPackage().ident))
+ {
+ Package pkg = m.parent ? m.parent.isPackage() : null;
+ if (!pkg || !visd.visibility.pkg.isAncestorPackageOf(pkg))
+ .error(visd.loc, "%s `%s` does not bind to one of ancestor packages of module `%s`", visd.kind(), visd.toPrettyChars(false), m.toPrettyChars(true));
+ }
+ }
+ attribAddMember(visd, sc, sds);
+ }
+
+ override void visit(StaticIfDeclaration sid)
+ {
+ //printf("StaticIfDeclaration::addMember() '%s'\n", sid.toChars());
+ /* This is deferred until the condition evaluated later (by the include() call),
+ * so that expressions in the condition can refer to declarations
+ * in the same scope, such as:
+ *
+ * template Foo(int i)
+ * {
+ * const int j = i + 1;
+ * static if (j == 3)
+ * const int k;
+ * }
+ */
+ sid.scopesym = sds;
+ }
+
+
+ override void visit(StaticForeachDeclaration sfd)
+ {
+ // used only for caching the enclosing symbol
+ sfd.scopesym = sds;
+ }
+
+ /***************************************
+ * Lazily initializes the scope to forward to.
+ */
+ override void visit(ForwardingAttribDeclaration fad)
+ {
+ fad.sym.parent = sds;
+ sds = fad.sym;
+ attribAddMember(fad, sc, fad.sym);
+ }
+
+ override void visit(MixinDeclaration md)
+ {
+ //printf("MixinDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\n", sc, sds, md.memnum);
+ md.scopesym = sds;
+ }
+
+ override void visit(DebugSymbol ds)
+ {
+ //printf("DebugSymbol::addMember('%s') %s\n", sds.toChars(), ds.toChars());
+ Module m = sds.isModule();
+ // Do not add the member to the symbol table,
+ // just make sure subsequent debug declarations work.
+ if (ds.ident)
+ {
+ if (!m)
+ {
+ .error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
+ ds.errors = true;
+ }
+ else
+ {
+ if (findCondition(m.debugidsNot, ds.ident))
+ {
+ .error(ds.loc, "%s `%s` defined after use", ds.kind, ds.toPrettyChars);
+ ds.errors = true;
+ }
+ if (!m.debugids)
+ m.debugids = new Identifiers();
+ m.debugids.push(ds.ident);
+ }
+ }
+ else
+ {
+ if (!m)
+ {
+ .error(ds.loc, "%s `%s` level declaration must be at module level", ds.kind, ds.toPrettyChars);
+ ds.errors = true;
+ }
+ else
+ m.debuglevel = ds.level;
+ }
+ }
+
+ override void visit(VersionSymbol vs)
+ {
+ //printf("VersionSymbol::addMember('%s') %s\n", sds.toChars(), vs.toChars());
+ Module m = sds.isModule();
+ // Do not add the member to the symbol table,
+ // just make sure subsequent debug declarations work.
+ if (vs.ident)
+ {
+ VersionCondition.checkReserved(vs.loc, vs.ident.toString());
+ if (!m)
+ {
+ .error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
+ vs.errors = true;
+ }
+ else
+ {
+ if (findCondition(m.versionidsNot, vs.ident))
+ {
+ .error(vs.loc, "%s `%s` defined after use", vs.kind, vs.toPrettyChars);
+ vs.errors = true;
+ }
+ if (!m.versionids)
+ m.versionids = new Identifiers();
+ m.versionids.push(vs.ident);
+ }
+ }
+ else
+ {
+ if (!m)
+ {
+ .error(vs.loc, "%s `%s` level declaration must be at module level", vs.kind, vs.toPrettyChars);
+ vs.errors = true;
+ }
+ else
+ m.versionlevel = vs.level;
+ }
+ }
+
+ override void visit(Nspace ns)
+ {
+ visit(cast(Dsymbol)ns);
+
+ if (ns.members)
+ {
+ if (!ns.symtab)
+ ns.symtab = new DsymbolTable();
+ // The namespace becomes 'imported' into the enclosing scope
+ for (Scope* sce = sc; 1; sce = sce.enclosing)
+ {
+ ScopeDsymbol sds2 = sce.scopesym;
+ if (sds2)
+ {
+ sds2.importScope(ns, Visibility(Visibility.Kind.public_));
+ break;
+ }
+ }
+ assert(sc);
+ sc = sc.push(ns);
+ sc.linkage = LINK.cpp; // namespaces default to C++ linkage
+ sc.parent = ns;
+ ns.members.foreachDsymbol(s => s.addMember(sc, ns));
+ sc.pop();
+ }
+ }
+
+ override void visit(EnumDeclaration ed)
+ {
+ version (none)
+ {
+ printf("EnumDeclaration::addMember() %s\n", ed.toChars());
+ for (size_t i = 0; i < ed.members.length; i++)
+ {
+ EnumMember em = (*ed.members)[i].isEnumMember();
+ printf(" member %s\n", em.toChars());
+ }
+ }
+ if (!ed.isAnonymous())
+ {
+ visit(cast(Dsymbol)ed);
+ }
+
+ addEnumMembersToSymtab(ed, sc, sds);
+ }
+}
+
/*******************************************
* Add members of EnumDeclaration to the symbol table(s).
* Params:
@@ -5899,7 +6266,7 @@ private bool isDRuntimeHook(Identifier id)
id == Id._d_arraysetlengthTImpl || id == Id._d_arraysetlengthT ||
id == Id._d_arraysetlengthTTrace ||
id == Id._d_arrayappendT || id == Id._d_arrayappendTTrace ||
- id == Id._d_arrayappendcTXImpl;
+ id == Id._d_arrayappendcTX;
}
void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList argumentList)
@@ -7426,3 +7793,617 @@ void checkPrintfScanfSignature(FuncDeclaration funcdecl, TypeFunction f, Scope*
p, funcdecl.toChars());
}
}
+
+/*********************************************
+ * Search for ident as member of d.
+ * Params:
+ * d = dsymbol where ident is searched for
+ * loc = location to print for error messages
+ * ident = identifier to search for
+ * flags = IgnoreXXXX
+ * Returns:
+ * null if not found
+ */
+extern(C++) Dsymbol search(Dsymbol d, const ref Loc loc, Identifier ident, int flags = IgnoreNone)
+{
+ scope v = new SearchVisitor(loc, ident, flags);
+ d.accept(v);
+ return v.result;
+}
+
+private extern(C++) class SearchVisitor : Visitor
+{
+ alias visit = Visitor.visit;
+
+ const Loc loc;
+ Identifier ident;
+ int flags;
+ Dsymbol result;
+
+ this(const ref Loc loc, Identifier ident, int flags)
+ {
+ this.loc = loc;
+ this.ident = ident;
+ this.flags = flags;
+ }
+
+ void setResult(Dsymbol d)
+ {
+ result = d;
+ }
+
+ override void visit(Dsymbol d)
+ {
+ //printf("Dsymbol::search(this=%p,%s, ident='%s')\n", d, d.toChars(), ident.toChars());
+ return setResult(null);
+ }
+
+ override void visit(ScopeDsymbol sds)
+ {
+ //printf("%s.ScopeDsymbol::search(ident='%s', flags=x%x)\n", sds.toChars(), ident.toChars(), flags);
+ //if (strcmp(ident.toChars(),"c") == 0) *(char*)0=0;
+
+ // Look in symbols declared in this module
+ if (sds.symtab && !(flags & SearchImportsOnly))
+ {
+ //printf(" look in locals\n");
+ auto s1 = sds.symtab.lookup(ident);
+ if (s1)
+ {
+ //printf("\tfound in locals = '%s.%s'\n",toChars(),s1.toChars());
+ return setResult(s1);
+ }
+ }
+ //printf(" not found in locals\n");
+
+ // Look in imported scopes
+ if (!sds.importedScopes)
+ return setResult(null);
+
+ //printf(" look in imports\n");
+ Dsymbol s = null;
+ OverloadSet a = null;
+ // Look in imported modules
+ for (size_t i = 0; i < sds.importedScopes.length; i++)
+ {
+ // If private import, don't search it
+ if ((flags & IgnorePrivateImports) && sds.visibilities[i] == Visibility.Kind.private_)
+ continue;
+ int sflags = flags & (IgnoreErrors | IgnoreAmbiguous); // remember these in recursive searches
+ Dsymbol ss = (*sds.importedScopes)[i];
+ //printf("\tscanning import '%s', visibilities = %d, isModule = %p, isImport = %p\n", ss.toChars(), visibilities[i], ss.isModule(), ss.isImport());
+
+ if (ss.isModule())
+ {
+ if (flags & SearchLocalsOnly)
+ continue;
+ }
+ else // mixin template
+ {
+ if (flags & SearchImportsOnly)
+ continue;
+
+ sflags |= SearchLocalsOnly;
+ }
+
+ /* Don't find private members if ss is a module
+ */
+ Dsymbol s2 = ss.search(loc, ident, sflags | (ss.isModule() ? IgnorePrivateImports : IgnoreNone));
+ import dmd.access : symbolIsVisible;
+ if (!s2 || !(flags & IgnoreSymbolVisibility) && !symbolIsVisible(sds, s2))
+ continue;
+ if (!s)
+ {
+ s = s2;
+ if (s && s.isOverloadSet())
+ a = sds.mergeOverloadSet(ident, a, s);
+ }
+ else if (s2 && s != s2)
+ {
+ if (s.toAlias() == s2.toAlias() || s.getType() == s2.getType() && s.getType())
+ {
+ /* After following aliases, we found the same
+ * symbol, so it's not an ambiguity. But if one
+ * alias is deprecated or less accessible, prefer
+ * the other.
+ */
+ if (s.isDeprecated() || s.visible() < s2.visible() && s2.visible().kind != Visibility.Kind.none)
+ s = s2;
+ }
+ else
+ {
+ /* Two imports of the same module should be regarded as
+ * the same.
+ */
+ Import i1 = s.isImport();
+ Import i2 = s2.isImport();
+ if (!(i1 && i2 && (i1.mod == i2.mod || (!i1.parent.isImport() && !i2.parent.isImport() && i1.ident.equals(i2.ident)))))
+ {
+ /* https://issues.dlang.org/show_bug.cgi?id=8668
+ * Public selective import adds AliasDeclaration in module.
+ * To make an overload set, resolve aliases in here and
+ * get actual overload roots which accessible via s and s2.
+ */
+ s = s.toAlias();
+ s2 = s2.toAlias();
+ /* If both s2 and s are overloadable (though we only
+ * need to check s once)
+ */
+
+ auto so2 = s2.isOverloadSet();
+ if ((so2 || s2.isOverloadable()) && (a || s.isOverloadable()))
+ {
+ if (symbolIsVisible(sds, s2))
+ {
+ a = sds.mergeOverloadSet(ident, a, s2);
+ }
+ if (!symbolIsVisible(sds, s))
+ s = s2;
+ continue;
+ }
+
+ /* Two different overflow sets can have the same members
+ * https://issues.dlang.org/show_bug.cgi?id=16709
+ */
+ auto so = s.isOverloadSet();
+ if (so && so2)
+ {
+ if (so.a.length == so2.a.length)
+ {
+ foreach (j; 0 .. so.a.length)
+ {
+ if (so.a[j] !is so2.a[j])
+ goto L1;
+ }
+ continue; // the same
+ L1:
+ { } // different
+ }
+ }
+
+ if (flags & IgnoreAmbiguous) // if return NULL on ambiguity
+ return setResult(null);
+
+ /* If two imports from C import files, pick first one, as C has global name space
+ */
+ if (s.isCsymbol() && s2.isCsymbol())
+ continue;
+
+ if (!(flags & IgnoreErrors))
+ ScopeDsymbol.multiplyDefined(loc, s, s2);
+ break;
+ }
+ }
+ }
+ }
+ if (s)
+ {
+ /* Build special symbol if we had multiple finds
+ */
+ if (a)
+ {
+ if (!s.isOverloadSet())
+ a = sds.mergeOverloadSet(ident, a, s);
+ s = a;
+ }
+ //printf("\tfound in imports %s.%s\n", toChars(), s.toChars());
+ return setResult(s);
+ }
+ //printf(" not found in imports\n");
+ return setResult(null);
+ }
+
+ override void visit(WithScopeSymbol ws)
+ {
+ //printf("WithScopeSymbol.search(%s)\n", ident.toChars());
+ if (flags & SearchImportsOnly)
+ return setResult(null);
+ // Acts as proxy to the with class declaration
+ Dsymbol s = null;
+ Expression eold = null;
+ for (Expression e = ws.withstate.exp; e && e != eold; e = resolveAliasThis(ws._scope, e, true))
+ {
+ if (auto se = e.isScopeExp())
+ {
+ s = se.sds;
+ }
+ else if (e.isTypeExp())
+ {
+ s = e.type.toDsymbol(null);
+ }
+ else
+ {
+ Type t = e.type.toBasetype();
+ s = t.toDsymbol(null);
+ }
+ if (s)
+ {
+ s = s.search(loc, ident, flags);
+ if (s)
+ return setResult(s);
+ }
+ eold = e;
+ }
+ return setResult(null);
+ }
+
+ override void visit(ArrayScopeSymbol ass)
+ {
+ //printf("ArrayScopeSymbol::search('%s', flags = %d)\n", ident.toChars(), flags);
+ if (ident != Id.dollar)
+ return setResult(null);
+
+ VarDeclaration* pvar;
+ Expression ce;
+
+ static Dsymbol dollarFromTypeTuple(const ref Loc loc, TypeTuple tt, Scope* sc)
+ {
+
+ /* $ gives the number of type entries in the type tuple
+ */
+ auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
+ Expression e = new IntegerExp(Loc.initial, tt.arguments.length, Type.tsize_t);
+ v._init = new ExpInitializer(Loc.initial, e);
+ v.storage_class |= STC.temp | STC.static_ | STC.const_;
+ v.dsymbolSemantic(sc);
+ return v;
+ }
+
+ const DYNCAST kind = ass.arrayContent.dyncast();
+ switch (kind) with (DYNCAST)
+ {
+ case dsymbol:
+ TupleDeclaration td = cast(TupleDeclaration) ass.arrayContent;
+ /* $ gives the number of elements in the tuple
+ */
+ auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
+ Expression e = new IntegerExp(Loc.initial, td.objects.length, Type.tsize_t);
+ v._init = new ExpInitializer(Loc.initial, e);
+ v.storage_class |= STC.temp | STC.static_ | STC.const_;
+ v.dsymbolSemantic(ass._scope);
+ return setResult(v);
+ case type:
+ return setResult(dollarFromTypeTuple(loc, cast(TypeTuple) ass.arrayContent, ass._scope));
+ default:
+ break;
+ }
+ Expression exp = cast(Expression) ass.arrayContent;
+ if (auto ie = exp.isIndexExp())
+ {
+ /* array[index] where index is some function of $
+ */
+ pvar = &ie.lengthVar;
+ ce = ie.e1;
+ }
+ else if (auto se = exp.isSliceExp())
+ {
+ /* array[lwr .. upr] where lwr or upr is some function of $
+ */
+ pvar = &se.lengthVar;
+ ce = se.e1;
+ }
+ else if (auto ae = exp.isArrayExp())
+ {
+ /* array[e0, e1, e2, e3] where e0, e1, e2 are some function of $
+ * $ is a opDollar!(dim)() where dim is the dimension(0,1,2,...)
+ */
+ pvar = &ae.lengthVar;
+ ce = ae.e1;
+ }
+ else
+ {
+ /* Didn't find $, look in enclosing scope(s).
+ */
+ return setResult(null);
+ }
+ ce = ce.lastComma();
+ /* If we are indexing into an array that is really a type
+ * tuple, rewrite this as an index into a type tuple and
+ * try again.
+ */
+ if (auto te = ce.isTypeExp())
+ {
+ if (auto ttp = te.type.isTypeTuple())
+ return setResult(dollarFromTypeTuple(loc, ttp, ass._scope));
+ }
+ /* *pvar is lazily initialized, so if we refer to $
+ * multiple times, it gets set only once.
+ */
+ if (!*pvar) // if not already initialized
+ {
+ /* Create variable v and set it to the value of $
+ */
+ VarDeclaration v;
+ Type t;
+ if (auto tupexp = ce.isTupleExp())
+ {
+ /* It is for an expression tuple, so the
+ * length will be a const.
+ */
+ Expression e = new IntegerExp(Loc.initial, tupexp.exps.length, Type.tsize_t);
+ v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, new ExpInitializer(Loc.initial, e));
+ v.storage_class |= STC.temp | STC.static_ | STC.const_;
+ }
+ else if (ce.type && (t = ce.type.toBasetype()) !is null && (t.ty == Tstruct || t.ty == Tclass))
+ {
+ // Look for opDollar
+ assert(exp.op == EXP.array || exp.op == EXP.slice);
+ AggregateDeclaration ad = isAggregate(t);
+ assert(ad);
+ Dsymbol s = ad.search(loc, Id.opDollar);
+ if (!s) // no dollar exists -- search in higher scope
+ return setResult(null);
+ s = s.toAlias();
+ Expression e = null;
+ // Check for multi-dimensional opDollar(dim) template.
+ if (TemplateDeclaration td = s.isTemplateDeclaration())
+ {
+ dinteger_t dim = 0;
+ if (auto ae = exp.isArrayExp())
+ {
+ dim = ae.currentDimension;
+ }
+ else if (exp.isSliceExp())
+ {
+ dim = 0; // slices are currently always one-dimensional
+ }
+ else
+ {
+ assert(0);
+ }
+ auto tiargs = new Objects();
+ Expression edim = new IntegerExp(Loc.initial, dim, Type.tsize_t);
+ edim = edim.expressionSemantic(ass._scope);
+ tiargs.push(edim);
+ e = new DotTemplateInstanceExp(loc, ce, td.ident, tiargs);
+ }
+ else
+ {
+ /* opDollar exists, but it's not a template.
+ * This is acceptable ONLY for single-dimension indexing.
+ * Note that it's impossible to have both template & function opDollar,
+ * because both take no arguments.
+ */
+ auto ae = exp.isArrayExp();
+ if (ae && ae.arguments.length != 1)
+ {
+ error(exp.loc, "`%s` only defines opDollar for one dimension", ad.toChars());
+ return setResult(null);
+ }
+ Declaration d = s.isDeclaration();
+ assert(d);
+ e = new DotVarExp(loc, ce, d);
+ }
+ e = e.expressionSemantic(ass._scope);
+ if (!e.type)
+ error(exp.loc, "`%s` has no value", e.toChars());
+ t = e.type.toBasetype();
+ if (t && t.ty == Tfunction)
+ e = new CallExp(e.loc, e);
+ v = new VarDeclaration(loc, null, Id.dollar, new ExpInitializer(Loc.initial, e));
+ v.storage_class |= STC.temp | STC.ctfe | STC.rvalue;
+ }
+ else
+ {
+ /* For arrays, $ will either be a compile-time constant
+ * (in which case its value in set during constant-folding),
+ * or a variable (in which case an expression is created in
+ * toir.c).
+ */
+
+ // https://issues.dlang.org/show_bug.cgi?id=16213
+ // For static arrays $ is known at compile time,
+ // so declare it as a manifest constant.
+ auto tsa = ce.type ? ce.type.isTypeSArray() : null;
+ if (tsa)
+ {
+ auto e = new ExpInitializer(loc, tsa.dim);
+ v = new VarDeclaration(loc, tsa.dim.type, Id.dollar, e, STC.manifest);
+ }
+ else
+ {
+ auto e = new VoidInitializer(Loc.initial);
+ e.type = Type.tsize_t;
+ v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e);
+ v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable
+ }
+ }
+ *pvar = v;
+ }
+ (*pvar).dsymbolSemantic(ass._scope);
+ return setResult((*pvar));
+
+ }
+
+ override void visit(Import imp)
+ {
+ //printf("%s.Import.search(ident = '%s', flags = x%x)\n", imp.toChars(), ident.toChars(), flags);
+ if (!imp.pkg)
+ {
+ imp.load(null);
+ imp.mod.importAll(null);
+ imp.mod.dsymbolSemantic(null);
+ }
+ // Forward it to the package/module
+ return setResult(imp.pkg.search(loc, ident, flags));
+
+ }
+
+ override void visit(Nspace ns)
+ {
+ //printf("%s.Nspace.search('%s')\n", toChars(), ident.toChars());
+ if (ns._scope && !ns.symtab)
+ dsymbolSemantic(ns, ns._scope);
+
+ if (!ns.members || !ns.symtab) // opaque or semantic() is not yet called
+ {
+ if (!(flags & IgnoreErrors))
+ .error(loc, "%s `%s` is forward referenced when looking for `%s`", ns.kind, ns.toPrettyChars, ident.toChars());
+ return setResult(null);
+ }
+
+ visit(cast(ScopeDsymbol)ns);
+ }
+
+ override void visit(EnumDeclaration em)
+ {
+ //printf("%s.EnumDeclaration::search('%s')\n", em.toChars(), ident.toChars());
+ if (em._scope)
+ {
+ // Try one last time to resolve this enum
+ dsymbolSemantic(em, em._scope);
+ }
+
+ visit(cast(ScopeDsymbol)em);
+ }
+
+ override void visit(Package pkg)
+ {
+ //printf("%s Package.search('%s', flags = x%x)\n", pkg.toChars(), ident.toChars(), flags);
+ flags &= ~SearchLocalsOnly; // searching an import is always transitive
+ if (!pkg.isModule() && pkg.mod)
+ {
+ // Prefer full package name.
+ Dsymbol s = pkg.symtab ? pkg.symtab.lookup(ident) : null;
+ if (s)
+ return setResult(s);
+ //printf("[%s] through pkdmod: %s\n", loc.toChars(), toChars());
+ return setResult(pkg.mod.search(loc, ident, flags));
+ }
+
+ visit(cast(ScopeDsymbol)pkg);
+ }
+
+ override void visit(Module m)
+ {
+ /* Since modules can be circularly referenced,
+ * need to stop infinite recursive searches.
+ * This is done with the cache.
+ */
+ //printf("%s Module.search('%s', flags = x%x) insearch = %d\n", m.toChars(), ident.toChars(), flags, m.insearch);
+ if (m.insearch)
+ return setResult(null);
+
+ /* Qualified module searches always search their imports,
+ * even if SearchLocalsOnly
+ */
+ if (!(flags & SearchUnqualifiedModule))
+ flags &= ~(SearchUnqualifiedModule | SearchLocalsOnly);
+
+ if (m.searchCacheIdent == ident && m.searchCacheFlags == flags)
+ {
+ //printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n",
+ // toChars(), ident.toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol.toChars() : "null");
+ return setResult(m.searchCacheSymbol);
+ }
+
+ uint errors = global.errors;
+
+ m.insearch = true;
+ visit(cast(ScopeDsymbol)m);
+ Dsymbol s = result;
+ m.insearch = false;
+
+ if (errors == global.errors)
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=10752
+ // Can cache the result only when it does not cause
+ // access error so the side-effect should be reproduced in later search.
+ m.searchCacheIdent = ident;
+ m.searchCacheSymbol = s;
+ m.searchCacheFlags = flags;
+ }
+ return setResult(s);
+ }
+
+ override void visit(Declaration decl)
+ {
+ Dsymbol s = null;
+ if (decl.type)
+ {
+ s = decl.type.toDsymbol(decl._scope);
+ if (s)
+ s = s.search(loc, ident, flags);
+ }
+ return setResult(s);
+ }
+
+ override void visit(StructDeclaration sd)
+ {
+ //printf("%s.StructDeclaration::search('%s', flags = x%x)\n", sd.toChars(), ident.toChars(), flags);
+ if (sd._scope && !sd.symtab)
+ dsymbolSemantic(sd, sd._scope);
+
+ if (!sd.members || !sd.symtab) // opaque or semantic() is not yet called
+ {
+ // .stringof is always defined (but may be hidden by some other symbol)
+ if(ident != Id.stringof && !(flags & IgnoreErrors) && sd.semanticRun < PASS.semanticdone)
+ .error(loc, "%s `%s` is forward referenced when looking for `%s`", sd.kind, sd.toPrettyChars, ident.toChars());
+ return setResult(null);
+ }
+
+ visit(cast(ScopeDsymbol)sd);
+ }
+
+ override void visit(ClassDeclaration cd)
+ {
+ //printf("%s.ClassDeclaration.search('%s', flags=x%x)\n", cd.toChars(), ident.toChars(), flags);
+ //if (_scope) printf("%s baseok = %d\n", toChars(), baseok);
+ if (cd._scope && cd.baseok < Baseok.semanticdone)
+ {
+ if (!cd.inuse)
+ {
+ // must semantic on base class/interfaces
+ cd.inuse = true;
+ dsymbolSemantic(cd, null);
+ cd.inuse = false;
+ }
+ }
+
+ if (!cd.members || !cd.symtab) // opaque or addMember is not yet done
+ {
+ // .stringof is always defined (but may be hidden by some other symbol)
+ if (ident != Id.stringof && !(flags & IgnoreErrors) && cd.semanticRun < PASS.semanticdone)
+ cd.classError("%s `%s` is forward referenced when looking for `%s`", ident.toChars());
+ //*(char*)0=0;
+ return setResult(null);
+ }
+
+ visit(cast(ScopeDsymbol)cd);
+ auto s = result;
+
+ // don't search imports of base classes
+ if (flags & SearchImportsOnly)
+ return setResult(s);
+
+ if (s)
+ return setResult(s);
+
+ // Search bases classes in depth-first, left to right order
+ foreach (b; (*cd.baseclasses)[])
+ {
+ if (!b.sym)
+ continue;
+
+ if (!b.sym.symtab)
+ {
+ cd.classError("%s `%s` base `%s` is forward referenced", b.sym.ident.toChars());
+ continue;
+ }
+
+ import dmd.access : symbolIsVisible;
+
+ s = b.sym.search(loc, ident, flags);
+ if (!s)
+ continue;
+ else if (s == cd) // happens if s is nested in this and derives from this
+ s = null;
+ else if (!(flags & IgnoreSymbolVisibility) && !(s.visible().kind == Visibility.Kind.protected_) && !symbolIsVisible(cd, s))
+ s = null;
+ else
+ break;
+ }
+
+ return setResult(s);
+ }
+}
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 883f4ac..037e0d0 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -69,6 +69,7 @@ import dmd.initsem;
import dmd.location;
import dmd.mtype;
import dmd.opover;
+import dmd.optimize;
import dmd.root.array;
import dmd.common.outbuffer;
import dmd.rootobject;
@@ -745,7 +746,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
OutBuffer buf;
HdrGenState hgs;
- buf.writestring(ident.toString());
+ buf.writestring(ident == Id.ctor ? "this" : ident.toString());
buf.writeByte('(');
foreach (i, const tp; *parameters)
{
@@ -762,6 +763,11 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
TypeFunction tf = cast(TypeFunction)fd.type;
buf.writestring(parametersTypeToChars(tf.parameterList));
+ if (tf.mod)
+ {
+ buf.writeByte(' ');
+ buf.MODtoBuffer(tf.mod);
+ }
}
}
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index 7c76da9..9f85574 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -20,6 +20,7 @@ import dmd.astenums;
import dmd.arraytypes;
import dmd.attrib;
import dmd.dsymbol;
+import dmd.dsymbolsem;
import dmd.errors;
import dmd.globals;
import dmd.hdrgen;
diff --git a/gcc/d/dmd/dversion.d b/gcc/d/dmd/dversion.d
index aa22532..31725c8 100644
--- a/gcc/d/dmd/dversion.d
+++ b/gcc/d/dmd/dversion.d
@@ -68,43 +68,6 @@ extern (C++) final class DebugSymbol : Dsymbol
}
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- //printf("DebugSymbol::addMember('%s') %s\n", sds.toChars(), toChars());
- Module m = sds.isModule();
- // Do not add the member to the symbol table,
- // just make sure subsequent debug declarations work.
- if (ident)
- {
- if (!m)
- {
- .error(loc, "%s `%s` declaration must be at module level", kind, toPrettyChars);
- errors = true;
- }
- else
- {
- if (findCondition(m.debugidsNot, ident))
- {
- .error(loc, "%s `%s` defined after use", kind, toPrettyChars);
- errors = true;
- }
- if (!m.debugids)
- m.debugids = new Identifiers();
- m.debugids.push(ident);
- }
- }
- else
- {
- if (!m)
- {
- .error(loc, "%s `%s` level declaration must be at module level", kind, toPrettyChars);
- errors = true;
- }
- else
- m.debuglevel = level;
- }
- }
-
override const(char)* kind() const nothrow
{
return "debug";
@@ -162,44 +125,6 @@ extern (C++) final class VersionSymbol : Dsymbol
}
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- //printf("VersionSymbol::addMember('%s') %s\n", sds.toChars(), toChars());
- Module m = sds.isModule();
- // Do not add the member to the symbol table,
- // just make sure subsequent debug declarations work.
- if (ident)
- {
- VersionCondition.checkReserved(loc, ident.toString());
- if (!m)
- {
- .error(loc, "%s `%s` declaration must be at module level", kind, toPrettyChars);
- errors = true;
- }
- else
- {
- if (findCondition(m.versionidsNot, ident))
- {
- .error(loc, "%s `%s` defined after use", kind, toPrettyChars);
- errors = true;
- }
- if (!m.versionids)
- m.versionids = new Identifiers();
- m.versionids.push(ident);
- }
- }
- else
- {
- if (!m)
- {
- .error(loc, "%s `%s` level declaration must be at module level", kind, toPrettyChars);
- errors = true;
- }
- else
- m.versionlevel = level;
- }
- }
-
override const(char)* kind() const nothrow
{
return "version";
diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h
index be12c65..e17e8cf 100644
--- a/gcc/d/dmd/enum.h
+++ b/gcc/d/dmd/enum.h
@@ -46,12 +46,10 @@ public:
bool inuse(bool v);
EnumDeclaration *syntaxCopy(Dsymbol *s) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
void setScope(Scope *sc) override;
bool oneMember(Dsymbol **ps, Identifier *ident) override;
Type *getType() override;
const char *kind() const override;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
bool isDeprecated() const override; // is Dsymbol deprecated?
Visibility visible() override;
bool isSpecial() const;
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 3f85ea0..e25fc84 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -25,7 +25,7 @@ import dmd.dsymbol;
import dmd.errors;
import dmd.expression;
import dmd.func;
-import dmd.globals;
+import dmd.globals : FeatureState;
import dmd.id;
import dmd.identifier;
import dmd.init;
@@ -169,7 +169,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
if (!(eb.isMutable || eb2.isMutable))
return;
- if (!tf.islive && !(global.params.useDIP1000 == FeatureState.enabled && sc.func && sc.func.setUnsafe()))
+ if (!tf.islive && !(sc.useDIP1000 == FeatureState.enabled && sc.func && sc.func.setUnsafe()))
return;
if (!gag)
@@ -377,7 +377,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc))
{
result = true;
- printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
+ printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), sc.useDIP1000), vPar, 10);
}
}
@@ -1094,7 +1094,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
{
if (p == sc.func)
{
- result |= escapingRef(v, global.params.useDIP1000);
+ result |= escapingRef(v, sc.useDIP1000);
continue;
}
}
@@ -1110,7 +1110,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
{
//printf("escaping reference to local ref variable %s\n", v.toChars());
//printf("storage class = x%llx\n", v.storage_class);
- result |= escapingRef(v, global.params.useDIP25);
+ result |= escapingRef(v, sc.useDIP25);
continue;
}
// Don't need to be concerned if v's parent does not return a ref
@@ -1125,12 +1125,12 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
const(char)* msg = "storing reference to outer local variable `%s` into allocated memory causes it to escape";
if (!gag)
{
- previewErrorFunc(sc.isDeprecated(), global.params.useDIP25)(e.loc, msg, v.toChars());
+ previewErrorFunc(sc.isDeprecated(), sc.useDIP25)(e.loc, msg, v.toChars());
}
// If -preview=dip25 is used, the user wants an error
// Otherwise, issue a deprecation
- result |= (global.params.useDIP25 == FeatureState.enabled);
+ result |= (sc.useDIP25 == FeatureState.enabled);
}
}
@@ -1264,7 +1264,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
// https://issues.dlang.org/show_bug.cgi?id=23191
if (!gag)
{
- previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)(e.loc,
+ previewErrorFunc(sc.isDeprecated(), sc.useDIP1000)(e.loc,
"scope parameter `%s` may not be returned", v.toChars()
);
result = true;
@@ -1403,7 +1403,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
{
//printf("escaping reference to local ref variable %s\n", v.toChars());
//printf("storage class = x%llx\n", v.storage_class);
- escapingRef(v, global.params.useDIP25);
+ escapingRef(v, sc.useDIP25);
continue;
}
// Don't need to be concerned if v's parent does not return a ref
@@ -1415,7 +1415,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
{
const(char)* msg = "escaping reference to outer local variable `%s`";
if (!gag)
- previewErrorFunc(sc.isDeprecated(), global.params.useDIP25)(e.loc, msg, v.toChars());
+ previewErrorFunc(sc.isDeprecated(), sc.useDIP25)(e.loc, msg, v.toChars());
result = true;
continue;
}
@@ -2588,7 +2588,7 @@ public
bool setUnsafeDIP1000(Scope* sc, bool gag, Loc loc, const(char)* msg,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
- return setUnsafePreview(sc, global.params.useDIP1000, gag, loc, msg, arg0, arg1, arg2);
+ return setUnsafePreview(sc, sc.useDIP1000, gag, loc, msg, arg0, arg1, arg2);
}
/***************************************
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 87611f4..cd93e54 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -18,25 +18,19 @@ import core.stdc.stdio;
import core.stdc.string;
import dmd.aggregate;
-import dmd.aliasthis;
-import dmd.arrayop;
import dmd.arraytypes;
import dmd.astenums;
import dmd.ast_node;
import dmd.gluelayer;
-import dmd.ctfeexpr;
-import dmd.ctorflow;
import dmd.dclass;
import dmd.declaration;
import dmd.dimport;
import dmd.dmodule;
-import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dtemplate;
import dmd.errors;
import dmd.errorsink;
-import dmd.expressionsem;
import dmd.func;
import dmd.globals;
import dmd.hdrgen;
@@ -45,39 +39,20 @@ import dmd.identifier;
import dmd.init;
import dmd.location;
import dmd.mtype;
-import dmd.opover;
-import dmd.optimize;
import dmd.root.complex;
import dmd.root.ctfloat;
-import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.optional;
import dmd.root.rmem;
import dmd.rootobject;
import dmd.root.string;
import dmd.root.utf;
-import dmd.safe;
import dmd.target;
import dmd.tokens;
import dmd.visitor;
enum LOGSEMANTIC = false;
-void emplaceExp(T : Expression, Args...)(void* p, Args args)
-{
- static if (__VERSION__ < 2099)
- const init = typeid(T).initializer;
- else
- const init = __traits(initSymbol, T);
- p[0 .. __traits(classInstanceSize, T)] = init[];
- (cast(T)p).__ctor(args);
-}
-
-void emplaceExp(T : UnionExp)(T* p, Expression e)
-{
- memcpy(p, cast(void*)e, e.size);
-}
-
/// Return value for `checkModifiable`
enum Modifiable
{
@@ -118,45 +93,6 @@ inout(Expression) lastComma(inout Expression e)
}
-/***********************************
- * Determine if a `this` is needed to access `d`.
- * Params:
- * sc = context
- * d = declaration to check
- * Returns:
- * true means a `this` is needed
- */
-bool isNeedThisScope(Scope* sc, Declaration d)
-{
- if (sc.intypeof == 1)
- return false;
-
- AggregateDeclaration ad = d.isThis();
- if (!ad)
- return false;
- //printf("d = %s, ad = %s\n", d.toChars(), ad.toChars());
-
- for (Dsymbol s = sc.parent; s; s = s.toParentLocal())
- {
- //printf("\ts = %s %s, toParent2() = %p\n", s.kind(), s.toChars(), s.toParent2());
- if (AggregateDeclaration ad2 = s.isAggregateDeclaration())
- {
- if (ad2 == ad)
- return false;
- else if (ad2.isNested())
- continue;
- else
- return true;
- }
- if (FuncDeclaration f = s.isFuncDeclaration())
- {
- if (f.isMemberLocal())
- break;
- }
- }
- return true;
-}
-
/****************************************
* Expand tuples in-place.
*
@@ -315,70 +251,6 @@ TemplateDeclaration getFuncTemplateDecl(Dsymbol s) @safe
return null;
}
-/****************************************************************/
-/* A type meant as a union of all the Expression types,
- * to serve essentially as a Variant that will sit on the stack
- * during CTFE to reduce memory consumption.
- */
-extern (D) struct UnionExp
-{
- // yes, default constructor does nothing
- extern (D) this(Expression e)
- {
- memcpy(&this, cast(void*)e, e.size);
- }
-
- /* Extract pointer to Expression
- */
- extern (D) Expression exp() return
- {
- return cast(Expression)&u;
- }
-
- /* Convert to an allocated Expression
- */
- extern (D) Expression copy()
- {
- Expression e = exp();
- //if (e.size > sizeof(u)) printf("%s\n", EXPtoString(e.op).ptr);
- assert(e.size <= u.sizeof);
- switch (e.op)
- {
- case EXP.cantExpression: return CTFEExp.cantexp;
- case EXP.voidExpression: return CTFEExp.voidexp;
- case EXP.break_: return CTFEExp.breakexp;
- case EXP.continue_: return CTFEExp.continueexp;
- case EXP.goto_: return CTFEExp.gotoexp;
- default: return e.copy();
- }
- }
-
-private:
- // Ensure that the union is suitably aligned.
- align(8) union _AnonStruct_u
- {
- char[__traits(classInstanceSize, Expression)] exp;
- char[__traits(classInstanceSize, IntegerExp)] integerexp;
- char[__traits(classInstanceSize, ErrorExp)] errorexp;
- char[__traits(classInstanceSize, RealExp)] realexp;
- char[__traits(classInstanceSize, ComplexExp)] complexexp;
- char[__traits(classInstanceSize, SymOffExp)] symoffexp;
- char[__traits(classInstanceSize, StringExp)] stringexp;
- char[__traits(classInstanceSize, ArrayLiteralExp)] arrayliteralexp;
- char[__traits(classInstanceSize, AssocArrayLiteralExp)] assocarrayliteralexp;
- char[__traits(classInstanceSize, StructLiteralExp)] structliteralexp;
- char[__traits(classInstanceSize, CompoundLiteralExp)] compoundliteralexp;
- char[__traits(classInstanceSize, NullExp)] nullexp;
- char[__traits(classInstanceSize, DotVarExp)] dotvarexp;
- char[__traits(classInstanceSize, AddrExp)] addrexp;
- char[__traits(classInstanceSize, IndexExp)] indexexp;
- char[__traits(classInstanceSize, SliceExp)] sliceexp;
- char[__traits(classInstanceSize, VectorExp)] vectorexp;
- }
-
- _AnonStruct_u u;
-}
-
/************************ TypeDotIdExp ************************************/
/* Things like:
* int.size
@@ -678,71 +550,6 @@ extern (C++) abstract class Expression : ASTNode
return false;
}
- /*******************************
- * Give error if we're not an lvalue.
- * If we can, convert expression to be an lvalue.
- */
- Expression toLvalue(Scope* sc, Expression e)
- {
- if (!e)
- e = this;
- else if (!loc.isValid())
- loc = e.loc;
-
- if (e.op == EXP.type)
- error(loc, "`%s` is a `%s` definition and cannot be modified", e.type.toChars(), e.type.kind());
- else
- error(loc, "`%s` is not an lvalue and cannot be modified", e.toChars());
-
- return ErrorExp.get();
- }
-
- Expression modifiableLvalue(Scope* sc, Expression e)
- {
- //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type.toChars());
- // See if this expression is a modifiable lvalue (i.e. not const)
- if (checkModifiable(this, sc) == Modifiable.yes)
- {
- assert(type);
- if (!type.isMutable())
- {
- if (auto dve = this.isDotVarExp())
- {
- if (isNeedThisScope(sc, dve.var))
- for (Dsymbol s = sc.func; s; s = s.toParentLocal())
- {
- FuncDeclaration ff = s.isFuncDeclaration();
- if (!ff)
- break;
- if (!ff.type.isMutable)
- {
- error(loc, "cannot modify `%s` in `%s` function", toChars(), MODtoChars(type.mod));
- return ErrorExp.get();
- }
- }
- }
- error(loc, "cannot modify `%s` expression `%s`", MODtoChars(type.mod), toChars());
- return ErrorExp.get();
- }
- else if (!type.isAssignable())
- {
- error(loc, "cannot modify struct instance `%s` of type `%s` because it contains `const` or `immutable` members",
- toChars(), type.toChars());
- return ErrorExp.get();
- }
- }
- return toLvalue(sc, e);
- }
-
- /****************************************
- * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, __FILE_FULL_PATH__ to loc.
- */
- Expression resolveLoc(const ref Loc loc, Scope* sc)
- {
- this.loc = loc;
- return this;
- }
-
/****************************************
* Check that the expression has a valid type.
* If not, generates an error "... has no type".
@@ -835,417 +642,6 @@ extern (C++) abstract class Expression : ASTNode
return checkValue();
}
- extern (D) final bool checkDeprecated(Scope* sc, Dsymbol s)
- {
- return s.checkDeprecated(loc, sc);
- }
-
- extern (D) final bool checkDisabled(Scope* sc, Dsymbol s)
- {
- if (auto d = s.isDeclaration())
- {
- return d.checkDisabled(loc, sc);
- }
-
- return false;
- }
-
- /*********************************************
- * Calling function f.
- * Check the purity, i.e. if we're in a pure function
- * we can only call other pure functions.
- * Returns true if error occurs.
- */
- extern (D) final bool checkPurity(Scope* sc, FuncDeclaration f)
- {
- if (!sc.func)
- return false;
- if (sc.func == f)
- return false;
- if (sc.intypeof == 1)
- return false;
- if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
- return false;
-
- // If the call has a pure parent, then the called func must be pure.
- if (!f.isPure() && checkImpure(sc, loc, null, f))
- {
- error(loc, "`pure` %s `%s` cannot call impure %s `%s`",
- sc.func.kind(), sc.func.toPrettyChars(), f.kind(),
- f.toPrettyChars());
-
- if (!f.isDtorDeclaration())
- errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.pure_);
-
- checkOverriddenDtor(sc, f, dd => dd.type.toTypeFunction().purity != PURE.impure, "impure");
- return true;
- }
- return false;
- }
-
- /**
- * Checks whether `f` is a generated `DtorDeclaration` that hides a user-defined one
- * which passes `check` while `f` doesn't (e.g. when the user defined dtor is pure but
- * the generated dtor is not).
- * In that case the method will identify and print all members causing the attribute
- * missmatch.
- *
- * Params:
- * sc = scope
- * f = potential `DtorDeclaration`
- * check = current check (e.g. whether it's pure)
- * checkName = the kind of check (e.g. `"pure"`)
- */
- extern (D) final void checkOverriddenDtor(Scope* sc, FuncDeclaration f,
- scope bool function(DtorDeclaration) check, const string checkName
- ) {
- auto dd = f.isDtorDeclaration();
- if (!dd || !dd.isGenerated())
- return;
-
- // DtorDeclaration without parents should fail at an earlier stage
- auto ad = cast(AggregateDeclaration) f.toParent2();
- assert(ad);
-
- if (ad.userDtors.length)
- {
- if (!check(ad.userDtors[0])) // doesn't match check (e.g. is impure as well)
- return;
-
- // Sanity check
- assert(!check(ad.fieldDtor));
- }
-
- dd.loc.errorSupplemental("%s`%s.~this` is %.*s because of the following field's destructors:",
- dd.isGenerated() ? "generated " : "".ptr,
- ad.toChars,
- cast(int) checkName.length, checkName.ptr);
-
- // Search for the offending fields
- foreach (field; ad.fields)
- {
- // Only structs may define automatically called destructors
- auto ts = field.type.isTypeStruct();
- if (!ts)
- {
- // But they might be part of a static array
- auto ta = field.type.isTypeSArray();
- if (!ta)
- continue;
-
- ts = ta.baseElemOf().isTypeStruct();
- if (!ts)
- continue;
- }
-
- auto fieldSym = ts.toDsymbol(sc);
- assert(fieldSym); // Resolving ts must succeed because missing defs. should error before
-
- auto fieldSd = fieldSym.isStructDeclaration();
- assert(fieldSd); // ts is a TypeStruct, this would imply a malformed ASR
-
- if (fieldSd.dtor && !check(fieldSd.dtor))
- {
- field.loc.errorSupplemental(" - %s %s", field.type.toChars(), field.toChars());
-
- if (fieldSd.dtor.isGenerated())
- checkOverriddenDtor(sc, fieldSd.dtor, check, checkName);
- else
- fieldSd.dtor.loc.errorSupplemental(" %.*s `%s.~this` is declared here",
- cast(int) checkName.length, checkName.ptr, fieldSd.toChars());
- }
- }
- }
-
- /*******************************************
- * Accessing variable v.
- * Check for purity and safety violations.
- * Returns true if error occurs.
- */
- extern (D) final bool checkPurity(Scope* sc, VarDeclaration v)
- {
- //printf("v = %s %s\n", v.type.toChars(), v.toChars());
- /* Look for purity and safety violations when accessing variable v
- * from current function.
- */
- if (!sc.func)
- return false;
- if (sc.intypeof == 1)
- return false; // allow violations inside typeof(expression)
- if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
- return false; // allow violations inside compile-time evaluated expressions and debug conditionals
- if (v.ident == Id.ctfe)
- return false; // magic variable never violates pure and safe
- if (v.isImmutable())
- return false; // always safe and pure to access immutables...
- if (v.isConst() && !v.isReference() && (v.isDataseg() || v.isParameter()) && v.type.implicitConvTo(v.type.immutableOf()))
- return false; // or const global/parameter values which have no mutable indirections
- if (v.storage_class & STC.manifest)
- return false; // ...or manifest constants
-
- // accessing empty structs is pure
- // https://issues.dlang.org/show_bug.cgi?id=18694
- // https://issues.dlang.org/show_bug.cgi?id=21464
- // https://issues.dlang.org/show_bug.cgi?id=23589
- if (v.type.ty == Tstruct)
- {
- StructDeclaration sd = (cast(TypeStruct)v.type).sym;
- if (sd.members) // not opaque
- {
- if (sd.semanticRun >= PASS.semanticdone)
- sd.determineSize(v.loc);
- if (sd.hasNoFields)
- return false;
- }
- }
-
- bool err = false;
- if (v.isDataseg())
- {
- // https://issues.dlang.org/show_bug.cgi?id=7533
- // Accessing implicit generated __gate is pure.
- if (v.ident == Id.gate)
- return false;
-
- if (checkImpure(sc, loc, "`pure` %s `%s` cannot access mutable static data `%s`", v))
- {
- error(loc, "`pure` %s `%s` cannot access mutable static data `%s`",
- sc.func.kind(), sc.func.toPrettyChars(), v.toChars());
- err = true;
- }
- }
- else
- {
- /* Given:
- * void f() {
- * int fx;
- * pure void g() {
- * int gx;
- * /+pure+/ void h() {
- * int hx;
- * /+pure+/ void i() { }
- * }
- * }
- * }
- * i() can modify hx and gx but not fx
- */
-
- Dsymbol vparent = v.toParent2();
- for (Dsymbol s = sc.func; !err && s; s = s.toParentP(vparent))
- {
- if (s == vparent)
- break;
-
- if (AggregateDeclaration ad = s.isAggregateDeclaration())
- {
- if (ad.isNested())
- continue;
- break;
- }
- FuncDeclaration ff = s.isFuncDeclaration();
- if (!ff)
- break;
- if (ff.isNested() || ff.isThis())
- {
- if (ff.type.isImmutable() ||
- ff.type.isShared() && !MODimplicitConv(ff.type.mod, v.type.mod))
- {
- OutBuffer ffbuf;
- OutBuffer vbuf;
- MODMatchToBuffer(&ffbuf, ff.type.mod, v.type.mod);
- MODMatchToBuffer(&vbuf, v.type.mod, ff.type.mod);
- error(loc, "%s%s `%s` cannot access %sdata `%s`",
- ffbuf.peekChars(), ff.kind(), ff.toPrettyChars(), vbuf.peekChars(), v.toChars());
- err = true;
- break;
- }
- continue;
- }
- break;
- }
- }
-
- /* Do not allow safe functions to access __gshared data
- */
- if (v.storage_class & STC.gshared)
- {
- if (sc.setUnsafe(false, this.loc,
- "`@safe` function `%s` cannot access `__gshared` data `%s`", sc.func, v))
- {
- err = true;
- }
- }
-
- return err;
- }
-
- /*
- Check if sc.func is impure or can be made impure.
- Returns true on error, i.e. if sc.func is pure and cannot be made impure.
- */
- private static bool checkImpure(Scope* sc, Loc loc, const(char)* fmt, RootObject arg0)
- {
- return sc.func && (isRootTraitsCompilesScope(sc)
- ? sc.func.isPureBypassingInference() >= PURE.weak
- : sc.func.setImpure(loc, fmt, arg0));
- }
-
- /*********************************************
- * Calling function f.
- * Check the safety, i.e. if we're in a @safe function
- * we can only call @safe or @trusted functions.
- * Returns true if error occurs.
- */
- extern (D) final bool checkSafety(Scope* sc, FuncDeclaration f)
- {
- if (sc.func == f)
- return false;
- if (sc.intypeof == 1)
- return false;
- if (sc.flags & SCOPE.debug_)
- return false;
- if ((sc.flags & SCOPE.ctfe) && sc.func)
- return false;
-
- if (!sc.func)
- {
- if (sc.varDecl && !f.safetyInprocess && !f.isSafe() && !f.isTrusted())
- {
- if (sc.varDecl.storage_class & STC.safe)
- {
- error(loc, "`@safe` variable `%s` cannot be initialized by calling `@system` function `%s`",
- sc.varDecl.toChars(), f.toChars());
- return true;
- }
- else
- {
- sc.varDecl.storage_class |= STC.system;
- sc.varDecl.systemInferred = true;
- }
- }
- return false;
- }
-
- if (!f.isSafe() && !f.isTrusted())
- {
- if (isRootTraitsCompilesScope(sc) ? sc.func.isSafeBypassingInference() : sc.func.setUnsafeCall(f))
- {
- if (!loc.isValid()) // e.g. implicitly generated dtor
- loc = sc.func.loc;
-
- const prettyChars = f.toPrettyChars();
- error(loc, "`@safe` %s `%s` cannot call `@system` %s `%s`",
- sc.func.kind(), sc.func.toPrettyChars(), f.kind(),
- prettyChars);
- if (!f.isDtorDeclaration)
- errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.safe);
- .errorSupplemental(f.loc, "`%s` is declared here", prettyChars);
-
- checkOverriddenDtor(sc, f, dd => dd.type.toTypeFunction().trust > TRUST.system, "@system");
-
- return true;
- }
- }
- else if (f.isSafe() && f.safetyViolation)
- {
- // for dip1000 by default transition, print deprecations for calling functions that will become `@system`
- if (sc.func.isSafeBypassingInference())
- {
- .deprecation(this.loc, "`@safe` function `%s` calling `%s`", sc.func.toChars(), f.toChars());
- errorSupplementalInferredAttr(f, 10, true, STC.safe);
- }
- else if (!sc.func.safetyViolation)
- {
- import dmd.func : AttributeViolation;
- sc.func.safetyViolation = new AttributeViolation(this.loc, null, f, null, null);
- }
- }
- return false;
- }
-
- /*********************************************
- * Calling function f.
- * Check the @nogc-ness, i.e. if we're in a @nogc function
- * we can only call other @nogc functions.
- * Returns true if error occurs.
- */
- extern (D) final bool checkNogc(Scope* sc, FuncDeclaration f)
- {
- if (!sc.func)
- return false;
- if (sc.func == f)
- return false;
- if (sc.intypeof == 1)
- return false;
- if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
- return false;
- /* The original expressions (`new S(...)` or `new S[...]``) will be
- * verified instead. This is to keep errors related to the original code
- * and not the lowering.
- */
- if (f.ident == Id._d_newitemT || f.ident == Id._d_newarrayT)
- return false;
-
- if (!f.isNogc())
- {
- if (isRootTraitsCompilesScope(sc) ? sc.func.isNogcBypassingInference() : sc.func.setGCCall(f))
- {
- if (loc.linnum == 0) // e.g. implicitly generated dtor
- loc = sc.func.loc;
-
- // Lowered non-@nogc'd hooks will print their own error message inside of nogc.d (NOGCVisitor.visit(CallExp e)),
- // so don't print anything to avoid double error messages.
- if (!(f.ident == Id._d_HookTraceImpl || f.ident == Id._d_arraysetlengthT
- || f.ident == Id._d_arrayappendT || f.ident == Id._d_arrayappendcTX
- || f.ident == Id._d_arraycatnTX || f.ident == Id._d_newclassT))
- {
- error(loc, "`@nogc` %s `%s` cannot call non-@nogc %s `%s`",
- sc.func.kind(), sc.func.toPrettyChars(), f.kind(), f.toPrettyChars());
-
- if (!f.isDtorDeclaration)
- f.errorSupplementalInferredAttr(/*max depth*/ 10, /*deprecation*/ false, STC.nogc);
- }
-
- checkOverriddenDtor(sc, f, dd => dd.type.toTypeFunction().isnogc, "non-@nogc");
-
- return true;
- }
- }
- return false;
- }
-
- /********************************************
- * Check that the postblit is callable if t is an array of structs.
- * Returns true if error happens.
- */
- extern (D) final bool checkPostblit(Scope* sc, Type t)
- {
- if (auto ts = t.baseElemOf().isTypeStruct())
- {
- if (global.params.useTypeInfo && Type.dtypeinfo)
- {
- // https://issues.dlang.org/show_bug.cgi?id=11395
- // Require TypeInfo generation for array concatenation
- semanticTypeInfo(sc, t);
- }
-
- StructDeclaration sd = ts.sym;
- if (sd.postblit)
- {
- if (sd.postblit.checkDisabled(loc, sc))
- return true;
-
- //checkDeprecated(sc, sd.postblit); // necessary?
- checkPurity(sc, sd.postblit);
- checkSafety(sc, sd.postblit);
- checkNogc(sc, sd.postblit);
- //checkAccess(sd, loc, sc, sd.postblit); // necessary?
- return false;
- }
- }
- return false;
- }
-
/*******************************
* Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.
* ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)
@@ -1308,11 +704,6 @@ extern (C++) abstract class Expression : ASTNode
return this;
}
- final Expression optimize(int result, bool keepLvalue = false)
- {
- return Expression_optimize(this, result, keepLvalue);
- }
-
final int isConst()
{
//printf("Expression::isConst(): %s\n", e.toChars());
@@ -1587,16 +978,6 @@ extern (C++) final class IntegerExp : Expression
return typeof(return)(r);
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (!e)
- e = this;
- else if (!loc.isValid())
- loc = e.loc;
- error(e.loc, "cannot modify constant `%s`", e.toChars());
- return ErrorExp.get();
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -1722,7 +1103,7 @@ extern (C++) final class IntegerExp : Expression
*/
extern (C++) final class ErrorExp : Expression
{
- private extern (D) this()
+ extern (D) this()
{
super(Loc.initial, EXP.error);
type = Type.terror;
@@ -1745,11 +1126,6 @@ extern (C++) final class ErrorExp : Expression
return errorexp;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -1987,11 +1363,6 @@ extern (C++) class IdentifierExp : Expression
return true;
}
- override final Expression toLvalue(Scope* sc, Expression e)
- {
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -2036,11 +1407,6 @@ extern (C++) final class DsymbolExp : Expression
return true;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -2087,16 +1453,6 @@ extern (C++) class ThisExp : Expression
return type.toBasetype().ty != Tclass;
}
- override final Expression toLvalue(Scope* sc, Expression e)
- {
- if (type.toBasetype().ty == Tclass)
- {
- // Class `this` is an rvalue; struct `this` is an lvalue.
- return Expression.toLvalue(sc, e);
- }
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -2464,18 +1820,6 @@ extern (C++) final class StringExp : Expression
return (type && type.toBasetype().ty == Tsarray);
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- //printf("StringExp::toLvalue(%s) type = %s\n", toChars(), type ? type.toChars() : NULL);
- return (type && type.toBasetype().ty == Tsarray) ? this : Expression.toLvalue(sc, e);
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- error(loc, "cannot modify string literal `%s`", toChars());
- return ErrorExp.get();
- }
-
/********************************
* Convert string contents to a 0 terminated string,
* allocated by mem.xmalloc().
@@ -3050,14 +2394,6 @@ extern (C++) final class StructLiteralExp : Expression
return -1;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (sc.flags & SCOPE.Cfile)
- return this; // C struct literals are lvalues
- else
- return Expression.toLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -3203,15 +2539,6 @@ extern (C++) final class TemplateExp : Expression
return fd !is null;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (!fd)
- return Expression.toLvalue(sc, e);
-
- assert(sc);
- return symbolToExp(fd, loc, sc, true);
- }
-
override bool checkType()
{
error(loc, "%s `%s` has no type", td.kind(), toChars());
@@ -3409,43 +2736,6 @@ extern (C++) final class VarExp : SymbolExp
return true;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (var.storage_class & STC.manifest)
- {
- error(loc, "manifest constant `%s` cannot be modified", var.toChars());
- return ErrorExp.get();
- }
- if (var.storage_class & STC.lazy_ && !delegateWasExtracted)
- {
- error(loc, "lazy variable `%s` cannot be modified", var.toChars());
- return ErrorExp.get();
- }
- if (var.ident == Id.ctfe)
- {
- error(loc, "cannot modify compiler-generated variable `__ctfe`");
- return ErrorExp.get();
- }
- if (var.ident == Id.dollar) // https://issues.dlang.org/show_bug.cgi?id=13574
- {
- error(loc, "cannot modify operator `$`");
- return ErrorExp.get();
- }
- return this;
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- //printf("VarExp::modifiableLvalue('%s')\n", var.toChars());
- if (var.storage_class & STC.manifest)
- {
- error(loc, "cannot modify manifest constant `%s`", toChars());
- return ErrorExp.get();
- }
- // See if this expression is a modifiable lvalue (i.e. not const)
- return Expression.modifiableLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -3472,11 +2762,6 @@ extern (C++) final class OverExp : Expression
return true;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -3522,52 +2807,6 @@ extern (C++) final class FuncExp : Expression
return false;
}
- extern (D) void genIdent(Scope* sc)
- {
- if (fd.ident == Id.empty)
- {
- const(char)[] s;
- if (fd.fes)
- s = "__foreachbody";
- else if (fd.tok == TOK.reserved)
- s = "__lambda";
- else if (fd.tok == TOK.delegate_)
- s = "__dgliteral";
- else
- s = "__funcliteral";
-
- DsymbolTable symtab;
- if (FuncDeclaration func = sc.parent.isFuncDeclaration())
- {
- if (func.localsymtab is null)
- {
- // Inside template constraint, symtab is not set yet.
- // Initialize it lazily.
- func.localsymtab = new DsymbolTable();
- }
- symtab = func.localsymtab;
- }
- else
- {
- ScopeDsymbol sds = sc.parent.isScopeDsymbol();
- if (!sds.symtab)
- {
- // Inside template constraint, symtab may not be set yet.
- // Initialize it lazily.
- assert(sds.isTemplateInstance());
- sds.symtab = new DsymbolTable();
- }
- symtab = sds.symtab;
- }
- assert(symtab);
- Identifier id = Identifier.generateId(s, symtab.length() + 1);
- fd.ident = id;
- if (td)
- td.ident = id;
- symtab.insert(td ? cast(Dsymbol)td : cast(Dsymbol)fd);
- }
- }
-
override FuncExp syntaxCopy()
{
if (td)
@@ -3815,12 +3054,6 @@ extern (C++) abstract class UnaExp : Expression
}
- override final Expression resolveLoc(const ref Loc loc, Scope* sc)
- {
- e1 = e1.resolveLoc(loc, sc);
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -3936,18 +3169,6 @@ extern (C++) class BinAssignExp : BinExp
return true;
}
- override final Expression toLvalue(Scope* sc, Expression ex)
- {
- // Lvalue-ness will be handled in glue layer.
- return this;
- }
-
- override final Expression modifiableLvalue(Scope* sc, Expression e)
- {
- // should check e1.checkModifiable() ?
- return toLvalue(sc, this);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -4156,58 +3377,6 @@ extern (C++) final class DotVarExp : UnaExp
return !(vd && vd.isField());
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- //printf("DotVarExp::toLvalue(%s)\n", toChars());
- if (sc && sc.flags & SCOPE.Cfile)
- {
- /* C11 6.5.2.3-3: A postfix expression followed by the '.' or '->' operator
- * is an lvalue if the first expression is an lvalue.
- */
- if (!e1.isLvalue())
- return Expression.toLvalue(sc, e);
- }
- if (!isLvalue())
- return Expression.toLvalue(sc, e);
- if (e1.op == EXP.this_ && sc.ctorflow.fieldinit.length && !(sc.ctorflow.callSuper & CSX.any_ctor))
- {
- if (VarDeclaration vd = var.isVarDeclaration())
- {
- auto ad = vd.isMember2();
- if (ad && ad.fields.length == sc.ctorflow.fieldinit.length)
- {
- foreach (i, f; ad.fields)
- {
- if (f == vd)
- {
- if (!(sc.ctorflow.fieldinit[i].csx & CSX.this_ctor))
- {
- /* If the address of vd is taken, assume it is thereby initialized
- * https://issues.dlang.org/show_bug.cgi?id=15869
- */
- modifyFieldVar(loc, sc, vd, e1);
- }
- break;
- }
- }
- }
- }
- }
- return this;
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- version (none)
- {
- printf("DotVarExp::modifiableLvalue(%s)\n", toChars());
- printf("e1.type = %s\n", e1.type.toChars());
- printf("var.type = %s\n", var.type.toChars());
- }
-
- return Expression.modifiableLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -4239,49 +3408,6 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp
return new DotTemplateInstanceExp(loc, e1.syntaxCopy(), ti.name, TemplateInstance.arraySyntaxCopy(ti.tiargs));
}
- extern (D) bool findTempDecl(Scope* sc)
- {
- static if (LOGSEMANTIC)
- {
- printf("DotTemplateInstanceExp::findTempDecl('%s')\n", toChars());
- }
- if (ti.tempdecl)
- return true;
-
- Expression e = new DotIdExp(loc, e1, ti.name);
- e = e.expressionSemantic(sc);
- if (e.op == EXP.dot)
- e = (cast(DotExp)e).e2;
-
- Dsymbol s = null;
- switch (e.op)
- {
- case EXP.overloadSet:
- s = (cast(OverExp)e).vars;
- break;
-
- case EXP.dotTemplateDeclaration:
- s = (cast(DotTemplateExp)e).td;
- break;
-
- case EXP.scope_:
- s = (cast(ScopeExp)e).sds;
- break;
-
- case EXP.dotVariable:
- s = (cast(DotVarExp)e).var;
- break;
-
- case EXP.variable:
- s = (cast(VarExp)e).var;
- break;
-
- default:
- return false;
- }
- return ti.updateTempDecl(sc, s);
- }
-
override bool checkType()
{
// Same logic as ScopeExp.checkType()
@@ -4486,13 +3612,6 @@ extern (C++) final class CallExp : UnaExp
return false;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (isLvalue())
- return this;
- return Expression.toLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -4600,30 +3719,6 @@ extern (C++) final class PtrExp : UnaExp
return true;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- return this;
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type.toChars());
- Declaration var;
- if (auto se = e1.isSymOffExp())
- var = se.var;
- else if (auto ve = e1.isVarExp())
- var = ve.var;
- if (var && var.type.isFunction_Delegate_PtrToFunction())
- {
- if (var.type.isTypeFunction())
- error(loc, "function `%s` is not an lvalue and cannot be modified", var.toChars());
- else
- error(loc, "function pointed to by `%s` is not an lvalue and cannot be modified", var.toChars());
- return ErrorExp.get();
- }
- return Expression.modifiableLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -4755,19 +3850,6 @@ extern (C++) final class CastExp : UnaExp
e1.type.mutableOf().unSharedOf().equals(to.mutableOf().unSharedOf());
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (sc && sc.flags & SCOPE.Cfile)
- {
- /* C11 6.5.4-5: A cast does not yield an lvalue.
- */
- return Expression.toLvalue(sc, e);
- }
- if (isLvalue())
- return this;
- return Expression.toLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -4822,12 +3904,6 @@ extern (C++) final class VectorArrayExp : UnaExp
return e1.isLvalue();
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- e1 = e1.toLvalue(sc, e);
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -4885,18 +3961,6 @@ extern (C++) final class SliceExp : UnaExp
return (type && type.toBasetype().ty == Tsarray);
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type.toChars() : NULL);
- return (type && type.toBasetype().ty == Tsarray) ? this : Expression.toLvalue(sc, e);
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- error(loc, "slice expression `%s` is not a modifiable lvalue", toChars());
- return this;
- }
-
override Optional!bool toBool()
{
return e1.toBool();
@@ -4964,13 +4028,6 @@ extern (C++) final class ArrayExp : UnaExp
return true;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (type && type.toBasetype().ty == Tvoid)
- error(loc, "`void`s have no value");
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -5018,18 +4075,6 @@ extern (C++) final class CommaExp : BinExp
return e2.isLvalue();
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- e2 = e2.toLvalue(sc, null);
- return this;
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- e2 = e2.modifiableLvalue(sc, e);
- return this;
- }
-
override Optional!bool toBool()
{
return e2.toBool();
@@ -5105,21 +4150,6 @@ extern (C++) final class DelegatePtrExp : UnaExp
return e1.isLvalue();
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- e1 = e1.toLvalue(sc, e);
- return this;
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- if (sc.setUnsafe(false, this.loc, "cannot modify delegate pointer in `@safe` code `%s`", this))
- {
- return ErrorExp.get();
- }
- return Expression.modifiableLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -5143,21 +4173,6 @@ extern (C++) final class DelegateFuncptrExp : UnaExp
return e1.isLvalue();
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- e1 = e1.toLvalue(sc, e);
- return this;
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- if (sc.setUnsafe(false, this.loc, "cannot modify delegate function pointer in `@safe` code `%s`", this))
- {
- return ErrorExp.get();
- }
- return Expression.modifiableLvalue(sc, e);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -5205,23 +4220,6 @@ extern (C++) final class IndexExp : BinExp
return true;
}
- override Expression toLvalue(Scope* sc, Expression e)
- {
- if (isLvalue())
- return this;
- return Expression.toLvalue(sc, e);
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- //printf("IndexExp::modifiableLvalue(%s)\n", toChars());
- Expression ex = markSettingAAElem();
- if (ex.op == EXP.error)
- return ex;
-
- return Expression.modifiableLvalue(sc, e);
- }
-
extern (D) Expression markSettingAAElem()
{
if (e1.type.toBasetype().ty == Taarray)
@@ -5324,20 +4322,6 @@ extern (C++) class AssignExp : BinExp
return true;
}
- override final Expression toLvalue(Scope* sc, Expression ex)
- {
- if (e1.op == EXP.slice || e1.op == EXP.arrayLength)
- {
- return Expression.toLvalue(sc, ex);
- }
-
- /* In front-end level, AssignExp should make an lvalue of e1.
- * Taking the address of e1 will be handled in low level layer,
- * so this function does nothing.
- */
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -5633,7 +4617,9 @@ extern (C++) final class UshrAssignExp : BinAssignExp
*/
extern (C++) class CatAssignExp : BinAssignExp
{
- extern (D) this(const ref Loc loc, Expression e1, Expression e2) @safe
+ Expression lowering; // lowered druntime hook `_d_arrayappend{cTX,T}`
+
+ extern (D) this(const ref Loc loc, Expression e1, Expression e2)
{
super(loc, EXP.concatenateAssign, e1, e2);
}
@@ -5733,13 +4719,6 @@ extern (C++) final class CatExp : BinExp
super(loc, EXP.concatenate, e1, e2);
}
- override Expression resolveLoc(const ref Loc loc, Scope* sc)
- {
- e1 = e1.resolveLoc(loc, sc);
- e2 = e2.resolveLoc(loc, sc);
- return this;
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -6074,28 +5053,6 @@ extern (C++) final class CondExp : BinExp
return e1.isLvalue() && e2.isLvalue();
}
- override Expression toLvalue(Scope* sc, Expression ex)
- {
- // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
- CondExp e = cast(CondExp)copy();
- e.e1 = e1.toLvalue(sc, null).addressOf();
- e.e2 = e2.toLvalue(sc, null).addressOf();
- e.type = type.pointerTo();
- return new PtrExp(loc, e, type);
- }
-
- override Expression modifiableLvalue(Scope* sc, Expression e)
- {
- if (!e1.isLvalue() && !e2.isLvalue())
- {
- error(loc, "conditional expression `%s` is not a modifiable lvalue", toChars());
- return ErrorExp.get();
- }
- e1 = e1.modifiableLvalue(sc, e1);
- e2 = e2.modifiableLvalue(sc, e2);
- return toLvalue(sc, this);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -6145,19 +5102,6 @@ extern (C++) final class FileInitExp : DefaultInitExp
super(loc, tok);
}
- override Expression resolveLoc(const ref Loc loc, Scope* sc)
- {
- //printf("FileInitExp::resolve() %s\n", toChars());
- const(char)* s;
- if (op == EXP.fileFullPath)
- s = FileName.toAbsolute(loc.isValid() ? loc.filename : sc._module.srcfile.toChars());
- else
- s = loc.isValid() ? loc.filename : sc._module.ident.toChars();
-
- Expression e = new StringExp(loc, s.toDString());
- return e.expressionSemantic(sc);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -6174,12 +5118,6 @@ extern (C++) final class LineInitExp : DefaultInitExp
super(loc, EXP.line);
}
- override Expression resolveLoc(const ref Loc loc, Scope* sc)
- {
- Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);
- return e.expressionSemantic(sc);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -6196,13 +5134,6 @@ extern (C++) final class ModuleInitExp : DefaultInitExp
super(loc, EXP.moduleString);
}
- override Expression resolveLoc(const ref Loc loc, Scope* sc)
- {
- const auto s = (sc.callsc ? sc.callsc : sc)._module.toPrettyChars().toDString();
- Expression e = new StringExp(loc, s);
- return e.expressionSemantic(sc);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -6219,19 +5150,6 @@ extern (C++) final class FuncInitExp : DefaultInitExp
super(loc, EXP.functionString);
}
- override Expression resolveLoc(const ref Loc loc, Scope* sc)
- {
- const(char)* s;
- if (sc.callsc && sc.callsc.func)
- s = sc.callsc.func.Dsymbol.toPrettyChars();
- else if (sc.func)
- s = sc.func.Dsymbol.toPrettyChars();
- else
- s = "";
- Expression e = new StringExp(loc, s.toDString());
- return e.expressionSemantic(sc);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -6248,29 +5166,153 @@ extern (C++) final class PrettyFuncInitExp : DefaultInitExp
super(loc, EXP.prettyFunction);
}
- override Expression resolveLoc(const ref Loc loc, Scope* sc)
+ override void accept(Visitor v)
{
- FuncDeclaration fd = (sc.callsc && sc.callsc.func)
- ? sc.callsc.func
- : sc.func;
+ v.visit(this);
+ }
+}
+
+/***********************************************************
+ * A reference to a class, or an interface. We need this when we
+ * point to a base class (we must record what the type is).
+ */
+extern (C++) final class ClassReferenceExp : Expression
+{
+ StructLiteralExp value;
- const(char)* s;
- if (fd)
+ extern (D) this(const ref Loc loc, StructLiteralExp lit, Type type) @safe
+ {
+ super(loc, EXP.classReference);
+ assert(lit && lit.sd && lit.sd.isClassDeclaration());
+ this.value = lit;
+ this.type = type;
+ }
+
+ ClassDeclaration originalClass()
+ {
+ return value.sd.isClassDeclaration();
+ }
+
+ // Return index of the field, or -1 if not found
+ int getFieldIndex(Type fieldtype, uint fieldoffset)
+ {
+ ClassDeclaration cd = originalClass();
+ uint fieldsSoFar = 0;
+ for (size_t j = 0; j < value.elements.length; j++)
{
- const funcStr = fd.Dsymbol.toPrettyChars();
- OutBuffer buf;
- functionToBufferWithIdent(fd.type.isTypeFunction(), buf, funcStr, fd.isStatic);
- s = buf.extractChars();
+ while (j - fieldsSoFar >= cd.fields.length)
+ {
+ fieldsSoFar += cd.fields.length;
+ cd = cd.baseClass;
+ }
+ VarDeclaration v2 = cd.fields[j - fieldsSoFar];
+ if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())
+ {
+ return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
+ }
}
- else
+ return -1;
+ }
+
+ // Return index of the field, or -1 if not found
+ // Same as getFieldIndex, but checks for a direct match with the VarDeclaration
+ int findFieldIndexByName(VarDeclaration v)
+ {
+ ClassDeclaration cd = originalClass();
+ size_t fieldsSoFar = 0;
+ for (size_t j = 0; j < value.elements.length; j++)
{
- s = "";
+ while (j - fieldsSoFar >= cd.fields.length)
+ {
+ fieldsSoFar += cd.fields.length;
+ cd = cd.baseClass;
+ }
+ VarDeclaration v2 = cd.fields[j - fieldsSoFar];
+ if (v == v2)
+ {
+ return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
+ }
}
+ return -1;
+ }
- Expression e = new StringExp(loc, s.toDString());
- e = e.expressionSemantic(sc);
- e.type = Type.tstring;
- return e;
+ override void accept(Visitor v)
+ {
+ v.visit(this);
+ }
+}
+
+/***********************************************************
+ * This type is only used by the interpreter.
+ */
+extern (C++) final class CTFEExp : Expression
+{
+ extern (D) this(EXP tok)
+ {
+ super(Loc.initial, tok);
+ type = Type.tvoid;
+ }
+
+ override const(char)* toChars() const
+ {
+ switch (op)
+ {
+ case EXP.cantExpression:
+ return "<cant>";
+ case EXP.voidExpression:
+ return "cast(void)0";
+ case EXP.showCtfeContext:
+ return "<error>";
+ case EXP.break_:
+ return "<break>";
+ case EXP.continue_:
+ return "<continue>";
+ case EXP.goto_:
+ return "<goto>";
+ default:
+ assert(0);
+ }
+ }
+
+ extern (D) __gshared CTFEExp cantexp;
+ extern (D) __gshared CTFEExp voidexp;
+ extern (D) __gshared CTFEExp breakexp;
+ extern (D) __gshared CTFEExp continueexp;
+ extern (D) __gshared CTFEExp gotoexp;
+ /* Used when additional information is needed regarding
+ * a ctfe error.
+ */
+ extern (D) __gshared CTFEExp showcontext;
+
+ extern (D) static bool isCantExp(const Expression e) @safe
+ {
+ return e && e.op == EXP.cantExpression;
+ }
+
+ extern (D) static bool isGotoExp(const Expression e) @safe
+ {
+ return e && e.op == EXP.goto_;
+ }
+}
+
+/***********************************************************
+ * Fake class which holds the thrown exception.
+ * Used for implementing exception handling.
+ */
+extern (C++) final class ThrownExceptionExp : Expression
+{
+ ClassReferenceExp thrown; // the thing being tossed
+
+ extern (D) this(const ref Loc loc, ClassReferenceExp victim) @safe
+ {
+ super(loc, EXP.thrownException);
+ this.thrown = victim;
+ this.type = victim.type;
+ }
+
+ override const(char)* toChars() const
+ {
+ return "CTFE ThrownException";
}
override void accept(Visitor v)
@@ -6330,154 +5372,6 @@ extern (C++) final class GenericExp : Expression
}
}
-/***************************************
- * Parameters:
- * sc: scope
- * flag: 1: do not issue error message for invalid modification
- 2: the exp is a DotVarExp and a subfield of the leftmost
- variable is modified
- * Returns:
- * Whether the type is modifiable
- */
-extern(D) Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag = ModifyFlags.none)
-{
- switch(exp.op)
- {
- case EXP.variable:
- auto varExp = cast(VarExp)exp;
-
- //printf("VarExp::checkModifiable %s", varExp.toChars());
- assert(varExp.type);
- return varExp.var.checkModify(varExp.loc, sc, null, flag);
-
- case EXP.dotVariable:
- auto dotVarExp = cast(DotVarExp)exp;
-
- //printf("DotVarExp::checkModifiable %s %s\n", dotVarExp.toChars(), dotVarExp.type.toChars());
- if (dotVarExp.e1.op == EXP.this_)
- return dotVarExp.var.checkModify(dotVarExp.loc, sc, dotVarExp.e1, flag);
-
- /* https://issues.dlang.org/show_bug.cgi?id=12764
- * If inside a constructor and an expression of type `this.field.var`
- * is encountered, where `field` is a struct declaration with
- * default construction disabled, we must make sure that
- * assigning to `var` does not imply that `field` was initialized
- */
- if (sc.func && sc.func.isCtorDeclaration())
- {
- // if inside a constructor scope and e1 of this DotVarExp
- // is another DotVarExp, then check if the leftmost expression is a `this` identifier
- if (auto dve = dotVarExp.e1.isDotVarExp())
- {
- // Iterate the chain of DotVarExp to find `this`
- // Keep track whether access to fields was limited to union members
- // s.t. one can initialize an entire struct inside nested unions
- // (but not its members)
- bool onlyUnion = true;
- while (true)
- {
- auto v = dve.var.isVarDeclaration();
- assert(v);
-
- // Accessing union member?
- auto t = v.type.isTypeStruct();
- if (!t || !t.sym.isUnionDeclaration())
- onlyUnion = false;
-
- // Another DotVarExp left?
- if (!dve.e1 || dve.e1.op != EXP.dotVariable)
- break;
-
- dve = cast(DotVarExp) dve.e1;
- }
-
- if (dve.e1.op == EXP.this_)
- {
- scope v = dve.var.isVarDeclaration();
- /* if v is a struct member field with no initializer, no default construction
- * and v wasn't intialized before
- */
- if (v && v.isField() && !v._init && !v.ctorinit)
- {
- if (auto ts = v.type.isTypeStruct())
- {
- if (ts.sym.noDefaultCtor)
- {
- /* checkModify will consider that this is an initialization
- * of v while it is actually an assignment of a field of v
- */
- scope modifyLevel = v.checkModify(dotVarExp.loc, sc, dve.e1, !onlyUnion ? (flag | ModifyFlags.fieldAssign) : flag);
- if (modifyLevel == Modifiable.initialization)
- {
- // https://issues.dlang.org/show_bug.cgi?id=22118
- // v is a union type field that was assigned
- // a variable, therefore it counts as initialization
- if (v.ctorinit)
- return Modifiable.initialization;
-
- return Modifiable.yes;
- }
- return modifyLevel;
- }
- }
- }
- }
- }
- }
-
- //printf("\te1 = %s\n", e1.toChars());
- return dotVarExp.e1.checkModifiable(sc, flag);
-
- case EXP.star:
- auto ptrExp = cast(PtrExp)exp;
- if (auto se = ptrExp.e1.isSymOffExp())
- {
- return se.var.checkModify(ptrExp.loc, sc, null, flag);
- }
- else if (auto ae = ptrExp.e1.isAddrExp())
- {
- return ae.e1.checkModifiable(sc, flag);
- }
- return Modifiable.yes;
-
- case EXP.slice:
- auto sliceExp = cast(SliceExp)exp;
-
- //printf("SliceExp::checkModifiable %s\n", sliceExp.toChars());
- auto e1 = sliceExp.e1;
- if (e1.type.ty == Tsarray || (e1.op == EXP.index && e1.type.ty != Tarray) || e1.op == EXP.slice)
- {
- return e1.checkModifiable(sc, flag);
- }
- return Modifiable.yes;
-
- case EXP.comma:
- return (cast(CommaExp)exp).e2.checkModifiable(sc, flag);
-
- case EXP.index:
- auto indexExp = cast(IndexExp)exp;
- auto e1 = indexExp.e1;
- if (e1.type.ty == Tsarray ||
- e1.type.ty == Taarray ||
- (e1.op == EXP.index && e1.type.ty != Tarray) ||
- e1.op == EXP.slice)
- {
- return e1.checkModifiable(sc, flag);
- }
- return Modifiable.yes;
-
- case EXP.question:
- auto condExp = cast(CondExp)exp;
- if (condExp.e1.checkModifiable(sc, flag) != Modifiable.no
- && condExp.e2.checkModifiable(sc, flag) != Modifiable.no)
- return Modifiable.yes;
- return Modifiable.no;
-
- default:
- return exp.type ? Modifiable.yes : Modifiable.no; // default modifiable
- }
-}
-
/**
* Verify if the given identifier is _d_array{,set}ctor.
*
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index f7f6b0b..b4ace74b 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -50,7 +50,10 @@ struct Symbol; // back end symbol
Expression *ctfeInterpret(Expression *e);
void expandTuples(Expressions *exps, Identifiers *names = nullptr);
StringExp *toUTF8(StringExp *se, Scope *sc);
+Expression *resolveLoc(Expression *exp, const Loc &loc, Scope *sc);
MATCH implicitConvTo(Expression *e, Type *t);
+Expression *toLvalue(Expression *_this, Scope *sc, const char* action);
+Expression *modifiableLvalue(Expression* exp, Scope *sc);
typedef unsigned char OwnedBy;
enum
@@ -99,9 +102,6 @@ public:
virtual complex_t toComplex();
virtual StringExp *toStringExp();
virtual bool isLvalue();
- virtual Expression *toLvalue(Scope *sc, Expression *e);
- virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
- virtual Expression *resolveLoc(const Loc &loc, Scope *sc);
virtual bool checkType();
virtual bool checkValue();
Expression *addressOf();
@@ -244,7 +244,6 @@ public:
real_t toImaginary() override;
complex_t toComplex() override;
Optional<bool> toBool() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
dinteger_t getInteger() { return value; }
template<int v>
@@ -254,7 +253,6 @@ public:
class ErrorExp final : public Expression
{
public:
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
static ErrorExp *errorexp; // handy shared value
@@ -302,7 +300,6 @@ public:
static IdentifierExp *create(const Loc &loc, Identifier *ident);
bool isLvalue() override final;
- Expression *toLvalue(Scope *sc, Expression *e) override final;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -320,7 +317,6 @@ public:
DsymbolExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -331,8 +327,7 @@ public:
ThisExp *syntaxCopy() override;
Optional<bool> toBool() override;
- bool isLvalue() override final;
- Expression *toLvalue(Scope *sc, Expression *e) override final;
+ bool isLvalue() override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -370,8 +365,6 @@ public:
StringExp *toStringExp() override;
Optional<bool> toBool() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
size_t numberOfCodeUnits(int tynto = 0) const;
void writeTo(void* dest, bool zero, int tyto = 0) const;
@@ -469,7 +462,6 @@ public:
static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
bool equals(const RootObject * const o) const override;
StructLiteralExp *syntaxCopy() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -501,7 +493,6 @@ public:
FuncDeclaration *fd;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
bool checkType() override;
bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
@@ -575,8 +566,6 @@ public:
static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
bool equals(const RootObject * const o) const override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -589,7 +578,6 @@ public:
OverloadSet *vars;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -678,7 +666,6 @@ public:
Expression *e1;
UnaExp *syntaxCopy() override;
- Expression *resolveLoc(const Loc &loc, Scope *sc) override final;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -701,8 +688,6 @@ class BinAssignExp : public BinExp
{
public:
bool isLvalue() override final;
- Expression *toLvalue(Scope *sc, Expression *ex) override final;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override final;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -767,8 +752,6 @@ public:
d_bool hasOverloads;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -821,7 +804,6 @@ public:
CallExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -836,8 +818,6 @@ class PtrExp final : public UnaExp
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -882,7 +862,6 @@ public:
CastExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -903,7 +882,6 @@ class VectorArrayExp final : public UnaExp
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -926,8 +904,6 @@ private:
public:
SliceExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
Optional<bool> toBool() override;
void accept(Visitor *v) override { v->visit(this); }
@@ -953,8 +929,6 @@ class DelegatePtrExp final : public UnaExp
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -962,8 +936,6 @@ class DelegateFuncptrExp final : public UnaExp
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -978,7 +950,6 @@ public:
ArrayExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -997,8 +968,6 @@ public:
d_bool isGenerated;
d_bool allowCommaExp;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
Optional<bool> toBool() override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -1012,8 +981,6 @@ public:
IndexExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -1047,7 +1014,6 @@ public:
MemorySet memset;
bool isLvalue() override final;
- Expression *toLvalue(Scope *sc, Expression *ex) override final;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -1148,6 +1114,8 @@ public:
class CatAssignExp : public BinAssignExp
{
public:
+ Expression *lowering; // lowered druntime hook `_d_arrayappend{cTX,T}`
+
void accept(Visitor *v) override { v->visit(this); }
};
@@ -1292,8 +1260,6 @@ public:
CondExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -1320,35 +1286,30 @@ public:
class FileInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class LineInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class ModuleInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class FuncInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class PrettyFuncInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 1ddb2b1..e6b9018 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -87,6 +87,46 @@ import dmd.visitor;
enum LOGSEMANTIC = false;
+/***********************************
+ * Determine if a `this` is needed to access `d`.
+ * Params:
+ * sc = context
+ * d = declaration to check
+ * Returns:
+ * true means a `this` is needed
+ */
+private bool isNeedThisScope(Scope* sc, Declaration d)
+{
+ if (sc.intypeof == 1)
+ return false;
+
+ AggregateDeclaration ad = d.isThis();
+ if (!ad)
+ return false;
+ //printf("d = %s, ad = %s\n", d.toChars(), ad.toChars());
+
+ for (Dsymbol s = sc.parent; s; s = s.toParentLocal())
+ {
+ //printf("\ts = %s %s, toParent2() = %p\n", s.kind(), s.toChars(), s.toParent2());
+ if (AggregateDeclaration ad2 = s.isAggregateDeclaration())
+ {
+ if (ad2 == ad)
+ return false;
+ else if (ad2.isNested())
+ continue;
+ else
+ return true;
+ }
+ if (FuncDeclaration f = s.isFuncDeclaration())
+ {
+ if (f.isMemberLocal())
+ break;
+ }
+ }
+ return true;
+}
+
+
/********************************************************
* Perform semantic analysis and CTFE on expressions to produce
* a string.
@@ -196,6 +236,51 @@ FuncDeclaration hasThis(Scope* sc)
}
+extern (D) bool findTempDecl(DotTemplateInstanceExp exp, Scope* sc)
+{
+ auto ti = exp.ti;
+ auto e1 = exp.e1;
+ static if (LOGSEMANTIC)
+ {
+ printf("DotTemplateInstanceExp::findTempDecl('%s')\n", exp.toChars());
+ }
+ if (ti.tempdecl)
+ return true;
+
+ Expression e = new DotIdExp(exp.loc, e1, ti.name);
+ e = e.expressionSemantic(sc);
+ if (e.op == EXP.dot)
+ e = (cast(DotExp)e).e2;
+
+ Dsymbol s = null;
+ switch (e.op)
+ {
+ case EXP.overloadSet:
+ s = (cast(OverExp)e).vars;
+ break;
+
+ case EXP.dotTemplateDeclaration:
+ s = (cast(DotTemplateExp)e).td;
+ break;
+
+ case EXP.scope_:
+ s = (cast(ScopeExp)e).sds;
+ break;
+
+ case EXP.dotVariable:
+ s = (cast(DotVarExp)e).var;
+ break;
+
+ case EXP.variable:
+ s = (cast(VarExp)e).var;
+ break;
+
+ default:
+ return false;
+ }
+ return ti.updateTempDecl(sc, s);
+}
+
/***********************************************************
* Resolve `exp` as a compile-time known string.
* Params:
@@ -1731,6 +1816,403 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
return false;
}
+/*********************************************
+ * Calling function f.
+ * Check the purity, i.e. if we're in a pure function
+ * we can only call other pure functions.
+ * Returns true if error occurs.
+ */
+private bool checkPurity(FuncDeclaration f, const ref Loc loc, Scope* sc)
+{
+ if (!sc.func)
+ return false;
+ if (sc.func == f)
+ return false;
+ if (sc.intypeof == 1)
+ return false;
+ if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
+ return false;
+
+ // If the call has a pure parent, then the called func must be pure.
+ if (!f.isPure() && checkImpure(sc, loc, null, f))
+ {
+ error(loc, "`pure` %s `%s` cannot call impure %s `%s`",
+ sc.func.kind(), sc.func.toPrettyChars(), f.kind(),
+ f.toPrettyChars());
+
+ if (!f.isDtorDeclaration())
+ errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.pure_);
+
+ f.checkOverriddenDtor(sc, loc, dd => dd.type.toTypeFunction().purity != PURE.impure, "impure");
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Checks whether `f` is a generated `DtorDeclaration` that hides a user-defined one
+ * which passes `check` while `f` doesn't (e.g. when the user defined dtor is pure but
+ * the generated dtor is not).
+ * In that case the method will identify and print all members causing the attribute
+ * missmatch.
+ *
+ * Params:
+ * f = potential `DtorDeclaration`
+ * sc = scope
+ * loc = location
+ * check = current check (e.g. whether it's pure)
+ * checkName = the kind of check (e.g. `"pure"`)
+ */
+void checkOverriddenDtor(FuncDeclaration f, Scope* sc, const ref Loc loc,
+ scope bool function(DtorDeclaration) check, const string checkName)
+{
+ auto dd = f.isDtorDeclaration();
+ if (!dd || !dd.isGenerated())
+ return;
+
+ // DtorDeclaration without parents should fail at an earlier stage
+ auto ad = cast(AggregateDeclaration) f.toParent2();
+ assert(ad);
+
+ if (ad.userDtors.length)
+ {
+ if (!check(ad.userDtors[0])) // doesn't match check (e.g. is impure as well)
+ return;
+
+ // Sanity check
+ assert(!check(ad.fieldDtor));
+ }
+
+ dd.loc.errorSupplemental("%s`%s.~this` is %.*s because of the following field's destructors:",
+ dd.isGenerated() ? "generated " : "".ptr,
+ ad.toChars,
+ cast(int) checkName.length, checkName.ptr);
+
+ // Search for the offending fields
+ foreach (field; ad.fields)
+ {
+ // Only structs may define automatically called destructors
+ auto ts = field.type.isTypeStruct();
+ if (!ts)
+ {
+ // But they might be part of a static array
+ auto ta = field.type.isTypeSArray();
+ if (!ta)
+ continue;
+
+ ts = ta.baseElemOf().isTypeStruct();
+ if (!ts)
+ continue;
+ }
+
+ auto fieldSym = ts.toDsymbol(sc);
+ assert(fieldSym); // Resolving ts must succeed because missing defs. should error before
+
+ auto fieldSd = fieldSym.isStructDeclaration();
+ assert(fieldSd); // ts is a TypeStruct, this would imply a malformed ASR
+
+ if (fieldSd.dtor && !check(fieldSd.dtor))
+ {
+ field.loc.errorSupplemental(" - %s %s", field.type.toChars(), field.toChars());
+
+ if (fieldSd.dtor.isGenerated())
+ fieldSd.dtor.checkOverriddenDtor(sc, loc, check, checkName);
+ else
+ fieldSd.dtor.loc.errorSupplemental(" %.*s `%s.~this` is declared here",
+ cast(int) checkName.length, checkName.ptr, fieldSd.toChars());
+ }
+ }
+}
+
+/*******************************************
+ * Accessing variable v.
+ * Check for purity and safety violations.
+ * Returns true if error occurs.
+ */
+private bool checkPurity(VarDeclaration v, const ref Loc loc, Scope* sc)
+{
+ //printf("v = %s %s\n", v.type.toChars(), v.toChars());
+ /* Look for purity and safety violations when accessing variable v
+ * from current function.
+ */
+ if (!sc.func)
+ return false;
+ if (sc.intypeof == 1)
+ return false; // allow violations inside typeof(expression)
+ if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
+ return false; // allow violations inside compile-time evaluated expressions and debug conditionals
+ if (v.ident == Id.ctfe)
+ return false; // magic variable never violates pure and safe
+ if (v.isImmutable())
+ return false; // always safe and pure to access immutables...
+ if (v.isConst() && !v.isReference() && (v.isDataseg() || v.isParameter()) && v.type.implicitConvTo(v.type.immutableOf()))
+ return false; // or const global/parameter values which have no mutable indirections
+ if (v.storage_class & STC.manifest)
+ return false; // ...or manifest constants
+
+ // accessing empty structs is pure
+ // https://issues.dlang.org/show_bug.cgi?id=18694
+ // https://issues.dlang.org/show_bug.cgi?id=21464
+ // https://issues.dlang.org/show_bug.cgi?id=23589
+ if (v.type.ty == Tstruct)
+ {
+ StructDeclaration sd = (cast(TypeStruct)v.type).sym;
+ if (sd.members) // not opaque
+ {
+ if (sd.semanticRun >= PASS.semanticdone)
+ sd.determineSize(v.loc);
+ if (sd.hasNoFields)
+ return false;
+ }
+ }
+
+ bool err = false;
+ if (v.isDataseg())
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=7533
+ // Accessing implicit generated __gate is pure.
+ if (v.ident == Id.gate)
+ return false;
+
+ if (checkImpure(sc, loc, "`pure` %s `%s` cannot access mutable static data `%s`", v))
+ {
+ error(loc, "`pure` %s `%s` cannot access mutable static data `%s`",
+ sc.func.kind(), sc.func.toPrettyChars(), v.toChars());
+ err = true;
+ }
+ }
+ else
+ {
+ /* Given:
+ * void f() {
+ * int fx;
+ * pure void g() {
+ * int gx;
+ * /+pure+/ void h() {
+ * int hx;
+ * /+pure+/ void i() { }
+ * }
+ * }
+ * }
+ * i() can modify hx and gx but not fx
+ */
+
+ Dsymbol vparent = v.toParent2();
+ for (Dsymbol s = sc.func; !err && s; s = s.toParentP(vparent))
+ {
+ if (s == vparent)
+ break;
+
+ if (AggregateDeclaration ad = s.isAggregateDeclaration())
+ {
+ if (ad.isNested())
+ continue;
+ break;
+ }
+ FuncDeclaration ff = s.isFuncDeclaration();
+ if (!ff)
+ break;
+ if (ff.isNested() || ff.isThis())
+ {
+ if (ff.type.isImmutable() ||
+ ff.type.isShared() && !MODimplicitConv(ff.type.mod, v.type.mod))
+ {
+ OutBuffer ffbuf;
+ OutBuffer vbuf;
+ MODMatchToBuffer(&ffbuf, ff.type.mod, v.type.mod);
+ MODMatchToBuffer(&vbuf, v.type.mod, ff.type.mod);
+ error(loc, "%s%s `%s` cannot access %sdata `%s`",
+ ffbuf.peekChars(), ff.kind(), ff.toPrettyChars(), vbuf.peekChars(), v.toChars());
+ err = true;
+ break;
+ }
+ continue;
+ }
+ break;
+ }
+ }
+
+ /* Do not allow safe functions to access __gshared data
+ */
+ if (v.storage_class & STC.gshared)
+ {
+ if (sc.setUnsafe(false, loc,
+ "`@safe` function `%s` cannot access `__gshared` data `%s`", sc.func, v))
+ {
+ err = true;
+ }
+ }
+
+ return err;
+}
+
+/*
+Check if sc.func is impure or can be made impure.
+Returns true on error, i.e. if sc.func is pure and cannot be made impure.
+*/
+private bool checkImpure(Scope* sc, Loc loc, const(char)* fmt, RootObject arg0)
+{
+ return sc.func && (isRootTraitsCompilesScope(sc)
+ ? sc.func.isPureBypassingInference() >= PURE.weak
+ : sc.func.setImpure(loc, fmt, arg0));
+}
+
+/*********************************************
+ * Calling function f.
+ * Check the safety, i.e. if we're in a @safe function
+ * we can only call @safe or @trusted functions.
+ * Returns true if error occurs.
+ */
+private bool checkSafety(FuncDeclaration f, ref Loc loc, Scope* sc)
+{
+ if (sc.func == f)
+ return false;
+ if (sc.intypeof == 1)
+ return false;
+ if (sc.flags & SCOPE.debug_)
+ return false;
+ if ((sc.flags & SCOPE.ctfe) && sc.func)
+ return false;
+
+ if (!sc.func)
+ {
+ if (sc.varDecl && !f.safetyInprocess && !f.isSafe() && !f.isTrusted())
+ {
+ if (sc.varDecl.storage_class & STC.safe)
+ {
+ error(loc, "`@safe` variable `%s` cannot be initialized by calling `@system` function `%s`",
+ sc.varDecl.toChars(), f.toChars());
+ return true;
+ }
+ else
+ {
+ sc.varDecl.storage_class |= STC.system;
+ sc.varDecl.systemInferred = true;
+ }
+ }
+ return false;
+ }
+
+ if (!f.isSafe() && !f.isTrusted())
+ {
+ if (isRootTraitsCompilesScope(sc) ? sc.func.isSafeBypassingInference() : sc.func.setUnsafeCall(f))
+ {
+ if (!loc.isValid()) // e.g. implicitly generated dtor
+ loc = sc.func.loc;
+
+ const prettyChars = f.toPrettyChars();
+ error(loc, "`@safe` %s `%s` cannot call `@system` %s `%s`",
+ sc.func.kind(), sc.func.toPrettyChars(), f.kind(),
+ prettyChars);
+ if (!f.isDtorDeclaration)
+ errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.safe);
+ .errorSupplemental(f.loc, "`%s` is declared here", prettyChars);
+
+ f.checkOverriddenDtor(sc, loc, dd => dd.type.toTypeFunction().trust > TRUST.system, "@system");
+
+ return true;
+ }
+ }
+ else if (f.isSafe() && f.safetyViolation)
+ {
+ // for dip1000 by default transition, print deprecations for calling functions that will become `@system`
+ if (sc.func.isSafeBypassingInference())
+ {
+ .deprecation(loc, "`@safe` function `%s` calling `%s`", sc.func.toChars(), f.toChars());
+ errorSupplementalInferredAttr(f, 10, true, STC.safe);
+ }
+ else if (!sc.func.safetyViolation)
+ {
+ import dmd.func : AttributeViolation;
+ sc.func.safetyViolation = new AttributeViolation(loc, null, f, null, null);
+ }
+ }
+ return false;
+}
+
+/*********************************************
+ * Calling function f.
+ * Check the @nogc-ness, i.e. if we're in a @nogc function
+ * we can only call other @nogc functions.
+ * Returns true if error occurs.
+ */
+private bool checkNogc(FuncDeclaration f, ref Loc loc, Scope* sc)
+{
+ if (!sc.func)
+ return false;
+ if (sc.func == f)
+ return false;
+ if (sc.intypeof == 1)
+ return false;
+ if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
+ return false;
+ /* The original expressions (`new S(...)` or `new S[...]``) will be
+ * verified instead. This is to keep errors related to the original code
+ * and not the lowering.
+ */
+ if (f.ident == Id._d_newitemT || f.ident == Id._d_newarrayT || f.ident == Id._d_newarraymTX)
+ return false;
+
+ if (!f.isNogc())
+ {
+ if (isRootTraitsCompilesScope(sc) ? sc.func.isNogcBypassingInference() : sc.func.setGCCall(f))
+ {
+ if (loc.linnum == 0) // e.g. implicitly generated dtor
+ loc = sc.func.loc;
+
+ // Lowered non-@nogc'd hooks will print their own error message inside of nogc.d (NOGCVisitor.visit(CallExp e)),
+ // so don't print anything to avoid double error messages.
+ if (!(f.ident == Id._d_HookTraceImpl || f.ident == Id._d_arraysetlengthT
+ || f.ident == Id._d_arrayappendT || f.ident == Id._d_arrayappendcTX
+ || f.ident == Id._d_arraycatnTX || f.ident == Id._d_newclassT))
+ {
+ error(loc, "`@nogc` %s `%s` cannot call non-@nogc %s `%s`",
+ sc.func.kind(), sc.func.toPrettyChars(), f.kind(), f.toPrettyChars());
+
+ if (!f.isDtorDeclaration)
+ f.errorSupplementalInferredAttr(/*max depth*/ 10, /*deprecation*/ false, STC.nogc);
+ }
+
+ f.checkOverriddenDtor(sc, loc, dd => dd.type.toTypeFunction().isnogc, "non-@nogc");
+
+ return true;
+ }
+ }
+ return false;
+}
+
+/********************************************
+ * Check that the postblit is callable if t is an array of structs.
+ * Returns true if error happens.
+ */
+private bool checkPostblit(Type t, ref Loc loc, Scope* sc)
+{
+ if (auto ts = t.baseElemOf().isTypeStruct())
+ {
+ if (global.params.useTypeInfo && Type.dtypeinfo)
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=11395
+ // Require TypeInfo generation for array concatenation
+ semanticTypeInfo(sc, t);
+ }
+
+ StructDeclaration sd = ts.sym;
+ if (sd.postblit)
+ {
+ if (sd.postblit.checkDisabled(loc, sc))
+ return true;
+
+ //checkDeprecated(sc, sd.postblit); // necessary?
+ sd.postblit.checkPurity(loc, sc);
+ sd.postblit.checkSafety(loc, sc);
+ sd.postblit.checkNogc(loc, sc);
+ //checkAccess(sd, loc, sc, sd.postblit); // necessary?
+ return false;
+ }
+ }
+ return false;
+}
+
/***************************************
* Pull out any properties.
*/
@@ -1942,7 +2424,7 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
{
if (auto v = ve.var.isVarDeclaration())
{
- if (ve.checkPurity(sc, v))
+ if (v.checkPurity(ve.loc, sc))
return ErrorExp.get();
}
}
@@ -2647,7 +3129,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
ev = new CommaExp(arg.loc, ev, new VarExp(arg.loc, v));
arg = ev.expressionSemantic(sc);
}
- arg = arg.toLvalue(sc, arg);
+ arg = arg.toLvalue(sc, "create `in` parameter from");
// Look for mutable misaligned pointer, etc., in @safe mode
err |= checkUnsafeAccess(sc, arg, false, true);
@@ -2665,7 +3147,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
ev = new CommaExp(arg.loc, ev, new VarExp(arg.loc, v));
arg = ev.expressionSemantic(sc);
}
- arg = arg.toLvalue(sc, arg);
+ arg = arg.toLvalue(sc, "create `ref` parameter from");
// Look for mutable misaligned pointer, etc., in @safe mode
err |= checkUnsafeAccess(sc, arg, false, true);
@@ -2684,7 +3166,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
err |= checkUnsafeAccess(sc, arg, false, true);
err |= checkDefCtor(arg.loc, t); // t must be default constructible
}
- arg = arg.toLvalue(sc, arg);
+ arg = arg.toLvalue(sc, "create `out` parameter from");
}
else if (p.isLazy())
{
@@ -2727,7 +3209,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
const explicitScope = p.isLazy() ||
((p.storageClass & STC.scope_) && !(p.storageClass & STC.scopeinferred));
if ((pStc & (STC.scope_ | STC.lazy_)) &&
- ((global.params.useDIP1000 == FeatureState.enabled) || explicitScope) &&
+ ((sc.useDIP1000 == FeatureState.enabled) || explicitScope) &&
!(pStc & STC.return_))
{
/* Argument value cannot escape from the called function.
@@ -4633,23 +5115,23 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
tb = tb.isTypeDArray().next.toBasetype();
}
- if (nargs == 1)
- {
- if (global.params.betterC || !sc.needsCodegen())
+ if (global.params.betterC || !sc.needsCodegen())
goto LskipNewArrayLowering;
- /* Class types may inherit base classes that have errors.
- * This may leak errors from the base class to the derived one
- * and then to the hook. Semantic analysis is performed eagerly
- * to a void this.
- */
- if (auto tc = exp.type.nextOf.isTypeClass())
- {
- tc.sym.dsymbolSemantic(sc);
- if (tc.sym.errors)
- goto LskipNewArrayLowering;
- }
+ /* Class types may inherit base classes that have errors.
+ * This may leak errors from the base class to the derived one
+ * and then to the hook. Semantic analysis is performed eagerly
+ * to a void this.
+ */
+ if (auto tc = exp.type.nextOf.isTypeClass())
+ {
+ tc.sym.dsymbolSemantic(sc);
+ if (tc.sym.errors)
+ goto LskipNewArrayLowering;
+ }
+ if (nargs == 1)
+ {
auto hook = global.params.tracegc ? Id._d_newarrayTTrace : Id._d_newarrayT;
if (!verifyHookExist(exp.loc, *sc, hook, "new array"))
goto LskipNewArrayLowering;
@@ -4684,6 +5166,45 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
lowering = new CallExp(exp.loc, lowering, arguments);
exp.lowering = lowering.expressionSemantic(sc);
}
+ else
+ {
+ auto hook = global.params.tracegc ? Id._d_newarraymTXTrace : Id._d_newarraymTX;
+ if (!verifyHookExist(exp.loc, *sc, hook, "new multi-dimensional array"))
+ goto LskipNewArrayLowering;
+
+ /* Lower the memory allocation and initialization of `new T[][]...[](n1, n2, ...)`
+ * to `_d_newarraymTX!(T[][]...[], T)([n1, n2, ...])`.
+ */
+ Expression lowering = new IdentifierExp(exp.loc, Id.empty);
+ lowering = new DotIdExp(exp.loc, lowering, Id.object);
+
+ auto tbn = exp.type.nextOf();
+ while (tbn.ty == Tarray)
+ tbn = tbn.nextOf();
+ auto unqualTbn = tbn.unqualify(MODFlags.wild | MODFlags.const_ |
+ MODFlags.immutable_ | MODFlags.shared_);
+
+ auto tiargs = new Objects();
+ tiargs.push(exp.type);
+ tiargs.push(unqualTbn);
+ lowering = new DotTemplateInstanceExp(exp.loc, lowering, hook, tiargs);
+
+ auto arguments = new Expressions();
+ if (global.params.tracegc)
+ {
+ auto funcname = (sc.callsc && sc.callsc.func) ?
+ sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
+ arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
+ arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
+ arguments.push(new StringExp(exp.loc, funcname.toDString()));
+ }
+
+ arguments.push(new ArrayLiteralExp(exp.loc, Type.tsize_t.sarrayOf(nargs), exp.arguments));
+ arguments.push(new IntegerExp(exp.loc, tbn.isShared(), Type.tbool));
+
+ lowering = new CallExp(exp.loc, lowering, arguments);
+ exp.lowering = lowering.expressionSemantic(sc);
+ }
}
else if (tb.isscalar())
{
@@ -4852,6 +5373,52 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = e;
}
+ private void genIdent(FuncExp exp, Scope* sc)
+ {
+ if (exp.fd.ident == Id.empty)
+ {
+ const(char)[] s;
+ if (exp.fd.fes)
+ s = "__foreachbody";
+ else if (exp.fd.tok == TOK.reserved)
+ s = "__lambda";
+ else if (exp.fd.tok == TOK.delegate_)
+ s = "__dgliteral";
+ else
+ s = "__funcliteral";
+
+ DsymbolTable symtab;
+ if (FuncDeclaration func = sc.parent.isFuncDeclaration())
+ {
+ if (func.localsymtab is null)
+ {
+ // Inside template constraint, symtab is not set yet.
+ // Initialize it lazily.
+ func.localsymtab = new DsymbolTable();
+ }
+ symtab = func.localsymtab;
+ }
+ else
+ {
+ ScopeDsymbol sds = sc.parent.isScopeDsymbol();
+ if (!sds.symtab)
+ {
+ // Inside template constraint, symtab may not be set yet.
+ // Initialize it lazily.
+ assert(sds.isTemplateInstance());
+ sds.symtab = new DsymbolTable();
+ }
+ symtab = sds.symtab;
+ }
+ assert(symtab);
+ Identifier id = Identifier.generateId(s, symtab.length() + 1);
+ exp.fd.ident = id;
+ if (exp.td)
+ exp.td.ident = id;
+ symtab.insert(exp.td ? cast(Dsymbol)exp.td : cast(Dsymbol)exp.fd);
+ }
+ }
+
override void visit(FuncExp exp)
{
static if (LOGSEMANTIC)
@@ -4882,7 +5449,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
//if (fd.treq)
// fd.treq = fd.treq.dsymbolSemantic(loc, sc);
- exp.genIdent(sc);
+ genIdent(exp, sc);
// Set target of return type inference
if (exp.fd.treq && !exp.fd.type.nextOf())
@@ -4995,7 +5562,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return checkarg;
}
- exp.genIdent(sc);
+ genIdent(exp, sc);
assert(exp.td.parameters && exp.td.parameters.length);
exp.td.dsymbolSemantic(sc);
@@ -5257,7 +5824,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
ve.type = t.typeSemantic(exp.loc, sc);
}
VarDeclaration v = ve.var.isVarDeclaration();
- if (v && ve.checkPurity(sc, v))
+ if (v && v.checkPurity(ve.loc, sc))
return setError();
}
@@ -5885,9 +6452,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Purity and safety check should run after testing arguments matching
if (exp.f)
{
- exp.checkPurity(sc, exp.f);
- exp.checkSafety(sc, exp.f);
- exp.checkNogc(sc, exp.f);
+ exp.f.checkPurity(exp.loc, sc);
+ exp.f.checkSafety(exp.loc, sc);
+ exp.f.checkNogc(exp.loc, sc);
if (exp.f.checkNestedReference(sc, exp.loc))
return setError();
}
@@ -6795,7 +7362,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
exp.e1 = exp.e1.expressionSemantic(sc);
- exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
+ exp.e1 = exp.e1.modifiableLvalue(sc);
exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true);
exp.type = exp.e1.type;
@@ -6873,7 +7440,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
uint errors = global.errors;
const len = buf.length;
const str = buf.extractChars()[0 .. len];
- const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput;
+ const bool doUnittests = global.params.parsingUnittestsRequired();
auto loc = adjustLocForMixin(str, exp.loc, global.params.mixinOut);
scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests);
p.transitionIn = global.params.v.vin;
@@ -7767,7 +8334,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
else
{
// `toLvalue` call further below is upon exp.e1, omitting & from the error message
- exp.toLvalue(sc, null);
+ exp.toLvalue(sc, "take address of");
return setError();
}
}
@@ -7857,7 +8424,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
}
- exp.e1 = exp.e1.toLvalue(sc, null);
+ exp.e1 = exp.e1.toLvalue(sc, "take address of");
if (exp.e1.op == EXP.error)
{
result = exp.e1;
@@ -7934,7 +8501,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!checkAddressVar(sc, exp.e1, v))
return setError();
- ve.checkPurity(sc, v);
+ v.checkPurity(ve.loc, sc);
}
FuncDeclaration f = ve.var.isFuncDeclaration();
if (f)
@@ -8006,7 +8573,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
*/
if (VarDeclaration v = expToVariable(exp.e1))
{
- exp.e1.checkPurity(sc, v);
+ v.checkPurity(exp.e1.loc, sc);
}
}
else if (wasCond)
@@ -8275,7 +8842,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
exp.e1 = resolveProperties(sc, exp.e1);
- exp.e1 = exp.e1.modifiableLvalue(sc, null);
+ exp.e1 = exp.e1.modifiableLvalue(sc);
if (exp.e1.op == EXP.error)
{
result = exp.e1;
@@ -8306,9 +8873,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (cd.dtor)
{
err |= !cd.dtor.functionSemantic();
- err |= exp.checkPurity(sc, cd.dtor);
- err |= exp.checkSafety(sc, cd.dtor);
- err |= exp.checkNogc(sc, cd.dtor);
+ err |= cd.dtor.checkPurity(exp.loc, sc);
+ err |= cd.dtor.checkSafety(exp.loc, sc);
+ err |= cd.dtor.checkNogc(exp.loc, sc);
}
if (err)
return setError();
@@ -8489,14 +9056,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- // Look for casting to a vector type
- if (tob.ty == Tvector && t1b.ty != Tvector)
- {
- result = new VectorExp(exp.loc, exp.e1, exp.to);
- result = result.expressionSemantic(sc);
- return;
- }
-
Expression ex = exp.e1.castTo(sc, exp.to);
if (ex.op == EXP.error)
{
@@ -9491,7 +10050,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
- exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
+ exp.e1 = exp.e1.modifiableLvalue(sc);
exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true);
e = exp;
@@ -10253,7 +10812,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Expression ex;
ex = new IndexExp(exp.loc, ea, ek);
ex = ex.expressionSemantic(sc);
- ex = ex.modifiableLvalue(sc, ex); // allocate new slot
+ ex = ex.modifiableLvalue(sc); // allocate new slot
ex = ex.optimize(WANTvalue);
ey = new ConstructExp(exp.loc, ex, ey);
@@ -10344,7 +10903,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (exp.op != EXP.blit && (e2x.op == EXP.slice && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op == EXP.cast_ && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op != EXP.slice && e2x.isLvalue()))
{
- if (e1x.checkPostblit(sc, t1))
+ if (t1.checkPostblit(e1x.loc, sc))
return setError();
}
@@ -10446,7 +11005,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
// e1 is not an lvalue, but we let code generator handle it
- auto ale1x = ale.e1.modifiableLvalue(sc, exp.e1);
+ auto ale1x = ale.e1.modifiableLvalueImpl(sc, exp.e1);
if (ale1x.op == EXP.error)
return setResult(ale1x);
ale.e1 = ale1x;
@@ -10532,7 +11091,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
se = cast(SliceExp)se.e1;
if (se.e1.op == EXP.question && se.e1.type.toBasetype().ty == Tsarray)
{
- se.e1 = se.e1.modifiableLvalue(sc, exp.e1);
+ se.e1 = se.e1.modifiableLvalueImpl(sc, exp.e1);
if (se.e1.op == EXP.error)
return setResult(se.e1);
}
@@ -10556,7 +11115,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Try to do a decent error message with the expression
// before it gets constant folded
if (exp.op == EXP.assign)
- e1x = e1x.modifiableLvalue(sc, e1old);
+ e1x = e1x.modifiableLvalueImpl(sc, e1old);
e1x = e1x.optimize(WANTvalue, /*keepLvalue*/ true);
@@ -10587,7 +11146,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// '= null' is the only allowable block assignment (Bug 7493)
exp.memset = MemorySet.blockAssign; // make it easy for back end to tell what this is
e2x = e2x.implicitCastTo(sc, t1.nextOf());
- if (exp.op != EXP.blit && e2x.isLvalue() && exp.e1.checkPostblit(sc, t1.nextOf()))
+ if (exp.op != EXP.blit && e2x.isLvalue() && t1.nextOf.checkPostblit(exp.e1.loc, sc))
return setError();
}
else if (exp.e1.op == EXP.slice &&
@@ -10625,7 +11184,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
e2x.op == EXP.cast_ && (cast(UnaExp)e2x).e1.isLvalue() ||
e2x.op != EXP.slice && e2x.isLvalue()))
{
- if (exp.e1.checkPostblit(sc, t1.nextOf()))
+ if (t1.nextOf().checkPostblit(exp.e1.loc, sc))
return setError();
}
@@ -11004,7 +11563,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
+ exp.e1 = exp.e1.modifiableLvalue(sc);
}
if ((exp.e1.type.isintegral() || exp.e1.type.isfloating()) && (exp.e2.type.isintegral() || exp.e2.type.isfloating()))
@@ -11063,7 +11622,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
}
- exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
+ exp.e1 = exp.e1.modifiableLvalue(sc);
if (exp.e1.op == EXP.error)
{
result = exp.e1;
@@ -11095,7 +11654,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
// EXP.concatenateAssign
assert(exp.op == EXP.concatenateAssign);
- if (exp.e1.checkPostblit(sc, tb1next))
+ if (tb1next.checkPostblit(exp.e1.loc, sc))
return setError();
exp.e2 = exp.e2.castTo(sc, exp.e1.type);
@@ -11113,7 +11672,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (tb2.ty == Tclass && (cast(TypeClass)tb2).implicitConvToThroughAliasThis(tb1next))
goto Laliasthis;
// Append element
- if (exp.e2.checkPostblit(sc, tb2))
+ if (tb2.checkPostblit(exp.e2.loc, sc))
return setError();
if (checkNewEscape(sc, exp.e2, false))
@@ -11199,8 +11758,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = res;
- if ((exp.op == EXP.concatenateAssign || exp.op == EXP.concatenateElemAssign) &&
- sc.needsCodegen())
+ if ((exp.op == EXP.concatenateAssign || exp.op == EXP.concatenateElemAssign) && sc.needsCodegen())
{
// if aa ordering is triggered, `res` will be a CommaExp
// and `.e2` will be the rewritten original expression.
@@ -11244,7 +11802,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
arguments.push(exp.e1);
arguments.push(exp.e2);
Expression ce = new CallExp(exp.loc, id, arguments);
- *output = ce.expressionSemantic(sc);
+
+ exp.lowering = ce.expressionSemantic(sc);
+ *output = exp;
}
else if (exp.op == EXP.concatenateElemAssign)
{
@@ -11264,15 +11824,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
Identifier hook = global.params.tracegc ? Id._d_arrayappendcTXTrace : Id._d_arrayappendcTX;
- if (!verifyHookExist(exp.loc, *sc, Id._d_arrayappendcTXImpl, "appending element to arrays", Id.object))
+ if (!verifyHookExist(exp.loc, *sc, hook, "appending element to arrays", Id.object))
return setError();
- // Lower to object._d_arrayappendcTXImpl!(typeof(e1))._d_arrayappendcTX{,Trace}(e1, 1), e1[$-1]=e2
+ // Lower to object._d_arrayappendcTX{,Trace}(e1, 1), e1[$-1]=e2
Expression id = new IdentifierExp(exp.loc, Id.empty);
id = new DotIdExp(exp.loc, id, Id.object);
- auto tiargs = new Objects();
- tiargs.push(exp.e1.type);
- id = new DotTemplateInstanceExp(exp.loc, id, Id._d_arrayappendcTXImpl, tiargs);
id = new DotIdExp(exp.loc, id, hook);
auto arguments = new Expressions();
@@ -11299,11 +11856,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
/* Before the template hook, this check was performed in e2ir.d
* for expressions like `a ~= a[$-1]`. Here, $ will be modified
- * by calling `_d_arrayappendcT`, so we need to save `a[$-1]` in
+ * by calling `_d_arrayappendcTX`, so we need to save `a[$-1]` in
* a temporary variable.
*/
value2 = extractSideEffect(sc, "__appendtmp", eValue2, value2, true);
- exp.e2 = value2;
// `__appendtmp*` will be destroyed together with the array `exp.e1`.
auto vd = eValue2.isDeclarationExp().declaration.isVarDeclaration();
@@ -11319,13 +11875,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
auto e0 = Expression.combine(ce, ae).expressionSemantic(sc);
e0 = Expression.combine(e0, value1);
e0 = Expression.combine(eValue1, e0);
-
e0 = Expression.combine(eValue2, e0);
- *output = e0.expressionSemantic(sc);
+ exp.lowering = e0.expressionSemantic(sc);
+ *output = exp;
}
}
-
}
override void visit(AddExp exp)
@@ -11746,7 +12301,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- if (exp.e2.checkPostblit(sc, tb2))
+ if (tb2.checkPostblit(exp.e2.loc, sc))
return setError();
// Postblit call will be done in runtime helper function
}
@@ -11781,7 +12336,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- if (exp.e1.checkPostblit(sc, tb1))
+ if (tb1.checkPostblit(exp.e1.loc, sc))
return setError();
}
@@ -11836,7 +12391,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (Type tbn = tb.nextOf())
{
- if (exp.checkPostblit(sc, tbn))
+ if (tbn.checkPostblit(exp.loc, sc))
return setError();
}
Type t1 = exp.e1.type.toBasetype();
@@ -13582,6 +14137,14 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
return exp;
}
+private bool checkDisabled(Dsymbol s, ref Loc loc, Scope* sc)
+{
+ if (auto d = s.isDeclaration())
+ return d.checkDisabled(loc, sc);
+
+ return false;
+}
+
/******************************
* Resolve properties, i.e. `e1.ident`, without seeing UFCS.
* Params:
@@ -13675,8 +14238,8 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)
// if 's' is a tuple variable, the tuple is returned.
s = s.toAlias();
- exp.checkDeprecated(sc, s);
- exp.checkDisabled(sc, s);
+ s.checkDeprecated(exp.loc, sc);
+ s.checkDisabled(exp.loc, sc);
if (auto em = s.isEnumMember())
{
@@ -14466,6 +15029,106 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
return check(e, returnRef);
}
+/****************************************
+ * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, __FILE_FULL_PATH__ to loc.
+ */
+Expression resolveLoc(Expression exp, const ref Loc loc, Scope* sc)
+{
+ Expression visit(Expression exp)
+ {
+ if (auto unaExp = exp.isUnaExp())
+ {
+ unaExp.e1 = unaExp.e1.resolveLoc(loc, sc);
+ return unaExp;
+ }
+ exp.loc = loc;
+ return exp;
+ }
+
+ Expression visitCat(CatExp exp)
+ {
+ exp.e1 = exp.e1.resolveLoc(loc, sc);
+ exp.e2 = exp.e2.resolveLoc(loc, sc);
+ return exp;
+ }
+
+ Expression visitFileInit(FileInitExp exp)
+ {
+ //printf("FileInitExp::resolve() %s\n", exp.toChars());
+ const(char)* s;
+ if (exp.op == EXP.fileFullPath)
+ s = FileName.toAbsolute(loc.isValid() ? loc.filename : sc._module.srcfile.toChars());
+ else
+ s = loc.isValid() ? loc.filename : sc._module.ident.toChars();
+
+ Expression e = new StringExp(loc, s.toDString());
+ return e.expressionSemantic(sc);
+ }
+
+ Expression visitLineInit(LineInitExp _)
+ {
+ Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);
+ return e.expressionSemantic(sc);
+ }
+
+ Expression visitModuleInit(ModuleInitExp _)
+ {
+ const auto s = (sc.callsc ? sc.callsc : sc)._module.toPrettyChars().toDString();
+ Expression e = new StringExp(loc, s);
+ return e.expressionSemantic(sc);
+ }
+
+ Expression visitFuncInit(FuncInitExp _)
+ {
+ const(char)* s;
+ if (sc.callsc && sc.callsc.func)
+ s = sc.callsc.func.Dsymbol.toPrettyChars();
+ else if (sc.func)
+ s = sc.func.Dsymbol.toPrettyChars();
+ else
+ s = "";
+ Expression e = new StringExp(loc, s.toDString());
+ return e.expressionSemantic(sc);
+ }
+
+ Expression visitPrettyFunc(PrettyFuncInitExp _)
+ {
+ FuncDeclaration fd = (sc.callsc && sc.callsc.func)
+ ? sc.callsc.func
+ : sc.func;
+
+ const(char)* s;
+ if (fd)
+ {
+ const funcStr = fd.Dsymbol.toPrettyChars();
+ OutBuffer buf;
+ functionToBufferWithIdent(fd.type.isTypeFunction(), buf, funcStr, fd.isStatic);
+ s = buf.extractChars();
+ }
+ else
+ {
+ s = "";
+ }
+
+ Expression e = new StringExp(loc, s.toDString());
+ e = e.expressionSemantic(sc);
+ e.type = Type.tstring;
+ return e;
+ }
+
+ switch(exp.op)
+ {
+ default: return visit(exp);
+ case EXP.concatenate: return visitCat(exp.isCatExp());
+ case EXP.file:
+ case EXP.fileFullPath: return visitFileInit(exp.isFileInitExp());
+ case EXP.line: return visitLineInit(exp.isLineInitExp);
+ case EXP.moduleString: return visitModuleInit(exp.isModuleInitExp());
+ case EXP.functionString: return visitFuncInit(exp.isFuncInitExp());
+ case EXP.prettyFunction: return visitPrettyFunc(exp.isPrettyFuncInitExp());
+ }
+}
+
/************************************************
* Destructors are attached to VarDeclarations.
* Hence, if expression returns a temp that needs a destructor,
@@ -14567,6 +15230,593 @@ Expression addDtorHook(Expression e, Scope* sc)
}
}
+/*******************************
+ * Try to convert an expression to be an lvalue.
+ *
+ * Give error if we're not an lvalue.
+ * Params:
+ * _this = expression to convert
+ * sc = scope
+ * action = for error messages, what the lvalue is needed for (e.g. take address of for `&x`, modify for `x++`)
+ * Returns: converted expression, or `ErrorExp` on error
+*/
+extern(C++) Expression toLvalue(Expression _this, Scope* sc, const(char)* action)
+{
+ return toLvalueImpl(_this, sc, action, _this);
+}
+
+// e = original un-lowered expression for error messages, in case of recursive calls
+private Expression toLvalueImpl(Expression _this, Scope* sc, const(char)* action, Expression e)
+{
+ if (!action)
+ action = "create lvalue of";
+
+ assert(e);
+ Expression visit(Expression _this)
+ {
+ // BinaryAssignExp does not have an EXP associated
+ // so it's treated on the default path.
+ // Lvalue-ness will be handled in glue :layer.
+ if (_this.isBinAssignExp())
+ return _this;
+ if (!_this.loc.isValid())
+ _this.loc = e.loc;
+
+ if (e.op == EXP.type)
+ error(_this.loc, "cannot %s type `%s`", action, e.type.toChars());
+ else if (e.op == EXP.template_)
+ error(_this.loc, "cannot %s template `%s`, perhaps instantiate it first", action, e.toChars());
+ else
+ error(_this.loc, "cannot %s expression `%s` because it is not an lvalue", action, e.toChars());
+
+ return ErrorExp.get();
+ }
+
+ Expression visitInteger(IntegerExp _this)
+ {
+ if (!_this.loc.isValid())
+ _this.loc = e.loc;
+ error(e.loc, "cannot %s constant `%s`", action, e.toChars());
+ return ErrorExp.get();
+ }
+
+ Expression visitThis(ThisExp _this)
+ {
+ if (_this.type.toBasetype().ty == Tclass)
+ {
+ // Class `this` is an rvalue; struct `this` is an lvalue.
+ return visit(_this);
+ }
+
+ return _this;
+ }
+
+ Expression visitString(StringExp _this)
+ {
+ //printf("StringExp::toLvalue(%s) type = %s\n", _this.toChars(), _this.type ? _this.type.toChars() : NULL);
+ return (_this.type && _this.type.toBasetype().ty == Tsarray) ? _this : visit(_this);
+ }
+
+ Expression visitStructLiteral(StructLiteralExp _this)
+ {
+ if (sc.flags & SCOPE.Cfile)
+ return _this; // C struct literals are lvalues
+ else
+ return visit(_this);
+ }
+
+ Expression visitTemplate(TemplateExp _this)
+ {
+ if (!_this.fd)
+ return visit(_this);
+
+ assert(sc);
+ return symbolToExp(_this.fd, _this.loc, sc, true);
+
+ }
+
+ Expression visitVar(VarExp _this)
+ {
+ auto var = _this.var;
+ if (var.storage_class & STC.manifest)
+ {
+ error(_this.loc, "cannot %s manifest constant `%s`", action, var.toChars());
+ return ErrorExp.get();
+ }
+ if (var.storage_class & STC.lazy_ && !_this.delegateWasExtracted)
+ {
+ error(_this.loc, "cannot %s lazy variable `%s`", action, var.toChars());
+ return ErrorExp.get();
+ }
+ if (var.ident == Id.ctfe)
+ {
+ error(_this.loc, "cannot %s compiler-generated variable `__ctfe`", action);
+ return ErrorExp.get();
+ }
+ if (var.ident == Id.dollar) // https://issues.dlang.org/show_bug.cgi?id=13574
+ {
+ error(_this.loc, "cannot %s operator `$`", action);
+ return ErrorExp.get();
+ }
+ return _this;
+ }
+
+ Expression visitDotVar(DotVarExp _this)
+ {
+ auto e1 = _this.e1;
+ auto var = _this.var;
+ //printf("DotVarExp::toLvalue(%s)\n", toChars());
+ if (sc && sc.flags & SCOPE.Cfile)
+ {
+ /* C11 6.5.2.3-3: A postfix expression followed by the '.' or '->' operator
+ * is an lvalue if the first expression is an lvalue.
+ */
+ if (!e1.isLvalue())
+ return visit(_this);
+ }
+ if (!_this.isLvalue())
+ return visit(_this);
+ if (e1.op == EXP.this_ && sc.ctorflow.fieldinit.length && !(sc.ctorflow.callSuper & CSX.any_ctor))
+ {
+ if (VarDeclaration vd = var.isVarDeclaration())
+ {
+ auto ad = vd.isMember2();
+ if (ad && ad.fields.length == sc.ctorflow.fieldinit.length)
+ {
+ foreach (i, f; ad.fields)
+ {
+ if (f == vd)
+ {
+ if (!(sc.ctorflow.fieldinit[i].csx & CSX.this_ctor))
+ {
+ /* If the address of vd is taken, assume it is thereby initialized
+ * https://issues.dlang.org/show_bug.cgi?id=15869
+ */
+ modifyFieldVar(_this.loc, sc, vd, e1);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ return _this;
+ }
+
+ Expression visitCall(CallExp _this)
+ {
+ if (_this.isLvalue())
+ return _this;
+ return visit(_this);
+ }
+
+ Expression visitCast(CastExp _this)
+ {
+ if (sc && sc.flags & SCOPE.Cfile)
+ {
+ /* C11 6.5.4-5: A cast does not yield an lvalue.
+ */
+ return visit(_this);
+ }
+ if (_this.isLvalue())
+ return _this;
+ return visit(_this);
+ }
+
+ Expression visitVectorArray(VectorArrayExp _this)
+ {
+ _this.e1 = _this.e1.toLvalueImpl(sc, action, e);
+ return _this;
+ }
+
+ Expression visitSlice(SliceExp _this)
+ {
+ //printf("SliceExp::toLvalue(%s) _this.type = %s\n", _this.toChars(), _this.type ? _this.type.toChars() : NULL);
+ return (_this.type && _this.type.toBasetype().ty == Tsarray) ? _this : visit(_this);
+ }
+
+ Expression visitArray(ArrayExp _this)
+ {
+ if (_this.type && _this.type.toBasetype().ty == Tvoid)
+ error(_this.loc, "`void`s have no value");
+ return _this;
+ }
+
+ Expression visitComma(CommaExp _this)
+ {
+ _this.e2 = _this.e2.toLvalue(sc, action);
+ return _this;
+ }
+
+ Expression visitDelegatePointer(DelegatePtrExp _this)
+ {
+ _this.e1 = _this.e1.toLvalueImpl(sc, action, e);
+ return _this;
+ }
+
+ Expression visitDelegateFuncptr(DelegateFuncptrExp _this)
+ {
+ _this.e1 = _this.e1.toLvalueImpl(sc, action, e);
+ return _this;
+ }
+
+ Expression visitIndex(IndexExp _this)
+ {
+ if (_this.isLvalue())
+ return _this;
+ return visit(_this);
+ }
+
+ Expression visitAssign(AssignExp _this)
+ {
+ if (_this.e1.op == EXP.slice || _this.e1.op == EXP.arrayLength)
+ {
+ return visit(_this);
+ }
+
+ /* In front-end level, AssignExp should make an lvalue of e1.
+ * Taking the address of e1 will be handled in low level layer,
+ * so this function does nothing.
+ */
+ return _this;
+ }
+
+ Expression visitCond(CondExp _this)
+ {
+ // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
+ CondExp e = cast(CondExp)(_this.copy());
+ e.e1 = _this.e1.toLvalue(sc, action).addressOf();
+ e.e2 = _this.e2.toLvalue(sc, action).addressOf();
+ e.type = _this.type.pointerTo();
+ return new PtrExp(_this.loc, e, _this.type);
+
+ }
+
+ switch(_this.op)
+ {
+ default: return visit(_this);
+
+ case EXP.int64: return visitInteger(_this.isIntegerExp());
+ case EXP.error: return _this;
+ case EXP.identifier: return _this;
+ case EXP.dSymbol: return _this;
+ case EXP.this_: return visitThis(_this.isThisExp());
+ case EXP.super_: return visitThis(_this.isSuperExp());
+ case EXP.string_: return visitString(_this.isStringExp());
+ case EXP.structLiteral: return visitStructLiteral(_this.isStructLiteralExp());
+ case EXP.template_: return visitTemplate(_this.isTemplateExp());
+ case EXP.variable: return visitVar(_this.isVarExp());
+ case EXP.overloadSet: return _this;
+ case EXP.dotVariable: return visitDotVar(_this.isDotVarExp());
+ case EXP.call: return visitCall(_this.isCallExp());
+ case EXP.star: return _this;
+ case EXP.cast_: return visitCast(_this.isCastExp());
+ case EXP.vectorArray: return visitVectorArray(_this.isVectorArrayExp());
+ case EXP.slice: return visitSlice(_this.isSliceExp());
+ case EXP.array: return visitArray(_this.isArrayExp());
+ case EXP.comma: return visitComma(_this.isCommaExp());
+ case EXP.delegatePointer: return visitDelegatePointer(_this.isDelegatePtrExp());
+ case EXP.delegateFunctionPointer: return visitDelegateFuncptr(_this.isDelegateFuncptrExp());
+ case EXP.index: return visitIndex(_this.isIndexExp());
+ case EXP.construct: return visitAssign(_this.isConstructExp());
+ case EXP.loweredAssignExp: return visitAssign(_this.isLoweredAssignExp());
+ case EXP.blit: return visitAssign(_this.isBlitExp());
+ case EXP.assign: return visitAssign(_this.isAssignExp());
+ case EXP.question: return visitCond(_this.isCondExp());
+ }
+}
+
+/***************************************
+ * Parameters:
+ * sc: scope
+ * flag: 1: do not issue error message for invalid modification
+ 2: the exp is a DotVarExp and a subfield of the leftmost
+ variable is modified
+ * Returns:
+ * Whether the type is modifiable
+ */
+Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag = ModifyFlags.none)
+{
+ switch(exp.op)
+ {
+ case EXP.variable:
+ auto varExp = cast(VarExp)exp;
+
+ //printf("VarExp::checkModifiable %s", varExp.toChars());
+ assert(varExp.type);
+ return varExp.var.checkModify(varExp.loc, sc, null, flag);
+
+ case EXP.dotVariable:
+ auto dotVarExp = cast(DotVarExp)exp;
+
+ //printf("DotVarExp::checkModifiable %s %s\n", dotVarExp.toChars(), dotVarExp.type.toChars());
+ if (dotVarExp.e1.op == EXP.this_)
+ return dotVarExp.var.checkModify(dotVarExp.loc, sc, dotVarExp.e1, flag);
+
+ /* https://issues.dlang.org/show_bug.cgi?id=12764
+ * If inside a constructor and an expression of type `this.field.var`
+ * is encountered, where `field` is a struct declaration with
+ * default construction disabled, we must make sure that
+ * assigning to `var` does not imply that `field` was initialized
+ */
+ if (sc.func && sc.func.isCtorDeclaration())
+ {
+ // if inside a constructor scope and e1 of this DotVarExp
+ // is another DotVarExp, then check if the leftmost expression is a `this` identifier
+ if (auto dve = dotVarExp.e1.isDotVarExp())
+ {
+ // Iterate the chain of DotVarExp to find `this`
+ // Keep track whether access to fields was limited to union members
+ // s.t. one can initialize an entire struct inside nested unions
+ // (but not its members)
+ bool onlyUnion = true;
+ while (true)
+ {
+ auto v = dve.var.isVarDeclaration();
+ assert(v);
+
+ // Accessing union member?
+ auto t = v.type.isTypeStruct();
+ if (!t || !t.sym.isUnionDeclaration())
+ onlyUnion = false;
+
+ // Another DotVarExp left?
+ if (!dve.e1 || dve.e1.op != EXP.dotVariable)
+ break;
+
+ dve = cast(DotVarExp) dve.e1;
+ }
+
+ if (dve.e1.op == EXP.this_)
+ {
+ scope v = dve.var.isVarDeclaration();
+ /* if v is a struct member field with no initializer, no default construction
+ * and v wasn't intialized before
+ */
+ if (v && v.isField() && !v._init && !v.ctorinit)
+ {
+ if (auto ts = v.type.isTypeStruct())
+ {
+ if (ts.sym.noDefaultCtor)
+ {
+ /* checkModify will consider that this is an initialization
+ * of v while it is actually an assignment of a field of v
+ */
+ scope modifyLevel = v.checkModify(dotVarExp.loc, sc, dve.e1, !onlyUnion ? (flag | ModifyFlags.fieldAssign) : flag);
+ if (modifyLevel == Modifiable.initialization)
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=22118
+ // v is a union type field that was assigned
+ // a variable, therefore it counts as initialization
+ if (v.ctorinit)
+ return Modifiable.initialization;
+
+ return Modifiable.yes;
+ }
+ return modifyLevel;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //printf("\te1 = %s\n", e1.toChars());
+ return dotVarExp.e1.checkModifiable(sc, flag);
+
+ case EXP.star:
+ auto ptrExp = cast(PtrExp)exp;
+ if (auto se = ptrExp.e1.isSymOffExp())
+ {
+ return se.var.checkModify(ptrExp.loc, sc, null, flag);
+ }
+ else if (auto ae = ptrExp.e1.isAddrExp())
+ {
+ return ae.e1.checkModifiable(sc, flag);
+ }
+ return Modifiable.yes;
+
+ case EXP.slice:
+ auto sliceExp = cast(SliceExp)exp;
+
+ //printf("SliceExp::checkModifiable %s\n", sliceExp.toChars());
+ auto e1 = sliceExp.e1;
+ if (e1.type.ty == Tsarray || (e1.op == EXP.index && e1.type.ty != Tarray) || e1.op == EXP.slice)
+ {
+ return e1.checkModifiable(sc, flag);
+ }
+ return Modifiable.yes;
+
+ case EXP.comma:
+ return (cast(CommaExp)exp).e2.checkModifiable(sc, flag);
+
+ case EXP.index:
+ auto indexExp = cast(IndexExp)exp;
+ auto e1 = indexExp.e1;
+ if (e1.type.ty == Tsarray ||
+ e1.type.ty == Taarray ||
+ (e1.op == EXP.index && e1.type.ty != Tarray) ||
+ e1.op == EXP.slice)
+ {
+ return e1.checkModifiable(sc, flag);
+ }
+ return Modifiable.yes;
+
+ case EXP.question:
+ auto condExp = cast(CondExp)exp;
+ if (condExp.e1.checkModifiable(sc, flag) != Modifiable.no
+ && condExp.e2.checkModifiable(sc, flag) != Modifiable.no)
+ return Modifiable.yes;
+ return Modifiable.no;
+
+ default:
+ return exp.type ? Modifiable.yes : Modifiable.no; // default modifiable
+ }
+}
+
+/**
+ * Similar to `toLvalue`, but also enforce it is mutable or raise an error.
+ * Params:
+ * _this = Expression to convert
+ * sc = scope
+ * Returns: `_this` converted to an lvalue, or an `ErrorExp`
+ */
+extern(C++) Expression modifiableLvalue(Expression _this, Scope* sc)
+{
+ return modifiableLvalueImpl(_this, sc, _this);
+}
+
+// e = original / un-lowered expression to print in error messages
+private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression e)
+{
+ assert(e);
+ Expression visit(Expression exp)
+ {
+ //printf("Expression::modifiableLvalue() %s, type = %s\n", exp.toChars(), exp.type.toChars());
+ // See if this expression is a modifiable lvalue (i.e. not const)
+ if (exp.isBinAssignExp())
+ return exp.toLvalue(sc, "modify");
+
+ auto type = exp.type;
+ if (checkModifiable(exp, sc) == Modifiable.yes)
+ {
+ assert(type);
+ if (!type.isMutable())
+ {
+ if (auto dve = exp.isDotVarExp())
+ {
+ if (isNeedThisScope(sc, dve.var))
+ for (Dsymbol s = sc.func; s; s = s.toParentLocal())
+ {
+ FuncDeclaration ff = s.isFuncDeclaration();
+ if (!ff)
+ break;
+ if (!ff.type.isMutable)
+ {
+ error(exp.loc, "cannot modify `%s` in `%s` function", exp.toChars(), MODtoChars(type.mod));
+ return ErrorExp.get();
+ }
+ }
+ }
+ error(exp.loc, "cannot modify `%s` expression `%s`", MODtoChars(type.mod), exp.toChars());
+ return ErrorExp.get();
+ }
+ else if (!type.isAssignable())
+ {
+ error(exp.loc, "cannot modify struct instance `%s` of type `%s` because it contains `const` or `immutable` members",
+ exp.toChars(), type.toChars());
+ return ErrorExp.get();
+ }
+ }
+ return exp.toLvalueImpl(sc, "modify", e);
+ }
+
+ Expression visitString(StringExp exp)
+ {
+ error(exp.loc, "cannot modify string literal `%s`", exp.toChars());
+ return ErrorExp.get();
+ }
+
+ Expression visitVar(VarExp exp)
+ {
+ //printf("VarExp::modifiableLvalue('%s')\n", exp.var.toChars());
+ if (exp.var.storage_class & STC.manifest)
+ {
+ error(exp.loc, "cannot modify manifest constant `%s`", exp.toChars());
+ return ErrorExp.get();
+ }
+ // See if this expression is a modifiable lvalue (i.e. not const)
+ return visit(exp);
+ }
+
+ Expression visitPtr(PtrExp exp)
+ {
+ //printf("PtrExp::modifiableLvalue() %s, type %s\n", exp.toChars(), exp.type.toChars());
+ Declaration var;
+ auto e1 = exp.e1;
+ if (auto se = e1.isSymOffExp())
+ var = se.var;
+ else if (auto ve = e1.isVarExp())
+ var = ve.var;
+ if (var && var.type.isFunction_Delegate_PtrToFunction())
+ {
+ if (var.type.isTypeFunction())
+ error(exp.loc, "function `%s` is not an lvalue and cannot be modified", var.toChars());
+ else
+ error(exp.loc, "function pointed to by `%s` is not an lvalue and cannot be modified", var.toChars());
+ return ErrorExp.get();
+ }
+ return visit(exp);
+ }
+
+ Expression visitSlice(SliceExp exp)
+ {
+ error(exp.loc, "slice expression `%s` is not a modifiable lvalue", exp.toChars());
+ return exp;
+ }
+
+ Expression visitComma(CommaExp exp)
+ {
+ exp.e2 = exp.e2.modifiableLvalueImpl(sc, e);
+ return exp;
+ }
+
+ Expression visitDelegatePtr(DelegatePtrExp exp)
+ {
+ if (sc.setUnsafe(false, exp.loc, "cannot modify delegate pointer in `@safe` code `%s`", exp))
+ {
+ return ErrorExp.get();
+ }
+ return visit(exp);
+ }
+
+ Expression visitDelegateFuncptr(DelegateFuncptrExp exp)
+ {
+ if (sc.setUnsafe(false, exp.loc, "cannot modify delegate function pointer in `@safe` code `%s`", exp))
+ {
+ return ErrorExp.get();
+ }
+ return visit(exp);
+ }
+
+ Expression visitIndex(IndexExp exp)
+ {
+ //printf("IndexExp::modifiableLvalue(%s)\n", exp.toChars());
+ Expression ex = exp.markSettingAAElem();
+ if (ex.op == EXP.error)
+ return ex;
+
+ return visit(exp);
+ }
+
+ Expression visitCond(CondExp exp)
+ {
+ if (!exp.e1.isLvalue() && !exp.e2.isLvalue())
+ {
+ error(exp.loc, "conditional expression `%s` is not a modifiable lvalue", exp.toChars());
+ return ErrorExp.get();
+ }
+ exp.e1 = exp.e1.modifiableLvalue(sc);
+ exp.e2 = exp.e2.modifiableLvalue(sc);
+ return exp.toLvalue(sc, "modify");
+ }
+
+ switch(_this.op)
+ {
+ default: return visit(_this);
+ case EXP.string_: return visitString(_this.isStringExp());
+ case EXP.variable: return visitVar(_this.isVarExp());
+ case EXP.star: return visitPtr(_this.isPtrExp());
+ case EXP.slice: return visitSlice(_this.isSliceExp());
+ case EXP.comma: return visitComma(_this.isCommaExp());
+ case EXP.delegatePointer: return visitDelegatePtr(_this.isDelegatePtrExp());
+ case EXP.delegateFunctionPointer: return visitDelegateFuncptr(_this.isDelegateFuncptrExp());
+ case EXP.index: return visitIndex(_this.isIndexExp());
+ case EXP.question: return visitCond(_this.isCondExp());
+ }
+}
+
+
/****************************************************
* Determine if `exp`, which gets its address taken, can do so safely.
* Params:
@@ -14589,7 +15839,7 @@ bool checkAddressVar(Scope* sc, Expression exp, VarDeclaration v)
}
if (sc.func && !sc.intypeof && !v.isDataseg())
{
- if (global.params.useDIP1000 != FeatureState.enabled &&
+ if (sc.useDIP1000 != FeatureState.enabled &&
!(v.storage_class & STC.temp) &&
sc.setUnsafe(false, exp.loc, "cannot take address of local `%s` in `@safe` function `%s`", v, sc.func))
{
@@ -14676,15 +15926,12 @@ bool checkAddressable(Expression e, Scope* sc)
*/
private bool checkFunctionAttributes(Expression exp, Scope* sc, FuncDeclaration f)
{
- with(exp)
- {
- bool error = checkDisabled(sc, f);
- error |= checkDeprecated(sc, f);
- error |= checkPurity(sc, f);
- error |= checkSafety(sc, f);
- error |= checkNogc(sc, f);
- return error;
- }
+ bool error = f.checkDisabled(exp.loc, sc);
+ error |= f.checkDeprecated(exp.loc, sc);
+ error |= f.checkPurity(exp.loc, sc);
+ error |= f.checkSafety(exp.loc, sc);
+ error |= f.checkNogc(exp.loc, sc);
+ return error;
}
/*******************************
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index edf113e..351faa47 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -3241,13 +3241,6 @@ unittest
assert(mismatches.isMutable);
}
-private const(char)* prependSpace(const(char)* str)
-{
- if (!str || !*str) return "";
-
- return (" " ~ str.toDString() ~ "\0").ptr;
-}
-
/// Flag used by $(LREF resolveFuncCall).
enum FuncResolveFlag : ubyte
{
@@ -3361,14 +3354,11 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
const(char)* lastprms = parametersTypeToChars(tf1.parameterList);
const(char)* nextprms = parametersTypeToChars(tf2.parameterList);
- const(char)* mod1 = prependSpace(MODtoChars(tf1.mod));
- const(char)* mod2 = prependSpace(MODtoChars(tf2.mod));
-
.error(loc, "`%s.%s` called with argument types `%s` matches both:\n%s: `%s%s%s`\nand:\n%s: `%s%s%s`",
s.parent.toPrettyChars(), s.ident.toChars(),
fargsBuf.peekChars(),
- m.lastf.loc.toChars(), m.lastf.toPrettyChars(), lastprms, mod1,
- m.nextf.loc.toChars(), m.nextf.toPrettyChars(), nextprms, mod2);
+ m.lastf.loc.toChars(), m.lastf.toPrettyChars(), lastprms, tf1.modToChars(),
+ m.nextf.loc.toChars(), m.nextf.toPrettyChars(), nextprms, tf2.modToChars());
return null;
}
@@ -3422,15 +3412,25 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
if (!tf)
tf = fd.originalType.toTypeFunction();
- if (tthis && !MODimplicitConv(tthis.mod, tf.mod)) // modifier mismatch
+ // modifier mismatch
+ if (tthis && (fd.isCtorDeclaration() ?
+ !MODimplicitConv(tf.mod, tthis.mod) :
+ !MODimplicitConv(tthis.mod, tf.mod)))
{
OutBuffer thisBuf, funcBuf;
MODMatchToBuffer(&thisBuf, tthis.mod, tf.mod);
auto mismatches = MODMatchToBuffer(&funcBuf, tf.mod, tthis.mod);
if (hasOverloads)
{
- .error(loc, "none of the overloads of `%s` are callable using a %sobject",
- fd.ident.toChars(), thisBuf.peekChars());
+ OutBuffer buf;
+ buf.argExpTypesToCBuffer(fargs);
+ if (fd.isCtorDeclaration())
+ .error(loc, "none of the overloads of `%s` can construct a %sobject with argument types `(%s)`",
+ fd.toChars(), thisBuf.peekChars(), buf.peekChars());
+ else
+ .error(loc, "none of the overloads of `%s` are callable using a %sobject with argument types `(%s)`",
+ fd.toChars(), thisBuf.peekChars(), buf.peekChars());
+
if (!global.gag || global.params.v.showGaggedErrors)
printCandidates(loc, fd, sc.isDeprecated());
return null;
@@ -3447,8 +3447,12 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
return null;
}
- .error(loc, "%smethod `%s` is not callable using a %sobject",
- funcBuf.peekChars(), fd.toPrettyChars(), thisBuf.peekChars());
+ if (fd.isCtorDeclaration())
+ .error(loc, "%s%s `%s` cannot construct a %sobject",
+ funcBuf.peekChars(), fd.kind(), fd.toPrettyChars(), thisBuf.peekChars());
+ else
+ .error(loc, "%smethod `%s` is not callable using a %sobject",
+ funcBuf.peekChars(), fd.toPrettyChars(), thisBuf.peekChars());
if (mismatches.isNotShared)
.errorSupplemental(fd.loc, "Consider adding `shared` here");
@@ -3535,11 +3539,17 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
if (!print)
return true;
auto tf = cast(TypeFunction) fd.type;
+ OutBuffer buf;
+ buf.writestring(fd.toPrettyChars());
+ buf.writestring(parametersTypeToChars(tf.parameterList));
+ if (tf.mod)
+ {
+ buf.writeByte(' ');
+ buf.MODtoBuffer(tf.mod);
+ }
.errorSupplemental(fd.loc,
- printed ? " `%s%s`" :
- single_candidate ? "Candidate is: `%s%s`" : "Candidates are: `%s%s`",
- fd.toPrettyChars(),
- parametersTypeToChars(tf.parameterList));
+ printed ? " `%s`" :
+ single_candidate ? "Candidate is: `%s`" : "Candidates are: `%s`", buf.peekChars());
}
else if (auto td = s.isTemplateDeclaration())
{
@@ -4621,7 +4631,14 @@ bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)
case default_:
if (!sc.func)
return false;
- if (!sc.func.isSafeBypassingInference() && !sc.func.safetyViolation)
+ if (sc.func.isSafeBypassingInference())
+ {
+ if (!gag)
+ {
+ warning(loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
+ }
+ }
+ else if (!sc.func.safetyViolation)
{
import dmd.func : AttributeViolation;
sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1, arg2);
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index 2f6fae3..8d88207 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -250,6 +250,12 @@ extern (C++) struct Param
const(char)[] resfile;
const(char)[] exefile;
const(char)[] mapfile;
+
+ ///
+ bool parsingUnittestsRequired()
+ {
+ return useUnitTests || ddoc.doOutput || dihdr.doOutput;
+ }
}
enum mars_ext = "d"; // for D source files
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index d935bd3..ac2dda3 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -41,6 +41,7 @@ import dmd.identifier;
import dmd.init;
import dmd.mtype;
import dmd.nspace;
+import dmd.optimize;
import dmd.parse;
import dmd.root.complex;
import dmd.root.ctfloat;
@@ -1942,7 +1943,7 @@ private void visitTemplateParameters(TemplateParameters* parameters, ref OutBuff
{
if (i)
buf.writestring(", ");
- p.templateParameterToBuffer(buf, &hgs);
+ toCBuffer(p, buf, hgs);
}
}
@@ -2884,10 +2885,10 @@ void floatToBuffer(Type type, const real_t value, ref OutBuffer buf, const bool
}
}
-private void templateParameterToBuffer(TemplateParameter tp, ref OutBuffer buf, HdrGenState* hgs)
+void toCBuffer(const TemplateParameter tp, ref OutBuffer buf, ref HdrGenState hgs)
{
- scope v = new TemplateParameterPrettyPrintVisitor(&buf, hgs);
- tp.accept(v);
+ scope v = new TemplateParameterPrettyPrintVisitor(&buf, &hgs);
+ (cast() tp).accept(v);
}
private extern (C++) final class TemplateParameterPrettyPrintVisitor : Visitor
@@ -3261,12 +3262,6 @@ void argExpTypesToCBuffer(ref OutBuffer buf, Expressions* arguments)
}
}
-void toCBuffer(const TemplateParameter tp, ref OutBuffer buf, ref HdrGenState hgs)
-{
- scope v = new TemplateParameterPrettyPrintVisitor(&buf, &hgs);
- (cast() tp).accept(v);
-}
-
void arrayObjectsToBuffer(ref OutBuffer buf, Objects* objects)
{
if (!objects || !objects.length)
@@ -3836,7 +3831,7 @@ private void visitFuncIdentWithPrefix(TypeFunction t, const Identifier ident, Te
{
if (i)
buf.writestring(", ");
- p.templateParameterToBuffer(buf, hgs);
+ toCBuffer(p, buf, *hgs);
}
buf.writeByte(')');
}
@@ -3861,6 +3856,11 @@ private void initializerToBuffer(Initializer inx, ref OutBuffer buf, HdrGenState
buf.writestring("void");
}
+ void visitDefault(DefaultInitializer iz)
+ {
+ buf.writestring("{ }");
+ }
+
void visitStruct(StructInitializer si)
{
//printf("StructInitializer::toCBuffer()\n");
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index 5494fec..92837b4 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -302,7 +302,7 @@ Ldone:
extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
{
//printf("GccAsmStatement.semantic()\n");
- const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput;
+ const bool doUnittests = global.params.parsingUnittestsRequired();
scope p = new Parser!ASTCodegen(sc._module, ";", false, global.errorSink, &global.compileEnv, doUnittests);
// Make a safe copy of the token list before parsing.
@@ -341,7 +341,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
e = e.expressionSemantic(sc);
// Check argument is a valid lvalue/rvalue.
if (i < s.outputargs)
- e = e.modifiableLvalue(sc, null);
+ e = e.modifiableLvalue(sc);
else if (e.checkValue())
e = ErrorExp.get();
(*s.args)[i] = e;
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 5fcda91..32221d9 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -323,6 +323,8 @@ immutable Msgtable[] msgtable =
{ "_d_newitemTTrace" },
{ "_d_newarrayT" },
{ "_d_newarrayTTrace" },
+ { "_d_newarraymTX" },
+ { "_d_newarraymTXTrace" },
{ "_d_assert_fail" },
{ "dup" },
{ "_aaApply" },
@@ -366,7 +368,6 @@ immutable Msgtable[] msgtable =
{ "_d_arraysetlengthTTrace"},
{ "_d_arrayappendT" },
{ "_d_arrayappendTTrace" },
- { "_d_arrayappendcTXImpl" },
{ "_d_arrayappendcTX" },
{ "_d_arrayappendcTXTrace" },
{ "_d_arraycatnTX" },
diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h
index 31ee61a..aeb3621 100644
--- a/gcc/d/dmd/import.h
+++ b/gcc/d/dmd/import.h
@@ -43,9 +43,7 @@ public:
Import *syntaxCopy(Dsymbol *s) override; // copy only syntax trees
void importAll(Scope *sc) override;
Dsymbol *toAlias() override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
void setScope(Scope* sc) override;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
bool overloadInsert(Dsymbol *s) override;
Import *isImport() override { return this; }
diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d
index 98ac903..2c7699b 100644
--- a/gcc/d/dmd/importc.d
+++ b/gcc/d/dmd/importc.d
@@ -20,6 +20,7 @@ import dmd.dcast;
import dmd.declaration;
import dmd.dscope;
import dmd.dsymbol;
+import dmd.dsymbolsem;
import dmd.errors;
import dmd.expression;
import dmd.expressionsem;
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index ebcd011..e484100 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -68,6 +68,11 @@ extern (C++) class Initializer : ASTNode
return kind == InitKind.void_ ? cast(inout VoidInitializer)cast(void*)this : null;
}
+ final inout(DefaultInitializer) isDefaultInitializer() inout @nogc nothrow pure
+ {
+ return kind == InitKind.default_ ? cast(inout DefaultInitializer)cast(void*)this : null;
+ }
+
final inout(StructInitializer) isStructInitializer() inout @nogc nothrow pure
{
return kind == InitKind.struct_ ? cast(inout StructInitializer)cast(void*)this : null;
@@ -112,6 +117,24 @@ extern (C++) final class VoidInitializer : Initializer
}
/***********************************************************
+ * The C23 default initializer `{ }`
+ */
+extern (C++) final class DefaultInitializer : Initializer
+{
+ Type type; // type that this will initialize to
+
+ extern (D) this(const ref Loc loc) @safe
+ {
+ super(loc, InitKind.default_);
+ }
+
+ override void accept(Visitor v)
+ {
+ v.visit(this);
+ }
+}
+
+/***********************************************************
*/
extern (C++) final class ErrorInitializer : Initializer
{
@@ -266,6 +289,11 @@ Initializer syntaxCopy(Initializer inx)
return new VoidInitializer(vi.loc);
}
+ static Initializer visitDefault(DefaultInitializer vi)
+ {
+ return new DefaultInitializer(vi.loc);
+ }
+
static Initializer visitError(ErrorInitializer vi)
{
return vi;
@@ -352,6 +380,7 @@ mixin template VisitInitializer(Result)
final switch (init.kind)
{
case InitKind.void_: mixin(visitCase("Void")); break;
+ case InitKind.default_: mixin(visitCase("Default")); break;
case InitKind.error: mixin(visitCase("Error")); break;
case InitKind.struct_: mixin(visitCase("Struct")); break;
case InitKind.array: mixin(visitCase("Array")); break;
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 67d0527..21bd07f 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -20,6 +20,7 @@ class Expression;
class Type;
class ErrorInitializer;
class VoidInitializer;
+class DefaultInitializer;
class StructInitializer;
class ArrayInitializer;
class ExpInitializer;
@@ -37,6 +38,7 @@ public:
ErrorInitializer *isErrorInitializer();
VoidInitializer *isVoidInitializer();
+ DefaultInitializer *isDefaultInitializer();
StructInitializer *isStructInitializer();
ArrayInitializer *isArrayInitializer();
ExpInitializer *isExpInitializer();
@@ -53,6 +55,14 @@ public:
void accept(Visitor *v) override { v->visit(this); }
};
+class DefaultInitializer final : public Initializer
+{
+public:
+ Type *type; // type that this will initialize to
+
+ void accept(Visitor *v) override { v->visit(this); }
+};
+
class ErrorInitializer final : public Initializer
{
public:
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index 632c0d0..76c2d89 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -24,6 +24,7 @@ import dmd.dinterpret;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
+import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
@@ -38,6 +39,7 @@ import dmd.init;
import dmd.location;
import dmd.mtype;
import dmd.opover;
+import dmd.optimize;
import dmd.statement;
import dmd.target;
import dmd.tokens;
@@ -105,6 +107,7 @@ Expression toAssocArrayLiteral(ArrayInitializer ai)
*/
extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedInterpret needInterpret)
{
+ //printf("initializerSemantic() tx: %p %s\n", tx, tx.toChars());
Type t = tx;
static Initializer err()
@@ -118,6 +121,12 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
return i;
}
+ Initializer visitDefault(DefaultInitializer i)
+ {
+ i.type = t;
+ return i;
+ }
+
Initializer visitError(ErrorInitializer i)
{
return i;
@@ -1016,6 +1025,12 @@ Initializer inferType(Initializer init, Scope* sc)
return new ErrorInitializer();
}
+ Initializer visitDefault(DefaultInitializer i)
+ {
+ error(i.loc, "cannot infer type from default initializer");
+ return new ErrorInitializer();
+ }
+
Initializer visitError(ErrorInitializer i)
{
return i;
@@ -1174,6 +1189,11 @@ extern (C++) Expression initializerToExpression(Initializer init, Type itype = n
return null;
}
+ Expression visitDefault(DefaultInitializer di)
+ {
+ return di.type ? di.type.defaultInit(Loc.initial, isCfile) : null;
+ }
+
Expression visitError(ErrorInitializer)
{
return ErrorExp.get();
diff --git a/gcc/d/dmd/lambdacomp.d b/gcc/d/dmd/lambdacomp.d
index ec070d8..d19d435 100644
--- a/gcc/d/dmd/lambdacomp.d
+++ b/gcc/d/dmd/lambdacomp.d
@@ -22,6 +22,7 @@ import dmd.astenums;
import dmd.declaration;
import dmd.denum;
import dmd.dsymbol;
+import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.expression;
import dmd.func;
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index a1214b2..b8faec7 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -3258,6 +3258,24 @@ class Lexer
scanloc.linnum = scanloc.linnum + 1;
line = p;
}
+
+ /****************************
+ * Print the tokens from the current `token` to the end,
+ * while not advancing the parser forward.
+ * Useful for debugging.
+ */
+ void printRestOfTokens()
+ {
+ auto tk = &token;
+ while (1)
+ {
+ printf("%s ", (*tk).toChars());
+ if (tk.value == TOK.endOfFile)
+ break;
+ tk = peek(tk);
+ }
+ printf("\n");
+ }
}
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 6e8153d..92efc16 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -43,7 +43,6 @@ public:
bool isAncestorPackageOf(const Package * const pkg) const;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
void accept(Visitor *v) override { v->visit(this); }
Module *isPackageMod();
@@ -124,7 +123,6 @@ public:
Module *parse(); // syntactic parse
void importAll(Scope *sc) override;
int needModuleInfo();
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0) override;
Dsymbol *symtabInsert(Dsymbol *s) override;
static void runDeferredSemantic();
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index 59bf1d5..e59b010 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -108,12 +108,6 @@ public:
return;
f.printGCUsage(e.loc, "setting `length` may cause a GC allocation");
}
- else if (fd.ident == Id._d_arrayappendT || fd.ident == Id._d_arrayappendcTX)
- {
- if (setGC(e, "cannot use operator `~=` in `@nogc` %s `%s`"))
- return;
- f.printGCUsage(e.loc, "operator `~=` may cause a GC allocation");
- }
}
override void visit(ArrayLiteralExp e)
@@ -187,20 +181,14 @@ public:
override void visit(CatAssignExp e)
{
- /* CatAssignExp will exist in `__traits(compiles, ...)` and in the `.e1` branch of a `__ctfe ? :` CondExp.
- * The other branch will be `_d_arrayappendcTX(e1, 1), e1[$-1]=e2` which will generate the warning about
- * GC usage. See visit(CallExp).
- */
if (checkOnly)
{
err = true;
return;
}
- if (f.setGC(e.loc, null))
- {
- err = true;
+ if (setGC(e, "cannot use operator `~=` in `@nogc` %s `%s`"))
return;
- }
+ f.printGCUsage(e.loc, "operator `~=` may cause a GC allocation");
}
override void visit(CatExp e)
diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d
index 2d3367a..a49e0bf 100644
--- a/gcc/d/dmd/nspace.d
+++ b/gcc/d/dmd/nspace.d
@@ -85,33 +85,6 @@ extern (C++) final class Nspace : ScopeDsymbol
return ns;
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- ScopeDsymbol.addMember(sc, sds);
-
- if (members)
- {
- if (!symtab)
- symtab = new DsymbolTable();
- // The namespace becomes 'imported' into the enclosing scope
- for (Scope* sce = sc; 1; sce = sce.enclosing)
- {
- ScopeDsymbol sds2 = sce.scopesym;
- if (sds2)
- {
- sds2.importScope(this, Visibility(Visibility.Kind.public_));
- break;
- }
- }
- assert(sc);
- sc = sc.push(this);
- sc.linkage = LINK.cpp; // namespaces default to C++ linkage
- sc.parent = this;
- members.foreachDsymbol(s => s.addMember(sc, this));
- sc.pop();
- }
- }
-
override void setScope(Scope* sc)
{
ScopeDsymbol.setScope(sc);
@@ -126,22 +99,6 @@ extern (C++) final class Nspace : ScopeDsymbol
}
}
- override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
- {
- //printf("%s.Nspace.search('%s')\n", toChars(), ident.toChars());
- if (_scope && !symtab)
- dsymbolSemantic(this, _scope);
-
- if (!members || !symtab) // opaque or semantic() is not yet called
- {
- if (!(flags & IgnoreErrors))
- .error(loc, "%s `%s` is forward referenced when looking for `%s`", kind, toPrettyChars, ident.toChars());
- return null;
- }
-
- return ScopeDsymbol.search(loc, ident, flags);
- }
-
override bool hasPointers()
{
//printf("Nspace::hasPointers() %s\n", toChars());
diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h
index e9fb7bd..7d30402 100644
--- a/gcc/d/dmd/nspace.h
+++ b/gcc/d/dmd/nspace.h
@@ -21,9 +21,7 @@ class Nspace final : public ScopeDsymbol
public:
Expression *identExp;
Nspace *syntaxCopy(Dsymbol *s) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
void setScope(Scope *sc) override;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
bool hasPointers() override;
void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override;
const char *kind() const override;
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index addcd01..b7bc925 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -23,6 +23,7 @@ import dmd.declaration;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
+import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
@@ -34,6 +35,7 @@ import dmd.id;
import dmd.identifier;
import dmd.location;
import dmd.mtype;
+import dmd.optimize;
import dmd.statement;
import dmd.tokens;
import dmd.typesem;
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index 0065b01..a979168 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -272,9 +272,9 @@ package void setLengthVarIfKnown(VarDeclaration lengthVar, Type type)
* Returns:
* Constant folded version of `e`
*/
-Expression Expression_optimize(Expression e, int result, bool keepLvalue)
+Expression optimize(Expression e, int result, bool keepLvalue = false)
{
- //printf("Expression_optimize() e: %s result: %d keepLvalue %d\n", e.toChars(), result, keepLvalue);
+ //printf("optimize() e: %s result: %d keepLvalue %d\n", e.toChars(), result, keepLvalue);
Expression ret = e;
void errorReturn()
@@ -288,7 +288,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
{
if (!e)
return false;
- Expression ex = Expression_optimize(e, flags, keepLvalue);
+ Expression ex = optimize(e, flags, keepLvalue);
if (ex.op == EXP.error)
{
ret = ex; // store error result
@@ -591,7 +591,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
Expression add = new AddExp(ae.loc, ex, new IntegerExp(ae.e2.loc, offset, ae.e2.type));
add.type = e.type;
- ret = Expression_optimize(add, result, keepLvalue);
+ ret = optimize(add, result, keepLvalue);
return;
}
}
@@ -928,6 +928,14 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
}
}
+ void visitCatAssign(CatAssignExp e)
+ {
+ if (auto lowering = e.lowering)
+ optimize(lowering, result, keepLvalue);
+ else
+ visitBinAssign(e);
+ }
+
void visitBin(BinExp e)
{
//printf("BinExp::optimize(result = %d) %s\n", result, e.toChars());
@@ -1239,7 +1247,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
ret = new CastExp(e.loc, ret, Type.tvoid);
ret.type = e.type;
}
- ret = Expression_optimize(ret, result, false);
+ ret = optimize(ret, result, false);
return;
}
expOptimize(e.e2, WANTvalue);
@@ -1294,7 +1302,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
// `["c"] ~ "a" ~ "b"` becoming `["c"] ~ "ab"`
scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);
cex.type = e.type;
- Expression ex = Expression_optimize(cex, result, false);
+ Expression ex = optimize(cex, result, false);
if (ex != cex)
{
e.e1 = ce1.e1;
@@ -1323,9 +1331,9 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
return;
const opt = e.econd.toBool();
if (opt.hasValue(true))
- ret = Expression_optimize(e.e1, result, keepLvalue);
+ ret = optimize(e.e1, result, keepLvalue);
else if (opt.hasValue(false))
- ret = Expression_optimize(e.e2, result, keepLvalue);
+ ret = optimize(e.e2, result, keepLvalue);
else
{
expOptimize(e.e1, result, keepLvalue);
@@ -1392,9 +1400,9 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
case EXP.leftShiftAssign:
case EXP.rightShiftAssign:
case EXP.unsignedRightShiftAssign:
+ case EXP.concatenateDcharAssign: visitBinAssign(ex.isBinAssignExp()); break;
case EXP.concatenateElemAssign:
- case EXP.concatenateDcharAssign:
- case EXP.concatenateAssign: visitBinAssign(ex.isBinAssignExp()); break;
+ case EXP.concatenateAssign: visitCatAssign(cast(CatAssignExp) ex); break;
case EXP.minusMinus:
case EXP.plusPlus:
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 51e522d..f9d174a 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -4878,30 +4878,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
AST.Declaration v;
AST.Dsymbol s;
- // try to parse function type:
- // TypeCtors? BasicType ( Parameters ) MemberFunctionAttributes
bool attributesAppended;
const StorageClass funcStc = parseTypeCtor();
- Token* tlu = &token;
Token* tk;
- if (token.value != TOK.function_ &&
- token.value != TOK.delegate_ &&
- isBasicType(&tlu) && tlu &&
- tlu.value == TOK.leftParenthesis)
- {
- AST.Type tret = parseBasicType();
- auto parameterList = parseParameterList(null);
-
- parseAttributes();
- if (udas)
- error("user-defined attributes not allowed for `alias` declarations");
-
- attributesAppended = true;
- storage_class = appendStorageClass(storage_class, funcStc);
- AST.Type tf = new AST.TypeFunction(parameterList, tret, link, storage_class);
- v = new AST.AliasDeclaration(loc, ident, tf);
- }
- else if (token.value == TOK.function_ ||
+ // function literal?
+ if (token.value == TOK.function_ ||
token.value == TOK.delegate_ ||
token.value == TOK.leftParenthesis &&
skipAttributes(peekPastParen(&token), &tk) &&
@@ -4911,10 +4892,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
token.value == TOK.ref_ && peekNext() == TOK.leftParenthesis &&
skipAttributes(peekPastParen(peek(&token)), &tk) &&
(tk.value == TOK.goesTo || tk.value == TOK.leftCurly) ||
- token.value == TOK.auto_ && peekNext() == TOK.ref_ &&
- peekNext2() == TOK.leftParenthesis &&
- skipAttributes(peekPastParen(peek(peek(&token))), &tk) &&
- (tk.value == TOK.goesTo || tk.value == TOK.leftCurly)
+ token.value == TOK.auto_ &&
+ (peekNext() == TOK.leftParenthesis || // for better error
+ peekNext() == TOK.ref_ &&
+ peekNext2() == TOK.leftParenthesis)
)
{
// function (parameters) { statements... }
@@ -4955,21 +4936,46 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
else
{
- parseAttributes();
// type
+ parseAttributes();
if (udas)
error("user-defined attributes not allowed for `alias` declarations");
- auto t = parseType();
+ auto t = parseBasicType();
+ t = parseTypeSuffixes(t);
+ if (token.value == TOK.identifier)
+ {
+ error("unexpected identifier `%s` after `%s`",
+ token.ident.toChars(), t.toChars());
+ nextToken();
+ }
+ else if (token.value == TOK.leftParenthesis)
+ {
+ // function type:
+ // StorageClasses Type ( Parameters ) MemberFunctionAttributes
+ auto parameterList = parseParameterList(null);
+ udas = null;
+ parseStorageClasses(storage_class, link, setAlignment, ealign, udas, linkloc);
+ if (udas)
+ error("user-defined attributes not allowed for `alias` declarations");
+
+ attributesAppended = true;
+ // Note: method types can have a TypeCtor attribute
+ storage_class = appendStorageClass(storage_class, funcStc);
+ t = new AST.TypeFunction(parameterList, t, link, storage_class);
+ }
// Disallow meaningless storage classes on type aliases
if (storage_class)
{
// Don't raise errors for STC that are part of a function/delegate type, e.g.
// `alias F = ref pure nothrow @nogc @safe int function();`
- auto tp = t.isTypePointer;
- const isFuncType = (tp && tp.next.isTypeFunction) || t.isTypeDelegate;
- const remStc = isFuncType ? (storage_class & ~STC.FUNCATTR) : storage_class;
+ const remStc = t.isTypeFunction ?
+ storage_class & ~(STC.FUNCATTR | STC.TYPECTOR) : {
+ auto tp = t.isTypePointer;
+ const isFuncType = (tp && tp.next.isTypeFunction) || t.isTypeDelegate;
+ return isFuncType ? (storage_class & ~STC.FUNCATTR) : storage_class;
+ }();
if (remStc)
{
@@ -7217,6 +7223,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
return false;
}
+ // pt = test token. If found, pt is set to the token after BasicType
private bool isBasicType(Token** pt)
{
// This code parallels parseBasicType()
diff --git a/gcc/d/dmd/parsetimevisitor.d b/gcc/d/dmd/parsetimevisitor.d
index a4a9434..3d0a585 100644
--- a/gcc/d/dmd/parsetimevisitor.d
+++ b/gcc/d/dmd/parsetimevisitor.d
@@ -298,5 +298,6 @@ public:
void visit(AST.StructInitializer i) { visit(cast(AST.Initializer)i); }
void visit(AST.ArrayInitializer i) { visit(cast(AST.Initializer)i); }
void visit(AST.VoidInitializer i) { visit(cast(AST.Initializer)i); }
+ void visit(AST.DefaultInitializer i) { visit(cast(AST.Initializer)i); }
void visit(AST.CInitializer i) { visit(cast(AST.CInitializer)i); }
}
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index 178542e..2cac5f2 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -61,6 +61,9 @@ enum class SCOPE
Cfile = 0x0800, // C semantics apply
free = 0x8000, // is on free list
fullinst = 0x10000, // fully instantiate templates
+ ctfeBlock = 0x20000, // inside a `if (__ctfe)` block
+ dip1000 = 0x40000, // dip1000 errors enabled for this scope
+ dip25 = 0x80000, // dip25 errors enabled for this scope
};
struct Scope
@@ -126,4 +129,6 @@ struct Scope
AliasDeclaration *aliasAsg; // if set, then aliasAsg is being assigned a new value,
// do not set wasRead for it
+
+ Dsymbol *search(const Loc &loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone);
};
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index 0b0ca91..c255701 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -54,6 +54,7 @@ import dmd.nspace;
import dmd.ob;
import dmd.objc;
import dmd.opover;
+import dmd.optimize;
import dmd.parse;
import dmd.root.filename;
import dmd.common.outbuffer;
@@ -917,7 +918,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (f.isref)
{
// Function returns a reference
- exp = exp.toLvalue(sc2, exp);
+ exp = exp.toLvalue(sc2, "`ref` return");
checkReturnEscapeRef(sc2, exp, false);
exp = exp.optimize(WANTvalue, /*keepLvalue*/ true);
}
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index d43d915..3873adc 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -55,6 +55,7 @@ import dmd.location;
import dmd.mtype;
import dmd.mustuse;
import dmd.nogc;
+import dmd.optimize;
import dmd.opover;
import dmd.parse;
import dmd.common.outbuffer;
@@ -3800,7 +3801,7 @@ private extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde,
{
version (none)
{
- if (global.params.useDIP1000 == FeatureState.enabled)
+ if (sc2.useDIP1000 == FeatureState.enabled)
{
message(loc, "To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`");
}
@@ -3808,7 +3809,7 @@ private extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde,
}
else
{
- if (global.params.useDIP1000 == FeatureState.enabled)
+ if (sc2.useDIP1000 == FeatureState.enabled)
++(cast(FuncExp)flde).fd.tookAddressOf; // allocate a closure unless the opApply() uses 'scope'
}
assert(tab.ty == Tstruct || tab.ty == Tclass);
@@ -4887,7 +4888,7 @@ private Statements* flatten(Statement statement, Scope* sc)
const len = buf.length;
buf.writeByte(0);
const str = buf.extractSlice()[0 .. len];
- const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput;
+ const bool doUnittests = global.params.parsingUnittestsRequired();
auto loc = adjustLocForMixin(str, cs.loc, global.params.mixinOut);
scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests);
p.transitionIn = global.params.v.vin;
diff --git a/gcc/d/dmd/staticassert.d b/gcc/d/dmd/staticassert.d
index 15c46b3..7f22c4c 100644
--- a/gcc/d/dmd/staticassert.d
+++ b/gcc/d/dmd/staticassert.d
@@ -52,11 +52,6 @@ extern (C++) final class StaticAssert : Dsymbol
return new StaticAssert(loc, exp.syntaxCopy(), msgs ? Expression.arraySyntaxCopy(msgs) : null);
}
- override void addMember(Scope* sc, ScopeDsymbol sds)
- {
- // we didn't add anything
- }
-
override bool oneMember(Dsymbol* ps, Identifier ident)
{
//printf("StaticAssert::oneMember())\n");
diff --git a/gcc/d/dmd/staticassert.h b/gcc/d/dmd/staticassert.h
index 2b7d300..c0d5363 100644
--- a/gcc/d/dmd/staticassert.h
+++ b/gcc/d/dmd/staticassert.h
@@ -21,7 +21,6 @@ public:
Expressions *msg;
StaticAssert *syntaxCopy(Dsymbol *s) override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
bool oneMember(Dsymbol **ps, Identifier *ident) override;
const char *kind() const override;
StaticAssert *isStaticAssert() override { return this; }
diff --git a/gcc/d/dmd/staticcond.d b/gcc/d/dmd/staticcond.d
index 923f1a9..1d18de3 100644
--- a/gcc/d/dmd/staticcond.d
+++ b/gcc/d/dmd/staticcond.d
@@ -22,6 +22,7 @@ import dmd.expressionsem;
import dmd.globals;
import dmd.identifier;
import dmd.mtype;
+import dmd.optimize;
import dmd.root.array;
import dmd.common.outbuffer;
import dmd.tokens;
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index ca2af79..0acadbb 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -32,6 +32,7 @@ import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
+import dmd.errorsink;
import dmd.expression;
import dmd.expressionsem;
import dmd.func;
@@ -42,6 +43,7 @@ import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.nogc;
+import dmd.optimize;
import dmd.parse;
import dmd.root.array;
import dmd.root.speller;
@@ -91,43 +93,50 @@ private Dsymbol getDsymbolWithoutExpCtx(RootObject oarg)
}
/**
- * get an array of size_t values that indicate possible pointer words in memory
- * if interpreted as the type given as argument
- * Returns: the size of the type in bytes, ulong.max on error
+ * Fill an array of target size_t values that indicate possible pointer words in memory
+ * if interpreted as the type given as argument.
+ * One bit in the array per pointer-sized piece of memory
+ * Params:
+ * loc = location for error messages
+ * t = type to generate pointer bitmap from
+ * data = array forming the bitmap
+ * eSink = error message sink
+ * Returns:
+ * size of the type `t` in bytes, ulong.max on error
*/
-ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data)
+ulong getTypePointerBitmap(Loc loc, Type t, ref Array!(ulong) data, ErrorSink eSink)
{
- ulong sz;
- if (t.ty == Tclass && !(cast(TypeClass)t).sym.isInterfaceDeclaration())
- sz = (cast(TypeClass)t).sym.AggregateDeclaration.size(loc);
- else
- sz = t.size(loc);
+ auto tc = t.isTypeClass();
+ const ulong sz = (tc && !tc.sym.isInterfaceDeclaration())
+ ? tc.sym.AggregateDeclaration.size(loc)
+ : t.size(loc);
if (sz == SIZE_INVALID)
return ulong.max;
- const sz_size_t = Type.tsize_t.size(loc);
+ const sz_size_t = Type.tsize_t.size(loc); // size of target's size_t
+ assert(sz_size_t <= ulong.sizeof);
if (sz > sz.max - sz_size_t)
{
- error(loc, "size overflow for type `%s`", t.toChars());
+ eSink.error(loc, "size overflow for type `%s`", t.toChars());
return ulong.max;
}
- ulong bitsPerWord = sz_size_t * 8;
- ulong cntptr = (sz + sz_size_t - 1) / sz_size_t;
- ulong cntdata = (cntptr + bitsPerWord - 1) / bitsPerWord;
+ const ulong bitsPerElement = sz_size_t * 8; // bits used in each array element
+ const ulong cntptr = (sz + sz_size_t - 1) / sz_size_t; // pointers have same size as sz_size_t
+ const ulong length = (cntptr + bitsPerElement - 1) / bitsPerElement; // a bit per pointer
- data.setDim(cast(size_t)cntdata);
+ data.setDim(cast(size_t)length);
data.zero();
ulong offset;
- bool error;
+ bool error; // sticky error indicator
void visit(Type t)
{
void setpointer(ulong off)
{
ulong ptroff = off / sz_size_t;
- (*data)[cast(size_t)(ptroff / (8 * sz_size_t))] |= 1L << (ptroff % (8 * sz_size_t));
+ data[cast(size_t)(ptroff / bitsPerElement)] |= 1L << (ptroff % bitsPerElement);
}
void visitType(Type t)
@@ -246,7 +255,7 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data)
visit.VisitType(t);
}
- if (auto tc = t.isTypeClass())
+ if (auto tcx = t.isTypeClass())
{
// a "toplevel" class is treated as an instance, while TypeClass fields are treated as references
void visitTopLevelClass(TypeClass t)
@@ -263,7 +272,7 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data)
offset = classoff;
}
- visitTopLevelClass(tc);
+ visitTopLevelClass(tcx);
}
else
visit(t);
@@ -280,28 +289,28 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data)
*
* Returns: [T.sizeof, pointerbit0-31/63, pointerbit32/64-63/128, ...]
*/
-private Expression pointerBitmap(TraitsExp e)
+private Expression pointerBitmap(TraitsExp e, ErrorSink eSink)
{
if (!e.args || e.args.length != 1)
{
- error(e.loc, "a single type expected for trait pointerBitmap");
+ eSink.error(e.loc, "a single type expected for trait pointerBitmap");
return ErrorExp.get();
}
Type t = getType((*e.args)[0]);
if (!t)
{
- error(e.loc, "`%s` is not a type", (*e.args)[0].toChars());
+ eSink.error(e.loc, "`%s` is not a type", (*e.args)[0].toChars());
return ErrorExp.get();
}
Array!(ulong) data;
- ulong sz = getTypePointerBitmap(e.loc, t, &data);
+ const ulong sz = getTypePointerBitmap(e.loc, t, data, eSink);
if (sz == ulong.max)
return ErrorExp.get();
auto exps = new Expressions(data.length + 1);
- (*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t);
+ (*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t); // [0] is size in bytes of t
foreach (size_t i; 1 .. exps.length)
(*exps)[i] = new IntegerExp(e.loc, data[cast(size_t) (i - 1)], Type.tsize_t);
@@ -471,13 +480,13 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
}
if (e.ident == Id.isAbstractClass)
{
- return isTypeX(t => t.toBasetype().ty == Tclass &&
- (cast(TypeClass)t.toBasetype()).sym.isAbstract());
+ return isTypeX(t => t.toBasetype().isTypeClass() &&
+ t.toBasetype().isTypeClass().sym.isAbstract());
}
if (e.ident == Id.isFinalClass)
{
- return isTypeX(t => t.toBasetype().ty == Tclass &&
- ((cast(TypeClass)t.toBasetype()).sym.storage_class & STC.final_) != 0);
+ return isTypeX(t => t.toBasetype().isTypeClass() &&
+ (t.toBasetype().isTypeClass().sym.storage_class & STC.final_) != 0);
}
if (e.ident == Id.isTemplate)
{
@@ -507,7 +516,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
}
Type tb = t.baseElemOf();
- if (auto sd = tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null)
+ auto ts = tb.isTypeStruct();
+ if (auto sd = ts ? ts.sym : null)
{
return sd.isPOD() ? True() : False();
}
@@ -528,7 +538,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
}
Type tb = t.baseElemOf();
- if (auto sd = tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null)
+ auto ts = tb.isTypeStruct();
+ if (auto sd = ts ? ts.sym : null)
{
return (e.ident == Id.hasPostblit) ? (sd.postblit ? True() : False())
: (sd.hasCopyCtor ? True() : False());
@@ -792,10 +803,10 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
{
if (auto p = s.toParent()) // `C`'s parent is `C!2`, believe it or not
{
- if (p.isTemplateInstance()) // `C!2` is a template instance
+ if (auto ti = p.isTemplateInstance()) // `C!2` is a template instance
{
s = p; // `C!2`'s parent is `T1`
- auto td = (cast(TemplateInstance)p).tempdecl;
+ auto td = ti.tempdecl;
if (td)
s = td; // get the declaration context just in case there's two contexts
}
@@ -1296,7 +1307,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
if (fd && fd.parent && fd.parent.isTemplateInstance)
{
fd.functionSemantic3();
- tf = cast(TypeFunction)fd.type;
+ tf = fd.type.isTypeFunction();
}
auto mods = new Expressions();
@@ -1737,9 +1748,9 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
ex = ex.expressionSemantic(sc2);
ex = resolvePropertiesOnly(sc2, ex);
ex = ex.optimize(WANTvalue);
- if (sc2.func && sc2.func.type.ty == Tfunction)
+ if (sc2.func && sc2.func.type.isTypeFunction())
{
- const tf = cast(TypeFunction)sc2.func.type;
+ const tf = sc2.func.type.isTypeFunction();
err |= tf.isnothrow && canThrow(ex, sc2.func, null);
}
ex = checkGC(sc2, ex);
@@ -1867,7 +1878,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
}
if (e.ident == Id.getPointerBitmap)
{
- return pointerBitmap(e);
+ return pointerBitmap(e, global.errorSink);
}
if (e.ident == Id.initSymbol)
{
@@ -1875,16 +1886,24 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
return dimError(1);
auto o = (*e.args)[0];
- Type t = isType(o);
- AggregateDeclaration ad = t ? isAggregate(t) : null;
- // Interfaces don't have an init symbol and hence cause linker errors
- if (!ad || ad.isInterfaceDeclaration())
+ ErrorExp badArgument()
{
error(e.loc, "struct / class type expected as argument to __traits(initSymbol) instead of `%s`", o.toChars());
return ErrorExp.get();
}
+ Type t = isType(o);
+
+ if (!t || t.isTypeEnum())
+ return badArgument();
+
+ AggregateDeclaration ad = isAggregate(t);
+
+ // Interfaces don't have an init symbol and hence cause linker errors
+ if (!ad || ad.isInterfaceDeclaration())
+ return badArgument();
+
Declaration d = new SymbolDeclaration(ad.loc, ad);
d.type = Type.tvoid.arrayOf().constOf();
d.storage_class |= STC.rvalue;
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index bbe11f6..8795002 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -53,6 +53,7 @@ import dmd.visitor;
import dmd.mtype;
import dmd.objc;
import dmd.opover;
+import dmd.optimize;
import dmd.parse;
import dmd.root.complex;
import dmd.root.ctfloat;
@@ -1098,7 +1099,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
if (isRefOrOut && !isAuto &&
!(global.params.previewIn && (fparam.storageClass & STC.in_)) &&
global.params.rvalueRefParam != FeatureState.enabled)
- e = e.toLvalue(sc, e);
+ e = e.toLvalue(sc, "create default argument for `ref` / `out` parameter from");
fparam.defaultArg = e;
return (e.op != EXP.error);
@@ -3748,7 +3749,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
}
// check before alias resolution; the alias itself might be deprecated!
if (s.isAliasDeclaration)
- e.checkDeprecated(sc, s);
+ s.checkDeprecated(e.loc, sc);
s = s.toAlias();
if (auto em = s.isEnumMember())
@@ -5009,7 +5010,7 @@ RootObject compileTypeMixin(TypeMixin tm, ref const Loc loc, Scope* sc)
const len = buf.length;
buf.writeByte(0);
const str = buf.extractSlice()[0 .. len];
- const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput;
+ const bool doUnittests = global.params.parsingUnittestsRequired();
auto locm = adjustLocForMixin(str, loc, global.params.mixinOut);
scope p = new Parser!ASTCodegen(locm, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests);
p.transitionIn = global.params.v.vin;
diff --git a/gcc/d/dmd/version.h b/gcc/d/dmd/version.h
index 697d46e..c268bc9 100644
--- a/gcc/d/dmd/version.h
+++ b/gcc/d/dmd/version.h
@@ -20,7 +20,6 @@ public:
DebugSymbol *syntaxCopy(Dsymbol *) override;
const char *toChars() const override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
const char *kind() const override;
DebugSymbol *isDebugSymbol() override;
void accept(Visitor *v) override { v->visit(this); }
@@ -34,7 +33,6 @@ public:
VersionSymbol *syntaxCopy(Dsymbol *) override;
const char *toChars() const override;
- void addMember(Scope *sc, ScopeDsymbol *sds) override;
const char *kind() const override;
VersionSymbol *isVersionSymbol() override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index 3d8c3e6..360784a 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -176,6 +176,7 @@ class NewDeclaration;
class Initializer;
class VoidInitializer;
+class DefaultInitializer;
class ErrorInitializer;
class StructInitializer;
class ArrayInitializer;
@@ -591,6 +592,7 @@ public:
virtual void visit(StructInitializer *i) { visit((Initializer *)i); }
virtual void visit(ArrayInitializer *i) { visit((Initializer *)i); }
virtual void visit(VoidInitializer *i) { visit((Initializer *)i); }
+ virtual void visit(DefaultInitializer *i) { visit((Initializer *)i); }
virtual void visit(CInitializer *i) { visit((Initializer *)i); }
};
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 17801a3..a907979 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -789,42 +789,58 @@ public:
void visit (CatAssignExp *e) final override
{
+ if (!global.params.useGC)
+ {
+ error_at (make_location_t (e->loc),
+ "appending to array in %qs requires the GC and cannot be "
+ "used with %<-fno-druntime%>", e->toChars ());
+ this->result_ = error_mark_node;
+ return;
+ }
+
Type *tb1 = e->e1->type->toBasetype ();
Type *tb2 = e->e2->type->toBasetype ();
- Type *etype = tb1->nextOf ()->toBasetype ();
-
- /* Save the address of `e1', so it can be evaluated first.
- As all D run-time library functions for concat assignments update `e1'
- in-place and then return its value, the saved address can also be used as
- the result of this expression as well. */
- tree lhs = build_expr (e->e1);
- tree lexpr = stabilize_expr (&lhs);
- tree ptr = d_save_expr (build_address (lhs));
- tree result = NULL_TREE;
- if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
- && (etype->ty == TY::Tchar || etype->ty == TY::Twchar))
+ if (e->op == EXP::concatenateDcharAssign)
{
/* Append a dchar to a char[] or wchar[]:
The assignment is handled by the D run-time library, so only
need to call `_d_arrayappend[cw]d(&e1, e2)' */
+ Type *etype = tb1->nextOf ()->toBasetype ();
+
+ /* Save the address of `e1', so it can be evaluated first.
+ As all D run-time library functions for concat assignments update
+ `e1' in-place and then return its value, the saved address can also
+ be used as the result of this expression as well. */
+ tree lhs = build_expr (e->e1);
+ tree lexpr = stabilize_expr (&lhs);
+ tree ptr = d_save_expr (build_address (lhs));
+ tree result = NULL_TREE;
+
+ gcc_assert (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
+ && (etype->ty == TY::Tchar || etype->ty == TY::Twchar));
+
libcall_fn libcall = (etype->ty == TY::Tchar)
? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
result = build_libcall (libcall, e->type, 2,
ptr, build_expr (e->e2));
+
+ /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
+ result = compound_expr (compound_expr (lexpr, ptr), result);
+ this->result_ = compound_expr (result, build_deref (ptr));
}
else
{
+ gcc_assert (e->op == EXP::concatenateAssign
+ || e->op == EXP::concatenateElemAssign);
+ gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
/* Appending an element or array to another array has already been
handled by the front-end. */
- gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
- gcc_unreachable ();
- }
+ gcc_assert (e->lowering);
- /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
- result = compound_expr (compound_expr (lexpr, ptr), result);
- this->result_ = compound_expr (result, build_deref (ptr));
+ this->result_ = build_expr (e->lowering);
+ }
}
/* Build an assignment expression. The right operand is implicitly
@@ -2359,50 +2375,9 @@ public:
/* Allocating memory for a new D array. */
gcc_assert (e->arguments && e->arguments->length >= 1);
- if (e->arguments->length == 1)
- {
- /* Single dimension array allocations has already been handled by
- the front-end. */
- gcc_assert (e->lowering);
- result = build_expr (e->lowering);
- }
- else
- {
- /* Multidimensional array allocations. */
- tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
- tree var = build_local_temp (tarray);
- vec <constructor_elt, va_gc> *elms = NULL;
-
- /* Get the base element type for the array, generating the
- initializer for the dims parameter along the way. */
- Type *telem = e->newtype->toBasetype ();
- for (size_t i = 0; i < e->arguments->length; i++)
- {
- Expression *arg = (*e->arguments)[i];
- CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
-
- gcc_assert (telem->ty == TY::Tarray);
- telem = telem->toBasetype ()->nextOf ();
- gcc_assert (telem);
- }
-
- /* Initialize the temporary. */
- tree init = modify_expr (var, build_constructor (tarray, elms));
- var = compound_expr (init, var);
-
- /* Generate: _d_newarraymTX(ti, dims)
- or: _d_newarraymiTX(ti, dims) */
- libcall_fn libcall = telem->isZeroInit ()
- ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
-
- tree tinfo = build_typeinfo (e, e->type);
- tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
- size_int (e->arguments->length),
- build_address (var));
-
- result = build_libcall (libcall, e->newtype->toBasetype (), 2,
- tinfo, dims);
- }
+ /* Array allocations have already been handled by the front-end. */
+ gcc_assert (e->lowering != NULL);
+ result = build_expr (e->lowering);
if (e->argprefix)
result = compound_expr (build_expr (e->argprefix), result);
diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def
index f7887e1..3307b3b 100644
--- a/gcc/d/runtime.def
+++ b/gcc/d/runtime.def
@@ -70,13 +70,6 @@ DEF_D_RUNTIME (DYNAMIC_CAST, "_d_dynamic_cast", RT(OBJECT),
DEF_D_RUNTIME (INTERFACE_CAST, "_d_interface_cast", RT(OBJECT),
P2(OBJECT, CLASSINFO), 0)
-/* Used when calling `new' on a multi-dimensional array.
- The `i' variant is for when the initializer is nonzero. */
-DEF_D_RUNTIME (NEWARRAYMTX, "_d_newarraymTX", RT(ARRAY_VOID),
- P2(CONST_TYPEINFO, ARRAY_SIZE_T), 0)
-DEF_D_RUNTIME (NEWARRAYMITX, "_d_newarraymiTX", RT(ARRAY_VOID),
- P2(CONST_TYPEINFO, ARRAY_SIZE_T), 0)
-
/* Used for allocating an array literal on the GC heap. */
DEF_D_RUNTIME (ARRAYLITERALTX, "_d_arrayliteralTX", RT(VOIDPTR),
P2(CONST_TYPEINFO, SIZE_T), 0)
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 04f357c..7bfe72b 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -3199,6 +3199,8 @@ directive}: @samp{#if}, @samp{#ifdef} or @samp{#ifndef}.
* @code{__has_cpp_attribute}::
* @code{__has_c_attribute}::
* @code{__has_builtin}::
+* @code{__has_feature}::
+* @code{__has_extension}::
* @code{__has_include}::
@end menu
@@ -3561,6 +3563,45 @@ the operator is as follows:
#endif
@end smallexample
+@node @code{__has_feature}
+@subsection @code{__has_feature}
+@cindex @code{__has_feature}
+
+The special operator @code{__has_feature (@var{operand})} may be used in
+constant integer contexts and in preprocessor @samp{#if} and @samp{#elif}
+expressions to test whether the identifier given in @var{operand} is recognized
+as a feature supported by GCC given the current options and, in the case of
+standard language features, whether the feature is available in the chosen
+version of the language standard.
+
+Note that @code{__has_feature} and @code{__has_extension} are not recommended
+for use in new code, and are only provided for compatibility with Clang. For
+details of which identifiers are accepted by these function-like macros, see
+@w{@uref{https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension,
+the Clang documentation}}.
+
+@node @code{__has_extension}
+@subsection @code{__has_extension}
+@cindex @code{__has_extension}
+
+The special operator @code{__has_extension (@var{operand})} may be used in
+constant integer contexts and in preprocessor @samp{#if} and @samp{#elif}
+expressions to test whether the identifier given in @var{operand} is recognized
+as an extension supported by GCC given the current options. In any given
+context, the features accepted by @code{__has_extension} are a strict superset
+of those accepted by @code{__has_feature}. Unlike @code{__has_feature},
+@code{__has_extension} tests whether a given feature is available regardless of
+strict language standards conformance.
+
+If the @option{-pedantic-errors} flag is given, @code{__has_extension} is
+equivalent to @code{__has_feature}.
+
+Note that @code{__has_feature} and @code{__has_extension} are not recommended
+for use in new code, and are only provided for compatibility with Clang. For
+details of which identifiers are accepted by these function-like macros, see
+@w{@uref{https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension,
+the Clang documentation}}.
+
@node @code{__has_include}
@subsection @code{__has_include}
@cindex @code{__has_include}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8293a7b..1ae589a 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7341,6 +7341,21 @@ Enable/disable the generation of the SM4 instructions.
@itemx no-usermsr
Enable/disable the generation of the USER_MSR instructions.
+@cindex @code{target("avx10.1")} function attribute, x86
+@item avx10.1
+@itemx no-avx10.1
+Enable/disable the generation of the AVX10.1 instructions.
+
+@cindex @code{target("avx10.1-256")} function attribute, x86
+@item avx10.1-256
+@itemx no-avx10.1-256
+Enable/disable the generation of the AVX10.1 instructions.
+
+@cindex @code{target("avx10.1-512")} function attribute, x86
+@item avx10.1-512
+@itemx no-avx10.1-512
+Enable/disable the generation of the AVX10.1 512 bit instructions.
+
@cindex @code{target("cld")} function attribute, x86
@item cld
@itemx no-cld
@@ -10914,6 +10929,11 @@ sign flag set
``not'' @var{flag}, or inverted versions of those above
@end table
+@item s390
+The flag output constraint for s390 is @samp{=@@cc}. Only one such
+constraint is allowed. The variable has to be stored in a @samp{int}
+variable.
+
@end table
@anchor{InputOperands}
@@ -14731,11 +14751,11 @@ The @code{__builtin_classify_type} returns a small integer with a category
of @var{arg} argument's type, like void type, integer type, enumeral type,
boolean type, pointer type, reference type, offset type, real type, complex
type, function type, method type, record type, union type, array type,
-string type, etc. When the argument is an expression, for
-backwards compatibility reason the argument is promoted like arguments
-passed to @code{...} in varargs function, so some classes are never returned
-in certain languages. Alternatively, the argument of the built-in
-function can be a typename, such as the @code{typeof} specifier.
+string type, bit-precise integer type, vector type, etc. When the argument
+is an expression, for backwards compatibility reason the argument is promoted
+like arguments passed to @code{...} in varargs function, so some classes are
+never returned in certain languages. Alternatively, the argument of the
+built-in function can be a typename, such as the @code{typeof} specifier.
@smallexample
int a[2];
@@ -15060,6 +15080,125 @@ unsigned integer (standard, extended or bit-precise). No integral argument
promotions are performed on the argument.
@enddefbuiltin
+@defbuiltin{@var{type} __builtin_stdc_bit_ceil (@var{type} @var{arg})}
+The @code{__builtin_stdc_bit_ceil} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{@var{arg} <= 1 ? (@var{type}) 1
+: (@var{type}) 2 << (@var{prec} - 1 - __builtin_clzg ((@var{type}) (@var{arg} - 1)))}
+where @var{prec} is bit width of @var{type}, except that side-effects
+in @var{arg} are evaluated just once.
+@enddefbuiltin
+
+@defbuiltin{@var{type} __builtin_stdc_bit_floor (@var{type} @var{arg})}
+The @code{__builtin_stdc_bit_floor} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{@var{arg} == 0 ? (@var{type}) 0
+: (@var{type}) 1 << (@var{prec} - 1 - __builtin_clzg (@var{arg}))}
+where @var{prec} is bit width of @var{type}, except that side-effects
+in @var{arg} are evaluated just once.
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_bit_width (@var{type} @var{arg})}
+The @code{__builtin_stdc_bit_width} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(unsigned int) (@var{prec} - __builtin_clzg (@var{arg}, @var{prec}))}
+where @var{prec} is bit width of @var{type}.
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_count_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_count_ones} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(unsigned int) __builtin_popcountg (@var{arg})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_count_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_count_zeros} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(unsigned int) __builtin_popcountg ((@var{type}) ~@var{arg})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_leading_one (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_leading_one} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{__builtin_clzg (@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_leading_zero (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_leading_zero} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{__builtin_clzg ((@var{type}) ~@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_trailing_one (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_trailing_one} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{__builtin_ctzg (@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_trailing_zero (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_trailing_zero} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{__builtin_ctzg ((@var{type}) ~@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_has_single_bit (@var{type} @var{arg})}
+The @code{__builtin_stdc_has_single_bit} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(_Bool) (__builtin_popcountg (@var{arg}) == 1)}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_leading_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_leading_ones} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(unsigned int) __builtin_clzg ((@var{type}) ~@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_leading_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_leading_zeros} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(unsigned int) __builtin_clzg (@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_trailing_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_trailing_ones} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(unsigned int) __builtin_ctzg ((@var{type}) ~@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_trailing_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_trailing_zeros} function is available only
+in C. It is type-generic, the argument can be any unsigned integer
+(standard, extended or bit-precise). No integral argument promotions are
+performed on the argument. It is equivalent to
+@code{(unsigned int) __builtin_ctzg (@var{arg}, @var{prec})}
+@enddefbuiltin
+
@defbuiltin{double __builtin_powi (double, int)}
@defbuiltinx{float __builtin_powif (float, int)}
@defbuiltinx{{long double} __builtin_powil (long double, int)}
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index f995b77..c1ccb8b 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -628,9 +628,9 @@ HTTPS as tarballs compressed with @command{gzip} or @command{bzip2}.
Please refer to the @uref{https://gcc.gnu.org/releases.html,,releases web page}
for information on how to obtain GCC@.
-The source distribution includes the C, C++, Objective-C, Fortran,
-and Ada (in the case of GCC 3.1 and later) compilers, as well as
-runtime libraries for C++, Objective-C, and Fortran.
+The source distribution includes the Ada, C, C++, Objective-C, D (GCC 9
+and later), Fortran, Go, and Modula-2 (GCC 13 and later) compilers, as
+well as runtime libraries for C++, Objective-C, and Fortran.
For previous versions these were downloadable as separate components such
as the core GCC distribution, which included the C language front end and
shared components, and language-specific distributions including the
@@ -3991,7 +3991,7 @@ Instead of GNU Binutils, you will need to install LLVM 13.0.1, or later, and cop
Use Newlib (4.3.0 or newer).
To run the binaries, install the HSA Runtime from the
-@uref{https://rocm.github.io,,ROCm Platform}, and use
+@uref{https://rocm.docs.amd.com/,,ROCm Platform}, and use
@file{libexec/gcc/amdhsa-amdhsa/@var{version}/gcn-run} to launch them
on the GPU.
@@ -3999,7 +3999,7 @@ To enable support for GCN3 Fiji devices (gfx803), GCC has to be configured with
@option{--with-arch=@code{fiji}} or
@option{--with-multilib-list=@code{fiji},...}. Note that support for Fiji
devices has been removed in ROCm 4.0 and support in LLVM is deprecated and will
-be removed in the future.
+be removed in LLVM 18.
@html
<hr />
@@ -4126,14 +4126,6 @@ This configuration is intended for embedded systems.
@end html
@anchor{x-x-freebsd}
@heading *-*-freebsd*
-In order to better utilize FreeBSD base system functionality and match
-the configuration of the system compiler, GCC 4.5 and above as well as
-GCC 4.4 past 2010-06-20 leverage SSP support in libc (which is present
-on FreeBSD 7 or later) and the use of @code{__cxa_atexit} by default
-(on FreeBSD 6 or later). The use of @code{dl_iterate_phdr} inside
-@file{libgcc_s.so.1} and boehm-gc (on FreeBSD 7 or later) is enabled
-by GCC 4.5 and above.
-
We support FreeBSD using the ELF file format with DWARF 2 debugging
for all CPU architectures. There are
no known issues with mixing object files and libraries with different
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1f10967..2e6bac3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -366,7 +366,7 @@ Objective-C and Objective-C++ Dialects}.
-Wformat-y2k -Wframe-address
-Wframe-larger-than=@var{byte-size} -Wno-free-nonheap-object
-Wno-if-not-aligned -Wno-ignored-attributes
--Wignored-qualifiers -Wno-incompatible-pointer-types
+-Wignored-qualifiers -Wno-incompatible-pointer-types -Whardened
-Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n}
-Wno-implicit-function-declaration -Wno-implicit-int
-Winfinite-recursion
@@ -383,7 +383,7 @@ Objective-C and Objective-C++ Dialects}.
-Wnormalized=@r{[}none@r{|}id@r{|}nfc@r{|}nfkc@r{]}
-Wnull-dereference -Wno-odr
-Wopenacc-parallelism
--Wopenmp-simd
+-Wopenmp -Wopenmp-simd
-Wno-overflow -Woverlength-strings -Wno-override-init-side-effects
-Wpacked -Wno-packed-bitfield-compat -Wpacked-not-aligned -Wpadded
-Wparentheses -Wno-pedantic-ms-format
@@ -644,7 +644,7 @@ Objective-C and Objective-C++ Dialects}.
-fasan-shadow-offset=@var{number} -fsanitize-sections=@var{s1},@var{s2},...
-fsanitize-undefined-trap-on-error -fbounds-check
-fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]}
--fharden-compares -fharden-conditional-branches
+-fharden-compares -fharden-conditional-branches -fhardened
-fharden-control-flow-redundancy -fhardcfr-skip-leaf
-fhardcfr-check-exceptions -fhardcfr-check-returning-calls
-fhardcfr-check-noreturn-calls=@r{[}always@r{|}no-xthrow@r{|}nothrow@r{|}never@r{]}
@@ -1245,6 +1245,7 @@ See RS/6000 and PowerPC Options.
-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg}
-mstack-protector-guard-offset=@var{offset}
-mcsr-check -mno-csr-check
+-mmovcc -mno-movcc
-minline-atomics -mno-inline-atomics
-minline-strlen -mno-inline-strlen
-minline-strcmp -mno-inline-strcmp
@@ -1453,7 +1454,7 @@ See RS/6000 and PowerPC Options.
-mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni
-mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16
-mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4 -mapxf
--musermsr
+-musermsr -mavx10.1 -mavx10.1-256 -mavx10.1-512
-mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops
-minline-stringops-dynamically -mstringop-strategy=@var{alg}
-mkl -mwidekl
@@ -6872,6 +6873,18 @@ This warning is upgraded to an error by @option{-pedantic-errors}.
Same as @option{-Wimplicit-int} and @option{-Wimplicit-function-declaration}.
This warning is enabled by @option{-Wall}.
+@opindex Whardened
+@opindex Wno-hardened
+@item -Whardened
+Warn when @option{-fhardened} did not enable an option from its set (for
+which see @option{-fhardened}). For instance, using @option{-fhardened}
+and @option{-fstack-protector} at the same time on the command line causes
+@option{-Whardened} to warn because @option{-fstack-protector-strong} is
+not enabled by @option{-fhardened}.
+
+This warning is enabled by default and has effect only when @option{-fhardened}
+is enabled.
+
@opindex Wimplicit-fallthrough
@opindex Wno-implicit-fallthrough
@item -Wimplicit-fallthrough
@@ -8093,7 +8106,7 @@ if the array is referenced as a flexible array member.
@opindex Wsuggest-attribute=
@opindex Wno-suggest-attribute=
-@item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]}
+@item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]}returns_nonnull@r{|}
Warn for cases where adding an attribute may be beneficial. The
attributes currently supported are listed below.
@@ -8113,9 +8126,11 @@ attributes currently supported are listed below.
@itemx -Wsuggest-attribute=noreturn
@itemx -Wmissing-noreturn
@itemx -Wsuggest-attribute=malloc
+@itemx -Wsuggest-attribute=returns_nonnull
+@itemx -Wno-suggest-attribute=returns_nonnull
Warn about functions that might be candidates for attributes
-@code{pure}, @code{const} or @code{noreturn} or @code{malloc}. The compiler
+@code{pure}, @code{const}, @code{noreturn}, @code{malloc} or @code{returns_nonnull}. The compiler
only warns for functions visible in other compilation units or (in the case of
@code{pure} and @code{const}) if it cannot prove that the function returns
normally. A function returns normally if it doesn't contain an infinite loop or
@@ -9104,6 +9119,13 @@ Do not warn about C++23 constructs in code being compiled using
an older C++ standard. Even without this option, some C++23 constructs
will only be diagnosed if @option{-Wpedantic} is used.
+@opindex Wc++26-extensions
+@opindex Wno-c++26-extensions
+@item -Wno-c++26-extensions @r{(C++ and Objective-C++ only)}
+Do not warn about C++26 constructs in code being compiled using
+an older C++ standard. Even without this option, some C++26 constructs
+will only be diagnosed if @option{-Wpedantic} is used.
+
@opindex Wcast-qual
@opindex Wno-cast-qual
@item -Wcast-qual
@@ -9935,6 +9957,11 @@ Enabled by default.
@item -Wopenacc-parallelism
Warn about potentially suboptimal choices related to OpenACC parallelism.
+@opindex Wopenmp
+@opindex Wno-openmp
+@item -Wno-openmp
+Warn about suspicious OpenMP code.
+
@opindex Wopenmp-simd
@opindex Wno-openmp-simd
@item -Wopenmp-simd
@@ -17628,6 +17655,39 @@ made @option{no-xthrow} the default setting for this option: it excludes
from the @code{noreturn} treatment only internal functions used to
(re)raise exceptions, that are not affected by these optimizations.
+@opindex fhardened
+@item -fhardened
+Enable a set of flags for C and C++ that improve the security of the
+generated code without affecting its ABI. The precise flags enabled
+may change between major releases of GCC, but are currently:
+
+@c Keep this in sync with print_help_hardened!
+@gccoptlist{
+-D_FORTIFY_SOURCE=3
+-D_GLIBCXX_ASSERTIONS
+-ftrivial-auto-var-init=zero
+-fPIE -pie -Wl,-z,relro,-z,now
+-fstack-protector-strong
+-fstack-clash-protection
+-fcf-protection=full @r{(x86 GNU/Linux only)}
+}
+
+The list of options enabled by @option{-fhardened} can be generated using
+the @option{--help=hardened} option.
+
+When the system glibc is older than 2.35, @option{-D_FORTIFY_SOURCE=2}
+is used instead.
+
+This option is intended to be used in production builds, not merely
+in debug builds.
+
+Currently, @option{-fhardened} is only supported on GNU/Linux targets.
+
+@option{-fhardened} only enables a particular option if it wasn't
+already specified anywhere on the command line. For instance,
+@option{-fhardened} @option{-fstack-protector} will only enable
+@option{-fstack-protector}, but not @option{-fstack-protector-strong}.
+
@opindex fstack-protector
@item -fstack-protector
Emit extra code to check for buffer overflows, such as stack smashing
@@ -29587,9 +29647,10 @@ conventions are: @samp{ilp32}, @samp{ilp32f}, @samp{ilp32d}, @samp{lp64},
@samp{lp64f}, and @samp{lp64d}. Some calling conventions are impossible to
implement on some ISAs: for example, @samp{-march=rv32if -mabi=ilp32d} is
invalid because the ABI requires 64-bit values be passed in F registers, but F
-registers are only 32 bits wide. There is also the @samp{ilp32e} ABI that can
-only be used with the @samp{rv32e} architecture. This ABI is not well
-specified at present, and is subject to change.
+registers are only 32 bits wide. There are also the @samp{ilp32e} ABI that can
+only be used with the @samp{rv32e} architecture and the @samp{lp64e} ABI that
+can only be used with the @samp{rv64e}. Those ABIs are not well specified at
+present, and are subject to change.
@opindex mfdiv
@item -mfdiv
@@ -29679,6 +29740,14 @@ Do or don't use smaller but slower prologue and epilogue code that uses
library function calls. The default is to use fast inline prologues and
epilogues.
+@opindex mmovcc
+@item -mmovcc
+@itemx -mno-movcc
+Do or don't produce branchless conditional-move code sequences even with
+targets that do not have specific instructions for conditional operations.
+If enabled, sequences of ALU operations are produced using base integer
+ISA instructions where profitable.
+
@opindex minline-atomics
@item -minline-atomics
@itemx -mno-inline-atomics
@@ -34123,6 +34192,15 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@need 200
@opindex musermsr
@itemx -musermsr
+@need 200
+@opindex mavx10.1
+@itemx -mavx10.1
+@need 200
+@opindex mavx10.1-256
+@itemx -mavx10.1-256
+@need 200
+@opindex mavx10.1-512
+@itemx -mavx10.1-512
These switches enable the use of instructions in the MMX, SSE,
AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA,
AES, PCLMUL, CLFLUSHOPT, CLWB, FSGSBASE, PTWRITE, RDRND, F16C, FMA, PCONFIG,
@@ -34133,9 +34211,9 @@ GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16,
ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE,
UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16,
AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AMX-FP16, PREFETCHI, RAOINT,
-AMX-COMPLEX, AVXVNNIINT16, SM3, SHA512, SM4, APX_F, USER_MSR or CLDEMOTE
-extended instruction sets. Each has a corresponding @option{-mno-} option
-to disable use of these instructions.
+AMX-COMPLEX, AVXVNNIINT16, SM3, SHA512, SM4, APX_F, USER_MSR, AVX10.1 or
+CLDEMOTE extended instruction sets. Each has a corresponding @option{-mno-}
+option to disable use of these instructions.
These extensions are also available as built-in functions: see
@ref{x86 Built-in Functions}, for details of the functions enabled and
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index e01cdcb..536ce99 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -4516,8 +4516,8 @@ Register constraints correspond directly to register classes.
@xref{Register Classes}. There is thus not much flexibility in their
definitions.
-@deffn {MD Expression} define_register_constraint name regclass docstring
-All three arguments are string constants.
+@deffn {MD Expression} define_register_constraint name regclass docstring [filter]
+All arguments are string constants.
@var{name} is the name of the constraint, as it will appear in
@code{match_operand} expressions. If @var{name} is a multi-letter
constraint its length shall be the same for all constraints starting
@@ -4529,6 +4529,43 @@ look at the operand. The usual use of expressions is to map some
register constraints to @code{NO_REGS} when the register class
is not available on a given subarchitecture.
+If an operand occupies multiple hard registers, the constraint
+requires all of those registers to belong to @var{regclass}.
+For example, if @var{regclass} is @code{GENERAL_REGS} and
+@code{GENERAL_REGS} contains registers @code{r0} to @code{r15},
+the constraint does not allow @var{r15} to be used for modes
+that occupy more than one register.
+
+@cindex @code{TARGET_HARD_REGNO_MODE_OK} and constraints
+The choice of register is also constrained by @code{TARGET_HARD_REGNO_MODE_OK}.
+For example, if @code{TARGET_HARD_REGNO_MODE_OK} disallows @samp{(reg:DI r1)},
+that requirement applies to all constraints whose classes include @code{r1}.
+
+However, it is sometimes useful to impose extra operand-specific
+requirements on the register number. For example, a target might not
+want to prevent @emph{all} odd-even pairs from holding @code{DImode}
+values, but it might still need to prevent specific operands from
+having an odd-numbered register. The optional @var{filter} argument
+exists for such cases. When given, @var{filter} is a C++ expression
+that evaluates to true if @code{regno} is a valid register for the
+operand. If an operand occupies multiple registers, the condition
+applies only to the first register.
+
+For example:
+
+@smallexample
+(define_register_constraint "e" "GENERAL_REGS" "..." "regno % 2 == 0")
+@end smallexample
+
+defines a constraint that requires an even-numbered general register.
+
+Filter conditions that impose an alignment are encouraged to test
+the alignment of @code{regno} itself, as in the example, rather than
+calculate an offset relative to the start of the class. If it is
+sometimes necessary for a register of class @var{c} to be aligned
+to @var{n}, the first register in @var{c} should itself by divisible
+by @var{n}.
+
@var{docstring} is a sentence documenting the meaning of the
constraint. Docstrings are explained further below.
@end deffn
@@ -6878,8 +6915,9 @@ individually copied data units in the block.
The @code{cpymem@var{m}} patterns need not give special consideration
to the possibility that the source and destination strings might
-overlap. These patterns are used to do inline expansion of
-@code{__builtin_memcpy}.
+overlap. An exception is the case where source and destination are
+equal, this case needs to be handled correctly.
+These patterns are used to do inline expansion of @code{__builtin_memcpy}.
@cindex @code{movmem@var{m}} instruction pattern
@item @samp{movmem@var{m}}
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index eaa75f0..e27e0fa 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2496,6 +2496,15 @@ Target supports compiling @code{avx} instructions.
@item avx_runtime
Target supports the execution of @code{avx} instructions.
+@item avx10.1
+Target supports the execution of @code{avx10.1} instructions.
+
+@item avx10.1-256
+Target supports the execution of @code{avx10.1} instructions.
+
+@item avx10.1-512
+Target supports the execution of @code{avx10.1-512} instructions.
+
@item avx2
Target supports compiling @code{avx2} instructions.
diff --git a/gcc/doc/standards.texi b/gcc/doc/standards.texi
index 4eb43f1..4b18fa9 100644
--- a/gcc/doc/standards.texi
+++ b/gcc/doc/standards.texi
@@ -184,7 +184,9 @@ GNU C library). @xref{Standard Libraries,,Standard Libraries}.
Most of the compiler support routines used by GCC are present in
@file{libgcc}, but there are a few exceptions. GCC requires the
freestanding environment provide @code{memcpy}, @code{memmove},
-@code{memset} and @code{memcmp}.
+@code{memset} and @code{memcmp}. Contrary to the standards
+covering @code{memcpy} GCC expects the case of an exact overlap
+of source and destination to work and not invoke undefined behavior.
Finally, if @code{__builtin_trap} is used, and the target does
not implement the @code{trap} pattern, then GCC emits a call
to @code{abort}.
@@ -238,7 +240,7 @@ new specification. For further details see
To select this standard in GCC, use the option @option{-std=c++20}.
More information about the C++ standards is available on the ISO C++
-committee's web site at @uref{http://www.open-std.org/@/jtc1/@/sc22/@/wg21/}.
+committee's web site at @uref{https://www.open-std.org/@/jtc1/@/sc22/@/wg21/}.
To obtain all the diagnostics required by any of the standard versions
described above you should specify @option{-pedantic}
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index dcf7735..c0f949b 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2478,7 +2478,8 @@ When a value occupying several consecutive registers is expected in a
certain class, all the registers used must belong to that class.
Therefore, register classes cannot be used to enforce a requirement for
a register pair to start with an even-numbered register. The way to
-specify this requirement is with @code{TARGET_HARD_REGNO_MODE_OK}.
+specify this requirement is with @code{TARGET_HARD_REGNO_MODE_OK},
+or with a filter expression in a @code{define_register_constraint}.
Register classes used for input-operands of bitwise-and or shift
instructions have a special requirement: each such class must have, for
@@ -5822,6 +5823,11 @@ This hook determines whether a function from a class of functions
@code{(enum function_class)}@var{fcode} has a fast implementation.
@end deftypefn
+@deftypefn {Target Hook} unsigned TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL (void)
+This hook determines what value _FORTIFY_SOURCE will be set to when using
+the command-line option -fhardened.
+@end deftypefn
+
@deftypefn {Target Hook} unsigned TARGET_LIBM_FUNCTION_MAX_ERROR (unsigned @var{cfn}, machine_mode @var{mode}, bool @var{boundary_p})
This hook determines expected maximum errors for math functions measured
in ulps (units of the last place). 0 means 0.5ulps precision (correctly
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index b61a59f..ef04c89 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2060,7 +2060,8 @@ When a value occupying several consecutive registers is expected in a
certain class, all the registers used must belong to that class.
Therefore, register classes cannot be used to enforce a requirement for
a register pair to start with an even-numbered register. The way to
-specify this requirement is with @code{TARGET_HARD_REGNO_MODE_OK}.
+specify this requirement is with @code{TARGET_HARD_REGNO_MODE_OK},
+or with a filter expression in a @code{define_register_constraint}.
Register classes used for input-operands of bitwise-and or shift
instructions have a special requirement: each such class must have, for
@@ -4043,6 +4044,8 @@ macro, a reasonable default is used.
@hook TARGET_LIBC_HAS_FAST_FUNCTION
+@hook TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL
+
@hook TARGET_LIBM_FUNCTION_MAX_ERROR
@defmac NEXT_OBJC_RUNTIME
diff --git a/gcc/dse.cc b/gcc/dse.cc
index 1a85dae..40c4c29 100644
--- a/gcc/dse.cc
+++ b/gcc/dse.cc
@@ -1900,8 +1900,11 @@ get_stored_val (store_info *store_info, machine_mode read_mode,
else
gap = read_offset - store_info->offset;
- if (gap.is_constant () && maybe_ne (gap, 0))
+ if (maybe_ne (gap, 0))
{
+ if (!gap.is_constant ())
+ return NULL_RTX;
+
poly_int64 shift = gap * BITS_PER_UNIT;
poly_int64 access_size = GET_MODE_SIZE (read_mode) + gap;
read_reg = find_shift_sequence (access_size, store_info, read_mode,
@@ -1940,6 +1943,10 @@ get_stored_val (store_info *store_info, machine_mode read_mode,
|| GET_MODE_CLASS (read_mode) != GET_MODE_CLASS (store_mode)))
read_reg = extract_low_bits (read_mode, store_mode,
copy_rtx (store_info->const_rhs));
+ else if (VECTOR_MODE_P (read_mode) && VECTOR_MODE_P (store_mode)
+ && known_le (GET_MODE_BITSIZE (read_mode), GET_MODE_BITSIZE (store_mode))
+ && targetm.modes_tieable_p (read_mode, store_mode))
+ read_reg = gen_lowpart (read_mode, copy_rtx (store_info->rhs));
else
read_reg = extract_low_bits (read_mode, store_mode,
copy_rtx (store_info->rhs));
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 556bcf7..c432170 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -1090,18 +1090,16 @@ by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
unsigned HOST_WIDE_INT n_insns = 0;
fixed_size_mode mode;
- if (targetm.overlap_op_by_pieces_p () && op != COMPARE_BY_PIECES)
+ if (targetm.overlap_op_by_pieces_p ())
{
/* NB: Round up L and ALIGN to the widest integer mode for
MAX_SIZE. */
mode = widest_fixed_size_mode_for_size (max_size, op);
- if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
- {
- unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
- if (up > l)
- l = up;
- align = GET_MODE_ALIGNMENT (mode);
- }
+ gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
+ unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
+ if (up > l)
+ l = up;
+ align = GET_MODE_ALIGNMENT (mode);
}
align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
@@ -1109,12 +1107,11 @@ by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
while (max_size > 1 && l > 0)
{
mode = widest_fixed_size_mode_for_size (max_size, op);
- enum insn_code icode;
+ gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
unsigned int modesize = GET_MODE_SIZE (mode);
- icode = optab_handler (mov_optab, mode);
- if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
+ if (align >= GET_MODE_ALIGNMENT (mode))
{
unsigned HOST_WIDE_INT n_pieces = l / modesize;
l %= modesize;
@@ -10698,6 +10695,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
&& mode != BLKmode \
&& modifier != EXPAND_MEMORY \
&& modifier != EXPAND_WRITE \
+ && modifier != EXPAND_INITIALIZER \
&& modifier != EXPAND_CONST_ADDRESS) \
? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 686c771..21c5f2a 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,33 @@
+2023-11-26 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/111880
+ * resolve.cc (resolve_common_vars): Do not call gfc_add_in_common
+ for symbols that are USE associated or used in a submodule.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * lang.opt (Wopenmp): Add, enabled by dafault and documented in C.
+ * openmp.cc (gfc_match_omp_declare_target, resolve_positive_int_expr,
+ resolve_nonnegative_int_expr, resolve_omp_clauses,
+ gfc_resolve_omp_do_blocks): Use OPT_Wopenmp with gfc_warning{,_now}.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * openmp.cc (gfc_match_omp_depobj): Accept optionally an argument
+ to the destroy clause.
+
+2023-11-23 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/112609
+ * check.cc (gfc_check_system_clock): Add checks on integer arguments
+ to SYSTEM_CLOCK specific to F2023.
+ * error.cc (notify_std_msg): Adjust to handle new features added
+ in F2023.
+ * gfortran.texi (_gfortran_set_options): Document GFC_STD_F2023_DEL,
+ remove obsolete option GFC_STD_F2008_TS and fix enumeration values.
+ * libgfortran.h (GFC_STD_F2023_DEL): Add and use in GFC_STD_OPT_F23.
+ * options.cc (set_default_std_flags): Add GFC_STD_F2023_DEL.
+
2023-11-17 Tobias Burnus <tobias@codesourcery.com>
* gfortran.texi (_gfortran_set_options): Document GFC_STD_F2023.
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 6c45e65..3b1a0f9 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -6774,6 +6774,8 @@ bool
gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate,
gfc_expr *count_max)
{
+ int first_int_kind = -1;
+
if (count != NULL)
{
if (!scalar_check (count, 0))
@@ -6788,8 +6790,17 @@ gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate,
&count->where))
return false;
+ if (count->ts.kind < gfc_default_integer_kind
+ && !gfc_notify_std (GFC_STD_F2023_DEL,
+ "COUNT argument to SYSTEM_CLOCK at %L "
+ "with kind smaller than default integer",
+ &count->where))
+ return false;
+
if (!variable_check (count, 0, false))
return false;
+
+ first_int_kind = count->ts.kind;
}
if (count_rate != NULL)
@@ -6816,6 +6827,16 @@ gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate,
"SYSTEM_CLOCK at %L has non-default kind",
&count_rate->where))
return false;
+
+ if (count_rate->ts.kind < gfc_default_integer_kind
+ && !gfc_notify_std (GFC_STD_F2023_DEL,
+ "COUNT_RATE argument to SYSTEM_CLOCK at %L "
+ "with kind smaller than default integer",
+ &count_rate->where))
+ return false;
+
+ if (first_int_kind < 0)
+ first_int_kind = count_rate->ts.kind;
}
}
@@ -6836,6 +6857,35 @@ gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate,
if (!variable_check (count_max, 2, false))
return false;
+
+ if (count_max->ts.kind < gfc_default_integer_kind
+ && !gfc_notify_std (GFC_STD_F2023_DEL,
+ "COUNT_MAX argument to SYSTEM_CLOCK at %L "
+ "with kind smaller than default integer",
+ &count_max->where))
+ return false;
+
+ if (first_int_kind < 0)
+ first_int_kind = count_max->ts.kind;
+ }
+
+ if (first_int_kind > 0)
+ {
+ if (count_rate
+ && count_rate->ts.type == BT_INTEGER
+ && count_rate->ts.kind != first_int_kind
+ && !gfc_notify_std (GFC_STD_F2023_DEL,
+ "integer arguments to SYSTEM_CLOCK at %L "
+ "with different kind parameters",
+ &count_rate->where))
+ return false;
+
+ if (count_max && count_max->ts.kind != first_int_kind
+ && !gfc_notify_std (GFC_STD_F2023_DEL,
+ "integer arguments to SYSTEM_CLOCK at %L "
+ "with different kind parameters",
+ &count_max->where))
+ return false;
}
return true;
diff --git a/gcc/fortran/error.cc b/gcc/fortran/error.cc
index 2ac51e9..56d2e63 100644
--- a/gcc/fortran/error.cc
+++ b/gcc/fortran/error.cc
@@ -980,7 +980,11 @@ char const*
notify_std_msg(int std)
{
- if (std & GFC_STD_F2018_DEL)
+ if (std & GFC_STD_F2023_DEL)
+ return _("Prohibited in Fortran 2023:");
+ else if (std & GFC_STD_F2023)
+ return _("Fortran 2023:");
+ else if (std & GFC_STD_F2018_DEL)
return _("Fortran 2018 deleted feature:");
else if (std & GFC_STD_F2018_OBS)
return _("Fortran 2018 obsolescent feature:");
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 41857cc..c29cb78 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -3476,13 +3476,13 @@ standard. Possible values are (bitwise or-ed) @code{GFC_STD_F77} (1),
@code{GFC_STD_F95_OBS} (2), @code{GFC_STD_F95_DEL} (4),
@code{GFC_STD_F95} (8), @code{GFC_STD_F2003} (16), @code{GFC_STD_GNU}
(32), @code{GFC_STD_LEGACY} (64), @code{GFC_STD_F2008} (128),
-@code{GFC_STD_F2008_OBS} (256), @code{GFC_STD_F2008_TS} (512),
-@code{GFC_STD_F2018} (1024), @code{GFC_STD_F2018_OBS} (2048),
-@code{GFC_STD=F2018_DEL} (4096), and @code{GFC_STD=F2023} (8192).
+@code{GFC_STD_F2008_OBS} (256), @code{GFC_STD_F2018} (512),
+@code{GFC_STD_F2018_OBS} (1024), @code{GFC_STD_F2018_DEL} (2048),
+@code{GFC_STD_F2023} (4096), and @code{GFC_STD_F2023_DEL} (8192).
Default: @code{GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_F95 |
-GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F2008_TS | GFC_STD_F2008_OBS
+GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F2008_OBS
| GFC_STD_F77 | GFC_STD_F2018 | GFC_STD_F2018_OBS | GFC_STD_F2018_DEL
-| GFC_STD_F2023 | GFC_STD_GNU | GFC_STD_LEGACY}.
+| GFC_STD_F2023 | GFC_STD_F2023_DEL | GFC_STD_GNU | GFC_STD_LEGACY}.
@item @var{option}[1] @tab Standard-warning flag; prints a warning to
standard error. Default: @code{GFC_STD_F95_DEL | GFC_STD_LEGACY}.
@item @var{option}[2] @tab If non zero, enable pedantic checking.
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 08c7539..adcfc28 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -289,6 +289,10 @@ Wopenacc-parallelism
Fortran
; Documented in C
+Wopenmp
+Fortran
+; Documented in C
+
Wopenmp-simd
Fortran
; Documented in C
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index bdddb31..2c71b90 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -20,8 +20,10 @@ along with GCC; see the file COPYING3. If not see
/* Flags to specify which standard/extension contains a feature.
Note that no features were obsoleted nor deleted in F2003 nor in F2023.
+ Nevertheless, some features available in F2018 are prohibited in F2023.
Please remember to keep those definitions in sync with
gfortran.texi. */
+#define GFC_STD_F2023_DEL (1<<13) /* Prohibited in F2023. */
#define GFC_STD_F2023 (1<<12) /* New in F2023. */
#define GFC_STD_F2018_DEL (1<<11) /* Deleted in F2018. */
#define GFC_STD_F2018_OBS (1<<10) /* Obsolescent in F2018. */
@@ -41,12 +43,13 @@ along with GCC; see the file COPYING3. If not see
* are allowed with a certain -std option. */
#define GFC_STD_OPT_F95 (GFC_STD_F77 | GFC_STD_F95 | GFC_STD_F95_OBS \
| GFC_STD_F2008_OBS | GFC_STD_F2018_OBS \
- | GFC_STD_F2018_DEL)
+ | GFC_STD_F2018_DEL | GFC_STD_F2023_DEL)
#define GFC_STD_OPT_F03 (GFC_STD_OPT_F95 | GFC_STD_F2003)
#define GFC_STD_OPT_F08 (GFC_STD_OPT_F03 | GFC_STD_F2008)
#define GFC_STD_OPT_F18 ((GFC_STD_OPT_F08 | GFC_STD_F2018) \
& (~GFC_STD_F2018_DEL))
-#define GFC_STD_OPT_F23 (GFC_STD_OPT_F18 | GFC_STD_F2023)
+#define GFC_STD_OPT_F23 ((GFC_STD_OPT_F18 | GFC_STD_F2023) \
+ & (~GFC_STD_F2023_DEL))
/* Bitmasks for the various FPE that can be enabled. These need to be straight integers
e.g., 8 instead of (1<<3), because they will be included in Fortran source. */
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 2e2e23d..794df19 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "options.h"
#include "gfortran.h"
#include "arith.h"
#include "match.h"
@@ -4731,10 +4732,20 @@ gfc_match_omp_depobj (void)
goto error;
}
}
- else if (gfc_match ("destroy") == MATCH_YES)
+ else if (gfc_match ("destroy ") == MATCH_YES)
{
+ gfc_expr *destroyobj = NULL;
c = gfc_get_omp_clauses ();
c->destroy = true;
+
+ if (gfc_match (" ( %v ) ", &destroyobj) == MATCH_YES)
+ {
+ if (destroyobj->symtree != depobj->symtree)
+ gfc_warning (0, "The same depend object should be used as DEPOBJ "
+ "argument at %L and as DESTROY argument at %L",
+ &depobj->where, &destroyobj->where);
+ gfc_free_expr (destroyobj);
+ }
}
else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_DEPEND), true, false)
!= MATCH_YES)
@@ -5553,8 +5564,9 @@ gfc_match_omp_declare_target (void)
&& !c->lists[OMP_LIST_ENTER]
&& !c->lists[OMP_LIST_TO]
&& !c->lists[OMP_LIST_LINK])
- gfc_warning_now (0, "OMP DECLARE TARGET directive at %L with only "
- "DEVICE_TYPE clause is ignored", &old_loc);
+ gfc_warning_now (OPT_Wopenmp,
+ "OMP DECLARE TARGET directive at %L with only "
+ "DEVICE_TYPE clause is ignored", &old_loc);
gfc_buffer_error (true);
@@ -7020,7 +7032,8 @@ resolve_positive_int_expr (gfc_expr *expr, const char *clause)
if (expr->expr_type == EXPR_CONSTANT
&& expr->ts.type == BT_INTEGER
&& mpz_sgn (expr->value.integer) <= 0)
- gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
+ gfc_warning ((flag_openmp || flag_openmp_simd) ? OPT_Wopenmp : 0,
+ "INTEGER expression of %s clause at %L must be positive",
clause, &expr->where);
}
@@ -7031,8 +7044,9 @@ resolve_nonnegative_int_expr (gfc_expr *expr, const char *clause)
if (expr->expr_type == EXPR_CONSTANT
&& expr->ts.type == BT_INTEGER
&& mpz_sgn (expr->value.integer) < 0)
- gfc_warning (0, "INTEGER expression of %s clause at %L must be "
- "non-negative", clause, &expr->where);
+ gfc_warning ((flag_openmp || flag_openmp_simd) ? OPT_Wopenmp : 0,
+ "INTEGER expression of %s clause at %L must be non-negative",
+ clause, &expr->where);
}
/* Emits error when symbol is pointer, cray pointer or cray pointee
@@ -7595,8 +7609,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
else if (expr->expr_type == EXPR_CONSTANT
&& expr->ts.type == BT_INTEGER
&& mpz_sgn (expr->value.integer) <= 0)
- gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
- "at %L must be positive", &expr->where);
+ gfc_warning (OPT_Wopenmp, "INTEGER expression of SCHEDULE clause's "
+ "chunk_size at %L must be positive", &expr->where);
}
if (omp_clauses->sched_kind != OMP_SCHED_NONE
&& omp_clauses->sched_nonmonotonic)
@@ -7906,8 +7920,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
}
if (n->sym->mark == 1)
{
- gfc_warning (0, "%qs appears more than once in %<allocate%> "
- "at %L" , n->sym->name, &n->where);
+ gfc_warning (OPT_Wopenmp, "%qs appears more than once in "
+ "%<allocate%> at %L" , n->sym->name, &n->where);
/* We have already seen this variable so it is a duplicate.
Remove it. */
if (prev != NULL && prev->next == n)
@@ -8905,8 +8919,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
&& omp_clauses->num_teams_upper->expr_type == EXPR_CONSTANT
&& mpz_cmp (omp_clauses->num_teams_lower->value.integer,
omp_clauses->num_teams_upper->value.integer) > 0)
- gfc_warning (0, "NUM_TEAMS lower bound at %L larger than upper bound at %L",
- &omp_clauses->num_teams_lower->where,
+ gfc_warning (OPT_Wopenmp, "NUM_TEAMS lower bound at %L larger than upper "
+ "bound at %L", &omp_clauses->num_teams_lower->where,
&omp_clauses->num_teams_upper->where);
if (omp_clauses->device)
resolve_scalar_int_expr (omp_clauses->device, "DEVICE");
@@ -9743,13 +9757,15 @@ gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
else
{
if (block->op == EXEC_OMP_SCAN)
- gfc_warning (0, "!$OMP SCAN at %L with zero executable "
+ gfc_warning (OPT_Wopenmp,
+ "!$OMP SCAN at %L with zero executable "
"statements in preceding structured block "
"sequence", &block->loc);
if ((block->op == EXEC_OMP_SCAN && !block->next)
|| (block->next && block->next->op == EXEC_OMP_SCAN
&& !block->next->next))
- gfc_warning (0, "!$OMP SCAN at %L with zero executable "
+ gfc_warning (OPT_Wopenmp,
+ "!$OMP SCAN at %L with zero executable "
"statements in succeeding structured block "
"sequence", block->op == EXEC_OMP_SCAN
? &block->loc : &block->next->loc);
diff --git a/gcc/fortran/options.cc b/gcc/fortran/options.cc
index b788521..02a29f8 100644
--- a/gcc/fortran/options.cc
+++ b/gcc/fortran/options.cc
@@ -57,8 +57,10 @@ set_default_std_flags (void)
gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
| GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77
| GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY
- | GFC_STD_F2018 | GFC_STD_F2018_DEL | GFC_STD_F2018_OBS | GFC_STD_F2023;
- gfc_option.warn_std = GFC_STD_F2018_DEL | GFC_STD_F95_DEL | GFC_STD_LEGACY;
+ | GFC_STD_F2018 | GFC_STD_F2018_DEL | GFC_STD_F2018_OBS | GFC_STD_F2023
+ | GFC_STD_F2023_DEL;
+ gfc_option.warn_std = GFC_STD_F2018_DEL | GFC_STD_F95_DEL | GFC_STD_LEGACY
+ | GFC_STD_F2023_DEL;
}
/* Set (or unset) the DEC extension flags. */
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 81a1465..166b702 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -986,8 +986,8 @@ resolve_common_vars (gfc_common_head *common_block, bool named_common)
/* gfc_add_in_common may have been called before, but the reported errors
have been ignored to continue parsing.
- We do the checks again here. */
- if (!csym->attr.use_assoc)
+ We do the checks again here, unless the symbol is USE associated. */
+ if (!csym->attr.use_assoc && !csym->attr.used_in_submodule)
{
gfc_add_in_common (&csym->attr, csym->name, &common_block->where);
gfc_notify_std (GFC_STD_F2018_OBS, "COMMON block at %L",
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 51120c1..9f21ad9 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -302,6 +302,13 @@ static size_t dumpdir_length = 0;
driver added to dumpdir after dumpbase or linker output name. */
static bool dumpdir_trailing_dash_added = false;
+/* True if -r, -shared, -pie, or -no-pie were specified on the command
+ line. */
+static bool any_link_options_p;
+
+/* True if -static was specified on the command line. */
+static bool static_p;
+
/* Basename of dump and aux outputs, computed from dumpbase (given or
derived from output name), to override input_basename in non-%w %b
et al. */
@@ -4605,10 +4612,20 @@ driver_handle_option (struct gcc_options *opts,
save_switch ("-o", 1, &arg, validated, true);
return true;
-#ifdef ENABLE_DEFAULT_PIE
case OPT_pie:
+#ifdef ENABLE_DEFAULT_PIE
/* -pie is turned on by default. */
+ validated = true;
#endif
+ case OPT_r:
+ case OPT_shared:
+ case OPT_no_pie:
+ any_link_options_p = true;
+ break;
+
+ case OPT_static:
+ static_p = true;
+ break;
case OPT_static_libgcc:
case OPT_shared_libgcc:
@@ -4984,6 +5001,35 @@ process_command (unsigned int decoded_options_count,
#endif
}
+ /* TODO: check if -static -pie works and maybe use it. */
+ if (flag_hardened)
+ {
+ if (!any_link_options_p && !static_p)
+ {
+#ifdef HAVE_LD_PIE
+ save_switch (LD_PIE_SPEC, 0, NULL, /*validated=*/true, /*known=*/false);
+#endif
+ /* These are passed straight down to collect2 so we have to break
+ it up like this. */
+ if (HAVE_LD_NOW_SUPPORT)
+ {
+ add_infile ("-z", "*");
+ add_infile ("now", "*");
+ }
+ if (HAVE_LD_RELRO_SUPPORT)
+ {
+ add_infile ("-z", "*");
+ add_infile ("relro", "*");
+ }
+ }
+ /* We can't use OPT_Whardened yet. Sigh. */
+ else if (warn_hardened)
+ warning_at (UNKNOWN_LOCATION, 0,
+ "linker hardening options not enabled by %<-fhardened%> "
+ "because other link options were specified on the command "
+ "line");
+ }
+
/* Handle -gtoggle as it would later in toplev.cc:process_options to
make the debug-level-gt spec function work as expected. */
if (flag_gtoggle)
diff --git a/gcc/genconfig.cc b/gcc/genconfig.cc
index 2ee323f..c8c2ebe 100644
--- a/gcc/genconfig.cc
+++ b/gcc/genconfig.cc
@@ -360,6 +360,8 @@ main (int argc, const char **argv)
printf ("#define MAX_INSNS_PER_PEEP2 0\n");
}
+ printf ("#define NUM_REGISTER_FILTERS %d\n", register_filters.length ());
+
puts ("\n#endif /* GCC_INSN_CONFIG_H */");
if (ferror (stdout) || fflush (stdout) || fclose (stdout))
diff --git a/gcc/genpreds.cc b/gcc/genpreds.cc
index bdd65ef..5535a75 100644
--- a/gcc/genpreds.cc
+++ b/gcc/genpreds.cc
@@ -677,6 +677,7 @@ public:
size_t namelen;
const char *regclass; /* for register constraints */
rtx exp; /* for other constraints */
+ const char *filter; /* the register filter condition, or null if none */
unsigned int is_register : 1;
unsigned int is_const_int : 1;
unsigned int is_const_dbl : 1;
@@ -763,7 +764,8 @@ mangle (const char *name)
is the register class, if any; EXP is the expression to test, if any;
IS_MEMORY, IS_SPECIAL_MEMORY, IS_RELAXED_MEMORY and IS_ADDRESS indicate
memory, special memory, and address constraints, respectively; LOC is the .md
- file location.
+ file location; FILTER is the filter condition for a register constraint,
+ or null if none.
Not all combinations of arguments are valid; most importantly, REGCLASS is
mutually exclusive with EXP, and
@@ -776,7 +778,8 @@ mangle (const char *name)
static void
add_constraint (const char *name, const char *regclass,
rtx exp, bool is_memory, bool is_special_memory,
- bool is_relaxed_memory, bool is_address, file_location loc)
+ bool is_relaxed_memory, bool is_address, file_location loc,
+ const char *filter = nullptr)
{
class constraint_data *c, **iter, **slot;
const char *p;
@@ -908,6 +911,7 @@ add_constraint (const char *name, const char *regclass,
c->namelen = namelen;
c->regclass = regclass;
c->exp = exp;
+ c->filter = filter;
c->is_register = regclass != 0;
c->is_const_int = is_const_int;
c->is_const_dbl = is_const_dbl;
@@ -966,7 +970,8 @@ static void
process_define_register_constraint (md_rtx_info *info)
{
add_constraint (XSTR (info->def, 0), XSTR (info->def, 1),
- 0, false, false, false, false, info->loc);
+ 0, false, false, false, false, info->loc,
+ XSTR (info->def, 3));
}
/* Put the constraints into enum order. We want to keep constraints
@@ -1319,6 +1324,34 @@ write_insn_const_int_ok_for_constraint (void)
" return false;\n"
"}\n");
}
+
+/* Print the init_reg_class_start_regs function, which initializes
+ this_target_constraints->register_filters from the C conditions
+ in the define_register_constraints. */
+static void
+write_init_reg_class_start_regs ()
+{
+ printf ("\n"
+ "void\n"
+ "init_reg_class_start_regs ()\n"
+ "{\n");
+ if (!register_filters.is_empty ())
+ {
+ printf (" for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER;"
+ " ++regno)\n"
+ " {\n");
+ for (unsigned int i = 0; i < register_filters.length (); ++i)
+ {
+ printf (" if (");
+ rtx_reader_ptr->print_c_condition (register_filters[i]);
+ printf (")\n"
+ " SET_HARD_REG_BIT (%s[%d], regno);\n",
+ "this_target_constraints->register_filters", i);
+ }
+ printf (" }\n");
+ }
+ printf ("}\n");
+}
/* Write a definition for a function NAME that returns true if a given
constraint_num is in the range [START, END). */
@@ -1401,6 +1434,54 @@ print_type_tree (const vec <std::pair <unsigned int, const char *> > &vec,
printf ("%*sreturn %s;\n", indent, "", fallback);
}
+/* Print the get_register_filter function, which returns a pointer
+ to the start register filter for a given constraint, or null if none. */
+static void
+write_get_register_filter ()
+{
+ constraint_data *c;
+
+ printf ("\n"
+ "#ifdef GCC_HARD_REG_SET_H\n"
+ "static inline const HARD_REG_SET *\n"
+ "get_register_filter (constraint_num%s)\n",
+ register_filters.is_empty () ? "" : " c");
+ printf ("{\n");
+ FOR_ALL_CONSTRAINTS (c)
+ if (c->is_register && c->filter)
+ {
+ printf (" if (c == CONSTRAINT_%s)\n", c->c_name);
+ printf (" return &this_target_constraints->register_filters[%d];\n",
+ get_register_filter_id (c->filter));
+ }
+ printf (" return nullptr;\n"
+ "}\n"
+ "#endif\n");
+}
+
+/* Print the get_register_filter_id function, which returns the index
+ of the given constraint's register filter in
+ this_target_constraints->register_filters, or -1 if none. */
+static void
+write_get_register_filter_id ()
+{
+ constraint_data *c;
+
+ printf ("\n"
+ "static inline int\n"
+ "get_register_filter_id (constraint_num%s)\n",
+ register_filters.is_empty () ? "" : " c");
+ printf ("{\n");
+ FOR_ALL_CONSTRAINTS (c)
+ if (c->is_register && c->filter)
+ {
+ printf (" if (c == CONSTRAINT_%s)\n", c->c_name);
+ printf (" return %d;\n", get_register_filter_id (c->filter));
+ }
+ printf (" return -1;\n"
+ "}\n");
+}
+
/* Write tm-preds.h. Unfortunately, it is impossible to forward-declare
an enumeration in portable C, so we have to condition all these
prototypes on HAVE_MACHINE_MODES. */
@@ -1425,6 +1506,53 @@ write_tm_preds_h (void)
puts ("#endif /* HAVE_MACHINE_MODES */\n");
+ /* Print the definition of the target_constraints structure. */
+ printf ("#ifdef GCC_HARD_REG_SET_H\n"
+ "struct target_constraints {\n"
+ " HARD_REG_SET register_filters[%d];\n",
+ MAX (register_filters.length (), 1));
+ printf ("};\n"
+ "\n"
+ "extern struct target_constraints default_target_constraints;\n"
+ "#if SWITCHABLE_TARGET\n"
+ "extern struct target_constraints *this_target_constraints;\n"
+ "#else\n"
+ "#define this_target_constraints (&default_target_constraints)\n"
+ "#endif\n");
+
+ /* Print TEST_REGISTER_FILTER_BIT, which tests whether register REGNO
+ is a valid start register for register filter ID. */
+ printf ("\n"
+ "#define TEST_REGISTER_FILTER_BIT(ID, REGNO) \\\n");
+ if (register_filters.is_empty ())
+ printf (" ((void) (ID), (void) (REGNO), false)\n");
+ else
+ printf (" TEST_HARD_REG_BIT ("
+ "this_target_constraints->register_filters[ID], REGNO)\n");
+
+ /* Print test_register_filters, which tests whether register REGNO
+ is a valid start register for the mask of register filters in MASK. */
+ printf ("\n"
+ "inline bool\n"
+ "test_register_filters (unsigned int%s, unsigned int%s)\n",
+ register_filters.is_empty () ? "" : " mask",
+ register_filters.is_empty () ? "" : " regno");
+ printf ("{\n");
+ if (register_filters.is_empty ())
+ printf (" return true;\n");
+ else
+ {
+ printf (" for (unsigned int id = 0; id < %d; ++id)\n",
+ register_filters.length ());
+ printf (" if ((mask & (1U << id))\n"
+ "\t&& !TEST_REGISTER_FILTER_BIT (id, regno))\n"
+ " return false;\n"
+ " return true;\n");
+ }
+ printf ("}\n"
+ "#endif\n"
+ "\n");
+
if (constraint_max_namelen > 0)
{
write_enum_constraint_num ();
@@ -1548,6 +1676,9 @@ write_tm_preds_h (void)
values.safe_push (std::make_pair (address_end, "CT_FIXED_FORM"));
print_type_tree (values, 0, values.length (), "CT_REGISTER", 2);
puts ("}");
+
+ write_get_register_filter ();
+ write_get_register_filter_id ();
}
puts ("#endif /* tm-preds.h */");
@@ -1599,6 +1730,13 @@ write_insn_preds_c (void)
#include \"tm-constrs.h\"\n\
#include \"target.h\"\n");
+ printf ("\n"
+ "struct target_constraints default_target_constraints;\n"
+ "#if SWITCHABLE_TARGET\n"
+ "struct target_constraints *this_target_constraints"
+ " = &default_target_constraints;\n"
+ "#endif\n");
+
FOR_ALL_PREDICATES (p)
write_one_predicate_function (p);
@@ -1613,6 +1751,8 @@ write_insn_preds_c (void)
if (have_const_int_constraints)
write_insn_const_int_ok_for_constraint ();
}
+
+ write_init_reg_class_start_regs ();
}
/* Argument parsing. */
diff --git a/gcc/gensupport.cc b/gcc/gensupport.cc
index 688808c..0ac0d07 100644
--- a/gcc/gensupport.cc
+++ b/gcc/gensupport.cc
@@ -400,6 +400,45 @@ process_define_predicate (rtx desc, file_location loc)
#undef I
#undef N
#undef Y
+
+/* Maps register filter conditions to the associated filter identifier. */
+static hash_map<nofree_string_hash, unsigned int> register_filter_map;
+
+/* All register filter conditions, indexed by identifier. */
+vec<const char *> register_filters;
+
+/* Return the unique identifier for filter condition FILTER. Identifiers
+ are assigned automatically when the define_register_constraint is
+ parsed. */
+
+unsigned int
+get_register_filter_id (const char *filter)
+{
+ unsigned int *slot = register_filter_map.get (filter);
+ gcc_assert (slot);
+ return *slot;
+}
+
+/* Process define_register_constraint directive DESC, at location LOC. */
+
+static void
+process_define_register_constraint (rtx desc, file_location loc)
+{
+ /* Assign identifiers to each unique register filter condition. */
+ if (const char *filter = XSTR (desc, 3))
+ {
+ bool existed = false;
+ unsigned int &id = register_filter_map.get_or_insert (filter, &existed);
+ if (!existed)
+ {
+ id = register_filters.length ();
+ if (id == 32)
+ fatal_at (loc, "too many distinct register filters, maximum"
+ " is 32");
+ register_filters.safe_push (filter);
+ }
+ }
+}
/* Queue PATTERN on LIST_TAIL. Return the address of the new queue
element. */
@@ -1075,10 +1114,15 @@ process_rtx (rtx desc, file_location loc)
case DEFINE_PREDICATE:
case DEFINE_SPECIAL_PREDICATE:
process_define_predicate (desc, loc);
- /* Fall through. */
+ queue_pattern (desc, &define_pred_tail, loc);
+ break;
- case DEFINE_CONSTRAINT:
case DEFINE_REGISTER_CONSTRAINT:
+ process_define_register_constraint (desc, loc);
+ queue_pattern (desc, &define_pred_tail, loc);
+ break;
+
+ case DEFINE_CONSTRAINT:
case DEFINE_MEMORY_CONSTRAINT:
case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
case DEFINE_RELAXED_MEMORY_CONSTRAINT:
diff --git a/gcc/gensupport.h b/gcc/gensupport.h
index 7396118..27e8444 100644
--- a/gcc/gensupport.h
+++ b/gcc/gensupport.h
@@ -108,6 +108,9 @@ struct optab_def
extern optab_def optabs[];
extern unsigned int num_optabs;
+extern vec<const char *> register_filters;
+extern unsigned int get_register_filter_id (const char *);
+
/* Information about an instruction name that matches an optab pattern. */
struct optab_pattern
{
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
index b709923..a7a8077 100644
--- a/gcc/gimple-iterator.h
+++ b/gcc/gimple-iterator.h
@@ -169,6 +169,41 @@ gsi_last_bb (basic_block bb)
return i;
}
+/* Return a new iterator pointing to before the first statement or after
+ last statement (depending on whether adding statements after it or before it)
+ in a GIMPLE_SEQ. */
+
+inline gimple_stmt_iterator
+gsi_end (gimple_seq &seq)
+{
+ gimple_stmt_iterator i;
+ gimple *g = gimple_seq_last (seq);
+
+ i.ptr = NULL;
+ i.seq = &seq;
+ i.bb = g ? gimple_bb (g) : NULL;
+
+ return i;
+}
+
+/* Return a new iterator pointing to before the first statement or after
+ last statement (depending on whether adding statements after it or before it)
+ in basic block BB. */
+
+inline gimple_stmt_iterator
+gsi_end_bb (basic_block bb)
+{
+ gimple_stmt_iterator i;
+ gimple_seq *seq;
+
+ seq = bb_seq_addr (bb);
+ i.ptr = NULL;
+ i.seq = seq;
+ i.bb = bb;
+
+ return i;
+}
+
/* Return true if I is at the end of its sequence. */
inline bool
diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index c429cb2..5024815 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -1294,6 +1294,11 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
g = gimple_build_assign (n, RSHIFT_EXPR, t, lpm1);
insert_before (g);
m_data[save_data_cnt + 1] = add_cast (m_limb_type, n);
+ m_init_gsi = m_gsi;
+ if (gsi_end_p (m_init_gsi))
+ m_init_gsi = gsi_last_bb (gsi_bb (m_init_gsi));
+ else
+ gsi_prev (&m_init_gsi);
m_gsi = save_gsi;
}
else if (m_upwards_2limb * limb_prec < TYPE_PRECISION (rhs_type))
@@ -1523,6 +1528,11 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
insert_before (g);
rext = add_cast (m_limb_type, gimple_assign_lhs (g));
}
+ m_init_gsi = m_gsi;
+ if (gsi_end_p (m_init_gsi))
+ m_init_gsi = gsi_last_bb (gsi_bb (m_init_gsi));
+ else
+ gsi_prev (&m_init_gsi);
m_gsi = save_gsi;
}
tree t;
@@ -1687,9 +1697,23 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
edge e = split_block (gsi_bb (m_gsi), g);
make_edge (e->src, eh_edge->dest, EDGE_EH)->probability
= profile_probability::very_unlikely ();
- m_init_gsi.bb = e->dest;
+ m_gsi = gsi_after_labels (e->dest);
+ if (gsi_bb (save_gsi) == e->src)
+ {
+ if (gsi_end_p (save_gsi))
+ save_gsi = gsi_end_bb (e->dest);
+ else
+ save_gsi = gsi_for_stmt (gsi_stmt (save_gsi));
+ }
+ if (m_preheader_bb == e->src)
+ m_preheader_bb = e->dest;
}
}
+ m_init_gsi = m_gsi;
+ if (gsi_end_p (m_init_gsi))
+ m_init_gsi = gsi_last_bb (gsi_bb (m_init_gsi));
+ else
+ gsi_prev (&m_init_gsi);
m_gsi = save_gsi;
tree out;
prepare_data_in_out (iv, idx, &out);
@@ -2359,11 +2383,7 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
edge_bb = e->src;
if (kind == bitint_prec_large)
- {
- m_gsi = gsi_last_bb (edge_bb);
- if (!gsi_end_p (m_gsi))
- gsi_next (&m_gsi);
- }
+ m_gsi = gsi_end_bb (edge_bb);
}
else
m_after_stmt = stmt;
@@ -2816,9 +2836,7 @@ bitint_large_huge::lower_comparison_stmt (gimple *stmt, tree_code &cmp_code,
gsi_prev (&gsi);
edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
edge_bb = e->src;
- m_gsi = gsi_last_bb (edge_bb);
- if (!gsi_end_p (m_gsi))
- gsi_next (&m_gsi);
+ m_gsi = gsi_end_bb (edge_bb);
edge *edges = XALLOCAVEC (edge, cnt * 2);
for (unsigned i = 0; i < cnt; i++)
@@ -4288,9 +4306,7 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple *stmt)
gsi_prev (&gsi);
edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
edge_bb = e->src;
- m_gsi = gsi_last_bb (edge_bb);
- if (!gsi_end_p (m_gsi))
- gsi_next (&m_gsi);
+ m_gsi = gsi_end_bb (edge_bb);
tree cmp = build_zero_cst (m_limb_type);
for (unsigned i = 0; i < cnt; i++)
@@ -4560,11 +4576,7 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
edge_bb = e->src;
if (kind == bitint_prec_large)
- {
- m_gsi = gsi_last_bb (edge_bb);
- if (!gsi_end_p (m_gsi))
- gsi_next (&m_gsi);
- }
+ m_gsi = gsi_end_bb (edge_bb);
bqp = XALLOCAVEC (struct bq_details, cnt);
}
else
@@ -4717,9 +4729,7 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
gsi_prev (&gsi);
edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
edge_bb = e->src;
- m_gsi = gsi_last_bb (edge_bb);
- if (!gsi_end_p (m_gsi))
- gsi_next (&m_gsi);
+ m_gsi = gsi_end_bb (edge_bb);
if (ifn == IFN_CLZ)
bqp = XALLOCAVEC (struct bq_details, cnt);
@@ -5625,6 +5635,21 @@ gimple_lower_bitint (void)
break;
}
}
+ /* Similarly, e.g. with -frounding-math casts from _BitInt INTEGER_CSTs
+ to floating point types need to be rewritten. */
+ else if (SCALAR_FLOAT_TYPE_P (type))
+ {
+ gimple *g = SSA_NAME_DEF_STMT (s);
+ if (is_gimple_assign (g) && gimple_assign_rhs_code (g) == FLOAT_EXPR)
+ {
+ tree t = gimple_assign_rhs1 (g);
+ if (TREE_CODE (t) == INTEGER_CST
+ && TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+ && (bitint_precision_kind (TREE_TYPE (t))
+ != bitint_prec_small))
+ break;
+ }
+ }
}
if (i == num_ssa_names)
return 0;
@@ -5845,6 +5870,21 @@ gimple_lower_bitint (void)
has_large_huge = true;
}
}
+ /* Similarly, e.g. with -frounding-math casts from _BitInt INTEGER_CSTs
+ to floating point types need to be rewritten. */
+ else if (SCALAR_FLOAT_TYPE_P (type))
+ {
+ gimple *g = SSA_NAME_DEF_STMT (s);
+ if (is_gimple_assign (g) && gimple_assign_rhs_code (g) == FLOAT_EXPR)
+ {
+ tree t = gimple_assign_rhs1 (g);
+ if (TREE_CODE (t) == INTEGER_CST
+ && TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+ && (bitint_precision_kind (TREE_TYPE (t))
+ >= bitint_prec_large))
+ has_large_huge = true;
+ }
+ }
}
for (i = first_large_huge; i < num_ssa_names; ++i)
{
@@ -6176,6 +6216,19 @@ gimple_lower_bitint (void)
kind = this_kind;
}
}
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == FLOAT_EXPR)
+ {
+ t = gimple_assign_rhs1 (stmt);
+ if (TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+ && TREE_CODE (t) == INTEGER_CST)
+ {
+ bitint_prec_kind this_kind
+ = bitint_precision_kind (TREE_TYPE (t));
+ if (this_kind > kind)
+ kind = this_kind;
+ }
+ }
if (is_gimple_call (stmt))
{
t = gimple_call_lhs (stmt);
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 6e9530c..998b760 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -44,6 +44,11 @@ along with GCC; see the file COPYING3. If not see
#include "value-query.h"
#include "gimple-range-op.h"
#include "gimple-range.h"
+#include "cgraph.h"
+#include "alloc-pool.h"
+#include "symbol-summary.h"
+#include "ipa-utils.h"
+#include "ipa-prop.h"
// Construct a fur_source, and set the m_query field.
fur_source::fur_source (range_query *q)
@@ -1013,6 +1018,25 @@ fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &)
else
r.set_varying (type);
+ tree callee = gimple_call_fndecl (call);
+ if (callee
+ && useless_type_conversion_p (TREE_TYPE (TREE_TYPE (callee)), type))
+ {
+ Value_Range val;
+ if (ipa_return_value_range (val, callee))
+ {
+ r.intersect (val);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Using return value range of ");
+ print_generic_expr (dump_file, callee, TDF_SLIM);
+ fprintf (dump_file, ": ");
+ val.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ }
+ }
+
// If there is an LHS, intersect that with what is known.
if (lhs)
{
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index d52d71b..02f85e7 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -14382,7 +14382,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
OMP_CLAUSE_LASTPRIVATE))
if (OMP_CLAUSE_DECL (c3) == decl)
{
- warning_at (OMP_CLAUSE_LOCATION (c3), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
"conditional %<lastprivate%> on loop "
"iterator %qD ignored", decl);
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
@@ -14490,7 +14490,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
OMP_CLAUSE_LASTPRIVATE))
if (OMP_CLAUSE_DECL (c3) == decl)
{
- warning_at (OMP_CLAUSE_LOCATION (c3), 0,
+ warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
"conditional %<lastprivate%> on loop "
"iterator %qD ignored", decl);
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index a0af553..be42609 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -3492,44 +3492,6 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
if (if_info->then_else_reversed)
std::swap (old_val, new_val);
-
- /* We allow simple lowpart register subreg SET sources in
- bb_ok_for_noce_convert_multiple_sets. Be careful when processing
- sequences like:
- (set (reg:SI r1) (reg:SI r2))
- (set (reg:HI r3) (subreg:HI (r1)))
- For the second insn new_val or old_val (r1 in this example) will be
- taken from the temporaries and have the wider mode which will not
- match with the mode of the other source of the conditional move, so
- we'll end up trying to emit r4:HI = cond ? (r1:SI) : (r3:HI).
- Wrap the two cmove operands into subregs if appropriate to prevent
- that. */
-
- if (!CONSTANT_P (new_val)
- && GET_MODE (new_val) != GET_MODE (temp))
- {
- machine_mode src_mode = GET_MODE (new_val);
- machine_mode dst_mode = GET_MODE (temp);
- if (!partial_subreg_p (dst_mode, src_mode))
- {
- end_sequence ();
- return false;
- }
- new_val = lowpart_subreg (dst_mode, new_val, src_mode);
- }
- if (!CONSTANT_P (old_val)
- && GET_MODE (old_val) != GET_MODE (temp))
- {
- machine_mode src_mode = GET_MODE (old_val);
- machine_mode dst_mode = GET_MODE (temp);
- if (!partial_subreg_p (dst_mode, src_mode))
- {
- end_sequence ();
- return false;
- }
- old_val = lowpart_subreg (dst_mode, old_val, src_mode);
- }
-
/* Try emitting a conditional move passing the backend the
canonicalized comparison. The backend is then able to
recognize expressions like
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index 5a998e7..cce73b3 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -102,8 +102,6 @@ lookup_hilo_internal_fn (internal_fn ifn, internal_fn *lo, internal_fn *hi)
{
default:
gcc_unreachable ();
-#undef DEF_INTERNAL_FN
-#undef DEF_INTERNAL_WIDENING_OPTAB_FN
#define DEF_INTERNAL_FN(NAME, FLAGS, TYPE)
#define DEF_INTERNAL_WIDENING_OPTAB_FN(NAME, F, S, SO, UO, T) \
case IFN_##NAME: \
@@ -111,8 +109,6 @@ lookup_hilo_internal_fn (internal_fn ifn, internal_fn *lo, internal_fn *hi)
*hi = internal_fn (IFN_##NAME##_HI); \
break;
#include "internal-fn.def"
-#undef DEF_INTERNAL_FN
-#undef DEF_INTERNAL_WIDENING_OPTAB_FN
}
}
@@ -129,8 +125,6 @@ lookup_evenodd_internal_fn (internal_fn ifn, internal_fn *even,
{
default:
gcc_unreachable ();
-#undef DEF_INTERNAL_FN
-#undef DEF_INTERNAL_WIDENING_OPTAB_FN
#define DEF_INTERNAL_FN(NAME, FLAGS, TYPE)
#define DEF_INTERNAL_WIDENING_OPTAB_FN(NAME, F, S, SO, UO, T) \
case IFN_##NAME: \
@@ -138,8 +132,6 @@ lookup_evenodd_internal_fn (internal_fn ifn, internal_fn *even,
*odd = internal_fn (IFN_##NAME##_ODD); \
break;
#include "internal-fn.def"
-#undef DEF_INTERNAL_FN
-#undef DEF_INTERNAL_WIDENING_OPTAB_FN
}
}
@@ -4261,7 +4253,6 @@ widening_fn_p (code_helper code)
internal_fn fn = as_internal_fn ((combined_fn) code);
switch (fn)
{
- #undef DEF_INTERNAL_WIDENING_OPTAB_FN
#define DEF_INTERNAL_WIDENING_OPTAB_FN(NAME, F, S, SO, UO, T) \
case IFN_##NAME: \
case IFN_##NAME##_HI: \
@@ -4270,7 +4261,6 @@ widening_fn_p (code_helper code)
case IFN_##NAME##_ODD: \
return true;
#include "internal-fn.def"
- #undef DEF_INTERNAL_WIDENING_OPTAB_FN
default:
return false;
@@ -4295,6 +4285,7 @@ set_edom_supported_p (void)
{ \
expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
}
+#define DEF_INTERNAL_INT_EXT_FN(CODE, FLAGS, OPTAB, TYPE)
#define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
UNSIGNED_OPTAB, TYPE) \
static void \
@@ -4305,8 +4296,6 @@ set_edom_supported_p (void)
expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
}
#include "internal-fn.def"
-#undef DEF_INTERNAL_OPTAB_FN
-#undef DEF_INTERNAL_SIGNED_OPTAB_FN
/* Routines to expand each internal function, indexed by function number.
Each routine has the prototype:
@@ -4465,8 +4454,6 @@ get_len_internal_fn (internal_fn fn)
{
switch (fn)
{
-#undef DEF_INTERNAL_COND_FN
-#undef DEF_INTERNAL_SIGNED_COND_FN
#define DEF_INTERNAL_COND_FN(NAME, ...) \
case IFN_COND_##NAME: \
return IFN_COND_LEN_##NAME;
@@ -4474,8 +4461,6 @@ get_len_internal_fn (internal_fn fn)
case IFN_COND_##NAME: \
return IFN_COND_LEN_##NAME;
#include "internal-fn.def"
-#undef DEF_INTERNAL_COND_FN
-#undef DEF_INTERNAL_SIGNED_COND_FN
default:
return IFN_LAST;
}
@@ -5113,3 +5098,67 @@ expand_BITINTTOFLOAT (internal_fn, gcall *stmt)
if (val != target)
emit_move_insn (target, val);
}
+
+void
+expand_POPCOUNT (internal_fn fn, gcall *stmt)
+{
+ if (gimple_call_num_args (stmt) == 1)
+ {
+ expand_unary_optab_fn (fn, stmt, popcount_optab);
+ return;
+ }
+ /* If .POPCOUNT call has 2 arguments, match_single_bit_test marked it
+ because the result is only used in an equality comparison against 1.
+ Use rtx costs in that case to determine if .POPCOUNT (arg) == 1
+ or (arg ^ (arg - 1)) > arg - 1 is cheaper. */
+ bool speed_p = optimize_insn_for_speed_p ();
+ tree lhs = gimple_call_lhs (stmt);
+ tree arg = gimple_call_arg (stmt, 0);
+ tree type = TREE_TYPE (arg);
+ machine_mode mode = TYPE_MODE (type);
+ do_pending_stack_adjust ();
+ start_sequence ();
+ expand_unary_optab_fn (fn, stmt, popcount_optab);
+ rtx_insn *popcount_insns = get_insns ();
+ end_sequence ();
+ start_sequence ();
+ rtx plhs = expand_normal (lhs);
+ rtx pcmp = emit_store_flag (NULL_RTX, EQ, plhs, const1_rtx, mode, 0, 0);
+ if (pcmp == NULL_RTX)
+ {
+ fail:
+ end_sequence ();
+ emit_insn (popcount_insns);
+ return;
+ }
+ rtx_insn *popcount_cmp_insns = get_insns ();
+ end_sequence ();
+ start_sequence ();
+ rtx op0 = expand_normal (arg);
+ rtx argm1 = expand_simple_binop (mode, PLUS, op0, constm1_rtx, NULL_RTX,
+ 1, OPTAB_DIRECT);
+ if (argm1 == NULL_RTX)
+ goto fail;
+ rtx argxorargm1 = expand_simple_binop (mode, XOR, op0, argm1, NULL_RTX,
+ 1, OPTAB_DIRECT);
+ if (argxorargm1 == NULL_RTX)
+ goto fail;
+ rtx cmp = emit_store_flag (NULL_RTX, GTU, argxorargm1, argm1, mode, 1, 1);
+ if (cmp == NULL_RTX)
+ goto fail;
+ rtx_insn *cmp_insns = get_insns ();
+ end_sequence ();
+ unsigned popcount_cost = (seq_cost (popcount_insns, speed_p)
+ + seq_cost (popcount_cmp_insns, speed_p));
+ unsigned cmp_cost = seq_cost (cmp_insns, speed_p);
+ if (popcount_cost <= cmp_cost)
+ emit_insn (popcount_insns);
+ else
+ {
+ emit_insn (cmp_insns);
+ plhs = expand_normal (lhs);
+ if (GET_MODE (cmp) != GET_MODE (plhs))
+ cmp = convert_to_mode (GET_MODE (plhs), cmp, 1);
+ emit_move_insn (plhs, cmp);
+ }
+}
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 3d5aca0..ba5e4ce 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -33,9 +33,13 @@ along with GCC; see the file COPYING3. If not see
DEF_INTERNAL_SIGNED_OPTAB_FN (NAME, FLAGS, SELECTOR, SIGNED_OPTAB,
UNSIGNED_OPTAB, TYPE)
DEF_INTERNAL_FLT_FN (NAME, FLAGS, OPTAB, TYPE)
+ DEF_INTERNAL_FLT_FLOATN_FN (NAME, FLAGS, OPTAB, TYPE)
DEF_INTERNAL_INT_FN (NAME, FLAGS, OPTAB, TYPE)
+ DEF_INTERNAL_INT_EXT_FN (NAME, FLAGS, OPTAB, TYPE)
DEF_INTERNAL_COND_FN (NAME, FLAGS, OPTAB, TYPE)
DEF_INTERNAL_SIGNED_COND_FN (NAME, FLAGS, OPTAB, TYPE)
+ DEF_INTERNAL_WIDENING_OPTAB_FN (NAME, FLAGS, SELECTOR, SOPTAB, UOPTAB,
+ TYPE)
where NAME is the name of the function, FLAGS is a set of
ECF_* flags and FNSPEC is a string describing functions fnspec.
@@ -97,6 +101,10 @@ along with GCC; see the file COPYING3. If not see
says that the function extends the C-level BUILT_IN_<NAME>{,L,LL,IMAX}
group of functions to any integral mode (including vector modes).
+ DEF_INTERNAL_INT_EXT_FN is like DEF_INTERNAL_INT_FN, except that it
+ has expand_##NAME defined in internal-fn.cc to override the
+ DEF_INTERNAL_INT_FN expansion behavior.
+
DEF_INTERNAL_WIDENING_OPTAB_FN is a wrapper that defines five internal
functions with DEF_INTERNAL_SIGNED_OPTAB_FN:
- one that describes a widening operation with the same number of elements
@@ -160,6 +168,11 @@ along with GCC; see the file COPYING3. If not see
DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
#endif
+#ifndef DEF_INTERNAL_INT_EXT_FN
+#define DEF_INTERNAL_INT_EXT_FN(NAME, FLAGS, OPTAB, TYPE) \
+ DEF_INTERNAL_INT_FN (NAME, FLAGS, OPTAB, TYPE)
+#endif
+
#ifndef DEF_INTERNAL_WIDENING_OPTAB_FN
#define DEF_INTERNAL_WIDENING_OPTAB_FN(NAME, FLAGS, SELECTOR, SOPTAB, UOPTAB, TYPE) \
DEF_INTERNAL_SIGNED_OPTAB_FN (NAME, FLAGS, SELECTOR, SOPTAB, UOPTAB, TYPE) \
@@ -432,7 +445,7 @@ DEF_INTERNAL_INT_FN (CLZ, ECF_CONST | ECF_NOTHROW, clz, unary)
DEF_INTERNAL_INT_FN (CTZ, ECF_CONST | ECF_NOTHROW, ctz, unary)
DEF_INTERNAL_INT_FN (FFS, ECF_CONST | ECF_NOTHROW, ffs, unary)
DEF_INTERNAL_INT_FN (PARITY, ECF_CONST | ECF_NOTHROW, parity, unary)
-DEF_INTERNAL_INT_FN (POPCOUNT, ECF_CONST | ECF_NOTHROW, popcount, unary)
+DEF_INTERNAL_INT_EXT_FN (POPCOUNT, ECF_CONST | ECF_NOTHROW, popcount, unary)
DEF_INTERNAL_FN (GOMP_TARGET_REV, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (GOMP_USE_SIMT, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
@@ -572,6 +585,10 @@ DEF_INTERNAL_FN (DIVMODBITINT, ECF_LEAF, ". O . O . R . R . ")
DEF_INTERNAL_FN (FLOATTOBITINT, ECF_LEAF | ECF_NOTHROW, ". O . . ")
DEF_INTERNAL_FN (BITINTTOFLOAT, ECF_PURE | ECF_LEAF, ". R . ")
+#undef DEF_INTERNAL_WIDENING_OPTAB_FN
+#undef DEF_INTERNAL_SIGNED_COND_FN
+#undef DEF_INTERNAL_COND_FN
+#undef DEF_INTERNAL_INT_EXT_FN
#undef DEF_INTERNAL_INT_FN
#undef DEF_INTERNAL_FLT_FN
#undef DEF_INTERNAL_FLT_FLOATN_FN
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 7d72f4d..93598fa 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -262,6 +262,7 @@ extern void expand_MULBITINT (internal_fn, gcall *);
extern void expand_DIVMODBITINT (internal_fn, gcall *);
extern void expand_FLOATTOBITINT (internal_fn, gcall *);
extern void expand_BITINTTOFLOAT (internal_fn, gcall *);
+extern void expand_POPCOUNT (internal_fn, gcall *);
extern bool vectorized_internal_fn_supported_p (internal_fn, tree);
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 7de2b78..e77bc9c 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -237,6 +237,35 @@ gt_ggc_mx (ipa_vr *&x)
return gt_ggc_mx ((ipa_vr *) x);
}
+/* Analysis summery of function call return value. */
+struct GTY(()) ipa_return_value_summary
+{
+ /* Known value range.
+ This needs to be wrapped in struccture due to specific way
+ we allocate ipa_vr. */
+ ipa_vr *vr;
+};
+
+/* Function summary for return values. */
+class ipa_return_value_sum_t : public function_summary <ipa_return_value_summary *>
+{
+public:
+ ipa_return_value_sum_t (symbol_table *table, bool ggc):
+ function_summary <ipa_return_value_summary *> (table, ggc) { }
+
+ /* Hook that is called by summary when a node is duplicated. */
+ void duplicate (cgraph_node *,
+ cgraph_node *,
+ ipa_return_value_summary *data,
+ ipa_return_value_summary *data2) final override
+ {
+ *data2=*data;
+ }
+};
+
+/* Variable hoding the return value summary. */
+static GTY(()) function_summary <ipa_return_value_summary *> *ipa_return_value_sum;
+
/* 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. */
@@ -5915,5 +5944,49 @@ ipcp_transform_function (struct cgraph_node *node)
return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
}
+/* Record that current function return value range is VAL. */
+
+void
+ipa_record_return_value_range (Value_Range val)
+{
+ cgraph_node *n = cgraph_node::get (current_function_decl);
+ if (!ipa_return_value_sum)
+ {
+ if (!ipa_vr_hash_table)
+ ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
+ ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ())
+ ipa_return_value_sum_t (symtab, true);
+ ipa_return_value_sum->disable_insertion_hook ();
+ }
+ ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Recording return range ");
+ val.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+}
+
+/* Return true if value range of DECL is known and if so initialize RANGE. */
+
+bool
+ipa_return_value_range (Value_Range &range, tree decl)
+{
+ cgraph_node *n = cgraph_node::get (decl);
+ if (!n || !ipa_return_value_sum)
+ return false;
+ enum availability avail;
+ n = n->ultimate_alias_target (&avail);
+ if (avail < AVAIL_AVAILABLE)
+ return false;
+ if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl)))
+ return false;
+ ipa_return_value_summary *v = ipa_return_value_sum->get (n);
+ if (!v)
+ return false;
+ v->vr->get_vrange (range);
+ return true;
+}
+
#include "gt-ipa-prop.h"
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index fcd0e5c..5901c80 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -309,7 +309,7 @@ public:
void get_vrange (Value_Range &) const;
bool equal_p (const vrange &) const;
const vrange_storage *storage () const { return m_storage; }
- void streamer_read (lto_input_block *, data_in *);
+ void streamer_read (lto_input_block *, class data_in *);
void streamer_write (output_block *) const;
void dump (FILE *) const;
@@ -1274,4 +1274,7 @@ ipa_range_set_and_normalize (vrange &r, tree val)
r.set (val, val);
}
+bool ipa_return_value_range (Value_Range &range, tree decl);
+void ipa_record_return_value_range (Value_Range val);
+
#endif /* IPA_PROP_H */
diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
index 058a7dd..3060ffe 100644
--- a/gcc/ipa-pure-const.cc
+++ b/gcc/ipa-pure-const.cc
@@ -292,6 +292,15 @@ warn_function_cold (tree decl)
true, warned_about, "cold");
}
+void
+warn_function_returns_nonnull (tree decl)
+{
+ static hash_set<tree> *warned_about;
+ warned_about
+ = suggest_attribute (OPT_Wsuggest_attribute_returns_nonnull, decl,
+ true, warned_about, "returns_nonnull");
+}
+
/* Check to see if the use (or definition when CHECKING_WRITE is true)
variable T is legal in a function that is either pure or const. */
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index 0eefcf4..84728c5 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -105,6 +105,7 @@ tree prevailing_odr_type (tree type);
void enable_odr_based_tbaa (tree type);
bool odr_based_tbaa_p (const_tree type);
void set_type_canonical_for_odr_type (tree type, tree canonical);
+void warn_function_returns_nonnull (tree);
void register_odr_enum (tree type);
diff --git a/gcc/ira-build.cc b/gcc/ira-build.cc
index 93e4603..c715a83 100644
--- a/gcc/ira-build.cc
+++ b/gcc/ira-build.cc
@@ -498,6 +498,7 @@ ira_create_allocno (int regno, bool cap_p,
ALLOCNO_NREFS (a) = 0;
ALLOCNO_FREQ (a) = 0;
ALLOCNO_MIGHT_CONFLICT_WITH_PARENT_P (a) = false;
+ ALLOCNO_SET_REGISTER_FILTERS (a, 0);
ALLOCNO_HARD_REGNO (a) = -1;
ALLOCNO_CALL_FREQ (a) = 0;
ALLOCNO_CALLS_CROSSED_NUM (a) = 0;
@@ -902,6 +903,7 @@ create_cap_allocno (ira_allocno_t a)
ALLOCNO_NREFS (cap) = ALLOCNO_NREFS (a);
ALLOCNO_FREQ (cap) = ALLOCNO_FREQ (a);
ALLOCNO_CALL_FREQ (cap) = ALLOCNO_CALL_FREQ (a);
+ ALLOCNO_SET_REGISTER_FILTERS (cap, ALLOCNO_REGISTER_FILTERS (a));
merge_hard_reg_conflicts (a, cap, false);
@@ -2064,6 +2066,9 @@ propagate_allocno_info (void)
ALLOCNO_BAD_SPILL_P (parent_a) = false;
ALLOCNO_NREFS (parent_a) += ALLOCNO_NREFS (a);
ALLOCNO_FREQ (parent_a) += ALLOCNO_FREQ (a);
+ ALLOCNO_SET_REGISTER_FILTERS (parent_a,
+ ALLOCNO_REGISTER_FILTERS (parent_a)
+ | ALLOCNO_REGISTER_FILTERS (a));
/* If A's allocation can differ from PARENT_A's, we can if necessary
spill PARENT_A on entry to A's loop and restore it afterwards.
@@ -2465,6 +2470,9 @@ propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a)
ALLOCNO_CROSSED_CALLS_ABIS (a) |= ALLOCNO_CROSSED_CALLS_ABIS (from_a);
ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)
|= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (from_a);
+ ALLOCNO_SET_REGISTER_FILTERS (a,
+ ALLOCNO_REGISTER_FILTERS (from_a)
+ | ALLOCNO_REGISTER_FILTERS (a));
ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
+= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a);
diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc
index f2e8ea3..214a4f1 100644
--- a/gcc/ira-color.cc
+++ b/gcc/ira-color.cc
@@ -2163,6 +2163,9 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
if (! check_hard_reg_p (a, hard_regno,
conflicting_regs, profitable_hard_regs))
continue;
+ if (NUM_REGISTER_FILTERS
+ && !test_register_filters (ALLOCNO_REGISTER_FILTERS (a), hard_regno))
+ continue;
cost = costs[i];
full_cost = full_costs[i];
if (!HONOR_REG_ALLOC_ORDER)
@@ -3205,6 +3208,9 @@ improve_allocation (void)
if (! check_hard_reg_p (a, hregno,
conflicting_regs, profitable_hard_regs))
continue;
+ if (NUM_REGISTER_FILTERS
+ && !test_register_filters (ALLOCNO_REGISTER_FILTERS (a), hregno))
+ continue;
ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
k = allocno_costs == NULL ? 0 : j;
costs[hregno] = (allocno_costs == NULL
@@ -5275,6 +5281,10 @@ fast_allocation (void)
|| (TEST_HARD_REG_BIT
(ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
continue;
+ if (NUM_REGISTER_FILTERS
+ && !test_register_filters (ALLOCNO_REGISTER_FILTERS (a),
+ hard_regno))
+ continue;
if (costs == NULL)
{
best_hard_regno = hard_regno;
diff --git a/gcc/ira-costs.cc b/gcc/ira-costs.cc
index e0528e7..c3efd295 100644
--- a/gcc/ira-costs.cc
+++ b/gcc/ira-costs.cc
@@ -1662,16 +1662,16 @@ scan_one_insn (rtx_insn *insn)
-/* Print allocnos costs to file F. */
+/* Print allocnos costs to the dump file. */
static void
-print_allocno_costs (FILE *f)
+print_allocno_costs (void)
{
int k;
ira_allocno_t a;
ira_allocno_iterator ai;
ira_assert (allocno_p);
- fprintf (f, "\n");
+ fprintf (ira_dump_file, "\n");
FOR_EACH_ALLOCNO (a, ai)
{
int i, rclass;
@@ -1681,32 +1681,34 @@ print_allocno_costs (FILE *f)
enum reg_class *cost_classes = cost_classes_ptr->classes;
i = ALLOCNO_NUM (a);
- fprintf (f, " a%d(r%d,", i, regno);
+ fprintf (ira_dump_file, " a%d(r%d,", i, regno);
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
- fprintf (f, "b%d", bb->index);
+ fprintf (ira_dump_file, "b%d", bb->index);
else
- fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
- fprintf (f, ") costs:");
+ fprintf (ira_dump_file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
+ fprintf (ira_dump_file, ") costs:");
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- fprintf (f, " %s:%d", reg_class_names[rclass],
+ fprintf (ira_dump_file, " %s:%d", reg_class_names[rclass],
COSTS (costs, i)->cost[k]);
if (flag_ira_region == IRA_REGION_ALL
|| flag_ira_region == IRA_REGION_MIXED)
- fprintf (f, ",%d", COSTS (total_allocno_costs, i)->cost[k]);
+ fprintf (ira_dump_file, ",%d",
+ COSTS (total_allocno_costs, i)->cost[k]);
}
- fprintf (f, " MEM:%i", COSTS (costs, i)->mem_cost);
+ fprintf (ira_dump_file, " MEM:%i", COSTS (costs, i)->mem_cost);
if (flag_ira_region == IRA_REGION_ALL
|| flag_ira_region == IRA_REGION_MIXED)
- fprintf (f, ",%d", COSTS (total_allocno_costs, i)->mem_cost);
- fprintf (f, "\n");
+ fprintf (ira_dump_file, ",%d",
+ COSTS (total_allocno_costs, i)->mem_cost);
+ fprintf (ira_dump_file, "\n");
}
}
-/* Print pseudo costs to file F. */
+/* Print pseudo costs to the dump file. */
static void
-print_pseudo_costs (FILE *f)
+print_pseudo_costs (void)
{
int regno, k;
int rclass;
@@ -1714,21 +1716,21 @@ print_pseudo_costs (FILE *f)
enum reg_class *cost_classes;
ira_assert (! allocno_p);
- fprintf (f, "\n");
+ fprintf (ira_dump_file, "\n");
for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--)
{
if (REG_N_REFS (regno) <= 0)
continue;
cost_classes_ptr = regno_cost_classes[regno];
cost_classes = cost_classes_ptr->classes;
- fprintf (f, " r%d costs:", regno);
+ fprintf (ira_dump_file, " r%d costs:", regno);
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- fprintf (f, " %s:%d", reg_class_names[rclass],
+ fprintf (ira_dump_file, " %s:%d", reg_class_names[rclass],
COSTS (costs, regno)->cost[k]);
}
- fprintf (f, " MEM:%i\n", COSTS (costs, regno)->mem_cost);
+ fprintf (ira_dump_file, " MEM:%i\n", COSTS (costs, regno)->mem_cost);
}
}
@@ -1939,7 +1941,7 @@ calculate_equiv_gains (void)
and their best costs. Set up preferred, alternative and allocno
classes for pseudos. */
static void
-find_costs_and_classes (FILE *dump_file)
+find_costs_and_classes (void)
{
int i, k, start, max_cost_classes_num;
int pass;
@@ -1991,8 +1993,8 @@ find_costs_and_classes (FILE *dump_file)
classes to guide the selection. */
for (pass = start; pass <= flag_expensive_optimizations; pass++)
{
- if ((!allocno_p || internal_flag_ira_verbose > 0) && dump_file)
- fprintf (dump_file,
+ if ((!allocno_p || internal_flag_ira_verbose > 0) && ira_dump_file)
+ fprintf (ira_dump_file,
"\nPass %i for finding pseudo/allocno costs\n\n", pass);
if (pass != start)
@@ -2244,8 +2246,8 @@ find_costs_and_classes (FILE *dump_file)
alt_class = NO_REGS;
setup_reg_classes (i, best, alt_class, regno_aclass[i]);
if ((!allocno_p || internal_flag_ira_verbose > 2)
- && dump_file != NULL)
- fprintf (dump_file,
+ && ira_dump_file != NULL)
+ fprintf (ira_dump_file,
" r%d: preferred %s, alternative %s, allocno %s\n",
i, reg_class_names[best], reg_class_names[alt_class],
reg_class_names[regno_aclass[i]]);
@@ -2295,16 +2297,16 @@ find_costs_and_classes (FILE *dump_file)
}
ALLOCNO_CLASS_COST (a) = allocno_cost;
}
- if (internal_flag_ira_verbose > 2 && dump_file != NULL
+ if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL
&& (pass == 0 || pref[a_num] != best))
{
- fprintf (dump_file, " a%d (r%d,", a_num, i);
+ fprintf (ira_dump_file, " a%d (r%d,", a_num, i);
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
- fprintf (dump_file, "b%d", bb->index);
+ fprintf (ira_dump_file, "b%d", bb->index);
else
- fprintf (dump_file, "l%d",
+ fprintf (ira_dump_file, "l%d",
ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
- fprintf (dump_file, ") best %s, allocno %s\n",
+ fprintf (ira_dump_file, ") best %s, allocno %s\n",
reg_class_names[best],
reg_class_names[aclass]);
}
@@ -2329,13 +2331,13 @@ find_costs_and_classes (FILE *dump_file)
}
}
- if (internal_flag_ira_verbose > 4 && dump_file)
+ if (internal_flag_ira_verbose > 4 && ira_dump_file)
{
if (allocno_p)
- print_allocno_costs (dump_file);
+ print_allocno_costs ();
else
- print_pseudo_costs (dump_file);
- fprintf (dump_file,"\n");
+ print_pseudo_costs ();
+ fprintf (ira_dump_file,"\n");
}
}
ira_free (regno_best_class);
@@ -2594,7 +2596,7 @@ ira_costs (void)
/* Process equivs in reload to update costs through hook
ira_adjust_equiv_reg_cost. */
calculate_elim_costs_all_insns ();
- find_costs_and_classes (ira_dump_file);
+ find_costs_and_classes ();
setup_allocno_class_and_costs ();
finish_regno_cost_classes ();
finish_costs ();
@@ -2606,17 +2608,20 @@ ira_costs (void)
void
ira_set_pseudo_classes (bool define_pseudo_classes, FILE *dump_file)
{
+ FILE *saved_file = ira_dump_file;
allocno_p = false;
internal_flag_ira_verbose = flag_ira_verbose;
+ ira_dump_file = dump_file;
cost_elements_num = max_reg_num ();
init_costs ();
initiate_regno_cost_classes ();
- find_costs_and_classes (dump_file);
+ find_costs_and_classes ();
finish_regno_cost_classes ();
if (define_pseudo_classes)
pseudo_classes_defined_p = true;
finish_costs ();
+ ira_dump_file = saved_file;
}
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 0685e1f..1c3548d 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -328,6 +328,13 @@ struct ira_allocno
This is only ever true for non-cap allocnos. */
unsigned int might_conflict_with_parent_p : 1;
+#ifndef NUM_REGISTER_FILTERS
+#error "insn-config.h not included"
+#elif NUM_REGISTER_FILTERS
+ /* The set of register filters applied to the allocno by operand
+ alternatives that accept class ACLASS. */
+ unsigned int register_filters : NUM_REGISTER_FILTERS;
+#endif
/* Accumulated usage references of the allocno. Here and below,
word 'accumulated' means info for given region and all nested
subregions. In this case, 'accumulated' means sum of references
@@ -432,6 +439,13 @@ struct ira_allocno
#define ALLOCNO_FREQ(A) ((A)->freq)
#define ALLOCNO_MIGHT_CONFLICT_WITH_PARENT_P(A) \
((A)->might_conflict_with_parent_p)
+#if NUM_REGISTER_FILTERS
+#define ALLOCNO_REGISTER_FILTERS(A) (A)->register_filters
+#define ALLOCNO_SET_REGISTER_FILTERS(A, X) ((A)->register_filters = (X))
+#else
+#define ALLOCNO_REGISTER_FILTERS(A) 0
+#define ALLOCNO_SET_REGISTER_FILTERS(A, X) ((void) (A), gcc_assert ((X) == 0))
+#endif
#define ALLOCNO_HARD_REGNO(A) ((A)->hard_regno)
#define ALLOCNO_CALL_FREQ(A) ((A)->call_freq)
#define ALLOCNO_CALLS_CROSSED_NUM(A) ((A)->calls_crossed_num)
diff --git a/gcc/ira-lives.cc b/gcc/ira-lives.cc
index 81af5c0..63f2314 100644
--- a/gcc/ira-lives.cc
+++ b/gcc/ira-lives.cc
@@ -1066,6 +1066,66 @@ process_single_reg_class_operands (bool in_p, int freq)
}
}
+/* Go through the operands of the extracted insn looking for operand
+ alternatives that apply a register filter. Record any such filters
+ in the operand's allocno. */
+static void
+process_register_constraint_filters ()
+{
+ for (int opno = 0; opno < recog_data.n_operands; ++opno)
+ {
+ rtx op = recog_data.operand[opno];
+ if (SUBREG_P (op))
+ op = SUBREG_REG (op);
+ if (REG_P (op) && !HARD_REGISTER_P (op))
+ {
+ ira_allocno_t a = ira_curr_regno_allocno_map[REGNO (op)];
+ for (int alt = 0; alt < recog_data.n_alternatives; alt++)
+ {
+ if (!TEST_BIT (preferred_alternatives, alt))
+ continue;
+
+ auto *op_alt = &recog_op_alt[alt * recog_data.n_operands];
+ auto cl = alternative_class (op_alt, opno);
+ /* The two extremes are easy:
+
+ - We should record the filter if CL matches the
+ allocno class.
+
+ - We should ignore the filter if CL and the allocno class
+ are disjoint. We'll either pick a different alternative
+ or reload the operand.
+
+ Things are trickier if the classes overlap. However:
+
+ - If the allocno class includes registers that are not
+ in CL, some choices of hard register will need a reload
+ anyway. It isn't obvious that reloads due to filters
+ are worse than reloads due to regnos being outside CL.
+
+ - Conversely, if the allocno class is a subset of CL,
+ any allocation will satisfy the class requirement.
+ We should try to make sure it satisfies the filter
+ requirement too. This is useful if, for example,
+ an allocno needs to be in "low" registers to satisfy
+ some uses, and its allocno class is therefore those
+ low registers, but the allocno is elsewhere allowed
+ to be in any even-numbered register. Picking an
+ even-numbered low register satisfies both types of use. */
+ if (!ira_class_subset_p[ALLOCNO_CLASS (a)][cl])
+ continue;
+
+ auto filters = alternative_register_filters (op_alt, opno);
+ if (!filters)
+ continue;
+
+ filters |= ALLOCNO_REGISTER_FILTERS (a);
+ ALLOCNO_SET_REGISTER_FILTERS (a, filters);
+ }
+ }
+ }
+}
+
/* Look through the CALL_INSN_FUNCTION_USAGE of a call insn INSN, and see if
we find a SET rtx that we can use to deduce that a register can be cheaply
caller-saved. Return such a register, or NULL_RTX if none is found. */
@@ -1378,6 +1438,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
}
preferred_alternatives = ira_setup_alts (insn);
+ process_register_constraint_filters ();
process_single_reg_class_operands (false, freq);
if (call_p)
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 0607c8b..9b6a2af 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -2149,6 +2149,7 @@ process_alt_operands (int only_alternative)
int reload_nregs, reload_sum;
bool costly_p;
enum reg_class cl;
+ const HARD_REG_SET *cl_filter;
/* Calculate some data common for all alternatives to speed up the
function. */
@@ -2514,6 +2515,7 @@ process_alt_operands (int only_alternative)
|| spilled_pseudo_p (op))
win = true;
cl = GENERAL_REGS;
+ cl_filter = nullptr;
goto reg;
default:
@@ -2523,7 +2525,10 @@ process_alt_operands (int only_alternative)
case CT_REGISTER:
cl = reg_class_for_constraint (cn);
if (cl != NO_REGS)
- goto reg;
+ {
+ cl_filter = get_register_filter (cn);
+ goto reg;
+ }
break;
case CT_CONST_INT:
@@ -2567,6 +2572,7 @@ process_alt_operands (int only_alternative)
win = true;
cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH);
+ cl_filter = nullptr;
badop = false;
goto reg;
@@ -2600,6 +2606,8 @@ process_alt_operands (int only_alternative)
this_alternative_exclude_start_hard_regs
|= ira_exclude_class_mode_regs[cl][mode];
this_alternative_set |= reg_class_contents[cl];
+ if (cl_filter)
+ this_alternative_exclude_start_hard_regs |= ~*cl_filter;
if (costly_p)
{
this_costly_alternative
@@ -2613,6 +2621,9 @@ process_alt_operands (int only_alternative)
if (hard_regno[nop] >= 0
&& in_hard_reg_set_p (this_alternative_set,
mode, hard_regno[nop])
+ && (!cl_filter
+ || TEST_HARD_REG_BIT (*cl_filter,
+ hard_regno[nop]))
&& ((REG_ATTRS (op) && (decl = REG_EXPR (op)) != NULL
&& VAR_P (decl) && DECL_HARD_REGISTER (decl))
|| !(TEST_HARD_REG_BIT
diff --git a/gcc/match.pd b/gcc/match.pd
index b30de36..95225e4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2596,6 +2596,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
|| TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))))
(op @0 @1))))
+/* And similar for pointers. */
+(for op (eq ne)
+ (simplify
+ (op (pointer_plus @0 @1) (pointer_plus @0 @2))
+ (op @1 @2)))
+(simplify
+ (pointer_diff (pointer_plus @0 @1) (pointer_plus @0 @2))
+ (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
+ (convert (minus @1 @2))))
/* X - Z < Y - Z is the same as X < Y when there is no overflow. */
(for op (lt le ge gt)
@@ -8285,7 +8294,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(simplify
(BIT_FIELD_REF (view_convert @0) @1 @2)
- (BIT_FIELD_REF @0 @1 @2))
+ (if (! INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ || type_has_mode_precision_p (TREE_TYPE (@0)))
+ (BIT_FIELD_REF @0 @1 @2)))
(simplify
(BIT_FIELD_REF @0 @1 integer_zerop)
diff --git a/gcc/objc/objc-act.cc b/gcc/objc/objc-act.cc
index fe19aa5..02ed6d9 100644
--- a/gcc/objc/objc-act.cc
+++ b/gcc/objc/objc-act.cc
@@ -10340,5 +10340,51 @@ objc_common_init_ts (void)
MARK_TS_TYPED (PROPERTY_REF);
}
+/* Information for Objective-C-specific features known to __has_feature. */
+
+struct objc_feature_info
+{
+ typedef bool (*predicate_t) ();
+
+ const char *ident;
+ predicate_t predicate;
+
+ constexpr objc_feature_info (const char *name)
+ : ident (name), predicate (nullptr) {}
+ constexpr objc_feature_info (const char *name, predicate_t p)
+ : ident (name), predicate (p) {}
+
+ bool has_feature () const
+ {
+ return predicate ? predicate () : true;
+ }
+};
+
+static bool objc_nonfragile_abi_p ()
+{
+ return flag_next_runtime && flag_objc_abi >= 2;
+}
+
+static constexpr objc_feature_info objc_features[] =
+{
+ { "objc_default_synthesize_properties" },
+ { "objc_instancetype" },
+ { "objc_nonfragile_abi", objc_nonfragile_abi_p }
+};
+
+/* Register Objective-C-specific features for __has_feature. */
+
+void
+objc_common_register_features ()
+{
+ for (unsigned i = 0; i < ARRAY_SIZE (objc_features); i++)
+ {
+ const objc_feature_info *info = objc_features + i;
+ if (!info->has_feature ())
+ continue;
+
+ c_common_register_feature (info->ident, true);
+ }
+}
#include "gt-objc-objc-act.h"
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index 68f9029..df40127 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -29,6 +29,9 @@ int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
void objc_common_init_ts (void);
const char *objc_get_sarif_source_language (const char *);
+/* Register features common to Objective-C and Objective-C++. */
+void objc_common_register_features ();
+
/* NB: The remaining public functions are prototyped in c-common.h, for the
benefit of stub-objc.cc and objc-act.cc. */
diff --git a/gcc/objc/objc-lang.cc b/gcc/objc/objc-lang.cc
index 8e56de6..107fb0e 100644
--- a/gcc/objc/objc-lang.cc
+++ b/gcc/objc/objc-lang.cc
@@ -56,6 +56,16 @@ objc_get_sarif_source_language (const char *)
return "objectivec";
}
+/* Implement c-family hook to add language-specific features
+ for __has_{feature,extension}. */
+
+void
+c_family_register_lang_features ()
+{
+ objc_common_register_features ();
+ c_register_features ();
+}
+
/* Lang hook routines common to C and ObjC appear in c-objc-common.cc;
there should be very few (if any) routines below. */
diff --git a/gcc/objcp/objcp-lang.cc b/gcc/objcp/objcp-lang.cc
index ee39aec..8a2c9f7 100644
--- a/gcc/objcp/objcp-lang.cc
+++ b/gcc/objcp/objcp-lang.cc
@@ -85,6 +85,16 @@ objcp_tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
#undef RECURSE
}
+/* Implement c-family hook to add language-specific features
+ for __has_{feature,extension}. */
+
+void
+c_family_register_lang_features ()
+{
+ objc_common_register_features ();
+ cp_register_features ();
+}
+
static void
objcxx_init_ts (void)
{
diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index 5c6a7f2..8281ec6 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -3416,8 +3416,9 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
forward = tree_int_cst_sgn (step) != -1;
}
if (forward ^ OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
- warning_at (loc, 0, "%qs clause with %<sink%> modifier "
- "waiting for lexically later iteration",
+ warning_at (loc, OPT_Wopenmp,
+ "%qs clause with %<sink%> modifier "
+ "waiting for lexically later iteration",
OMP_CLAUSE_DOACROSS_DEPEND (c)
? "depend" : "doacross");
break;
@@ -3555,9 +3556,9 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
build_int_cst (itype, 0));
if (integer_zerop (t) && !warned_step)
{
- warning_at (loc, 0, "%qs clause with %<sink%> modifier "
- "refers to iteration never in the iteration "
- "space",
+ warning_at (loc, OPT_Wopenmp,
+ "%qs clause with %<sink%> modifier refers to "
+ "iteration never in the iteration space",
OMP_CLAUSE_DOACROSS_DEPEND (c)
? "depend" : "doacross");
warned_step = true;
diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc
index b88d593..8241574 100644
--- a/gcc/omp-general.cc
+++ b/gcc/omp-general.cc
@@ -1201,12 +1201,12 @@ omp_check_context_selector (location_t loc, tree ctx)
return error_mark_node;
}
else if (TREE_PURPOSE (t2))
- warning_at (loc, 0,
+ warning_at (loc, OPT_Wopenmp,
"unknown property %qs of %qs selector",
IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
props[i].selector);
else
- warning_at (loc, 0,
+ warning_at (loc, OPT_Wopenmp,
"unknown property %qE of %qs selector",
TREE_VALUE (t2), props[i].selector);
break;
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 161bcfe..dd802ca 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -2844,12 +2844,13 @@ scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
tree_code outer_op = OMP_CLAUSE_REDUCTION_CODE (outer_clause);
if (outer_var == local_var && outer_op != local_op)
{
- warning_at (OMP_CLAUSE_LOCATION (local_clause), 0,
- "conflicting reduction operations for %qE",
- local_var);
- inform (OMP_CLAUSE_LOCATION (outer_clause),
- "location of the previous reduction for %qE",
- outer_var);
+ if (warning_at (OMP_CLAUSE_LOCATION (local_clause),
+ OPT_Wopenmp, "conflicting reduction "
+ "operations for %qE",
+ local_var))
+ inform (OMP_CLAUSE_LOCATION (outer_clause),
+ "location of the previous reduction for %qE",
+ outer_var);
}
if (outer_var == local_var)
{
@@ -2880,7 +2881,7 @@ scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
}
}
if (!found)
- warning_at (gimple_location (curr_loop->stmt), 0,
+ warning_at (gimple_location (curr_loop->stmt), OPT_Wopenmp,
"nested loop in reduction needs "
"reduction clause for %qE",
local_var);
@@ -3427,12 +3428,12 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
ctx->cancellable = true;
if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
OMP_CLAUSE_NOWAIT))
- warning_at (gimple_location (stmt), 0,
+ warning_at (gimple_location (stmt), OPT_Wopenmp,
"%<cancel for%> inside "
"%<nowait%> for construct");
if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
OMP_CLAUSE_ORDERED))
- warning_at (gimple_location (stmt), 0,
+ warning_at (gimple_location (stmt), OPT_Wopenmp,
"%<cancel for%> inside "
"%<ordered%> for construct");
}
@@ -3452,7 +3453,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
if (omp_find_clause (gimple_omp_sections_clauses
(ctx->stmt),
OMP_CLAUSE_NOWAIT))
- warning_at (gimple_location (stmt), 0,
+ warning_at (gimple_location (stmt), OPT_Wopenmp,
"%<cancel sections%> inside "
"%<nowait%> sections construct");
}
@@ -3465,7 +3466,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
if (omp_find_clause (gimple_omp_sections_clauses
(ctx->outer->stmt),
OMP_CLAUSE_NOWAIT))
- warning_at (gimple_location (stmt), 0,
+ warning_at (gimple_location (stmt), OPT_Wopenmp,
"%<cancel sections%> inside "
"%<nowait%> sections construct");
}
@@ -3928,7 +3929,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
break;
}
- warning_at (gimple_location (stmt), 0,
+ warning_at (gimple_location (stmt), OPT_Wopenmp,
"%qs construct inside of %qs region",
stmt_name, ctx_stmt_name);
}
@@ -9783,8 +9784,8 @@ lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
wi::abs (wi::to_wide (fd.loops[i].step)),
UNSIGNED))
{
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
- "ignoring sink clause with offset that is not "
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
+ "ignoring %<sink%> clause with offset that is not "
"a multiple of the loop step");
remove = true;
goto next_ordered_clause;
diff --git a/gcc/omp-simd-clone.cc b/gcc/omp-simd-clone.cc
index 57b0793..3fbe428 100644
--- a/gcc/omp-simd-clone.cc
+++ b/gcc/omp-simd-clone.cc
@@ -387,13 +387,13 @@ simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
step = fold_convert (ssizetype, step);
if (!tree_fits_shwi_p (step))
{
- warning_at (OMP_CLAUSE_LOCATION (t), 0,
+ warning_at (OMP_CLAUSE_LOCATION (t), OPT_Wopenmp,
"ignoring large linear step");
return NULL;
}
else if (integer_zerop (step))
{
- warning_at (OMP_CLAUSE_LOCATION (t), 0,
+ warning_at (OMP_CLAUSE_LOCATION (t), OPT_Wopenmp,
"ignoring zero linear step");
return NULL;
}
@@ -455,7 +455,7 @@ simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
out:
if (TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (node->decl))))
{
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wopenmp,
"ignoring %<#pragma omp declare simd%> on function "
"with %<_Atomic%> qualified return type");
return NULL;
@@ -465,7 +465,7 @@ simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
if (TYPE_ATOMIC (args[argno])
&& clone_info->args[argno].arg_type != SIMD_CLONE_ARG_TYPE_UNIFORM)
{
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wopenmp,
"ignoring %<#pragma omp declare simd%> on function "
"with %<_Atomic%> qualified non-%<uniform%> argument");
args.release ();
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 33165c9..5d5efaf 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -42,6 +42,10 @@ along with GCC; see the file COPYING3. If not see
/* Set by -fcanon-prefix-map. */
bool flag_canon_prefix_map;
+/* Set by finish_options when flag_stack_protector was set only because of
+ -fhardened. Yuck. */
+bool flag_stack_protector_set_by_fhardened_p;
+
static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
/* Names of fundamental debug info formats indexed by enum
@@ -1092,6 +1096,17 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
opts->x_flag_section_anchors = 0;
}
+ if (opts->x_flag_hardened)
+ {
+ if (!opts_set->x_flag_auto_var_init)
+ opts->x_flag_auto_var_init = AUTO_INIT_ZERO;
+ else if (opts->x_flag_auto_var_init != AUTO_INIT_ZERO)
+ warning_at (loc, OPT_Whardened,
+ "%<-ftrivial-auto-var-init=zero%> is not enabled by "
+ "%<-fhardened%> because it was specified on the command "
+ "line");
+ }
+
if (!opts->x_flag_opts_finished)
{
/* We initialize opts->x_flag_pie to -1 so that targets can set a
@@ -1101,7 +1116,8 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
/* We initialize opts->x_flag_pic to -1 so that we can tell if
-fpic, -fPIC, -fno-pic or -fno-PIC is used. */
if (opts->x_flag_pic == -1)
- opts->x_flag_pie = DEFAULT_FLAG_PIE;
+ opts->x_flag_pie = (opts->x_flag_hardened
+ ? /*-fPIE*/ 2 : DEFAULT_FLAG_PIE);
else
opts->x_flag_pie = 0;
}
@@ -1116,9 +1132,29 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
}
/* We initialize opts->x_flag_stack_protect to -1 so that targets
- can set a default value. */
+ can set a default value. With --enable-default-ssp or -fhardened
+ the default is -fstack-protector-strong. */
if (opts->x_flag_stack_protect == -1)
- opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
+ {
+ /* This should check FRAME_GROWS_DOWNWARD, but on some targets it's
+ defined in such a way that it uses flag_stack_protect which can't
+ be used here. Moreover, some targets like BPF don't support
+ -fstack-protector at all but we don't know that here. So remember
+ that flag_stack_protect was set at the behest of -fhardened. */
+ if (opts->x_flag_hardened)
+ {
+ opts->x_flag_stack_protect = SPCT_FLAG_STRONG;
+ flag_stack_protector_set_by_fhardened_p = true;
+ }
+ else
+ opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
+ }
+ else if (opts->x_flag_hardened
+ && opts->x_flag_stack_protect != SPCT_FLAG_STRONG)
+ warning_at (UNKNOWN_LOCATION, OPT_Whardened,
+ "%<-fstack-protector-strong%> is not enabled by "
+ "%<-fhardened%> because it was specified on the command "
+ "line");
if (opts->x_optimize == 0)
{
@@ -2460,6 +2496,30 @@ parse_and_check_patch_area (const char *arg, bool report_error,
free (patch_area_arg);
}
+/* Print options enabled by -fhardened. Keep this in sync with the manual! */
+
+static void
+print_help_hardened ()
+{
+ printf ("%s\n", "The following options are enabled by -fhardened:");
+ /* Unfortunately, I can't seem to use targetm.fortify_source_default_level
+ here. */
+ printf (" %s\n", "-D_FORTIFY_SOURCE=3 (or =2 for glibc < 2.35)");
+ printf (" %s\n", "-D_GLIBCXX_ASSERTIONS");
+ printf (" %s\n", "-ftrivial-auto-var-init=zero");
+#ifdef HAVE_LD_PIE
+ printf (" %s %s\n", "-fPIE", "-pie");
+#endif
+ if (HAVE_LD_NOW_SUPPORT)
+ printf (" %s\n", "-Wl,-z,now");
+ if (HAVE_LD_RELRO_SUPPORT)
+ printf (" %s\n", "-Wl,-z,relro");
+ printf (" %s\n", "-fstack-protector-strong");
+ printf (" %s\n", "-fstack-clash-protection");
+ printf (" %s\n", "-fcf-protection=full");
+ putchar ('\n');
+}
+
/* Print help when OPT__help_ is set. */
void
@@ -2575,6 +2635,8 @@ print_help (struct gcc_options *opts, unsigned int lang_mask,
}
else if (lang_flag != 0)
*pflags |= lang_flag;
+ else if (strncasecmp (a, "hardened", len) == 0)
+ print_help_hardened ();
else
warning (0,
"unrecognized argument to %<--help=%> option: %q.*s",
diff --git a/gcc/opts.h b/gcc/opts.h
index 00f377f..d89c5de 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -344,6 +344,7 @@ struct cl_option_handlers
/* Hold command-line options associated with stack limitation. */
extern const char *opt_fstack_limit_symbol_arg;
extern int opt_fstack_limit_register_no;
+extern bool flag_stack_protector_set_by_fhardened_p;
/* Input file names. */
diff --git a/gcc/recog.cc b/gcc/recog.cc
index 3bd2d73..eaab79c 100644
--- a/gcc/recog.cc
+++ b/gcc/recog.cc
@@ -2857,6 +2857,7 @@ preprocess_constraints (int n_operands, int n_alternatives,
for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
{
op_alt[i].cl = NO_REGS;
+ op_alt[i].register_filters = 0;
op_alt[i].constraint = p;
op_alt[i].matches = -1;
op_alt[i].matched = -1;
@@ -2919,7 +2920,12 @@ preprocess_constraints (int n_operands, int n_alternatives,
case CT_REGISTER:
cl = reg_class_for_constraint (cn);
if (cl != NO_REGS)
- op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
+ {
+ op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
+ auto filter_id = get_register_filter_id (cn);
+ if (filter_id >= 0)
+ op_alt[i].register_filters |= 1U << filter_id;
+ }
break;
case CT_CONST_INT:
@@ -3219,13 +3225,17 @@ constrain_operands (int strict, alternative_mask alternatives)
enum reg_class cl = reg_class_for_constraint (cn);
if (cl != NO_REGS)
{
+ auto *filter = get_register_filter (cn);
if (strict < 0
|| (strict == 0
&& REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER)
|| (strict == 0 && GET_CODE (op) == SCRATCH)
|| (REG_P (op)
- && reg_fits_class_p (op, cl, offset, mode)))
+ && reg_fits_class_p (op, cl, offset, mode)
+ && (!filter
+ || TEST_HARD_REG_BIT (*filter,
+ REGNO (op) + offset))))
win = true;
}
diff --git a/gcc/recog.h b/gcc/recog.h
index c6ef619..5c801e7 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -42,6 +42,7 @@ enum op_type {
OP_INOUT
};
+#ifndef GENERATOR_FILE
struct operand_alternative
{
/* Pointer to the beginning of the constraint string for this alternative,
@@ -62,6 +63,11 @@ struct operand_alternative
matches this one. */
int matched : 8;
+ /* Bit ID is set if the constraint string includes a register constraint with
+ register filter ID. Use test_register_filters (REGISTER_FILTERS, REGNO)
+ to test whether REGNO is a valid start register for the operand. */
+ unsigned int register_filters : MAX (NUM_REGISTER_FILTERS, 1);
+
/* Nonzero if '&' was found in the constraint string. */
unsigned int earlyclobber : 1;
/* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint
@@ -72,8 +78,6 @@ struct operand_alternative
/* Nonzero if 'X' was found in the constraint string, or if the constraint
string for this alternative was empty. */
unsigned int anything_ok : 1;
-
- unsigned int unused : 12;
};
/* Return the class for operand I of alternative ALT, taking matching
@@ -85,6 +89,18 @@ alternative_class (const operand_alternative *alt, int i)
return alt[i].matches >= 0 ? alt[alt[i].matches].cl : alt[i].cl;
}
+/* Return the mask of register filters that should be applied to operand I
+ of alternative ALT, taking matching constraints into account. */
+
+inline unsigned int
+alternative_register_filters (const operand_alternative *alt, int i)
+{
+ return (alt[i].matches >= 0
+ ? alt[alt[i].matches].register_filters
+ : alt[i].register_filters);
+}
+#endif
+
/* A class for substituting one rtx for another within an instruction,
or for recursively simplifying the instruction as-is. Derived classes
can record or filter certain decisions. */
@@ -242,9 +258,11 @@ extern void extract_insn (rtx_insn *);
extern void extract_constrain_insn (rtx_insn *insn);
extern void extract_constrain_insn_cached (rtx_insn *);
extern void extract_insn_cached (rtx_insn *);
+#ifndef GENERATOR_FILE
extern void preprocess_constraints (int, int, const char **,
operand_alternative *, rtx **);
extern const operand_alternative *preprocess_insn_constraints (unsigned int);
+#endif
extern void preprocess_constraints (rtx_insn *);
extern rtx_insn *peep2_next_insn (int);
extern bool peep2_regno_dead_p (int, int);
@@ -380,6 +398,7 @@ struct recog_data_d
extern struct recog_data_d recog_data;
+#ifndef GENERATOR_FILE
extern const operand_alternative *recog_op_alt;
/* Return a pointer to an array in which index OP describes the constraints
@@ -393,6 +412,7 @@ which_op_alt ()
recog_data.n_alternatives - 1));
return &recog_op_alt[which_alternative * recog_data.n_operands];
}
+#endif
/* A table defined in insn-output.cc that give information about
each insn-code value. */
diff --git a/gcc/reginfo.cc b/gcc/reginfo.cc
index d472a35..5b6e706 100644
--- a/gcc/reginfo.cc
+++ b/gcc/reginfo.cc
@@ -140,6 +140,9 @@ reginfo_cc_finalize (void)
CLEAR_HARD_REG_SET (global_reg_set);
}
+/* In insn-preds.cc. */
+extern void init_reg_class_start_regs ();
+
/* Given a register bitmap, turn on the bits in a HARD_REG_SET that
correspond to the hard registers, if any, set in that map. This
could be done far more efficiently by having all sorts of special-cases
@@ -198,6 +201,8 @@ init_reg_sets (void)
SET_HARD_REG_SET (accessible_reg_set);
SET_HARD_REG_SET (operand_reg_set);
+
+ init_reg_class_start_regs ();
}
/* We need to save copies of some of the register information which
diff --git a/gcc/rtl-ssa/access-utils.h b/gcc/rtl-ssa/access-utils.h
index f078625b..9a62add 100644
--- a/gcc/rtl-ssa/access-utils.h
+++ b/gcc/rtl-ssa/access-utils.h
@@ -78,6 +78,46 @@ drop_memory_access (T accesses)
return T (arr.begin (), accesses.size () - 1);
}
+// Filter ACCESSES to return an access_array of only those accesses that
+// satisfy PREDICATE. Alocate the new array above WATERMARK.
+template<typename T, typename FilterPredicate>
+inline T
+filter_accesses (obstack_watermark &watermark,
+ T accesses,
+ FilterPredicate predicate)
+{
+ access_array_builder builder (watermark);
+ builder.reserve (accesses.size ());
+ for (auto access : accesses)
+ if (predicate (access))
+ builder.quick_push (access);
+ return T (builder.finish ());
+}
+
+// Given an array of ACCESSES, remove any access with regno REGNO.
+// Allocate the new access array above WM.
+template<typename T>
+inline T
+remove_regno_access (obstack_watermark &watermark,
+ T accesses, unsigned int regno)
+{
+ using Access = decltype (accesses[0]);
+ auto pred = [regno](Access a) { return a->regno () != regno; };
+ return filter_accesses (watermark, accesses, pred);
+}
+
+// As above, but additionally check that we actually did remove an access.
+template<typename T>
+inline T
+check_remove_regno_access (obstack_watermark &watermark,
+ T accesses, unsigned regno)
+{
+ auto orig_size = accesses.size ();
+ auto result = remove_regno_access (watermark, accesses, regno);
+ gcc_assert (result.size () < orig_size);
+ return result;
+}
+
// If sorted array ACCESSES includes a reference to REGNO, return the
// access, otherwise return null.
template<typename T>
diff --git a/gcc/rtl-ssa/accesses.cc b/gcc/rtl-ssa/accesses.cc
index 510545a..9ec0e6b 100644
--- a/gcc/rtl-ssa/accesses.cc
+++ b/gcc/rtl-ssa/accesses.cc
@@ -1456,6 +1456,16 @@ function_info::make_uses_available (obstack_watermark &watermark,
return use_array (new_uses, num_uses);
}
+set_info *
+function_info::create_set (obstack_watermark &watermark,
+ insn_info *insn,
+ resource_info resource)
+{
+ auto set = change_alloc<set_info> (watermark, insn, resource);
+ set->m_is_temp = true;
+ return set;
+}
+
// Return true if ACCESS1 can represent ACCESS2 and if ACCESS2 can
// represent ACCESS1.
static bool
@@ -1587,16 +1597,14 @@ access_array
rtl_ssa::remove_note_accesses_base (obstack_watermark &watermark,
access_array accesses)
{
+ auto predicate = [](access_info *a) {
+ return !a->only_occurs_in_notes ();
+ };
+
for (access_info *access : accesses)
if (access->only_occurs_in_notes ())
- {
- access_array_builder builder (watermark);
- builder.reserve (accesses.size ());
- for (access_info *access2 : accesses)
- if (!access2->only_occurs_in_notes ())
- builder.quick_push (access2);
- return builder.finish ();
- }
+ return filter_accesses (watermark, accesses, predicate);
+
return accesses;
}
diff --git a/gcc/rtl-ssa/accesses.h b/gcc/rtl-ssa/accesses.h
index fce31d4..7e7a90e 100644
--- a/gcc/rtl-ssa/accesses.h
+++ b/gcc/rtl-ssa/accesses.h
@@ -204,6 +204,10 @@ public:
// in the main instruction pattern.
bool only_occurs_in_notes () const { return m_only_occurs_in_notes; }
+ // Return true if this is a temporary access, e.g. one created for
+ // an insn that is about to be inserted.
+ bool is_temporary () const { return m_is_temp; }
+
protected:
access_info (resource_info, access_kind);
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index aab532b..2f2d12d 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -394,14 +394,20 @@ move_insn (insn_change &change, insn_info *after)
// At the moment we don't support moving instructions between EBBs,
// but this would be worth adding if it's useful.
insn_info *insn = change.insn ();
- gcc_assert (after->ebb () == insn->ebb ());
+
bb_info *bb = after->bb ();
basic_block cfg_bb = bb->cfg_bb ();
- if (insn->bb () != bb)
- // Force DF to mark the old block as dirty.
- df_insn_delete (rtl);
- ::remove_insn (rtl);
+ if (!insn->is_temporary ())
+ {
+ gcc_assert (after->ebb () == insn->ebb ());
+
+ if (insn->bb () != bb)
+ // Force DF to mark the old block as dirty.
+ df_insn_delete (rtl);
+ ::remove_insn (rtl);
+ }
+
::add_insn_after (rtl, after_rtl, cfg_bb);
}
@@ -437,12 +443,33 @@ function_info::finalize_new_accesses (insn_change &change, insn_info *pos)
{
def_info *def = find_access (change.new_defs, ref.regno);
gcc_assert (def);
+
+ if (def->m_is_temp && is_a<set_info *> (def) && def->last_def ())
+ {
+ // For temporary sets being added with this change, we keep track of
+ // the corresponding permanent def using the last_def link.
+ //
+ // So if we have one of these, follow it to get the permanent def.
+ def = def->last_def ();
+ gcc_assert (!def->m_is_temp && !def->m_has_been_superceded);
+ }
+
if (def->m_is_temp)
{
- // At present, the only temporary instruction definitions we
- // create are clobbers, such as those added during recog.
- gcc_assert (is_a<clobber_info *> (def));
- def = allocate<clobber_info> (change.insn (), ref.regno);
+ if (is_a<clobber_info *> (def))
+ def = allocate<clobber_info> (change.insn (), ref.regno);
+ else if (is_a<set_info *> (def))
+ {
+ // Install the permanent set in the last_def link of the
+ // temporary def. This allows us to find the permanent def
+ // later in case we see a second write to the same resource.
+ def_info *perm_def = allocate<set_info> (change.insn (),
+ def->resource ());
+ def->set_last_def (perm_def);
+ def = perm_def;
+ }
+ else
+ gcc_unreachable ();
}
else if (!def->m_has_been_superceded)
{
@@ -645,6 +672,8 @@ function_info::apply_changes_to_insn (insn_change &change)
insn->set_accesses (builder.finish ().begin (), num_defs, num_uses);
}
+
+ insn->m_is_temp = false;
}
// Add a temporary placeholder instruction after AFTER.
@@ -677,7 +706,8 @@ function_info::change_insns (array_slice<insn_change *> changes)
if (!change->is_deletion ())
{
// Remove any notes that are no longer relevant.
- update_notes (change->rtl ());
+ if (!change->insn ()->m_is_temp)
+ update_notes (change->rtl ());
// Make sure that the placement of this instruction would still
// leave room for previous instructions.
@@ -686,6 +716,17 @@ function_info::change_insns (array_slice<insn_change *> changes)
// verify_insn_changes is supposed to make sure that this holds.
gcc_unreachable ();
min_insn = later_insn (min_insn, change->move_range.first);
+
+ if (change->insn ()->m_is_temp)
+ {
+ change->m_insn = allocate<insn_info> (change->insn ()->bb (),
+ change->rtl (),
+ change->insn_uid ());
+
+ // Set the flag again so subsequent logic is aware.
+ // It will be cleared later on.
+ change->m_insn->m_is_temp = true;
+ }
}
}
@@ -784,7 +825,8 @@ function_info::change_insns (array_slice<insn_change *> changes)
// Remove the placeholder first so that we have a wider range of
// program points when inserting INSN.
insn_info *after = placeholder->prev_any_insn ();
- remove_insn (insn);
+ if (!insn->is_temporary ())
+ remove_insn (insn);
remove_insn (placeholder);
insn->set_bb (after->bb ());
add_insn_after (insn, after);
@@ -1105,6 +1147,28 @@ function_info::perform_pending_updates ()
return changed_cfg;
}
+insn_info *
+function_info::create_insn (obstack_watermark &watermark,
+ rtx_code insn_code,
+ rtx pat)
+{
+ rtx_insn *rti = nullptr;
+
+ // TODO: extend, move in to emit-rtl.cc.
+ switch (insn_code)
+ {
+ case INSN:
+ rti = make_insn_raw (pat);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ auto insn = change_alloc<insn_info> (watermark, nullptr, rti, INSN_UID (rti));
+ insn->m_is_temp = true;
+ return insn;
+}
+
// Print a description of CHANGE to PP.
void
rtl_ssa::pp_insn_change (pretty_printer *pp, const insn_change &change)
diff --git a/gcc/rtl-ssa/changes.h b/gcc/rtl-ssa/changes.h
index d56e3a6..d91cf43 100644
--- a/gcc/rtl-ssa/changes.h
+++ b/gcc/rtl-ssa/changes.h
@@ -32,6 +32,8 @@ namespace rtl_ssa {
// something that we might do.
class insn_change
{
+ friend class function_info;
+
public:
enum delete_action { DELETE };
diff --git a/gcc/rtl-ssa/functions.h b/gcc/rtl-ssa/functions.h
index ecb40fd..4ffd3fa 100644
--- a/gcc/rtl-ssa/functions.h
+++ b/gcc/rtl-ssa/functions.h
@@ -68,6 +68,16 @@ public:
// Return the SSA information for CFG_BB.
bb_info *bb (basic_block cfg_bb) const { return m_bbs[cfg_bb->index]; }
+ // Create a temporary def.
+ set_info *create_set (obstack_watermark &watermark,
+ insn_info *insn,
+ resource_info resource);
+
+ // Create a temporary insn with code INSN_CODE and pattern PAT.
+ insn_info *create_insn (obstack_watermark &watermark,
+ rtx_code insn_code,
+ rtx pat);
+
// Return a list of all the instructions in the function, in reverse
// postorder. The list includes both real and artificial instructions.
//
@@ -195,6 +205,10 @@ public:
// Print the contents of the function to PP.
void print (pretty_printer *pp) const;
+ // Allocate an object of type T above the obstack watermark WM.
+ template<typename T, typename... Ts>
+ T *change_alloc (obstack_watermark &wm, Ts... args);
+
private:
class bb_phi_info;
class build_info;
diff --git a/gcc/rtl-ssa/insns.cc b/gcc/rtl-ssa/insns.cc
index 5fde3f2..2fa48e0 100644
--- a/gcc/rtl-ssa/insns.cc
+++ b/gcc/rtl-ssa/insns.cc
@@ -192,6 +192,11 @@ insn_info::print_full (pretty_printer *pp) const
pp_newline_and_indent (pp, 0);
pp_string (pp, "has volatile refs");
}
+ if (m_is_temp)
+ {
+ pp_newline_and_indent (pp, 0);
+ pp_string (pp, "temporary");
+ }
}
pp_indentation (pp) -= 2;
}
diff --git a/gcc/rtl-ssa/insns.h b/gcc/rtl-ssa/insns.h
index a604fe2..6d05067 100644
--- a/gcc/rtl-ssa/insns.h
+++ b/gcc/rtl-ssa/insns.h
@@ -306,6 +306,8 @@ public:
// Print a full description of the instruction.
void print_full (pretty_printer *) const;
+ bool is_temporary () const { return m_is_temp; }
+
private:
// The first-order way of representing the order between instructions
// is to assign "program points", with higher point numbers coming
@@ -414,8 +416,11 @@ private:
unsigned int m_has_pre_post_modify : 1;
unsigned int m_has_volatile_refs : 1;
+ // Indicates the insn is a temporary / new user-allocated insn.
+ unsigned int m_is_temp : 1;
+
// For future expansion.
- unsigned int m_spare : 27;
+ unsigned int m_spare : 26;
// The program point at which the instruction occurs.
//
diff --git a/gcc/rtl-ssa/internals.inl b/gcc/rtl-ssa/internals.inl
index e49297c..907c450 100644
--- a/gcc/rtl-ssa/internals.inl
+++ b/gcc/rtl-ssa/internals.inl
@@ -415,6 +415,7 @@ inline insn_info::insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid)
m_is_asm (false),
m_has_pre_post_modify (false),
m_has_volatile_refs (false),
+ m_is_temp (false),
m_spare (0),
m_point (0),
m_cost_or_uid (cost_or_uid),
diff --git a/gcc/rtl-ssa/member-fns.inl b/gcc/rtl-ssa/member-fns.inl
index ce2db04..b8940ca 100644
--- a/gcc/rtl-ssa/member-fns.inl
+++ b/gcc/rtl-ssa/member-fns.inl
@@ -962,4 +962,16 @@ function_info::add_regno_clobber (obstack_watermark &watermark,
return true;
}
+template<typename T, typename... Ts>
+inline T *
+function_info::change_alloc (obstack_watermark &wm, Ts... args)
+{
+ static_assert (std::is_trivially_destructible<T>::value,
+ "destructor won't be called");
+ static_assert (alignof (T) <= obstack_alignment,
+ "too much alignment required");
+ void *addr = XOBNEW (wm, T);
+ return new (addr) T (std::forward<Ts> (args)...);
+}
+
}
diff --git a/gcc/rtl-ssa/movement.h b/gcc/rtl-ssa/movement.h
index ec076db..41226dd 100644
--- a/gcc/rtl-ssa/movement.h
+++ b/gcc/rtl-ssa/movement.h
@@ -182,6 +182,11 @@ restrict_movement_for_defs_ignoring (insn_range_info &move_range,
{
for (def_info *def : defs)
{
+ // Skip fresh defs that are being inserted, as these shouldn't
+ // constrain movement.
+ if (def->is_temporary ())
+ continue;
+
// If the definition is a clobber, we can move it with respect
// to other clobbers.
//
@@ -247,7 +252,8 @@ restrict_movement_for_defs_ignoring (insn_range_info &move_range,
// Make sure that we don't move stores between basic blocks, since we
// don't have enough information to tell whether it's safe.
- if (def_info *def = memory_access (defs))
+ def_info *def = memory_access (defs);
+ if (def && !def->is_temporary ())
{
move_range = move_later_than (move_range, def->bb ()->head_insn ());
move_range = move_earlier_than (move_range, def->bb ()->end_insn ());
diff --git a/gcc/rtl.def b/gcc/rtl.def
index 88e2b19..a40e1a7 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -1016,8 +1016,10 @@ DEF_RTL_EXPR(DEFINE_SPECIAL_PREDICATE, "define_special_predicate", "ses", RTX_EX
at -m switches and the like.
2: A docstring for this constraint, in Texinfo syntax; not currently
used, in future will be incorporated into the manual's list of
- machine-specific operand constraints. */
-DEF_RTL_EXPR(DEFINE_REGISTER_CONSTRAINT, "define_register_constraint", "sss", RTX_EXTRA)
+ machine-specific operand constraints.
+ 3: A C expression that evalutes to true if "regno" is a valid
+ start register. */
+DEF_RTL_EXPR(DEFINE_REGISTER_CONSTRAINT, "define_register_constraint", "sssS", RTX_EXTRA)
/* Definition of a non-register operand constraint. These look at the
operand and decide whether it fits the constraint.
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
index 186ff4c..f942a8f 100644
--- a/gcc/rust/ChangeLog
+++ b/gcc/rust/ChangeLog
@@ -1,3 +1,7 @@
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * rust-location.h: Include "rich-location.h".
+
2023-10-20 Patrick Palka <ppalka@redhat.com>
PR rust/111899
diff --git a/gcc/sort.cc b/gcc/sort.cc
index 9a0113f..feef345 100644
--- a/gcc/sort.cc
+++ b/gcc/sort.cc
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see
- deterministic (but not necessarily stable)
- fast, especially for common cases (0-5 elements of size 8 or 4)
- The implementation uses a network sort for up to 5 elements and
+ The implementation uses sorting networks for up to 5 elements and
a merge sort on top of that. Neither stage has branches depending on
comparator result, trading extra arithmetic for branch mispredictions. */
@@ -53,7 +53,7 @@ struct sort_ctx
char *out; // output buffer
size_t n; // number of elements
size_t size; // element size
- size_t nlim; // limit for network sort
+ size_t nlim; // limit for using sorting networks
};
/* Like sort_ctx, but for use with qsort_r-style comparators. Several
@@ -151,7 +151,7 @@ cmp1 (char *e0, char *e1, sort_ctx *c)
return x & (c->cmp (e0, e1) >> 31);
}
-/* Execute network sort on 2 to 5 elements from IN, placing them into C->OUT.
+/* Apply a sorting network to 2 to 5 elements from IN, placing them into C->OUT.
IN may be equal to C->OUT, in which case elements are sorted in place. */
template<typename sort_ctx>
static void
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index 3ed6162..5fd49a2 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -71,7 +71,7 @@ public:
= m_symtab->add_cgraph_insertion_hook (m_symtab_insertion, this);
}
- /* Enable insertion hook invocation. */
+ /* Disable insertion hook invocation. */
void disable_insertion_hook ()
{
if (m_symtab_insertion_hook != NULL)
diff --git a/gcc/system.h b/gcc/system.h
index e924152..16db87b 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1217,28 +1217,11 @@ helper_const_non_const_cast (const char *p)
#endif
#ifdef ENABLE_VALGRIND_ANNOTATIONS
-# ifdef HAVE_VALGRIND_MEMCHECK_H
-# include <valgrind/memcheck.h>
-# elif defined HAVE_MEMCHECK_H
-# include <memcheck.h>
-# else
-# include <valgrind.h>
-# endif
-/* Compatibility macros to let valgrind 3.1 work. */
-# ifndef VALGRIND_MAKE_MEM_NOACCESS
-# define VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_NOACCESS
-# endif
-# ifndef VALGRIND_MAKE_MEM_DEFINED
-# define VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_READABLE
-# endif
-# ifndef VALGRIND_MAKE_MEM_UNDEFINED
-# define VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_WRITABLE
-# endif
+#include <valgrind/memcheck.h>
#else
-/* Avoid #ifdef:s when we can help it. */
+/* VALGRIND_DISCARD unregisters the given block handle,
+ but our code misuses it for discarding annotations. */
#define VALGRIND_DISCARD(x)
-#define VALGRIND_MALLOCLIKE_BLOCK(w,x,y,z)
-#define VALGRIND_FREELIKE_BLOCK(x,y)
#endif
/* Macros to temporarily ignore some warnings. */
diff --git a/gcc/target-globals.cc b/gcc/target-globals.cc
index 81244b1..cfa0045 100644
--- a/gcc/target-globals.cc
+++ b/gcc/target-globals.cc
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "bb-reorder.h"
#include "lower-subreg.h"
#include "function-abi.h"
+#include "tm_p.h"
#if SWITCHABLE_TARGET
class target_globals default_target_globals = {
@@ -60,7 +61,8 @@ class target_globals default_target_globals = {
&default_target_builtins,
&default_target_gcse,
&default_target_bb_reorder,
- &default_target_lower_subreg
+ &default_target_lower_subreg,
+ &default_target_constraints
};
class target_globals *
@@ -84,6 +86,7 @@ save_target_globals (void)
g->gcse = XCNEW (struct target_gcse);
g->bb_reorder = XCNEW (struct target_bb_reorder);
g->lower_subreg = XCNEW (struct target_lower_subreg);
+ g->constraints = XCNEW (target_constraints);
restore_target_globals (g);
init_reg_sets ();
target_reinit ();
@@ -141,6 +144,7 @@ target_globals::~target_globals ()
XDELETE (gcse);
XDELETE (bb_reorder);
XDELETE (lower_subreg);
+ XDELETE (constraints);
}
}
diff --git a/gcc/target-globals.h b/gcc/target-globals.h
index daedf66..42f082c 100644
--- a/gcc/target-globals.h
+++ b/gcc/target-globals.h
@@ -38,6 +38,7 @@ extern struct target_builtins *this_target_builtins;
extern struct target_gcse *this_target_gcse;
extern struct target_bb_reorder *this_target_bb_reorder;
extern struct target_lower_subreg *this_target_lower_subreg;
+extern struct target_constraints *this_target_constraints;
#endif
class GTY(()) target_globals {
@@ -61,6 +62,7 @@ public:
struct target_gcse *GTY((skip)) gcse;
struct target_bb_reorder *GTY((skip)) bb_reorder;
struct target_lower_subreg *GTY((skip)) lower_subreg;
+ struct target_constraints *GTY((skip)) constraints;
};
#if SWITCHABLE_TARGET
@@ -89,6 +91,7 @@ restore_target_globals (class target_globals *g)
this_target_gcse = g->gcse;
this_target_bb_reorder = g->bb_reorder;
this_target_lower_subreg = g->lower_subreg;
+ this_target_constraints = g->constraints;
}
#endif
diff --git a/gcc/target.def b/gcc/target.def
index 475c55c..eae7959 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2671,6 +2671,13 @@ DEFHOOK
default_libc_has_fast_function)
DEFHOOK
+(fortify_source_default_level,
+ "This hook determines what value _FORTIFY_SOURCE will be set to when using\n\
+the command-line option -fhardened.",
+ unsigned, (void),
+ default_fortify_source_default_level)
+
+DEFHOOK
(libm_function_max_error,
"This hook determines expected maximum errors for math functions measured\n\
in ulps (units of the last place). 0 means 0.5ulps precision (correctly\n\
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index 6b5173b..a2dc733 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -1906,6 +1906,14 @@ bsd_libc_has_function (enum function_class fn_class,
return false;
}
+/* By default, -fhardened will add -D_FORTIFY_SOURCE=2. */
+
+unsigned
+default_fortify_source_default_level ()
+{
+ return 2;
+}
+
unsigned
default_libm_function_max_error (unsigned, machine_mode, bool)
{
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 0b35e8a..26695ab 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -219,6 +219,7 @@ extern bool default_libc_has_fast_function (int fcode);
extern bool no_c99_libc_has_function (enum function_class, tree);
extern bool gnu_libc_has_function (enum function_class, tree);
extern bool bsd_libc_has_function (enum function_class, tree);
+extern unsigned default_fortify_source_default_level (void);
extern unsigned default_libm_function_max_error (unsigned, machine_mode, bool);
extern unsigned glibc_linux_libm_function_max_error (unsigned, machine_mode,
bool);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 53e7e89..e331429 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,1413 @@
+2023-11-26 Hans-Peter Nilsson <hp@axis.com>
+
+ * gcc.dg/uninit-pred-9_b.c: Remove xfail for line 20. Pass
+ --param=logical-op-non-short-circuit=0. Comment why.
+
+2023-11-26 Hans-Peter Nilsson <hp@axis.com>
+
+ * gcc.dg/uninit-pred-9_b.c: Remove xfail for MMIX from line 23.
+
+2023-11-26 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/111880
+ * gfortran.dg/pr111880.f90: New test.
+
+2023-11-26 John David Anglin <danglin@gcc.gnu.org>
+
+ * gcc.dg/analyzer/strndup-1.c: Skip on hppa*-*-hpux*.
+
+2023-11-26 John David Anglin <danglin@gcc.gnu.org>
+
+ * gcc.dg/analyzer/fd-glibc-datagram-client.c: Skip on hppa*-*-hpux*.
+ * gcc.dg/analyzer/fd-glibc-datagram-socket.c: Likewise.
+
+2023-11-26 John David Anglin <danglin@gcc.gnu.org>
+
+ * g++.dg/pr104869.C: Add attribute visibility default to
+ main prototype.
+
+2023-11-26 John David Anglin <danglin@gcc.gnu.org>
+
+ * g++.dg/modules/bad-mapper-1.C: Add hppa*-*-hpux* to dg-error
+ "this-will-not-work" targets.
+
+2023-11-26 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gcc.target/i386/cf_check-6.c: Only run on Linux.
+
+2023-11-26 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gcc.target/i386/pr112686.c: Add a requirement for split_stack.
+
+2023-11-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112599
+ * gcc.target/riscv/rvv/base/vf_avl-1.c: Adapt test.
+ * gcc.target/riscv/rvv/autovec/pr112599-3.c: New test.
+
+2023-11-26 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR testsuite/112691
+ * gcc.dg/vla-1.c: Add -fno-ipa-vrp.
+ Remove noipa from f1.
+
+2023-11-26 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR testsuite/112688
+ * gcc.target/aarch64/simd/vmulx.x (foo32): Mark as noipa rather
+ than noinline.
+ (foo4): Likewise.
+
+2023-11-26 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR testsuite/108321
+ * g++.dg/contracts/contracts-tmpl-spec2.C: Add -fsigned-char
+ to options.
+
+2023-11-25 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR testsuite/112688
+ * gcc.target/aarch64/movk.c: Add noipa on dummy_number_generator
+ and remove -fno-inline option.
+
+2023-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/111408
+ * gcc.c-torture/execute/pr111408.c: New test.
+
+2023-11-25 Andrew Pinski <pinskia@gmail.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/109977
+ * gcc.dg/pr109977.c: New test.
+
+2023-11-25 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ * g++.dg/modules/using-10.C: New test.
+ * g++.dg/modules/using-enum-2.C: New test.
+
+2023-11-25 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/102341
+ * g++.dg/modules/export-1.C: Adjust test.
+ * g++.dg/modules/export-2_a.C: New test.
+ * g++.dg/modules/export-2_b.C: New test.
+
+2023-11-24 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR pch/112319
+ * g++.dg/pch/pr112319.C: New test.
+ * g++.dg/pch/pr112319.Hs: New test.
+ * gcc.dg/pch/pr112319.c: New test.
+ * gcc.dg/pch/pr112319.hs: New test.
+
+2023-11-24 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/109849
+ * g++.dg/tree-ssa/pr109849.C: New test.
+ * g++.dg/tree-ssa/sra-eh-1.C: Likewise.
+ * gcc.dg/tree-ssa/pr109849.c: Likewise.
+ * gcc.dg/tree-ssa/sra-longjmp-1.c: Likewise.
+ * gfortran.dg/pr43984.f90: Added -fno-tree-sra to dg-options.
+
+2023-11-24 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/112686
+ * gcc.target/i386/pr112686.c: New test.
+
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * c-c++-common/gomp/depobj-3.c: New test.
+ * gfortran.dg/gomp/depobj-3.f90: New test.
+
+2023-11-24 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/99232
+ * g++.dg/modules/pr99232_a.C: New test.
+ * g++.dg/modules/pr99232_b.C: New test.
+
+2023-11-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112694
+ * gcc.target/riscv/rvv/autovec/pr112694-1.c: New test.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/112681
+ * gcc.target/i386/sse4-pr112681.c: New test.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/112673
+ * gcc.dg/pr112673.c: New test.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112679
+ * gcc.dg/bitint-42.c: New test.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112668
+ * gcc.dg/bitint-40.c: New test.
+
+2023-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/112619
+ * g++.dg/eh/pr112619.C: New test.
+
+2023-11-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112599
+ * gcc.target/riscv/rvv/autovec/pr112599-2.c: New test.
+
+2023-11-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c: Adapt test.
+ * gcc.target/riscv/rvv/autovec/vls/perm-4.c: Ditto.
+
+2023-11-24 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/107398
+ * g++.dg/modules/lambda-6_a.C: New test.
+ * g++.dg/modules/lambda-6_b.C: New test.
+
+2023-11-24 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/98885
+ * g++.dg/modules/export-1.C: Adjust error messages. Remove
+ xfails for working case. Add new test case.
+
+2023-11-23 John David Anglin <danglin@gcc.gnu.org>
+
+ * g++.dg/modules/bad-mapper-1.C: Add hppa*-*-hpux* to dg-error
+ "-:failed mapper handshake communication" targets.
+
+2023-11-23 John David Anglin <danglin@gcc.gnu.org>
+
+ * gcc.dg/analyzer/fd-4.c: Define _MODE_T on hpux.
+
+2023-11-23 John David Anglin <danglin@gcc.gnu.org>
+
+ * g++.dg/pr104869.C: Export main on hpux.
+
+2023-11-23 Iain Sandoe <iain@sandoe.co.uk>
+
+ * lib/scanasm.exp: Allow multiple function start symbols,
+ taking the last as the function name.
+
+2023-11-23 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104819
+ * gfortran.dg/assumed_rank_10.f90: Add MOLD argument to NULL().
+ * gfortran.dg/assumed_rank_8.f90: Likewise.
+
+2023-11-23 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/112609
+ * gfortran.dg/system_clock_1.f90: Add option -std=f2003.
+ * gfortran.dg/system_clock_3.f08: Add option -std=f2008.
+ * gfortran.dg/system_clock_4.f90: New test.
+
+2023-11-23 John David Anglin <danglin@gcc.gnu.org>
+
+ * g++.dg/cpp0x/initlist-const1.C: xfail scan-assembler-not
+ check on hppa*-*-hpux*.
+
+2023-11-23 John David Anglin <danglin@gcc.gnu.org>
+
+ * c-c++-common/Wattributes.c: Don't skip check for warning
+ at line 411 in Wattributes.c on hppa*64*-*-*.
+
+2023-11-23 Marek Polacek <polacek@redhat.com>
+
+ * gcc.misc-tests/help.exp: Test -fhardened.
+ * c-c++-common/fhardened-1.S: New test.
+ * c-c++-common/fhardened-1.c: New test.
+ * c-c++-common/fhardened-10.c: New test.
+ * c-c++-common/fhardened-11.c: New test.
+ * c-c++-common/fhardened-12.c: New test.
+ * c-c++-common/fhardened-13.c: New test.
+ * c-c++-common/fhardened-14.c: New test.
+ * c-c++-common/fhardened-15.c: New test.
+ * c-c++-common/fhardened-2.c: New test.
+ * c-c++-common/fhardened-3.c: New test.
+ * c-c++-common/fhardened-4.c: New test.
+ * c-c++-common/fhardened-5.c: New test.
+ * c-c++-common/fhardened-6.c: New test.
+ * c-c++-common/fhardened-7.c: New test.
+ * c-c++-common/fhardened-8.c: New test.
+ * c-c++-common/fhardened-9.c: New test.
+ * gcc.target/i386/cf_check-6.c: New test.
+
+2023-11-23 Maciej W. Rozycki <macro@embecosm.com>
+
+ * lib/scanasm.exp (scan-assembler-times): Remove the `-inline'
+ option to `regexp' and the wrapping `llength' call.
+
+2023-11-23 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/aarch64/ccmp_1.c: Use non-capturing parentheses
+ with `scan-assembler-times'.
+
+2023-11-23 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/arm/pr53447-5.c: Use non-capturing parentheses with
+ `scan-assembler-times'.
+
+2023-11-23 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/112672
+ * gcc.target/i386/pr112672.c: New test.
+
+2023-11-23 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/89316
+ * g++.target/i386/pr89316.C: New test.
+ * gcc.target/i386/pr112605-1.c: New test.
+ * gcc.target/i386/pr112605-2.c: New test.
+ * gcc.target/i386/pr112605.c: New test.
+
+2023-11-23 Juergen Christ <jchrist@linux.ibm.com>
+
+ * gcc.target/s390/ccor.c: New test.
+
+2023-11-23 Juergen Christ <jchrist@linux.ibm.com>
+
+ * gcc.target/s390/int128load.c: New test.
+
+2023-11-23 Di Zhao <dizhao@os.amperecomputing.com>
+
+ * gcc.dg/pr110279-1.c: New test.
+
+2023-11-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112599
+ PR target/112670
+ * gcc.target/riscv/rvv/autovec/pr112599-1.c: New test.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112336
+ * gcc.dg/bitint-41.c: New test.
+
+2023-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/110879
+ * g++.dg/opt/pr110879.C: Require C++11 or later.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/builtin-stdc-bit-1.c: New test.
+ * gcc.dg/builtin-stdc-bit-2.c: New test.
+
+2023-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/110348
+ * g++.dg/cpp26/static_assert1.C: New test.
+ * g++.dg/cpp26/feat-cxx26.C (__cpp_static_assert): Expect
+ 202306L rather than 201411L.
+ * g++.dg/cpp0x/udlit-error1.C: Expect different diagnostics for
+ static_assert with user-defined literal.
+
+2023-11-23 Pan Li <pan2.li@intel.com>
+
+ PR target/111720
+ * gcc.target/riscv/rvv/base/pr111720-0.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-1.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-10.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-2.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-3.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-4.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-5.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-6.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-7.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-8.c: New test.
+ * gcc.target/riscv/rvv/base/pr111720-9.c: New test.
+
+2023-11-23 Hans-Peter Nilsson <hp@axis.com>
+
+ PR testsuite/106120
+ * g++.dg/warn/Wstringop-overflow-4.C:144 XFAIL bogus warning for
+ lp64 targets with c++98.
+
+2023-11-22 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/112633
+ * g++.dg/cpp0x/alias-decl-75.C: New test.
+
+2023-11-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * lib/plugin-support.exp: Update the expected path to an
+ in-tree build of libintl.
+
+2023-11-22 Iain Sandoe <iain@sandoe.co.uk>
+ Richard Sandiford <richard.sandiford@arm.com>
+
+ * lib/scanasm.exp: Initial handling for Mach-O function body scans.
+
+2023-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112344
+ * gcc.dg/torture/pr112344.c: New testcase.
+
+2023-11-22 Florian Weimer <fweimer@redhat.com>
+
+ * gcc.misc-tests/linkage-y.c (puts): Declare.
+ (main): Add int return type and return 0.
+
+2023-11-22 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112598
+ * gcc.target/riscv/rvv/autovec/pr112598-3.c: New test.
+
+2023-11-22 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/uxtl-combine-4.c: Fix typo.
+ * gcc.target/aarch64/uxtl-combine-5.c: Likewise.
+ * gcc.target/aarch64/uxtl-combine-6.c: Likewise.
+
+2023-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/112518
+ * gcc.target/i386/bmi2-pr112518.c: New test.
+
+2023-11-22 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/vect-shuf-fp.c: New test.
+
+2023-11-22 Hongyu Wang <hongyu.wang@intel.com>
+
+ * gcc.target/i386/apx-push2pop2-1.c: Adjust output scan.
+ * gcc.target/i386/apx-push2pop2_force_drap-1.c: Likewise.
+
+2023-11-22 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112598
+ * gcc.target/riscv/rvv/autovec/pr112598-2.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ PR target/111815
+ * gcc.dg/torture/pr111815.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/adddifne.c: New test.
+ * gcc.target/riscv/addsifne.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/adddibfne.c: New test.
+ * gcc.target/riscv/addsibfne.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdifeq-sfb.c: New test.
+ * gcc.target/riscv/movdifeq-thead.c: New test.
+ * gcc.target/riscv/movdifeq-ventana.c: New test.
+ * gcc.target/riscv/movdifeq-zicond.c: New test.
+ * gcc.target/riscv/movdifeq.c: New test.
+ * gcc.target/riscv/movsifeq-sfb.c: New test.
+ * gcc.target/riscv/movsifeq-thead.c: New test.
+ * gcc.target/riscv/movsifeq-ventana.c: New test.
+ * gcc.target/riscv/movsifeq-zicond.c: New test.
+ * gcc.target/riscv/movsifeq.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibfeq-ventana.c: New test.
+ * gcc.target/riscv/movdibfeq-zicond.c: New test.
+ * gcc.target/riscv/movdibfeq.c: New test.
+ * gcc.target/riscv/movsibfeq-ventana.c: New test.
+ * gcc.target/riscv/movsibfeq-zicond.c: New test.
+ * gcc.target/riscv/movsibfeq.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/adddifeq.c: New test.
+ * gcc.target/riscv/adddifge.c: New test.
+ * gcc.target/riscv/adddifgt.c: New test.
+ * gcc.target/riscv/adddifle.c: New test.
+ * gcc.target/riscv/adddiflt.c: New test.
+ * gcc.target/riscv/addsifeq.c: New test.
+ * gcc.target/riscv/addsifge.c: New test.
+ * gcc.target/riscv/addsifgt.c: New test.
+ * gcc.target/riscv/addsifle.c: New test.
+ * gcc.target/riscv/addsiflt.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/adddibfeq.c: New test.
+ * gcc.target/riscv/adddibfge.c: New test.
+ * gcc.target/riscv/adddibfgt.c: New test.
+ * gcc.target/riscv/adddibfle.c: New test.
+ * gcc.target/riscv/adddibflt.c: New test.
+ * gcc.target/riscv/addsibfeq.c: New test.
+ * gcc.target/riscv/addsibfge.c: New test.
+ * gcc.target/riscv/addsibfgt.c: New test.
+ * gcc.target/riscv/addsibfle.c: New test.
+ * gcc.target/riscv/addsibflt.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdifge.c: New test.
+ * gcc.target/riscv/movdifgt.c: New test.
+ * gcc.target/riscv/movdifle.c: New test.
+ * gcc.target/riscv/movdiflt.c: New test.
+ * gcc.target/riscv/movdifne.c: New test.
+ * gcc.target/riscv/movsifge.c: New test.
+ * gcc.target/riscv/movsifgt.c: New test.
+ * gcc.target/riscv/movsifle.c: New test.
+ * gcc.target/riscv/movsiflt.c: New test.
+ * gcc.target/riscv/movsifne.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibfge.c: New test.
+ * gcc.target/riscv/movdibfgt.c: New test.
+ * gcc.target/riscv/movdibfle.c: New test.
+ * gcc.target/riscv/movdibflt.c: New test.
+ * gcc.target/riscv/movdibfne.c: New test.
+ * gcc.target/riscv/movsibfge.c: New test.
+ * gcc.target/riscv/movsibfgt.c: New test.
+ * gcc.target/riscv/movsibfle.c: New test.
+ * gcc.target/riscv/movsibflt.c: New test.
+ * gcc.target/riscv/movsibfne.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdifge-sfb.c: Reject "if-conversion
+ succeeded through" rather than accepting it.
+ * gcc.target/riscv/movdifge-thead.c: Likewise.
+ * gcc.target/riscv/movdifge-ventana.c: Likewise.
+ * gcc.target/riscv/movdifge-zicond.c: Likewise.
+ * gcc.target/riscv/movdifgt-sfb.c: Likewise.
+ * gcc.target/riscv/movdifgt-thead.c: Likewise.
+ * gcc.target/riscv/movdifgt-ventana.c: Likewise.
+ * gcc.target/riscv/movdifgt-zicond.c: Likewise.
+ * gcc.target/riscv/movdifle-sfb.c: Likewise.
+ * gcc.target/riscv/movdifle-thead.c: Likewise.
+ * gcc.target/riscv/movdifle-ventana.c: Likewise.
+ * gcc.target/riscv/movdifle-zicond.c: Likewise.
+ * gcc.target/riscv/movdiflt-sfb.c: Likewise.
+ * gcc.target/riscv/movdiflt-thead.c: Likewise.
+ * gcc.target/riscv/movdiflt-ventana.c: Likewise.
+ * gcc.target/riscv/movdiflt-zicond.c: Likewise.
+ * gcc.target/riscv/movsifge-sfb.c: Likewise.
+ * gcc.target/riscv/movsifge-thead.c: Likewise.
+ * gcc.target/riscv/movsifge-ventana.c: Likewise.
+ * gcc.target/riscv/movsifge-zicond.c: Likewise.
+ * gcc.target/riscv/movsifgt-sfb.c: Likewise.
+ * gcc.target/riscv/movsifgt-thead.c: Likewise.
+ * gcc.target/riscv/movsifgt-ventana.c: Likewise.
+ * gcc.target/riscv/movsifgt-zicond.c: Likewise.
+ * gcc.target/riscv/movsifle-sfb.c: Likewise.
+ * gcc.target/riscv/movsifle-thead.c: Likewise.
+ * gcc.target/riscv/movsifle-ventana.c: Likewise.
+ * gcc.target/riscv/movsifle-zicond.c: Likewise.
+ * gcc.target/riscv/movsiflt-sfb.c: Likewise.
+ * gcc.target/riscv/movsiflt-thead.c: Likewise.
+ * gcc.target/riscv/movsiflt-ventana.c: Likewise.
+ * gcc.target/riscv/movsiflt-zicond.c: Likewise.
+ * gcc.target/riscv/smax-ieee.c: Also accept FLT.D.
+ * gcc.target/riscv/smaxf-ieee.c: Also accept FLT.S.
+ * gcc.target/riscv/smin-ieee.c: Also accept FGT.D.
+ * gcc.target/riscv/sminf-ieee.c: Also accept FGT.S.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/adddieq.c: New test.
+ * gcc.target/riscv/adddige.c: New test.
+ * gcc.target/riscv/adddigeu.c: New test.
+ * gcc.target/riscv/adddigt.c: New test.
+ * gcc.target/riscv/adddigtu.c: New test.
+ * gcc.target/riscv/adddile.c: New test.
+ * gcc.target/riscv/adddileu.c: New test.
+ * gcc.target/riscv/adddilt.c: New test.
+ * gcc.target/riscv/adddiltu.c: New test.
+ * gcc.target/riscv/adddine.c: New test.
+ * gcc.target/riscv/addsieq.c: New test.
+ * gcc.target/riscv/addsige.c: New test.
+ * gcc.target/riscv/addsigeu.c: New test.
+ * gcc.target/riscv/addsigt.c: New test.
+ * gcc.target/riscv/addsigtu.c: New test.
+ * gcc.target/riscv/addsile.c: New test.
+ * gcc.target/riscv/addsileu.c: New test.
+ * gcc.target/riscv/addsilt.c: New test.
+ * gcc.target/riscv/addsiltu.c: New test.
+ * gcc.target/riscv/addsine.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/adddibeq.c: New test.
+ * gcc.target/riscv/adddibge.c: New test.
+ * gcc.target/riscv/adddibgeu.c: New test.
+ * gcc.target/riscv/adddibgt.c: New test.
+ * gcc.target/riscv/adddibgtu.c: New test.
+ * gcc.target/riscv/adddible.c: New test.
+ * gcc.target/riscv/adddibleu.c: New test.
+ * gcc.target/riscv/adddiblt.c: New test.
+ * gcc.target/riscv/adddibltu.c: New test.
+ * gcc.target/riscv/adddibne.c: New test.
+ * gcc.target/riscv/addsibeq.c: New test.
+ * gcc.target/riscv/addsibge.c: New test.
+ * gcc.target/riscv/addsibgeu.c: New test.
+ * gcc.target/riscv/addsibgt.c: New test.
+ * gcc.target/riscv/addsibgtu.c: New test.
+ * gcc.target/riscv/addsible.c: New test.
+ * gcc.target/riscv/addsibleu.c: New test.
+ * gcc.target/riscv/addsiblt.c: New test.
+ * gcc.target/riscv/addsibltu.c: New test.
+ * gcc.target/riscv/addsibne.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdieq.c: New test.
+ * gcc.target/riscv/movdige.c: New test.
+ * gcc.target/riscv/movdigeu.c: New test.
+ * gcc.target/riscv/movdigt.c: New test.
+ * gcc.target/riscv/movdigtu.c: New test.
+ * gcc.target/riscv/movdile.c: New test.
+ * gcc.target/riscv/movdileu.c: New test.
+ * gcc.target/riscv/movdilt.c: New test.
+ * gcc.target/riscv/movdiltu.c: New test.
+ * gcc.target/riscv/movdine.c: New test.
+ * gcc.target/riscv/movsieq.c: New test.
+ * gcc.target/riscv/movsige.c: New test.
+ * gcc.target/riscv/movsigeu.c: New test.
+ * gcc.target/riscv/movsigt.c: New test.
+ * gcc.target/riscv/movsigtu.c: New test.
+ * gcc.target/riscv/movsile.c: New test.
+ * gcc.target/riscv/movsileu.c: New test.
+ * gcc.target/riscv/movsilt.c: New test.
+ * gcc.target/riscv/movsiltu.c: New test.
+ * gcc.target/riscv/movsine.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibeq.c: New test.
+ * gcc.target/riscv/movdibge.c: New test.
+ * gcc.target/riscv/movdibgeu.c: New test.
+ * gcc.target/riscv/movdibgt.c: New test.
+ * gcc.target/riscv/movdibgtu.c: New test.
+ * gcc.target/riscv/movdible.c: New test.
+ * gcc.target/riscv/movdibleu.c: New test.
+ * gcc.target/riscv/movdiblt.c: New test.
+ * gcc.target/riscv/movdibltu.c: New test.
+ * gcc.target/riscv/movdibne.c: New test.
+ * gcc.target/riscv/movsibeq.c: New test.
+ * gcc.target/riscv/movsibge.c: New test.
+ * gcc.target/riscv/movsibgeu.c: New test.
+ * gcc.target/riscv/movsibgt.c: New test.
+ * gcc.target/riscv/movsibgtu.c: New test.
+ * gcc.target/riscv/movsible.c: New test.
+ * gcc.target/riscv/movsibleu.c: New test.
+ * gcc.target/riscv/movsiblt.c: New test.
+ * gcc.target/riscv/movsibltu.c: New test.
+ * gcc.target/riscv/movsibne.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/zbs-bext-02.c: Adjust to reject SLL rather
+ than AND.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdige-thead.c: New test.
+ * gcc.target/riscv/movdigeu-thead.c: New test.
+ * gcc.target/riscv/movdigt-thead.c: New test.
+ * gcc.target/riscv/movdigtu-thead.c: New test.
+ * gcc.target/riscv/movdile-thead.c: New test.
+ * gcc.target/riscv/movdileu-thead.c: New test.
+ * gcc.target/riscv/movdilt-thead.c: New test.
+ * gcc.target/riscv/movdiltu-thead.c: New test.
+ * gcc.target/riscv/movsige-thead.c: New test.
+ * gcc.target/riscv/movsigeu-thead.c: New test.
+ * gcc.target/riscv/movsigt-thead.c: New test.
+ * gcc.target/riscv/movsigtu-thead.c: New test.
+ * gcc.target/riscv/movsile-thead.c: New test.
+ * gcc.target/riscv/movsileu-thead.c: New test.
+ * gcc.target/riscv/movsilt-thead.c: New test.
+ * gcc.target/riscv/movsiltu-thead.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibge-thead.c: New test.
+ * gcc.target/riscv/movdibgeu-thead.c: New test.
+ * gcc.target/riscv/movdibgt-thead.c: New test.
+ * gcc.target/riscv/movdibgtu-thead.c: New test.
+ * gcc.target/riscv/movdible-thead.c: New test.
+ * gcc.target/riscv/movdibleu-thead.c: New test.
+ * gcc.target/riscv/movdiblt-thead.c: New test.
+ * gcc.target/riscv/movdibltu-thead.c: New test.
+ * gcc.target/riscv/movsibge-thead.c: New test.
+ * gcc.target/riscv/movsibgeu-thead.c: New test.
+ * gcc.target/riscv/movsibgt-thead.c: New test.
+ * gcc.target/riscv/movsibgtu-thead.c: New test.
+ * gcc.target/riscv/movsible-thead.c: New test.
+ * gcc.target/riscv/movsibleu-thead.c: New test.
+ * gcc.target/riscv/movsiblt-thead.c: New test.
+ * gcc.target/riscv/movsibltu-thead.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdieq-ventana.c: New test.
+ * gcc.target/riscv/movdieq-zicond.c: New test.
+ * gcc.target/riscv/movdine-ventana.c: New test.
+ * gcc.target/riscv/movdine-zicond.c: New test.
+ * gcc.target/riscv/movsieq-ventana.c: New test.
+ * gcc.target/riscv/movsieq-zicond.c: New test.
+ * gcc.target/riscv/movsine-ventana.c: New test.
+ * gcc.target/riscv/movsine-zicond.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibeq-ventana.c: New test.
+ * gcc.target/riscv/movdibeq-zicond.c: New test.
+ * gcc.target/riscv/movdibne-ventana.c: New test.
+ * gcc.target/riscv/movdibne-zicond.c: New test.
+ * gcc.target/riscv/movsibeq-ventana.c: New test.
+ * gcc.target/riscv/movsibeq-zicond.c: New test.
+ * gcc.target/riscv/movsibne-ventana.c: New test.
+ * gcc.target/riscv/movsibne-zicond.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c:
+ Lower `-mbranch-cost=' setting.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c:
+ Likewise.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdigtu-ventana.c: New test.
+ * gcc.target/riscv/movdigtu-zicond.c: New test.
+ * gcc.target/riscv/movdiltu-ventana.c: New test.
+ * gcc.target/riscv/movdiltu-zicond.c: New test.
+ * gcc.target/riscv/movsigtu-ventana.c: New test.
+ * gcc.target/riscv/movsigtu-zicond.c: New test.
+ * gcc.target/riscv/movsiltu-ventana.c: New test.
+ * gcc.target/riscv/movsiltu-zicond.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibgtu-ventana.c: New test.
+ * gcc.target/riscv/movdibgtu-zicond.c: New test.
+ * gcc.target/riscv/movdibltu-ventana.c: New test.
+ * gcc.target/riscv/movdibltu-zicond.c: New test.
+ * gcc.target/riscv/movsibgtu-ventana.c: New test.
+ * gcc.target/riscv/movsibgtu-zicond.c: New test.
+ * gcc.target/riscv/movsibltu-ventana.c: New test.
+ * gcc.target/riscv/movsibltu-zicond.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdifge-sfb.c: New test.
+ * gcc.target/riscv/movdifge-thead.c: New test.
+ * gcc.target/riscv/movdifge-ventana.c: New test.
+ * gcc.target/riscv/movdifge-zicond.c: New test.
+ * gcc.target/riscv/movdifgt-sfb.c: New test.
+ * gcc.target/riscv/movdifgt-thead.c: New test.
+ * gcc.target/riscv/movdifgt-ventana.c: New test.
+ * gcc.target/riscv/movdifgt-zicond.c: New test.
+ * gcc.target/riscv/movdifle-sfb.c: New test.
+ * gcc.target/riscv/movdifle-thead.c: New test.
+ * gcc.target/riscv/movdifle-ventana.c: New test.
+ * gcc.target/riscv/movdifle-zicond.c: New test.
+ * gcc.target/riscv/movdiflt-sfb.c: New test.
+ * gcc.target/riscv/movdiflt-thead.c: New test.
+ * gcc.target/riscv/movdiflt-ventana.c: New test.
+ * gcc.target/riscv/movdiflt-zicond.c: New test.
+ * gcc.target/riscv/movdifne-sfb.c: New test.
+ * gcc.target/riscv/movdifne-thead.c: New test.
+ * gcc.target/riscv/movdifne-ventana.c: New test.
+ * gcc.target/riscv/movdifne-zicond.c: New test.
+ * gcc.target/riscv/movsifge-sfb.c: New test.
+ * gcc.target/riscv/movsifge-thead.c: New test.
+ * gcc.target/riscv/movsifge-ventana.c: New test.
+ * gcc.target/riscv/movsifge-zicond.c: New test.
+ * gcc.target/riscv/movsifgt-sfb.c: New test.
+ * gcc.target/riscv/movsifgt-thead.c: New test.
+ * gcc.target/riscv/movsifgt-ventana.c: New test.
+ * gcc.target/riscv/movsifgt-zicond.c: New test.
+ * gcc.target/riscv/movsifle-sfb.c: New test.
+ * gcc.target/riscv/movsifle-thead.c: New test.
+ * gcc.target/riscv/movsifle-ventana.c: New test.
+ * gcc.target/riscv/movsifle-zicond.c: New test.
+ * gcc.target/riscv/movsiflt-sfb.c: New test.
+ * gcc.target/riscv/movsiflt-thead.c: New test.
+ * gcc.target/riscv/movsiflt-ventana.c: New test.
+ * gcc.target/riscv/movsiflt-zicond.c: New test.
+ * gcc.target/riscv/movsifne-sfb.c: New test.
+ * gcc.target/riscv/movsifne-thead.c: New test.
+ * gcc.target/riscv/movsifne-ventana.c: New test.
+ * gcc.target/riscv/movsifne-zicond.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibfge-ventana.c: New test.
+ * gcc.target/riscv/movdibfge-zicond.c: New test.
+ * gcc.target/riscv/movdibfgt-ventana.c: New test.
+ * gcc.target/riscv/movdibfgt-zicond.c: New test.
+ * gcc.target/riscv/movdibfle-ventana.c: New test.
+ * gcc.target/riscv/movdibfle-zicond.c: New test.
+ * gcc.target/riscv/movdibflt-ventana.c: New test.
+ * gcc.target/riscv/movdibflt-zicond.c: New test.
+ * gcc.target/riscv/movdibfne-ventana.c: New test.
+ * gcc.target/riscv/movdibfne-zicond.c: New test.
+ * gcc.target/riscv/movsibfge-ventana.c: New test.
+ * gcc.target/riscv/movsibfge-zicond.c: New test.
+ * gcc.target/riscv/movsibfgt-ventana.c: New test.
+ * gcc.target/riscv/movsibfgt-zicond.c: New test.
+ * gcc.target/riscv/movsibfle-ventana.c: New test.
+ * gcc.target/riscv/movsibfle-zicond.c: New test.
+ * gcc.target/riscv/movsibflt-ventana.c: New test.
+ * gcc.target/riscv/movsibflt-zicond.c: New test.
+ * gcc.target/riscv/movsibfne-ventana.c: New test.
+ * gcc.target/riscv/movsibfne-zicond.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdieq-thead.c: New test.
+ * gcc.target/riscv/movdige-ventana.c: New test.
+ * gcc.target/riscv/movdige-zicond.c: New test.
+ * gcc.target/riscv/movdigeu-ventana.c: New test.
+ * gcc.target/riscv/movdigeu-zicond.c: New test.
+ * gcc.target/riscv/movdigt-ventana.c: New test.
+ * gcc.target/riscv/movdigt-zicond.c: New test.
+ * gcc.target/riscv/movdile-ventana.c: New test.
+ * gcc.target/riscv/movdile-zicond.c: New test.
+ * gcc.target/riscv/movdileu-ventana.c: New test.
+ * gcc.target/riscv/movdileu-zicond.c: New test.
+ * gcc.target/riscv/movdilt-ventana.c: New test.
+ * gcc.target/riscv/movdilt-zicond.c: New test.
+ * gcc.target/riscv/movdine-thead.c: New test.
+ * gcc.target/riscv/movsieq-thead.c: New test.
+ * gcc.target/riscv/movsige-ventana.c: New test.
+ * gcc.target/riscv/movsige-zicond.c: New test.
+ * gcc.target/riscv/movsigeu-ventana.c: New test.
+ * gcc.target/riscv/movsigeu-zicond.c: New test.
+ * gcc.target/riscv/movsigt-ventana.c: New test.
+ * gcc.target/riscv/movsigt-zicond.c: New test.
+ * gcc.target/riscv/movsile-ventana.c: New test.
+ * gcc.target/riscv/movsile-zicond.c: New test.
+ * gcc.target/riscv/movsileu-ventana.c: New test.
+ * gcc.target/riscv/movsileu-zicond.c: New test.
+ * gcc.target/riscv/movsilt-ventana.c: New test.
+ * gcc.target/riscv/movsilt-zicond.c: New test.
+ * gcc.target/riscv/movsine-thead.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdibeq-thead.c: New test.
+ * gcc.target/riscv/movdibge-ventana.c: New test.
+ * gcc.target/riscv/movdibge-zicond.c: New test.
+ * gcc.target/riscv/movdibgeu-ventana.c: New test.
+ * gcc.target/riscv/movdibgeu-zicond.c: New test.
+ * gcc.target/riscv/movdibgt-ventana.c: New test.
+ * gcc.target/riscv/movdibgt-zicond.c: New test.
+ * gcc.target/riscv/movdible-ventana.c: New test.
+ * gcc.target/riscv/movdible-zicond.c: New test.
+ * gcc.target/riscv/movdibleu-ventana.c: New test.
+ * gcc.target/riscv/movdibleu-zicond.c: New test.
+ * gcc.target/riscv/movdiblt-ventana.c: New test.
+ * gcc.target/riscv/movdiblt-zicond.c: New test.
+ * gcc.target/riscv/movdibne-thead.c: New test.
+ * gcc.target/riscv/movsibeq-thead.c: New test.
+ * gcc.target/riscv/movsibge-ventana.c: New test.
+ * gcc.target/riscv/movsibge-zicond.c: New test.
+ * gcc.target/riscv/movsibgeu-ventana.c: New test.
+ * gcc.target/riscv/movsibgeu-zicond.c: New test.
+ * gcc.target/riscv/movsibgt-ventana.c: New test.
+ * gcc.target/riscv/movsibgt-zicond.c: New test.
+ * gcc.target/riscv/movsible-ventana.c: New test.
+ * gcc.target/riscv/movsible-zicond.c: New test.
+ * gcc.target/riscv/movsibleu-ventana.c: New test.
+ * gcc.target/riscv/movsibleu-zicond.c: New test.
+ * gcc.target/riscv/movsiblt-ventana.c: New test.
+ * gcc.target/riscv/movsiblt-zicond.c: New test.
+ * gcc.target/riscv/movsibne-thead.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c:
+ Explicitly set the branch cost.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c:
+ Likewise.
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c:
+ Likewise.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/movdieq-sfb.c: New test.
+ * gcc.target/riscv/movdige-sfb.c: New test.
+ * gcc.target/riscv/movdigeu-sfb.c: New test.
+ * gcc.target/riscv/movdigt-sfb.c: New test.
+ * gcc.target/riscv/movdigtu-sfb.c: New test.
+ * gcc.target/riscv/movdile-sfb.c: New test.
+ * gcc.target/riscv/movdileu-sfb.c: New test.
+ * gcc.target/riscv/movdilt-sfb.c: New test.
+ * gcc.target/riscv/movdiltu-sfb.c: New test.
+ * gcc.target/riscv/movdine-sfb.c: New test.
+ * gcc.target/riscv/movsieq-sfb.c: New test.
+ * gcc.target/riscv/movsige-sfb.c: New test.
+ * gcc.target/riscv/movsigeu-sfb.c: New test.
+ * gcc.target/riscv/movsigt-sfb.c: New test.
+ * gcc.target/riscv/movsigtu-sfb.c: New test.
+ * gcc.target/riscv/movsile-sfb.c: New test.
+ * gcc.target/riscv/movsileu-sfb.c: New test.
+ * gcc.target/riscv/movsilt-sfb.c: New test.
+ * gcc.target/riscv/movsiltu-sfb.c: New test.
+ * gcc.target/riscv/movsine-sfb.c: New test.
+
+2023-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.dg/torture/addieq.c: New test.
+ * gcc.dg/torture/addifeq.c: New test.
+ * gcc.dg/torture/addifge.c: New test.
+ * gcc.dg/torture/addifgt.c: New test.
+ * gcc.dg/torture/addifle.c: New test.
+ * gcc.dg/torture/addiflt.c: New test.
+ * gcc.dg/torture/addifne.c: New test.
+ * gcc.dg/torture/addige.c: New test.
+ * gcc.dg/torture/addigeu.c: New test.
+ * gcc.dg/torture/addigt.c: New test.
+ * gcc.dg/torture/addigtu.c: New test.
+ * gcc.dg/torture/addile.c: New test.
+ * gcc.dg/torture/addileu.c: New test.
+ * gcc.dg/torture/addilt.c: New test.
+ * gcc.dg/torture/addiltu.c: New test.
+ * gcc.dg/torture/addine.c: New test.
+ * gcc.dg/torture/addleq.c: New test.
+ * gcc.dg/torture/addlfeq.c: New test.
+ * gcc.dg/torture/addlfge.c: New test.
+ * gcc.dg/torture/addlfgt.c: New test.
+ * gcc.dg/torture/addlfle.c: New test.
+ * gcc.dg/torture/addlflt.c: New test.
+ * gcc.dg/torture/addlfne.c: New test.
+ * gcc.dg/torture/addlge.c: New test.
+ * gcc.dg/torture/addlgeu.c: New test.
+ * gcc.dg/torture/addlgt.c: New test.
+ * gcc.dg/torture/addlgtu.c: New test.
+ * gcc.dg/torture/addlle.c: New test.
+ * gcc.dg/torture/addlleu.c: New test.
+ * gcc.dg/torture/addllt.c: New test.
+ * gcc.dg/torture/addlltu.c: New test.
+ * gcc.dg/torture/addlne.c: New test.
+ * gcc.dg/torture/movieq.c: New test.
+ * gcc.dg/torture/movifeq.c: New test.
+ * gcc.dg/torture/movifge.c: New test.
+ * gcc.dg/torture/movifgt.c: New test.
+ * gcc.dg/torture/movifle.c: New test.
+ * gcc.dg/torture/moviflt.c: New test.
+ * gcc.dg/torture/movifne.c: New test.
+ * gcc.dg/torture/movige.c: New test.
+ * gcc.dg/torture/movigeu.c: New test.
+ * gcc.dg/torture/movigt.c: New test.
+ * gcc.dg/torture/movigtu.c: New test.
+ * gcc.dg/torture/movile.c: New test.
+ * gcc.dg/torture/movileu.c: New test.
+ * gcc.dg/torture/movilt.c: New test.
+ * gcc.dg/torture/moviltu.c: New test.
+ * gcc.dg/torture/movine.c: New test.
+ * gcc.dg/torture/movleq.c: New test.
+ * gcc.dg/torture/movlfeq.c: New test.
+ * gcc.dg/torture/movlfge.c: New test.
+ * gcc.dg/torture/movlfgt.c: New test.
+ * gcc.dg/torture/movlfle.c: New test.
+ * gcc.dg/torture/movlflt.c: New test.
+ * gcc.dg/torture/movlfne.c: New test.
+ * gcc.dg/torture/movlge.c: New test.
+ * gcc.dg/torture/movlgeu.c: New test.
+ * gcc.dg/torture/movlgt.c: New test.
+ * gcc.dg/torture/movlgtu.c: New test.
+ * gcc.dg/torture/movlle.c: New test.
+ * gcc.dg/torture/movlleu.c: New test.
+ * gcc.dg/torture/movllt.c: New test.
+ * gcc.dg/torture/movlltu.c: New test.
+ * gcc.dg/torture/movlne.c: New test.
+
+2023-11-21 Thomas Schwinge <thomas@codesourcery.com>
+
+ * gcc.dg/tree-ssa/return-value-range-1.c: Fix.
+
+2023-11-21 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/aarch64/pr112406-2.c: New test.
+
+2023-11-21 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/unop/popcount.c: Adjust check.
+ * lib/target-supports.exp: Add riscv_zbb.
+
+2023-11-21 Robin Dapp <rdapp@ventanamicro.com>
+
+ * g++.target/riscv/rvv/base/bug-14.C: Add
+ dg-require-effective-target rv64.
+ * g++.target/riscv/rvv/base/bug-9.C: Ditto.
+
+2023-11-21 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/rvv.exp: Remove -march and -mabi from
+ default CFLAGS.
+
+2023-11-21 Patrick O'Neill <patrick@rivosinc.com>
+
+ * gfortran.dg/vect/pr107254.f90: Remove dg-do run directive.
+ * gfortran.dg/vect/pr85853.f90: Ditto.
+ * gfortran.dg/vect/vect-alias-check-1.F90: Ditto.
+
+2023-11-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112623
+ * gcc.target/i386/pr112623.c: New testcase.
+
+2023-11-21 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.dg/asm1.d: Adjust expected diagnostic.
+
+2023-11-21 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112598
+ * gcc.target/riscv/rvv/autovec/pr112598-1.c: New test.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/111370
+ * gcc.target/aarch64/sve/cond_asrd_1.c: Updated.
+ * gcc.target/aarch64/sve/cond_cnot_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_5.c: Likewise.
+ * gcc.target/aarch64/sve/cond_uxt_5.c: Likewise.
+ * gcc.target/aarch64/target_attr_13.c: Likewise.
+ * gcc.target/aarch64/target_attr_15.c: Likewise.
+
+2023-11-21 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/simd/vmovl_high_1.c: Update codegen.
+ * gcc.target/aarch64/uxtl-combine-1.c: New test.
+ * gcc.target/aarch64/uxtl-combine-2.c: New test.
+ * gcc.target/aarch64/uxtl-combine-3.c: New test.
+ * gcc.target/aarch64/uxtl-combine-4.c: New test.
+ * gcc.target/aarch64/uxtl-combine-5.c: New test.
+ * gcc.target/aarch64/uxtl-combine-6.c: New test.
+
+2023-11-21 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/pr112438.c: Add missing dump check.
+
+2023-11-21 Thomas Schwinge <thomas@codesourcery.com>
+
+ * gcc.dg/tree-ssa/return-value-range-1.c: Fix.
+
+2023-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/warn25.adb: Add xfail.
+
+2023-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/111309
+ * c-c++-common/pr111309-2.c (foo): Don't expect errors for C++ with
+ -fshort-enums if second argument is E0.
+
+2023-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/112639
+ * gcc.dg/torture/pr112639.c: New test.
+
+2023-11-21 Hongyu Wang <hongyu.wang@intel.com>
+
+ * gcc.target/i386/apx-interrupt-1.c: Adjust option to restrict them
+ under certain subfeatures.
+ * gcc.target/i386/apx-push2pop2-1.c: Likewise.
+ * gcc.target/i386/apx-push2pop2_force_drap-1.c: Likewise.
+ * gcc.target/i386/apx-push2pop2_interrupt-1.c: Likewise.
+ * gcc.target/i386/apx-ppx-1.c: New test.
+
+2023-11-21 Richard Biener <rguenther@suse.de>
+
+ * gcc.target/arm/bfloat16_vector_typecheck_1.c: Adjust.
+ * gcc.target/arm/bfloat16_vector_typecheck_2.c: Likewise.
+ * gcc.target/aarch64/bfloat16_vector_typecheck_1.c: Likewise.
+ * gcc.target/aarch64/bfloat16_vector_typecheck_2.c: Likewise.
+
+2023-11-21 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c: Fix bug.
+
+2023-11-21 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr112325-mmx-1.c: New test.
+
+2023-11-20 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/ipa/devirt-2.C: Add noipa attribute to prevent ipa-vrp.
+ * g++.dg/ipa/devirt-7.C: Disable ipa-vrp.
+ * g++.dg/ipa/ipa-icf-2.C: Disable ipa-vrp.
+ * g++.dg/ipa/ipa-icf-3.C: Disable ipa-vrp.
+ * g++.dg/ipa/ivinline-1.C: Disable ipa-vrp.
+ * g++.dg/ipa/ivinline-3.C: Disable ipa-vrp.
+ * g++.dg/ipa/ivinline-5.C: Disable ipa-vrp.
+ * g++.dg/ipa/ivinline-8.C: Disable ipa-vrp.
+ * g++.dg/ipa/nothrow-1.C: Disable ipa-vrp.
+ * g++.dg/ipa/pure-const-1.C: Disable ipa-vrp.
+ * g++.dg/ipa/pure-const-2.C: Disable ipa-vrp.
+ * g++.dg/lto/inline-crossmodule-1_0.C: Disable ipa-vrp.
+ * gcc.c-torture/compile/pr106433.c: Add noipa attribute to prevent ipa-vrp.
+ * gcc.c-torture/execute/frame-address.c: Likewise.
+ * gcc.dg/vla-1.c: Add noipa attribute to prevent ipa-vrp.
+ * gcc.dg/ipa/fopt-info-inline-1.c: Disable ipa-vrp.
+ * gcc.dg/ipa/ipa-icf-25.c: Disable ipa-vrp.
+ * gcc.dg/ipa/ipa-icf-38.c: Disable ipa-vrp.
+ * gcc.dg/ipa/pure-const-1.c: Disable ipa-vrp.
+ * gcc.dg/ipa/remref-0.c: Add noipa attribute to prevent ipa-vrp.
+ * gcc.dg/tree-prof/time-profiler-1.c: Disable ipa-vrp.
+ * gcc.dg/tree-prof/time-profiler-2.c: Disable ipa-vrp.
+ * gcc.dg/tree-ssa/pr110269.c: Disable ipa-vrp.
+ * gcc.dg/tree-ssa/pr20701.c: Disable ipa-vrp.
+ * gcc.dg/tree-ssa/vrp05.c: Disable ipa-vrp.
+ * gcc.dg/tree-ssa/return-value-range-1.c: New test.
+ * gcc.dg/nonnull-7.c: New file.
+
+2023-11-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112618
+ * gcc.dg/pr112618.c: New testcase.
+
+2023-11-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112281
+ * gcc.dg/torture/pr112281-1.c: New testcase.
+ * gcc.dg/torture/pr112281-2.c: Likewise.
+
+2023-11-20 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/112622
+ * gcc.dg/pr112622.c: New testcase.
+ * gcc.dg/simd-2.c: Adjust.
+ * gcc.target/i386/vect-bfloat16-typecheck_1.c: Likewise.
+ * gcc.target/i386/vect-bfloat16-typecheck_2.c: Likewise.
+
+2023-11-20 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/112597
+ * gcc.target/riscv/rvv/autovec/pr112597-1.c: New test.
+
+2023-11-20 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c:
+ Adjust include.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c:
+ Adjust include.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c:
+ Adjust include.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c: Moved to...
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c: ...here.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c:
+ Adjust include.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-12.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-5.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-6.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-5.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-6.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c: New test.
+ * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c: New test.
+
+2023-11-20 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/arm/mve/intrinsics/vst1q_f16.c: Remove 'return'.
+ * gcc.target/arm/mve/intrinsics/vst1q_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vst1q_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vst1q_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vst1q_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vst1q_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vst1q_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vst1q_u8.c: Likewise.
+
+2023-11-20 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * lib/target-supports.exp: Remove scalable compile option.
+
+2023-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/builtin-classify-type-1.c (main): Add tests for vector
+ types.
+
+2023-11-20 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gfortran.dg/pr112406.f90: New test.
+
+2023-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/90693
+ * gcc.target/i386/pr90693.c: New test.
+
+2023-11-20 Alexandre Oliva <oliva@adacore.com>
+
+ * lib/target-supports.exp
+ (check_effective_target_arm_thumb1_cbz_ok): Fix prop name
+ cut&pasto.
+
+2023-11-20 Alexandre Oliva <oliva@adacore.com>
+
+ * c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c:
+ Expect "unaligned pointer value" warning on short_enums
+ targets, but not in c++.
+ * c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c:
+ Likewise.
+
+2023-11-20 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.dg/tree-ssa/scev-3.c: xfail on all ilp32 targets,
+ though some of these do pass.
+ * gcc.dg/tree-ssa/scev-4.c: Likewise.
+ * gcc.dg/tree-ssa/scev-5.c: Likewise.
+
+2023-11-20 Haochen Jiang <haochen.jiang@intel.com>
+
+ * gcc.target/i386/avx10_1-1.c: New test.
+ * gcc.target/i386/avx10_1-10.c: Ditto.
+ * gcc.target/i386/avx10_1-11.c: Ditto.
+ * gcc.target/i386/avx10_1-12.c: Ditto.
+ * gcc.target/i386/avx10_1-13.c: Ditto.
+ * gcc.target/i386/avx10_1-14.c: Ditto.
+ * gcc.target/i386/avx10_1-15.c: Ditto.
+ * gcc.target/i386/avx10_1-16.c: Ditto.
+ * gcc.target/i386/avx10_1-17.c: Ditto.
+ * gcc.target/i386/avx10_1-18.c: Ditto.
+ * gcc.target/i386/avx10_1-19.c: Ditto.
+ * gcc.target/i386/avx10_1-2.c: Ditto.
+ * gcc.target/i386/avx10_1-20.c: Ditto.
+ * gcc.target/i386/avx10_1-21.c: Ditto.
+ * gcc.target/i386/avx10_1-22.c: Ditto.
+ * gcc.target/i386/avx10_1-23.c: Ditto.
+ * gcc.target/i386/avx10_1-3.c: Ditto.
+ * gcc.target/i386/avx10_1-4.c: Ditto.
+ * gcc.target/i386/avx10_1-5.c: Ditto.
+ * gcc.target/i386/avx10_1-6.c: Ditto.
+ * gcc.target/i386/avx10_1-7.c: Ditto.
+ * gcc.target/i386/avx10_1-8.c: Ditto.
+ * gcc.target/i386/avx10_1-9.c: Ditto.
+
+2023-11-20 liuhongt <hongtao.liu@intel.com>
+
+ * lib/target-supports.exp (vect_logical_reduc): Add i?86-*-*
+ and x86_64-*-*.
+
+2023-11-20 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr112325-1.c: New test.
+ * gcc.target/i386/pr112325-2.c: New test.
+
+2023-11-20 xuli <xuli1@eswincomputing.com>
+
+ PR target/112537
+ * gcc.target/riscv/rvv/base/cpymem-strategy-1.c: New test.
+ * gcc.target/riscv/rvv/base/cpymem-strategy-2.c: New test.
+ * gcc.target/riscv/rvv/base/cpymem-strategy-3.c: New test.
+ * gcc.target/riscv/rvv/base/cpymem-strategy-4.c: New test.
+ * gcc.target/riscv/rvv/base/cpymem-strategy-5.c: New test.
+ * gcc.target/riscv/rvv/base/cpymem-strategy.h: New test.
+
+2023-11-19 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/post-ra-avl.c: New test.
+
+2023-11-19 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/99187
+ * g++.dg/modules/pr99187.C: New test.
+
+2023-11-19 David Edelsohn <dje.gcc@gmail.com>
+
+ * lib/target-supports.exp (add_options_for___float128): Only add
+ -mfloat128 to powerpc*-*-linux*.
+
+2023-11-19 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/pr112561.c: New test.
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107573
+ * c-c++-common/analyzer/strtok-1.c: New test.
+ * c-c++-common/analyzer/strtok-2.c: New test.
+ * c-c++-common/analyzer/strtok-3.c: New test.
+ * c-c++-common/analyzer/strtok-4.c: New test.
+ * c-c++-common/analyzer/strtok-cppreference.c: New test.
+
2023-11-18 Xi Ruoyao <xry111@xry111.site>
* gcc.target/loongarch/div-div32.c: New test.
diff --git a/gcc/testsuite/c-c++-common/Wattributes.c b/gcc/testsuite/c-c++-common/Wattributes.c
index 978f3f9..49a085d 100644
--- a/gcc/testsuite/c-c++-common/Wattributes.c
+++ b/gcc/testsuite/c-c++-common/Wattributes.c
@@ -408,7 +408,7 @@ finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .warn_unused
/* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */
inline int ATTR ((aligned (4)))
- finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(8\\)." "" { target { ! { hppa*64*-*-* } } } } */
+ finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(8\\)." "" } */
inline int ATTR ((aligned (8)))
finline_hot_noret_align (int); /* { dg-note "previous declaration here" } */
diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
index c46ffe9..aaa2031 100644
--- a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
@@ -61,7 +61,7 @@ static inline enum obj_type obj_type(const enum obj_type *t)
}
static inline struct connection *__objt_conn(enum obj_type *t)
{
- return ((struct connection *)(((char *)(t)) - ((long)&((struct connection *)0)->obj_type)));
+ return ((struct connection *)(((char *)(t)) - ((long)&((struct connection *)0)->obj_type))); /* { dg-warning "unaligned pointer value" "warning" { target { short_enums && { ! c++ } } } } */
}
static inline struct connection *objt_conn(enum obj_type *t)
{
diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
index ef34a76..6c96f5a 100644
--- a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
@@ -60,7 +60,7 @@ static inline enum obj_type obj_type(const enum obj_type *t)
}
static inline struct connection *__objt_conn(enum obj_type *t)
{
- return ((struct connection *)(((char *)(t)) - ((long)&((struct connection *)0)->obj_type)));
+ return ((struct connection *)(((char *)(t)) - ((long)&((struct connection *)0)->obj_type))); /* { dg-warning "unaligned pointer value" "warning" { target { short_enums && { ! c++ } } } } */
}
static inline struct connection *objt_conn(enum obj_type *t)
{
diff --git a/gcc/testsuite/c-c++-common/builtin-classify-type-1.c b/gcc/testsuite/c-c++-common/builtin-classify-type-1.c
index a41dbe1..f90f2d9 100644
--- a/gcc/testsuite/c-c++-common/builtin-classify-type-1.c
+++ b/gcc/testsuite/c-c++-common/builtin-classify-type-1.c
@@ -22,6 +22,10 @@ main ()
const char *p = (const char *) 0;
float f = 0.0;
_Complex double c = 0.0;
+ typedef int VI __attribute__((vector_size (4 * sizeof (int))));
+ typedef float VF __attribute__((vector_size (4 * sizeof (int))));
+ VI vi = { 0, 0, 0, 0 };
+ VF vf = { 0.0f, 0.0f, 0.0f, 0.0f };
#ifdef __cplusplus
struct T { void foo (); };
int &r = a[0];
@@ -43,6 +47,8 @@ main ()
static_assert (__builtin_classify_type (struct S) == 12, "");
static_assert (__builtin_classify_type (union U) == 13, "");
static_assert (__builtin_classify_type (int [2]) == 14, "");
+ static_assert (__builtin_classify_type (VI) == 19, "");
+ static_assert (__builtin_classify_type (VF) == 19, "");
static_assert (__builtin_classify_type (__typeof__ (a[0])) == 1, "");
static_assert (__builtin_classify_type (__typeof__ (e)) == 3, "");
static_assert (__builtin_classify_type (__typeof__ (b)) == 4, "");
@@ -57,6 +63,8 @@ main ()
static_assert (__builtin_classify_type (__typeof__ (s)) == 12, "");
static_assert (__builtin_classify_type (__typeof__ (u)) == 13, "");
static_assert (__builtin_classify_type (__typeof__ (a)) == 14, "");
+ static_assert (__builtin_classify_type (__typeof__ (vi)) == 19, "");
+ static_assert (__builtin_classify_type (__typeof__ (vf)) == 19, "");
#ifndef __cplusplus
static_assert (__builtin_classify_type (a[0]) == 1, "");
static_assert (__builtin_classify_type (e) == 1, "");
@@ -102,4 +110,8 @@ main ()
abort ();
if (__builtin_classify_type (a) != 5)
abort ();
+ if (__builtin_classify_type (vi) != 19)
+ abort ();
+ if (__builtin_classify_type (vf) != 19)
+ abort ();
}
diff --git a/gcc/testsuite/c-c++-common/fhardened-1.S b/gcc/testsuite/c-c++-common/fhardened-1.S
new file mode 100644
index 0000000..9d0a577
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-1.S
@@ -0,0 +1,6 @@
+/* { dg-do preprocess { target { { *-*-linux* *-*-gnu* } && pie } } } */
+/* { dg-options "-fhardened -O" } */
+
+#if __PIE__ != 2
+# error "-fPIE not enabled"
+#endif
diff --git a/gcc/testsuite/c-c++-common/fhardened-1.c b/gcc/testsuite/c-c++-common/fhardened-1.c
new file mode 100644
index 0000000..7e67406
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -O" } */
+
+#ifndef __SSP_STRONG__
+# error "-fstack-protector-strong not enabled"
+#endif
+
+#if _FORTIFY_SOURCE < 2
+# error "_FORTIFY_SOURCE not enabled"
+#endif
+
+#ifndef _GLIBCXX_ASSERTIONS
+# error "_GLIBCXX_ASSERTIONS not enabled"
+#endif
diff --git a/gcc/testsuite/c-c++-common/fhardened-10.c b/gcc/testsuite/c-c++-common/fhardened-10.c
new file mode 100644
index 0000000..badebc5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-10.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -D_FORTIFY_SOURCE=1" } */
+
+#if _FORTIFY_SOURCE != 1
+# error "_FORTIFY_SOURCE != 1"
+#endif
+
+#ifndef _GLIBCXX_ASSERTIONS
+# error "_GLIBCXX_ASSERTIONS disabled when it should not be"
+#endif
+
+/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-11.c b/gcc/testsuite/c-c++-common/fhardened-11.c
new file mode 100644
index 0000000..d1a973d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-11.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -O -D_FORTIFY_SOURCE_ -D_GLIBCXX_ASSERTIONS_" } */
+
+#ifndef _FORTIFY_SOURCE
+# error "_FORTIFY_SOURCE disabled when it should not be"
+#endif
+
+#ifndef _GLIBCXX_ASSERTIONS
+# error "_GLIBCXX_ASSERTIONS disabled when it should not be"
+#endif
diff --git a/gcc/testsuite/c-c++-common/fhardened-12.c b/gcc/testsuite/c-c++-common/fhardened-12.c
new file mode 100644
index 0000000..eb128f6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-12.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -O -fdump-tree-gimple" } */
+
+int
+foo ()
+{
+ int i;
+ return i;
+}
+
+/* { dg-final { scan-tree-dump ".DEFERRED_INIT" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-13.c b/gcc/testsuite/c-c++-common/fhardened-13.c
new file mode 100644
index 0000000..8722e6d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-13.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
+/* { dg-options "-fhardened -O" } */
+
+#if __PIE__ != 2
+# error "-fPIE not enabled"
+#endif
diff --git a/gcc/testsuite/c-c++-common/fhardened-14.c b/gcc/testsuite/c-c++-common/fhardened-14.c
new file mode 100644
index 0000000..04d6c8f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-14.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
+/* { dg-options "-fhardened -O -fno-PIE" } */
+
+#ifdef __PIE__
+# error "PIE enabled when it should not be"
+#endif
diff --git a/gcc/testsuite/c-c++-common/fhardened-15.c b/gcc/testsuite/c-c++-common/fhardened-15.c
new file mode 100644
index 0000000..86dc522
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-15.c
@@ -0,0 +1,5 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-require-stack-check "specific" } */
+/* { dg-options "-fhardened -O -fstack-check" } */
+
+/* { dg-warning ".-fstack-clash-protection. is not enabled by .-fhardened. because .-fstack-check. was specified" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-2.c b/gcc/testsuite/c-c++-common/fhardened-2.c
new file mode 100644
index 0000000..280ff96
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -fstack-protector" } */
+
+#ifdef __SSP_STRONG__
+# error "-fstack-protector-strong enabled when it should not be"
+#endif
+#ifndef __SSP__
+# error "-fstack-protector not enabled"
+#endif
+
+/* { dg-warning ".-fstack-protector-strong. is not enabled" "" { target *-*-* } 0 } */
+/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-3.c b/gcc/testsuite/c-c++-common/fhardened-3.c
new file mode 100644
index 0000000..f2306ca
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -O0" } */
+/* Test that we don't get any diagnostic coming from libc headers. */
+
+#include <stdio.h>
+
+/* The most useful C program known to man. */
+
+int
+main ()
+{
+}
+
+/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-4.c b/gcc/testsuite/c-c++-common/fhardened-4.c
new file mode 100644
index 0000000..312fabb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-4.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -O0 -Wno-hardened" } */
+
+/* { dg-bogus "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-5.c b/gcc/testsuite/c-c++-common/fhardened-5.c
new file mode 100644
index 0000000..eb128f6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-5.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -O -fdump-tree-gimple" } */
+
+int
+foo ()
+{
+ int i;
+ return i;
+}
+
+/* { dg-final { scan-tree-dump ".DEFERRED_INIT" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-6.c b/gcc/testsuite/c-c++-common/fhardened-6.c
new file mode 100644
index 0000000..d3cb7c8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-6.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -O -ftrivial-auto-var-init=uninitialized -fdump-tree-gimple" } */
+
+int
+foo ()
+{
+ int i;
+ return i;
+}
+
+/* { dg-final { scan-tree-dump-not ".DEFERRED_INIT" "gimple" } } */
+/* { dg-warning ".-ftrivial-auto-var-init=zero. is not enabled" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fhardened-7.c b/gcc/testsuite/c-c++-common/fhardened-7.c
new file mode 100644
index 0000000..b47bf43
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-7.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
+/* { dg-options "-fhardened -O -fpie" } */
+
+/* -fpie takes precedence over -fhardened */
+#if __PIE__ != 1
+# error "__PIE__ != 1"
+#endif
diff --git a/gcc/testsuite/c-c++-common/fhardened-8.c b/gcc/testsuite/c-c++-common/fhardened-8.c
new file mode 100644
index 0000000..85c9ad9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-8.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
+/* { dg-options "-fhardened -O -fPIC" } */
+
+/* -fPIC takes precedence over -fhardened */
+#ifdef __PIE__
+# error "PIE enabled when it should not be"
+#endif
diff --git a/gcc/testsuite/c-c++-common/fhardened-9.c b/gcc/testsuite/c-c++-common/fhardened-9.c
new file mode 100644
index 0000000..4e4131f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fhardened-9.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-fhardened -U_FORTIFY_SOURCE -U_GLIBCXX_ASSERTIONS" } */
+
+#if defined(_FORTIFY_SOURCE) || defined(_GLIBCXX_ASSERTIONS)
+# error "hardening enabled when it should not be"
+#endif
+
+/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
+/* { dg-warning "._GLIBCXX_ASSERTIONS. is not enabled" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/gomp/depobj-3.c b/gcc/testsuite/c-c++-common/gomp/depobj-3.c
new file mode 100644
index 0000000..a5017a4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/depobj-3.c
@@ -0,0 +1,47 @@
+typedef struct __attribute__((__aligned__ (sizeof (void *)))) omp_depend_t {
+ char __omp_depend_t__[2 * sizeof (void *)];
+} omp_depend_t;
+
+void
+f ()
+{
+ omp_depend_t obj2;
+ struct { omp_depend_t c; } s;
+ float a;
+ #pragma omp depobj(s.c) depend(inout: a)
+
+ #pragma omp depobj(s.c) destroy(s.c) /* OK */
+
+ #pragma omp depobj(s.c) destroy(obj2)
+/* { dg-warning "the 'destroy' expression 'obj2' should be the same as the 'depobj' argument 's.c'" "" { target c } .-1 } */
+/* { dg-warning "the 'destroy' expression 'obj2' should be the same as the 'depobj' argument 's.f\\(\\)::<unnamed struct>::c'" "" { target c++ } .-2 } */
+}
+
+void
+g ()
+{
+ volatile omp_depend_t obj3;
+ #pragma omp depobj(obj3) destroy(obj3)
+}
+
+int
+main ()
+{
+ float a;
+ omp_depend_t obj;
+
+ #pragma omp depobj(obj) depend(inout: a)
+
+ #pragma omp depobj(obj) destroy(obj) /* OK */
+
+ #pragma omp depobj(obj) destroy(a + 5)
+/* { dg-error "'destroy' expression is not lvalue expression" "" { target c } .-1 } */
+/* { dg-warning "the 'destroy' expression '\\(a \\+ \\(float\\)5\\)' should be the same as the 'depobj' argument 'obj'" "" { target c++ } .-2 } */
+
+ #pragma omp depobj(obj+5) destroy(a)
+/* { dg-error "invalid operands to binary \\+ \\(have 'omp_depend_t' and 'int'\\)" "" { target c } .-1 } */
+/* { dg-error "no match for 'operator\\+' in 'obj \\+ 5' \\(operand types are 'omp_depend_t' and 'int'\\)" "" { target c++ } .-2 } */
+
+ #pragma omp depobj(obj) destroy(a) /* { dg-warning "the 'destroy' expression 'a' should be the same as the 'depobj' argument 'obj'" } */
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/has-feature-common.c b/gcc/testsuite/c-c++-common/has-feature-common.c
new file mode 100644
index 0000000..1604d77
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/has-feature-common.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* Test __has_{feature,extension} for generic features. */
+
+#define FEAT(x) (__has_feature (x) && __has_extension (x))
+#define EXT(x) (__has_extension (x) && !__has_feature (x))
+
+#if __has_feature (unknown_feature) || __has_extension (unknown_feature)
+#error unknown feature is known!
+#endif
+
+#if !EXT (gnu_asm_goto_with_outputs)
+#error
+#endif
+
+#if !EXT (__gnu_asm_goto_with_outputs__)
+#error
+#endif
+
+#if !EXT (gnu_asm_goto_with_outputs_full)
+#error
+#endif
+
+#if !EXT (__gnu_asm_goto_with_outputs_full__)
+#error
+#endif
+
+#if !FEAT (enumerator_attributes)
+#error
+#endif
+
+#if !FEAT (__enumerator_attributes__)
+#error
+#endif
+
+#if !FEAT (attribute_deprecated_with_message)
+#error
+#endif
+
+#if !FEAT (__attribute_deprecated_with_message__)
+#error
+#endif
+
+#if !FEAT (attribute_unavailable_with_message)
+#error
+#endif
+
+#if !FEAT (__attribute_unavailable_with_message__)
+#error
+#endif
+
+#if !FEAT (tls)
+#error
+#endif
+
+#if !FEAT(__tls__)
+#error
+#endif
+
+#if defined (__SANITIZE_ADDRESS__) != __has_feature (address_sanitizer)
+#error
+#endif
+
+#if defined (__SANITIZE_ADDRESS__) != __has_extension (address_sanitizer)
+#error
+#endif
+
+#if defined (__SANITIZE_THREAD__) != __has_feature (thread_sanitizer)
+#error
+#endif
+
+#if defined (__SANITIZE_THREAD__) != __has_extension (thread_sanitizer)
+#error
+#endif
diff --git a/gcc/testsuite/c-c++-common/has-feature-pedantic.c b/gcc/testsuite/c-c++-common/has-feature-pedantic.c
new file mode 100644
index 0000000..4ac16a4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/has-feature-pedantic.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-pedantic-errors" } */
+
+/* When -pedantic-errors is passed, __has_extension should behave like
+ __has_feature. */
+
+#if __has_feature (gnu_asm_goto_with_outputs)
+#error extension recognized as feature
+#endif
+
+#if __has_extension (gnu_asm_goto_with_outputs)
+#error pure extensions should not be recognized with -pedantic-errors
+#endif
+
+#if !__has_feature (tls) || !__has_extension (tls)
+#error features should still be recognized with -pedantic-errors
+#endif
+
+/* Make this TU non-empty to appease -pedantic-errors. */
+int foo;
diff --git a/gcc/testsuite/c-c++-common/pr111309-2.c b/gcc/testsuite/c-c++-common/pr111309-2.c
index 535208b..13e9673 100644
--- a/gcc/testsuite/c-c++-common/pr111309-2.c
+++ b/gcc/testsuite/c-c++-common/pr111309-2.c
@@ -32,7 +32,7 @@ foo (void)
__builtin_clzg (0U, 2LL); /* { dg-error "does not have 'int' type" } */
__builtin_clzg (0U, 2U); /* { dg-error "does not have 'int' type" } */
__builtin_clzg (0U, true);
- __builtin_clzg (0U, E0); /* { dg-error "does not have 'int' type" "" { target c++ } } */
+ __builtin_clzg (0U, E0); /* { dg-error "does not have 'int' type" "" { target { c++ && { ! short_enums } } } } */
__builtin_ctzg (); /* { dg-error "too few arguments" } */
__builtin_ctzg (0U, 1, 2); /* { dg-error "too many arguments" } */
__builtin_ctzg (0); /* { dg-error "has signed type" } */
@@ -51,7 +51,7 @@ foo (void)
__builtin_ctzg (0U, 2LL); /* { dg-error "does not have 'int' type" } */
__builtin_ctzg (0U, 2U); /* { dg-error "does not have 'int' type" } */
__builtin_ctzg (0U, true);
- __builtin_ctzg (0U, E0); /* { dg-error "does not have 'int' type" "" { target c++ } } */
+ __builtin_ctzg (0U, E0); /* { dg-error "does not have 'int' type" "" { target { c++ && { ! short_enums } } } } */
__builtin_clrsbg (); /* { dg-error "too few arguments" } */
__builtin_clrsbg (0, 1); /* { dg-error "too many arguments" } */
__builtin_clrsbg (0U); /* { dg-error "has unsigned type" } */
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C
index 8211767..fd3a25b 100644
--- a/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C
+++ b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C
@@ -1,6 +1,6 @@
// basic test to ensure contracts work for class and member specializations
// { dg-do run }
-// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on -fsigned-char" }
#include <cstdio>
// template specializations can have differing contracts
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-75.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-75.C
new file mode 100644
index 0000000..1a73a99
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-75.C
@@ -0,0 +1,13 @@
+// PR c++/112633
+// { dg-do compile { target c++11 } }
+
+struct A { using type = void; };
+
+template<class>
+using ty1 = A;
+
+template<class T>
+using ty2 = typename ty1<T>::type;
+
+template<class T>
+ty2<T> f();
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-const1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-const1.C
index 0da0759..260448aa 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist-const1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-const1.C
@@ -6,4 +6,4 @@
const auto x = { 1, 2 };
-// { dg-final { scan-assembler-not {\.data} { xfail powerpc-ibm-aix* } } }
+// { dg-final { scan-assembler-not {\.data} { xfail hppa*-*-hpux* powerpc-ibm-aix* } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-error1.C b/gcc/testsuite/g++.dg/cpp0x/udlit-error1.C
index 40566e0..6d6cd45 100644
--- a/gcc/testsuite/g++.dg/cpp0x/udlit-error1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/udlit-error1.C
@@ -11,7 +11,9 @@ void operator""_x(const char *, decltype(sizeof(0)));
#pragma message "hi"_x // { dg-warning "string literal with user-defined suffix is invalid in this context" }
extern "C"_x { void g(); } // { dg-error "before user-defined string literal" }
-static_assert(true, "foo"_x); // { dg-error "string literal with user-defined suffix is invalid in this context|expected" }
+static_assert(true, "foo"_x); // { dg-error "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "invalid use of 'void'" "" { target *-*-* } .-2 }
[[deprecated("oof"_x)]] // { dg-error "string literal with user-defined suffix is invalid in this context" "" { target c++26 } }
void
diff --git a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
index 0977d96..80e8ef6 100644
--- a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
+++ b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
@@ -304,8 +304,8 @@
#ifndef __cpp_static_assert
# error "__cpp_static_assert"
-#elif __cpp_static_assert != 201411
-# error "__cpp_static_assert != 201411"
+#elif __cpp_static_assert != 202306
+# error "__cpp_static_assert != 202306"
#endif
#ifndef __cpp_namespace_attributes
diff --git a/gcc/testsuite/g++.dg/cpp26/static_assert1.C b/gcc/testsuite/g++.dg/cpp26/static_assert1.C
new file mode 100644
index 0000000..9dec52b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/static_assert1.C
@@ -0,0 +1,309 @@
+// C++26 P2741R3 - user-generated static_assert messages
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+static_assert (true, "");
+static_assert (true, ("")); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "request for member 'size' in '\\\(\\\"\\\"\\\)', which is of non-class type 'const char \\\[1\\\]'" "" { target *-*-* } .-2 }
+static_assert (true, "" + 0); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "request for member 'size' in '\\\(const char\\\*\\\)\\\"\\\"', which is of non-class type 'const char\\\*'" "" { target *-*-* } .-2 }
+static_assert (true, 0); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "request for member 'size' in '0', which is of non-class type 'int'" "" { target *-*-* } .-2 }
+struct A {};
+static_assert (true, A {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "'struct A' has no member named 'size'" "" { target *-*-* } .-2 }
+struct B { int size; };
+static_assert (true, B {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "'struct B' has no member named 'data'" "" { target *-*-* } .-2 }
+struct C { constexpr int size () const { return 0; } };
+static_assert (true, C {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "'struct C' has no member named 'data'" "" { target *-*-* } .-2 }
+struct D { constexpr int size () const { return 0; } int data; };
+static_assert (true, D {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'D\\\(\\\).D::data' cannot be used as a function" "" { target *-*-* } .-1 }
+struct E { int size = 0;
+ constexpr const char *data () const { return ""; } };
+static_assert (true, E {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'E\\\(\\\).E::size' cannot be used as a function" "" { target c++11_only } .-1 }
+ // { dg-error "'E\\\{0\\\}.E::size' cannot be used as a function" "" { target c++14 } .-2 }
+struct F { constexpr const char *size () const { return ""; }
+ constexpr const char *data () const { return ""; } };
+static_assert (true, F {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message 'size\\\(\\\)' must be implicitly convertible to 'std::size_t'" "" { target *-*-* } .-1 }
+ // { dg-error "could not convert 'F\\\(\\\).F::size\\\(\\\)' from 'const char\\\*' to '\[^']*'" "" { target *-*-* } .-2 }
+ // { dg-error "conversion from 'const char\\\*' to '\[^']*' in a converted constant expression" "" { target *-*-* } .-3 }
+struct G { constexpr long size () const { return 0; }
+ constexpr float data () const { return 0.0f; } };
+static_assert (true, G {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message 'data\\\(\\\)' must be implicitly convertible to 'const char\\\*'" "" { target *-*-* } .-1 }
+ // { dg-error "could not convert 'G\\\(\\\).G::data\\\(\\\)' from 'float' to 'const char\\\*'" "" { target *-*-* } .-2 }
+struct H { short size () const { return 0; }
+ constexpr const char *data () const { return ""; } };
+static_assert (true, H {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+struct I { constexpr signed char size () const { return 0; }
+ const char *data () const { return ""; } };
+static_assert (true, I {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+struct J { constexpr int size () const { return j ? throw 1 : 0; } // { dg-error "expression '<throw-expression>' is not a constant expression" }
+ constexpr const char *data () const { return ""; };
+ constexpr J (int x) : j (x) {}
+ int j; };
+static_assert (true, J (1)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+static_assert (false, J (0)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed" "" { target *-*-* } .-1 }
+static_assert (false, J (1)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message 'size\\\(\\\)' must be a constant expression" "" { target *-*-* } .-1 }
+struct K { constexpr operator int () { return 4; } };
+struct L { constexpr operator const char * () { return "test"; } };
+struct M { constexpr K size () const { return {}; }
+ constexpr L data () const { return {}; } };
+static_assert (true, M {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+static_assert (false, M {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+#if __cpp_constexpr_dynamic_alloc >= 201907L
+struct N { constexpr int size () const { return 3; }
+ constexpr const char *data () const { return new char[3] { 'b', 'a', 'd' }; } }; // { dg-error "'\\\* N\\\(\\\).N::data\\\(\\\)' is not a constant expression because allocated storage has not been deallocated" "" { target c++20 } }
+static_assert (true, N {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++20 && c++23_down } } }
+static_assert (false, N {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++20 && c++23_down } } }
+ // { dg-error "'static_assert' message 'data\\\(\\\)\\\[0\\\]' must be a constant expression" "" { target c++20 } .-1 }
+#endif
+constexpr const char a[] = { 't', 'e', 's', 't' };
+struct O { constexpr int size () const { return 4; }
+ constexpr const char *data () const { return a; } };
+static_assert (false, O {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+struct P { constexpr int size () const { return 4 - p; }
+ constexpr const char *data () const { return &a[p]; }
+ constexpr P (int x) : p (x) {}
+ int p; };
+static_assert (false, P (0)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+static_assert (false, P (2)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: st" "" { target *-*-* } .-1 }
+struct Q { constexpr int size () const { return 4 - q; }
+ constexpr const char *data () const { return &"test"[q]; }
+ constexpr Q (int x) : q (x) {}
+ int q; };
+static_assert (false, Q (0)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+static_assert (false, Q (1)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: est" "" { target *-*-* } .-1 }
+struct R { constexpr int size () const { return 4 - r; }
+ constexpr const char *d () const { return "test"; }
+ constexpr const char *data () const { return d () + r; }
+ constexpr R (int x) : r (x) {}
+ int r; };
+static_assert (false, R (0)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+static_assert (false, R (2)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: st" "" { target *-*-* } .-1 }
+struct S { constexpr float size (float) const { return 42.0f; }
+ constexpr int size (void * = nullptr) const { return 4; }
+ constexpr double data (double) const { return 42.0; }
+ constexpr const char *data (int = 0) const { return "test"; } };
+static_assert (true, S {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+static_assert (false, S {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+
+using size_t = decltype (sizeof (0));
+struct string_view {
+ size_t s;
+ const char *d;
+ constexpr string_view () : s (0), d (nullptr) {}
+ constexpr string_view (const char *p) : s (__builtin_strlen (p)), d (p) {}
+ constexpr string_view (size_t l, const char *p) : s (l), d (p) {}
+ constexpr size_t size () const noexcept { return s; }
+ constexpr const char *data () const noexcept { return d; }
+};
+static_assert (true, string_view{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+static_assert (false, string_view ("test")); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+static_assert (false, string_view ("א")); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: א" "" { target *-*-* } .-1 }
+static_assert (false, string_view (0, nullptr)); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed" "" { target *-*-* } .-1 }
+static_assert (false, string_view (4, "testwithextrachars")); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+static_assert (false, string_view (42, "test")); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "array subscript value '41' is outside the bounds of array type 'const char \\\[5\\\]'" "" { target *-*-* } .-1 }
+ // { dg-error "'static_assert' message 'data\\\(\\\)\\\[41\\\]' must be a constant expression" "" { target *-*-* } .-2 }
+
+template <typename T, size_t N>
+struct array {
+ constexpr size_t size () const { return N; }
+ constexpr const T *data () const { return a; }
+ const T a[N];
+};
+static_assert (true, array<char, 2> { 'O', 'K' }); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+static_assert (true, array<wchar_t, 2> { L'O', L'K' }); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "'static_assert' message 'data\\\(\\\)' must be implicitly convertible to 'const char\\\*'" "" { target *-*-* } .-1 }
+ // { dg-error "could not convert 'array<wchar_t, 2>{const wchar_t \\\[2\\\]{\[0-9]+, \[0-9]+}}.array<wchar_t, 2>::data\\\(\\\)' from 'const wchar_t\\\*' to 'const char\\\*'" "" { target *-*-* } .-2 }
+static_assert (false, array<char, 4> { 't', 'e', 's', 't' }); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+
+void
+foo ()
+{
+ constexpr auto a = array<char, 4> { 't', 'e', 's', 't' };
+ static_assert (false, a); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+} // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+
+#if __cpp_constexpr_dynamic_alloc >= 201907L
+struct T {
+ const char *d = init ();
+ constexpr int size () const { return 4; }
+ constexpr const char *data () const { return d; }
+ constexpr const char *init () const { return new char[4] { 't', 'e', 's', 't' }; }
+ constexpr ~T () { delete[] d; }
+};
+static_assert (false, T{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++20 && c++23_down } } }
+ // { dg-error "static assertion failed: test" "" { target c++20 } .-1 }
+#endif
+struct U { constexpr operator const char * () const { return u; }
+ char u[5] = "test"; };
+#if __cplusplus >= 201402L
+struct V { constexpr auto size () const { return K{}; }
+ constexpr auto data () const { return U{}; } };
+static_assert (false, V{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++14 && c++23_down } } }
+ // { dg-error "static assertion failed: test" "" { target c++14 } .-1 }
+#endif
+struct W { constexpr int size (int) const { return 4; }
+ constexpr const char *data () const { return "test"; } };
+static_assert (true, W{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "no matching function for call to 'W::size\\\(\\\)'" "" { target *-*-* } .-1 }
+struct X { constexpr int size () const { return 4; }
+ constexpr const char *data (int) const { return "test"; } };
+static_assert (true, X{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "no matching function for call to 'X::data\\\(\\\)'" "" { target *-*-* } .-1 }
+struct Y { constexpr int size () { return 4; }
+ constexpr const char *data (int) { return "test"; } };
+static_assert (true, Y{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "no matching function for call to 'Y::data\\\(\\\)'" "" { target *-*-* } .-1 }
+#if __cpp_concepts >= 201907L
+struct Z { constexpr int size (auto...) const { return 4; }
+ constexpr const char *data (auto...) const { return "test"; } };
+static_assert (false, Z{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++20 && c++23_down } } }
+ // { dg-error "static assertion failed: test" "" { target c++20 } .-1 }
+#endif
+
+namespace NN
+{
+ template <typename T>
+ struct A {
+ constexpr int size () const = delete;
+ constexpr const char *data () const { return "test"; } };
+ static_assert (true, A<int>{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "use of deleted function 'constexpr int NN::A<T>::size\\\(\\\) const \\\[with T = int\\\]'" "" { target *-*-* } .-1 }
+#if __cpp_concepts >= 201907L
+ template <typename T>
+ struct B {
+ constexpr int size () const { return 4; }
+ constexpr const char *data () const requires false { return "test"; } };
+ static_assert (true, B<short>{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++20 && c++23_down } } }
+ // { dg-error "no matching function for call to 'NN::B<short int>::data\\\(\\\)'" "" { target c++20 } .-1 }
+#endif
+ class C {
+ constexpr int size () const = delete;
+ constexpr const char *data () const { return "test"; } };
+ static_assert (true, C{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "use of deleted function 'constexpr int NN::C::size\\\(\\\) const'" "" { target *-*-* } .-1 }
+ // { dg-error "'constexpr const char\\\* NN::C::data\\\(\\\) const' is private within this context" "" { target *-*-* } .-2 }
+#if __cplusplus >= 201402L
+ struct D {
+ constexpr int size () { return 4; }
+ constexpr int size () const { return 3; }
+ constexpr const char *data () { return "test"; }
+ constexpr const char *data () const { return "ehlo"; } };
+ static_assert (true, D{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++14 && c++23_down } } }
+ static_assert (false, D{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++14 && c++23_down } } }
+ // { dg-error "static assertion failed: test" "" { target c++14 } .-1 }
+#endif
+ struct E {
+ constexpr int size () const { return 4; }
+ constexpr const char *data () const { return "test"; } };
+ template <typename T>
+ struct F {
+ static_assert (false, T{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ }; // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+ template <typename T>
+ struct G {
+ static_assert (false, T{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ }; // { dg-error "'static_assert' message must be a string literal or object with 'size' and 'data' members" "" { target *-*-* } .-1 }
+ // { dg-error "request for member 'size' in '0', which is of non-class type 'long int'" "" { target *-*-* } .-2 }
+ F<E> fe;
+ G<long> gl;
+ constexpr E operator ""_myd (const char *, size_t) { return E{}; }
+ static_assert (false, "foo"_myd); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+ constexpr E operator + (const char *, const E &) { return E{}; }
+ static_assert (false, "foo" + E{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: test" "" { target *-*-* } .-1 }
+ struct H {
+ static constexpr int size () { return 7; }
+ static constexpr const char *data () { return "message"; } };
+ static_assert (true, H{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ static_assert (false, H{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: message" "" { target *-*-* } .-1 }
+ struct I {
+ static constexpr int size () { return 0; }
+ static constexpr const char *data () { return nullptr; } };
+ static_assert (true, I{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ static_assert (false, I{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed" "" { target *-*-* } .-1 }
+#if __cplusplus >= 201402L
+ struct J {
+ static constexpr int size () { return 0; }
+ static constexpr const char *data (int x = 0) { if (x) return nullptr; else throw 1; } }; // { dg-error "expression '<throw-expression>' is not a constant expression" "" { target c++14 } }
+ static_assert (true, J{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++14 && c++23_down } } }
+ static_assert (false, J{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target { c++14 && c++23_down } } }
+ // { dg-error "'static_assert' message 'data\\\(\\\)' must be a core constant expression" "" { target c++14 } .-1 }
+#endif
+#if __cpp_if_consteval >= 202106L
+ struct K {
+ static constexpr int size () { if consteval { return 4; } else { throw 1; } }
+ static constexpr const char *data () { return "test"; }
+ };
+ static_assert (true, K{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ static_assert (false, K{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ // { dg-error "static assertion failed: test" "" { target c++23 } .-1 }
+ struct L {
+ static constexpr int size () { return 4; }
+ static constexpr const char *data () { if consteval { return "test"; } else { throw 1; } }
+ };
+ static_assert (true, L{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ static_assert (false, L{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ // { dg-error "static assertion failed: test" "" { target c++23 } .-1 }
+ struct M {
+ static constexpr int size () { if consteval { throw 1; } else { return 4; } } // { dg-error "expression '<throw-expression>' is not a constant expression" "" { target c++23 } }
+ static constexpr const char *data () { return "test"; }
+ };
+ static_assert (true, M{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ static_assert (false, M{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ // { dg-error "'static_assert' message 'size\\\(\\\)' must be a constant expression" "" { target c++23 } .-1 }
+ struct N {
+ static constexpr int size () { return 4; }
+ static constexpr const char *data () { if consteval { throw 1; } else { return "test"; } } // { dg-error "expression '<throw-expression>' is not a constant expression" "" { target c++23 } }
+ };
+ static_assert (true, N{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ static_assert (false, N{}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_only } }
+ // { dg-error "'static_assert' message 'data\\\(\\\)\\\[0\\\]' must be a constant expression" "" { target c++23 } .-1 }
+#endif
+ struct O { constexpr int operator () () const { return 12; } };
+ struct P { constexpr const char *operator () () const { return "another test"; } };
+ struct Q { O size; P data; };
+ static_assert (true, Q ()); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ static_assert (false, Q {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: another test" "" { target *-*-* } .-1 }
+ constexpr int get_size () { return 16; }
+ constexpr const char *get_data () { return "yet another test"; }
+ struct R { int (*size) () = NN::get_size;
+ const char *(*data) () = NN::get_data; };
+ static_assert (true, R ()); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ static_assert (false, R {}); // { dg-warning "'static_assert' with non-string message only available with" "" { target c++23_down } }
+ // { dg-error "static assertion failed: yet another test" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/g++.dg/eh/pr112619.C b/gcc/testsuite/g++.dg/eh/pr112619.C
new file mode 100644
index 0000000..f04e1c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/pr112619.C
@@ -0,0 +1,15 @@
+// PR c++/112619
+// { dg-do compile }
+
+struct S { S (); ~S (); };
+
+S
+foo (int a, int b)
+{
+ if (a || b)
+ {
+ S s;
+ return s;
+ }
+ return S ();
+}
diff --git a/gcc/testsuite/g++.dg/ext/has-feature.C b/gcc/testsuite/g++.dg/ext/has-feature.C
new file mode 100644
index 0000000..52191b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has-feature.C
@@ -0,0 +1,206 @@
+// { dg-do compile }
+// { dg-options "" }
+
+#define FEAT(x) (__has_feature(x) && __has_extension(x))
+#define CXX11 (__cplusplus >= 201103L)
+#define CXX14 (__cplusplus >= 201402L)
+
+#if !FEAT(cxx_exceptions) || !FEAT(cxx_rtti)
+#error
+#endif
+
+#if __has_feature (cxx_access_control_sfinae) != CXX11
+#error
+#endif
+
+#if !__has_extension (cxx_access_control_sfinae)
+#error
+#endif
+
+#if FEAT(cxx_alias_templates) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_alignas) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_alignof) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_attributes) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_constexpr) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_decltype) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_decltype_incomplete_return_types) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_default_function_template_args) != CXX11
+#error
+#endif
+
+#if FEAT(cxx_defaulted_functions) != CXX11
+#error
+#endif
+
+#if __has_feature (cxx_delegating_constructors) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_deleted_functions) != CXX11
+#error
+#endif
+
+#if __has_feature (cxx_explicit_conversions) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_generalized_initializers) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_implicit_moves) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_inheriting_constructors) != CXX11
+#error
+#endif
+
+#if !__has_extension (cxx_inline_namespaces)
+#error
+#endif
+
+#if __has_feature (cxx_inline_namespaces) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_lambdas) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_local_type_template_args) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_noexcept) != CXX11
+#error
+#endif
+
+#if __has_feature (cxx_nonstatic_member_init) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_nullptr) != CXX11
+#error
+#endif
+
+#if __has_feature (cxx_override_control) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_reference_qualified_functions) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_range_for) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_raw_string_literals) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_rvalue_references) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_static_assert) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_thread_local) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_auto_type) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_strong_enums) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_trailing_return) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_unicode_literals) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_unrestricted_unions) != CXX11
+#error
+#endif
+
+#if FEAT (cxx_user_literals) != CXX11
+#error
+#endif
+
+#if !__has_extension (cxx_variadic_templates)
+#error
+#endif
+
+#if __has_feature (cxx_variadic_templates) != CXX11
+#error
+#endif
+
+#if !__has_extension (cxx_binary_literals)
+#error
+#endif
+
+#if __has_feature (cxx_binary_literals) != CXX14
+#error
+#endif
+
+#if FEAT (cxx_decltype_auto) != CXX14
+#error
+#endif
+
+#if FEAT (cxx_aggregate_nsdmi) != CXX14
+#error
+#endif
+
+#if __has_extension (cxx_init_captures) != CXX11
+#error
+#endif
+
+#if __has_feature (cxx_init_captures) != CXX14
+#error
+#endif
+
+#if FEAT (cxx_generic_lambdas) != CXX14
+#error
+#endif
+
+#if FEAT (cxx_relaxed_constexpr) != CXX14
+#error
+#endif
+
+#if FEAT (cxx_return_type_deduction) != CXX14
+#error
+#endif
+
+#if __has_feature (cxx_variable_templates) != CXX14
+#error
+#endif
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-2.C b/gcc/testsuite/g++.dg/ipa/devirt-2.C
index 48a94e0..1797db6 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-2.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-2.C
@@ -43,7 +43,7 @@ int C::foo (int i)
return i + 3;
}
-int __attribute__ ((noinline,noclone)) get_input(void)
+int __attribute__ ((noinline,noclone,noipa)) get_input(void)
{
return 1;
}
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-7.C b/gcc/testsuite/g++.dg/ipa/devirt-7.C
index f27a264..b24b2bc 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-7.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-7.C
@@ -1,7 +1,7 @@
/* Verify that IPA-CP can do devirtualization even if the virtual call
comes from a method that has been early-inlined into a descendant. */
/* { dg-do run } */
-/* { dg-options "-O3 -fdump-ipa-cp" } */
+/* { dg-options "-O3 -fdump-ipa-cp -fno-ipa-vrp" } */
/* { dg-add-options bind_pic_locally } */
extern "C" void abort (void);
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C
index 7f56189..ae121e8 100644
--- a/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C
+++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized -fno-ipa-vrp" } */
class A
{
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C
index 5a3cca2..03c10f1 100644
--- a/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C
+++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized -fno-ipa-vrp" } */
__attribute__ ((noinline))
int zero()
diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-1.C b/gcc/testsuite/g++.dg/ipa/ivinline-1.C
index 2d988bc..ccb1870 100644
--- a/gcc/testsuite/g++.dg/ipa/ivinline-1.C
+++ b/gcc/testsuite/g++.dg/ipa/ivinline-1.C
@@ -1,7 +1,7 @@
/* Verify that simple virtual calls are inlined even without early
inlining. */
/* { dg-do run { target { nonpic || pie_enabled } } } */
-/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */
+/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */
extern "C" void abort (void);
diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-3.C b/gcc/testsuite/g++.dg/ipa/ivinline-3.C
index f756a16..02e7e44 100644
--- a/gcc/testsuite/g++.dg/ipa/ivinline-3.C
+++ b/gcc/testsuite/g++.dg/ipa/ivinline-3.C
@@ -1,7 +1,7 @@
/* Verify that simple virtual calls on an object refrence are inlined
even without early inlining. */
/* { dg-do run { target { nonpic || pie_enabled } } } */
-/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */
+/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */
extern "C" void abort (void);
diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-5.C b/gcc/testsuite/g++.dg/ipa/ivinline-5.C
index 6c19907..cb889d1 100644
--- a/gcc/testsuite/g++.dg/ipa/ivinline-5.C
+++ b/gcc/testsuite/g++.dg/ipa/ivinline-5.C
@@ -1,7 +1,7 @@
/* Verify that virtual call inlining does not pick a wrong method when
there is a user defined ancestor in an object. */
/* { dg-do run { target { nonpic || pie_enabled } } } */
-/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */
+/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */
extern "C" void abort (void);
diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-8.C b/gcc/testsuite/g++.dg/ipa/ivinline-8.C
index bc81abf..f29e818 100644
--- a/gcc/testsuite/g++.dg/ipa/ivinline-8.C
+++ b/gcc/testsuite/g++.dg/ipa/ivinline-8.C
@@ -1,7 +1,7 @@
/* Verify that virtual calls are inlined (ithout early inlining) even
when their caller is itself indirectly inlined. */
/* { dg-do run { target { nonpic || pie_enabled } } } */
-/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */
+/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */
extern "C" void abort (void);
diff --git a/gcc/testsuite/g++.dg/ipa/nothrow-1.C b/gcc/testsuite/g++.dg/ipa/nothrow-1.C
index b30b021..1f24310 100644
--- a/gcc/testsuite/g++.dg/ipa/nothrow-1.C
+++ b/gcc/testsuite/g++.dg/ipa/nothrow-1.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fnon-call-exceptions -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fnon-call-exceptions -fdump-tree-optimized -fno-ipa-vrp" } */
int *ptr;
static int barvar;
diff --git a/gcc/testsuite/g++.dg/ipa/pure-const-1.C b/gcc/testsuite/g++.dg/ipa/pure-const-1.C
index 61940c6..c18278c 100644
--- a/gcc/testsuite/g++.dg/ipa/pure-const-1.C
+++ b/gcc/testsuite/g++.dg/ipa/pure-const-1.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-ipa-vrp" } */
int *ptr;
static int barvar;
diff --git a/gcc/testsuite/g++.dg/ipa/pure-const-2.C b/gcc/testsuite/g++.dg/ipa/pure-const-2.C
index 6e739de..d5f18bf 100644
--- a/gcc/testsuite/g++.dg/ipa/pure-const-2.C
+++ b/gcc/testsuite/g++.dg/ipa/pure-const-2.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-ipa-vrp" } */
int *ptr;
static int barvar;
/* We can not detect A to be const because it may be interposed by unoptimized
diff --git a/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C b/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C
index 0294dcc..c56360e 100644
--- a/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C
+++ b/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C
@@ -1,5 +1,5 @@
// { dg-lto-do link }
-/* { dg-lto-options { "-O2 -fno-early-inlining -fno-implicit-constexpr -flto -fdump-ipa-inline-details" } } */
+/* { dg-lto-options { "-O2 -fno-early-inlining -fno-implicit-constexpr -flto -fdump-ipa-inline-details -fno-ipa-vrp" } } */
#include "inline-crossmodule-1.h"
int a::key ()
{
diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-1.C b/gcc/testsuite/g++.dg/modules/bad-mapper-1.C
index 53e3e1d..b0b0b86 100644
--- a/gcc/testsuite/g++.dg/modules/bad-mapper-1.C
+++ b/gcc/testsuite/g++.dg/modules/bad-mapper-1.C
@@ -1,9 +1,9 @@
// { dg-additional-options "-fmodules-ts -fmodule-mapper=|this-will-not-work" }
import unique1.bob;
-// { dg-error "-:failed (exec|CreateProcess|posix_spawn).*mapper.* .*this-will-not-work" "" { target { ! { *-*-darwin[89]* *-*-darwin10* } } } 0 }
+// { dg-error "-:failed (exec|CreateProcess|posix_spawn).*mapper.* .*this-will-not-work" "" { target { ! { *-*-darwin[89]* *-*-darwin10* hppa*-*-hpux* } } } 0 }
// { dg-prune-output "fatal error:" }
// { dg-prune-output "failed to read" }
// { dg-prune-output "compilation terminated" }
-// { dg-error "-:failed mapper handshake communication" "" { target { *-*-darwin[89]* *-*-darwin10* } } 0 }
+// { dg-error "-:failed mapper handshake communication" "" { target { *-*-darwin[89]* *-*-darwin10* hppa*-*-hpux* } } 0 }
// { dg-prune-output "trying to exec .this-will-not-work." }
// { dg-prune-output "unknown Compiled Module Interface" }
diff --git a/gcc/testsuite/g++.dg/modules/export-1.C b/gcc/testsuite/g++.dg/modules/export-1.C
index 8ca696e..5988143 100644
--- a/gcc/testsuite/g++.dg/modules/export-1.C
+++ b/gcc/testsuite/g++.dg/modules/export-1.C
@@ -4,19 +4,25 @@ export module frob;
// { dg-module-cmi !frob }
int x ();
-export int x (); // { dg-error "conflicting exporting declaration" }
+export int x (); // { dg-error "conflicting exporting for declaration" }
int y;
-export extern int y; // { dg-error "conflicting exporting declaration" }
+export extern int y; // { dg-error "conflicting exporting for declaration" }
+// A typedef is not an entity so the following is OK; see [module.interface] example 4
typedef int z;
-export typedef int z; // { dg-error "conflicting exporting declaration" }
+export typedef int z; // { dg-bogus "conflicting exporting for declaration" }
+
+template <typename T> using w = T;
+export template <typename T> using w = T; // { dg-error "conflicting exporting for declaration" }
template <typename T> int f (T);
-export template <typename T> int f (T); // { dg-error "conflicting exporting declaration" }
+export template <typename T> int f (T); // { dg-error "conflicting exporting for declaration" }
-// doesn't go via duplicate_decls so we miss this for now
class A;
-export class A; // { dg-error "conflicting exporting declaration" "" { xfail *-*-* } }
+export class A; // { dg-error "conflicting exporting for declaration" }
+
+template <typename T> struct B;
+export template <typename T> struct B {}; // { dg-error "conflicting exporting for declaration" }
-// { dg-warning "due to errors" "" { target *-*-* } 0 }
+// { dg-warning "due to errors" "" { target *-*-* } 0 }
diff --git a/gcc/testsuite/g++.dg/modules/export-2_a.C b/gcc/testsuite/g++.dg/modules/export-2_a.C
new file mode 100644
index 0000000..9a201bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/export-2_a.C
@@ -0,0 +1,14 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi aliases }
+
+export module aliases;
+
+typedef int x;
+export typedef int x;
+
+using y = double;
+export using y = double;
+
+struct S {};
+using T = S;
+export using T = S;
diff --git a/gcc/testsuite/g++.dg/modules/export-2_b.C b/gcc/testsuite/g++.dg/modules/export-2_b.C
new file mode 100644
index 0000000..456aa8d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/export-2_b.C
@@ -0,0 +1,7 @@
+// { dg-additional-options "-fmodules-ts" }
+
+import aliases;
+
+x a = 123;
+y b = 12.45;
+T c = T{};
diff --git a/gcc/testsuite/g++.dg/modules/lambda-6_a.C b/gcc/testsuite/g++.dg/modules/lambda-6_a.C
new file mode 100644
index 0000000..28bfb35
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lambda-6_a.C
@@ -0,0 +1,16 @@
+// PR c++/107398
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi Lambda6 }
+
+export module Lambda6;
+
+template <typename T>
+struct R { static int x; };
+
+template <typename T>
+int R<T>::x = []{int i; return 1;}();
+
+export int foo();
+int foo() {
+ return R<int>::x;
+}
diff --git a/gcc/testsuite/g++.dg/modules/lambda-6_b.C b/gcc/testsuite/g++.dg/modules/lambda-6_b.C
new file mode 100644
index 0000000..ab0c4ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lambda-6_b.C
@@ -0,0 +1,9 @@
+// PR c++/107398
+// { dg-additional-options "-fmodules-ts" }
+
+import Lambda6;
+
+int main() {
+ if (foo() != 1)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr99187.C b/gcc/testsuite/g++.dg/modules/pr99187.C
new file mode 100644
index 0000000..7f707e0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99187.C
@@ -0,0 +1,10 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi pr99187 }
+
+export module pr99187;
+
+export struct A { ~A() {} };
+
+export inline void f() {
+ static thread_local A a;
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr99232_a.C b/gcc/testsuite/g++.dg/modules/pr99232_a.C
new file mode 100644
index 0000000..097fb5e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99232_a.C
@@ -0,0 +1,12 @@
+// PR c++/99232
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi pr99232 }
+
+export module pr99232;
+
+export const double lambda{ 1.3 };
+export constexpr int a = 42;
+
+export const double* get_lambda_addr() {
+ return &lambda;
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr99232_b.C b/gcc/testsuite/g++.dg/modules/pr99232_b.C
new file mode 100644
index 0000000..a36a76f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99232_b.C
@@ -0,0 +1,13 @@
+// PR c++/99232
+// { dg-module-do run }
+// { dg-additional-options "-fmodules-ts" }
+
+import pr99232;
+
+double foo() { return lambda * 2.0; }
+static_assert(a == 42);
+
+int main() {
+ if (&lambda != get_lambda_addr())
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/modules/using-10.C b/gcc/testsuite/g++.dg/modules/using-10.C
new file mode 100644
index 0000000..5735353
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-10.C
@@ -0,0 +1,71 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi !bad }
+
+export module bad;
+
+// internal linkage
+namespace s {
+ namespace {
+ struct a1 {}; // { dg-message "declared here with internal linkage" }
+
+ template <typename T>
+ struct b1; // { dg-message "declared here with internal linkage" }
+
+ int x1; // { dg-message "declared here with internal linkage" }
+
+ template <typename T>
+ T y1; // { dg-message "declared here with internal linkage" }
+
+ void f1(); // { dg-message "declared here with internal linkage" }
+
+ template <typename T>
+ void g1(); // { dg-message "declared here with internal linkage" }
+ }
+}
+
+// module linkage
+namespace m {
+ struct a2 {}; // { dg-message "declared here with module linkage" }
+
+ template <typename T>
+ struct b2; // { dg-message "declared here with module linkage" }
+
+ int x2; // { dg-message "declared here with module linkage" }
+
+ template <typename T>
+ T y2; // { dg-message "declared here with module linkage" }
+
+ void f2(); // { dg-message "declared here with module linkage" }
+
+ template <typename T>
+ void g2(); // { dg-message "declared here with module linkage" }
+}
+
+export using s::a1; // { dg-error "does not have external linkage" }
+export using s::b1; // { dg-error "does not have external linkage" }
+export using s::x1; // { dg-error "does not have external linkage" }
+export using s::y1; // { dg-error "does not have external linkage" }
+export using s::f1; // { dg-error "does not have external linkage" }
+export using s::g1; // { dg-error "does not have external linkage" }
+
+export using m::a2; // { dg-error "does not have external linkage" }
+export using m::b2; // { dg-error "does not have external linkage" }
+export using m::x2; // { dg-error "does not have external linkage" }
+export using m::y2; // { dg-error "does not have external linkage" }
+export using m::f2; // { dg-error "does not have external linkage" }
+export using m::g2; // { dg-error "does not have external linkage" }
+
+namespace t {
+ using a = int; // { dg-message "declared here with no linkage" }
+
+ template <typename T>
+ using b = int; // { dg-message "declared here with no linkage" }
+
+ typedef int c; // { dg-message "declared here with no linkage" }
+}
+
+export using t::a; // { dg-error "does not have external linkage" }
+export using t::b; // { dg-error "does not have external linkage" }
+export using t::c; // { dg-error "does not have external linkage" }
+
+// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/using-enum-2.C b/gcc/testsuite/g++.dg/modules/using-enum-2.C
new file mode 100644
index 0000000..813e2f6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-enum-2.C
@@ -0,0 +1,23 @@
+// { dg-additional-options "-fmodules-ts -std=c++2a" }
+// { dg-module-cmi !bad }
+
+export module bad;
+
+namespace s {
+ namespace {
+ enum e1 { x1 }; // { dg-message "declared here with internal linkage" }
+ enum class e2 { x2 }; // { dg-message "declared here with internal linkage" }
+ }
+}
+
+namespace m {
+ enum e3 { x3 }; // { dg-message "declared here with module linkage" }
+ enum class e4 { x4 }; // { dg-message "declared here with module linkage" }
+}
+
+export using enum s::e1; // { dg-error "does not have external linkage" }
+export using enum s::e2; // { dg-error "does not have external linkage" }
+export using enum m::e3; // { dg-error "does not have external linkage" }
+export using enum m::e4; // { dg-error "does not have external linkage" }
+
+// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/opt/pr110879.C b/gcc/testsuite/g++.dg/opt/pr110879.C
index 7f0a0a8..5755660 100644
--- a/gcc/testsuite/g++.dg/opt/pr110879.C
+++ b/gcc/testsuite/g++.dg/opt/pr110879.C
@@ -1,4 +1,4 @@
-// { dg-do compile }
+// { dg-do compile { target c++11 } }
// { dg-options "-O3 -fdump-tree-optimized" }
#include <vector>
diff --git a/gcc/testsuite/g++.dg/pch/pr112319.C b/gcc/testsuite/g++.dg/pch/pr112319.C
new file mode 100644
index 0000000..9e0457e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr112319.C
@@ -0,0 +1,5 @@
+/* { dg-additional-options "-Wpragmas -save-temps" } */
+#include "pr112319.H"
+#pragma GCC diagnostic error "-Wpragmas"
+#pragma GCC diagnostic ignored "oops" /* { dg-error "oops" } */
+/* { dg-regexp {[^[:space:]]*: some warnings being treated as errors} } */
diff --git a/gcc/testsuite/g++.dg/pch/pr112319.Hs b/gcc/testsuite/g++.dg/pch/pr112319.Hs
new file mode 100644
index 0000000..3b6178b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr112319.Hs
@@ -0,0 +1 @@
+/* This space intentionally left blank. */
diff --git a/gcc/testsuite/g++.dg/pr104869.C b/gcc/testsuite/g++.dg/pr104869.C
index 9a6ef88..851d653 100644
--- a/gcc/testsuite/g++.dg/pr104869.C
+++ b/gcc/testsuite/g++.dg/pr104869.C
@@ -68,6 +68,9 @@ struct ControlFlow {
foo(2);
return false;
}
+#ifdef __hpux__
+extern int main(void) __attribute__ ((visibility ("default")));
+#endif
int
main() {
ControlFlow cf = { nullptr, ControlFlow::UnwindType::EE };
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr109849.C b/gcc/testsuite/g++.dg/tree-ssa/pr109849.C
new file mode 100644
index 0000000..cd348c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr109849.C
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-sra" } */
+
+#include <vector>
+typedef unsigned int uint32_t;
+std::pair<uint32_t, uint32_t> pair;
+void
+test()
+{
+ std::vector<std::pair<uint32_t, uint32_t> > stack;
+ stack.push_back (pair);
+ while (!stack.empty()) {
+ std::pair<uint32_t, uint32_t> cur = stack.back();
+ stack.pop_back();
+ if (!cur.first)
+ {
+ cur.second++;
+ stack.push_back (cur);
+ }
+ if (cur.second > 10000)
+ break;
+ }
+}
+int
+main()
+{
+ for (int i = 0; i < 10000; i++)
+ test();
+}
+
+/* { dg-final { scan-tree-dump "Created a replacement for stack offset" "sra"} } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/sra-eh-1.C b/gcc/testsuite/g++.dg/tree-ssa/sra-eh-1.C
new file mode 100644
index 0000000..9c216a6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/sra-eh-1.C
@@ -0,0 +1,187 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-sra" } */
+
+struct E
+{
+ short c;
+ E (short param) : c(param) {};
+};
+
+volatile short vs = 0;
+long buf[16];
+long * volatile pbuf = (long *) &buf;
+
+static void __attribute__((noinline))
+unrelated_throwing (void)
+{
+ throw E (256);
+}
+
+struct S {
+ long *b;
+ int c;
+ int s;
+};
+
+static void __attribute__((noinline))
+crazy_alloc_s (struct S *p)
+{
+ int s = p->c ? p->c * 2 : 16;
+
+ long *b = pbuf;
+ if (!b || s > 16)
+ {
+ p->s = -p->s;
+ throw E (127);
+ }
+
+ __builtin_memcpy (b, p->b, p->c);
+ p->b = b;
+ p->s = s;
+ pbuf = 0;
+ return;
+}
+
+long __attribute__((noipa))
+process (long v)
+{
+ return v + 1;
+}
+
+void __attribute__((noipa))
+check (int s, short c)
+{
+ if (vs < c)
+ vs = c;
+ if (c == 127)
+ {
+ if (s >= 0)
+ __builtin_abort ();
+ }
+ else
+ {
+ if (s != 0)
+ __builtin_abort ();
+ }
+ return;
+}
+
+
+void
+foo (void)
+{
+ struct S foo_stack;
+
+ foo_stack.c = 0;
+ crazy_alloc_s (&foo_stack);
+ foo_stack.b[0] = 1;
+ foo_stack.c = 1;
+
+ while (foo_stack.c)
+ {
+ long l = foo_stack.b[--foo_stack.c];
+
+ if (l > 0)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ try
+ {
+ if (foo_stack.s <= foo_stack.c + 1)
+ crazy_alloc_s (&foo_stack);
+ }
+ catch (E e)
+ {
+ check (foo_stack.s, e.c);
+ return;
+ }
+ l = process (l);
+ foo_stack.b[foo_stack.c++] = l;
+ }
+ }
+ }
+ return;
+}
+
+
+volatile int vi;
+
+int __attribute__((noipa))
+save (int s)
+{
+ vi = s;
+ return 0;
+}
+
+int __attribute__((noipa))
+restore ()
+{
+ return vi;
+}
+
+
+void
+bar (void)
+{
+ struct S bar_stack;
+
+ bar_stack.c = 0;
+ crazy_alloc_s (&bar_stack);
+ bar_stack.b[0] = 1;
+ bar_stack.c = 1;
+
+ while (bar_stack.c)
+ {
+ long l = bar_stack.b[--bar_stack.c];
+
+ if (l > 0)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ try
+ {
+ if (i == 2)
+ {
+ bar_stack.s = save (bar_stack.s);
+ unrelated_throwing ();
+ }
+ if (bar_stack.s <= bar_stack.c + 1)
+ crazy_alloc_s (&bar_stack);
+ }
+ catch (E e)
+ {
+ check (bar_stack.s, e.c);
+ if (e.c == 127)
+ return;
+ bar_stack.s = restore ();
+ continue;
+ }
+ l = process (l);
+ bar_stack.b[bar_stack.c++] = l;
+ }
+ }
+ }
+ return;
+}
+
+
+
+
+int main (int argc, char **argv)
+{
+ vs = 0;
+ pbuf = (long *) &buf;
+ foo ();
+ if (vs != 127)
+ __builtin_abort ();
+
+ vs = 0;
+ pbuf = (long *) &buf;
+ bar ();
+ if (vs != 256)
+ __builtin_abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "Created a replacement for foo_stack offset" "sra"} } */
+/* { dg-final { scan-tree-dump "Created a replacement for bar_stack offset" "sra"} } */
diff --git a/gcc/testsuite/g++.dg/vect/pr36648.cc b/gcc/testsuite/g++.dg/vect/pr36648.cc
index 8d24d3d..7bda828 100644
--- a/gcc/testsuite/g++.dg/vect/pr36648.cc
+++ b/gcc/testsuite/g++.dg/vect/pr36648.cc
@@ -25,6 +25,6 @@ int main() { }
targets, ! vect_no_align is a sufficient test. */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { { { ! vect_no_align } && { ! powerpc*-*-* } } || { powerpc*-*-* && vect_hw_misalign } } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { { { ! vect_no_align } && { ! powerpc*-*-* } } || { powerpc*-*-* && vect_hw_misalign } } xfail { vect_variable_length && vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { { { ! vect_no_align } && { ! powerpc*-*-* } } || { powerpc*-*-* && vect_hw_misalign } } } } } */
diff --git a/gcc/testsuite/g++.dg/warn/Wstringop-overflow-4.C b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-4.C
index 275ecac..2024f8d 100644
--- a/gcc/testsuite/g++.dg/warn/Wstringop-overflow-4.C
+++ b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-4.C
@@ -141,7 +141,7 @@ void test_strcpy_new_int16_t (size_t n, const size_t vals[])
int r_imin_imax = SR (INT_MIN, INT_MAX);
T (S (1), new int16_t[r_imin_imax]);
- T (S (2), new int16_t[r_imin_imax + 1]); // { dg-bogus "into a region of size" "pr106120" { xfail { c++98_only } } }
+ T (S (2), new int16_t[r_imin_imax + 1]); // { dg-bogus "into a region of size" "pr106120" { xfail { lp64 && c++98_only } } }
T (S (9), new int16_t[r_imin_imax * 2 + 1]);
int r_0_imax = SR (0, INT_MAX);
diff --git a/gcc/testsuite/g++.target/i386/pr89316.C b/gcc/testsuite/g++.target/i386/pr89316.C
new file mode 100644
index 0000000..2f05ef7
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr89316.C
@@ -0,0 +1,6 @@
+// PR target/89316
+// { dg-do compile }
+// { dg-require-effective-target split_stack }
+// { dg-options "-fsplit-stack -mforce-indirect-call" }
+
+struct foo { foo (); } foobar;
diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/bug-14.C b/gcc/testsuite/g++.target/riscv/rvv/base/bug-14.C
index bf0c7bd..f2d67c85 100644
--- a/gcc/testsuite/g++.target/riscv/rvv/base/bug-14.C
+++ b/gcc/testsuite/g++.target/riscv/rvv/base/bug-14.C
@@ -1,5 +1,7 @@
-/* { dg-do run { target { { {riscv_v} && {rv64} } } } } */
+/* { dg-do run } */
/* { dg-options "-O2" } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-require-effective-target riscv_v } */
#include<cstdalign>
#include<cmath>
diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/bug-9.C b/gcc/testsuite/g++.target/riscv/rvv/base/bug-9.C
index 8d17883..c43dfae 100644
--- a/gcc/testsuite/g++.target/riscv/rvv/base/bug-9.C
+++ b/gcc/testsuite/g++.target/riscv/rvv/base/bug-9.C
@@ -1,5 +1,7 @@
-/* { dg-do run { target { { {riscv_v} && {rv64} } } } } */
+/* { dg-do run } */
/* { dg-options "-O2" } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-require-effective-target riscv_v } */
#include<cstdalign>
#include<cmath>
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106433.c b/gcc/testsuite/gcc.c-torture/compile/pr106433.c
index b840e5e..e02ad5f 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr106433.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106433.c
@@ -2,7 +2,7 @@
int m, *p;
-__attribute__ ((simd)) int
+__attribute__ ((simd,noipa)) int
bar (int x)
{
if (x)
diff --git a/gcc/testsuite/gcc.c-torture/execute/frame-address.c b/gcc/testsuite/gcc.c-torture/execute/frame-address.c
index 5afa691..5950581 100644
--- a/gcc/testsuite/gcc.c-torture/execute/frame-address.c
+++ b/gcc/testsuite/gcc.c-torture/execute/frame-address.c
@@ -1,10 +1,10 @@
/* { dg-require-effective-target return_address } */
void abort (void);
-int check_fa_work (const char *, const char *) __attribute__((noinline));
-int check_fa_mid (const char *) __attribute__((noinline));
-int check_fa (char *) __attribute__((noinline));
-int how_much (void) __attribute__((noinline));
+int check_fa_work (const char *, const char *) __attribute__((noinline,noipa));
+int check_fa_mid (const char *) __attribute__((noinline,noipa));
+int check_fa (char *) __attribute__((noinline,noipa));
+int how_much (void) __attribute__((noinline,noipa));
int check_fa_work (const char *c, const char *f)
{
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111408.c b/gcc/testsuite/gcc.c-torture/execute/pr111408.c
new file mode 100644
index 0000000..6dfb0a3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr111408.c
@@ -0,0 +1,26 @@
+/* PR target/111408 */
+
+int a, b, c, d;
+short e;
+
+int
+foo ()
+{
+ c = a % (sizeof (int) * 8);
+ if (b & 1 << c)
+ return -1;
+ return 0;
+}
+
+int
+main ()
+{
+ for (; e != 1; e++)
+ {
+ int g = foo ();
+ if (g + d - 9 + d)
+ continue;
+ for (;;)
+ __builtin_abort ();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-4.c b/gcc/testsuite/gcc.dg/analyzer/fd-4.c
index 994bad8..3a961e4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-4.c
@@ -1,4 +1,4 @@
-#ifdef _AIX
+#if defined(_AIX) || defined(__hpux)
#define _MODE_T
#endif
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c
index fa98e3c..6d4dc60 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c
@@ -1,6 +1,6 @@
/* Example from the glibc manual (16.10.4). */
/* { dg-require-effective-target sockets } */
-/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */
#include <stdio.h>
#include <errno.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c
index 0d4894d..7e179cf 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c
@@ -1,6 +1,6 @@
/* Example from glibc manual (16.10.3). */
/* { dg-require-effective-target sockets } */
-/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */
#include <stdio.h>
#include <errno.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c
index 8cf7a42..85ccae8 100644
--- a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c
@@ -1,4 +1,4 @@
-/* { dg-skip-if "no strndup in libc" { *-*-darwin[789]* *-*-darwin10* *-*-mingw* *-*-vxworks* } } */
+/* { dg-skip-if "no strndup in libc" { *-*-darwin[789]* *-*-darwin10* hppa*-*-hpux* *-*-mingw* *-*-vxworks* } } */
#include <string.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/asan/has-feature-asan.c b/gcc/testsuite/gcc.dg/asan/has-feature-asan.c
new file mode 100644
index 0000000..810b69b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/has-feature-asan.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=address" } */
+#define FEAT(x) (__has_feature (x) && __has_extension (x))
+#if !FEAT (address_sanitizer)
+#error
+#endif
diff --git a/gcc/testsuite/gcc.dg/bitint-40.c b/gcc/testsuite/gcc.dg/bitint-40.c
new file mode 100644
index 0000000..e418509
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-40.c
@@ -0,0 +1,29 @@
+/* PR middle-end/112668 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c23 -fnon-call-exceptions" } */
+
+#if __BITINT_MAXWIDTH__ >= 156
+struct T156 { _BitInt(156) a : 2; unsigned _BitInt(156) b : 135; _BitInt(156) c : 2; };
+extern void foo156 (struct T156 *);
+
+unsigned _BitInt(156)
+bar156 (int i)
+{
+ struct T156 r156[12];
+ foo156 (&r156[0]);
+ return r156[i].b;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 495
+struct T495 { _BitInt(495) a : 2; unsigned _BitInt(495) b : 471; _BitInt(495) c : 2; };
+extern void foo495 (struct T495 *r495);
+
+unsigned _BitInt(495)
+bar495 (int i)
+{
+ struct T495 r495[12];
+ foo495 (r495);
+ return r495[i].b;
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/bitint-41.c b/gcc/testsuite/gcc.dg/bitint-41.c
new file mode 100644
index 0000000..d87ea08
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-41.c
@@ -0,0 +1,36 @@
+/* PR middle-end/112336 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2x" } */
+
+unsigned _BitInt(1) v1;
+unsigned _BitInt(1) *p1 = &v1;
+signed _BitInt(2) v2;
+signed _BitInt(2) *p2 = &v2;
+unsigned _BitInt(11) v11;
+unsigned _BitInt(11) *p11 = &v11;
+signed _BitInt(12) v12;
+signed _BitInt(12) *p12 = &v12;
+unsigned _BitInt(21) v21;
+unsigned _BitInt(21) *p21 = &v21;
+signed _BitInt(22) v22;
+signed _BitInt(22) *p22 = &v22;
+unsigned _BitInt(31) v31;
+unsigned _BitInt(31) *p31 = &v31;
+signed _BitInt(32) v32;
+signed _BitInt(32) *p32 = &v32;
+unsigned _BitInt(41) v41;
+unsigned _BitInt(41) *p41 = &v41;
+signed _BitInt(42) v42;
+signed _BitInt(42) *p42 = &v42;
+#if __BITINT_MAXWIDTH__ >= 128
+unsigned _BitInt(127) v127;
+unsigned _BitInt(127) *p127 = &v127;
+signed _BitInt(128) v128;
+signed _BitInt(128) *p128 = &v128;
+#endif
+#if __BITINT_MAXWIDTH__ >= 258
+unsigned _BitInt(257) v257;
+unsigned _BitInt(257) *p257 = &v257;
+signed _BitInt(258) v258;
+signed _BitInt(258) *p258 = &v258;
+#endif
diff --git a/gcc/testsuite/gcc.dg/bitint-42.c b/gcc/testsuite/gcc.dg/bitint-42.c
new file mode 100644
index 0000000..9d3090b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-42.c
@@ -0,0 +1,9 @@
+/* PR middle-end/112679 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-frounding-math" } */
+
+float
+foo (void)
+{
+ return 0x353eab28b46b03ea99b84f9736cd8dbe5e986915a0383c3cb381c0da41e31b3621c75fd53262bfcb1b0e6251dbf00f3988784e29b08b65640c263e4d0959832a20e2ff5245be1e60uwb;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c b/gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c
new file mode 100644
index 0000000..6ba95ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c
@@ -0,0 +1,927 @@
+/* { dg-do run } */
+/* { dg-options "-std=c11" } */
+
+unsigned int
+leading_zeros (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_leading_zeros (a)
+ + __builtin_stdc_leading_zeros (b)
+ + __builtin_stdc_leading_zeros (c)
+ + __builtin_stdc_leading_zeros (d)
+ + __builtin_stdc_leading_zeros (e));
+}
+
+unsigned int
+leading_ones (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_leading_ones (a)
+ + __builtin_stdc_leading_ones (b)
+ + __builtin_stdc_leading_ones (c)
+ + __builtin_stdc_leading_ones (d)
+ + __builtin_stdc_leading_ones (e));
+}
+
+unsigned int
+trailing_zeros (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_trailing_zeros (a)
+ + __builtin_stdc_trailing_zeros (b)
+ + __builtin_stdc_trailing_zeros (c)
+ + __builtin_stdc_trailing_zeros (d)
+ + __builtin_stdc_trailing_zeros (e));
+}
+
+unsigned int
+trailing_ones (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_trailing_ones (a)
+ + __builtin_stdc_trailing_ones (b)
+ + __builtin_stdc_trailing_ones (c)
+ + __builtin_stdc_trailing_ones (d)
+ + __builtin_stdc_trailing_ones (e));
+}
+
+unsigned int
+first_leading_zero (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_first_leading_zero (a)
+ + __builtin_stdc_first_leading_zero (b)
+ + __builtin_stdc_first_leading_zero (c)
+ + __builtin_stdc_first_leading_zero (d)
+ + __builtin_stdc_first_leading_zero (e));
+}
+
+unsigned int
+first_leading_one (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_first_leading_one (a)
+ + __builtin_stdc_first_leading_one (b)
+ + __builtin_stdc_first_leading_one (c)
+ + __builtin_stdc_first_leading_one (d)
+ + __builtin_stdc_first_leading_one (e));
+}
+
+unsigned int
+first_trailing_zero (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_first_trailing_zero (a)
+ + __builtin_stdc_first_trailing_zero (b)
+ + __builtin_stdc_first_trailing_zero (c)
+ + __builtin_stdc_first_trailing_zero (d)
+ + __builtin_stdc_first_trailing_zero (e));
+}
+
+unsigned int
+first_trailing_one (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_first_trailing_one (a)
+ + __builtin_stdc_first_trailing_one (b)
+ + __builtin_stdc_first_trailing_one (c)
+ + __builtin_stdc_first_trailing_one (d)
+ + __builtin_stdc_first_trailing_one (e));
+}
+
+unsigned int
+count_zeros (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_count_zeros (a)
+ + __builtin_stdc_count_zeros (b)
+ + __builtin_stdc_count_zeros (c)
+ + __builtin_stdc_count_zeros (d)
+ + __builtin_stdc_count_zeros (e));
+}
+
+unsigned int
+count_ones (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_count_ones (a)
+ + __builtin_stdc_count_ones (b)
+ + __builtin_stdc_count_ones (c)
+ + __builtin_stdc_count_ones (d)
+ + __builtin_stdc_count_ones (e));
+}
+
+unsigned int
+has_single_bit (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_has_single_bit (a)
+ || __builtin_stdc_has_single_bit (b)
+ || __builtin_stdc_has_single_bit (c)
+ || __builtin_stdc_has_single_bit (d)
+ || __builtin_stdc_has_single_bit (e));
+}
+
+unsigned int
+bit_width (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_bit_width (a)
+ + __builtin_stdc_bit_width (b)
+ + __builtin_stdc_bit_width (c)
+ + __builtin_stdc_bit_width (d)
+ + __builtin_stdc_bit_width (e));
+}
+
+unsigned long long
+bit_floor (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_bit_floor (a)
+ + __builtin_stdc_bit_floor (b)
+ + __builtin_stdc_bit_floor (c)
+ + __builtin_stdc_bit_floor (d)
+ + __builtin_stdc_bit_floor (e));
+}
+
+unsigned long long
+bit_ceil (unsigned char a, unsigned short b, unsigned int c,
+ unsigned long d, unsigned long long e)
+{
+ return (__builtin_stdc_bit_ceil (a)
+ + __builtin_stdc_bit_ceil (b)
+ + __builtin_stdc_bit_ceil (c)
+ + __builtin_stdc_bit_ceil (d)
+ + __builtin_stdc_bit_ceil (e));
+}
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+
+int
+main ()
+{
+ if (__builtin_stdc_leading_zeros ((unsigned char) 0) != __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_leading_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_leading_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_leading_zeros (0U), unsigned int)
+ || __builtin_stdc_leading_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_leading_zeros (0UL), unsigned int)
+ || __builtin_stdc_leading_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_leading_zeros (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_leading_zeros ((unsigned char) ~0U) != 0
+ || __builtin_stdc_leading_zeros ((unsigned short) ~0U) != 0
+ || __builtin_stdc_leading_zeros (~0U) != 0
+ || __builtin_stdc_leading_zeros (~0UL) != 0
+ || __builtin_stdc_leading_zeros (~0ULL) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_zeros ((unsigned char) 3) != __CHAR_BIT__ - 2
+ || __builtin_stdc_leading_zeros ((unsigned short) 9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 4
+ || __builtin_stdc_leading_zeros (34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 6
+ || __builtin_stdc_leading_zeros (130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 8
+ || __builtin_stdc_leading_zeros (512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 10)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones ((unsigned char) 0) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_leading_ones ((unsigned short) 0) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_leading_ones (0U) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones (0U), unsigned int)
+ || __builtin_stdc_leading_ones (0UL) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones (0UL), unsigned int)
+ || __builtin_stdc_leading_ones (0ULL) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones ((unsigned char) ~0U) != __CHAR_BIT__
+ || __builtin_stdc_leading_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+ || __builtin_stdc_leading_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+ || __builtin_stdc_leading_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+ || __builtin_stdc_leading_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones ((unsigned char) ~3) != __CHAR_BIT__ - 2
+ || __builtin_stdc_leading_ones ((unsigned short) ~9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 4
+ || __builtin_stdc_leading_ones (~34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 6
+ || __builtin_stdc_leading_ones (~130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 8
+ || __builtin_stdc_leading_ones (~512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 10)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros ((unsigned char) 0) != __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_trailing_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_trailing_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_trailing_zeros (0U), unsigned int)
+ || __builtin_stdc_trailing_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_trailing_zeros (0UL), unsigned int)
+ || __builtin_stdc_trailing_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_trailing_zeros (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros ((unsigned char) ~0U) != 0
+ || __builtin_stdc_trailing_zeros ((unsigned short) ~0U) != 0
+ || __builtin_stdc_trailing_zeros (~0U) != 0
+ || __builtin_stdc_trailing_zeros (~0UL) != 0
+ || __builtin_stdc_trailing_zeros (~0ULL) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros ((unsigned char) 2) != 1
+ || __builtin_stdc_trailing_zeros ((unsigned short) 24) != 3
+ || __builtin_stdc_trailing_zeros (32U) != 5
+ || __builtin_stdc_trailing_zeros (128UL) != 7
+ || __builtin_stdc_trailing_zeros (512ULL) != 9)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones ((unsigned char) 0) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_trailing_ones ((unsigned short) 0) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_trailing_ones (0U) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones (0U), unsigned int)
+ || __builtin_stdc_trailing_ones (0UL) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones (0UL), unsigned int)
+ || __builtin_stdc_trailing_ones (0ULL) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones ((unsigned char) ~0U) != __CHAR_BIT__
+ || __builtin_stdc_trailing_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+ || __builtin_stdc_trailing_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+ || __builtin_stdc_trailing_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+ || __builtin_stdc_trailing_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones ((unsigned char) 5) != 1
+ || __builtin_stdc_trailing_ones ((unsigned short) 15) != 4
+ || __builtin_stdc_trailing_ones (127U) != 7
+ || __builtin_stdc_trailing_ones (511UL) != 9
+ || __builtin_stdc_trailing_ones (~0ULL >> 2) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 2)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero ((unsigned char) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_first_leading_zero ((unsigned short) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_first_leading_zero (0U) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero (0U), unsigned int)
+ || __builtin_stdc_first_leading_zero (0UL) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero (0UL), unsigned int)
+ || __builtin_stdc_first_leading_zero (0ULL) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero ((unsigned char) ~0U) != 0
+ || __builtin_stdc_first_leading_zero ((unsigned short) ~0U) != 0
+ || __builtin_stdc_first_leading_zero (~0U) != 0
+ || __builtin_stdc_first_leading_zero (~0UL) != 0
+ || __builtin_stdc_first_leading_zero (~0ULL) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero ((unsigned char) ~3U) != __CHAR_BIT__ - 1
+ || __builtin_stdc_first_leading_zero ((unsigned short) ~15U) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+ || __builtin_stdc_first_leading_zero (~63U) != __SIZEOF_INT__ * __CHAR_BIT__ - 5
+ || __builtin_stdc_first_leading_zero (~255UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 7
+ || __builtin_stdc_first_leading_zero (~1023ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 9)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one ((unsigned char) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_first_leading_one ((unsigned short) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_first_leading_one (0U) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one (0U), unsigned int)
+ || __builtin_stdc_first_leading_one (0UL) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one (0UL), unsigned int)
+ || __builtin_stdc_first_leading_one (0ULL) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one ((unsigned char) ~0U) != 1
+ || __builtin_stdc_first_leading_one ((unsigned short) ~0U) != 1
+ || __builtin_stdc_first_leading_one (~0U) != 1
+ || __builtin_stdc_first_leading_one (~0UL) != 1
+ || __builtin_stdc_first_leading_one (~0ULL) != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one ((unsigned char) 3) != __CHAR_BIT__ - 1
+ || __builtin_stdc_first_leading_one ((unsigned short) 9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+ || __builtin_stdc_first_leading_one (34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 5
+ || __builtin_stdc_first_leading_one (130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 7
+ || __builtin_stdc_first_leading_one (512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 9)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero ((unsigned char) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_first_trailing_zero ((unsigned short) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_first_trailing_zero (0U) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero (0U), unsigned int)
+ || __builtin_stdc_first_trailing_zero (0UL) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero (0UL), unsigned int)
+ || __builtin_stdc_first_trailing_zero (0ULL) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero ((unsigned char) ~0U) != 0
+ || __builtin_stdc_first_trailing_zero ((unsigned short) ~0U) != 0
+ || __builtin_stdc_first_trailing_zero (~0U) != 0
+ || __builtin_stdc_first_trailing_zero (~0UL) != 0
+ || __builtin_stdc_first_trailing_zero (~0ULL) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero ((unsigned char) 2) != 1
+ || __builtin_stdc_first_trailing_zero ((unsigned short) 15) != 5
+ || __builtin_stdc_first_trailing_zero (63U) != 7
+ || __builtin_stdc_first_trailing_zero (128UL) != 1
+ || __builtin_stdc_first_trailing_zero (511ULL) != 10)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one ((unsigned char) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_first_trailing_one ((unsigned short) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_first_trailing_one (0U) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one (0U), unsigned int)
+ || __builtin_stdc_first_trailing_one (0UL) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one (0UL), unsigned int)
+ || __builtin_stdc_first_trailing_one (0ULL) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one ((unsigned char) ~0U) != 1
+ || __builtin_stdc_first_trailing_one ((unsigned short) ~0U) != 1
+ || __builtin_stdc_first_trailing_one (~0U) != 1
+ || __builtin_stdc_first_trailing_one (~0UL) != 1
+ || __builtin_stdc_first_trailing_one (~0ULL) != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one ((unsigned char) 4) != 3
+ || __builtin_stdc_first_trailing_one ((unsigned short) 96) != 6
+ || __builtin_stdc_first_trailing_one (127U) != 1
+ || __builtin_stdc_first_trailing_one (511UL) != 1
+ || __builtin_stdc_first_trailing_one (~0ULL << 12) != 13)
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros ((unsigned char) 0) != __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_count_zeros ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_count_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_count_zeros ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_count_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_count_zeros (0U), unsigned int)
+ || __builtin_stdc_count_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_count_zeros (0UL), unsigned int)
+ || __builtin_stdc_count_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_count_zeros (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros ((unsigned char) ~0U) != 0
+ || __builtin_stdc_count_zeros ((unsigned short) ~0U) != 0
+ || __builtin_stdc_count_zeros (~0U) != 0
+ || __builtin_stdc_count_zeros (~0UL) != 0
+ || __builtin_stdc_count_zeros (~0ULL) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros ((unsigned char) 1U) != __CHAR_BIT__ - 1
+ || __builtin_stdc_count_zeros ((unsigned short) 42) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+ || __builtin_stdc_count_zeros (291U) != __SIZEOF_INT__ * __CHAR_BIT__ - 4
+ || __builtin_stdc_count_zeros (~1315UL) != 5
+ || __builtin_stdc_count_zeros (3363ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 6)
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones ((unsigned char) 0) != 0
+ || !expr_has_type (__builtin_stdc_count_ones ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_count_ones ((unsigned short) 0) != 0
+ || !expr_has_type (__builtin_stdc_count_ones ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_count_ones (0U) != 0
+ || !expr_has_type (__builtin_stdc_count_ones (0U), unsigned int)
+ || __builtin_stdc_count_ones (0UL) != 0
+ || !expr_has_type (__builtin_stdc_count_ones (0UL), unsigned int)
+ || __builtin_stdc_count_ones (0ULL) != 0
+ || !expr_has_type (__builtin_stdc_count_ones (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones ((unsigned char) ~0U) != __CHAR_BIT__
+ || __builtin_stdc_count_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+ || __builtin_stdc_count_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+ || __builtin_stdc_count_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+ || __builtin_stdc_count_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones ((unsigned char) ~1U) != __CHAR_BIT__ - 1
+ || __builtin_stdc_count_ones ((unsigned short) ~42) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+ || __builtin_stdc_count_ones (~291U) != __SIZEOF_INT__ * __CHAR_BIT__ - 4
+ || __builtin_stdc_count_ones (1315UL) != 5
+ || __builtin_stdc_count_ones (~3363ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 6)
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit ((unsigned char) 0)
+ || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned char) 0), _Bool)
+ || __builtin_stdc_has_single_bit ((unsigned short) 0)
+ || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned short) 0), _Bool)
+ || __builtin_stdc_has_single_bit (0U)
+ || !expr_has_type (__builtin_stdc_has_single_bit (0U), _Bool)
+ || __builtin_stdc_has_single_bit (0UL)
+ || !expr_has_type (__builtin_stdc_has_single_bit (0UL), _Bool)
+ || __builtin_stdc_has_single_bit (0ULL)
+ || !expr_has_type (__builtin_stdc_has_single_bit (0ULL), _Bool))
+ __builtin_abort ();
+ if (!__builtin_stdc_has_single_bit ((unsigned char) 2)
+ || !__builtin_stdc_has_single_bit ((unsigned short) 8)
+ || !__builtin_stdc_has_single_bit (32U)
+ || !__builtin_stdc_has_single_bit (128UL)
+ || !__builtin_stdc_has_single_bit (512ULL))
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit ((unsigned char) 7)
+ || __builtin_stdc_has_single_bit ((unsigned short) 96)
+ || __builtin_stdc_has_single_bit (513U)
+ || __builtin_stdc_has_single_bit (1022UL)
+ || __builtin_stdc_has_single_bit (12ULL))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width ((unsigned char) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_width ((unsigned char) 0), unsigned int)
+ || __builtin_stdc_bit_width ((unsigned short) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_width ((unsigned short) 0), unsigned int)
+ || __builtin_stdc_bit_width (0U) != 0
+ || !expr_has_type (__builtin_stdc_bit_width (0U), unsigned int)
+ || __builtin_stdc_bit_width (0UL) != 0
+ || !expr_has_type (__builtin_stdc_bit_width (0UL), unsigned int)
+ || __builtin_stdc_bit_width (0ULL) != 0
+ || !expr_has_type (__builtin_stdc_bit_width (0ULL), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width ((unsigned char) ~0U) != __CHAR_BIT__
+ || __builtin_stdc_bit_width ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+ || __builtin_stdc_bit_width (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+ || __builtin_stdc_bit_width (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+ || __builtin_stdc_bit_width (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width ((unsigned char) ((unsigned char) ~0U >> 1)) != __CHAR_BIT__ - 1
+ || __builtin_stdc_bit_width ((unsigned char) 6) != 3
+ || __builtin_stdc_bit_width ((unsigned short) 12U) != 4
+ || __builtin_stdc_bit_width ((unsigned short) ((unsigned short) ~0U >> 5)) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 5
+ || __builtin_stdc_bit_width (137U) != 8
+ || __builtin_stdc_bit_width (269U) != 9
+ || __builtin_stdc_bit_width (39UL) != 6
+ || __builtin_stdc_bit_width (~0UL >> 2) != __SIZEOF_LONG__ * __CHAR_BIT__ - 2
+ || __builtin_stdc_bit_width (1023ULL) != 10
+ || __builtin_stdc_bit_width (1024ULL) != 11)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor ((unsigned char) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_floor ((unsigned char) 0), unsigned char)
+ || __builtin_stdc_bit_floor ((unsigned short) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_floor ((unsigned short) 0), unsigned short)
+ || __builtin_stdc_bit_floor (0U) != 0U
+ || !expr_has_type (__builtin_stdc_bit_floor (0U), unsigned int)
+ || __builtin_stdc_bit_floor (0UL) != 0UL
+ || !expr_has_type (__builtin_stdc_bit_floor (0UL), unsigned long)
+ || __builtin_stdc_bit_floor (0ULL) != 0ULL
+ || !expr_has_type (__builtin_stdc_bit_floor (0ULL), unsigned long long))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor ((unsigned char) ~0U) != (1U << (__CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_floor ((unsigned short) ~0U) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_floor (~0U) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_floor (~0UL) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_floor (~0ULL) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor ((unsigned char) 4) != 4
+ || __builtin_stdc_bit_floor ((unsigned char) 7) != 4
+ || __builtin_stdc_bit_floor ((unsigned short) 8U) != 8
+ || __builtin_stdc_bit_floor ((unsigned short) 31U) != 16
+ || __builtin_stdc_bit_floor (137U) != 128U
+ || __builtin_stdc_bit_floor (269U) != 256U
+ || __builtin_stdc_bit_floor (511UL) != 256UL
+ || __builtin_stdc_bit_floor (512UL) != 512UL
+ || __builtin_stdc_bit_floor (513UL) != 512ULL
+ || __builtin_stdc_bit_floor (1024ULL) != 1024ULL)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil ((unsigned char) 0) != 1
+ || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned char) 0), unsigned char)
+ || __builtin_stdc_bit_ceil ((unsigned short) 0) != 1
+ || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned short) 0), unsigned short)
+ || __builtin_stdc_bit_ceil (0U) != 1U
+ || !expr_has_type (__builtin_stdc_bit_ceil (0U), unsigned int)
+ || __builtin_stdc_bit_ceil (0UL) != 1UL
+ || !expr_has_type (__builtin_stdc_bit_ceil (0UL), unsigned long)
+ || __builtin_stdc_bit_ceil (0ULL) != 1ULL
+ || !expr_has_type (__builtin_stdc_bit_ceil (0ULL), unsigned long long))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil ((unsigned char) ~0U) != 0
+ || __builtin_stdc_bit_ceil ((unsigned short) ~0U) != 0
+ || __builtin_stdc_bit_ceil (~0U) != 0U
+ || __builtin_stdc_bit_ceil (~0UL) != 0UL
+ || __builtin_stdc_bit_ceil (~0ULL) != 0ULL)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil (~0U >> 1) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1)) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1))
+ || __builtin_stdc_bit_ceil (~0ULL >> 1) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil ((unsigned char) 1) != 1
+ || __builtin_stdc_bit_ceil ((unsigned char) 2) != 2
+ || __builtin_stdc_bit_ceil ((unsigned short) 3U) != 4
+ || __builtin_stdc_bit_ceil ((unsigned short) 4U) != 4
+ || __builtin_stdc_bit_ceil (5U) != 8U
+ || __builtin_stdc_bit_ceil (269U) != 512U
+ || __builtin_stdc_bit_ceil (511UL) != 512UL
+ || __builtin_stdc_bit_ceil (512UL) != 512UL
+ || __builtin_stdc_bit_ceil (513ULL) != 1024ULL
+ || __builtin_stdc_bit_ceil (1025ULL) != 2048ULL)
+ __builtin_abort ();
+#ifdef __SIZEOF_INT128__
+ if (__builtin_stdc_leading_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_leading_zeros (~(unsigned __int128) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones ((unsigned __int128) 0) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_leading_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_trailing_zeros (~(unsigned __int128) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones ((unsigned __int128) 0) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_trailing_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero ((unsigned __int128) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_first_leading_zero (~(unsigned __int128) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one ((unsigned __int128) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_first_leading_one (~(unsigned __int128) 0) != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero ((unsigned __int128) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_first_trailing_zero (~(unsigned __int128) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one ((unsigned __int128) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_first_trailing_one (~(unsigned __int128) 0) != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+ || !expr_has_type (__builtin_stdc_count_zeros ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_count_zeros (~(unsigned __int128) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones ((unsigned __int128) 0) != 0
+ || !expr_has_type (__builtin_stdc_count_ones ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_count_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit ((unsigned __int128) 0)
+ || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned __int128) 0), _Bool)
+ || __builtin_stdc_has_single_bit (~(unsigned __int128) 0))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width ((unsigned __int128) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_width ((unsigned __int128) 0), unsigned int)
+ || __builtin_stdc_bit_width (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor ((unsigned __int128) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_floor ((unsigned __int128) 0), unsigned __int128)
+ || __builtin_stdc_bit_floor (~(unsigned __int128) 0) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil ((unsigned __int128) 0) != 1
+ || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned __int128) 0), unsigned __int128)
+ || __builtin_stdc_bit_ceil ((unsigned __int128) 1) != 1
+ || __builtin_stdc_bit_ceil ((~(unsigned __int128) 0) >> 1) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1)
+ || __builtin_stdc_bit_ceil (~(unsigned __int128) 0) != 0)
+ __builtin_abort ();
+#endif
+#if __has_builtin (__builtin_stdc_leading_zeros) != 1
+#error __builtin_stdc_leading_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_leading_ones) != 1
+#error __builtin_stdc_leading_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_trailing_zeros) != 1
+#error __builtin_stdc_trailing_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_trailing_ones) != 1
+#error __builtin_stdc_trailing_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_leading_zero) != 1
+#error __builtin_stdc_first_leading_zero not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_leading_one) != 1
+#error __builtin_stdc_first_leading_one not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_trailing_zero) != 1
+#error __builtin_stdc_first_trailing_zero not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_trailing_one) != 1
+#error __builtin_stdc_first_trailing_one not implemented
+#endif
+#if __has_builtin (__builtin_stdc_count_zeros) != 1
+#error __builtin_stdc_count_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_count_ones) != 1
+#error __builtin_stdc_count_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_has_single_bit) != 1
+#error __builtin_stdc_single_bit not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_width) != 1
+#error __builtin_stdc_bit_width not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_floor) != 1
+#error __builtin_stdc_bit_floor not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_ceil) != 1
+#error __builtin_stdc_bit_ceil not implemented
+#endif
+ unsigned char a = 0;
+ if (__builtin_stdc_bit_width (a++) != 0 || a != 1)
+ __builtin_abort ();
+ unsigned long long b = 0;
+ if (__builtin_stdc_bit_width (b++) != 0 || b != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (a++) != 1 || a != 2)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (b++) != 1 || b != 2)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (a++) != 2 || a != 3)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (b++) != 2 || b != 3)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_zeros (a++) != __CHAR_BIT__ - 2 || a != 4)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_zeros (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 2 || b != 4)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones (a++) != 0 || a != 5)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones (b++) != 0 || b != 5)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros (a++) != 0 || a != 6)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros (b++) != 0 || b != 6)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones (a++) != 0 || a != 7)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones (b++) != 0 || b != 7)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero (a++) != 1 || a != 8)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero (b++) != 1 || b != 8)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one (a++) != __CHAR_BIT__ - 3 || a != 9)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 3 || b != 9)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero (a++) != 2 || a != 10)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero (b++) != 2 || b != 10)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one (a++) != 2 || a != 11)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one (b++) != 2 || b != 11)
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros (a++) != __CHAR_BIT__ - 3 || a != 12)
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 3 || b != 12)
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones (a++) != 2 || a != 13)
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones (b++) != 2 || b != 13)
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit (a++) || a != 14)
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit (b++) || b != 14)
+ __builtin_abort ();
+#if __BITINT_MAXWIDTH__ >= 64
+ if (__builtin_stdc_leading_zeros (0uwb) != 1
+ || !expr_has_type (__builtin_stdc_leading_zeros (0uwb), unsigned int)
+ || __builtin_stdc_leading_zeros (1uwb) != 0
+ || !expr_has_type (__builtin_stdc_leading_zeros (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones (0uwb) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones (0uwb), unsigned int)
+ || __builtin_stdc_leading_ones (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_leading_ones (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros (0uwb) != 1
+ || !expr_has_type (__builtin_stdc_trailing_zeros (0uwb), unsigned int)
+ || __builtin_stdc_trailing_zeros (1uwb) != 0
+ || !expr_has_type (__builtin_stdc_trailing_zeros (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones (0uwb) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones (0uwb), unsigned int)
+ || __builtin_stdc_trailing_ones (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_trailing_ones (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero (0uwb) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero (0uwb), unsigned int)
+ || __builtin_stdc_first_leading_zero (1uwb) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_zero (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one (0uwb) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one (0uwb), unsigned int)
+ || __builtin_stdc_first_leading_one (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_one (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero (0uwb) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero (0uwb), unsigned int)
+ || __builtin_stdc_first_trailing_zero (1uwb) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_zero (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one (0uwb) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one (0uwb), unsigned int)
+ || __builtin_stdc_first_trailing_one (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_one (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros (0uwb) != 1
+ || !expr_has_type (__builtin_stdc_count_zeros (0uwb), unsigned int)
+ || __builtin_stdc_count_zeros (1uwb) != 0
+ || !expr_has_type (__builtin_stdc_count_zeros (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones (0uwb) != 0
+ || !expr_has_type (__builtin_stdc_count_ones (0uwb), unsigned int)
+ || __builtin_stdc_count_ones (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_count_ones (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit (0uwb)
+ || !expr_has_type (__builtin_stdc_has_single_bit (0uwb), _Bool)
+ || !__builtin_stdc_has_single_bit (1uwb)
+ || !expr_has_type (__builtin_stdc_has_single_bit (1uwb), _Bool))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width (0uwb) != 0
+ || !expr_has_type (__builtin_stdc_bit_width (0uwb), unsigned int)
+ || __builtin_stdc_bit_width (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_bit_width (1uwb), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (0uwb) != 0
+ || !expr_has_type (__builtin_stdc_bit_floor (0uwb), unsigned _BitInt(1))
+ || __builtin_stdc_bit_floor (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_bit_floor (1uwb), unsigned _BitInt(1)))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (0uwb) != 1
+ || !expr_has_type (__builtin_stdc_bit_ceil (0uwb), unsigned _BitInt(1))
+ || __builtin_stdc_bit_ceil (1uwb) != 1
+ || !expr_has_type (__builtin_stdc_bit_ceil (1uwb), unsigned _BitInt(1)))
+ __builtin_abort ();
+ unsigned _BitInt(1) c = 0;
+ if (__builtin_stdc_bit_floor (c++) != 0 || c != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (c++) != 1 || c != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (c++) != 1 || c != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (c++) != 1 || c != 0)
+ __builtin_abort ();
+#endif
+#if __BITINT_MAXWIDTH__ >= 512
+ if (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0) != 512
+ || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 0) != 373
+ || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_leading_zeros (~(unsigned _BitInt(512)) 0) != 0
+ || __builtin_stdc_leading_zeros (~(unsigned _BitInt(373)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 275) != 512 - 9
+ || __builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 512) != 373 - 10)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones ((unsigned _BitInt(512)) 0) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_leading_ones ((unsigned _BitInt(373)) 0) != 0
+ || !expr_has_type (__builtin_stdc_leading_ones ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones (~(unsigned _BitInt(512)) 0) != 512
+ || __builtin_stdc_leading_ones (~(unsigned _BitInt(373)) 0) != 373)
+ __builtin_abort ();
+ if (__builtin_stdc_leading_ones (~(unsigned _BitInt(512)) 275) != 512 - 9
+ || __builtin_stdc_leading_ones (~(unsigned _BitInt(373)) 512) != 373 - 10)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 0) != 512
+ || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 0) != 373
+ || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros (~(unsigned _BitInt(512)) 0) != 0
+ || __builtin_stdc_trailing_zeros (~(unsigned _BitInt(373)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 256) != 8
+ || __builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 512) != 9)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 0) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_trailing_ones ((unsigned _BitInt(373)) 0) != 0
+ || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones (~(unsigned _BitInt(512)) 0) != 512
+ || __builtin_stdc_trailing_ones (~(unsigned _BitInt(373)) 0) != 373)
+ __builtin_abort ();
+ if (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 255) != 8
+ || __builtin_stdc_trailing_ones ((~(unsigned _BitInt(373)) 0) >> 2) != 373 - 2)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero ((unsigned _BitInt(512)) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_first_leading_zero ((unsigned _BitInt(373)) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero (~(unsigned _BitInt(512)) 0) != 0
+ || __builtin_stdc_first_leading_zero (~(unsigned _BitInt(373)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_zero (~(unsigned _BitInt(512)) 511) != 512 - 8
+ || __builtin_stdc_first_leading_zero (~(unsigned _BitInt(373)) 1023) != 373 - 9)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one (~(unsigned _BitInt(512)) 0) != 1
+ || __builtin_stdc_first_leading_one (~(unsigned _BitInt(373)) 0) != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 275) != 512 - 8
+ || __builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 512) != 373 - 9)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 0) != 1
+ || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero (~(unsigned _BitInt(512)) 0) != 0
+ || __builtin_stdc_first_trailing_zero (~(unsigned _BitInt(373)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 255) != 9
+ || __builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 511) != 10)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one ((unsigned _BitInt(512)) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_first_trailing_one ((unsigned _BitInt(373)) 0) != 0
+ || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one (~(unsigned _BitInt(512)) 0) != 1
+ || __builtin_stdc_first_trailing_one (~(unsigned _BitInt(373)) 0) != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_first_trailing_one (((unsigned _BitInt(512)) 255) << 175) != 176
+ || __builtin_stdc_first_trailing_one ((~(unsigned _BitInt(373)) 0) << 311) != 312)
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 0) != 512
+ || !expr_has_type (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_count_zeros ((unsigned _BitInt(373)) 0) != 373
+ || !expr_has_type (__builtin_stdc_count_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros (~(unsigned _BitInt(512)) 0) != 0
+ || __builtin_stdc_count_zeros (~(unsigned _BitInt(373)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 1315) != 512 - 5
+ || __builtin_stdc_count_zeros ((unsigned _BitInt(373)) 3363) != 373 - 6)
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones ((unsigned _BitInt(512)) 0) != 0
+ || !expr_has_type (__builtin_stdc_count_ones ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_count_ones ((unsigned _BitInt(373)) 0) != 0
+ || !expr_has_type (__builtin_stdc_count_ones ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones (~(unsigned _BitInt(512)) 0) != 512
+ || __builtin_stdc_count_ones (~(unsigned _BitInt(373)) 0) != 373)
+ __builtin_abort ();
+ if (__builtin_stdc_count_ones (~(unsigned _BitInt(512)) 1315) != 512 - 5
+ || __builtin_stdc_count_ones (~(unsigned _BitInt(373)) 3363) != 373 - 6)
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit ((unsigned _BitInt(512)) 0)
+ || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned _BitInt(512)) 0), _Bool)
+ || __builtin_stdc_has_single_bit ((unsigned _BitInt(373)) 0)
+ || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned _BitInt(373)) 0), _Bool))
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit (~(unsigned _BitInt(512)) 0)
+ || __builtin_stdc_has_single_bit (~(unsigned _BitInt(373)) 0))
+ __builtin_abort ();
+ if (__builtin_stdc_has_single_bit (((unsigned _BitInt(512)) 1022) << 279)
+ || __builtin_stdc_has_single_bit (((unsigned _BitInt(373)) 12) << 305))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0), unsigned int)
+ || __builtin_stdc_bit_width ((unsigned _BitInt(373)) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(373)) 0), unsigned int))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width (~(unsigned _BitInt(512)) 0) != 512
+ || __builtin_stdc_bit_width (~(unsigned _BitInt(373)) 0) != 373)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_width (((unsigned _BitInt(512)) 1023) << 405) != 405 + 10
+ || __builtin_stdc_bit_width (((unsigned _BitInt(373)) 1024) << 242) != 242 + 11)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+ || __builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0) != 0
+ || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (~(unsigned _BitInt(512)) 0) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+ || __builtin_stdc_bit_floor (~(unsigned _BitInt(373)) 0) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (((unsigned _BitInt(512)) 511) << 405) != (((unsigned _BitInt(512)) 256) << 405)
+ || __builtin_stdc_bit_floor (((unsigned _BitInt(373)) 512) << 242) != (((unsigned _BitInt(512)) 512) << 242))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0) != 1
+ || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+ || __builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0) != 1
+ || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (~(unsigned _BitInt(512)) 0) != 0
+ || __builtin_stdc_bit_ceil (~(unsigned _BitInt(373)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 1) << (512 - 1)) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+ || __builtin_stdc_bit_ceil ((~(unsigned _BitInt(373)) 0) >> 1) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 512) << 405) != (((unsigned _BitInt(512)) 512) << 405)
+ || __builtin_stdc_bit_ceil (((unsigned _BitInt(373)) 513) << 242) != (((unsigned _BitInt(512)) 1024) << 242))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (~(unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_floor (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 511) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 256) << 405)
+ || __builtin_stdc_bit_floor (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 1)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (~(unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 0)
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1)) != ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1))
+ __builtin_abort ();
+ if (__builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405)
+ || __builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 513) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1024) << 405))
+ __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c b/gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c
new file mode 100644
index 0000000..1997753
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c
@@ -0,0 +1,150 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+ typedef int V __attribute__ ((vector_size (4 * sizeof (int))));
+ struct S { int s; };
+ enum E { E0, E1 };
+ __builtin_stdc_leading_zeros (0.0f); /* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+ __builtin_stdc_leading_zeros (0.0); /* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+ __builtin_stdc_leading_zeros (0.0L); /* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+ __builtin_stdc_leading_zeros ((V) {}); /* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+ __builtin_stdc_leading_zeros ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+ __builtin_stdc_leading_zeros (); /* { dg-error "wrong number of arguments to '__builtin_stdc_leading_zeros'" } */
+ __builtin_stdc_leading_zeros (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_leading_zeros'" } */
+ __builtin_stdc_leading_zeros ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+ __builtin_stdc_leading_zeros ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+ __builtin_stdc_leading_zeros (0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+ __builtin_stdc_leading_ones (0.0f); /* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+ __builtin_stdc_leading_ones (0.0); /* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+ __builtin_stdc_leading_ones (0.0L); /* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+ __builtin_stdc_leading_ones ((V) {}); /* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+ __builtin_stdc_leading_ones ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+ __builtin_stdc_leading_ones (); /* { dg-error "wrong number of arguments to '__builtin_stdc_leading_ones'" } */
+ __builtin_stdc_leading_ones (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_leading_ones'" } */
+ __builtin_stdc_leading_ones ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+ __builtin_stdc_leading_ones ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+ __builtin_stdc_leading_ones (0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+ __builtin_stdc_trailing_zeros (0.0f); /* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+ __builtin_stdc_trailing_zeros (0.0); /* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+ __builtin_stdc_trailing_zeros (0.0L); /* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+ __builtin_stdc_trailing_zeros ((V) {}); /* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+ __builtin_stdc_trailing_zeros ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+ __builtin_stdc_trailing_zeros (); /* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_zeros'" } */
+ __builtin_stdc_trailing_zeros (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_zeros'" } */
+ __builtin_stdc_trailing_zeros ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+ __builtin_stdc_trailing_zeros ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+ __builtin_stdc_trailing_zeros (0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+ __builtin_stdc_trailing_ones (0.0f); /* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+ __builtin_stdc_trailing_ones (0.0); /* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+ __builtin_stdc_trailing_ones (0.0L); /* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+ __builtin_stdc_trailing_ones ((V) {}); /* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+ __builtin_stdc_trailing_ones ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+ __builtin_stdc_trailing_ones (); /* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_ones'" } */
+ __builtin_stdc_trailing_ones (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_ones'" } */
+ __builtin_stdc_trailing_ones ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+ __builtin_stdc_trailing_ones ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+ __builtin_stdc_trailing_ones (0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+ __builtin_stdc_first_leading_zero (0.0f); /* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+ __builtin_stdc_first_leading_zero (0.0); /* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+ __builtin_stdc_first_leading_zero (0.0L); /* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+ __builtin_stdc_first_leading_zero ((V) {}); /* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+ __builtin_stdc_first_leading_zero ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+ __builtin_stdc_first_leading_zero (); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_zero'" } */
+ __builtin_stdc_first_leading_zero (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_zero'" } */
+ __builtin_stdc_first_leading_zero ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+ __builtin_stdc_first_leading_zero ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+ __builtin_stdc_first_leading_zero (0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+ __builtin_stdc_first_leading_one (0.0f); /* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+ __builtin_stdc_first_leading_one (0.0); /* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+ __builtin_stdc_first_leading_one (0.0L); /* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+ __builtin_stdc_first_leading_one ((V) {}); /* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+ __builtin_stdc_first_leading_one ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+ __builtin_stdc_first_leading_one (); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_one'" } */
+ __builtin_stdc_first_leading_one (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_one'" } */
+ __builtin_stdc_first_leading_one ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+ __builtin_stdc_first_leading_one ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+ __builtin_stdc_first_leading_one (0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+ __builtin_stdc_first_trailing_zero (0.0f); /* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+ __builtin_stdc_first_trailing_zero (0.0); /* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+ __builtin_stdc_first_trailing_zero (0.0L); /* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+ __builtin_stdc_first_trailing_zero ((V) {}); /* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+ __builtin_stdc_first_trailing_zero ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+ __builtin_stdc_first_trailing_zero (); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_zero'" } */
+ __builtin_stdc_first_trailing_zero (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_zero'" } */
+ __builtin_stdc_first_trailing_zero ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+ __builtin_stdc_first_trailing_zero ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+ __builtin_stdc_first_trailing_zero (0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+ __builtin_stdc_first_trailing_one (0.0f); /* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+ __builtin_stdc_first_trailing_one (0.0); /* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+ __builtin_stdc_first_trailing_one (0.0L); /* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+ __builtin_stdc_first_trailing_one ((V) {}); /* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+ __builtin_stdc_first_trailing_one ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+ __builtin_stdc_first_trailing_one (); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_one'" } */
+ __builtin_stdc_first_trailing_one (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_one'" } */
+ __builtin_stdc_first_trailing_one ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+ __builtin_stdc_first_trailing_one ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+ __builtin_stdc_first_trailing_one (0); /* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+ __builtin_stdc_count_zeros (0.0f); /* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+ __builtin_stdc_count_zeros (0.0); /* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+ __builtin_stdc_count_zeros (0.0L); /* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+ __builtin_stdc_count_zeros ((V) {}); /* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+ __builtin_stdc_count_zeros ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+ __builtin_stdc_count_zeros (); /* { dg-error "wrong number of arguments to '__builtin_stdc_count_zeros'" } */
+ __builtin_stdc_count_zeros (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_count_zeros'" } */
+ __builtin_stdc_count_zeros ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+ __builtin_stdc_count_zeros ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+ __builtin_stdc_count_zeros (0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+ __builtin_stdc_count_ones (0.0f); /* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+ __builtin_stdc_count_ones (0.0); /* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+ __builtin_stdc_count_ones (0.0L); /* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+ __builtin_stdc_count_ones ((V) {}); /* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+ __builtin_stdc_count_ones ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+ __builtin_stdc_count_ones (); /* { dg-error "wrong number of arguments to '__builtin_stdc_count_ones'" } */
+ __builtin_stdc_count_ones (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_count_ones'" } */
+ __builtin_stdc_count_ones ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+ __builtin_stdc_count_ones ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+ __builtin_stdc_count_ones (0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+ __builtin_stdc_has_single_bit (0.0f); /* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+ __builtin_stdc_has_single_bit (0.0); /* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+ __builtin_stdc_has_single_bit (0.0L); /* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+ __builtin_stdc_has_single_bit ((V) {}); /* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+ __builtin_stdc_has_single_bit ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+ __builtin_stdc_has_single_bit (); /* { dg-error "wrong number of arguments to '__builtin_stdc_has_single_bit'" } */
+ __builtin_stdc_has_single_bit (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_has_single_bit'" } */
+ __builtin_stdc_has_single_bit ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+ __builtin_stdc_has_single_bit ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+ __builtin_stdc_has_single_bit (0); /* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+ __builtin_stdc_bit_width (0.0f); /* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+ __builtin_stdc_bit_width (0.0); /* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+ __builtin_stdc_bit_width (0.0L); /* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+ __builtin_stdc_bit_width ((V) {}); /* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+ __builtin_stdc_bit_width ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+ __builtin_stdc_bit_width (); /* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+ __builtin_stdc_bit_width (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+ __builtin_stdc_bit_width ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+ __builtin_stdc_bit_width ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+ __builtin_stdc_bit_width (0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+ __builtin_stdc_bit_floor (0.0f); /* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+ __builtin_stdc_bit_floor (0.0); /* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+ __builtin_stdc_bit_floor (0.0L); /* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+ __builtin_stdc_bit_floor ((V) {}); /* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+ __builtin_stdc_bit_floor ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+ __builtin_stdc_bit_floor (); /* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+ __builtin_stdc_bit_floor (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+ __builtin_stdc_bit_floor ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+ __builtin_stdc_bit_floor ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+ __builtin_stdc_bit_floor (0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+ __builtin_stdc_bit_ceil (0.0f); /* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+ __builtin_stdc_bit_ceil (0.0); /* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+ __builtin_stdc_bit_ceil (0.0L); /* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+ __builtin_stdc_bit_ceil ((V) {}); /* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+ __builtin_stdc_bit_ceil ((struct S) { 0 }); /* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+ __builtin_stdc_bit_ceil (); /* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+ __builtin_stdc_bit_ceil (0U, 0U); /* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+ __builtin_stdc_bit_ceil ((_Bool) 0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+ __builtin_stdc_bit_ceil ((enum E) E0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+ __builtin_stdc_bit_ceil (0); /* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/has-feature.c b/gcc/testsuite/gcc.dg/has-feature.c
new file mode 100644
index 0000000..2fd0b4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/has-feature.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* Test __has_{feature,extension} for C language features. */
+
+#if !__has_extension (c_alignas) || !__has_extension (c_alignof)
+#error
+#endif
+
+#if !__has_extension (c_atomic) || !__has_extension (c_generic_selections)
+#error
+#endif
+
+#if !__has_extension (c_static_assert) || !__has_extension (c_thread_local)
+#error
+#endif
+
+#if !__has_extension (cxx_binary_literals)
+#error
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+/* Have C11 features. */
+#if !__has_feature (c_alignas) || !__has_feature (c_alignof)
+#error
+#endif
+
+#if !__has_feature (c_atomic) || !__has_feature (c_generic_selections)
+#error
+#endif
+
+#if !__has_feature (c_static_assert) || !__has_feature (c_thread_local)
+#error
+#endif
+
+#else
+/* Don't have C11 features. */
+#if __has_feature (c_alignas) || __has_feature (c_alignof)
+#error
+#endif
+
+#if __has_feature (c_atomic) || __has_feature (c_generic_selections)
+#error
+#endif
+
+#if __has_feature (c_static_assert) || __has_feature (c_thread_local)
+#error
+#endif
+
+#endif
+
+#if __STDC_VERSION__ >= 202000L
+/* Have C2x features. */
+#if !__has_feature (cxx_binary_literals)
+#error
+#endif
+
+#else
+/* Don't have C2x features. */
+#if __has_feature (cxx_binary_literals)
+#error
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c b/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c
index 4032ad1..155a682 100644
--- a/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -fopt-info-inline-optimized-missed" } */
+/* { dg-options "-O3 -fopt-info-inline-optimized-missed -fno-ipa-vrp" } */
static int foo (int a)
{
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c
index fad0891..cbda685 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf-optimized-all" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized-all -fno-ipa-vrp" } */
static int zip();
static int zap();
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c
index 57c5262..a8824d0 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c
@@ -1,6 +1,6 @@
/* { dg-do link } */
/* { dg-require-alias "" } */
-/* { dg-options "-O2 -fdump-ipa-icf-optimized -flto -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized -flto -fdump-tree-optimized -fno-ipa-vrp" } */
/* { dg-require-effective-target lto } */
/* { dg-additional-sources "ipa-icf-38a.c" }*/
diff --git a/gcc/testsuite/gcc.dg/ipa/pure-const-1.c b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c
index dd58457..10b5727 100644
--- a/gcc/testsuite/gcc.dg/ipa/pure-const-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { nonpic || pie_enabled } } } */
-/* { dg-options "-O3 -fdump-tree-local-pure-const1 -fdump-ipa-pure-const -fdump-tree-optimized -fno-early-inlining -fgnu89-inline" } */
+/* { dg-options "-O3 -fno-ipa-vrp -fdump-tree-local-pure-const1 -fdump-ipa-pure-const -fdump-tree-optimized -fno-early-inlining -fgnu89-inline" } */
void abort (void);
int error_code;
static int val;
diff --git a/gcc/testsuite/gcc.dg/ipa/remref-0.c b/gcc/testsuite/gcc.dg/ipa/remref-0.c
index 6073c02..497136e 100644
--- a/gcc/testsuite/gcc.dg/ipa/remref-0.c
+++ b/gcc/testsuite/gcc.dg/ipa/remref-0.c
@@ -3,7 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fno-early-inlining -fno-ipa-sra -fno-ipa-cp -fdump-ipa-inline -fdump-tree-optimized" } */
-extern int __attribute__ ((noinline, noclone, used))
+extern int __attribute__ ((noinline, noclone, used, noipa))
stuff (int i)
{
return 0;
diff --git a/gcc/testsuite/gcc.dg/nonnull-7.c b/gcc/testsuite/gcc.dg/nonnull-7.c
new file mode 100644
index 0000000..d66a609
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/nonnull-7.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target nonpic } }
+ { dg-options "-O2 -Wsuggest-attribute=returns_nonnull" } */
+
+int *q;
+int *test() /* { dg-warning "candidate for attribute .returns_nonnull." } */
+{
+ if (!q)
+ __builtin_unreachable ();
+ return q;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/pr112319.c b/gcc/testsuite/gcc.dg/pch/pr112319.c
new file mode 100644
index 0000000..0438814
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/pr112319.c
@@ -0,0 +1,5 @@
+/* { dg-additional-options "-Wpragmas -save-temps" } */
+#include "pr112319.h"
+#pragma GCC diagnostic error "-Wpragmas"
+#pragma GCC diagnostic ignored "oops" /* { dg-error "oops" } */
+/* { dg-regexp {[^[:space:]]*: some warnings being treated as errors} } */
diff --git a/gcc/testsuite/gcc.dg/pch/pr112319.hs b/gcc/testsuite/gcc.dg/pch/pr112319.hs
new file mode 100644
index 0000000..3b6178b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/pr112319.hs
@@ -0,0 +1 @@
+/* This space intentionally left blank. */
diff --git a/gcc/testsuite/gcc.dg/pr109977.c b/gcc/testsuite/gcc.dg/pr109977.c
new file mode 100644
index 0000000..03d9a33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr109977.c
@@ -0,0 +1,16 @@
+/* PR target/109977 */
+/* { dg-do compile } */
+/* { dg-options "-Og" } */
+
+typedef double __attribute__((__vector_size__ (8))) V;
+typedef double __attribute__((__vector_size__ (16))) W;
+V v;
+int i;
+extern void bar (void *);
+
+void
+foo (void)
+{
+ W w = __builtin_shufflevector (v, (W) { }, 0, 0);
+ bar (&w);
+}
diff --git a/gcc/testsuite/gcc.dg/pr110279-1.c b/gcc/testsuite/gcc.dg/pr110279-1.c
new file mode 100644
index 0000000..f25b6ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110279-1.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast --param avoid-fma-max-bits=512 --param tree-reassoc-width=4 -fdump-tree-widening_mul-details" } */
+/* { dg-additional-options "-march=armv8.2-a" { target aarch64-*-* } } */
+
+#define LOOP_COUNT 800000000
+typedef double data_e;
+
+/* Check that FMAs with backedge dependency are avoided. Otherwise there won't
+ be FMA generated with "--param avoid-fma-max-bits=512". */
+
+data_e
+foo1 (data_e a, data_e b, data_e c, data_e d)
+{
+ data_e result = 0;
+
+ for (int ic = 0; ic < LOOP_COUNT; ic++)
+ {
+ result += (a * b + c * d);
+
+ a -= 0.1;
+ b += 0.9;
+ c *= 1.02;
+ d *= 0.61;
+ }
+
+ return result;
+}
+
+data_e
+foo2 (data_e a, data_e b, data_e c, data_e d)
+{
+ data_e result = 0;
+
+ for (int ic = 0; ic < LOOP_COUNT; ic++)
+ {
+ result = a * b + result + c * d;
+
+ a -= 0.1;
+ b += 0.9;
+ c *= 1.02;
+ d *= 0.61;
+ }
+
+ return result;
+}
+
+data_e
+foo3 (data_e a, data_e b, data_e c, data_e d)
+{
+ data_e result = 0;
+
+ for (int ic = 0; ic < LOOP_COUNT; ic++)
+ {
+ result = result + a * b + c * d;
+
+ a -= 0.1;
+ b += 0.9;
+ c *= 1.02;
+ d *= 0.61;
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-tree-dump-times "Generated FMA" 3 "widening_mul"} } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/pr112618.c b/gcc/testsuite/gcc.dg/pr112618.c
new file mode 100644
index 0000000..897e6a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112618.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int m, *p;
+
+__attribute__ ((simd)) int
+bar (int x)
+{
+ if (x)
+ {
+ if (m < 1)
+ for (m = 0; m < 1; ++m)
+ ++x;
+ p = &x;
+ for (;;)
+ ++m;
+ }
+ return 0;
+}
+
+__attribute__ ((simd)) int
+foo (int x)
+{
+ bar (x);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr112622.c b/gcc/testsuite/gcc.dg/pr112622.c
new file mode 100644
index 0000000..c73587c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112622.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+
+typedef __attribute__((__vector_size__(4))) float V;
+
+V v = (float)-v; /* { dg-error "vector value used" } */
diff --git a/gcc/testsuite/gcc.dg/pr112673.c b/gcc/testsuite/gcc.dg/pr112673.c
new file mode 100644
index 0000000..531f277
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112673.c
@@ -0,0 +1,10 @@
+/* PR tree-optimization/112673 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-O3" } */
+/* { dg-additional-options "-mavx2" { target i?86-*-* x86_64-*-* } } */
+
+int
+foo (_BitInt(256) x)
+{
+ return __builtin_ctzg ((unsigned _BitInt(512)) x);
+}
diff --git a/gcc/testsuite/gcc.dg/simd-2.c b/gcc/testsuite/gcc.dg/simd-2.c
index d24e076..411bb49 100644
--- a/gcc/testsuite/gcc.dg/simd-2.c
+++ b/gcc/testsuite/gcc.dg/simd-2.c
@@ -33,10 +33,10 @@ hanneke ()
foo = a; /* { dg-error "incompatible types when assigning" } */
/* Casted assignment between scalar and SIMD of same size. */
- foo = (typeof (foo)) foo2; /* { dg-error "aggregate value used where a floating-point was expected" } */
+ foo = (typeof (foo)) foo2; /* { dg-error "vector value used where a floating-point was expected" } */
/* Casted assignment between scalar and SIMD of different size. */
- foo1 = (typeof (foo1)) foo2; /* { dg-error "aggregate value used where a floating-point was expected" } */
+ foo1 = (typeof (foo1)) foo2; /* { dg-error "vector value used where a floating-point was expected" } */
/* Operators on compatible SIMD types. */
a += b + b;
diff --git a/gcc/testsuite/gcc.dg/torture/addieq.c b/gcc/testsuite/gcc.dg/torture/addieq.c
new file mode 100644
index 0000000..5fea38e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addieq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addieq (-1, -1, 12, 23) != 35)
+ return 1;
+ if (addieq (-1, 3, 12, 23) != 12)
+ return 1;
+ if (addieq (1, 3, 12, 23) != 12)
+ return 1;
+ if (addieq (3, 3, 12, 23) != 35)
+ return 1;
+ if (addieq (5, 3, 12, 23) != 12)
+ return 1;
+ if (addieq (3, -1, 12, 23) != 12)
+ return 1;
+ if (addieq (3, 1, 12, 23) != 12)
+ return 1;
+ if (addieq (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addifeq.c b/gcc/testsuite/gcc.dg/torture/addifeq.c
new file mode 100644
index 0000000..b3d9973
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addifeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addifeq (-1.0, -1.0, 12, 23) != 35)
+ return 1;
+ if (addifeq (-1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifeq (1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifeq (3.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifeq (5.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifeq (3.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (addifeq (3.0, 1.0, 12, 23) != 12)
+ return 1;
+ if (addifeq (3.0, 5.0, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addifge.c b/gcc/testsuite/gcc.dg/torture/addifge.c
new file mode 100644
index 0000000..b719a3d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addifge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addifge (-1.0, -1.0, 12, 23) != 35)
+ return 1;
+ if (addifge (-1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifge (1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifge (3.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifge (5.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifge (3.0, -1.0, 12, 23) != 35)
+ return 1;
+ if (addifge (3.0, 1.0, 12, 23) != 35)
+ return 1;
+ if (addifge (3.0, 5.0, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addifgt.c b/gcc/testsuite/gcc.dg/torture/addifgt.c
new file mode 100644
index 0000000..5ad591a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addifgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addifgt (-1.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (addifgt (-1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifgt (1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifgt (3.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifgt (5.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifgt (3.0, -1.0, 12, 23) != 35)
+ return 1;
+ if (addifgt (3.0, 1.0, 12, 23) != 35)
+ return 1;
+ if (addifgt (3.0, 5.0, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addifle.c b/gcc/testsuite/gcc.dg/torture/addifle.c
new file mode 100644
index 0000000..7353f40
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addifle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addifle (-1.0, -1.0, 12, 23) != 35)
+ return 1;
+ if (addifle (-1.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifle (1.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifle (3.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifle (5.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifle (3.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (addifle (3.0, 1.0, 12, 23) != 12)
+ return 1;
+ if (addifle (3.0, 5.0, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addiflt.c b/gcc/testsuite/gcc.dg/torture/addiflt.c
new file mode 100644
index 0000000..0bdd6d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addiflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addiflt (-1.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (addiflt (-1.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addiflt (1.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addiflt (3.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addiflt (5.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addiflt (3.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (addiflt (3.0, 1.0, 12, 23) != 12)
+ return 1;
+ if (addiflt (3.0, 5.0, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addifne.c b/gcc/testsuite/gcc.dg/torture/addifne.c
new file mode 100644
index 0000000..3e53709
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addifne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addifne (-1.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (addifne (-1.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifne (1.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifne (3.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (addifne (5.0, 3.0, 12, 23) != 35)
+ return 1;
+ if (addifne (3.0, -1.0, 12, 23) != 35)
+ return 1;
+ if (addifne (3.0, 1.0, 12, 23) != 35)
+ return 1;
+ if (addifne (3.0, 5.0, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addige.c b/gcc/testsuite/gcc.dg/torture/addige.c
new file mode 100644
index 0000000..79b4528
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addige.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addige (-1, -1, 12, 23) != 35)
+ return 1;
+ if (addige (-1, 3, 12, 23) != 12)
+ return 1;
+ if (addige (1, 3, 12, 23) != 12)
+ return 1;
+ if (addige (3, 3, 12, 23) != 35)
+ return 1;
+ if (addige (5, 3, 12, 23) != 35)
+ return 1;
+ if (addige (3, -1, 12, 23) != 35)
+ return 1;
+ if (addige (3, 1, 12, 23) != 35)
+ return 1;
+ if (addige (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addigeu.c b/gcc/testsuite/gcc.dg/torture/addigeu.c
new file mode 100644
index 0000000..59bb615
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addigeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addigeu (-1, -1, 12, 23) != 35)
+ return 1;
+ if (addigeu (-1, 3, 12, 23) != 35)
+ return 1;
+ if (addigeu (1, 3, 12, 23) != 12)
+ return 1;
+ if (addigeu (3, 3, 12, 23) != 35)
+ return 1;
+ if (addigeu (5, 3, 12, 23) != 35)
+ return 1;
+ if (addigeu (3, -1, 12, 23) != 12)
+ return 1;
+ if (addigeu (3, 1, 12, 23) != 35)
+ return 1;
+ if (addigeu (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addigt.c b/gcc/testsuite/gcc.dg/torture/addigt.c
new file mode 100644
index 0000000..8c90e5f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addigt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addigt (-1, -1, 12, 23) != 12)
+ return 1;
+ if (addigt (-1, 3, 12, 23) != 12)
+ return 1;
+ if (addigt (1, 3, 12, 23) != 12)
+ return 1;
+ if (addigt (3, 3, 12, 23) != 12)
+ return 1;
+ if (addigt (5, 3, 12, 23) != 35)
+ return 1;
+ if (addigt (3, -1, 12, 23) != 35)
+ return 1;
+ if (addigt (3, 1, 12, 23) != 35)
+ return 1;
+ if (addigt (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addigtu.c b/gcc/testsuite/gcc.dg/torture/addigtu.c
new file mode 100644
index 0000000..1837ad6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addigtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addigtu (-1, -1, 12, 23) != 12)
+ return 1;
+ if (addigtu (-1, 3, 12, 23) != 35)
+ return 1;
+ if (addigtu (1, 3, 12, 23) != 12)
+ return 1;
+ if (addigtu (3, 3, 12, 23) != 12)
+ return 1;
+ if (addigtu (5, 3, 12, 23) != 35)
+ return 1;
+ if (addigtu (3, -1, 12, 23) != 12)
+ return 1;
+ if (addigtu (3, 1, 12, 23) != 35)
+ return 1;
+ if (addigtu (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addile.c b/gcc/testsuite/gcc.dg/torture/addile.c
new file mode 100644
index 0000000..9e436b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addile.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addile (-1, -1, 12, 23) != 35)
+ return 1;
+ if (addile (-1, 3, 12, 23) != 35)
+ return 1;
+ if (addile (1, 3, 12, 23) != 35)
+ return 1;
+ if (addile (3, 3, 12, 23) != 35)
+ return 1;
+ if (addile (5, 3, 12, 23) != 12)
+ return 1;
+ if (addile (3, -1, 12, 23) != 12)
+ return 1;
+ if (addile (3, 1, 12, 23) != 12)
+ return 1;
+ if (addile (3, 5, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addileu.c b/gcc/testsuite/gcc.dg/torture/addileu.c
new file mode 100644
index 0000000..a70bacb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addileu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addileu (-1, -1, 12, 23) != 35)
+ return 1;
+ if (addileu (-1, 3, 12, 23) != 12)
+ return 1;
+ if (addileu (1, 3, 12, 23) != 35)
+ return 1;
+ if (addileu (3, 3, 12, 23) != 35)
+ return 1;
+ if (addileu (5, 3, 12, 23) != 12)
+ return 1;
+ if (addileu (3, -1, 12, 23) != 35)
+ return 1;
+ if (addileu (3, 1, 12, 23) != 12)
+ return 1;
+ if (addileu (3, 5, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addilt.c b/gcc/testsuite/gcc.dg/torture/addilt.c
new file mode 100644
index 0000000..1573915
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addilt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addilt (-1, -1, 12, 23) != 12)
+ return 1;
+ if (addilt (-1, 3, 12, 23) != 35)
+ return 1;
+ if (addilt (1, 3, 12, 23) != 35)
+ return 1;
+ if (addilt (3, 3, 12, 23) != 12)
+ return 1;
+ if (addilt (5, 3, 12, 23) != 12)
+ return 1;
+ if (addilt (3, -1, 12, 23) != 12)
+ return 1;
+ if (addilt (3, 1, 12, 23) != 12)
+ return 1;
+ if (addilt (3, 5, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addiltu.c b/gcc/testsuite/gcc.dg/torture/addiltu.c
new file mode 100644
index 0000000..3db7065
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addiltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addiltu (-1, -1, 12, 23) != 12)
+ return 1;
+ if (addiltu (-1, 3, 12, 23) != 12)
+ return 1;
+ if (addiltu (1, 3, 12, 23) != 35)
+ return 1;
+ if (addiltu (3, 3, 12, 23) != 12)
+ return 1;
+ if (addiltu (5, 3, 12, 23) != 12)
+ return 1;
+ if (addiltu (3, -1, 12, 23) != 35)
+ return 1;
+ if (addiltu (3, 1, 12, 23) != 12)
+ return 1;
+ if (addiltu (3, 5, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addine.c b/gcc/testsuite/gcc.dg/torture/addine.c
new file mode 100644
index 0000000..505d815
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addine.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addine (-1, -1, 12, 23) != 12)
+ return 1;
+ if (addine (-1, 3, 12, 23) != 35)
+ return 1;
+ if (addine (1, 3, 12, 23) != 35)
+ return 1;
+ if (addine (3, 3, 12, 23) != 12)
+ return 1;
+ if (addine (5, 3, 12, 23) != 35)
+ return 1;
+ if (addine (3, -1, 12, 23) != 35)
+ return 1;
+ if (addine (3, 1, 12, 23) != 35)
+ return 1;
+ if (addine (3, 5, 12, 23) != 35)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addleq.c b/gcc/testsuite/gcc.dg/torture/addleq.c
new file mode 100644
index 0000000..02ac6d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addleq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addleq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addleq (-1L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addleq (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addleq (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addleq (3L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addleq (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addleq (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addleq (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (addleq (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlfeq.c b/gcc/testsuite/gcc.dg/torture/addlfeq.c
new file mode 100644
index 0000000..ca95f78
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlfeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlfeq (-1.0, -1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfeq (-1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfeq (1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfeq (3.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfeq (5.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfeq (3.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfeq (3.0, 1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfeq (3.0, 5.0, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlfge.c b/gcc/testsuite/gcc.dg/torture/addlfge.c
new file mode 100644
index 0000000..b63de69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlfge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlfge (-1.0, -1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfge (-1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfge (1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfge (3.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfge (5.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfge (3.0, -1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfge (3.0, 1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfge (3.0, 5.0, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlfgt.c b/gcc/testsuite/gcc.dg/torture/addlfgt.c
new file mode 100644
index 0000000..1077cc0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlfgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlfgt (-1.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfgt (-1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfgt (1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfgt (3.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfgt (5.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfgt (3.0, -1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfgt (3.0, 1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfgt (3.0, 5.0, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlfle.c b/gcc/testsuite/gcc.dg/torture/addlfle.c
new file mode 100644
index 0000000..0fd8128
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlfle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlfle (-1.0, -1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfle (-1.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfle (1.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfle (3.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfle (5.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfle (3.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfle (3.0, 1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfle (3.0, 5.0, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlflt.c b/gcc/testsuite/gcc.dg/torture/addlflt.c
new file mode 100644
index 0000000..cc4cb45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlflt (-1.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlflt (-1.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlflt (1.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlflt (3.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlflt (5.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlflt (3.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlflt (3.0, 1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlflt (3.0, 5.0, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlfne.c b/gcc/testsuite/gcc.dg/torture/addlfne.c
new file mode 100644
index 0000000..f8018dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlfne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlfne (-1.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfne (-1.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfne (1.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfne (3.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (addlfne (5.0, 3.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfne (3.0, -1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfne (3.0, 1.0, 12L, 23L) != 35L)
+ return 1;
+ if (addlfne (3.0, 5.0, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlge.c b/gcc/testsuite/gcc.dg/torture/addlge.c
new file mode 100644
index 0000000..f23773e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlge (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlge (-1L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlge (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlge (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlge (3L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlge (5L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlge (3L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlge (3L, 1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlge (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlgeu.c b/gcc/testsuite/gcc.dg/torture/addlgeu.c
new file mode 100644
index 0000000..254bb57
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlgeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlgeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlgeu (-1L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgeu (-1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgeu (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgeu (3L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgeu (5L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgeu (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgeu (3L, 1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgeu (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlgt.c b/gcc/testsuite/gcc.dg/torture/addlgt.c
new file mode 100644
index 0000000..0bd0fe1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlgt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlgt (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgt (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgt (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgt (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgt (5L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgt (3L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgt (3L, 1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgt (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlgtu.c b/gcc/testsuite/gcc.dg/torture/addlgtu.c
new file mode 100644
index 0000000..20e7e02
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlgtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlgtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlgtu (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgtu (-1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgtu (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgtu (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgtu (5L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgtu (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlgtu (3L, 1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlgtu (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlle.c b/gcc/testsuite/gcc.dg/torture/addlle.c
new file mode 100644
index 0000000..108e072
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlle (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlle (-1L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlle (-1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlle (1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlle (3L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlle (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlle (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlle (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlle (3L, 5L, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlleu.c b/gcc/testsuite/gcc.dg/torture/addlleu.c
new file mode 100644
index 0000000..b7542cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlleu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlleu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlleu (-1L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlleu (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlleu (1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlleu (3L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlleu (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlleu (3L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlleu (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlleu (3L, 5L, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addllt.c b/gcc/testsuite/gcc.dg/torture/addllt.c
new file mode 100644
index 0000000..b76ef8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addllt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addllt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addllt (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addllt (-1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addllt (1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addllt (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addllt (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addllt (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addllt (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (addllt (3L, 5L, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlltu.c b/gcc/testsuite/gcc.dg/torture/addlltu.c
new file mode 100644
index 0000000..e4c1ad7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlltu (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlltu (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlltu (1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlltu (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlltu (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlltu (3L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlltu (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlltu (3L, 5L, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/addlne.c b/gcc/testsuite/gcc.dg/torture/addlne.c
new file mode 100644
index 0000000..9be07ab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/addlne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlne (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+ if (addlne (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (addlne (-1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlne (1L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlne (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (addlne (5L, 3L, 12L, 23L) != 35L)
+ return 1;
+ if (addlne (3L, -1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlne (3L, 1L, 12L, 23L) != 35L)
+ return 1;
+ if (addlne (3L, 5L, 12L, 23L) != 35L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movieq.c b/gcc/testsuite/gcc.dg/torture/movieq.c
new file mode 100644
index 0000000..966dd5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movieq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movieq (-1, -1, 12, 23) != 12)
+ return 1;
+ if (movieq (-1, 3, 12, 23) != 23)
+ return 1;
+ if (movieq (1, 3, 12, 23) != 23)
+ return 1;
+ if (movieq (3, 3, 12, 23) != 12)
+ return 1;
+ if (movieq (5, 3, 12, 23) != 23)
+ return 1;
+ if (movieq (3, -1, 12, 23) != 23)
+ return 1;
+ if (movieq (3, 1, 12, 23) != 23)
+ return 1;
+ if (movieq (3, 5, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movifeq.c b/gcc/testsuite/gcc.dg/torture/movifeq.c
new file mode 100644
index 0000000..7f143e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movifeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movifeq (-1.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (movifeq (-1.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifeq (1.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifeq (3.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifeq (5.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifeq (3.0, -1.0, 12, 23) != 23)
+ return 1;
+ if (movifeq (3.0, 1.0, 12, 23) != 23)
+ return 1;
+ if (movifeq (3.0, 5.0, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movifge.c b/gcc/testsuite/gcc.dg/torture/movifge.c
new file mode 100644
index 0000000..af19043
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movifge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movifge (-1.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (movifge (-1.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifge (1.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifge (3.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifge (5.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifge (3.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (movifge (3.0, 1.0, 12, 23) != 12)
+ return 1;
+ if (movifge (3.0, 5.0, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movifgt.c b/gcc/testsuite/gcc.dg/torture/movifgt.c
new file mode 100644
index 0000000..bf8563f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movifgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movifgt (-1.0, -1.0, 12, 23) != 23)
+ return 1;
+ if (movifgt (-1.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifgt (1.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifgt (3.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifgt (5.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifgt (3.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (movifgt (3.0, 1.0, 12, 23) != 12)
+ return 1;
+ if (movifgt (3.0, 5.0, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movifle.c b/gcc/testsuite/gcc.dg/torture/movifle.c
new file mode 100644
index 0000000..c925804
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movifle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movifle (-1.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (movifle (-1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifle (1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifle (3.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifle (5.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifle (3.0, -1.0, 12, 23) != 23)
+ return 1;
+ if (movifle (3.0, 1.0, 12, 23) != 23)
+ return 1;
+ if (movifle (3.0, 5.0, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/moviflt.c b/gcc/testsuite/gcc.dg/torture/moviflt.c
new file mode 100644
index 0000000..25f3ad4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/moviflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+moviflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+int
+main (void)
+{
+ if (moviflt (-1.0, -1.0, 12, 23) != 23)
+ return 1;
+ if (moviflt (-1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (moviflt (1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (moviflt (3.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (moviflt (5.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (moviflt (3.0, -1.0, 12, 23) != 23)
+ return 1;
+ if (moviflt (3.0, 1.0, 12, 23) != 23)
+ return 1;
+ if (moviflt (3.0, 5.0, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movifne.c b/gcc/testsuite/gcc.dg/torture/movifne.c
new file mode 100644
index 0000000..6e76df3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movifne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movifne (-1.0, -1.0, 12, 23) != 23)
+ return 1;
+ if (movifne (-1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifne (1.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifne (3.0, 3.0, 12, 23) != 23)
+ return 1;
+ if (movifne (5.0, 3.0, 12, 23) != 12)
+ return 1;
+ if (movifne (3.0, -1.0, 12, 23) != 12)
+ return 1;
+ if (movifne (3.0, 1.0, 12, 23) != 12)
+ return 1;
+ if (movifne (3.0, 5.0, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movige.c b/gcc/testsuite/gcc.dg/torture/movige.c
new file mode 100644
index 0000000..b4149b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movige.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movige (-1, -1, 12, 23) != 12)
+ return 1;
+ if (movige (-1, 3, 12, 23) != 23)
+ return 1;
+ if (movige (1, 3, 12, 23) != 23)
+ return 1;
+ if (movige (3, 3, 12, 23) != 12)
+ return 1;
+ if (movige (5, 3, 12, 23) != 12)
+ return 1;
+ if (movige (3, -1, 12, 23) != 12)
+ return 1;
+ if (movige (3, 1, 12, 23) != 12)
+ return 1;
+ if (movige (3, 5, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movigeu.c b/gcc/testsuite/gcc.dg/torture/movigeu.c
new file mode 100644
index 0000000..14df122
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movigeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+movigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movigeu (-1, -1, 12, 23) != 12)
+ return 1;
+ if (movigeu (-1, 3, 12, 23) != 12)
+ return 1;
+ if (movigeu (1, 3, 12, 23) != 23)
+ return 1;
+ if (movigeu (3, 3, 12, 23) != 12)
+ return 1;
+ if (movigeu (5, 3, 12, 23) != 12)
+ return 1;
+ if (movigeu (3, -1, 12, 23) != 23)
+ return 1;
+ if (movigeu (3, 1, 12, 23) != 12)
+ return 1;
+ if (movigeu (3, 5, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movigt.c b/gcc/testsuite/gcc.dg/torture/movigt.c
new file mode 100644
index 0000000..9684013
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movigt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movigt (-1, -1, 12, 23) != 23)
+ return 1;
+ if (movigt (-1, 3, 12, 23) != 23)
+ return 1;
+ if (movigt (1, 3, 12, 23) != 23)
+ return 1;
+ if (movigt (3, 3, 12, 23) != 23)
+ return 1;
+ if (movigt (5, 3, 12, 23) != 12)
+ return 1;
+ if (movigt (3, -1, 12, 23) != 12)
+ return 1;
+ if (movigt (3, 1, 12, 23) != 12)
+ return 1;
+ if (movigt (3, 5, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movigtu.c b/gcc/testsuite/gcc.dg/torture/movigtu.c
new file mode 100644
index 0000000..d620e8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movigtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+movigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movigtu (-1, -1, 12, 23) != 23)
+ return 1;
+ if (movigtu (-1, 3, 12, 23) != 12)
+ return 1;
+ if (movigtu (1, 3, 12, 23) != 23)
+ return 1;
+ if (movigtu (3, 3, 12, 23) != 23)
+ return 1;
+ if (movigtu (5, 3, 12, 23) != 12)
+ return 1;
+ if (movigtu (3, -1, 12, 23) != 23)
+ return 1;
+ if (movigtu (3, 1, 12, 23) != 12)
+ return 1;
+ if (movigtu (3, 5, 12, 23) != 23)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movile.c b/gcc/testsuite/gcc.dg/torture/movile.c
new file mode 100644
index 0000000..c637d4f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movile.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movile (-1, -1, 12, 23) != 12)
+ return 1;
+ if (movile (-1, 3, 12, 23) != 12)
+ return 1;
+ if (movile (1, 3, 12, 23) != 12)
+ return 1;
+ if (movile (3, 3, 12, 23) != 12)
+ return 1;
+ if (movile (5, 3, 12, 23) != 23)
+ return 1;
+ if (movile (3, -1, 12, 23) != 23)
+ return 1;
+ if (movile (3, 1, 12, 23) != 23)
+ return 1;
+ if (movile (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movileu.c b/gcc/testsuite/gcc.dg/torture/movileu.c
new file mode 100644
index 0000000..ead6555
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movileu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+movileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movileu (-1, -1, 12, 23) != 12)
+ return 1;
+ if (movileu (-1, 3, 12, 23) != 23)
+ return 1;
+ if (movileu (1, 3, 12, 23) != 12)
+ return 1;
+ if (movileu (3, 3, 12, 23) != 12)
+ return 1;
+ if (movileu (5, 3, 12, 23) != 23)
+ return 1;
+ if (movileu (3, -1, 12, 23) != 12)
+ return 1;
+ if (movileu (3, 1, 12, 23) != 23)
+ return 1;
+ if (movileu (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movilt.c b/gcc/testsuite/gcc.dg/torture/movilt.c
new file mode 100644
index 0000000..3ff3b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movilt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movilt (-1, -1, 12, 23) != 23)
+ return 1;
+ if (movilt (-1, 3, 12, 23) != 12)
+ return 1;
+ if (movilt (1, 3, 12, 23) != 12)
+ return 1;
+ if (movilt (3, 3, 12, 23) != 23)
+ return 1;
+ if (movilt (5, 3, 12, 23) != 23)
+ return 1;
+ if (movilt (3, -1, 12, 23) != 23)
+ return 1;
+ if (movilt (3, 1, 12, 23) != 23)
+ return 1;
+ if (movilt (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/moviltu.c b/gcc/testsuite/gcc.dg/torture/moviltu.c
new file mode 100644
index 0000000..9679e37
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/moviltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+moviltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+int
+main (void)
+{
+ if (moviltu (-1, -1, 12, 23) != 23)
+ return 1;
+ if (moviltu (-1, 3, 12, 23) != 23)
+ return 1;
+ if (moviltu (1, 3, 12, 23) != 12)
+ return 1;
+ if (moviltu (3, 3, 12, 23) != 23)
+ return 1;
+ if (moviltu (5, 3, 12, 23) != 23)
+ return 1;
+ if (moviltu (3, -1, 12, 23) != 12)
+ return 1;
+ if (moviltu (3, 1, 12, 23) != 23)
+ return 1;
+ if (moviltu (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movine.c b/gcc/testsuite/gcc.dg/torture/movine.c
new file mode 100644
index 0000000..fc6f9b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movine.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movine (-1, -1, 12, 23) != 23)
+ return 1;
+ if (movine (-1, 3, 12, 23) != 12)
+ return 1;
+ if (movine (1, 3, 12, 23) != 12)
+ return 1;
+ if (movine (3, 3, 12, 23) != 23)
+ return 1;
+ if (movine (5, 3, 12, 23) != 12)
+ return 1;
+ if (movine (3, -1, 12, 23) != 12)
+ return 1;
+ if (movine (3, 1, 12, 23) != 12)
+ return 1;
+ if (movine (3, 5, 12, 23) != 12)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movleq.c b/gcc/testsuite/gcc.dg/torture/movleq.c
new file mode 100644
index 0000000..2c773fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movleq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movleq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movleq (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movleq (-1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movleq (1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movleq (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movleq (5L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movleq (3L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movleq (3L, 1L, 12L, 23L) != 23L)
+ return 1;
+ if (movleq (3L, 5L, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlfeq.c b/gcc/testsuite/gcc.dg/torture/movlfeq.c
new file mode 100644
index 0000000..96c3efc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlfeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlfeq (-1.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfeq (-1.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfeq (1.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfeq (3.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfeq (5.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfeq (3.0, -1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfeq (3.0, 1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfeq (3.0, 5.0, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlfge.c b/gcc/testsuite/gcc.dg/torture/movlfge.c
new file mode 100644
index 0000000..118c0a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlfge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlfge (-1.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfge (-1.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfge (1.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfge (3.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfge (5.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfge (3.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfge (3.0, 1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfge (3.0, 5.0, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlfgt.c b/gcc/testsuite/gcc.dg/torture/movlfgt.c
new file mode 100644
index 0000000..48ab58b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlfgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlfgt (-1.0, -1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfgt (-1.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfgt (1.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfgt (3.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfgt (5.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfgt (3.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfgt (3.0, 1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfgt (3.0, 5.0, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlfle.c b/gcc/testsuite/gcc.dg/torture/movlfle.c
new file mode 100644
index 0000000..940a7e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlfle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlfle (-1.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfle (-1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfle (1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfle (3.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfle (5.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfle (3.0, -1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfle (3.0, 1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfle (3.0, 5.0, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlflt.c b/gcc/testsuite/gcc.dg/torture/movlflt.c
new file mode 100644
index 0000000..fc7f102
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlflt (-1.0, -1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlflt (-1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlflt (1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlflt (3.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlflt (5.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlflt (3.0, -1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlflt (3.0, 1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlflt (3.0, 5.0, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlfne.c b/gcc/testsuite/gcc.dg/torture/movlfne.c
new file mode 100644
index 0000000..088fa25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlfne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlfne (-1.0, -1.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfne (-1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfne (1.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfne (3.0, 3.0, 12L, 23L) != 23L)
+ return 1;
+ if (movlfne (5.0, 3.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfne (3.0, -1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfne (3.0, 1.0, 12L, 23L) != 12L)
+ return 1;
+ if (movlfne (3.0, 5.0, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlge.c b/gcc/testsuite/gcc.dg/torture/movlge.c
new file mode 100644
index 0000000..34798e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlge (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlge (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlge (-1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlge (1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlge (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlge (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlge (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlge (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlge (3L, 5L, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlgeu.c b/gcc/testsuite/gcc.dg/torture/movlgeu.c
new file mode 100644
index 0000000..2895556
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlgeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlgeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlgeu (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgeu (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgeu (1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgeu (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgeu (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgeu (3L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgeu (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgeu (3L, 5L, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlgt.c b/gcc/testsuite/gcc.dg/torture/movlgt.c
new file mode 100644
index 0000000..ab6ce0b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlgt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlgt (-1L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgt (-1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgt (1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgt (3L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgt (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgt (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgt (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgt (3L, 5L, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlgtu.c b/gcc/testsuite/gcc.dg/torture/movlgtu.c
new file mode 100644
index 0000000..c43f04c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlgtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlgtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlgtu (-1L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgtu (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgtu (1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgtu (3L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgtu (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgtu (3L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlgtu (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlgtu (3L, 5L, 12L, 23L) != 23L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlle.c b/gcc/testsuite/gcc.dg/torture/movlle.c
new file mode 100644
index 0000000..81a9d6f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlle (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlle (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlle (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlle (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlle (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlle (5L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlle (3L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlle (3L, 1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlle (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlleu.c b/gcc/testsuite/gcc.dg/torture/movlleu.c
new file mode 100644
index 0000000..6d46fdb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlleu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlleu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlleu (-1L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlleu (-1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlleu (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlleu (3L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlleu (5L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlleu (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlleu (3L, 1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlleu (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movllt.c b/gcc/testsuite/gcc.dg/torture/movllt.c
new file mode 100644
index 0000000..ee32669
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movllt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movllt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movllt (-1L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movllt (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movllt (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movllt (3L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movllt (5L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movllt (3L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movllt (3L, 1L, 12L, 23L) != 23L)
+ return 1;
+ if (movllt (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlltu.c b/gcc/testsuite/gcc.dg/torture/movlltu.c
new file mode 100644
index 0000000..0a854da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlltu (-1L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlltu (-1L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlltu (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlltu (3L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlltu (5L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlltu (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlltu (3L, 1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlltu (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/movlne.c b/gcc/testsuite/gcc.dg/torture/movlne.c
new file mode 100644
index 0000000..d8f81a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/movlne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlne (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+int
+main (void)
+{
+ if (movlne (-1L, -1L, 12L, 23L) != 23L)
+ return 1;
+ if (movlne (-1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlne (1L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlne (3L, 3L, 12L, 23L) != 23L)
+ return 1;
+ if (movlne (5L, 3L, 12L, 23L) != 12L)
+ return 1;
+ if (movlne (3L, -1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlne (3L, 1L, 12L, 23L) != 12L)
+ return 1;
+ if (movlne (3L, 5L, 12L, 23L) != 12L)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr111815.c b/gcc/testsuite/gcc.dg/torture/pr111815.c
new file mode 100644
index 0000000..5e80b77
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr111815.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+
+char x[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+};
+
+__attribute__ ((noinline)) char *
+p (char *a, int o, int i)
+{
+ return a + ++o + (1 << ++i);
+}
+
+int
+main (void)
+{
+ if (*p (x, 0, 0) != 3)
+ return 1;
+ if (*p (x, 1, 2) != 10)
+ return 1;
+ if (*p (x, 2, 1) != 7)
+ return 1;
+ if (*p (x, 3, 3) != 20)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr112281-1.c b/gcc/testsuite/gcc.dg/torture/pr112281-1.c
new file mode 100644
index 0000000..711f566
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr112281-1.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-loop-distribution" } */
+
+struct {
+ int : 8;
+ int a;
+} b, d[4] = {{0}, {0}, {0}, {5}};
+int c, e;
+int main() {
+ for (c = 2; c; c--)
+ for (e = 0; e < 2; e++) {
+ d[c] = b = d[c + 1];
+ d[c + 1].a = 0;
+ }
+ if (b.a != 0)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr112281-2.c b/gcc/testsuite/gcc.dg/torture/pr112281-2.c
new file mode 100644
index 0000000..d7671e3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr112281-2.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-loop-distribution" } */
+
+struct {
+ int : 8;
+ int a;
+} b, d[4] = {{5}, {0}, {0}, {0}};
+int c, e;
+int main() {
+ for (c = 0; c < 2; c++)
+ for (e = 0; e < 2; e++) {
+ d[c + 1] = b = d[c];
+ d[c].a = 0;
+ }
+ if (b.a != 0)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr112344.c b/gcc/testsuite/gcc.dg/torture/pr112344.c
new file mode 100644
index 0000000..c52d2c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr112344.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+int
+main ()
+{
+ long long b = 2036854775807LL;
+ signed char c = 3;
+ short d = 0;
+ int e = -2147483647 - 1, f;
+ for (f = 0; f < 7; f++)
+ while (e < 20)
+ {
+ e += 2;
+ d = c -= b;
+ }
+ if (d != 13)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr112639.c b/gcc/testsuite/gcc.dg/torture/pr112639.c
new file mode 100644
index 0000000..9450d88
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr112639.c
@@ -0,0 +1,34 @@
+/* PR middle-end/112639 */
+/* { dg-do run } */
+
+unsigned long long b = 0;
+
+int
+foo (void)
+{
+ return __builtin_clzg (b++, __SIZEOF_LONG_LONG__ * __CHAR_BIT__);
+}
+
+int
+bar (void)
+{
+ return __builtin_ctzg (b++, __SIZEOF_LONG_LONG__ * __CHAR_BIT__);
+}
+
+int
+main ()
+{
+ if (foo () != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ || b != 1)
+ __builtin_abort ();
+ if (foo () != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1 || b != 2)
+ __builtin_abort ();
+ if (foo () != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 2 || b != 3)
+ __builtin_abort ();
+ b = 0;
+ if (bar () != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ || b != 1)
+ __builtin_abort ();
+ if (bar () != 0 || b != 2)
+ __builtin_abort ();
+ if (bar () != 1 || b != 3)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c
index 455f923..3f1d1e0 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-ipa-profile -fno-ipa-vrp" } */
__attribute__ ((noinline))
int foo()
diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
index e6eaeb9..eed0b1d 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-ipa-profile -fno-ipa-vrp" } */
#include <unistd.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109849.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109849.c
new file mode 100644
index 0000000..2d58e8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109849.c
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-sra" } */
+
+struct D
+{
+ long a;
+ short b;
+};
+
+struct S {
+ struct D *b;
+ int c;
+ int s;
+};
+
+struct D * __attribute__((malloc)) some_realloc_function (int c);
+
+static void __attribute__((noinline))
+realloc_s (struct S *p)
+{
+ int s = p->c ? p->c * 2 : 16;
+ p->b = some_realloc_function (s);
+ p->s = s;
+ return;
+}
+
+void modify (struct D *d);
+int test (struct D *d);
+
+static struct D gd;
+
+int
+foo (void)
+{
+ struct S stack;
+
+ stack.c = 1;
+ stack.s = 0;
+ realloc_s (&stack);
+ stack.b[0] = gd;
+ stack.c = 1;
+
+ while (stack.c)
+ {
+ struct D d = stack.b[--stack.c];
+ if (test (&d))
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ if (stack.s <= stack.c + 1)
+ realloc_s (&stack);
+ modify(&d);
+ stack.b[stack.c++] = d;
+ }
+ }
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "Created a replacement for stack offset" "sra"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c
index c68a6f9..dd5022f3 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ccp2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-ccp2 -fdump-tree-optimized -fno-ipa-vrp" } */
void foo(void);
static int a = 1, c;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr112706.c b/gcc/testsuite/gcc.dg/tree-ssa/pr112706.c
new file mode 100644
index 0000000..217730b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112706.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+int *ptr;
+void link_error ();
+void
+test ()
+{
+ int *ptr1 = ptr + 10;
+ int *ptr2 = ptr + 20;
+ if (ptr1 == ptr2)
+ link_error ();
+}
+
+/* { dg-final { scan-tree-dump-not "if" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c b/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
index f05076c..3a7c03b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdelete-null-pointer-checks -fno-thread-jumps" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdelete-null-pointer-checks -fno-thread-jumps -fno-ipa-vrp" } */
typedef struct {
int code;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/return-value-range-1.c b/gcc/testsuite/gcc.dg/tree-ssa/return-value-range-1.c
new file mode 100644
index 0000000..9729448
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/return-value-range-1.c
@@ -0,0 +1,22 @@
+/* { dg-do link } */
+/* { dg-options "-O2 -fdump-tree-evrp-details" } */
+__attribute__ ((__noinline__))
+int a(signed char c)
+{
+ return c;
+}
+void link_error ();
+
+void
+test(int d)
+{
+ if (a(d) > 200)
+ link_error ();
+}
+int
+main(int argc, char **argv)
+{
+ test(argc);
+ return 0;
+}
+/* { dg-final { scan-tree-dump-times "Recording return range" 2 "evrp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
index ac8c8d4..beea9ae 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
@@ -40,4 +40,5 @@ __BB(6):
}
-/* { dg-final { scan-tree-dump-times "&a" 1 "ivopts" { xfail ia32 } } } */
+/* Not all 32-bit systems fail this, but several do. */
+/* { dg-final { scan-tree-dump-times "&a" 1 "ivopts" { xfail ilp32 } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
index 57cb021..a97f75f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
@@ -45,4 +45,5 @@ __BB(6):
}
-/* { dg-final { scan-tree-dump-times "&a" 1 "ivopts" } } */
+/* Not all 32-bit systems fail this, but several do. */
+/* { dg-final { scan-tree-dump-times "&a" 1 "ivopts" { xfail ilp32 } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
index c911a92..08f4260 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
@@ -40,4 +40,5 @@ __BB(6):
}
-/* { dg-final { scan-tree-dump-times "&a" 1 "ivopts" { xfail ia32 } } } */
+/* Not all 32-bit systems fail this, but several do. */
+/* { dg-final { scan-tree-dump-times "&a" 1 "ivopts" { xfail ilp32 } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-longjmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-longjmp-1.c
new file mode 100644
index 0000000..fa19e76
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-longjmp-1.c
@@ -0,0 +1,87 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-sra" } */
+/* { dg-require-effective-target indirect_jumps } */
+
+#include <setjmp.h>
+
+struct S {
+ long *b;
+ int c;
+ int s;
+};
+
+static jmp_buf the_jmpbuf;
+volatile short vs = 0;
+long buf[16];
+long * volatile pbuf = (long *) &buf;
+
+static void __attribute__((noinline))
+crazy_alloc_s (struct S *p)
+{
+ int s = p->c ? p->c * 2 : 16;
+
+ long *b = pbuf;
+ if (!b || s > 16)
+ {
+ p->s = -p->s;
+ vs = 127;
+ longjmp (the_jmpbuf, 1);
+ }
+
+ __builtin_memcpy (b, p->b, p->c);
+ p->b = b;
+ p->s = s;
+ pbuf = 0;
+ return;
+}
+
+long __attribute__((noipa))
+process (long v)
+{
+ return v + 1;
+}
+
+void
+foo (void)
+{
+ struct S stack;
+
+ if (setjmp (the_jmpbuf))
+ return;
+
+ stack.c = 0;
+ crazy_alloc_s (&stack);
+ stack.b[0] = 1;
+ stack.c = 1;
+
+ while (stack.c)
+ {
+ long l = stack.b[--stack.c];
+
+ if (l > 0)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ if (stack.s <= stack.c + 1)
+ crazy_alloc_s (&stack);
+ l = process (l);
+ stack.b[stack.c++] = l;
+ }
+ }
+ }
+
+ return;
+}
+
+int main (int argc, char **argv)
+{
+ vs = 0;
+ pbuf = (long *) &buf;
+ foo ();
+ if (vs != 127)
+ __builtin_abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Created a replacement for stack offset" "sra"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c
index 7f38e8d..f7ba16c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fno-thread-jumps" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fno-thread-jumps -fno-ipa-vrp" } */
inline int ten()
diff --git a/gcc/testsuite/gcc.dg/ubsan/has-feature-ubsan.c b/gcc/testsuite/gcc.dg/ubsan/has-feature-ubsan.c
new file mode 100644
index 0000000..e5da1cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/has-feature-ubsan.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+#define FEAT(x) (__has_feature (x) && __has_extension (x))
+#if !FEAT (undefined_behavior_sanitizer)
+#error
+#endif
diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c
index 3c83d50..1877d5d 100644
--- a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c
+++ b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2" } */
+/* The param shuts up a bogus uninitialized warning at line 21. */
+/* { dg-options "-Wuninitialized -O2 --param=logical-op-non-short-circuit=0" } */
int g;
void bar();
@@ -17,10 +18,10 @@ int foo (int n, int l, int m, int r)
if (l > 100)
if ( (n <= 9) && (m < 100) && (r < 19) )
- blah(v); /* { dg-bogus "uninitialized" "bogus warning" { xfail *-*-* } } */
+ blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( (n <= 8) && (m < 99) && (r < 19) )
- blah(v); /* { dg-bogus "uninitialized" "pr101674" { xfail mmix-*-* } } */
+ blah(v); /* { dg-bogus "uninitialized" "pr101674" } */
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/vla-1.c b/gcc/testsuite/gcc.dg/vla-1.c
index 902166c..d16e73d 100644
--- a/gcc/testsuite/gcc.dg/vla-1.c
+++ b/gcc/testsuite/gcc.dg/vla-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-g -O3 -fdump-tree-optimized -fvar-tracking-assignments -fno-selective-scheduling -fno-selective-scheduling2" } */
+/* { dg-options "-g -O3 -fdump-tree-optimized -fvar-tracking-assignments -fno-selective-scheduling -fno-selective-scheduling2 -fno-ipa-vrp" } */
int __attribute__((noinline))
f1 (int i)
diff --git a/gcc/testsuite/gcc.misc-tests/help.exp b/gcc/testsuite/gcc.misc-tests/help.exp
index 52b9cb0..15d618a 100644
--- a/gcc/testsuite/gcc.misc-tests/help.exp
+++ b/gcc/testsuite/gcc.misc-tests/help.exp
@@ -151,6 +151,8 @@ foreach cls { "ada" "c" "c++" "d" "fortran" "go" \
# Listing only excludes gives empty results.
check_for_options c "--help=^joined,^separate" "" "" ""
+check_for_options c "--help=hardened" "The following options are enabled by -fhardened" "" ""
+
if [ info exists prev_columns ] {
# Reset the enviroment variable to its oriuginal value.
set env(COLUMNS) $prev_columns
diff --git a/gcc/testsuite/gcc.misc-tests/linkage-y.c b/gcc/testsuite/gcc.misc-tests/linkage-y.c
index eaffa5e..4235325 100644
--- a/gcc/testsuite/gcc.misc-tests/linkage-y.c
+++ b/gcc/testsuite/gcc.misc-tests/linkage-y.c
@@ -1,8 +1,11 @@
/* 920717-y.c */
extern const char s[];
+extern int puts(const char *);
+int
main()
{
puts(s);
+ return 0;
}
diff --git a/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_1.c b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_1.c
index b746daf..39d9142 100644
--- a/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_1.c
@@ -127,12 +127,12 @@ bfloat16x4_t footest (bfloat16x4_t vector0)
(void) glob_bfloat_vec;
(bfloat16x4_t) glob_bfloat_vec;
- (bfloat16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (bfloat16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x4_t' to type 'short int' which has different size} } */
(int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x4_t' to type 'int' which has different size} } */
- (float16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (float16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (float) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (double) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(int32x4_t) glob_bfloat_vec; /* { dg-error {cannot convert a value of type 'bfloat16x4_t' to vector type '__Int32x4_t' which has different size} } */
(float32x4_t) glob_bfloat_vec; /* { dg-error {cannot convert a value of type 'bfloat16x4_t' to vector type '__Float32x4_t' which has different size} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_2.c b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_2.c
index 779bb52..c320b00 100644
--- a/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck_2.c
@@ -126,12 +126,12 @@ bfloat16x8_t footest (bfloat16x8_t vector0)
(void) glob_bfloat_vec;
(bfloat16x8_t) glob_bfloat_vec;
- (bfloat16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (bfloat16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x8_t' to type 'short int' which has different size} } */
(int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x8_t' to type 'int' which has different size} } */
- (float16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (float16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (float) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (double) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(int32x4_t) glob_bfloat_vec;
(float32x4_t) glob_bfloat_vec;
diff --git a/gcc/testsuite/gcc.target/aarch64/ccmp_1.c b/gcc/testsuite/gcc.target/aarch64/ccmp_1.c
index fd38b2c..9b68c07 100644
--- a/gcc/testsuite/gcc.target/aarch64/ccmp_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/ccmp_1.c
@@ -86,8 +86,8 @@ f13 (int a, int b)
/* { dg-final { scan-assembler "cmp\t(.)+35" } } */
/* { dg-final { scan-assembler-times "\tcmp\tw\[0-9\]+, 0" 4 } } */
-/* { dg-final { scan-assembler-times "fcmpe\t(.)+0\\.0" 2 } } */
-/* { dg-final { scan-assembler-times "fcmp\t(.)+0\\.0" 2 } } */
+/* { dg-final { scan-assembler-times "fcmpe\t(?:.)+0\\.0" 1 } } */
+/* { dg-final { scan-assembler-times "fcmp\t(?:.)+0\\.0" 1 } } */
/* { dg-final { scan-assembler "adds\t" } } */
/* { dg-final { scan-assembler-times "\tccmp\t" 11 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/movk.c b/gcc/testsuite/gcc.target/aarch64/movk.c
index e6e4e3a..1fa1154 100644
--- a/gcc/testsuite/gcc.target/aarch64/movk.c
+++ b/gcc/testsuite/gcc.target/aarch64/movk.c
@@ -1,8 +1,11 @@
/* { dg-do run } */
-/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-options "-O2 --save-temps" } */
extern void abort (void);
+/* Note GCC can optimize this to -346565474575675 even without inlining so
+ mark it for noipa. */
+[[gnu::noipa]]
long long int
dummy_number_generator ()
{
diff --git a/gcc/testsuite/gcc.target/aarch64/pr112406-2.c b/gcc/testsuite/gcc.target/aarch64/pr112406-2.c
new file mode 100644
index 0000000..bb6e9cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr112406-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { aarch64*-*-* } } } */
+/* { dg-options "-march=armv8-a+sve -Ofast" } */
+
+double MADPictureC1;
+extern int PictureRejected[];
+int PictureMAD_0, MADModelEstimator_n_windowSize_i, MADModelEstimator_n_windowSize_oneSampleQ;
+
+void MADModelEstimator_n_windowSize() {
+ int estimateX2 = 0;
+ for (; MADModelEstimator_n_windowSize_i; MADModelEstimator_n_windowSize_i++) {
+ if (MADModelEstimator_n_windowSize_oneSampleQ &&
+ !PictureRejected[MADModelEstimator_n_windowSize_i])
+ estimateX2 = 1;
+ if (!PictureRejected[MADModelEstimator_n_windowSize_i])
+ MADPictureC1 += PictureMAD_0;
+ }
+ if (estimateX2)
+ for (;;)
+ ;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c b/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c
index d45bb83..a2d09ea 100644
--- a/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c
@@ -22,11 +22,11 @@ FUNC (int32x4_t, int64x2_t, s32)
/* { dg-final { scan-assembler-times {sxtl2\tv0\.2d, v0\.4s} 1} } */
FUNC (uint8x16_t, uint16x8_t, u8)
-/* { dg-final { scan-assembler-times {uxtl2\tv0\.8h, v0\.16b} 1} } */
+/* { dg-final { scan-assembler-times {zip2\tv0\.16b, v0\.16b} 1} } */
FUNC (uint16x8_t, uint32x4_t, u16)
-/* { dg-final { scan-assembler-times {uxtl2\tv0\.4s, v0\.8h} 1} } */
+/* { dg-final { scan-assembler-times {zip2\tv0\.8h, v0\.8h} 1} } */
FUNC (uint32x4_t, uint64x2_t, u32)
-/* { dg-final { scan-assembler-times {uxtl2\tv0\.2d, v0\.4s} 1} } */
+/* { dg-final { scan-assembler-times {zip2\tv0\.4s, v0\.4s} 1} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x b/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x
index 8968a64..869e748 100644
--- a/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x
+++ b/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x
@@ -33,13 +33,13 @@
while (0) \
/* Functions used to return values that won't be optimised away. */
-float32_t __attribute__ ((noinline))
+float32_t __attribute__ ((noipa))
foo32 ()
{
return 1.0;
}
-float64_t __attribute__ ((noinline))
+float64_t __attribute__ ((noipa))
foo64 ()
{
return 1.0;
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_asrd_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_asrd_1.c
index aac06bd..96e9935 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_asrd_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_asrd_1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256" } */
+/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256 --param=aarch64-autovec-preference=2" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_4.c
index f627891..6f969a8 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256" } */
+/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256 --param=aarch64-autovec-preference=2" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_5.c
index 03a6636..e6ec515 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256" } */
+/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256 --param=aarch64-autovec-preference=2" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_5.c
index 9a2bd8f..7ed3592 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256" } */
+/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256 --param=aarch64-autovec-preference=2" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/target_attr_13.c b/gcc/testsuite/gcc.target/aarch64/target_attr_13.c
index d5bee3a..4bdb167 100644
--- a/gcc/testsuite/gcc.target/aarch64/target_attr_13.c
+++ b/gcc/testsuite/gcc.target/aarch64/target_attr_13.c
@@ -1,5 +1,5 @@
/* { dg-do assemble } */
-/* { dg-options "-O2 -march=armv8-a+crc+crypto -mcpu=generic" } */
+/* { dg-options "-O2 -mcpu=generic+crypto" } */
#include "arm_acle.h"
diff --git a/gcc/testsuite/gcc.target/aarch64/target_attr_15.c b/gcc/testsuite/gcc.target/aarch64/target_attr_15.c
index 069a001..e6f31ba 100644
--- a/gcc/testsuite/gcc.target/aarch64/target_attr_15.c
+++ b/gcc/testsuite/gcc.target/aarch64/target_attr_15.c
@@ -1,5 +1,5 @@
/* { dg-do assemble } */
-/* { dg-options "-march=armv8-a+crypto -mcpu=generic -save-temps" } */
+/* { dg-options "-mcpu=generic+crypto -save-temps" } */
/* Check that "+nothing" clears the ISA flags. */
diff --git a/gcc/testsuite/gcc.target/aarch64/uxtl-combine-1.c b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-1.c
new file mode 100755
index 0000000..68fa9a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-1.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#pragma GCC target "+nosve"
+
+#define SIGN unsigned
+#define TYPE1 char
+#define TYPE2 short
+
+void d2 (SIGN TYPE2 * restrict a, SIGN TYPE1 *b, int n)
+{
+ for (int i = 0; i < (n & -8); i++)
+ a[i] = b[i];
+}
+
+/* { dg-final { scan-assembler-times {\tzip1\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tzip2\t} 1 } } */
+/* { dg-final { scan-assembler-not {\tuxtl\t} } } */
+/* { dg-final { scan-assembler-not {\tuxtl2\t} } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/uxtl-combine-2.c b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-2.c
new file mode 100755
index 0000000..af8a890
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-2.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#pragma GCC target "+nosve"
+
+#define SIGN unsigned
+#define TYPE1 short
+#define TYPE2 int
+
+void d2 (SIGN TYPE2 * restrict a, SIGN TYPE1 *b, int n)
+{
+ for (int i = 0; i < (n & -8); i++)
+ a[i] = b[i];
+}
+
+/* { dg-final { scan-assembler-times {\tzip1\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tzip2\t} 1 } } */
+/* { dg-final { scan-assembler-not {\tuxtl\t} } } */
+/* { dg-final { scan-assembler-not {\tuxtl2\t} } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/uxtl-combine-3.c b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-3.c
new file mode 100755
index 0000000..cdae6d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-3.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#pragma GCC target "+nosve"
+
+#define SIGN unsigned
+#define TYPE1 int
+#define TYPE2 long long
+
+void d2 (SIGN TYPE2 * restrict a, SIGN TYPE1 *b, int n)
+{
+ for (int i = 0; i < (n & -8); i++)
+ a[i] = b[i];
+}
+
+/* { dg-final { scan-assembler-times {\tzip1\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tzip2\t} 1 } } */
+/* { dg-final { scan-assembler-not {\tuxtl\t} } } */
+/* { dg-final { scan-assembler-not {\tuxtl2\t} } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/uxtl-combine-4.c b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-4.c
new file mode 100755
index 0000000..67944f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-4.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#pragma GCC target "+nosve"
+
+#define SIGN signed
+#define TYPE1 char
+#define TYPE2 short
+
+void d2 (SIGN TYPE2 * restrict a, SIGN TYPE1 *b, int n)
+{
+ for (int i = 0; i < (n & -8); i++)
+ a[i] = b[i];
+}
+
+/* { dg-final { scan-assembler-not {\tzip1\t} } } */
+/* { dg-final { scan-assembler-not {\tzip2\t} } } */
+/* { dg-final { scan-assembler-times {\tsxtl\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tsxtl2\t} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/uxtl-combine-5.c b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-5.c
new file mode 100755
index 0000000..e691c4f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-5.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#pragma GCC target "+nosve"
+
+#define SIGN signed
+#define TYPE1 short
+#define TYPE2 int
+
+void d2 (SIGN TYPE2 * restrict a, SIGN TYPE1 *b, int n)
+{
+ for (int i = 0; i < (n & -8); i++)
+ a[i] = b[i];
+}
+
+/* { dg-final { scan-assembler-not {\tzip1\t} } } */
+/* { dg-final { scan-assembler-not {\tzip2\t} } } */
+/* { dg-final { scan-assembler-times {\tsxtl\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tsxtl2\t} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/uxtl-combine-6.c b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-6.c
new file mode 100755
index 0000000..9383f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/uxtl-combine-6.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#pragma GCC target "+nosve"
+
+#define SIGN signed
+#define TYPE1 int
+#define TYPE2 long long
+
+void d2 (SIGN TYPE2 * restrict a, SIGN TYPE1 *b, int n)
+{
+ for (int i = 0; i < (n & -8); i++)
+ a[i] = b[i];
+}
+
+/* { dg-final { scan-assembler-not {\tzip1\t} } } */
+/* { dg-final { scan-assembler-not {\tzip2\t} } } */
+/* { dg-final { scan-assembler-times {\tsxtl\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tsxtl2\t} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c
index f3c350b..b677180 100644
--- a/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c
+++ b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c
@@ -130,12 +130,12 @@ bfloat16x4_t footest (bfloat16x4_t vector0)
(void) glob_bfloat_vec;
(bfloat16x4_t) glob_bfloat_vec;
- (bfloat16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (bfloat16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x4_t' to type 'short int' which has different size} } */
(int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x4_t' to type 'int' which has different size} } */
- (float16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (float16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (float) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (double) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(int32x4_t) glob_bfloat_vec; /* { dg-error {cannot convert a value of type 'bfloat16x4_t' to vector type '__simd128_int32_t' which has different size} } */
(float32x4_t) glob_bfloat_vec; /* { dg-error {cannot convert a value of type 'bfloat16x4_t' to vector type '__simd128_float32_t' which has different size} } */
diff --git a/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c
index de0ade5..3c18dc5 100644
--- a/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c
+++ b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c
@@ -122,12 +122,12 @@ bfloat16x8_t footest (bfloat16x8_t vector0)
(void) glob_bfloat_vec;
(bfloat16x8_t) glob_bfloat_vec;
- (bfloat16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (bfloat16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x8_t' to type 'short int' which has different size} } */
(int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x8_t' to type 'int' which has different size} } */
- (float16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (float16_t) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (float) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (double) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(int32x4_t) glob_bfloat_vec;
(float32x4_t) glob_bfloat_vec;
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f16.c
index 1fa02f0..e4b4060 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f16.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (float16_t *base, float16x8_t value)
{
- return vst1q_f16 (base, value);
+ vst1q_f16 (base, value);
}
@@ -31,7 +31,7 @@ foo (float16_t *base, float16x8_t value)
void
foo1 (float16_t *base, float16x8_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f32.c
index 67cc3ae..8f42323c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_f32.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (float32_t *base, float32x4_t value)
{
- return vst1q_f32 (base, value);
+ vst1q_f32 (base, value);
}
@@ -31,7 +31,7 @@ foo (float32_t *base, float32x4_t value)
void
foo1 (float32_t *base, float32x4_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s16.c
index 052959b..891ac41 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s16.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (int16_t *base, int16x8_t value)
{
- return vst1q_s16 (base, value);
+ vst1q_s16 (base, value);
}
@@ -31,7 +31,7 @@ foo (int16_t *base, int16x8_t value)
void
foo1 (int16_t *base, int16x8_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s32.c
index 444ad07..a28d1eb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s32.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (int32_t *base, int32x4_t value)
{
- return vst1q_s32 (base, value);
+ vst1q_s32 (base, value);
}
@@ -31,7 +31,7 @@ foo (int32_t *base, int32x4_t value)
void
foo1 (int32_t *base, int32x4_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s8.c
index 684ff0a..81c141a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_s8.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (int8_t *base, int8x16_t value)
{
- return vst1q_s8 (base, value);
+ vst1q_s8 (base, value);
}
@@ -31,7 +31,7 @@ foo (int8_t *base, int8x16_t value)
void
foo1 (int8_t *base, int8x16_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u16.c
index 1fea2de..b8ce7fb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u16.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (uint16_t *base, uint16x8_t value)
{
- return vst1q_u16 (base, value);
+ vst1q_u16 (base, value);
}
@@ -31,7 +31,7 @@ foo (uint16_t *base, uint16x8_t value)
void
foo1 (uint16_t *base, uint16x8_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u32.c
index 64c43c5..1dbb555 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u32.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (uint32_t *base, uint32x4_t value)
{
- return vst1q_u32 (base, value);
+ vst1q_u32 (base, value);
}
@@ -31,7 +31,7 @@ foo (uint32_t *base, uint32x4_t value)
void
foo1 (uint32_t *base, uint32x4_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u8.c
index 5517611..ab22be8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vst1q_u8.c
@@ -18,7 +18,7 @@ extern "C" {
void
foo (uint8_t *base, uint8x16_t value)
{
- return vst1q_u8 (base, value);
+ vst1q_u8 (base, value);
}
@@ -31,7 +31,7 @@ foo (uint8_t *base, uint8x16_t value)
void
foo1 (uint8_t *base, uint8x16_t value)
{
- return vst1q (base, value);
+ vst1q (base, value);
}
#ifdef __cplusplus
diff --git a/gcc/testsuite/gcc.target/arm/pr53447-5.c b/gcc/testsuite/gcc.target/arm/pr53447-5.c
index da91811..e428361 100644
--- a/gcc/testsuite/gcc.target/arm/pr53447-5.c
+++ b/gcc/testsuite/gcc.target/arm/pr53447-5.c
@@ -15,8 +15,6 @@ void foo(long long* p)
p[9] -= p[10];
}
-/* We accept neon instructions vldr.64 and vstr.64 as well.
- Note: DejaGnu counts patterns with alternatives twice,
- so actually there are only 10 loads and 9 stores. */
-/* { dg-final { scan-assembler-times "(ldrd|vldr\\.64)" 20 } } */
-/* { dg-final { scan-assembler-times "(strd|vstr\\.64)" 18 } } */
+/* We accept neon instructions vldr.64 and vstr.64 as well. */
+/* { dg-final { scan-assembler-times "(?:ldrd|vldr\\.64)" 10 } } */
+/* { dg-final { scan-assembler-times "(?:strd|vstr\\.64)" 9 } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-bind.c b/gcc/testsuite/gcc.target/bpf/helper-bind.c
index 8dfde24..53514ba 100644
--- a/gcc/testsuite/gcc.target/bpf/helper-bind.c
+++ b/gcc/testsuite/gcc.target/bpf/helper-bind.c
@@ -2,7 +2,9 @@
/* { dg-options "-std=gnu99" } */
#include <stdint.h>
-#include <bpf-helpers.h>
+
+int bpf_bind (void *ctx, void *addr, int addr_len)
+ __attribute__((kernel_helper(64)));
void
foo ()
diff --git a/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c
deleted file mode 100644
index 9937d5a..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- uint32_t ifindex;
- uint64_t flags;
-
- ret = bpf_redirect (ifindex, flags);
-}
-
-/* { dg-final { scan-assembler "call\t23" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c
deleted file mode 100644
index e38adbc..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t ifindex;
- uint64_t flags;
-
- ret = bpf_clone_redirect (skb, ifindex, flags);
-}
-
-/* { dg-final { scan-assembler "call\t13" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c b/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c
deleted file mode 100644
index a1c8bf5..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int64_t ret;
- int32_t *to, *from;
- uint64_t to_size, from_size;
- int seed;
-
- ret = bpf_csum_diff (from, from_size, to, to_size, seed);
-}
-
-/* { dg-final { scan-assembler "call\t28" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-update.c b/gcc/testsuite/gcc.target/bpf/helper-csum-update.c
deleted file mode 100644
index 4f65033..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-csum-update.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int64_t ret;
- void *skb;
- int csum;
-
- ret = bpf_csum_update (skb, csum);
-}
-
-/* { dg-final { scan-assembler "call\t40" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c
deleted file mode 100644
index 5b05378..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *map;
- uint32_t index;
-
- ret = bpf_current_task_under_cgroup (map, index);
-}
-
-/* { dg-final { scan-assembler "call\t37" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c b/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c
deleted file mode 100644
index 8290234..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *params;
- int plen;
- uint32_t flags;
-
- ret = bpf_fib_lookup (ctx, params, plen, flags);
-}
-
-/* { dg-final { scan-assembler "call\t69" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c b/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c
deleted file mode 100644
index 5d85a89..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint32_t ret;
- void *skb;
-
- ret = bpf_get_cgroup_classid (skb);
-}
-
-/* { dg-final { scan-assembler "call\t17" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c
deleted file mode 100644
index 6f55e51..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
-
- ret = bpf_get_current_cgroup_id ();
-}
-
-/* { dg-final { scan-assembler "call\t80" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c
deleted file mode 100644
index 1e25cd1..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *buf;
- uint32_t size_of_buf;
-
- ret = bpf_get_current_comm (buf, size_of_buf);
-}
-
-/* { dg-final { scan-assembler "call\t16" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c
deleted file mode 100644
index 1dd7a1e..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
-
- ret = bpf_get_current_pid_tgid ();
-}
-
-/* { dg-final { scan-assembler "call\t14" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c
deleted file mode 100644
index 79344d1..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
-
- ret = bpf_get_current_task ();
-}
-
-/* { dg-final { scan-assembler "call\t35" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c
deleted file mode 100644
index b3e7261..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
-
- ret = bpf_get_current_uid_gid ();
-}
-
-/* { dg-final { scan-assembler "call\t15" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c b/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c
deleted file mode 100644
index e9d87ae..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint32_t ret;
- void *skb;
-
- ret = bpf_get_hash_recalc (skb);
-}
-
-/* { dg-final { scan-assembler "call\t34" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c b/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c
deleted file mode 100644
index 500ba78..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret, *sk;
-
- ret = bpf_get_listener_sock (sk);
-}
-
-/* { dg-final { scan-assembler "call\t98" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c b/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c
deleted file mode 100644
index 616342c..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret, *map;
- uint64_t flags;
-
- ret = bpf_get_local_storage (map, flags);
-}
-
-/* { dg-final { scan-assembler "call\t81" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c
deleted file mode 100644
index e6477a5..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
-
- ret = bpf_get_numa_node_id ();
-}
-
-/* { dg-final { scan-assembler "call\t42" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c b/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c
deleted file mode 100644
index f30cafd..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint32_t ret;
-
- ret = bpf_get_prandom_u32 ();
-}
-
-/* { dg-final { scan-assembler "call\t7" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c b/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c
deleted file mode 100644
index b779430..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint32_t ret;
- void *skb;
-
- ret = bpf_get_route_realm (skb);
-}
-
-/* { dg-final { scan-assembler "call\t24" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c
deleted file mode 100644
index 7d0e986..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint32_t ret;
-
- ret = bpf_get_smp_processor_id ();
-}
-
-/* { dg-final { scan-assembler "call\t8" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c
deleted file mode 100644
index e6c5385..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
- void *skb;
-
- ret = bpf_get_socket_cookie (skb);
-}
-
-/* { dg-final { scan-assembler "call\t46" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c
deleted file mode 100644
index c1eaa2b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint32_t ret;
- void *skb;
-
- ret = bpf_get_socket_uid (skb);
-}
-
-/* { dg-final { scan-assembler "call\t47" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stack.c b/gcc/testsuite/gcc.target/bpf/helper-get-stack.c
deleted file mode 100644
index cc3f6a0..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-stack.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *regs, *buf;
- uint32_t size;
- uint64_t flags;
-
- ret = bpf_get_stack (regs, buf, size, flags);
-}
-
-/* { dg-final { scan-assembler "call\t67" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c b/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c
deleted file mode 100644
index cc3ecb0..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *map;
- uint64_t flags;
-
- ret = bpf_get_stackid (ctx, map, flags);
-}
-
-/* { dg-final { scan-assembler "call\t27" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c
deleted file mode 100644
index 3f71b6b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *bpf_socket;
- int level, optname, optlen;
- char *optval;
-
- ret = bpf_getsockopt (bpf_socket, level,
- optname, optval, optlen);
-}
-
-/* { dg-final { scan-assembler "call\t57" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c b/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c
deleted file mode 100644
index 77f1661..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
- ret = bpf_ktime_get_ns ();
-}
-
-/* { dg-final { scan-assembler "call\t5" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c
deleted file mode 100644
index c3f1b78..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t offset;
- uint64_t from, to, size;
-
- ret = bpf_l3_csum_replace (skb, offset, from, to, size);
-}
-
-/* { dg-final { scan-assembler "call\t10" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c
deleted file mode 100644
index fd54f0b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t offset;
- uint64_t from, to, size;
-
- ret = bpf_l4_csum_replace (skb, offset, from, to, size);
-}
-
-/* { dg-final { scan-assembler "call\t11" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c
deleted file mode 100644
index c6d82cc..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *hdr;
- uint32_t type, len;
-
- ret = bpf_lwt_push_encap (skb, type, hdr, len);
-}
-
-/* { dg-final { scan-assembler "call\t73" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c
deleted file mode 100644
index 2fc7e48..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *param;
- uint32_t action, param_len;
-
- ret = bpf_lwt_seg6_action (skb, action,
- param, param_len);
-}
-
-/* { dg-final { scan-assembler "call\t76" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c
deleted file mode 100644
index 762ab41..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t offset, delta;
-
- ret = bpf_lwt_seg6_adjust_srh (skb, offset, delta);
-}
-
-/* { dg-final { scan-assembler "call\t75" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c
deleted file mode 100644
index 80a1f12..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *from;
- uint32_t offset, len;
-
- ret = bpf_lwt_seg6_store_bytes (skb, offset, from, len);
-}
-
-/* { dg-final { scan-assembler "call\t74" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c
deleted file mode 100644
index 0200b15..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <bpf-helpers.h>
-
-char *map () { return 0; }
-
-void
-foo ()
-{
- int ret;
- char *key = 0;
-
- ret = bpf_map_delete_elem (map (), key);
-}
-
-/* { dg-final { scan-assembler "call\t3" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c
deleted file mode 100644
index 1d443a0..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <bpf-helpers.h>
-
-char *map () { return 0; }
-
-void
-foo ()
-{
- char *key = 0, *value = 0;
- value = bpf_map_lookup_elem (map (), key);
-}
-
-/* { dg-final { scan-assembler "call\t1" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c
deleted file mode 100644
index de833f2..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <bpf-helpers.h>
-
-char *map () { return 0; }
-
-void
-foo ()
-{
- int ret;
- char *value = 0;
-
- ret = bpf_map_peek_elem (map (), value);
-}
-
-/* { dg-final { scan-assembler "call\t89" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c
deleted file mode 100644
index 7d76f85..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <bpf-helpers.h>
-
-char *map () { return 0; }
-
-void
-foo ()
-{
- int ret;
- char *value = 0;
-
- ret = bpf_map_pop_elem (map (), value);
-}
-
-/* { dg-final { scan-assembler "call\t88" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c
deleted file mode 100644
index b4b2a8e..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <bpf-helpers.h>
-
-char *map () { return 0; }
-
-void
-foo ()
-{
- int ret;
- char *value = 0;
- long long flags = 0;
-
- ret = bpf_map_push_elem (map (), value, flags);
-}
-
-/* { dg-final { scan-assembler "call\t87" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c
deleted file mode 100644
index 6cceafe..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <bpf-helpers.h>
-
-char *map () { return 0; }
-
-void
-foo ()
-{
- int ret;
- long long flags = 0;
- char *key = 0, *value = 0;
-
- ret = bpf_map_update_elem (map (), key, value, flags);
-}
-
-/* { dg-final { scan-assembler "call\t2" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c
deleted file mode 100644
index e72035c..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *msg;
- uint32_t bytes;
-
- ret = bpf_msg_apply_bytes (msg, bytes);
-}
-
-/* { dg-final { scan-assembler "call\t61" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c
deleted file mode 100644
index 350c2bf..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *msg;
- uint32_t bytes;
-
- ret = bpf_msg_cork_bytes (msg, bytes);
-}
-
-/* { dg-final { scan-assembler "call\t62" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c
deleted file mode 100644
index 5679044..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t start, pop;
- uint64_t flags;
-
- ret = bpf_msg_pop_data (skb, start, pop, flags);
-}
-
-/* { dg-final { scan-assembler "call\t91" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c
deleted file mode 100644
index 98d343b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *msg;
- int len;
-
- ret = bpf_msg_pull_data (msg, len);
-}
-
-/* { dg-final { scan-assembler "call\t63" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c
deleted file mode 100644
index 40b9361..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t start, len;
- uint64_t flags;
-
- ret = bpf_msg_push_data (skb, start, len, flags);
-}
-
-/* { dg-final { scan-assembler "call\t90" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c
deleted file mode 100644
index 6ac680c..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *msg, *map, *key;
- uint64_t flags;
-
- ret = bpf_msg_redirect_hash (msg, map, key,
- flags);
-}
-
-/* { dg-final { scan-assembler "call\t71" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c
deleted file mode 100644
index ed7652b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *msg, *map;
- uint64_t key;
- uint64_t flags;
-
- ret = bpf_msg_redirect_map (msg, map, key, flags);
-}
-
-/* { dg-final { scan-assembler "call\t60" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-override-return.c b/gcc/testsuite/gcc.target/bpf/helper-override-return.c
deleted file mode 100644
index 5036686..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-override-return.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *regs;
- uint64_t rc;
-
- ret = bpf_override_return (regs, rc);
-}
-
-/* { dg-final { scan-assembler "call\t58" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c
deleted file mode 100644
index 24ed565..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *map;
- uint64_t flags;
- void *data;
- uint64_t size;
-
- ret = bpf_perf_event_output (ctx, map, flags, data, size);
-}
-
-/* { dg-final { scan-assembler "call\t25" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c
deleted file mode 100644
index 6e6184f..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *map, *buf;
- uint64_t flags;
- uint64_t buf_size;
-
- ret = bpf_perf_event_read_value (map, flags, buf, buf_size);
-}
-
-/* { dg-final { scan-assembler "call\t55" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c
deleted file mode 100644
index 674058d..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
- void *map;
- uint64_t flags;
-
- ret = bpf_perf_event_read (map, flags);
-}
-
-/* { dg-final { scan-assembler "call\t22" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c
deleted file mode 100644
index 341a541..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *buf;
- uint64_t buf_size;
-
- ret = bpf_perf_prog_read_value (ctx, buf, buf_size);
-}
-
-/* { dg-final { scan-assembler "call\t56" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c
deleted file mode 100644
index 02d1a07..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- int size;
- void *dst;
- const void *unsafe_ptr;
-
- ret = bpf_probe_read_str (dst, size, unsafe_ptr);
-}
-
-/* { dg-final { scan-assembler "call\t45" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read.c
deleted file mode 100644
index 64261c5..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-probe-read.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *src, *dst;
- uint32_t size;
-
- ret = bpf_probe_read (dst, size, src);
-}
-
-/* { dg-final { scan-assembler "call\t4" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c b/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c
deleted file mode 100644
index 127ae61..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *dst, *src;
- uint32_t len;
-
- ret = bpf_probe_write_user (dst, src, len);
-}
-
-/* { dg-final { scan-assembler "call\t36" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c b/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c
deleted file mode 100644
index dd90423..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx;
- uint32_t protocol, toggle;
- uint64_t scancode;
-
- ret = bpf_rc_keydown (ctx, protocol, scancode, toggle);
-}
-
-/* { dg-final { scan-assembler "call\t78" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c b/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c
deleted file mode 100644
index ca0a5c4..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx;
- int32_t rel_x, rel_y;
-
- ret = bpf_rc_pointer_rel (ctx, rel_x, rel_y);
-}
-
-/* { dg-final { scan-assembler "call\t92" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c b/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c
deleted file mode 100644
index 79d3b5c..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx;
-
- ret = bpf_rc_repeat (ctx);
-}
-
-/* { dg-final { scan-assembler "call\t77" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c
deleted file mode 100644
index 50b3e81..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *map;
- uint32_t key;
- uint64_t flags;
-
- ret = bpf_redirect_map (map, key, flags);
-}
-
-/* { dg-final { scan-assembler "call\t51" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c
deleted file mode 100644
index adbc41b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *skb;
-
- bpf_set_hash_invalid (skb);
-}
-
-/* { dg-final { scan-assembler "call\t41" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash.c
deleted file mode 100644
index cafe539..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-set-hash.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint32_t ret;
- void *skb;
- uint32_t hash;
-
- ret = bpf_set_hash (skb, hash);
-}
-
-/* { dg-final { scan-assembler "call\t48" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c
deleted file mode 100644
index 930b8b2..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *bpf_socket;
- int level;
- int optname;
- void *optval;
- int optlen;
-
- ret = bpf_setsockopt (bpf_socket, level, optname, optval, optlen);
-}
-
-/* { dg-final { scan-assembler "call\t49" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c b/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c
deleted file mode 100644
index 9e66e94..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret, *sk;
-
- ret = bpf_sk_fullsock (sk);
-}
-
-/* { dg-final { scan-assembler "call\t95" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c
deleted file mode 100644
index 9d48c4c..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret;
- void *ctx, *tuple;
- uint32_t tuple_size;
- uint64_t netns, flags;
-
- ret = bpf_sk_lookup_tcp (ctx,
- tuple,
- tuple_size,
- netns, flags);
-}
-
-/* { dg-final { scan-assembler "call\t84" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c
deleted file mode 100644
index f41fd32..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret;
- void *ctx, *tuple;
- uint32_t tuple_size;
- uint64_t netns, flags;
-
- ret = bpf_sk_lookup_udp (ctx,
- tuple,
- tuple_size,
- netns, flags);
-}
-
-/* { dg-final { scan-assembler "call\t85" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c
deleted file mode 100644
index f449b5b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *map, *key;
- uint64_t flags;
-
- ret = bpf_sk_redirect_hash (skb, map, key, flags);
-}
-
-/* { dg-final { scan-assembler "call\t72" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c
deleted file mode 100644
index 42aab8a..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *map;
- uint32_t key;
- uint64_t flags;
-
- ret = bpf_sk_redirect_map (ctx, map, key, flags);
-}
-
-/* { dg-final { scan-assembler "call\t52" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-release.c b/gcc/testsuite/gcc.target/bpf/helper-sk-release.c
deleted file mode 100644
index b01412c..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-release.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *sock;
-
- ret = bpf_sk_release (sock);
-}
-
-/* { dg-final { scan-assembler "call\t86" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c b/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c
deleted file mode 100644
index b1a2802..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *reuse, *map, *key;
- uint64_t flags;
-
- ret = bpf_sk_select_reuseport (reuse, map,
- key, flags);
-}
-
-/* { dg-final { scan-assembler "call\t82" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c
deleted file mode 100644
index ea36a3d6..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *map, *sk;
-
- ret = bpf_sk_storage_delete (map, sk);
-}
-
-/* { dg-final { scan-assembler "call\t108" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c
deleted file mode 100644
index 1ea0e7b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret;
- void *map, *sk, *value;
- uint64_t flags;
-
- ret = bpf_sk_storage_get (map, sk, value, flags);
-}
-
-/* { dg-final { scan-assembler "call\t107" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c b/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c
deleted file mode 100644
index 3bce73f..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- int32_t len_diff;
- uint32_t mode;
- uint64_t flags;
-
- ret = bpf_skb_adjust_room (skb, len_diff, mode, flags);
-}
-
-/* { dg-final { scan-assembler "call\t50" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c
index 13ccf36..693f390 100644
--- a/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c
@@ -1,8 +1,10 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
+/* { dg-options "-std=gnu99 -O2" } */
#include <stdint.h>
-#include <bpf-helpers.h>
+
+struct __sk_buff;
+static uint64_t (*bpf_skb_ancestor_cgroup_id)(struct __sk_buff *skb, int ancestor_level) = (void *) 83;
void
foo ()
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c
deleted file mode 100644
index 5085c75..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- uint64_t ret;
- void *skb;
-
- ret = bpf_skb_cgroup_id (skb);
-}
-
-/* { dg-final { scan-assembler "call\t79" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c
deleted file mode 100644
index 281104b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t len;
- uint64_t flags;
-
- ret = bpf_skb_change_head (skb, len, flags);
-}
-
-/* { dg-final { scan-assembler "call\t43" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c
deleted file mode 100644
index a41d197..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- int16_t proto;
- uint64_t flags;
-
- ret = bpf_skb_change_proto (skb, proto, flags);
-}
-
-/* { dg-final { scan-assembler "call\t31" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c
deleted file mode 100644
index 2bfc5979..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t len;
- uint64_t flags;
-
- ret = bpf_skb_change_tail (skb, len, flags);
-}
-
-/* { dg-final { scan-assembler "call\t38" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c
deleted file mode 100644
index 46a9421..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t type;
-
- ret = bpf_skb_change_type (skb, type);
-}
-
-/* { dg-final { scan-assembler "call\t32" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c b/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c
deleted file mode 100644
index c028ec1..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
-
- ret = bpf_skb_ecn_set_ce (skb);
-}
-
-/* { dg-final { scan-assembler "call\t97" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c
deleted file mode 100644
index aad8472..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *key;
- uint32_t size;
- uint64_t flags;
-
- ret = bpf_skb_get_tunnel_key (skb, key, size, flags);
-}
-
-/* { dg-final { scan-assembler "call\t20" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c
deleted file mode 100644
index 0b39ad7..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint8_t *opt;
- uint32_t size;
-
- ret = bpf_skb_get_tunnel_opt (skb, opt, size);
-}
-
-/* { dg-final { scan-assembler "call\t29" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c
deleted file mode 100644
index de83d91..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *xfrm_state;
- uint32_t index, size;
- uint64_t flags;
-
- ret = bpf_skb_get_xfrm_state (skb, index,
- xfrm_state, size, flags);
-}
-
-/* { dg-final { scan-assembler "call\t66" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c
deleted file mode 100644
index cd8c2c2..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *to;
- uint32_t offset, len, start_header;
-
- ret = bpf_skb_load_bytes_relative (skb, offset,
- to, len,
- start_header);
-}
-
-/* { dg-final { scan-assembler "call\t68" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c
deleted file mode 100644
index 1e4612a..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *to;
- uint32_t offset, len;
-
- ret = bpf_skb_load_bytes (skb, offset, to, len);
-}
-
-/* { dg-final { scan-assembler "call\t26" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c
deleted file mode 100644
index 579d856..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t len;
-
- ret = bpf_skb_pull_data (skb, len);
-}
-
-/* { dg-final { scan-assembler "call\t39" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c
deleted file mode 100644
index 85754fd..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *key;
- uint32_t size;
- uint64_t flags;
-
- ret = bpf_skb_set_tunnel_key (skb, key, size, flags);
-}
-
-/* { dg-final { scan-assembler "call\t21" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c
deleted file mode 100644
index 591eb48..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint8_t *opt;
- uint32_t size;
-
- ret = bpf_skb_set_tunnel_opt (skb, opt, size);
-}
-
-/* { dg-final { scan-assembler "call\t30" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c
deleted file mode 100644
index 17f8e02..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- uint32_t offset;
- void *from;
- uint32_t len;
- uint64_t flags;
-
- ret = bpf_skb_store_bytes (skb, offset, from, len, flags);
-}
-
-/* { dg-final { scan-assembler "call\t9" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c
deleted file mode 100644
index 72adfcd..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb, *map;
- uint32_t index;
-
- ret = bpf_skb_under_cgroup (skb, map, index);
-}
-
-/* { dg-final { scan-assembler "call\t33" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c
deleted file mode 100644
index 4d5b347..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
-
- ret = bpf_skb_vlan_pop (skb);
-}
-
-/* { dg-final { scan-assembler "call\t19" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c
deleted file mode 100644
index 1a43bd4..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skb;
- int16_t vlan_proto;
- uint16_t vlan_tci;
-
- ret = bpf_skb_vlan_push (skb, vlan_proto, vlan_tci);
-}
-
-/* { dg-final { scan-assembler "call\t18" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c
deleted file mode 100644
index 8ed2d46..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret;
- void *ctx, *tuple;
- uint32_t tuple_size;
- uint64_t netns, flags;
-
- ret = bpf_skc_lookup_tcp (ctx, tuple,
- tuple_size, netns, flags);
-}
-
-/* { dg-final { scan-assembler "call\t99" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c
deleted file mode 100644
index 81ff4dd..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skops, *map, *key;
- uint64_t flags;
-
- ret = bpf_sock_hash_update (skops, map, key,
- flags);
-}
-
-/* { dg-final { scan-assembler "call\t70" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c
deleted file mode 100644
index b263583..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *skops, *map, *key;
- uint64_t flags;
-
- ret = bpf_sock_map_update (skops, map, key, flags);
-}
-
-/* { dg-final { scan-assembler "call\t53" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c b/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c
deleted file mode 100644
index 7a98fa9..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *bpf_sock;
- int argval;
-
- ret = bpf_sock_ops_cb_flags_set (bpf_sock, argval);
-}
-
-/* { dg-final { scan-assembler "call\t59" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c
deleted file mode 100644
index 8358e88f..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *lock;
-
- bpf_spin_lock (lock);
-}
-
-/* { dg-final { scan-assembler "call\t93" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c
deleted file mode 100644
index 400695f..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *lock;
-
- bpf_spin_unlock (lock);
-}
-
-/* { dg-final { scan-assembler "call\t94" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtol.c b/gcc/testsuite/gcc.target/bpf/helper-strtol.c
deleted file mode 100644
index d98a0a7..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-strtol.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *buf;
- long res;
- uint64_t flags;
- size_t buf_len;
-
- ret = bpf_strtol (buf, buf_len, flags, &res);
-}
-
-/* { dg-final { scan-assembler "call\t105" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtoul.c b/gcc/testsuite/gcc.target/bpf/helper-strtoul.c
deleted file mode 100644
index f68abf2..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-strtoul.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *buf;
- unsigned long res;
- uint64_t flags;
- size_t buf_len;
-
- ret = bpf_strtoul (buf, buf_len, flags, &res);
-}
-
-/* { dg-final { scan-assembler "call\t106" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c
deleted file mode 100644
index a1f6529..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *buf;
- size_t buf_len;
-
- ret = bpf_sysctl_get_current_value (ctx, buf, buf_len);
-}
-
-/* { dg-final { scan-assembler "call\t102" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c
deleted file mode 100644
index ca9c42b..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *buf;
- size_t buf_len;
- uint64_t flags;
-
- ret = bpf_sysctl_get_name (ctx, buf, buf_len, flags);
-}
-
-/* { dg-final { scan-assembler "call\t101" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c
deleted file mode 100644
index d22b214..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *buf;
- size_t buf_len;
-
- ret = bpf_sysctl_get_new_value (ctx, buf, buf_len);
-}
-
-/* { dg-final { scan-assembler "call\t103" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c
deleted file mode 100644
index 78004c2..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *buf;
- size_t buf_len;
-
- ret = bpf_sysctl_set_new_value (ctx, buf, buf_len);
-}
-
-/* { dg-final { scan-assembler "call\t104" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-tail-call.c b/gcc/testsuite/gcc.target/bpf/helper-tail-call.c
deleted file mode 100644
index 0f35b00..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-tail-call.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *ctx, *prog_array_map;
- uint32_t index;
-
- ret = bpf_tail_call (ctx, prog_array_map, index);
-}
-
-/* { dg-final { scan-assembler "call\t12" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c
deleted file mode 100644
index 06210bb..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *sk, *iph, *th;
- uint32_t iph_len, th_len;
-
- ret = bpf_tcp_check_syncookie (sk, iph,
- iph_len,
- th, th_len);
-}
-
-/* { dg-final { scan-assembler "call\t100" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c
deleted file mode 100644
index cd6d995..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- void *ret, *sk;
-
- ret = bpf_tcp_sock (sk);
-}
-
-/* { dg-final { scan-assembler "call\t96" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c b/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c
deleted file mode 100644
index 135ae29..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <bpf-helpers.h>
-
-char *map () { return 0; }
-
-void
-foo ()
-{
- int ret;
-
- ret = bpf_trace_printk ("foo %d %d", sizeof ("foo %d %d"), 10, 20);
-}
-
-/* { dg-final { scan-assembler "call\t6" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c
deleted file mode 100644
index ac6fef4..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *xdp_md;
- int delta;
-
- ret = bpf_xdp_adjust_head (xdp_md, delta);
-}
-
-/* { dg-final { scan-assembler "call\t44" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c
deleted file mode 100644
index 1379350..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *xdp_md;
- int delta;
-
- ret = bpf_xdp_adjust_meta (xdp_md, delta);
-}
-
-/* { dg-final { scan-assembler "call\t54" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c
deleted file mode 100644
index db55168..0000000
--- a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-
-#include <stdint.h>
-#include <bpf-helpers.h>
-
-void
-foo ()
-{
- int ret;
- void *xdp_md;
- int delta;
-
- ret = bpf_xdp_adjust_tail (xdp_md, delta);
-}
-
-/* { dg-final { scan-assembler "call\t65" } } */
diff --git a/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c b/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c
index 5f732d3..ffcb8fc 100644
--- a/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c
+++ b/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-mapxf -m64 -O2 -mgeneral-regs-only -mno-cld -mno-push-args -maccumulate-outgoing-args" } */
+/* { dg-options "-mapx-features=egpr -m64 -O2 -mgeneral-regs-only -mno-cld -mno-push-args -maccumulate-outgoing-args" } */
/* { dg-skip-if "does not emit .cfi_xxx" "*-*-darwin*" } */
extern void foo (void *) __attribute__ ((interrupt));
diff --git a/gcc/testsuite/gcc.target/i386/apx-ppx-1.c b/gcc/testsuite/gcc.target/i386/apx-ppx-1.c
new file mode 100644
index 0000000..e9a5953
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/apx-ppx-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mapx-features=egpr,push2pop2,ppx" } */
+
+#include "apx-push2pop2-1.c"
+
+/* { dg-final { scan-assembler "pushp" } } */
+/* { dg-final { scan-assembler "popp" } } */
+/* { dg-final { scan-assembler "push2p" } } */
+/* { dg-final { scan-assembler "pop2p" } } */
diff --git a/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c b/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c
index 089941d..d78c96d 100644
--- a/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c
+++ b/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-O2 -mapxf" } */
+/* { dg-options "-O2 -mapx-features=push2pop2" } */
/* { dg-skip-if "does not emit .cfi_xxx" "*-*-darwin*" } */
extern int bar (int);
@@ -24,11 +24,11 @@ void foo ()
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 16" 2 } } */
/* { dg-final { scan-assembler-times "pushq\[^\n\r]*%r15(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 15, -16(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%r14\[^\n\r]*%r13\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%r13\[^\n\r]*%r14\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 32" 2 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 14, -24(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 13, -32(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%r12\[^\n\r]*%rbp\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%rbp\[^\n\r]*%r12\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 48" 2 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 12, -40(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 6, -48(?:\n|\[ \\t\]+#)" 1 } } */
@@ -36,10 +36,10 @@ void foo ()
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 56" 2 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 3, -56(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "popq\[^\n\r]*rbx(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%rbp\[^\n\r]*%r12\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%r12\[^\n\r]*%rbp\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 12(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 6(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%r13\[^\n\r]*%r14\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%r14\[^\n\r]*%r13\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 14(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 13(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "popq\[^\n\r]*%r15(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/apx-push2pop2_force_drap-1.c b/gcc/testsuite/gcc.target/i386/apx-push2pop2_force_drap-1.c
index 656ca91..3cac7b1 100644
--- a/gcc/testsuite/gcc.target/i386/apx-push2pop2_force_drap-1.c
+++ b/gcc/testsuite/gcc.target/i386/apx-push2pop2_force_drap-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-O2 -mapxf -mforce-drap" } */
+/* { dg-options "-O2 -mapx-features=push2pop2 -mforce-drap" } */
/* { dg-skip-if "does not emit .cfi_xxx" "*-*-darwin*" } */
#include "apx-push2pop2-1.c"
@@ -8,11 +8,11 @@
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 16" 2 } } */
/* { dg-final { scan-assembler-times "pushq\[^\n\r]*%r15(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 15, -16(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%r14\[^\n\r]*%r13\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%r13\[^\n\r]*%r14\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 32" 2 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 14, -24(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 13, -32(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%r12\[^\n\r]*%rbp\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "push2\[\\t \]*\[^\n\r]*%rbp\[^\n\r]*%r12\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 48" 2 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 12, -40(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 6, -48(?:\n|\[ \\t\]+#)" 1 } } */
@@ -20,10 +20,10 @@
/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 56" 2 } } */
/* { dg-final { scan-assembler-times ".cfi_offset 3, -56(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "popq\[^\n\r]*rbx(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%rbp\[^\n\r]*%r12\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%r12\[^\n\r]*%rbp\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 12(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 6(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%r13\[^\n\r]*%r14\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "pop2\[\\t \]*\[^\n\r]*%r14\[^\n\r]*%r13\[^\n\r]*(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 14(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times ".cfi_restore 13(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "popq\[^\n\r]*%r15(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/apx-push2pop2_interrupt-1.c b/gcc/testsuite/gcc.target/i386/apx-push2pop2_interrupt-1.c
index 747f7aa..a5b4689 100644
--- a/gcc/testsuite/gcc.target/i386/apx-push2pop2_interrupt-1.c
+++ b/gcc/testsuite/gcc.target/i386/apx-push2pop2_interrupt-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-O2 -mapxf -mgeneral-regs-only -mno-cld -mno-push-args -maccumulate-outgoing-args" } */
+/* { dg-options "-O2 -mapx-features=egpr,push2pop2 -mgeneral-regs-only -mno-cld -mno-push-args -maccumulate-outgoing-args" } */
extern void foo (void *) __attribute__ ((interrupt));
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-1.c b/gcc/testsuite/gcc.target/i386/avx10_1-1.c
new file mode 100644
index 0000000..cfd9662
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -march=x86-64 -mavx10.1" } */
+
+#include <immintrin.h>
+
+void
+f1 ()
+{
+ register __m256d a __asm ("ymm17");
+ register __m256d b __asm ("ymm16");
+ a = _mm256_add_pd (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 ()
+{
+ register __m128d a __asm ("xmm17");
+ register __m128d b __asm ("xmm16");
+ a = _mm_add_pd (a, b);
+ asm volatile ("" : "+v" (a));
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-10.c b/gcc/testsuite/gcc.target/i386/avx10_1-10.c
new file mode 100644
index 0000000..0db5240
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-10.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1-512 -mavx512f -mno-evex512" } */
+/* { dg-warning "'-mno-evex512' or '-mno-avx512XXX' cannot disable AVX10 instructions when AVX10.1-512 is available" "" { target *-*-* } 0 } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+#include "avx10_1-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-11.c b/gcc/testsuite/gcc.target/i386/avx10_1-11.c
new file mode 100644
index 0000000..c0ad4fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-11.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1-512 -mno-avx512f" } */
+/* { dg-warning "'-mno-evex512' or '-mno-avx512XXX' cannot disable AVX10 instructions when AVX10.1-512 is available" "" { target *-*-* } 0 } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+#include "avx10_1-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-12.c b/gcc/testsuite/gcc.target/i386/avx10_1-12.c
new file mode 100644
index 0000000..61f0e4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-12.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mno-avx10.1-512 -mavx512f" } */
+/* { dg-warning "'-mno-avx10.1, -mno-avx10.1-256, -mno-avx10.1-512' cannot disable AVX512 instructions when '-mavx512XXX'" "" { target *-*-* } 0 } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+#include "avx10_1-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-13.c b/gcc/testsuite/gcc.target/i386/avx10_1-13.c
new file mode 100644
index 0000000..8a11119
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-13.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("avx512f"))) __m512d
+foo ()
+{ /* { dg-warning "Vector size conflicts between AVX10.1 and AVX512, using 512 as max vector size" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-14.c b/gcc/testsuite/gcc.target/i386/avx10_1-14.c
new file mode 100644
index 0000000..03222a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-14.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx512f" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("avx10.1"))) __m512d
+foo ()
+{ /* { dg-warning "Vector size conflicts between AVX10.1 and AVX512, using 512 as max vector size" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-15.c b/gcc/testsuite/gcc.target/i386/avx10_1-15.c
new file mode 100644
index 0000000..d1731f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-15.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1-512" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("avx512f,no-evex512"))) __m512d
+foo ()
+{ /* { dg-warning "'-mno-evex512' or '-mno-avx512XXX' cannot disable AVX10 instructions when AVX10.1-512 is available" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-16.c b/gcc/testsuite/gcc.target/i386/avx10_1-16.c
new file mode 100644
index 0000000..f5f3ff8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-16.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx512f -mno-evex512" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("avx10.1-512"))) __m512d
+foo ()
+{ /* { dg-warning "'-mno-evex512' or '-mno-avx512XXX' cannot disable AVX10 instructions when AVX10.1-512 is available" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-17.c b/gcc/testsuite/gcc.target/i386/avx10_1-17.c
new file mode 100644
index 0000000..a19230f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-17.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx512f" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("no-avx10.1"))) __m512d
+foo ()
+{ /* { dg-warning "'-mno-avx10.1, -mno-avx10.1-256, -mno-avx10.1-512' cannot disable AVX512 instructions when '-mavx512XXX'" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-18.c b/gcc/testsuite/gcc.target/i386/avx10_1-18.c
new file mode 100644
index 0000000..c50fd2b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-18.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1-512" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("no-avx512f"))) __m512d
+foo ()
+{ /* { dg-warning "'-mno-evex512' or '-mno-avx512XXX' cannot disable AVX10 instructions when AVX10.1-512 is available" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-19.c b/gcc/testsuite/gcc.target/i386/avx10_1-19.c
new file mode 100644
index 0000000..7aacc15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-19.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mno-avx10.1-512" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("avx512f"))) __m512d
+foo ()
+{ /* { dg-warning "'-mno-avx10.1, -mno-avx10.1-256, -mno-avx10.1-512' cannot disable AVX512 instructions when '-mavx512XXX'" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-2.c b/gcc/testsuite/gcc.target/i386/avx10_1-2.c
new file mode 100644
index 0000000..0b3991d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1-512" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__m512d
+foo ()
+{
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-20.c b/gcc/testsuite/gcc.target/i386/avx10_1-20.c
new file mode 100644
index 0000000..d63c6b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-20.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mno-avx512f" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("avx10.1-512"))) __m512d
+foo ()
+{ /* { dg-warning "'-mno-evex512' or '-mno-avx512XXX' cannot disable AVX10 instructions when AVX10.1-512 is available" } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-21.c b/gcc/testsuite/gcc.target/i386/avx10_1-21.c
new file mode 100644
index 0000000..27a7265
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-21.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1 -mevex512 -Wno-psabi" } */
+/* { dg-warning "Using '-mevex512' without any AVX512 features enabled together with AVX10.1 only will not enable any AVX512 or AVX10.1-512 features, using 256 as max vector size" "" { target *-*-* } 0 } */
+/* { dg-final { scan-assembler-not "%zmm" } } */
+
+#include "avx10_1-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-22.c b/gcc/testsuite/gcc.target/i386/avx10_1-22.c
new file mode 100644
index 0000000..7962622
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-22.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1 -Wno-psabi" } */
+/* { dg-final { scan-assembler-not "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("evex512"))) __m512d
+foo ()
+{ /* { dg-warning "Using '-mevex512' without any AVX512 features enabled together with AVX10.1 only will not enable any AVX512 or AVX10.1-512 features, using 256 as max vector size" "" { target *-*-* } 0 } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-23.c b/gcc/testsuite/gcc.target/i386/avx10_1-23.c
new file mode 100644
index 0000000..6e8d64d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-23.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mevex512 -Wno-psabi" } */
+/* { dg-final { scan-assembler-not "%zmm" } } */
+
+typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__attribute__ ((target ("avx10.1"))) __m512d
+foo ()
+{ /* { dg-warning "Using '-mevex512' without any AVX512 features enabled together with AVX10.1 only will not enable any AVX512 or AVX10.1-512 features, using 256 as max vector size" "" { target *-*-* } 0 } */
+ __m512d a, b;
+ a = a + b;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-3.c b/gcc/testsuite/gcc.target/i386/avx10_1-3.c
new file mode 100644
index 0000000..3be988a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64 -mavx10.1" } */
+
+#include <immintrin.h>
+
+int
+foo (int c)
+{
+ register int a __asm ("k7") = c;
+ int b = foo (a);
+ asm volatile ("" : "+k" (b));
+ return b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-4.c b/gcc/testsuite/gcc.target/i386/avx10_1-4.c
new file mode 100644
index 0000000..68cbf19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64 -mavx10.1-512" } */
+
+#include <immintrin.h>
+
+long long
+foo (long long c)
+{
+ register long long a __asm ("k7") = c;
+ long long b = foo (a);
+ asm volatile ("" : "+k" (b));
+ return b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-5.c b/gcc/testsuite/gcc.target/i386/avx10_1-5.c
new file mode 100644
index 0000000..20b78ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-5.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -march=x86-64 -mavx10.1 -Wno-psabi" } */
+/* { dg-final { scan-assembler-not ".%zmm" } } */
+
+#include "avx10_1-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-6.c b/gcc/testsuite/gcc.target/i386/avx10_1-6.c
new file mode 100644
index 0000000..827c80c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-6.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64 -mavx10.1" } */
+
+#include <immintrin.h>
+
+long long
+foo (long long c)
+{
+ register long long a __asm ("k7") = c;
+ long long b = foo (a);
+ asm volatile ("" : "+k" (b)); /* { dg-error "inconsistent operand constraints in an 'asm'" } */
+ return b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-7.c b/gcc/testsuite/gcc.target/i386/avx10_1-7.c
new file mode 100644
index 0000000..afce290
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-7.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1-512 -mavx512f" } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+#include "avx10_1-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-8.c b/gcc/testsuite/gcc.target/i386/avx10_1-8.c
new file mode 100644
index 0000000..69b6c6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-8.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-march=x86-64 -mavx10.1 -mavx512f -mno-evex512" } */
+
+#include "avx10_1-1.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx10_1-9.c b/gcc/testsuite/gcc.target/i386/avx10_1-9.c
new file mode 100644
index 0000000..8e83827
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx10_1-9.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64 -mavx10.1-256 -mavx512f" } */
+/* { dg-warning "Vector size conflicts between AVX10.1 and AVX512, using 512 as max vector size" "" { target *-*-* } 0 } */
+/* { dg-final { scan-assembler "%zmm" } } */
+
+#include "avx10_1-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/bmi2-pr112518.c b/gcc/testsuite/gcc.target/i386/bmi2-pr112518.c
new file mode 100644
index 0000000..6aea13f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bmi2-pr112518.c
@@ -0,0 +1,25 @@
+/* PR target/112518 */
+/* { dg-do run { target { bmi2 && int128 } } } */
+/* { dg-options "-Os -mbmi2" } */
+
+#include "bmi2-check.h"
+
+unsigned u;
+int g;
+
+unsigned long long
+foo (int i)
+{
+ unsigned long long x = u;
+ g = __builtin_mul_overflow_p (u, ((unsigned __int128) 4292468825) << 64 | 150, 0);
+ x |= g % i;
+ return x;
+}
+
+static __attribute__((noipa)) void
+bmi2_test ()
+{
+ unsigned long long x = foo (3);
+ if (x)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/cf_check-6.c b/gcc/testsuite/gcc.target/i386/cf_check-6.c
new file mode 100644
index 0000000..71ebdd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cf_check-6.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-O2 -fhardened -mno-manual-endbr" } */
+/* { dg-final { scan-assembler-times {\mendbr} 1 } } */
+/* Test that -fhardened enables CET. */
+
+extern void bar (void) __attribute__((__cf_check__));
+
+void
+foo (void)
+{
+ bar ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112325-1.c b/gcc/testsuite/gcc.target/i386/pr112325-1.c
new file mode 100644
index 0000000..56e20c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112325-1.c
@@ -0,0 +1,116 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512vl -mavx512bw -O2 -mtune=generic -mprefer-vector-width=512 -fdump-tree-slp2" } */
+/* { dg-final { scan-tree-dump-times ".REDUC_PLUS" 3 "slp2" } } */
+/* { dg-final { scan-tree-dump-times ".REDUC_IOR" 4 "slp2" } } */
+
+int
+__attribute__((noipa))
+plus_v4si (int* a)
+{
+ int sum = 0;
+ sum += a[0];
+ sum += a[1];
+ sum += a[2];
+ sum += a[3];
+ return sum;
+}
+
+short
+__attribute__((noipa))
+plus_v8hi (short* a)
+{
+ short sum = 0;
+ sum += a[0];
+ sum += a[1];
+ sum += a[2];
+ sum += a[3];
+ sum += a[4];
+ sum += a[5];
+ sum += a[6];
+ sum += a[7];
+ return sum;
+}
+
+long long
+__attribute__((noipa))
+plus_v8di (long long* a)
+{
+ long long sum = 0;
+ sum += a[0];
+ sum += a[1];
+ sum += a[2];
+ sum += a[3];
+ sum += a[4];
+ sum += a[5];
+ sum += a[6];
+ sum += a[7];
+ return sum;
+}
+
+int
+__attribute__((noipa))
+ior_v4si (int* a)
+{
+ int sum = 0;
+ sum |= a[0];
+ sum |= a[1];
+ sum |= a[2];
+ sum |= a[3];
+ return sum;
+}
+
+short
+__attribute__((noipa))
+ior_v8hi (short* a)
+{
+ short sum = 0;
+ sum |= a[0];
+ sum |= a[1];
+ sum |= a[2];
+ sum |= a[3];
+ sum |= a[4];
+ sum |= a[5];
+ sum |= a[6];
+ sum |= a[7];
+ return sum;
+}
+
+long long
+__attribute__((noipa))
+ior_v8di (long long* a)
+{
+ long long sum = 0;
+ sum |= a[0];
+ sum |= a[1];
+ sum |= a[2];
+ sum |= a[3];
+ sum |= a[4];
+ sum |= a[5];
+ sum |= a[6];
+ sum |= a[7];
+ return sum;
+}
+
+char
+__attribute__((noipa))
+ior_v16qi (char* a)
+{
+ char sum = 0;
+ sum |= a[0];
+ sum |= a[1];
+ sum |= a[2];
+ sum |= a[3];
+ sum |= a[4];
+ sum |= a[5];
+ sum |= a[6];
+ sum |= a[7];
+ sum |= a[8];
+ sum |= a[9];
+ sum |= a[10];
+ sum |= a[11];
+ sum |= a[12];
+ sum |= a[13];
+ sum |= a[14];
+ sum |= a[15];
+ return sum;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112325-2.c b/gcc/testsuite/gcc.target/i386/pr112325-2.c
new file mode 100644
index 0000000..650006b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112325-2.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-require-effective-target sse2 } */
+
+#include "sse2-check.h"
+#include "pr112325-1.c"
+
+static void
+sse2_test (void)
+{
+ int d[4] = { 3, 11, 22, 89};
+ short w[8] = { 3, 11, 22, 89, 4, 9, 13, 7};
+ char b[16] = { 3, 11, 22, 89, 4, 9, 13, 7, 2, 6, 5, 111, 163, 88, 11, 235};
+ long long q[8] = { 3, 11, 22, 89, 4, 9, 13, 7};
+
+ /* if (plus_v4si (d) != 125) */
+ /* __builtin_abort (); */
+
+ /* if (plus_v8hi (w) != 158) */
+ /* __builtin_abort (); */
+
+ /* if (plus_v8di (q) != 158) */
+ /* __builtin_abort (); */
+
+ /* if (ior_v4si (d) != 95) */
+ /* __builtin_abort (); */
+
+ /* if (ior_v8hi (w) != 95) */
+ /* __builtin_abort (); */
+
+ /* if (ior_v16qi (b) != (char)255) */
+ /* __builtin_abort (); */
+
+ if (ior_v8di (q) != 95)
+ __builtin_abort ();
+
+ return;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112325-mmx-1.c b/gcc/testsuite/gcc.target/i386/pr112325-mmx-1.c
new file mode 100644
index 0000000..887249f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112325-mmx-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-msse2 -O2 -fdump-tree-slp2" } */
+/* { dg-final { scan-tree-dump-times ".REDUC_IOR" 3 "slp2" } } */
+
+short
+foo1 (short* a)
+{
+ short sum = 0;
+ sum |= a[0];
+ sum |= a[1];
+ sum |= a[2];
+ sum |= a[3];
+ return sum;
+}
+
+char
+foo2 (char* a)
+{
+ char sum = 0;
+ sum |= a[0];
+ sum |= a[1];
+ sum |= a[2];
+ sum |= a[3];
+ sum |= a[4];
+ sum |= a[5];
+ sum |= a[6];
+ sum |= a[7];
+ return sum;
+}
+
+char
+foo3 (char* a)
+{
+ char sum = 0;
+ sum |= a[0];
+ sum |= a[1];
+ sum |= a[2];
+ sum |= a[3];
+ return sum;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112605-1.c b/gcc/testsuite/gcc.target/i386/pr112605-1.c
new file mode 100644
index 0000000..57b9190
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112605-1.c
@@ -0,0 +1,7 @@
+/* PR target/112605 */
+/* { dg-do compile } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-fsplit-stack -fpic -mforce-indirect-call" } */
+
+#include "pr112605.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr112605-2.c b/gcc/testsuite/gcc.target/i386/pr112605-2.c
new file mode 100644
index 0000000..7db9aba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112605-2.c
@@ -0,0 +1,7 @@
+/* PR target/112605 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-fsplit-stack -fpic -mcmodel=large -mforce-indirect-call " } */
+
+#include "pr112605.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr112605.c b/gcc/testsuite/gcc.target/i386/pr112605.c
new file mode 100644
index 0000000..da50a0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112605.c
@@ -0,0 +1,24 @@
+/* PR target/112605 */
+/* { dg-do compile } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-options "-fsplit-stack -mforce-indirect-call" } */
+
+int x;
+int y;
+
+void __attribute__((noinline)) f1(void)
+{
+ x++;
+}
+
+static __attribute__((noinline)) void f3(void)
+{
+ y++;
+}
+
+void f2()
+{
+ f1();
+ f3();
+ f1();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112623.c b/gcc/testsuite/gcc.target/i386/pr112623.c
new file mode 100644
index 0000000..c4ebace
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112623.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mavx512vl -mavx512fp16" } */
+
+typedef __bf16 __attribute__((__vector_size__ (16))) BF;
+typedef float __attribute__((__vector_size__ (32))) F;
+
+BF
+foo (F f)
+{
+ return __builtin_convertvector (f, BF);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112672.c b/gcc/testsuite/gcc.target/i386/pr112672.c
new file mode 100644
index 0000000..583e9fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112672.c
@@ -0,0 +1,23 @@
+/* PR target/112672 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+typedef unsigned short u16;
+
+u16 g = 254;
+
+static inline u16
+foo (u16 u)
+{
+ u *= g;
+ return u + __builtin_parityl (u);
+}
+
+int
+main (void)
+{
+ u16 x = foo (4);
+ if (x != 4 * 254 + 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112686.c b/gcc/testsuite/gcc.target/i386/pr112686.c
new file mode 100644
index 0000000..4f452d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112686.c
@@ -0,0 +1,6 @@
+/* PR target/112686 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-options "-fsplit-stack -mcmodel=large" } */
+
+void foo (void) {}
diff --git a/gcc/testsuite/gcc.target/i386/pr90693.c b/gcc/testsuite/gcc.target/i386/pr90693.c
new file mode 100644
index 0000000..1659f26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90693.c
@@ -0,0 +1,29 @@
+/* PR tree-optimization/90693 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-abm -mno-popcnt -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "POPCOUNT \\\(" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "__builtin_popcount(ll)? \\\(" "optimized" } } */
+
+int
+foo (unsigned int x)
+{
+ return __builtin_popcount (x) == 1;
+}
+
+int
+bar (unsigned int x)
+{
+ return (x ^ (x - 1)) > x - 1;
+}
+
+int
+baz (unsigned long long x)
+{
+ return __builtin_popcountll (x) == 1;
+}
+
+int
+qux (unsigned long long x)
+{
+ return (x ^ (x - 1)) > x - 1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4-pr112681.c b/gcc/testsuite/gcc.target/i386/sse4-pr112681.c
new file mode 100644
index 0000000..6c91087
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse4-pr112681.c
@@ -0,0 +1,11 @@
+/* PR target/112681 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4 -mno-avx" } */
+
+struct S { void *c; char d[16]; } a, b;
+
+int
+foo (void)
+{
+ return __builtin_memcmp (a.d, b.d, sizeof (a.d)) != 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c
index 8bc3f4a..5d19dcb 100644
--- a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c
+++ b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c
@@ -123,12 +123,12 @@ __m128bf16 footest (__m128bf16 vector0)
(void) glob_bfloat_vec;
(__m128bf16) glob_bfloat_vec;
- (__bf16) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (__bf16) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type '__m128bf16' {aka '__vector\(8\) __bf16'} to type 'short int' which has different size} } */
(int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type '__m128bf16' {aka '__vector\(8\) __bf16'} to type 'int' which has different size} } */
- (_Float16) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (_Float16) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (float) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (double) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(__v8si) glob_bfloat_vec; /* { dg-error {cannot convert a value of type '__m128bf16' {aka '__vector\(8\) __bf16'} to vector type '__vector\(8\) int' which has different size} } */
(__m256) glob_bfloat_vec; /* { dg-error {cannot convert a value of type '__m128bf16' {aka '__vector\(8\) __bf16'} to vector type '__vector\(8\) float' which has different size} } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c
index 2a8a535..d4e6fc8 100644
--- a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c
+++ b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c
@@ -116,12 +116,12 @@ __m256bf16 footest (__m256bf16 vector0)
(void) glob_bfloat_vec;
(__m256bf16) glob_bfloat_vec;
- (__bf16) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (__bf16) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type '__m256bf16' {aka '__vector\(16\) __bf16'} to type 'short int' which has different size} } */
(int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type '__m256bf16' {aka '__vector\(16\) __bf16'} to type 'int' which has different size} } */
- (_Float16) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
- (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+ (_Float16) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (float) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
+ (double) glob_bfloat_vec; /* { dg-error {vector value used where a floating-point was expected} } */
(__v8si) glob_bfloat_vec;
(__m256) glob_bfloat_vec;
diff --git a/gcc/testsuite/gcc.target/loongarch/imm-load1.c b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
index 2ff0297..f64cc29 100644
--- a/gcc/testsuite/gcc.target/loongarch/imm-load1.c
+++ b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-mabi=lp64d -O2" } */
-/* { dg-final { scan-assembler "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */
+/* { dg-final { scan-assembler-not "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */
+/* { dg-final { scan-assembler "test:.*lu12i\.w.*\n\tbstrins\.d.*\n\.L2:" } } */
extern long long b[10];
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-shuf-fp.c b/gcc/testsuite/gcc.target/loongarch/vect-shuf-fp.c
new file mode 100644
index 0000000..7acc211
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vect-shuf-fp.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mlasx -O3" } */
+/* { dg-final { scan-assembler "vshuf\.w" } } */
+
+#define V __attribute__ ((vector_size (16)))
+
+int a V;
+float b V;
+float c V;
+float d V;
+
+void
+test (void)
+{
+ d = __builtin_shuffle (b, c, a);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/adddibeq.c b/gcc/testsuite/gcc.target/riscv/adddibeq.c
new file mode 100644
index 0000000..624c56e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibfeq.c b/gcc/testsuite/gcc.target/riscv/adddibfeq.c
new file mode 100644
index 0000000..403200f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibfeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibfge.c b/gcc/testsuite/gcc.target/riscv/adddibfge.c
new file mode 100644
index 0000000..82fce9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibfge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibfgt.c b/gcc/testsuite/gcc.target/riscv/adddibfgt.c
new file mode 100644
index 0000000..0263154
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibfgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibfle.c b/gcc/testsuite/gcc.target/riscv/adddibfle.c
new file mode 100644
index 0000000..6fd65f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibfle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibflt.c b/gcc/testsuite/gcc.target/riscv/adddibflt.c
new file mode 100644
index 0000000..bfee522
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibfne.c b/gcc/testsuite/gcc.target/riscv/adddibfne.c
new file mode 100644
index 0000000..73ade4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibfne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a5,fa0,fa1
+ bne a5,zero,.L2
+ add a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibge.c b/gcc/testsuite/gcc.target/riscv/adddibge.c
new file mode 100644
index 0000000..017b69f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibgeu.c b/gcc/testsuite/gcc.target/riscv/adddibgeu.c
new file mode 100644
index 0000000..ed17898
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibgt.c b/gcc/testsuite/gcc.target/riscv/adddibgt.c
new file mode 100644
index 0000000..201852f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibgtu.c b/gcc/testsuite/gcc.target/riscv/adddibgtu.c
new file mode 100644
index 0000000..60850c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddible.c b/gcc/testsuite/gcc.target/riscv/adddible.c
new file mode 100644
index 0000000..5bed30c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibleu.c b/gcc/testsuite/gcc.target/riscv/adddibleu.c
new file mode 100644
index 0000000..3d16d09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddiblt.c b/gcc/testsuite/gcc.target/riscv/adddiblt.c
new file mode 100644
index 0000000..8ab979d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibltu.c b/gcc/testsuite/gcc.target/riscv/adddibltu.c
new file mode 100644
index 0000000..858e70f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ add a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddibne.c b/gcc/testsuite/gcc.target/riscv/adddibne.c
new file mode 100644
index 0000000..e5dfee5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ add a0,a2,a3
+ ret
+.L3:
+ mv a0,a2
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddieq.c b/gcc/testsuite/gcc.target/riscv/adddieq.c
new file mode 100644
index 0000000..6195bf5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddieq.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ seqz a1,a1
+ neg a1,a1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddifeq.c b/gcc/testsuite/gcc.target/riscv/adddifeq.c
new file mode 100644
index 0000000..07c3f66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddifeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ neg a5,a5
+ and a5,a5,a1
+ add a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddifge.c b/gcc/testsuite/gcc.target/riscv/adddifge.c
new file mode 100644
index 0000000..7c4307c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddifge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ neg a5,a5
+ and a5,a5,a1
+ add a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddifgt.c b/gcc/testsuite/gcc.target/riscv/adddifgt.c
new file mode 100644
index 0000000..f4774c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddifgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ neg a5,a5
+ and a5,a5,a1
+ add a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddifle.c b/gcc/testsuite/gcc.target/riscv/adddifle.c
new file mode 100644
index 0000000..20a2736
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddifle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ neg a5,a5
+ and a5,a5,a1
+ add a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddiflt.c b/gcc/testsuite/gcc.target/riscv/adddiflt.c
new file mode 100644
index 0000000..18221f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddiflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ neg a5,a5
+ and a5,a5,a1
+ add a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddifne.c b/gcc/testsuite/gcc.target/riscv/adddifne.c
new file mode 100644
index 0000000..58fcb40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddifne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ addi a5,a5,-1
+ and a5,a5,a1
+ add a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddige.c b/gcc/testsuite/gcc.target/riscv/adddige.c
new file mode 100644
index 0000000..85e4224
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddige.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ addi a1,a1,-1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddigeu.c b/gcc/testsuite/gcc.target/riscv/adddigeu.c
new file mode 100644
index 0000000..f96714b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddigeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ addi a1,a1,-1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddigt.c b/gcc/testsuite/gcc.target/riscv/adddigt.c
new file mode 100644
index 0000000..047cbd4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddigt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ neg a1,a1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddigtu.c b/gcc/testsuite/gcc.target/riscv/adddigtu.c
new file mode 100644
index 0000000..10126369a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddigtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ neg a1,a1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddile.c b/gcc/testsuite/gcc.target/riscv/adddile.c
new file mode 100644
index 0000000..e69b195
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddile.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ addi a1,a1,-1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddileu.c b/gcc/testsuite/gcc.target/riscv/adddileu.c
new file mode 100644
index 0000000..1e3bbd8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddileu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ addi a1,a1,-1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddilt.c b/gcc/testsuite/gcc.target/riscv/adddilt.c
new file mode 100644
index 0000000..647263a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddilt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ neg a1,a1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddiltu.c b/gcc/testsuite/gcc.target/riscv/adddiltu.c
new file mode 100644
index 0000000..4a511b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddiltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ neg a1,a1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/adddine.c b/gcc/testsuite/gcc.target/riscv/adddine.c
new file mode 100644
index 0000000..00ff875
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/adddine.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ snez a1,a1
+ neg a1,a1
+ and a1,a1,a3
+ add a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibeq.c b/gcc/testsuite/gcc.target/riscv/addsibeq.c
new file mode 100644
index 0000000..c1e810d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ addw a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sub|subw)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibfeq.c b/gcc/testsuite/gcc.target/riscv/addsibfeq.c
new file mode 100644
index 0000000..27d13a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibfeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add[w] a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibfge.c b/gcc/testsuite/gcc.target/riscv/addsibfge.c
new file mode 100644
index 0000000..501f756
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibfge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add[w] a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibfgt.c b/gcc/testsuite/gcc.target/riscv/addsibfgt.c
new file mode 100644
index 0000000..fff809b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibfgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a5,fa0,fa1
+ beq a5,zero,.L2
+ add[w] a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibfle.c b/gcc/testsuite/gcc.target/riscv/addsibfle.c
new file mode 100644
index 0000000..abcad61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibfle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a5,fa0,fa1
+ beq a5,zero,.L2
+ addw a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibflt.c b/gcc/testsuite/gcc.target/riscv/addsibflt.c
new file mode 100644
index 0000000..2a82c28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a5,fa0,fa1
+ beq a5,zero,.L2
+ addw a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibfne.c b/gcc/testsuite/gcc.target/riscv/addsibfne.c
new file mode 100644
index 0000000..94da071
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibfne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a5,fa0,fa1
+ bne a5,zero,.L2
+ add[w] a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibge.c b/gcc/testsuite/gcc.target/riscv/addsibge.c
new file mode 100644
index 0000000..3f67d16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibgeu.c b/gcc/testsuite/gcc.target/riscv/addsibgeu.c
new file mode 100644
index 0000000..b6df531
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibgt.c b/gcc/testsuite/gcc.target/riscv/addsibgt.c
new file mode 100644
index 0000000..86fcd6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibgtu.c b/gcc/testsuite/gcc.target/riscv/addsibgtu.c
new file mode 100644
index 0000000..63ebe65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsible.c b/gcc/testsuite/gcc.target/riscv/addsible.c
new file mode 100644
index 0000000..164d9c0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibleu.c b/gcc/testsuite/gcc.target/riscv/addsibleu.c
new file mode 100644
index 0000000..b02170b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsiblt.c b/gcc/testsuite/gcc.target/riscv/addsiblt.c
new file mode 100644
index 0000000..a7911fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibltu.c b/gcc/testsuite/gcc.target/riscv/addsibltu.c
new file mode 100644
index 0000000..69ee2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ add[w] a2,a2,a3
+.L2:
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsibne.c b/gcc/testsuite/gcc.target/riscv/addsibne.c
new file mode 100644
index 0000000..929e057
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ add[w] a0,a2,a3
+ ret
+.L3:
+ mv a0,a2
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sub|subw)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsieq.c b/gcc/testsuite/gcc.target/riscv/addsieq.c
new file mode 100644
index 0000000..c5797a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsieq.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sub[w] a1,a0,a1
+ seqz a1,a1
+ neg[w] a1,a1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sub|subw)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsifeq.c b/gcc/testsuite/gcc.target/riscv/addsifeq.c
new file mode 100644
index 0000000..fe93f41
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsifeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ neg[w] a5,a5
+ and a5,a5,a1
+ add[w] a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsifge.c b/gcc/testsuite/gcc.target/riscv/addsifge.c
new file mode 100644
index 0000000..a0d31b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsifge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ neg[w] a5,a5
+ and a5,a5,a1
+ add[w] a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsifgt.c b/gcc/testsuite/gcc.target/riscv/addsifgt.c
new file mode 100644
index 0000000..f61efb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsifgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ neg[w] a5,a5
+ and a5,a5,a1
+ add[w] a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsifle.c b/gcc/testsuite/gcc.target/riscv/addsifle.c
new file mode 100644
index 0000000..a9a86bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsifle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ neg[w] a5,a5
+ and a5,a5,a1
+ add[w] a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsiflt.c b/gcc/testsuite/gcc.target/riscv/addsiflt.c
new file mode 100644
index 0000000..f68bd2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsiflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ neg[w] a5,a5
+ and a5,a5,a1
+ add[w] a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsifne.c b/gcc/testsuite/gcc.target/riscv/addsifne.c
new file mode 100644
index 0000000..9875d62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsifne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ addi[w] a5,a5,-1
+ and a5,a5,a1
+ add[w] a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsige.c b/gcc/testsuite/gcc.target/riscv/addsige.c
new file mode 100644
index 0000000..461f2ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsige.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ addi[w] a1,a1,-1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsigeu.c b/gcc/testsuite/gcc.target/riscv/addsigeu.c
new file mode 100644
index 0000000..3afcc33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsigeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ addi[w] a1,a1,-1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsigt.c b/gcc/testsuite/gcc.target/riscv/addsigt.c
new file mode 100644
index 0000000..247626a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsigt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ neg[w] a1,a1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsigtu.c b/gcc/testsuite/gcc.target/riscv/addsigtu.c
new file mode 100644
index 0000000..c6948b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsigtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ neg[w] a1,a1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsile.c b/gcc/testsuite/gcc.target/riscv/addsile.c
new file mode 100644
index 0000000..5072521
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsile.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ addi[w] a1,a1,-1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsileu.c b/gcc/testsuite/gcc.target/riscv/addsileu.c
new file mode 100644
index 0000000..2758a9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsileu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ addi[w] a1,a1,-1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsilt.c b/gcc/testsuite/gcc.target/riscv/addsilt.c
new file mode 100644
index 0000000..bad08e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsilt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ neg[w] a1,a1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsiltu.c b/gcc/testsuite/gcc.target/riscv/addsiltu.c
new file mode 100644
index 0000000..0cee92f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsiltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ neg[w] a1,a1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/addsine.c b/gcc/testsuite/gcc.target/riscv/addsine.c
new file mode 100644
index 0000000..4d45b83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/addsine.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+ sub[w] a1,a0,a1
+ snez a1,a1
+ neg[w] a1,a1
+ and a1,a1,a3
+ add[w] a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sub|subw)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibeq-thead.c b/gcc/testsuite/gcc.target/riscv/movdibeq-thead.c
new file mode 100644
index 0000000..26737ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibeq-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibeq-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibeq-ventana.c
new file mode 100644
index 0000000..c48e57e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibeq-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibeq-zicond.c
new file mode 100644
index 0000000..6f61731
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibeq.c b/gcc/testsuite/gcc.target/riscv/movdibeq.c
new file mode 100644
index 0000000..8359eca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfeq-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibfeq-ventana.c
new file mode 100644
index 0000000..e43b642
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfeq-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfeq-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibfeq-zicond.c
new file mode 100644
index 0000000..ea4ff14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfeq-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfeq.c b/gcc/testsuite/gcc.target/riscv/movdibfeq.c
new file mode 100644
index 0000000..03c934b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c
new file mode 100644
index 0000000..b80f5c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c
new file mode 100644
index 0000000..ed72259
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfge.c b/gcc/testsuite/gcc.target/riscv/movdibfge.c
new file mode 100644
index 0000000..68dacb6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c
new file mode 100644
index 0000000..fd392ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c
new file mode 100644
index 0000000..158ad9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfgt.c b/gcc/testsuite/gcc.target/riscv/movdibfgt.c
new file mode 100644
index 0000000..dbd60d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c
new file mode 100644
index 0000000..bc9d719
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c
new file mode 100644
index 0000000..ac9f159
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfle.c b/gcc/testsuite/gcc.target/riscv/movdibfle.c
new file mode 100644
index 0000000..42d5401
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c
new file mode 100644
index 0000000..3a26107
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c
new file mode 100644
index 0000000..a8e362b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibflt.c b/gcc/testsuite/gcc.target/riscv/movdibflt.c
new file mode 100644
index 0000000..08935ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c
new file mode 100644
index 0000000..634872a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ bne a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c
new file mode 100644
index 0000000..24db9fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ bne a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibfne.c b/gcc/testsuite/gcc.target/riscv/movdibfne.c
new file mode 100644
index 0000000..1b71ad9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibfne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ bne a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibge-thead.c b/gcc/testsuite/gcc.target/riscv/movdibge-thead.c
new file mode 100644
index 0000000..4c05937
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibge-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibge-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibge-ventana.c
new file mode 100644
index 0000000..c0190e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibge-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibge-zicond.c
new file mode 100644
index 0000000..c4bd650
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibge.c b/gcc/testsuite/gcc.target/riscv/movdibge.c
new file mode 100644
index 0000000..e991835
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgeu-thead.c b/gcc/testsuite/gcc.target/riscv/movdibgeu-thead.c
new file mode 100644
index 0000000..c846160
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgeu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c
new file mode 100644
index 0000000..584bf26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c
new file mode 100644
index 0000000..e6ea9d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgeu.c b/gcc/testsuite/gcc.target/riscv/movdibgeu.c
new file mode 100644
index 0000000..b0e3e3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgt-thead.c b/gcc/testsuite/gcc.target/riscv/movdibgt-thead.c
new file mode 100644
index 0000000..cc22ff6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c
new file mode 100644
index 0000000..00b954c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c
new file mode 100644
index 0000000..1a1445f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgt.c b/gcc/testsuite/gcc.target/riscv/movdibgt.c
new file mode 100644
index 0000000..9890c6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgtu-thead.c b/gcc/testsuite/gcc.target/riscv/movdibgtu-thead.c
new file mode 100644
index 0000000..e616c15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgtu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgtu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibgtu-ventana.c
new file mode 100644
index 0000000..ea4548d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgtu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibgtu-zicond.c
new file mode 100644
index 0000000..19198f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibgtu.c b/gcc/testsuite/gcc.target/riscv/movdibgtu.c
new file mode 100644
index 0000000..7fa25c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdible-thead.c b/gcc/testsuite/gcc.target/riscv/movdible-thead.c
new file mode 100644
index 0000000..16415d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdible-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdible-ventana.c b/gcc/testsuite/gcc.target/riscv/movdible-ventana.c
new file mode 100644
index 0000000..2d1a49e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdible-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdible-zicond.c b/gcc/testsuite/gcc.target/riscv/movdible-zicond.c
new file mode 100644
index 0000000..ec26a36
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdible-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdible.c b/gcc/testsuite/gcc.target/riscv/movdible.c
new file mode 100644
index 0000000..23de185
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibleu-thead.c b/gcc/testsuite/gcc.target/riscv/movdibleu-thead.c
new file mode 100644
index 0000000..37781af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibleu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c
new file mode 100644
index 0000000..3e10d7b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c
new file mode 100644
index 0000000..bc1fb68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibleu.c b/gcc/testsuite/gcc.target/riscv/movdibleu.c
new file mode 100644
index 0000000..032e93b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiblt-thead.c b/gcc/testsuite/gcc.target/riscv/movdiblt-thead.c
new file mode 100644
index 0000000..43a772e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiblt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c
new file mode 100644
index 0000000..0636f90
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c
new file mode 100644
index 0000000..3c82f0b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiblt.c b/gcc/testsuite/gcc.target/riscv/movdiblt.c
new file mode 100644
index 0000000..0b7a40c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibltu-thead.c b/gcc/testsuite/gcc.target/riscv/movdibltu-thead.c
new file mode 100644
index 0000000..ec44b1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibltu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibltu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibltu-ventana.c
new file mode 100644
index 0000000..c92a494
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibltu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibltu-zicond.c
new file mode 100644
index 0000000..68bdccf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibltu.c b/gcc/testsuite/gcc.target/riscv/movdibltu.c
new file mode 100644
index 0000000..277d08e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibne-thead.c b/gcc/testsuite/gcc.target/riscv/movdibne-thead.c
new file mode 100644
index 0000000..8edcfd5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibne-thead.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibne-ventana.c b/gcc/testsuite/gcc.target/riscv/movdibne-ventana.c
new file mode 100644
index 0000000..5752f14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibne-zicond.c b/gcc/testsuite/gcc.target/riscv/movdibne-zicond.c
new file mode 100644
index 0000000..1c97a3c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdibne.c b/gcc/testsuite/gcc.target/riscv/movdibne.c
new file mode 100644
index 0000000..f3b6715
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdieq-sfb.c b/gcc/testsuite/gcc.target/riscv/movdieq-sfb.c
new file mode 100644
index 0000000..aed11b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdieq-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bne a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdieq-thead.c b/gcc/testsuite/gcc.target/riscv/movdieq-thead.c
new file mode 100644
index 0000000..2109a72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdieq-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdieq-ventana.c b/gcc/testsuite/gcc.target/riscv/movdieq-ventana.c
new file mode 100644
index 0000000..bca40ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdieq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdieq-zicond.c b/gcc/testsuite/gcc.target/riscv/movdieq-zicond.c
new file mode 100644
index 0000000..3222c87
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdieq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdieq.c b/gcc/testsuite/gcc.target/riscv/movdieq.c
new file mode 100644
index 0000000..9878341
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdieq.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=7 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a5,a0,a1
+ snez a5,a5
+ neg a5,a5
+ and a3,a5,a3
+ not a5,a5
+ and a5,a5,a2
+ or a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifeq-sfb.c b/gcc/testsuite/gcc.target/riscv/movdifeq-sfb.c
new file mode 100644
index 0000000..fe5a79a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifeq-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ feq.d a5,fa0,fa1
+ beq a5,zero,1f # movcc
+ mv a1,a0
+1:
+ mv a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifeq-thead.c b/gcc/testsuite/gcc.target/riscv/movdifeq-thead.c
new file mode 100644
index 0000000..487e3eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifeq-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifeq-ventana.c b/gcc/testsuite/gcc.target/riscv/movdifeq-ventana.c
new file mode 100644
index 0000000..6d6c801
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ vt.maskcn a1,a1,a5
+ vt.maskc a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifeq-zicond.c b/gcc/testsuite/gcc.target/riscv/movdifeq-zicond.c
new file mode 100644
index 0000000..15bd6e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ czero.nez a1,a1,a5
+ czero.eqz a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifeq.c b/gcc/testsuite/gcc.target/riscv/movdifeq.c
new file mode 100644
index 0000000..de6e17e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c b/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
new file mode 100644
index 0000000..b5eb0f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ fge.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifge-thead.c b/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
new file mode 100644
index 0000000..6fb210c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c b/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
new file mode 100644
index 0000000..be33171
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c b/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
new file mode 100644
index 0000000..0c6a10f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifge.c b/gcc/testsuite/gcc.target/riscv/movdifge.c
new file mode 100644
index 0000000..3193aae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c b/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
new file mode 100644
index 0000000..0fc5a1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ fgt.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c b/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
new file mode 100644
index 0000000..1eece07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
new file mode 100644
index 0000000..7df01a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
new file mode 100644
index 0000000..6b18e8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifgt.c b/gcc/testsuite/gcc.target/riscv/movdifgt.c
new file mode 100644
index 0000000..466b4ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c b/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
new file mode 100644
index 0000000..475c7f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ fle.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifle-thead.c b/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
new file mode 100644
index 0000000..9ee0dbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c b/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
new file mode 100644
index 0000000..d6f67ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c b/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
new file mode 100644
index 0000000..c1f13b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifle.c b/gcc/testsuite/gcc.target/riscv/movdifle.c
new file mode 100644
index 0000000..579f14d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c b/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
new file mode 100644
index 0000000..c116fe3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ flt.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c b/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
new file mode 100644
index 0000000..f4f210c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
new file mode 100644
index 0000000..049b77c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
new file mode 100644
index 0000000..6a1d7ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiflt.c b/gcc/testsuite/gcc.target/riscv/movdiflt.c
new file mode 100644
index 0000000..280eaa4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifne-sfb.c b/gcc/testsuite/gcc.target/riscv/movdifne-sfb.c
new file mode 100644
index 0000000..4d0b64c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifne-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ feq.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a1,a0
+1:
+ mv a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifne-thead.c b/gcc/testsuite/gcc.target/riscv/movdifne-thead.c
new file mode 100644
index 0000000..54f82d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifne-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ th.mvnez a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifne-ventana.c b/gcc/testsuite/gcc.target/riscv/movdifne-ventana.c
new file mode 100644
index 0000000..ae95b6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifne-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ vt.maskc a1,a1,a5
+ vt.maskcn a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifne-zicond.c b/gcc/testsuite/gcc.target/riscv/movdifne-zicond.c
new file mode 100644
index 0000000..b296d94
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifne-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ czero.eqz a1,a1,a5
+ czero.nez a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdifne.c b/gcc/testsuite/gcc.target/riscv/movdifne.c
new file mode 100644
index 0000000..e06bb14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdifne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ neg a5,a5
+ and a1,a5,a1
+ not a5,a5
+ and a0,a5,a0
+ or a0,a1,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdige-sfb.c b/gcc/testsuite/gcc.target/riscv/movdige-sfb.c
new file mode 100644
index 0000000..bcbc263
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdige-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ blt a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdige-thead.c b/gcc/testsuite/gcc.target/riscv/movdige-thead.c
new file mode 100644
index 0000000..5ade711
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdige-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdige-ventana.c b/gcc/testsuite/gcc.target/riscv/movdige-ventana.c
new file mode 100644
index 0000000..ea60c88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdige-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdige-zicond.c b/gcc/testsuite/gcc.target/riscv/movdige-zicond.c
new file mode 100644
index 0000000..958ebe7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdige-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdige.c b/gcc/testsuite/gcc.target/riscv/movdige.c
new file mode 100644
index 0000000..f24f4a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdige.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c b/gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c
new file mode 100644
index 0000000..fd5abf0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bltu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigeu-thead.c b/gcc/testsuite/gcc.target/riscv/movdigeu-thead.c
new file mode 100644
index 0000000..6fa48f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigeu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c
new file mode 100644
index 0000000..a89151b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c
new file mode 100644
index 0000000..2dbd655
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigeu.c b/gcc/testsuite/gcc.target/riscv/movdigeu.c
new file mode 100644
index 0000000..ae2f957
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigeu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigt-sfb.c b/gcc/testsuite/gcc.target/riscv/movdigt-sfb.c
new file mode 100644
index 0000000..f3c4186
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ ble a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigt-thead.c b/gcc/testsuite/gcc.target/riscv/movdigt-thead.c
new file mode 100644
index 0000000..d687dd2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdigt-ventana.c
new file mode 100644
index 0000000..8206f3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdigt-zicond.c
new file mode 100644
index 0000000..632d007
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigt.c b/gcc/testsuite/gcc.target/riscv/movdigt.c
new file mode 100644
index 0000000..83e5244
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c b/gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c
new file mode 100644
index 0000000..a788107
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bleu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigtu-thead.c b/gcc/testsuite/gcc.target/riscv/movdigtu-thead.c
new file mode 100644
index 0000000..3fb471a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigtu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c
new file mode 100644
index 0000000..d34314d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c
new file mode 100644
index 0000000..61a0c14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdigtu.c b/gcc/testsuite/gcc.target/riscv/movdigtu.c
new file mode 100644
index 0000000..184b384
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdigtu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdile-sfb.c b/gcc/testsuite/gcc.target/riscv/movdile-sfb.c
new file mode 100644
index 0000000..3758764
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdile-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bgt a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|bgt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdile-thead.c b/gcc/testsuite/gcc.target/riscv/movdile-thead.c
new file mode 100644
index 0000000..6ba8d8d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdile-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdile-ventana.c b/gcc/testsuite/gcc.target/riscv/movdile-ventana.c
new file mode 100644
index 0000000..dee7bf7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdile-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdile-zicond.c b/gcc/testsuite/gcc.target/riscv/movdile-zicond.c
new file mode 100644
index 0000000..a3989a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdile-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdile.c b/gcc/testsuite/gcc.target/riscv/movdile.c
new file mode 100644
index 0000000..a1b7a57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdile.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdileu-sfb.c b/gcc/testsuite/gcc.target/riscv/movdileu-sfb.c
new file mode 100644
index 0000000..312b52c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdileu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bgtu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdileu-thead.c b/gcc/testsuite/gcc.target/riscv/movdileu-thead.c
new file mode 100644
index 0000000..3661165
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdileu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdileu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdileu-ventana.c
new file mode 100644
index 0000000..c50cb43
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdileu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdileu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdileu-zicond.c
new file mode 100644
index 0000000..018babe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdileu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdileu.c b/gcc/testsuite/gcc.target/riscv/movdileu.c
new file mode 100644
index 0000000..4eb8267
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdileu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdilt-sfb.c b/gcc/testsuite/gcc.target/riscv/movdilt-sfb.c
new file mode 100644
index 0000000..f37b35b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdilt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bge a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdilt-thead.c b/gcc/testsuite/gcc.target/riscv/movdilt-thead.c
new file mode 100644
index 0000000..7ae6357
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdilt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdilt-ventana.c b/gcc/testsuite/gcc.target/riscv/movdilt-ventana.c
new file mode 100644
index 0000000..9d98d93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdilt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdilt-zicond.c b/gcc/testsuite/gcc.target/riscv/movdilt-zicond.c
new file mode 100644
index 0000000..79bfefe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdilt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdilt.c b/gcc/testsuite/gcc.target/riscv/movdilt.c
new file mode 100644
index 0000000..0ba8da0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdilt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c b/gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c
new file mode 100644
index 0000000..fa799df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bgeu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiltu-thead.c b/gcc/testsuite/gcc.target/riscv/movdiltu-thead.c
new file mode 100644
index 0000000..345c88b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiltu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c b/gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c
new file mode 100644
index 0000000..23f2572
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c b/gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c
new file mode 100644
index 0000000..641bfb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdiltu.c b/gcc/testsuite/gcc.target/riscv/movdiltu.c
new file mode 100644
index 0000000..0bbc006
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdiltu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdine-sfb.c b/gcc/testsuite/gcc.target/riscv/movdine-sfb.c
new file mode 100644
index 0000000..40aec9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdine-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ beq a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdine-thead.c b/gcc/testsuite/gcc.target/riscv/movdine-thead.c
new file mode 100644
index 0000000..2ea8388
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdine-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ th.mveqz a2,a3,a1
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdine-ventana.c b/gcc/testsuite/gcc.target/riscv/movdine-ventana.c
new file mode 100644
index 0000000..0713bac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdine-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdine-zicond.c b/gcc/testsuite/gcc.target/riscv/movdine-zicond.c
new file mode 100644
index 0000000..825003b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdine-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movdine.c b/gcc/testsuite/gcc.target/riscv/movdine.c
new file mode 100644
index 0000000..0180d05
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movdine.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a5,a0,a1
+ seqz a5,a5
+ neg a5,a5
+ and a3,a5,a3
+ not a5,a5
+ and a5,a5,a2
+ or a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibeq-thead.c b/gcc/testsuite/gcc.target/riscv/movsibeq-thead.c
new file mode 100644
index 0000000..ac8496d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibeq-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibeq-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibeq-ventana.c
new file mode 100644
index 0000000..f9f69c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibeq-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibeq-zicond.c
new file mode 100644
index 0000000..d2cc9a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibeq.c b/gcc/testsuite/gcc.target/riscv/movsibeq.c
new file mode 100644
index 0000000..8f499de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bne a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfeq-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibfeq-ventana.c
new file mode 100644
index 0000000..44ecadc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfeq-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfeq-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibfeq-zicond.c
new file mode 100644
index 0000000..addbb2e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfeq-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfeq.c b/gcc/testsuite/gcc.target/riscv/movsibfeq.c
new file mode 100644
index 0000000..27b1014
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c
new file mode 100644
index 0000000..e285102
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c
new file mode 100644
index 0000000..f696b33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfge.c b/gcc/testsuite/gcc.target/riscv/movsibfge.c
new file mode 100644
index 0000000..fdfdf20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fge.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c
new file mode 100644
index 0000000..f26577b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c
new file mode 100644
index 0000000..4d1de86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfgt.c b/gcc/testsuite/gcc.target/riscv/movsibfgt.c
new file mode 100644
index 0000000..20c55fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fgt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c
new file mode 100644
index 0000000..a52721e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c
new file mode 100644
index 0000000..b22292f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfle.c b/gcc/testsuite/gcc.target/riscv/movsibfle.c
new file mode 100644
index 0000000..9e428ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ fle.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c
new file mode 100644
index 0000000..5c40cb6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c
new file mode 100644
index 0000000..502a8e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibflt.c b/gcc/testsuite/gcc.target/riscv/movsibflt.c
new file mode 100644
index 0000000..6a5f9fb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ flt.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ beq a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c
new file mode 100644
index 0000000..0f52852
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ bne a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c
new file mode 100644
index 0000000..5f8df56
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ bne a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibfne.c b/gcc/testsuite/gcc.target/riscv/movsibfne.c
new file mode 100644
index 0000000..88f1469
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibfne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ feq.d a4,fa0,fa1
+ mv a5,a0
+ mv a0,a1
+ bne a4,zero,.L2
+ mv a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibge-thead.c b/gcc/testsuite/gcc.target/riscv/movsibge-thead.c
new file mode 100644
index 0000000..3dd9119
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibge-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibge-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibge-ventana.c
new file mode 100644
index 0000000..e40abbe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibge-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibge-zicond.c
new file mode 100644
index 0000000..c7b62b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibge.c b/gcc/testsuite/gcc.target/riscv/movsibge.c
new file mode 100644
index 0000000..6153d7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ blt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgeu-thead.c b/gcc/testsuite/gcc.target/riscv/movsibgeu-thead.c
new file mode 100644
index 0000000..4d850f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgeu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c
new file mode 100644
index 0000000..be7fa13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c
new file mode 100644
index 0000000..6f8dacb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgeu.c b/gcc/testsuite/gcc.target/riscv/movsibgeu.c
new file mode 100644
index 0000000..8d5363b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bltu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgt-thead.c b/gcc/testsuite/gcc.target/riscv/movsibgt-thead.c
new file mode 100644
index 0000000..7143c0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c
new file mode 100644
index 0000000..6664ff0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c
new file mode 100644
index 0000000..09b82d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgt.c b/gcc/testsuite/gcc.target/riscv/movsibgt.c
new file mode 100644
index 0000000..4851c6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ ble a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgtu-thead.c b/gcc/testsuite/gcc.target/riscv/movsibgtu-thead.c
new file mode 100644
index 0000000..21e418e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgtu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgtu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibgtu-ventana.c
new file mode 100644
index 0000000..0716ba8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgtu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibgtu-zicond.c
new file mode 100644
index 0000000..a8018cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibgtu.c b/gcc/testsuite/gcc.target/riscv/movsibgtu.c
new file mode 100644
index 0000000..bd9329d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bleu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsible-thead.c b/gcc/testsuite/gcc.target/riscv/movsible-thead.c
new file mode 100644
index 0000000..abcdbdf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsible-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsible-ventana.c b/gcc/testsuite/gcc.target/riscv/movsible-ventana.c
new file mode 100644
index 0000000..c49f12f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsible-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsible-zicond.c b/gcc/testsuite/gcc.target/riscv/movsible-zicond.c
new file mode 100644
index 0000000..bb5fe35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsible-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsible.c b/gcc/testsuite/gcc.target/riscv/movsible.c
new file mode 100644
index 0000000..de2fca4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgt a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibleu-thead.c b/gcc/testsuite/gcc.target/riscv/movsibleu-thead.c
new file mode 100644
index 0000000..1ddb03c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibleu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c
new file mode 100644
index 0000000..8096888
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c
new file mode 100644
index 0000000..2ded825
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibleu.c b/gcc/testsuite/gcc.target/riscv/movsibleu.c
new file mode 100644
index 0000000..1787614
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgtu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiblt-thead.c b/gcc/testsuite/gcc.target/riscv/movsiblt-thead.c
new file mode 100644
index 0000000..1459d37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiblt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c
new file mode 100644
index 0000000..47b611d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c
new file mode 100644
index 0000000..59e6b84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiblt.c b/gcc/testsuite/gcc.target/riscv/movsiblt.c
new file mode 100644
index 0000000..458c9f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bge a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibltu-thead.c b/gcc/testsuite/gcc.target/riscv/movsibltu-thead.c
new file mode 100644
index 0000000..89a0fab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibltu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibltu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibltu-ventana.c
new file mode 100644
index 0000000..8f45f02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibltu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibltu-zicond.c
new file mode 100644
index 0000000..0abb111
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibltu.c b/gcc/testsuite/gcc.target/riscv/movsibltu.c
new file mode 100644
index 0000000..973beaa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ bgeu a0,a1,.L2
+ mv a3,a2
+.L2:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibne-thead.c b/gcc/testsuite/gcc.target/riscv/movsibne-thead.c
new file mode 100644
index 0000000..a76744c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibne-thead.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibne-ventana.c b/gcc/testsuite/gcc.target/riscv/movsibne-ventana.c
new file mode 100644
index 0000000..cc1961a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibne-zicond.c b/gcc/testsuite/gcc.target/riscv/movsibne-zicond.c
new file mode 100644
index 0000000..0bc2e26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsibne.c b/gcc/testsuite/gcc.target/riscv/movsibne.c
new file mode 100644
index 0000000..5b3e6ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+ beq a0,a1,.L3
+ mv a0,a2
+ ret
+.L3:
+ mv a0,a3
+ ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsieq-sfb.c b/gcc/testsuite/gcc.target/riscv/movsieq-sfb.c
new file mode 100644
index 0000000..8525f6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsieq-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bne a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsieq-thead.c b/gcc/testsuite/gcc.target/riscv/movsieq-thead.c
new file mode 100644
index 0000000..35a1e91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsieq-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsieq-ventana.c b/gcc/testsuite/gcc.target/riscv/movsieq-ventana.c
new file mode 100644
index 0000000..65be52f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsieq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsieq-zicond.c b/gcc/testsuite/gcc.target/riscv/movsieq-zicond.c
new file mode 100644
index 0000000..afa14c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsieq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsieq.c b/gcc/testsuite/gcc.target/riscv/movsieq.c
new file mode 100644
index 0000000..7d7e99d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsieq.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=7 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=7 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a5,a0,a1
+ snez a5,a5
+ neg a5,a5
+ and a3,a5,a3
+ not a5,a5
+ and a5,a5,a2
+ or a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifeq-sfb.c b/gcc/testsuite/gcc.target/riscv/movsifeq-sfb.c
new file mode 100644
index 0000000..1f20bb4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifeq-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ feq.d a5,fa0,fa1
+ beq a5,zero,1f # movcc
+ mv a1,a0
+1:
+ mv a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifeq-thead.c b/gcc/testsuite/gcc.target/riscv/movsifeq-thead.c
new file mode 100644
index 0000000..e2e69e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifeq-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifeq-ventana.c b/gcc/testsuite/gcc.target/riscv/movsifeq-ventana.c
new file mode 100644
index 0000000..9fb29aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ vt.maskcn a1,a1,a5
+ vt.maskc a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifeq-zicond.c b/gcc/testsuite/gcc.target/riscv/movsifeq-zicond.c
new file mode 100644
index 0000000..d967d32
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ czero.nez a1,a1,a5
+ czero.eqz a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifeq.c b/gcc/testsuite/gcc.target/riscv/movsifeq.c
new file mode 100644
index 0000000..a4c0c67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+ return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c b/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
new file mode 100644
index 0000000..c9f0e2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ fge.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifge-thead.c b/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
new file mode 100644
index 0000000..893a522a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c b/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
new file mode 100644
index 0000000..26e55b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c b/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
new file mode 100644
index 0000000..e38aa80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifge.c b/gcc/testsuite/gcc.target/riscv/movsifge.c
new file mode 100644
index 0000000..c3f170e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fge.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c b/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
new file mode 100644
index 0000000..47ea2c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ fgt.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c b/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
new file mode 100644
index 0000000..0ec4e57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
new file mode 100644
index 0000000..8896266
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
new file mode 100644
index 0000000..bada72f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifgt.c b/gcc/testsuite/gcc.target/riscv/movsifgt.c
new file mode 100644
index 0000000..68aca07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fgt.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c b/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
new file mode 100644
index 0000000..7cb9167
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ fle.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifle-thead.c b/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
new file mode 100644
index 0000000..b05a02a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c b/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
new file mode 100644
index 0000000..24b49d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c b/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
new file mode 100644
index 0000000..5aad910
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifle.c b/gcc/testsuite/gcc.target/riscv/movsifle.c
new file mode 100644
index 0000000..3b1b06c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ fle.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c b/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
new file mode 100644
index 0000000..110e38a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ flt.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c b/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
new file mode 100644
index 0000000..124c408
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ th.mveqz a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
new file mode 100644
index 0000000..911a502
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ vt.maskc a0,a0,a5
+ vt.maskcn a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
new file mode 100644
index 0000000..7db2b99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ czero.eqz a0,a0,a5
+ czero.nez a5,a1,a5
+ or a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiflt.c b/gcc/testsuite/gcc.target/riscv/movsiflt.c
new file mode 100644
index 0000000..a74d859
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ flt.d a5,fa0,fa1
+ neg a5,a5
+ and a0,a5,a0
+ not a5,a5
+ and a5,a5,a1
+ or a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifne-sfb.c b/gcc/testsuite/gcc.target/riscv/movsifne-sfb.c
new file mode 100644
index 0000000..e08a0e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifne-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ feq.d a5,fa0,fa1
+ bne a5,zero,1f # movcc
+ mv a1,a0
+1:
+ mv a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifne-thead.c b/gcc/testsuite/gcc.target/riscv/movsifne-thead.c
new file mode 100644
index 0000000..19a3950
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifne-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ th.mvnez a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifne-ventana.c b/gcc/testsuite/gcc.target/riscv/movsifne-ventana.c
new file mode 100644
index 0000000..6c038fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifne-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ vt.maskc a1,a1,a5
+ vt.maskcn a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifne-zicond.c b/gcc/testsuite/gcc.target/riscv/movsifne-zicond.c
new file mode 100644
index 0000000..2148f4b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifne-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ czero.eqz a1,a1,a5
+ czero.nez a0,a0,a5
+ or a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsifne.c b/gcc/testsuite/gcc.target/riscv/movsifne.c
new file mode 100644
index 0000000..f73f6f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsifne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ feq.d a5,fa0,fa1
+ neg a5,a5
+ and a1,a5,a1
+ not a5,a5
+ and a0,a5,a0
+ or a0,a1,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsige-sfb.c b/gcc/testsuite/gcc.target/riscv/movsige-sfb.c
new file mode 100644
index 0000000..cc9f2b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsige-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ blt a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsige-thead.c b/gcc/testsuite/gcc.target/riscv/movsige-thead.c
new file mode 100644
index 0000000..87ce0df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsige-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsige-ventana.c b/gcc/testsuite/gcc.target/riscv/movsige-ventana.c
new file mode 100644
index 0000000..8222e10
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsige-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsige-zicond.c b/gcc/testsuite/gcc.target/riscv/movsige-zicond.c
new file mode 100644
index 0000000..4a8c09d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsige-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsige.c b/gcc/testsuite/gcc.target/riscv/movsige.c
new file mode 100644
index 0000000..aabd182
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsige.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c b/gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c
new file mode 100644
index 0000000..20bbf51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bltu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigeu-thead.c b/gcc/testsuite/gcc.target/riscv/movsigeu-thead.c
new file mode 100644
index 0000000..d2f51ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigeu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c
new file mode 100644
index 0000000..448b807
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c
new file mode 100644
index 0000000..6c2ba09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigeu.c b/gcc/testsuite/gcc.target/riscv/movsigeu.c
new file mode 100644
index 0000000..2828e39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigeu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigt-sfb.c b/gcc/testsuite/gcc.target/riscv/movsigt-sfb.c
new file mode 100644
index 0000000..c494292
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ ble a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgt|ble)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigt-thead.c b/gcc/testsuite/gcc.target/riscv/movsigt-thead.c
new file mode 100644
index 0000000..e99b79f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsigt-ventana.c
new file mode 100644
index 0000000..750366d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsigt-zicond.c
new file mode 100644
index 0000000..a117bc8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigt.c b/gcc/testsuite/gcc.target/riscv/movsigt.c
new file mode 100644
index 0000000..5f4af28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c b/gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c
new file mode 100644
index 0000000..bfe4a5b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bleu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigtu-thead.c b/gcc/testsuite/gcc.target/riscv/movsigtu-thead.c
new file mode 100644
index 0000000..33770e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigtu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c
new file mode 100644
index 0000000..73a8c53
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c
new file mode 100644
index 0000000..a42578d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsigtu.c b/gcc/testsuite/gcc.target/riscv/movsigtu.c
new file mode 100644
index 0000000..24ee2c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsigtu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsile-sfb.c b/gcc/testsuite/gcc.target/riscv/movsile-sfb.c
new file mode 100644
index 0000000..82a6995
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsile-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bgt a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsile-thead.c b/gcc/testsuite/gcc.target/riscv/movsile-thead.c
new file mode 100644
index 0000000..6e724a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsile-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsile-ventana.c b/gcc/testsuite/gcc.target/riscv/movsile-ventana.c
new file mode 100644
index 0000000..96bbe92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsile-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsile-zicond.c b/gcc/testsuite/gcc.target/riscv/movsile-zicond.c
new file mode 100644
index 0000000..33f9ebd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsile-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsile.c b/gcc/testsuite/gcc.target/riscv/movsile.c
new file mode 100644
index 0000000..8e9fe6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsile.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsileu-sfb.c b/gcc/testsuite/gcc.target/riscv/movsileu-sfb.c
new file mode 100644
index 0000000..e8b7c45
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsileu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bgtu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsileu-thead.c b/gcc/testsuite/gcc.target/riscv/movsileu-thead.c
new file mode 100644
index 0000000..fb72753
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsileu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a0,a0,a1
+ th.mvnez a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsileu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsileu-ventana.c
new file mode 100644
index 0000000..ff64c38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsileu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ vt.maskc a3,a3,a1
+ vt.maskcn a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsileu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsileu-zicond.c
new file mode 100644
index 0000000..29e4fc4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsileu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ czero.eqz a3,a3,a1
+ czero.nez a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsileu.c b/gcc/testsuite/gcc.target/riscv/movsileu.c
new file mode 100644
index 0000000..a0b733e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsileu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sgtu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsilt-sfb.c b/gcc/testsuite/gcc.target/riscv/movsilt-sfb.c
new file mode 100644
index 0000000..822c778
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsilt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bge a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsilt-thead.c b/gcc/testsuite/gcc.target/riscv/movsilt-thead.c
new file mode 100644
index 0000000..ca957b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsilt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsilt-ventana.c b/gcc/testsuite/gcc.target/riscv/movsilt-ventana.c
new file mode 100644
index 0000000..63df590
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsilt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsilt-zicond.c b/gcc/testsuite/gcc.target/riscv/movsilt-zicond.c
new file mode 100644
index 0000000..11ce70f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsilt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsilt.c b/gcc/testsuite/gcc.target/riscv/movsilt.c
new file mode 100644
index 0000000..109f67e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsilt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ slt a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c b/gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c
new file mode 100644
index 0000000..5fd441c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ bgeu a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiltu-thead.c b/gcc/testsuite/gcc.target/riscv/movsiltu-thead.c
new file mode 100644
index 0000000..680f673
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiltu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a0,a0,a1
+ th.mveqz a2,a3,a0
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c b/gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c
new file mode 100644
index 0000000..05ee813
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c b/gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c
new file mode 100644
index 0000000..79e7850
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsiltu.c b/gcc/testsuite/gcc.target/riscv/movsiltu.c
new file mode 100644
index 0000000..a7d4caf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsiltu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+ return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sltu a1,a0,a1
+ neg a1,a1
+ and a3,a1,a3
+ not a1,a1
+ and a1,a1,a2
+ or a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsine-sfb.c b/gcc/testsuite/gcc.target/riscv/movsine-sfb.c
new file mode 100644
index 0000000..f7ac7c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsine-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+ beq a0,a1,1f # movcc
+ mv a3,a2
+1:
+ mv a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsine-thead.c b/gcc/testsuite/gcc.target/riscv/movsine-thead.c
new file mode 100644
index 0000000..fc0d1e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsine-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ th.mveqz a2,a3,a1
+ mv a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsine-ventana.c b/gcc/testsuite/gcc.target/riscv/movsine-ventana.c
new file mode 100644
index 0000000..c9a2538
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsine-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ vt.maskcn a3,a3,a1
+ vt.maskc a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsine-zicond.c b/gcc/testsuite/gcc.target/riscv/movsine-zicond.c
new file mode 100644
index 0000000..326c32c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsine-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a1,a0,a1
+ czero.nez a3,a3,a1
+ czero.eqz a1,a2,a1
+ or a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/movsine.c b/gcc/testsuite/gcc.target/riscv/movsine.c
new file mode 100644
index 0000000..60dee08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/movsine.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+ return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+ sub a5,a0,a1
+ seqz a5,a5
+ neg a5,a5
+ and a3,a5,a3
+ not a5,a5
+ and a5,a5,a2
+ or a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/predef-1.c b/gcc/testsuite/gcc.target/riscv/predef-1.c
index 9dddc18..250812a 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-1.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-1.c
@@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-2.c b/gcc/testsuite/gcc.target/riscv/predef-2.c
index 755fe4e..fa5bdea 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-2.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-2.c
@@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if !defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-3.c b/gcc/testsuite/gcc.target/riscv/predef-3.c
index 5136453..868b561 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-3.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-3.c
@@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if !defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-4.c b/gcc/testsuite/gcc.target/riscv/predef-4.c
index 76b6fee..ba8b5c7 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-4.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-4.c
@@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if !defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-5.c b/gcc/testsuite/gcc.target/riscv/predef-5.c
index 54a5150..560d6ea 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-5.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-5.c
@@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-6.c b/gcc/testsuite/gcc.target/riscv/predef-6.c
index f61709f..8987b72 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-6.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-6.c
@@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if !defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-7.c b/gcc/testsuite/gcc.target/riscv/predef-7.c
index 4121755..833e2be 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-7.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-7.c
@@ -13,6 +13,9 @@ int main () {
#if !defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-8.c b/gcc/testsuite/gcc.target/riscv/predef-8.c
index 982056a..8fa8b42 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-8.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-8.c
@@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
+#if defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
#if defined(__riscv_atomic)
#error "__riscv_atomic"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-9.c b/gcc/testsuite/gcc.target/riscv/predef-9.c
new file mode 100644
index 0000000..cc3abc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/predef-9.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64em -mabi=lp64e -mno-div -mcmodel=medlow" } */
+
+int main () {
+#if !defined(__riscv)
+#error "__riscv"
+#endif
+
+#if defined(__riscv_compressed)
+#error "__riscv_compressed"
+#endif
+
+#if defined(__riscv_32e)
+#error "__riscv_32e"
+#endif
+#if !defined(__riscv_64e)
+#error "__riscv_64e"
+#endif
+
+#if defined(__riscv_atomic)
+#error "__riscv_atomic"
+#endif
+
+#if !defined(__riscv_mul)
+#error "__riscv_mul"
+#endif
+#if defined(__riscv_div)
+#error "__riscv_div"
+#endif
+#if defined(__riscv_muldiv)
+#error "__riscv_muldiv"
+#endif
+
+#if __riscv_xlen != 64
+#error "__riscv_xlen"
+#endif
+
+#if defined(__riscv_fdiv)
+#error "__riscv_fdiv"
+#endif
+#if defined(__riscv_fsqrt)
+#error "__riscv_fsqrt"
+#endif
+
+#if !defined(__riscv_abi_rve)
+#error "__riscv_abi_rve"
+#endif
+#if !defined(__riscv_float_abi_soft)
+#error "__riscv_float_abi_soft"
+#endif
+#if defined(__riscv_float_abi_single)
+#error "__riscv_float_abi_single"
+#endif
+#if defined(__riscv_float_abi_double)
+#error "__riscv_float_abi_double"
+#endif
+
+#if !defined(__riscv_cmodel_medlow)
+#error "__riscv_cmodel_medlow"
+#endif
+#if defined(__riscv_cmodel_medany)
+#error "__riscv_cmodel_medlow"
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c
new file mode 100644
index 0000000..8ae5106
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+#define INDEX16 uint16_t
+#define INDEX32 uint32_t
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c
new file mode 100644
index 0000000..d705c92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 int64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c
new file mode 100644
index 0000000..4e183cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(DATA_TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict *src) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += *src[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (_Float16) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (float) \
+ T (int64_t) \
+ T (uint64_t) \
+ T (double)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c
index 6277682..6277682 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c
new file mode 100644
index 0000000..e4e42fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 int8_t
+#define INDEX16 int16_t
+#define INDEX32 int32_t
+#define INDEX64 int64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c
new file mode 100644
index 0000000..e385fee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c
new file mode 100644
index 0000000..e5cb19d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 int8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c
new file mode 100644
index 0000000..a437e73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 uint16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c
new file mode 100644
index 0000000..487dca9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 int16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c
new file mode 100644
index 0000000..ff91929
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 uint32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c
new file mode 100644
index 0000000..81df57f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 int32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c
new file mode 100644
index 0000000..238b6bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-1.c
index 3b26bf1..eabe012 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-10.c
index 63949cb..ba4bc78 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-10.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-11.c
index 8dc1da3..e75b694 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-12.c
new file mode 100644
index 0000000..d8daf3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-12.c
@@ -0,0 +1,110 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(DATA_TYPE, INDEX_TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE##_##INDEX_TYPE (DATA_TYPE *restrict y, DATA_TYPE *restrict x, \
+ INDEX_TYPE *restrict index) \
+ { \
+ for (int i = 0; i < 100; ++i) \
+ { \
+ y[i * 2] = x[index[i * 2]] + 1; \
+ y[i * 2 + 1] = x[index[i * 2 + 1]] + 2; \
+ } \
+ }
+
+TEST_LOOP (int8_t, int8_t)
+TEST_LOOP (uint8_t, int8_t)
+TEST_LOOP (int16_t, int8_t)
+TEST_LOOP (uint16_t, int8_t)
+TEST_LOOP (int32_t, int8_t)
+TEST_LOOP (uint32_t, int8_t)
+TEST_LOOP (int64_t, int8_t)
+TEST_LOOP (uint64_t, int8_t)
+TEST_LOOP (_Float16, int8_t)
+TEST_LOOP (float, int8_t)
+TEST_LOOP (double, int8_t)
+TEST_LOOP (int8_t, int16_t)
+TEST_LOOP (uint8_t, int16_t)
+TEST_LOOP (int16_t, int16_t)
+TEST_LOOP (uint16_t, int16_t)
+TEST_LOOP (int32_t, int16_t)
+TEST_LOOP (uint32_t, int16_t)
+TEST_LOOP (int64_t, int16_t)
+TEST_LOOP (uint64_t, int16_t)
+TEST_LOOP (_Float16, int16_t)
+TEST_LOOP (float, int16_t)
+TEST_LOOP (double, int16_t)
+TEST_LOOP (int8_t, int32_t)
+TEST_LOOP (uint8_t, int32_t)
+TEST_LOOP (int16_t, int32_t)
+TEST_LOOP (uint16_t, int32_t)
+TEST_LOOP (int32_t, int32_t)
+TEST_LOOP (uint32_t, int32_t)
+TEST_LOOP (int64_t, int32_t)
+TEST_LOOP (uint64_t, int32_t)
+TEST_LOOP (_Float16, int32_t)
+TEST_LOOP (float, int32_t)
+TEST_LOOP (double, int32_t)
+TEST_LOOP (int8_t, int64_t)
+TEST_LOOP (uint8_t, int64_t)
+TEST_LOOP (int16_t, int64_t)
+TEST_LOOP (uint16_t, int64_t)
+TEST_LOOP (int32_t, int64_t)
+TEST_LOOP (uint32_t, int64_t)
+TEST_LOOP (int64_t, int64_t)
+TEST_LOOP (uint64_t, int64_t)
+TEST_LOOP (_Float16, int64_t)
+TEST_LOOP (float, int64_t)
+TEST_LOOP (double, int64_t)
+TEST_LOOP (int8_t, uint8_t)
+TEST_LOOP (uint8_t, uint8_t)
+TEST_LOOP (int16_t, uint8_t)
+TEST_LOOP (uint16_t, uint8_t)
+TEST_LOOP (int32_t, uint8_t)
+TEST_LOOP (uint32_t, uint8_t)
+TEST_LOOP (int64_t, uint8_t)
+TEST_LOOP (uint64_t, uint8_t)
+TEST_LOOP (_Float16, uint8_t)
+TEST_LOOP (float, uint8_t)
+TEST_LOOP (double, uint8_t)
+TEST_LOOP (int8_t, uint16_t)
+TEST_LOOP (uint8_t, uint16_t)
+TEST_LOOP (int16_t, uint16_t)
+TEST_LOOP (uint16_t, uint16_t)
+TEST_LOOP (int32_t, uint16_t)
+TEST_LOOP (uint32_t, uint16_t)
+TEST_LOOP (int64_t, uint16_t)
+TEST_LOOP (uint64_t, uint16_t)
+TEST_LOOP (_Float16, uint16_t)
+TEST_LOOP (float, uint16_t)
+TEST_LOOP (double, uint16_t)
+TEST_LOOP (int8_t, uint32_t)
+TEST_LOOP (uint8_t, uint32_t)
+TEST_LOOP (int16_t, uint32_t)
+TEST_LOOP (uint16_t, uint32_t)
+TEST_LOOP (int32_t, uint32_t)
+TEST_LOOP (uint32_t, uint32_t)
+TEST_LOOP (int64_t, uint32_t)
+TEST_LOOP (uint64_t, uint32_t)
+TEST_LOOP (_Float16, uint32_t)
+TEST_LOOP (float, uint32_t)
+TEST_LOOP (double, uint32_t)
+TEST_LOOP (int8_t, uint64_t)
+TEST_LOOP (uint8_t, uint64_t)
+TEST_LOOP (int16_t, uint64_t)
+TEST_LOOP (uint16_t, uint64_t)
+TEST_LOOP (int32_t, uint64_t)
+TEST_LOOP (uint32_t, uint64_t)
+TEST_LOOP (int64_t, uint64_t)
+TEST_LOOP (uint64_t, uint64_t)
+TEST_LOOP (_Float16, uint64_t)
+TEST_LOOP (float, uint64_t)
+TEST_LOOP (double, uint64_t)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 88 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-2.c
index 89e4b40..3389bc4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-3.c
index 02fd37c..b23603a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-4.c
index af6a76a..0247103 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-5.c
index bd9a449..19ff214 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-6.c
index 6d776af..fd7684b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-7.c
index 040300a..9800b93 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-8.c
index 9223bf0..4f84fe1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-9.c
index 2e06fe6..41a7ae5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_64-9.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c
index 232873c..3ca1b0c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-1.c"
+#include "gather_load_64-1.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c
index 9696a21..ef1517a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-10.c"
+#include "gather_load_64-10.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c
index 459a1a8..c435584 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-11.c"
+#include "gather_load_64-11.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c
index 1cbf507..d48d529 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-12.c"
+#include "gather_load_64-12.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c
index 93a07e0..b1290ec 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-2.c"
+#include "gather_load_64-2.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c
index f318a43..8b86870 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-3.c"
+#include "gather_load_64-3.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c
index a210cdf..2085474 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-4.c"
+#include "gather_load_64-4.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c
index ade9175..ad91813 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-5.c"
+#include "gather_load_64-5.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c
index f5bdece..53b3254 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-6.c"
+#include "gather_load_64-6.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c
index 47a1783..8e135a7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c
@@ -5,7 +5,7 @@
compiles properly. */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "gather_load-7.c"
+#include "gather_load_64-7.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c
index 1ce18040..8f13ec6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c
@@ -5,7 +5,7 @@
compiles properly. */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "gather_load-8.c"
+#include "gather_load_64-8.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c
index 3c08c63..2e17075 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "gather_load-9.c"
+#include "gather_load_64-9.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c
index abab3b9..c0b5833 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c
@@ -37,3 +37,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c
index 61ab1fb..9e4fcee 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c
index e574181..e574181 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c
index cc5f52e..aadc020 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c
@@ -37,3 +37,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c
index 311e25e..b547dd6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c
index 9223df9..ac60125 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c
index 9ec7e60..f003a17 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c
index ff18009..d1d9581 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c
index fd05df7..c8b5cea 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c
index a58c1c2..dfb8a93 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c
index 36947db..32ddba6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c
@@ -34,3 +34,5 @@ TEST_ALL (TEST_LOOP)
/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-1.c
new file mode 100644
index 0000000..154c535
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+#define INDEX16 uint16_t
+#define INDEX32 uint32_t
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-10.c
new file mode 100644
index 0000000..c0fe926
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-10.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 int64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-11.c
new file mode 100644
index 0000000..2a38273
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-11.c
@@ -0,0 +1,114 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(DATA_TYPE, INDEX_TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE##_##INDEX_TYPE (DATA_TYPE *restrict y, DATA_TYPE *restrict x, \
+ INDEX_TYPE *restrict index, \
+ INDEX_TYPE *restrict cond) \
+ { \
+ for (int i = 0; i < 100; ++i) \
+ { \
+ if (cond[i * 2]) \
+ y[i * 2] = x[index[i * 2]] + 1; \
+ if (cond[i * 2 + 1]) \
+ y[i * 2 + 1] = x[index[i * 2 + 1]] + 2; \
+ } \
+ }
+
+TEST_LOOP (int8_t, int8_t)
+TEST_LOOP (uint8_t, int8_t)
+TEST_LOOP (int16_t, int8_t)
+TEST_LOOP (uint16_t, int8_t)
+TEST_LOOP (int32_t, int8_t)
+TEST_LOOP (uint32_t, int8_t)
+TEST_LOOP (int64_t, int8_t)
+TEST_LOOP (uint64_t, int8_t)
+TEST_LOOP (_Float16, int8_t)
+TEST_LOOP (float, int8_t)
+TEST_LOOP (double, int8_t)
+TEST_LOOP (int8_t, int16_t)
+TEST_LOOP (uint8_t, int16_t)
+TEST_LOOP (int16_t, int16_t)
+TEST_LOOP (uint16_t, int16_t)
+TEST_LOOP (int32_t, int16_t)
+TEST_LOOP (uint32_t, int16_t)
+TEST_LOOP (int64_t, int16_t)
+TEST_LOOP (uint64_t, int16_t)
+TEST_LOOP (_Float16, int16_t)
+TEST_LOOP (float, int16_t)
+TEST_LOOP (double, int16_t)
+TEST_LOOP (int8_t, int32_t)
+TEST_LOOP (uint8_t, int32_t)
+TEST_LOOP (int16_t, int32_t)
+TEST_LOOP (uint16_t, int32_t)
+TEST_LOOP (int32_t, int32_t)
+TEST_LOOP (uint32_t, int32_t)
+TEST_LOOP (int64_t, int32_t)
+TEST_LOOP (uint64_t, int32_t)
+TEST_LOOP (_Float16, int32_t)
+TEST_LOOP (float, int32_t)
+TEST_LOOP (double, int32_t)
+TEST_LOOP (int8_t, int64_t)
+TEST_LOOP (uint8_t, int64_t)
+TEST_LOOP (int16_t, int64_t)
+TEST_LOOP (uint16_t, int64_t)
+TEST_LOOP (int32_t, int64_t)
+TEST_LOOP (uint32_t, int64_t)
+TEST_LOOP (int64_t, int64_t)
+TEST_LOOP (uint64_t, int64_t)
+TEST_LOOP (_Float16, int64_t)
+TEST_LOOP (float, int64_t)
+TEST_LOOP (double, int64_t)
+TEST_LOOP (int8_t, uint8_t)
+TEST_LOOP (uint8_t, uint8_t)
+TEST_LOOP (int16_t, uint8_t)
+TEST_LOOP (uint16_t, uint8_t)
+TEST_LOOP (int32_t, uint8_t)
+TEST_LOOP (uint32_t, uint8_t)
+TEST_LOOP (int64_t, uint8_t)
+TEST_LOOP (uint64_t, uint8_t)
+TEST_LOOP (_Float16, uint8_t)
+TEST_LOOP (float, uint8_t)
+TEST_LOOP (double, uint8_t)
+TEST_LOOP (int8_t, uint16_t)
+TEST_LOOP (uint8_t, uint16_t)
+TEST_LOOP (int16_t, uint16_t)
+TEST_LOOP (uint16_t, uint16_t)
+TEST_LOOP (int32_t, uint16_t)
+TEST_LOOP (uint32_t, uint16_t)
+TEST_LOOP (int64_t, uint16_t)
+TEST_LOOP (uint64_t, uint16_t)
+TEST_LOOP (_Float16, uint16_t)
+TEST_LOOP (float, uint16_t)
+TEST_LOOP (double, uint16_t)
+TEST_LOOP (int8_t, uint32_t)
+TEST_LOOP (uint8_t, uint32_t)
+TEST_LOOP (int16_t, uint32_t)
+TEST_LOOP (uint16_t, uint32_t)
+TEST_LOOP (int32_t, uint32_t)
+TEST_LOOP (uint32_t, uint32_t)
+TEST_LOOP (int64_t, uint32_t)
+TEST_LOOP (uint64_t, uint32_t)
+TEST_LOOP (_Float16, uint32_t)
+TEST_LOOP (float, uint32_t)
+TEST_LOOP (double, uint32_t)
+TEST_LOOP (int8_t, uint64_t)
+TEST_LOOP (uint8_t, uint64_t)
+TEST_LOOP (int16_t, uint64_t)
+TEST_LOOP (uint16_t, uint64_t)
+TEST_LOOP (int32_t, uint64_t)
+TEST_LOOP (uint32_t, uint64_t)
+TEST_LOOP (int64_t, uint64_t)
+TEST_LOOP (uint64_t, uint64_t)
+TEST_LOOP (_Float16, uint64_t)
+TEST_LOOP (float, uint64_t)
+TEST_LOOP (double, uint64_t)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 88 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-assembler-not {vlse64\.v\s+v[0-9]+,\s*0\([a-x0-9]+\),\s*zero} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-2.c
new file mode 100644
index 0000000..b586d64
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-2.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 int8_t
+#define INDEX16 int16_t
+#define INDEX32 int32_t
+#define INDEX64 int64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-3.c
new file mode 100644
index 0000000..11818a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-3.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-4.c
new file mode 100644
index 0000000..3660198
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-4.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 int8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-5.c
new file mode 100644
index 0000000..3058974
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-5.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 uint16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-6.c
new file mode 100644
index 0000000..a8cc99a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-6.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 int16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-7.c
new file mode 100644
index 0000000..9639235
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-7.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 uint32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-8.c
new file mode 100644
index 0000000..a2526ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-8.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 int32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-9.c
new file mode 100644
index 0000000..0eb5744
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_64-9.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[i] += src[indices[i]]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c
index fb34285..913d2f7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-1.c"
+#include "mask_gather_load_64-1.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c
index 531f298..3336a18 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-10.c"
+#include "mask_gather_load_64-10.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c
index 0ce20a8..eba0be9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "mask_gather_load-11.c"
+#include "mask_gather_load_64-11.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c
index 8bb78aea..50a9490 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-2.c"
+#include "mask_gather_load_64-2.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c
index 0472ed0..ba93eb8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-3.c"
+#include "mask_gather_load_64-3.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c
index 4fab81a..d96fc13 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-4.c"
+#include "mask_gather_load_64-4.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c
index 8db1ea1..05fdae3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-5.c"
+#include "mask_gather_load_64-5.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c
index d58bc80..175ce08 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-6.c"
+#include "mask_gather_load_64-6.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c
index cc49571..5a82541 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "mask_gather_load-7.c"
+#include "mask_gather_load_64-7.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c
index 4745985..4195f26 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "mask_gather_load-8.c"
+#include "mask_gather_load_64-8.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c
index 32924f0..686d0a5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_gather_load-9.c"
+#include "mask_gather_load_64-9.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c
new file mode 100644
index 0000000..39e09f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+#define INDEX16 uint16_t
+#define INDEX32 uint32_t
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c
new file mode 100644
index 0000000..b1a2344
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 int64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c
new file mode 100644
index 0000000..b522193
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 int8_t
+#define INDEX16 int16_t
+#define INDEX32 int32_t
+#define INDEX64 int64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c
new file mode 100644
index 0000000..4706d0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c
new file mode 100644
index 0000000..aec7a93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 int8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c
new file mode 100644
index 0000000..286e2db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 uint16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c
new file mode 100644
index 0000000..7674e2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 int16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c
new file mode 100644
index 0000000..1738f73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 uint32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c
new file mode 100644
index 0000000..d819a1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 int32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c
new file mode 100644
index 0000000..ee453e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* For some reason we exceed
+ the default code model's +-2 GiB limits. We should investigate why and
+ add a proper description here. For now just make sure the test case
+ compiles properly. */
+/* { dg-additional-options "-mcmodel=medany" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ if (cond[i]) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c
index 0099ed3..27c982a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c
index 089ec48..93f3369 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c
index 57a1ace..cbb2250 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c
index ba89eb3..93a8405 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c
index 2d6499f..c5816e0 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c
index f55db71..c140d05 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c
index a7ec279..41a03d3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c
index b7bd3f4..f29ae25 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c
index f2ab865..8d72d98 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c
index 42ce1c5..dfd9412 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
/* For some reason we exceed
the default code model's +-2 GiB limits. We should investigate why and
add a proper description here. For now just make sure the test case
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c
index cf89555..077bf82 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-1.c"
+#include "mask_scatter_store_64-1.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c
index 6e5dc5d..a1e8df1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-10.c"
+#include "mask_scatter_store_64-10.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c
index 197b443..5ee2717 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-2.c"
+#include "mask_scatter_store_64-2.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c
index 81059e4..b77fb63 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-3.c"
+#include "mask_scatter_store_64-3.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c
index a50b6d2..0a8b4a5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-4.c"
+#include "mask_scatter_store_64-4.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c
index 645e3a5..8eca62b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-5.c"
+#include "mask_scatter_store_64-5.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c
index 52032ba..4bcaf42 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-6.c"
+#include "mask_scatter_store_64-6.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c
index 38b0595..7e4b1d8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "mask_scatter_store-7.c"
+#include "mask_scatter_store_64-7.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c
index fcb3110..0189aa8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c
@@ -5,7 +5,7 @@
compiles properly. */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "mask_scatter_store-8.c"
+#include "mask_scatter_store_64-8.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c
index c120e68..e2a3a8c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "mask_scatter_store-9.c"
+#include "mask_scatter_store_64-9.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c
new file mode 100644
index 0000000..4ad244b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+#define INDEX16 uint16_t
+#define INDEX32 uint32_t
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c
new file mode 100644
index 0000000..a44cbc1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 int64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c
new file mode 100644
index 0000000..35e9701
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 uint8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c
new file mode 100644
index 0000000..fb72b09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX8 int8_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 8) \
+ T (uint8_t, 8) \
+ T (int16_t, 8) \
+ T (uint16_t, 8) \
+ T (_Float16, 8) \
+ T (int32_t, 8) \
+ T (uint32_t, 8) \
+ T (float, 8) \
+ T (int64_t, 8) \
+ T (uint64_t, 8) \
+ T (double, 8)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c
new file mode 100644
index 0000000..7b562bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 uint16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c
new file mode 100644
index 0000000..67ea0e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX16 int16_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 16) \
+ T (uint8_t, 16) \
+ T (int16_t, 16) \
+ T (uint16_t, 16) \
+ T (_Float16, 16) \
+ T (int32_t, 16) \
+ T (uint32_t, 16) \
+ T (float, 16) \
+ T (int64_t, 16) \
+ T (uint64_t, 16) \
+ T (double, 16)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c
new file mode 100644
index 0000000..76f8485
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 uint32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c
new file mode 100644
index 0000000..e6e4901
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX32 int32_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 32) \
+ T (uint8_t, 32) \
+ T (int16_t, 32) \
+ T (uint16_t, 32) \
+ T (_Float16, 32) \
+ T (int32_t, 32) \
+ T (uint32_t, 32) \
+ T (float, 32) \
+ T (int64_t, 32) \
+ T (uint64_t, 32) \
+ T (double, 32)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c
new file mode 100644
index 0000000..81eb935
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define INDEX64 uint64_t
+
+#define TEST_LOOP(DATA_TYPE, BITS) \
+ void __attribute__ ((noinline, noclone)) \
+ f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \
+ INDEX##BITS *restrict indices) \
+ { \
+ for (int i = 0; i < 128; ++i) \
+ dest[indices[i]] = src[i] + 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 64) \
+ T (uint8_t, 64) \
+ T (int16_t, 64) \
+ T (uint16_t, 64) \
+ T (_Float16, 64) \
+ T (int32_t, 64) \
+ T (uint32_t, 64) \
+ T (float, 64) \
+ T (int64_t, 64) \
+ T (uint64_t, 64) \
+ T (double, 64)
+
+TEST_ALL (TEST_LOOP)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */
+/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c
index 28c4bae..343a365 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c
index 2cd3e72..76b0b07 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c
index ee44f41..7eb8819 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c
index 899b05f..47e8ce3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c
index ff6d90c..5c51741 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c
index 212bd2d..cc0b2fe 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c
index 4b6b39d..3408cbd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c
index 2415c69..f45c9bc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c
index 4c2fcb1..64fe305 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c
index 0f4f94c..bd1538d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c
index 91edba7..ec1e020 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "scatter_store-1.c"
+#include "scatter_store_64-1.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c
index 40e34c6..d61a37a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "scatter_store-10.c"
+#include "scatter_store_64-10.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c
index 721c6f6..c1c3200 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "scatter_store-2.c"
+#include "scatter_store_64-2.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c
index 8d268a6..8234f84 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "scatter_store-3.c"
+#include "scatter_store_64-3.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c
index 3931a81..b137e1d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "scatter_store-4.c"
+#include "scatter_store_64-4.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c
index ff30630..1290f87 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "scatter_store-5.c"
+#include "scatter_store_64-5.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c
index a30c47d..79b1ea7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
-#include "scatter_store-6.c"
+#include "scatter_store_64-6.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c
index 94ab404..c204e7c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c
@@ -5,7 +5,7 @@
compiles properly. */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "scatter_store-7.c"
+#include "scatter_store_64-7.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c
index 16c1e17..1dafaba 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c
@@ -5,7 +5,7 @@
compiles properly. */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "scatter_store-8.c"
+#include "scatter_store_64-8.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c
index a91b500..1b37cac 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { riscv_v } } } */
/* { dg-additional-options "-mcmodel=medany" } */
-#include "scatter_store-9.c"
+#include "scatter_store_64-9.c"
#include <assert.h>
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/post-ra-avl.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/post-ra-avl.c
new file mode 100644
index 0000000..f3d12ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/post-ra-avl.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+int a, b, c, e;
+short d[7][7] = {};
+int foo() {
+ short f;
+ c = 0;
+ for (; c <= 6; c++) {
+ e |= d[c][c] & 1;
+ b &= f & 3;
+ }
+ return a;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112438.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112438.c
index 51f90df..d6770af 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112438.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112438.c
@@ -31,3 +31,4 @@ float * __restrict out, float x)
}
/* We don't want to see vect_vec_iv_.21_25 + { POLY_INT_CST [4, 4], ... }. */
+/* { dg-final { scan-tree-dump-not "\\+ \{ POLY_INT_CST" "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112597-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112597-1.c
new file mode 100644
index 0000000..73aa3ee2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112597-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv_zvl256b -mabi=ilp32d -O3 --param riscv-autovec-preference=fixed-vlmax" } */
+
+#include <stdint-gcc.h>
+
+typedef int64_t vnx2di __attribute__ ((vector_size (16)));
+
+__attribute__ ((noipa)) void
+f_vnx2di (int64_t a, int64_t b, int64_t *out)
+{
+ vnx2di v = {a, b};
+ *(vnx2di *) out = v;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-1.c
new file mode 100644
index 0000000..a1d7e5b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-1.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv_zvfh_zfh_zvl512b -mabi=ilp32d -O3 --param=riscv-autovec-lmul=m8 -O3 -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+#define TEST_UNARY_CALL_CVT(TYPE_IN, TYPE_OUT, CALL) \
+ void test_##TYPE_IN##_##TYPE_OUT##_##CALL ( \
+ TYPE_OUT *out, TYPE_IN *in, unsigned count) \
+ { \
+ for (unsigned i = 0; i < count; i++) \
+ out[i] = CALL (in[i]); \
+ }
+#define TEST_ASSERT(TYPE) \
+ void test_##TYPE##_assert (TYPE *out, TYPE *ref, unsigned size) \
+ { \
+ for (unsigned i = 0; i < size; i++) \
+ { \
+ if (out[i] != ref[i]) \
+ __builtin_abort (); \
+ } \
+ }
+#define TEST_INIT_CVT(TYPE_IN, VAL_IN, TYPE_REF, VAL_REF, NUM) \
+ void test_##TYPE_IN##_##TYPE_REF##_init_##NUM ( \
+ TYPE_IN *in, TYPE_REF *ref, unsigned size) \
+ { \
+ for (unsigned i = 0; i < size; i++) \
+ { \
+ in[i] = VAL_IN; \
+ ref[i] = VAL_REF; \
+ } \
+ }
+#define RUN_TEST_CVT(TYPE_IN, TYPE_OUT, NUM, CALL, IN, OUT, REF, SIZE) \
+ test_##TYPE_IN##_##TYPE_OUT##_init_##NUM (IN, REF, SIZE); \
+ test_##TYPE_IN##_##TYPE_OUT##_##CALL (OUT, IN, SIZE); \
+ test_##TYPE_OUT##_assert (OUT, REF, SIZE);
+
+#define ARRAY_SIZE 128
+
+float in[ARRAY_SIZE];
+int64_t out[ARRAY_SIZE];
+int64_t ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (float, int64_t, __builtin_llceilf)
+
+TEST_ASSERT (int64_t)
+
+
+TEST_INIT_CVT (float, 9223372036854775808.0, int64_t, 0x7fffffffffffffff, 26)
+TEST_INIT_CVT (float, __builtin_inf (), int64_t, __builtin_llceilf (__builtin_inf ()), 29)
+
+int64_t
+main ()
+{
+ RUN_TEST_CVT (float, int64_t, 26, __builtin_llceilf, in, out, ref, ARRAY_SIZE);
+ RUN_TEST_CVT (float, int64_t, 29, __builtin_llceilf, in, out, ref, ARRAY_SIZE);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-2.c
new file mode 100644
index 0000000..d32e8ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-2.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zfh_zvl512b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include <stdint-gcc.h>
+
+void
+f (uint8_t *restrict a, uint8_t *restrict b, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[i * 8] = b[i * 8 + 3] + 1;
+ a[i * 8 + 1] = b[i * 8 + 2] + 2;
+ a[i * 8 + 2] = b[i * 8 + 1] + 3;
+ a[i * 8 + 3] = b[i * 8 + 0] + 4;
+ a[i * 8 + 4] = b[i * 8 + 7] + 5;
+ a[i * 8 + 5] = b[i * 8 + 6] + 6;
+ a[i * 8 + 6] = b[i * 8 + 5] + 7;
+ a[i * 8 + 7] = b[i * 8 + 4] + 8;
+ }
+}
+
+/* We don't want EEW8 LMUL8 vrgather.vv. */
+/* { dg-final { scan-assembler-not {vrgather\.vv} } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-3.c
new file mode 100644
index 0000000..231a068
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112598-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv_zvfh_zfh_zvl512b -mabi=ilp32d -O3 -ftree-vectorize -std=c99 -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#define TYPE uint64_t
+#define ITYPE int64_t
+
+void __attribute__ ((noinline, noclone))
+foo (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+ TYPE *__restrict d, ITYPE n)
+{
+ for (ITYPE i = 0; i < n; ++i)
+ {
+ d[i * 3] = a[i];
+ d[i * 3 + 1] = b[i];
+ d[i * 3 + 2] = c[i];
+ }
+}
+
+/* We don't want vcompress.vv. */
+/* { dg-final { scan-assembler-not {vcompress\.vv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-1.c
new file mode 100644
index 0000000..911b692
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zfh_zvl1024b -mabi=lp64d -O3 --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "riscv_vector.h"
+
+typedef int64_t v1024b __attribute__ ((vector_size (128)));
+
+void foo (void *out, void *in, int64_t a, int64_t b)
+{
+ v1024b v = {a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a};
+ v1024b v2 = {b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b};
+ v1024b index = *(v1024b*)in;
+ v1024b v3 = __builtin_shuffle (v, v2, index);
+ __riscv_vse64_v_i64m1 (out, (vint64m1_t)v3, 10);
+}
+
+/* { dg-final { scan-assembler {vsetivli\s+zero,\s*16} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-2.c
new file mode 100644
index 0000000..fd87565
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl1024b -mabi=lp64d -O3" } */
+
+struct s { struct s *n; } *p;
+struct s ss;
+#define MAX 10
+struct s sss[MAX];
+int count = 0;
+
+int look( struct s *p, struct s **pp )
+{
+ for ( ; p; p = p->n )
+ ;
+ *pp = p;
+ count++;
+ return( 1 );
+}
+
+void sub( struct s *p, struct s **pp )
+{
+ for ( ; look( p, pp ); ) {
+ if ( p )
+ p = p->n;
+ else
+ break;
+ }
+}
+
+int
+foo(void)
+{
+ struct s *pp;
+ struct s *next;
+ int i;
+
+ p = &ss;
+ next = p;
+ for ( i = 0; i < MAX; i++ ) {
+ next->n = &sss[i];
+ next = next->n;
+ }
+ next->n = 0;
+
+ sub( p, &pp );
+ if (count != MAX+2)
+ __builtin_abort ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not {vrgather} } } */
+/* { dg-final { scan-assembler-times {vslide1up\.vx} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-3.c
new file mode 100644
index 0000000..0954fe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112599-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zfh_zvl1024b -mabi=lp64d -O3 --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "riscv_vector.h"
+
+typedef int64_t v1024b __attribute__ ((vector_size (128)));
+
+void foo (void *out, void *in, int64_t a, int64_t b, int64_t c, int64_t d, int64_t e)
+{
+ v1024b v = {a,a,a,a,a,a,a,a,a,a,a,a,b,c,d,e};
+ __riscv_vse64_v_i64m1 (out, (vint64m1_t)v, 12);
+}
+
+/* { dg-final { scan-assembler {vsetivli\s+zero,\s*16} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112694-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112694-1.c
new file mode 100644
index 0000000..8c7f7a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112694-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d_zvfh_zfh -mabi=ilp32d -mcmodel=medany -fdiagnostics-plain-output -ftree-vectorize -O2 --param riscv-autovec-lmul=m1 -std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__((noipa)) \
+ void vmul_##TYPE (TYPE *dst, TYPE *a, TYPE *b, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = a[i] * b[i]; \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE(_Float16) \
+
+TEST_ALL()
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE, VAL) \
+ TYPE a##TYPE[SZ]; \
+ TYPE b##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ a##TYPE[i] = 2; \
+ b##TYPE[i] = VAL; \
+ } \
+ vmul_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (a##TYPE[i] == 2 * VAL);
+
+#define RUN_ALL() \
+ RUN(_Float16, 4) \
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c
index a0d5904..0f95e61 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c
@@ -1,5 +1,4 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */
#define N 0x1100
@@ -14,8 +13,8 @@ main (void)
if (add_loop (x, 0, 33) != 33
|| add_loop (x, 11, 30) != 4078
- || add_loop (x, 0x100, 45) != 45001773
- || add_loop (x, 0x11f, 300) != 63369900)
+ || add_loop (x, 0x100, 45) != 45001776
+ || add_loop (x, 0x11f, 300) != 63369904)
__builtin_abort ();
return 0;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount.c
index 585a522..ca1319c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount.c
@@ -1461,4 +1461,12 @@ main ()
RUN_ALL ()
}
-/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 229 "vect" } } */
+/* TODO: Due to an over-zealous check in tree-vect-patterns we do not vectorize
+ e.g.
+ uint64_t dst[];
+ uint32_t src[];
+ dst[i] = __builtin_popcountll (src[i]);
+ even though we could. Therefore, for now, adjust the following checks.
+ This difference was exposed in r14-5557-g6dd4c703be17fa. */
+/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 229 "vect" { target { { rv64 } && { ! riscv_zbb } } } } } */
+/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 250 "vect" { target { { rv32 } || { riscv_zbb } } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c
index b235ec7..7ab3104 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c
@@ -55,7 +55,7 @@
TEST_ALL (PERMUTE)
-/* { dg-final { scan-assembler-times {vrgather\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 18 } } */
+/* { dg-final { scan-assembler-times {vrgather\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 19 } } */
/* { dg-final { scan-assembler-times {vrgatherei16\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 12 } } */
-/* { dg-final { scan-assembler-times {vrsub\.vi} 23 } } */
+/* { dg-final { scan-assembler-times {vrsub\.vi} 24 } } */
/* { dg-final { scan-assembler-times {vrsub\.vx} 7 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c
index d2d4938..4d6862c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c
@@ -3,7 +3,7 @@
#include "../vls-vlmax/perm-4.c"
-/* { dg-final { scan-assembler-times {vrgather\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 18 } } */
+/* { dg-final { scan-assembler-times {vrgather\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 19 } } */
/* { dg-final { scan-assembler-times {vrgatherei16\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 12 } } */
-/* { dg-final { scan-assembler-times {vrsub\.vi} 23 } } */
+/* { dg-final { scan-assembler-times {vrsub\.vi} 24 } } */
/* { dg-final { scan-assembler-times {vrsub\.vx} 7 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-1.c
new file mode 100644
index 0000000..ae49706
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -mmemcpy-strategy=libcall" } */
+
+#include "cpymem-strategy.h"
+
+/* { dg-final { scan-assembler-times {call\tmemcpy} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-2.c
new file mode 100644
index 0000000..73ffc57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32gcv -mabi=ilp32d -mmemcpy-strategy=scalar" } */
+
+#include "cpymem-strategy.h"
+
+/* { dg-final { scan-assembler-times {call\tmemcpy} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-3.c
new file mode 100644
index 0000000..44f5f78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-3.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -mmemcpy-strategy=vector" } */
+
+#include "cpymem-strategy.h"
+
+/* { dg-final { scan-assembler-times {v[ls]+e[0-9]+\.v\tv[0-9]+\,0\([a-z0-9]+\)} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-4.c
new file mode 100644
index 0000000..8056895
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -mmemcpy-strategy=auto" } */
+
+#include "cpymem-strategy.h"
+
+/* { dg-final { scan-assembler-times {v[ls]+e[0-9]+\.v\tv[0-9]+\,0\([a-z0-9]+\)} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-5.c
new file mode 100644
index 0000000..82ecab0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy-5.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -mmemcpy-strategy=vector" } */
+
+#include "cpymem-strategy.h"
+
+/* { dg-final { scan-assembler-times {call\tmemcpy} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy.h b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy.h
new file mode 100644
index 0000000..700d224
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/cpymem-strategy.h
@@ -0,0 +1,12 @@
+typedef struct { unsigned char a[56]; } a56;
+typedef struct { int b[32]; } b32;
+
+void f1 (a56 *v1, a56 *v2)
+{
+ *v1 = *v2;
+}
+
+void f2 (b32 *v1, b32 *v2)
+{
+ *v1 = *v2;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c
new file mode 100644
index 0000000..a61e94a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vuint8m1_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vle8_v_u8m1(arr, 32);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c
new file mode 100644
index 0000000..46efd73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vuint8m2_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vle8_v_u8m2(arr, 32);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[09]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
new file mode 100644
index 0000000..8bebac2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vbool4_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vlm_v_b4(arr, 32);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c
new file mode 100644
index 0000000..47e4243
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vuint8m1_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vle8_v_u8m1(arr, 16);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c
new file mode 100644
index 0000000..5331e54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vuint8m2_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vle8_v_u8m2(arr, 8);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[09]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c
new file mode 100644
index 0000000..0c728f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vuint8mf2_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vle8_v_u8mf2(arr, 32);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c
new file mode 100644
index 0000000..ccfc40c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vuint8m2_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vle8_v_u8m2(arr, 4);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[09]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c
new file mode 100644
index 0000000..ce7ddbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vuint8m8_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ return __riscv_vle8_v_u8m8(arr, 32);
+}
+
+/* { dg-final { scan-assembler-times {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} 1 } } */
+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c
new file mode 100644
index 0000000..ac0100a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vbool8_t test () {
+ uint8_t arr[32] = {
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ 1, 2, 7, 1, 3, 4, 5, 3,
+ 1, 0, 1, 2, 4, 4, 9, 9,
+ };
+
+ vuint8m1_t varr = __riscv_vle8_v_u8m1(arr, 32);
+ vuint8m1_t vand_m = __riscv_vand_vx_u8m1(varr, 1, 32);
+
+ return __riscv_vreinterpret_v_u8m1_b8(vand_m);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c
new file mode 100644
index 0000000..b7ebef8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t test () {
+ float arr[32] = {
+ 1.0, 2.2, 7.8, 1.2, 3.3, 4.7, 5.5, 3.3,
+ 1.0, 0.2, 1.8, 2.2, 4.3, 4.7, 9.5, 9.3,
+ 1.0, 2.2, 7.8, 1.2, 3.3, 4.7, 5.5, 3.3,
+ 1.0, 0.2, 1.8, 2.2, 4.3, 4.7, 9.5, 9.3,
+ };
+
+ return __riscv_vle32_v_f32m1(arr, 32);
+}
+
+/* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
+/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c
new file mode 100644
index 0000000..21fed06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat64m8_t test () {
+ double arr[8] = {
+ 1.0, 2.2, 7.8, 1.2, 3.3, 4.7, 5.5, 3.3,
+ };
+
+ return __riscv_vle64_v_f64m8(arr, 4);
+}
+
+/* { dg-final { scan-assembler-times {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} 1 } } */
+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vf_avl-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vf_avl-1.c
index 11adf6b..8f352db 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/vf_avl-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vf_avl-1.c
@@ -12,4 +12,4 @@ f_vnx2qi (int8_t a, int8_t b, int8_t *out)
*(vnx2qi *) out = v;
}
-/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*2,\s*e8,\s*mf8,\s*t[au],\s*m[au]} 1 } } */
+/* { dg-final { scan-assembler {vsetivli\s+zero,\s*2,\s*e8,\s*mf8,\s*t[au],\s*m[au]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
index 237a20e..1d5041b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
@@ -30,18 +30,11 @@ if ![info exists DEFAULT_CFLAGS] then {
set DEFAULT_CFLAGS " -ansi -pedantic-errors"
}
-set gcc_march "rv64gcv_zfh"
-set gcc_mabi "lp64d"
-if [istarget riscv32-*-*] then {
- set gcc_march "rv32gcv_zfh"
- set gcc_mabi "ilp32d"
-}
-
# Initialize `dg'.
dg-init
# Main loop.
-set CFLAGS "$DEFAULT_CFLAGS -march=$gcc_march -mabi=$gcc_mabi -O3"
+set CFLAGS "$DEFAULT_CFLAGS -O3"
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/base/*.\[cS\]]] \
"" $CFLAGS
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vsetvl/*.\[cS\]]] \
diff --git a/gcc/testsuite/gcc.target/riscv/smax-ieee.c b/gcc/testsuite/gcc.target/riscv/smax-ieee.c
index 2dbccef..775e515 100644
--- a/gcc/testsuite/gcc.target/riscv/smax-ieee.c
+++ b/gcc/testsuite/gcc.target/riscv/smax-ieee.c
@@ -10,4 +10,4 @@ smax (double x, double y)
/* { dg-final { scan-assembler-not "\t(call|tail)\tfmax\t" } } */
/* { dg-final { scan-assembler-not "\tfmax\\.d\t" } } */
-/* { dg-final { scan-assembler "\tfge\\.d\t" } } */
+/* { dg-final { scan-assembler "\t(fge\\.d|flt\\.d)\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c b/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c
index 31b9bfa..c794bc3 100644
--- a/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c
+++ b/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c
@@ -10,4 +10,4 @@ smaxf (float x, float y)
/* { dg-final { scan-assembler-not "\t(call|tail)\tfmaxf\t" } } */
/* { dg-final { scan-assembler-not "\tfmax\\.s\t" } } */
-/* { dg-final { scan-assembler "\tfge\\.s\t" } } */
+/* { dg-final { scan-assembler "\t(fge\\.s|flt\\.s)\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/smin-ieee.c b/gcc/testsuite/gcc.target/riscv/smin-ieee.c
index ea36c2d..28cedd3 100644
--- a/gcc/testsuite/gcc.target/riscv/smin-ieee.c
+++ b/gcc/testsuite/gcc.target/riscv/smin-ieee.c
@@ -10,4 +10,4 @@ smin (double x, double y)
/* { dg-final { scan-assembler-not "\t(call|tail)\tfmin\t" } } */
/* { dg-final { scan-assembler-not "\tfmin\\.d\t" } } */
-/* { dg-final { scan-assembler "\tfle\\.d\t" } } */
+/* { dg-final { scan-assembler "\t(fgt\\.d|fle\\.d)\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sminf-ieee.c b/gcc/testsuite/gcc.target/riscv/sminf-ieee.c
index 427617a..18d4858 100644
--- a/gcc/testsuite/gcc.target/riscv/sminf-ieee.c
+++ b/gcc/testsuite/gcc.target/riscv/sminf-ieee.c
@@ -10,4 +10,4 @@ sminf (float x, float y)
/* { dg-final { scan-assembler-not "\t(call|tail)\tfminf\t" } } */
/* { dg-final { scan-assembler-not "\tfmin\\.s\t" } } */
-/* { dg-final { scan-assembler "\tfle\\.s\t" } } */
+/* { dg-final { scan-assembler "\t(fgt\\.s|fle\\.s)\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bext-02.c b/gcc/testsuite/gcc.target/riscv/zbs-bext-02.c
index 8c5d8c7..81d826d 100644
--- a/gcc/testsuite/gcc.target/riscv/zbs-bext-02.c
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bext-02.c
@@ -15,4 +15,4 @@ foo(const long long B, int a)
/* { dg-final { scan-assembler-times "bext\t" 1 } } */
/* { dg-final { scan-assembler-not {\mbset} } } */
-/* { dg-final { scan-assembler-not {\mand} } } */
+/* { dg-final { scan-assembler-not {\msll} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
index e806f6f..4015220 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
long primitiveSemantics_compare_imm_return_imm_imm_00(long a, long b) {
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
index f976d60..dd3665c4 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
long primitiveSemantics_compare_imm_return_imm_reg_00(long a, long b) {
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
index 90e9119..19ca4a4 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
long primitiveSemantics_compare_imm_return_reg_reg_00(long a, long b, long c) {
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
index 8ad97ab..e670d1d 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
long primitiveSemantics_compare_reg_return_imm_imm_00(long a, long b, long c) {
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
index 5199ba7..e25487c 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
long primitiveSemantics_compare_reg_return_imm_reg_00(long a, long b, long c) {
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
index eecb956..765c0e0 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
long primitiveSemantics_compare_reg_return_reg_reg_00(long a, long b, long c,
diff --git a/gcc/testsuite/gcc.target/s390/ccor.c b/gcc/testsuite/gcc.target/s390/ccor.c
new file mode 100644
index 0000000..31f30f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/ccor.c
@@ -0,0 +1,88 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=zEC12 -mzarch" } */
+
+#define GENFUN1(C) \
+ int foo_ ##C(int x) \
+ { \
+ int cc; \
+ asm volatile ("ahi %[x],42\n" \
+ : [x] "+d"(x), "=@cc" (cc)); \
+ return cc == C ? 42 : 0; \
+ }
+
+#define GENFUN2(C1,C2) \
+ int foo_ ##C1##C2(int x) \
+ { \
+ int cc; \
+ asm volatile ("ahi %[x],42\n" \
+ : [x] "+d"(x), "=@cc" (cc)); \
+ return cc == C1 || cc == C2 ? 42 : 0; \
+ }
+
+#define GENFUN3(C1,C2,C3) \
+ int foo_ ##C1##C2##C3(int x) \
+ { \
+ int cc; \
+ asm volatile ("ahi %[x],42\n" \
+ : [x] "+d"(x), "=@cc" (cc)); \
+ return cc == C1 || cc == C2 || cc == C3 ? 42 : 0; \
+ }
+
+GENFUN1(0)
+
+/* { dg-final { scan-assembler {locrne} } } */
+
+GENFUN1(1)
+
+/* { dg-final { scan-assembler {locrnl} } } */
+
+GENFUN1(2)
+
+/* { dg-final { scan-assembler {locrnh} } } */
+
+GENFUN1(3)
+
+/* { dg-final { scan-assembler {locrno} } } */
+
+GENFUN2(0,1)
+
+/* { dg-final { scan-assembler {locrnle} } } */
+
+GENFUN2(0,2)
+
+/* { dg-final { scan-assembler {locrhe} } } */
+
+GENFUN2(0,3)
+
+/* currently unoptimized */
+
+GENFUN2(1,2)
+
+/* { dg-final { scan-assembler {locrnlh} } } */
+
+GENFUN2(1,3)
+
+/* { dg-final { scan-assembler {locrnhe} } } */
+
+GENFUN2(2,3)
+
+/* { dg-final { scan-assembler {locrle} } } */
+
+GENFUN3(0,1,2)
+
+/* { dg-final { scan-assembler {locrh} } } */
+
+GENFUN3(0,1,3)
+
+/* currently unoptimized */
+
+GENFUN3(0,2,3)
+
+/* currently unoptimized */
+
+GENFUN3(1,2,3)
+
+/* { dg-final { scan-assembler {locre} } } */
+
+/* for the unoptimized cases, we get an ipm */
+/* { dg-final { scan-assembler-times {ipm} 3 } } */
diff --git a/gcc/testsuite/gcc.target/s390/int128load.c b/gcc/testsuite/gcc.target/s390/int128load.c
new file mode 100644
index 0000000..3eb335c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/int128load.c
@@ -0,0 +1,14 @@
+/* Check that int128 loads and stores are split. */
+
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -mzarch -march=zEC12" } */
+
+__int128 global;
+
+void f(__int128 x)
+{
+ global = x;
+}
+
+/* { dg-final { scan-assembler-times "lg\t" 2 } } */
+/* { dg-final { scan-assembler-times "stg\t" 2 } } */
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp16-convert.c b/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp16-convert.c
index 5ed7e05..7d7c13e 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp16-convert.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp16-convert.c
@@ -10,10 +10,10 @@ main ()
vector float fp1 = (vector float){ 1.0f, 2.0f, 3.0f, 4.0f };
vector float fp2 = (vector float){ 5.0f, 6.0f, 7.0f, 8.0f };
- vector short int tmp1 = vec_round_from_fp32 (fp1, fp2, 0);
+ vector unsigned short int tmp1 = vec_round_from_fp32 (fp1, fp2, 0);
- vector short int tmp2 = vec_convert_to_fp16 (tmp1, 0);
- vector short int tmp3 = vec_convert_from_fp16 (tmp2, 0);
+ vector unsigned short int tmp2 = vec_convert_to_fp16 (tmp1, 0);
+ vector unsigned short int tmp3 = vec_convert_from_fp16 (tmp2, 0);
vector float fp1_ret = vec_extend_to_fp32_hi (tmp3, 0);
vector float fp2_ret = vec_extend_to_fp32_lo (tmp3, 0);
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp32-convert-1.c b/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp32-convert-1.c
index 321488a..6dcfad4 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp32-convert-1.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec-nnpa-fp32-convert-1.c
@@ -9,7 +9,7 @@ main ()
{
vector float fp1 = (vector float){ 1.0f, 2.0f, 3.0f, 4.0f };
vector float fp2 = (vector float){ 5.0f, 6.0f, 7.0f, 8.0f };
- vector short int conv = vec_round_from_fp32 (fp1, fp2, 0);
+ vector unsigned short int conv = vec_round_from_fp32 (fp1, fp2, 0);
vector float fp1_ret = vec_extend_to_fp32_hi (conv, 0);
vector float fp2_ret = vec_extend_to_fp32_lo (conv, 0);
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_convert_from_fp16.c b/gcc/testsuite/gcc.target/s390/zvector/vec_convert_from_fp16.c
index fc7ccf0..86fad2c 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec_convert_from_fp16.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec_convert_from_fp16.c
@@ -3,8 +3,8 @@
#include <vecintrin.h>
-vector short int
-test_vec_convert_from_fp16 (vector short int a)
+vector unsigned short int
+test_vec_convert_from_fp16 (vector unsigned short int a)
{
return vec_convert_from_fp16 (a, 0);
}
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_convert_to_fp16.c b/gcc/testsuite/gcc.target/s390/zvector/vec_convert_to_fp16.c
index 7232643..eda2952 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec_convert_to_fp16.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec_convert_to_fp16.c
@@ -3,8 +3,8 @@
#include <vecintrin.h>
-vector short int
-test_vec_convert_to_fp16 (vector short int a)
+vector unsigned short int
+test_vec_convert_to_fp16 (vector unsigned short int a)
{
return vec_convert_to_fp16 (a, 0);
}
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_hi.c b/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_hi.c
index feb5e78..feedef8 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_hi.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_hi.c
@@ -4,7 +4,7 @@
#include <vecintrin.h>
vector float
-test_vec_extend_to_fp32_hi (vector short int a)
+test_vec_extend_to_fp32_hi (vector unsigned short int a)
{
return vec_extend_to_fp32_hi (a, 0);
}
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_lo.c b/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_lo.c
index 179de17..dbdf530 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_lo.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec_extend_to_fp32_lo.c
@@ -4,7 +4,7 @@
#include <vecintrin.h>
vector float
-test_vec_extend_to_fp32_lo (vector short int a)
+test_vec_extend_to_fp32_lo (vector unsigned short int a)
{
return vec_extend_to_fp32_lo (a, 0);
}
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_round_from_fp32.c b/gcc/testsuite/gcc.target/s390/zvector/vec_round_from_fp32.c
index 83924522..617a820 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec_round_from_fp32.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec_round_from_fp32.c
@@ -3,7 +3,7 @@
#include <vecintrin.h>
-vector short int
+vector unsigned short int
test_vec_round_from_fp32 (vector float hi, vector float lo)
{
return vec_round_from_fp32 (hi, lo, 0);
diff --git a/gcc/testsuite/gdc.dg/asm1.d b/gcc/testsuite/gdc.dg/asm1.d
index 1b249ee..1593eb6 100644
--- a/gcc/testsuite/gdc.dg/asm1.d
+++ b/gcc/testsuite/gdc.dg/asm1.d
@@ -58,7 +58,7 @@ void semantic1()
void semantic2a(X...)(X expr)
{
alias X[0] var1;
- asm { "%0" : "=m" (var1); } // { dg-error "double' is a 'double' definition and cannot be modified" }
+ asm { "%0" : "=m" (var1); } // { dg-error "cannot modify type 'double'" }
}
void semantic2()
diff --git a/gcc/testsuite/gdc.test/compilable/issue16020.d b/gcc/testsuite/gdc.test/compilable/issue16020.d
index cfd078c..38a5d62 100644
--- a/gcc/testsuite/gdc.test/compilable/issue16020.d
+++ b/gcc/testsuite/gdc.test/compilable/issue16020.d
@@ -1,3 +1,4 @@
+// function type aliases
module issue16020;
alias F1 = const(int)(); const(int) f1(){return 42;}
@@ -36,4 +37,8 @@ alias Specialized = FunTemplate!int;
alias Compared = void(int);
static assert(is(Specialized == Compared));
-void main() {}
+// type suffixes
+alias FT = const(int)*();
+static assert(is(FT* == const(int)* function()));
+alias FT2 = int*[2]() pure;
+static assert(is(FT2* == int*[2] function() pure));
diff --git a/gcc/testsuite/gdc.test/compilable/nogc.d b/gcc/testsuite/gdc.test/compilable/nogc.d
index 88cf122..959adc4 100644
--- a/gcc/testsuite/gdc.test/compilable/nogc.d
+++ b/gcc/testsuite/gdc.test/compilable/nogc.d
@@ -119,3 +119,12 @@ void f(bool cond, string s) @nogc {
alias Unused2 = typeof(&inner); // (Does not) INFERS GC (anymore)
enum Unused3 = __traits(compiles , &inner);
}
+
+// https://issues.dlang.org/show_bug.cgi?id=24072
+
+version (D_SIMD) void f24072() @nogc
+{
+ alias int4 = __vector(int[4]);
+ int4 b = cast(int4)[1, 2, 3, 4];
+ int4 c = cast(int4)[1, 2];
+}
diff --git a/gcc/testsuite/gdc.test/compilable/previewin.d b/gcc/testsuite/gdc.test/compilable/previewin.d
index 8926fbd..558005c 100644
--- a/gcc/testsuite/gdc.test/compilable/previewin.d
+++ b/gcc/testsuite/gdc.test/compilable/previewin.d
@@ -79,14 +79,11 @@ version (Win64)
{
void checkReal(in real p)
{
- // ref for x87 real, value for double-precision real
- static assert(__traits(isRef, p) == (real.sizeof > 8));
}
struct RGB { ubyte r, g, b; }
void checkNonPowerOf2(in RGB p)
{
- static assert(__traits(isRef, p));
}
}
else version (X86_64) // Posix x86_64
@@ -94,7 +91,6 @@ else version (X86_64) // Posix x86_64
struct Empty {} // 1 dummy byte passed on the stack
void checkEmptyStruct(in Empty p)
{
- static assert(!__traits(isRef, p));
}
static if (is(__vector(double[4])))
@@ -102,7 +98,6 @@ else version (X86_64) // Posix x86_64
struct AvxVectorWrapper { __vector(double[4]) a; } // 256 bits
void checkAvxVector(in AvxVectorWrapper p)
{
- static assert(!__traits(isRef, p));
}
}
}
@@ -111,6 +106,5 @@ else version (AArch64)
alias HVA = __vector(float[4])[4]; // can be passed in 4 vector registers
void checkHVA(in HVA p)
{
- static assert(!__traits(isRef, p));
}
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/b20011.d b/gcc/testsuite/gdc.test/fail_compilation/b20011.d
index 7baad47..3ddcdaa 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/b20011.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/b20011.d
@@ -1,10 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/b20011.d(25): Error: `S1(cast(ubyte)0u).member` is not an lvalue and cannot be modified
-fail_compilation/b20011.d(28): Error: `S2(null).member` is not an lvalue and cannot be modified
-fail_compilation/b20011.d(29): Error: `S2(null).member` is not an lvalue and cannot be modified
-fail_compilation/b20011.d(32): Error: `U1(cast(ubyte)0u, ).m2` is not an lvalue and cannot be modified
+fail_compilation/b20011.d(25): Error: cannot modify expression `S1(cast(ubyte)0u).member` because it is not an lvalue
+fail_compilation/b20011.d(28): Error: cannot modify expression `S2(null).member` because it is not an lvalue
+fail_compilation/b20011.d(29): Error: cannot modify expression `S2(null).member` because it is not an lvalue
+fail_compilation/b20011.d(32): Error: cannot modify expression `U1(cast(ubyte)0u, ).m2` because it is not an lvalue
fail_compilation/b20011.d(37): Error: function `b20011.main.assignableByRef(ref ubyte p)` is not callable using argument types `(ubyte)`
fail_compilation/b20011.d(37): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `ref ubyte p`
fail_compilation/b20011.d(38): Error: function `b20011.main.assignableByOut(out ubyte p)` is not callable using argument types `(ubyte)`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/const_ctor.d b/gcc/testsuite/gdc.test/fail_compilation/const_ctor.d
new file mode 100644
index 0000000..ae37023
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/const_ctor.d
@@ -0,0 +1,26 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/const_ctor.d(23): Error: `const` copy constructor `const_ctor.S1.this` cannot construct a mutable object
+fail_compilation/const_ctor.d(25): Error: `const` constructor `const_ctor.S2.this` cannot construct a mutable object
+---
+*/
+
+struct S1
+{
+ this(ref const S1 s) const {}
+ int* i;
+}
+struct S2
+{
+ this(int) const {}
+ int* i;
+}
+
+void main()
+{
+ const(S1) s1;
+ S1 m1 = s1;
+
+ S2 s2 = S2(5);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ctor_attr.d b/gcc/testsuite/gdc.test/fail_compilation/ctor_attr.d
new file mode 100644
index 0000000..337ded0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ctor_attr.d
@@ -0,0 +1,29 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/ctor_attr.d(26): Error: none of the overloads of `this` can construct a mutable object with argument types `(int)`
+fail_compilation/ctor_attr.d(16): Candidates are: `ctor_attr.S.this(int x) const`
+fail_compilation/ctor_attr.d(18): `ctor_attr.S.this(string x)`
+fail_compilation/ctor_attr.d(17): `this()(int x) shared`
+fail_compilation/ctor_attr.d(28): Error: none of the overloads of `foo` are callable using a mutable object with argument types `(int)`
+fail_compilation/ctor_attr.d(20): Candidates are: `ctor_attr.S.foo(int x) immutable`
+fail_compilation/ctor_attr.d(21): `ctor_attr.S.foo(string x)`
+---
+*/
+
+struct S
+{
+ this(int x) const {}
+ this()(int x) shared {}
+ this(string x) {}
+
+ void foo(int x) immutable {}
+ void foo(string x) {}
+}
+
+void f()
+{
+ auto s = S(1);
+ S t;
+ t.foo(1);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10415.d b/gcc/testsuite/gdc.test/fail_compilation/diag10415.d
index 207f6a4..7444432 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10415.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10415.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/diag10415.d(36): Error: none of the overloads of `x` are callable using argument types `(int) const`
-fail_compilation/diag10415.d(13): Candidates are: `diag10415.C.x()`
+fail_compilation/diag10415.d(13): Candidates are: `diag10415.C.x() const`
fail_compilation/diag10415.d(18): `diag10415.C.x(int __param_0)`
fail_compilation/diag10415.d(39): Error: d.x is not an lvalue
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10862.d b/gcc/testsuite/gdc.test/fail_compilation/diag10862.d
index 3e15497..2c93841 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10862.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10862.d
@@ -26,10 +26,10 @@ fail_compilation/diag10862.d-mixin-78(78): Error: assignment cannot be used as a
fail_compilation/diag10862.d-mixin-79(79): Error: assignment cannot be used as a condition, perhaps `==` was meant?
fail_compilation/diag10862.d-mixin-80(80): Error: using the result of a comma expression is not allowed
fail_compilation/diag10862.d-mixin-80(80): Error: assignment cannot be used as a condition, perhaps `==` was meant?
-fail_compilation/diag10862.d-mixin-83(83): Error: `a + b` is not an lvalue and cannot be modified
+fail_compilation/diag10862.d-mixin-83(83): Error: cannot modify expression `a + b` because it is not an lvalue
fail_compilation/diag10862.d-mixin-84(84): Error: undefined identifier `c`
fail_compilation/diag10862.d(86): Error: undefined identifier `semanticError`
-fail_compilation/diag10862.d(93): Error: lazy variable `bar` cannot be modified
+fail_compilation/diag10862.d(93): Error: cannot modify lazy variable `bar`
fail_compilation/diag10862.d(95): Error: template instance `diag10862.test3.foo!int` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10926.d b/gcc/testsuite/gdc.test/fail_compilation/diag10926.d
index f98a5b2..9bad633 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10926.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10926.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag10926.d(11): Error: `cast(const(int)[])c` is not an lvalue and cannot be modified
+fail_compilation/diag10926.d(11): Error: cannot modify expression `cast(const(int)[])c` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14102.d b/gcc/testsuite/gdc.test/fail_compilation/diag14102.d
index e93d40b..b88dd78 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag14102.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14102.d
@@ -1,10 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag14102.d(14): Error: `-x` is not an lvalue and cannot be modified
-fail_compilation/diag14102.d(15): Error: `-(x -= 1)` is not an lvalue and cannot be modified
-fail_compilation/diag14102.d(16): Error: `-(x -= 1 -= 1)` is not an lvalue and cannot be modified
-fail_compilation/diag14102.d(17): Error: `-(x -= 1 -= 1 -= 1)` is not an lvalue and cannot be modified
+fail_compilation/diag14102.d(14): Error: cannot modify expression `-x` because it is not an lvalue
+fail_compilation/diag14102.d(15): Error: cannot modify expression `-(x -= 1)` because it is not an lvalue
+fail_compilation/diag14102.d(16): Error: cannot modify expression `-(x -= 1 -= 1)` because it is not an lvalue
+fail_compilation/diag14102.d(17): Error: cannot modify expression `-(x -= 1 -= 1 -= 1)` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag4596.d b/gcc/testsuite/gdc.test/fail_compilation/diag4596.d
index f6b49d6..d43342b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag4596.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag4596.d
@@ -1,9 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag4596.d(15): Error: `this` is not an lvalue and cannot be modified
+fail_compilation/diag4596.d(15): Error: cannot modify expression `this` because it is not an lvalue
fail_compilation/diag4596.d(16): Error: conditional expression `1 ? this : this` is not a modifiable lvalue
-fail_compilation/diag4596.d(18): Error: `super` is not an lvalue and cannot be modified
+fail_compilation/diag4596.d(18): Error: cannot modify expression `super` because it is not an lvalue
fail_compilation/diag4596.d(19): Error: conditional expression `1 ? super : super` is not a modifiable lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d
index a55ef73..626fb82 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d
@@ -6,7 +6,7 @@ fail_compilation/diag8101b.d(19): Candidates are: `diag8101b.S.foo(int __
fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int __param_0, int __param_1)`
fail_compilation/diag8101b.d(30): Error: function `diag8101b.S.bar(int __param_0)` is not callable using argument types `(double)`
fail_compilation/diag8101b.d(30): cannot pass argument `1.0` of type `double` to parameter `int __param_0`
-fail_compilation/diag8101b.d(33): Error: none of the overloads of `foo` are callable using a `const` object
+fail_compilation/diag8101b.d(33): Error: none of the overloads of `foo` are callable using a `const` object with argument types `(int)`
fail_compilation/diag8101b.d(19): Candidates are: `diag8101b.S.foo(int __param_0)`
fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int __param_0, int __param_1)`
fail_compilation/diag8101b.d(35): Error: mutable method `diag8101b.S.bar` is not callable using a `const` object
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d b/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d
deleted file mode 100644
index 77ab520..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-REQUIRED_ARGS: -de
-TEST_OUTPUT:
----
-fail_compilation/dip1000_deprecation.d(17): Deprecation: `@safe` function `main` calling `inferred`
-fail_compilation/dip1000_deprecation.d(25): which wouldn't be `@safe` because of:
-fail_compilation/dip1000_deprecation.d(25): scope variable `x0` may not be returned
-fail_compilation/dip1000_deprecation.d(19): Deprecation: `@safe` function `main` calling `inferredC`
-fail_compilation/dip1000_deprecation.d(36): which calls `dip1000_deprecation.inferred`
-fail_compilation/dip1000_deprecation.d(25): which wouldn't be `@safe` because of:
-fail_compilation/dip1000_deprecation.d(25): scope variable `x0` may not be returned
----
-*/
-
-void main() @safe
-{
- cast(void)inferred();
- cast(void)inferredB(); // no deprecation, trusted
- cast(void)inferredC(); // nested deprecation
-}
-
-auto inferred()
-{
- scope int* x0;
- return x0;
-}
-
-auto inferredB() @trusted
-{
- scope int* x1;
- return x1;
-}
-
-auto inferredC()
-{
- return inferred(); // no deprecation, inferredC is not explicit `@safe`
-}
-
-@safe:
-
-struct S
-{
- int* ptr;
- int* incorrectReturnRef() scope return @trusted {return ptr;}
-}
-
-S createS() { return S.init; }
-
-int* escape(int i)
-{
- if (i) return S().incorrectReturnRef();
- if (i) return createS().incorrectReturnRef();
-
- S s;
- return s.incorrectReturnRef();
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10299.d b/gcc/testsuite/gdc.test/fail_compilation/fail10299.d
index f0eaeba..d9cfb04 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10299.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10299.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail10299.d(11): Error: `foo!string` is not an lvalue and cannot be modified
+fail_compilation/fail10299.d(11): Error: cannot take address of expression `foo!string` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13116.d b/gcc/testsuite/gdc.test/fail_compilation/fail13116.d
index ac520d7..156da43 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail13116.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail13116.d
@@ -1,8 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail13116.d(14): Error: `this` is not an lvalue and cannot be modified
-fail_compilation/fail13116.d(23): Error: `super` is not an lvalue and cannot be modified
+fail_compilation/fail13116.d(14): Error: cannot `ref` return expression `this` because it is not an lvalue
+fail_compilation/fail13116.d(23): Error: cannot `ref` return expression `super` because it is not an lvalue
---
*/
struct S
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13336a.d b/gcc/testsuite/gdc.test/fail_compilation/fail13336a.d
index e3f990c..6307e90 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail13336a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail13336a.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail13336a.d(28): Error: `choose(true)` is not an lvalue and cannot be modified
+fail_compilation/fail13336a.d(28): Error: cannot modify expression `choose(true)` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13336b.d b/gcc/testsuite/gdc.test/fail_compilation/fail13336b.d
index b8fb12d..f8959a2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail13336b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail13336b.d
@@ -6,8 +6,8 @@ double sy;
/*
TEST_OUTPUT:
---
-fail_compilation/fail13336b.d(16): Error: `cast(double)sx` is not an lvalue and cannot be modified
-fail_compilation/fail13336b.d(24): Error: `cast(double)sx` is not an lvalue and cannot be modified
+fail_compilation/fail13336b.d(16): Error: cannot `ref` return expression `cast(double)sx` because it is not an lvalue
+fail_compilation/fail13336b.d(24): Error: cannot `ref` return expression `cast(double)sx` because it is not an lvalue
---
*/
ref f1(bool f)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17491.d b/gcc/testsuite/gdc.test/fail_compilation/fail17491.d
index 0fb9708..718948c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17491.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail17491.d
@@ -1,13 +1,13 @@
/* TEST_OUTPUT:
---
-fail_compilation/fail17491.d(22): Error: `(S17491).init` is not an lvalue and cannot be modified
-fail_compilation/fail17491.d(23): Error: `S17491(0)` is not an lvalue and cannot be modified
-fail_compilation/fail17491.d(25): Error: `S17491(0).field` is not an lvalue and cannot be modified
-fail_compilation/fail17491.d(26): Error: `S17491(0).field` is not an lvalue and cannot be modified
-fail_compilation/fail17491.d(31): Error: `S17491(0)` is not an lvalue and cannot be modified
-fail_compilation/fail17491.d(32): Error: `S17491(0)` is not an lvalue and cannot be modified
-fail_compilation/fail17491.d(34): Error: `S17491(0).field` is not an lvalue and cannot be modified
-fail_compilation/fail17491.d(35): Error: `S17491(0).field` is not an lvalue and cannot be modified
+fail_compilation/fail17491.d(22): Error: cannot modify expression `(S17491).init` because it is not an lvalue
+fail_compilation/fail17491.d(23): Error: cannot take address of expression `S17491(0)` because it is not an lvalue
+fail_compilation/fail17491.d(25): Error: cannot modify expression `S17491(0).field` because it is not an lvalue
+fail_compilation/fail17491.d(26): Error: cannot take address of expression `S17491(0).field` because it is not an lvalue
+fail_compilation/fail17491.d(31): Error: cannot modify expression `S17491(0)` because it is not an lvalue
+fail_compilation/fail17491.d(32): Error: cannot take address of expression `S17491(0)` because it is not an lvalue
+fail_compilation/fail17491.d(34): Error: cannot modify expression `S17491(0).field` because it is not an lvalue
+fail_compilation/fail17491.d(35): Error: cannot take address of expression `S17491(0).field` because it is not an lvalue
---
*/
// https://issues.dlang.org/show_bug.cgi?id=17491
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail212.d b/gcc/testsuite/gdc.test/fail_compilation/fail212.d
index 5f30863..780cd82 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail212.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail212.d
@@ -1,10 +1,14 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail212.d(14): Error: function `fail212.S.bar` without `this` cannot be `const`
+fail_compilation/fail212.d(10): Error: function `fail212.baz` without `this` cannot be `const`
+fail_compilation/fail212.d(10): did you mean to use `const(int)` as the return type?
+fail_compilation/fail212.d(18): Error: function `fail212.S.bar` without `this` cannot be `const`
---
*/
+const int baz();
+
struct S
{
void foo() const
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21243.d b/gcc/testsuite/gdc.test/fail_compilation/fail21243.d
index 2e170d0..0b4117d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail21243.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21243.d
@@ -1,16 +1,12 @@
/+ TEST_OUTPUT:
---
-fail_compilation/fail21243.d(16): Error: found `(` when expecting `ref` and function literal following `auto`
-fail_compilation/fail21243.d(16): Error: semicolon expected following auto declaration, not `int`
-fail_compilation/fail21243.d(16): Error: semicolon needed to end declaration of `x` instead of `)`
-fail_compilation/fail21243.d(16): Error: declaration expected, not `)`
-fail_compilation/fail21243.d(17): Error: `auto` can only be used as part of `auto ref` for function literal return values
-fail_compilation/fail21243.d(18): Error: basic type expected, not `(`
-fail_compilation/fail21243.d(18): Error: function declaration without return type. (Note that constructors are always named `this`)
-fail_compilation/fail21243.d(18): Deprecation: storage class `auto` has no effect in type aliases
-fail_compilation/fail21243.d(18): Error: semicolon expected to close `alias` declaration, not `=>`
-fail_compilation/fail21243.d(18): Error: declaration expected, not `=>`
-fail_compilation/fail21243.d(19): Error: `auto` can only be used as part of `auto ref` for function literal return values
+fail_compilation/fail21243.d(12): Error: found `(` when expecting `ref` and function literal following `auto`
+fail_compilation/fail21243.d(12): Error: semicolon expected following auto declaration, not `int`
+fail_compilation/fail21243.d(12): Error: semicolon needed to end declaration of `x` instead of `)`
+fail_compilation/fail21243.d(12): Error: declaration expected, not `)`
+fail_compilation/fail21243.d(13): Error: `auto` can only be used as part of `auto ref` for function literal return values
+fail_compilation/fail21243.d(14): Error: `auto` can only be used as part of `auto ref` for function literal return values
+fail_compilation/fail21243.d(15): Error: `auto` can only be used as part of `auto ref` for function literal return values
---
+/
auto a = auto (int x) => x;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail217.d b/gcc/testsuite/gdc.test/fail_compilation/fail217.d
index 11ad76f..ecae1a3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail217.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail217.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail217.d(22): Error: mutable method `fail217.Message.this` is not callable using a `immutable` object
+fail_compilation/fail217.d(22): Error: mutable constructor `fail217.Message.this` cannot construct a `immutable` object
fail_compilation/fail217.d(13): Consider adding `const` or `inout` here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail24224.d b/gcc/testsuite/gdc.test/fail_compilation/fail24224.d
new file mode 100644
index 0000000..db87f53
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail24224.d
@@ -0,0 +1,22 @@
+/+
+TEST_OUTPUT:
+---
+fail_compilation/fail24224.d(19): Error: struct / class type expected as argument to __traits(initSymbol) instead of `ES`
+fail_compilation/fail24224.d(20): Error: struct / class type expected as argument to __traits(initSymbol) instead of `EU`
+fail_compilation/fail24224.d(21): Error: struct / class type expected as argument to __traits(initSymbol) instead of `EC`
+---
++/
+struct S {}
+union U {}
+class C {}
+
+enum ES : S { a = S.init }
+enum EU : U { a = U.init }
+enum EC : C { a = C.init }
+
+void test()
+{
+ auto init1 = __traits(initSymbol, ES);
+ auto init2 = __traits(initSymbol, EU);
+ auto init3 = __traits(initSymbol, EC);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail6795.d b/gcc/testsuite/gdc.test/fail_compilation/fail6795.d
index 584a467..26d4429 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail6795.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail6795.d
@@ -2,12 +2,12 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail6795.d(19): Error: `[0][0]` is not an lvalue and cannot be modified
-fail_compilation/fail6795.d(20): Error: `[0:0][0]` is not an lvalue and cannot be modified
-fail_compilation/fail6795.d(22): Error: `[0][0]` is not an lvalue and cannot be modified
-fail_compilation/fail6795.d(23): Error: `[0:0][0]` is not an lvalue and cannot be modified
-fail_compilation/fail6795.d(25): Error: `[0][0]` is not an lvalue and cannot be modified
-fail_compilation/fail6795.d(26): Error: `[0:0][0]` is not an lvalue and cannot be modified
+fail_compilation/fail6795.d(19): Error: cannot modify expression `[0][0]` because it is not an lvalue
+fail_compilation/fail6795.d(20): Error: cannot modify expression `[0:0][0]` because it is not an lvalue
+fail_compilation/fail6795.d(22): Error: cannot modify expression `[0][0]` because it is not an lvalue
+fail_compilation/fail6795.d(23): Error: cannot modify expression `[0:0][0]` because it is not an lvalue
+fail_compilation/fail6795.d(25): Error: cannot take address of expression `[0][0]` because it is not an lvalue
+fail_compilation/fail6795.d(26): Error: cannot take address of expression `[0:0][0]` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d
index 38f47ba..920956b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424d.d(10): Error: template `this.g()()` has no value
+fail_compilation/fail7424d.d(10): Error: template `this.g()() immutable` has no value
---
*/
struct S7424d
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d
index e92b469..ddf9d1a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424e.d(10): Error: template `this.g()()` has no value
+fail_compilation/fail7424e.d(10): Error: template `this.g()() immutable` has no value
---
*/
struct S7424e
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d
index 1af14f8..2f7f8f3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424f.d(10): Error: template `this.g()()` has no value
+fail_compilation/fail7424f.d(10): Error: template `this.g()() shared` has no value
---
*/
struct S7424f
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d
index 6352166..4e922d6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424i.d(10): Error: template `this.g()()` has no value
+fail_compilation/fail7424i.d(10): Error: template `this.g()() immutable` has no value
---
*/
struct S7424g
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7603a.d b/gcc/testsuite/gdc.test/fail_compilation/fail7603a.d
index 76a92c2..a106a56 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7603a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7603a.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7603a.d(7): Error: cannot modify constant `true`
+fail_compilation/fail7603a.d(7): Error: cannot create default argument for `ref` / `out` parameter from constant `true`
---
*/
void test(ref bool val = true) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7603b.d b/gcc/testsuite/gdc.test/fail_compilation/fail7603b.d
index 9b84d3f..a652422 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7603b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7603b.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7603b.d(7): Error: cannot modify constant `true`
+fail_compilation/fail7603b.d(7): Error: cannot create default argument for `ref` / `out` parameter from constant `true`
---
*/
void test(out bool val = true) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7603c.d b/gcc/testsuite/gdc.test/fail_compilation/fail7603c.d
index 25a7399..3d030fc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7603c.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7603c.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7603c.d(8): Error: cannot modify constant `3`
+fail_compilation/fail7603c.d(8): Error: cannot create default argument for `ref` / `out` parameter from constant `3`
---
*/
enum x = 3;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9537.d b/gcc/testsuite/gdc.test/fail_compilation/fail9537.d
index e08badf..4d593e3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail9537.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail9537.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail9537.d(26): Error: `foo(tuple(1, 2))` is not an lvalue and cannot be modified
+fail_compilation/fail9537.d(26): Error: cannot take address of expression `foo(tuple(1, 2))` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9773.d b/gcc/testsuite/gdc.test/fail_compilation/fail9773.d
index b49ffe1..26447a7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail9773.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail9773.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail9773.d(7): Error: `""` is not an lvalue and cannot be modified
+fail_compilation/fail9773.d(7): Error: cannot create default argument for `ref` / `out` parameter from expression `""` because it is not an lvalue
---
*/
void f(ref string a = "")
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9891.d b/gcc/testsuite/gdc.test/fail_compilation/fail9891.d
index 791e734..0c2384f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail9891.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail9891.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/fail9891.d(13): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `ref int` of parameter `n`
fail_compilation/fail9891.d(18): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `out int` of parameter `n`
-fail_compilation/fail9891.d(23): Error: `prop()` is not an lvalue and cannot be modified
+fail_compilation/fail9891.d(23): Error: cannot create default argument for `ref` / `out` parameter from expression `prop()` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
index c3c735e..0db6a45 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
@@ -207,21 +207,21 @@ fail_compilation/fail_arrayop2.d(265): Error: array operation `[1] * 6` without
fail_compilation/fail_arrayop2.d(268): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(269): Error: array operation `"abc"[] + '\x01'` without destination memory not allowed
fail_compilation/fail_arrayop2.d(272): Error: array operation `[1] * 6` without destination memory not allowed
-fail_compilation/fail_arrayop2.d(275): Error: `([1] * 6)[0..2]` is not an lvalue and cannot be modified
+fail_compilation/fail_arrayop2.d(275): Error: cannot take address of expression `([1] * 6)[0..2]` because it is not an lvalue
fail_compilation/fail_arrayop2.d(278): Error: can only `*` a pointer, not a `int[]`
fail_compilation/fail_arrayop2.d(281): Error: the `delete` keyword is obsolete
fail_compilation/fail_arrayop2.d(281): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
fail_compilation/fail_arrayop2.d(284): Error: array operation `da[] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(287): Error: array operation `da[] * 6` without destination memory not allowed
-fail_compilation/fail_arrayop2.d(290): Error: `[1] * 6` is not an lvalue and cannot be modified
+fail_compilation/fail_arrayop2.d(290): Error: cannot modify expression `[1] * 6` because it is not an lvalue
fail_compilation/fail_arrayop2.d(291): Error: array operation `[1] * 6` without destination memory not allowed
-fail_compilation/fail_arrayop2.d(294): Error: `[1] * 6` is not an lvalue and cannot be modified
-fail_compilation/fail_arrayop2.d(295): Error: `([1] * 6)[]` is not an lvalue and cannot be modified
+fail_compilation/fail_arrayop2.d(294): Error: cannot modify expression `[1] * 6` because it is not an lvalue
+fail_compilation/fail_arrayop2.d(295): Error: cannot modify expression `([1] * 6)[]` because it is not an lvalue
fail_compilation/fail_arrayop2.d(298): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(299): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(300): Error: array operation `[1] * 6` without destination memory not allowed
-fail_compilation/fail_arrayop2.d(303): Error: `[1] * 6` is not an lvalue and cannot be modified
-fail_compilation/fail_arrayop2.d(304): Error: `[1] * 6` is not an lvalue and cannot be modified
+fail_compilation/fail_arrayop2.d(303): Error: cannot modify expression `[1] * 6` because it is not an lvalue
+fail_compilation/fail_arrayop2.d(304): Error: cannot modify expression `[1] * 6` because it is not an lvalue
fail_compilation/fail_arrayop2.d(307): Error: `[1] * 6` is not of integral type, it is a `int[]`
fail_compilation/fail_arrayop2.d(308): Error: `[1] * 6` is not of integral type, it is a `int[]`
fail_compilation/fail_arrayop2.d(309): Error: `[1] * 6` is not of integral type, it is a `int[]`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
index a9e5429..9851ffc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
@@ -1,10 +1,6 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail_scope.d(28): Deprecation: scope parameter `da` may not be returned
-fail_compilation/fail_scope.d(30): Deprecation: scope parameter `o` may not be returned
-fail_compilation/fail_scope.d(31): Deprecation: scope parameter `dg` may not be returned
-fail_compilation/fail_scope.d(38): Deprecation: scope parameter `p` may not be returned
fail_compilation/fail_scope.d(43): Error: returning `cast(char[])string` escapes a reference to local variable `string`
fail_compilation/fail_scope.d(61): Error: returning `s.bar()` escapes a reference to local variable `s`
fail_compilation/fail_scope.d(72): Error: `fail_scope.foo8` called with argument types `(int)` matches both:
@@ -23,6 +19,10 @@ fail_compilation/fail_scope.d(135): Error: returning `foo16226(i)` escapes a ref
//fail_compilation/fail_scope.d(40): Error: scope variable `p` may not be returned
*/
+
+
+
+
alias int delegate() dg_t;
int[] checkEscapeScope1(scope int[] da) { return da; }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10419.d b/gcc/testsuite/gdc.test/fail_compilation/ice10419.d
index 827f045..fed8c60 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10419.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10419.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice10419.d(12): Error: `arr().length` is not an lvalue and cannot be modified
+fail_compilation/ice10419.d(12): Error: cannot modify expression `arr().length` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice12841.d b/gcc/testsuite/gdc.test/fail_compilation/ice12841.d
index c5894d2..343624d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice12841.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice12841.d
@@ -1,8 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice12841.d(23): Error: `taskPool().amap(Args...)(Args args)` is not an lvalue and cannot be modified
-fail_compilation/ice12841.d(24): Error: `amap(Args...)(Args args)` is not an lvalue and cannot be modified
+fail_compilation/ice12841.d(23): Error: cannot take address of expression `taskPool().amap(Args...)(Args args)` because it is not an lvalue
+fail_compilation/ice12841.d(24): Error: cannot take address of template `amap(Args...)(Args args)`, perhaps instantiate it first
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice13459.d b/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
index d34fc60..6998e68 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/ice13459.d(12): Error: undefined identifier `B`
fail_compilation/ice13459.d(18): Error: none of the overloads of `opSlice` are callable using argument types `(int, int)`
-fail_compilation/ice13459.d(11): Candidate is: `ice13459.A.opSlice()`
+fail_compilation/ice13459.d(11): Candidate is: `ice13459.A.opSlice() const`
---
*/
struct A
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice20264.d b/gcc/testsuite/gdc.test/fail_compilation/ice20264.d
index 0d697e2..df6667d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice20264.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice20264.d
@@ -2,7 +2,7 @@
DISABLED: freebsd32 linux32 osx32 win32
TEST_OUTPUT:
---
-fail_compilation/ice20264.d(12): Error: `cast(__vector(float[4]))a` is not an lvalue and cannot be modified
+fail_compilation/ice20264.d(12): Error: cannot modify expression `cast(__vector(float[4]))a` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
index 47fd44c..c9ab014 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/ice9284.d(14): Error: template `ice9284.C.__ctor` is not callable using argument types `!()(int)`
-fail_compilation/ice9284.d(12): Candidate is: `__ctor()(string)`
+fail_compilation/ice9284.d(12): Candidate is: `this()(string)`
fail_compilation/ice9284.d(20): Error: template instance `ice9284.C.__ctor!()` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/immutable_ctor.d b/gcc/testsuite/gdc.test/fail_compilation/immutable_ctor.d
new file mode 100644
index 0000000..408e402
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/immutable_ctor.d
@@ -0,0 +1,19 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/immutable_ctor.d(18): Error: `immutable` copy constructor `immutable_ctor.S1.this` cannot construct a mutable object
+---
+*/
+
+struct S1
+{
+ this(ref const S1 s) immutable {
+ }
+ int i;
+}
+
+void main()
+{
+ const(S1) s1;
+ S1 ms1 = s1;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue16020.d b/gcc/testsuite/gdc.test/fail_compilation/issue16020.d
index fe4ad78..79eda2e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/issue16020.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/issue16020.d
@@ -1,9 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/issue16020.d(12): Error: user-defined attributes not allowed for `alias` declarations
-fail_compilation/issue16020.d(13): Error: semicolon expected to close `alias` declaration, not `(`
-fail_compilation/issue16020.d(13): Error: declaration expected, not `(`
+fail_compilation/issue16020.d(13): Error: user-defined attributes not allowed for `alias` declarations
+fail_compilation/issue16020.d(14): Error: semicolon expected to close `alias` declaration, not `(`
+fail_compilation/issue16020.d(14): Error: declaration expected, not `(`
+fail_compilation/issue16020.d(15): Deprecation: storage class `final` has no effect in type aliases
---
*/
module issue16020;
@@ -11,3 +12,4 @@ module issue16020;
struct UDA{}
alias Fun = @UDA void();
alias FunTemplate = void(T)(T t);
+alias F2 = final int();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue20704.d b/gcc/testsuite/gdc.test/fail_compilation/issue20704.d
index 1e1f2e6..ba91b06 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/issue20704.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/issue20704.d
@@ -1,12 +1,12 @@
/* TEST_OUTPUT:
---
-fail_compilation/issue20704.d(17): Error: cannot modify constant `0`
+fail_compilation/issue20704.d(17): Error: cannot create default argument for `ref` / `out` parameter from constant `0`
fail_compilation/issue20704.d(28): Error: template instance `issue20704.f2!int` error instantiating
-fail_compilation/issue20704.d(19): Error: cannot modify constant `0`
+fail_compilation/issue20704.d(19): Error: cannot create default argument for `ref` / `out` parameter from constant `0`
fail_compilation/issue20704.d(30): Error: template instance `issue20704.f4!int` error instantiating
-fail_compilation/issue20704.d(17): Error: `S(0)` is not an lvalue and cannot be modified
+fail_compilation/issue20704.d(17): Error: cannot create default argument for `ref` / `out` parameter from expression `S(0)` because it is not an lvalue
fail_compilation/issue20704.d(36): Error: template instance `issue20704.f2!(S)` error instantiating
-fail_compilation/issue20704.d(17): Error: `null` is not an lvalue and cannot be modified
+fail_compilation/issue20704.d(17): Error: cannot create default argument for `ref` / `out` parameter from expression `null` because it is not an lvalue
fail_compilation/issue20704.d(38): Error: template instance `issue20704.f2!(C)` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16381.d b/gcc/testsuite/gdc.test/fail_compilation/test16381.d
index fd92798..5847e04 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test16381.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test16381.d
@@ -2,7 +2,7 @@
REQUIRED_ARGS: -m64
TEST_OUTPUT:
---
-fail_compilation/test16381.d(15): Error: `foo()` is not an lvalue and cannot be modified
+fail_compilation/test16381.d(15): Error: cannot take address of expression `foo()` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22048.d b/gcc/testsuite/gdc.test/fail_compilation/test22048.d
index e056068..72b9154 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test22048.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22048.d
@@ -3,7 +3,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/test22048.d(10): Error: unexpected identifier `p` in declarator
+fail_compilation/test22048.d(10): Error: unexpected identifier `p` after `int`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test24157.d b/gcc/testsuite/gdc.test/fail_compilation/test24157.d
index 5022014..d78c9b6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test24157.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test24157.d
@@ -3,8 +3,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/test24157.d(23): Error: `p.self()` is not an lvalue and cannot be modified
-fail_compilation/test24157.d(27): Error: `p.unshared()` is not an lvalue and cannot be modified
+fail_compilation/test24157.d(23): Error: cannot take address of expression `p.self()` because it is not an lvalue
+fail_compilation/test24157.d(27): Error: cannot take address of expression `p.unshared()` because it is not an lvalue
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test24159.d b/gcc/testsuite/gdc.test/fail_compilation/test24159.d
new file mode 100644
index 0000000..35c7f36
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test24159.d
@@ -0,0 +1,14 @@
+// https://issues.dlang.org/show_bug.cgi?id=24159
+// REQUIRED_ARGS: -betterC
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test24159.d(13): Error: appending to array in `x ~= 3` requires the GC which is not available with -betterC
+---
+*/
+
+extern(C) void main()
+{
+ int[] x = null;
+ x ~= 3;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d b/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d
index 50cebab..1173d14 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d
@@ -5,9 +5,9 @@ TEST_OUTPUT:
---
fail_compilation/testrvaluecpctor.d(16): Error: cannot define both an rvalue constructor and a copy constructor for `struct Foo`
fail_compilation/testrvaluecpctor.d(24): Template instance `testrvaluecpctor.Foo!int.Foo.__ctor!(immutable(Foo!int), immutable(Foo!int))` creates an rvalue constructor for `struct Foo`
-fail_compilation/testrvaluecpctor.d(24): Error: none of the overloads of `__ctor` are callable using a `immutable` object
+fail_compilation/testrvaluecpctor.d(24): Error: none of the overloads of `this` can construct a `immutable` object with argument types `(immutable(Foo!int))`
fail_compilation/testrvaluecpctor.d(18): Candidates are: `testrvaluecpctor.Foo!int.Foo.this(ref scope Foo!int rhs)`
-fail_compilation/testrvaluecpctor.d(16): `__ctor(Rhs, this This)(scope Rhs rhs)`
+fail_compilation/testrvaluecpctor.d(16): `this(Rhs, this This)(scope Rhs rhs)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/tolvalue.d b/gcc/testsuite/gdc.test/fail_compilation/tolvalue.d
new file mode 100644
index 0000000..e911dff
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/tolvalue.d
@@ -0,0 +1,48 @@
+/**
+TEST_OUTPUT:
+---
+fail_compilation/tolvalue.d(28): Error: cannot take address of template `templateFunc(T)()`, perhaps instantiate it first
+fail_compilation/tolvalue.d(29): Error: cannot take address of type `int`
+fail_compilation/tolvalue.d(30): Error: cannot take address of constant `3`
+fail_compilation/tolvalue.d(31): Error: cannot take address of operator `$`
+fail_compilation/tolvalue.d(32): Error: cannot take address of compiler-generated variable `__ctfe`
+fail_compilation/tolvalue.d(33): Error: cannot take address of manifest constant `f`
+fail_compilation/tolvalue.d(38): Error: cannot create default argument for `ref` / `out` parameter from constant `3`
+fail_compilation/tolvalue.d(39): Error: cannot create default argument for `ref` / `out` parameter from compiler-generated variable `__ctfe`
+fail_compilation/tolvalue.d(40): Error: cannot create default argument for `ref` / `out` parameter from manifest constant `f`
+fail_compilation/tolvalue.d(45): Error: cannot modify constant `3`
+fail_compilation/tolvalue.d(46): Error: cannot modify compiler-generated variable `__ctfe`
+fail_compilation/tolvalue.d(47): Error: cannot modify manifest constant `f`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=24238
+
+void templateFunc(T)() {}
+alias intAlias = int;
+enum E { f }
+
+void addr()
+{
+ int[] a;
+ auto x0 = &templateFunc;
+ auto x1 = &intAlias;
+ auto x2 = &3;
+ auto x3 = a[&$];
+ auto x4 = &__ctfe;
+ auto x6 = &E.f;
+}
+
+void refArg()
+{
+ void f0(ref int = 3) {}
+ void f1(ref bool = __ctfe) {}
+ void f3(ref E = E.f) {}
+}
+
+void inc(int lz)
+{
+ 3++;
+ __ctfe++;
+ E.f++;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/vector_cast.d b/gcc/testsuite/gdc.test/fail_compilation/vector_cast.d
new file mode 100644
index 0000000..e8a8d48
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/vector_cast.d
@@ -0,0 +1,13 @@
+/**
+REQUIRED_ARGS: -m64
+TEST_OUTPUT:
+---
+fail_compilation/vector_cast.d(11): Error: cannot cast expression `a` of type `int[3]` to `__vector(int[4])`
+fail_compilation/vector_cast.d(13): Error: cannot cast expression `a` of type `int[5]` to `__vector(int[4])`
+---
+*/
+
+alias int4 = __vector(int[4]);
+int4 convtest3(int[3] a) { return cast(int4) a; }
+int4 convtest4(int[4] a) { return cast(int4) a; }
+int4 convtest5(int[5] a) { return cast(int4) a; }
diff --git a/gcc/testsuite/gdc.test/runnable/previewin.d b/gcc/testsuite/gdc.test/runnable/previewin.d
index 117070df..50f22ee 100644
--- a/gcc/testsuite/gdc.test/runnable/previewin.d
+++ b/gcc/testsuite/gdc.test/runnable/previewin.d
@@ -154,27 +154,25 @@ struct WithDtor
@safe pure nothrow @nogc:
// By value
-void testin1(in uint p) { static assert(!__traits(isRef, p)); }
+void testin1(in uint p) { }
// By ref because of size
-void testin2(in ulong[64] p) { static assert(__traits(isRef, p)); }
+void testin2(in ulong[64] p) { }
// By value or ref depending on size (or structs always passed by reference)
-void testin3(in ValueT p) { static assert(!__traits(isRef, p) || true); }
-void testin3(in RefT p) { static assert(__traits(isRef, p)); }
+void testin3(in ValueT p) { }
+void testin3(in RefT p) { }
// By ref because of size (or arrays always passed by reference)
-void testin4(in ValueT[64] p) { static assert(__traits(isRef, p)); }
-void testin4(in RefT[4] p) { static assert(__traits(isRef, p)); }
+void testin4(in ValueT[64] p) { }
+void testin4(in RefT[4] p) { }
// By ref because of non-copyability
-void testin5(in NonCopyable noncopy) { static assert(__traits(isRef, noncopy)); }
-static assert(testin5.mangleof == "_D9previewin7testin5FNaNbNiNfIKSQBe11NonCopyableZv"); // incl. `ref`
+void testin5(in NonCopyable noncopy) { }
// By ref because of postblit
-void testin6(in WithPostblit withpostblit) { static assert(__traits(isRef, withpostblit)); }
+void testin6(in WithPostblit withpostblit) { }
// By ref because of copy ctor
-void testin7(in WithCopyCtor withcopy) { static assert(__traits(isRef, withcopy)); }
+void testin7(in WithCopyCtor withcopy) { }
// By ref because of dtor
void testin8(in WithDtor withdtor, scope bool* isTestOver)
{
- static assert(__traits(isRef, withdtor));
if (isTestOver)
*isTestOver = true;
}
diff --git a/gcc/testsuite/gdc.test/runnable/staticaa.d b/gcc/testsuite/gdc.test/runnable/staticaa.d
index 17a2ecb..606b70e 100644
--- a/gcc/testsuite/gdc.test/runnable/staticaa.d
+++ b/gcc/testsuite/gdc.test/runnable/staticaa.d
@@ -56,7 +56,7 @@ struct Key
{
int v;
bool opEquals(ref const Key o) const { return v == o.v; }
- size_t toHash() const { return v; }
+ size_t toHash() const nothrow { return v; }
}
Destructing[Key] dAa = [Key(1): Destructing(10), Key(2): Destructing(20)];
@@ -142,6 +142,18 @@ void testImmutable()
/////////////////////////////////////////////
+// https://issues.dlang.org/show_bug.cgi?id=24209
+void testLocalStatic() @trusted
+{
+ static int[int] aa0 = [1: 2];
+ __gshared string[string] aa1 = null;
+
+ assert(aa0[1] == 2);
+ assert(aa1.length == 0);
+}
+
+/////////////////////////////////////////////
+
void main()
{
testSimple();
@@ -150,4 +162,5 @@ void main()
testStructInit();
testClassInit();
testImmutable();
+ testLocalStatic();
}
diff --git a/gcc/testsuite/gdc.test/runnable/test24184.d b/gcc/testsuite/gdc.test/runnable/test24184.d
new file mode 100644
index 0000000..736824fc
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test24184.d
@@ -0,0 +1,30 @@
+// https://issues.dlang.org/show_bug.cgi?id=24184
+
+void stage3(alias abc)(ubyte[])
+{
+ bool skipSpaces()
+ {
+ abc();
+ return false;
+ }
+ skipSpaces;
+}
+ubyte[] singleThreadJsonImpl(alias xxx)(ubyte[] table)
+{
+ align(64) ubyte[] vector;
+
+ ubyte[] abc() { return vector; }
+
+ stage3!(abc)(table);
+
+ return table;
+}
+ubyte[] singleThreadJsonText()
+{
+ bool xxx() { return true; }
+
+ return singleThreadJsonImpl!(xxx)([]);
+}
+void deserializeJson() { singleThreadJsonText(); }
+
+void main() { deserializeJson(); }
diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_10.f90 b/gcc/testsuite/gfortran.dg/assumed_rank_10.f90
index 6a3cc94..f22d43a 100644
--- a/gcc/testsuite/gfortran.dg/assumed_rank_10.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_10.f90
@@ -50,9 +50,9 @@ program test
is_present = .false.
- call fpa(null(), null()) ! No copy back
- call fpi(null(), null()) ! No copy back
- call fno(null(), null()) ! No copy back
+ call fpa(null(iip), null(jjp)) ! No copy back
+ call fpi(null(iip), null(jjp)) ! No copy back
+ call fno(null(iip), null(jjp)) ! No copy back
call fno() ! No copy back
diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_8.f90 b/gcc/testsuite/gfortran.dg/assumed_rank_8.f90
index 5873296..34ff42c 100644
--- a/gcc/testsuite/gfortran.dg/assumed_rank_8.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_8.f90
@@ -22,13 +22,13 @@ program main
call f (ii)
call f (489)
call f ()
- call f (null())
+ call f (null(kk))
call f (kk)
if (j /= 2) STOP 1
j = 0
nullify (ll)
- call g (null())
+ call g (null(ll))
call g (ll)
call g (ii)
if (j /= 1) STOP 2
diff --git a/gcc/testsuite/gfortran.dg/gomp/depobj-3.f90 b/gcc/testsuite/gfortran.dg/gomp/depobj-3.f90
new file mode 100644
index 0000000..8a3625e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/depobj-3.f90
@@ -0,0 +1,18 @@
+! { dg-do compile { target { fortran_integer_16 || ilp32 } } }
+! omp_depend_kind = 2*intptr_t --> 16 (128 bit) on 64bit-pointer systems
+! --> 8 (128 bit) on 32bit-pointer systems
+subroutine f1
+ !use omp_lib ! N/A in gcc/testsuite
+ use iso_c_binding, only: c_intptr_t
+ implicit none
+ integer, parameter :: omp_depend_kind = 2*c_intptr_t
+ integer :: a, b
+ integer(kind=omp_depend_kind) :: depobj, depobj1(5), depobj2
+
+ !$omp depobj(depobj) destroy
+
+ !$omp depobj(depobj) destroy( depobj)
+
+ !$omp depobj(depobj) destroy( depobj2) ! { dg-warning "The same depend object should be used as DEPOBJ argument at .1. and as DESTROY argument at .2." }
+ !$omp depobj(depobj) destroy( a) ! { dg-warning "The same depend object should be used as DEPOBJ argument at .1. and as DESTROY argument at .2." }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr111880.f90 b/gcc/testsuite/gfortran.dg/pr111880.f90
new file mode 100644
index 0000000..c0cd98a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr111880.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-options "-std=f2018" }
+! PR fortran/111880 - redundant warning of obsolescent COMMON with submodule
+
+module third_party_module
+ integer :: some_param
+ common /not_my_code/ some_param ! { dg-warning "COMMON block" }
+end module third_party_module
+
+module foo
+ use third_party_module
+ interface
+ module subroutine bar()
+ end subroutine bar
+ end interface
+end module foo
+
+submodule (foo) foo_submod ! We do not need a warning here!
+contains
+ module procedure bar
+ end procedure bar
+end submodule foo_submod
diff --git a/gcc/testsuite/gfortran.dg/pr112406.f90 b/gcc/testsuite/gfortran.dg/pr112406.f90
new file mode 100644
index 0000000..27e96df
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr112406.f90
@@ -0,0 +1,21 @@
+! { dg-do compile { target { aarch64-*-* || riscv*-*-* } } }
+! { dg-options "-Ofast -w -fprofile-generate" }
+! { dg-additional-options "-march=rv64gcv -mabi=lp64d" { target riscv*-*-* } }
+! { dg-additional-options "-march=armv8-a+sve" { target aarch64-*-* } }
+
+module brute_force
+ integer, parameter :: r=9
+ integer sudoku1(1, r)
+ contains
+subroutine brute
+integer l(r), u(r)
+ where(sudoku1(1, :) /= 1)
+ l = 1
+ u = 1
+ end where
+do i1 = 1, u(1)
+ do
+ end do
+ end do
+end
+end
diff --git a/gcc/testsuite/gfortran.dg/pr43984.f90 b/gcc/testsuite/gfortran.dg/pr43984.f90
index 130d114..dce26b0 100644
--- a/gcc/testsuite/gfortran.dg/pr43984.f90
+++ b/gcc/testsuite/gfortran.dg/pr43984.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-pre" }
+! { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-pre -fno-tree-sra" }
module test
type shell1quartet_type
diff --git a/gcc/testsuite/gfortran.dg/system_clock_1.f90 b/gcc/testsuite/gfortran.dg/system_clock_1.f90
index 41027de..0cb0145 100644
--- a/gcc/testsuite/gfortran.dg/system_clock_1.f90
+++ b/gcc/testsuite/gfortran.dg/system_clock_1.f90
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options "-std=f2003" }
integer :: i, j, k
integer(kind=8) :: i8, j8, k8
diff --git a/gcc/testsuite/gfortran.dg/system_clock_3.f08 b/gcc/testsuite/gfortran.dg/system_clock_3.f08
index e52a51a..c12849b 100644
--- a/gcc/testsuite/gfortran.dg/system_clock_3.f08
+++ b/gcc/testsuite/gfortran.dg/system_clock_3.f08
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options "-std=f2008" }
! PR64432
program countem
implicit none
diff --git a/gcc/testsuite/gfortran.dg/system_clock_4.f90 b/gcc/testsuite/gfortran.dg/system_clock_4.f90
new file mode 100644
index 0000000..1bb42ef
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/system_clock_4.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-std=f2023" }
+! PR fortran/112609 - F2023 restrictions on integer arguments to SYSTEM_CLOCK
+
+program p
+ implicit none
+ integer :: i, j, k
+ integer(2) :: i2, j2, k2
+ integer(8) :: i8, j8, k8
+ real :: x
+
+ call system_clock(count=i2) ! { dg-error "kind smaller than default integer" }
+ call system_clock(count_rate=j2) ! { dg-error "kind smaller than default integer" }
+ call system_clock(count_max=k2) ! { dg-error "kind smaller than default integer" }
+
+ call system_clock(count=i8,count_rate=x,count_max=k8)
+ call system_clock(count=i, count_rate=j8) ! { dg-error "different kind" }
+ call system_clock(count=i8,count_rate=j) ! { dg-error "different kind" }
+ call system_clock(count=i, count_max=k8) ! { dg-error "different kind" }
+ call system_clock(count=i8,count_max=k) ! { dg-error "different kind" }
+ call system_clock(count_rate=j, count_max=k8) ! { dg-error "different kind" }
+ call system_clock(count_rate=j8,count_max=k) ! { dg-error "different kind" }
+ call system_clock(i,x,k8) ! { dg-error "different kind" }
+end
diff --git a/gcc/testsuite/gfortran.dg/vect/pr107254.f90 b/gcc/testsuite/gfortran.dg/vect/pr107254.f90
index 85bcb5f..adce6be 100644
--- a/gcc/testsuite/gfortran.dg/vect/pr107254.f90
+++ b/gcc/testsuite/gfortran.dg/vect/pr107254.f90
@@ -1,5 +1,3 @@
-! { dg-do run }
-
subroutine dlartg( f, g, s, r )
implicit none
double precision :: f, g, r, s
diff --git a/gcc/testsuite/gfortran.dg/vect/pr85853.f90 b/gcc/testsuite/gfortran.dg/vect/pr85853.f90
index 68f4a00..4c0e3b8 100644
--- a/gcc/testsuite/gfortran.dg/vect/pr85853.f90
+++ b/gcc/testsuite/gfortran.dg/vect/pr85853.f90
@@ -1,5 +1,4 @@
! Taken from execute/where_2.f90, but with special flags.
-! { dg-do run }
! { dg-additional-options "-fno-tree-loop-vectorize" }
! Program to test the WHERE constructs
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-alias-check-1.F90 b/gcc/testsuite/gfortran.dg/vect/vect-alias-check-1.F90
index 3014ff9..85ae9b1 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-alias-check-1.F90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-alias-check-1.F90
@@ -1,4 +1,3 @@
-! { dg-do run }
! { dg-additional-options "-fno-inline" }
#define N 200
diff --git a/gcc/testsuite/gnat.dg/warn25.adb b/gcc/testsuite/gnat.dg/warn25.adb
index e784870..cdf28ae 100644
--- a/gcc/testsuite/gnat.dg/warn25.adb
+++ b/gcc/testsuite/gnat.dg/warn25.adb
@@ -1,5 +1,6 @@
-- { dg-do compile }
-- { dg-options "-gnatwa" }
+-- { dg-xfail-if "expected regression" { *-*-* } }
with Ada.Exceptions;
procedure Warn25 is
diff --git a/gcc/testsuite/lib/plugin-support.exp b/gcc/testsuite/lib/plugin-support.exp
index 378881b..8accf13 100644
--- a/gcc/testsuite/lib/plugin-support.exp
+++ b/gcc/testsuite/lib/plugin-support.exp
@@ -85,7 +85,7 @@ proc plugin-test-execute { plugin_src plugin_tests } {
set gcc_objdir "$objdir/../../.."
set includes "-I. -I${srcdir} -I${gcc_srcdir}/gcc -I${gcc_objdir}/gcc \
-I${gcc_srcdir}/include -I${gcc_srcdir}/libcpp/include \
- $GMPINC -I${gcc_objdir}/intl"
+ $GMPINC -I${gcc_objdir}/gettext/intl"
if { [ ishost *-*-darwin* ] } {
# -mdynamic-no-pic is incompatible with -fPIC.
diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index 16b5198..d30e361 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -505,7 +505,7 @@ proc scan-assembler-times { args } {
close $fd
regsub -all {(^|\n)[[:space:]]*\.section[[:space:]]*\.gnu\.lto_(?:[^\n]*\n(?![[:space:]]*\.(section|text|data|bss)))*[^\n]*\n} $text {\1} text
- set result_count [llength [regexp -inline -all -- $pattern $text]]
+ set result_count [regexp -all -- $pattern $text]
if {$result_count == $times} {
pass "$testcase scan-assembler-times $pp_pattern $times"
} else {
@@ -804,23 +804,34 @@ proc configure_check-function-bodies { config } {
# Regexp for the start of a function definition (name in \1).
if { [istarget nvptx*-*-*] } {
- set up_config(start) {^// BEGIN(?: GLOBAL|) FUNCTION DEF: ([a-zA-Z_]\S+)$}
+ set up_config(start) {
+ {^// BEGIN(?: GLOBAL|) FUNCTION DEF: ([a-zA-Z_]\S+)$}
+ }
+ } elseif { [istarget *-*-darwin*] } {
+ set up_config(start) {
+ {^_([a-zA-Z_]\S+):$}
+ {^LFB[0-9]+:}
+ }
} else {
- set up_config(start) {^([a-zA-Z_]\S+):$}
+ set up_config(start) {{^([a-zA-Z_]\S+):$}}
}
# Regexp for the end of a function definition.
if { [istarget nvptx*-*-*] } {
set up_config(end) {^\}$}
+ } elseif { [istarget *-*-darwin*] } {
+ set up_config(end) {^LFE[0-9]+}
} else {
set up_config(end) {^\s*\.size}
}
-
+
# Regexp for lines that aren't interesting.
if { [istarget nvptx*-*-*] } {
# Skip lines beginning with '//' comments ('-fverbose-asm', for
# example).
set up_config(fluff) {^\s*(?://)}
+ } elseif { [istarget *-*-darwin*] } {
+ set up_config(fluff) {^\s*(?:\.|//|@)|^L[0-9ACESV]}
} else {
# Skip lines beginning with labels ('.L[...]:') or other directives
# ('.align', '.cfi_startproc', '.quad [...]', '.text', etc.), '//' or
@@ -852,11 +863,28 @@ proc parse_function_bodies { config filename result } {
set fd [open $filename r]
set in_function 0
while { [gets $fd line] >= 0 } {
- if { [regexp $up_config(start) $line dummy function_name] } {
- set in_function 1
- set function_body ""
+ if { $in_function == 0 } {
+ if { [regexp [lindex $up_config(start) 0] \
+ $line dummy function_name] } {
+ set in_function 1
+ set function_body ""
+ }
+ } elseif { $in_function < [llength $up_config(start)] } {
+ if { [regexp [lindex $up_config(start) $in_function] $line] } {
+ incr in_function
+ } else {
+ verbose "parse_function_bodies: skipped $function_name"
+ set in_function 0
+ }
} elseif { $in_function } {
- if { [regexp $up_config(end) $line] } {
+ # We allow multiple function start labels, taking the last one seen
+ # as the function name.
+ if { [regexp [lindex $up_config(start) 0] \
+ $line dummy maybe_function_name] } {
+ verbose "parse_function_bodies: overriding $function_name with $maybe_function_name"
+ set function_name $maybe_function_name
+ set in_function 1
+ } elseif { [regexp $up_config(end) $line] } {
verbose "parse_function_bodies: $function_name:\n$function_body"
set up_result($function_name) $function_body
set in_function 0
@@ -957,7 +985,6 @@ proc check-function-bodies { args } {
set start_expected {^(\S+):$}
configure_check-function-bodies config
-
set have_bodies 0
if { [is_remote host] } {
remote_upload host "$filename"
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 8777e3b..87b2ae5 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1983,6 +1983,17 @@ proc check_effective_target_riscv_ztso { } {
}]
}
+# Return 1 if the target arch supports the Zbb extension, 0 otherwise.
+# Cache the result.
+
+proc check_effective_target_riscv_zbb { } {
+ return [check_no_compiler_messages riscv_ext_zbb assembly {
+ #ifndef __riscv_zbb
+ #error "Not __riscv_zbb"
+ #endif
+ }]
+}
+
# Return 1 if we can execute code when using dg-add-options riscv_v
proc check_effective_target_riscv_v_ok { } {
@@ -3805,7 +3816,7 @@ proc check_effective_target___float128 { } {
}
proc add_options_for___float128 { flags } {
- if { [istarget powerpc*-*-*] } {
+ if { [istarget powerpc*-*-linux*] } {
return "$flags -mfloat128 -mvsx"
}
return "$flags"
@@ -5592,7 +5603,7 @@ proc check_effective_target_arm_thumb1_movt_ok {} {
proc check_effective_target_arm_thumb1_cbz_ok {} {
if [check_effective_target_arm_thumb1_ok] {
- return [check_no_compiler_messages arm_movt object {
+ return [check_no_compiler_messages arm_cbz object {
int
foo (void)
{
@@ -7178,7 +7189,7 @@ proc check_effective_target_powerpc_vsx_ok { } {
return 0
}
# Darwin doesn't have VSX, even if it's used with an assembler
- # which recognises the insns.
+ # which recognises the insns.
if { [istarget *-*-darwin*] } {
return 0
}
@@ -9257,7 +9268,8 @@ proc check_effective_target_vect_call_roundf { } {
proc check_effective_target_vect_logical_reduc { } {
return [expr { [check_effective_target_aarch64_sve]
|| [istarget amdgcn-*-*]
- || [check_effective_target_riscv_v] }]
+ || [check_effective_target_riscv_v]
+ || [istarget i?86-*-*] || [istarget x86_64-*-*]}]
}
# Return 1 if the target supports the fold_extract_last optab.
@@ -11090,7 +11102,7 @@ proc check_effective_target_gas { } {
if { [ string first "GNU" $as_output ] >= 0 } {
# Some Darwin versions have an assembler which is based on an old
# version of GAS (and reports GNU assembler in its -v output) but
- # but doesn't support many of the modern GAS features.
+ # but doesn't support many of the modern GAS features.
if { [ string first "cctools" $as_output ] >= 0 } {
set use_gas_saved 0
} else {
@@ -11563,7 +11575,6 @@ proc check_vect_support_and_set_flags { } {
set dg-do-what-default run
} elseif [istarget riscv64-*-*] {
if [check_effective_target_riscv_vector_hw] {
- lappend DEFAULT_VECTCFLAGS "--param" "riscv-autovec-preference=scalable"
lappend DEFAULT_VECTCFLAGS "--param" "riscv-vector-abi"
set dg-do-what-default run
} else {
diff --git a/gcc/testsuite/obj-c++.dg/has-feature.mm b/gcc/testsuite/obj-c++.dg/has-feature.mm
new file mode 100644
index 0000000..77c7617
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/has-feature.mm
@@ -0,0 +1,21 @@
+// { dg-do compile }
+
+#define CXX11 (__cplusplus >= 201103L)
+
+#if !__has_feature (objc_instancetype)
+#error
+#endif
+
+#if !__has_feature (objc_default_synthesize_properties)
+#error
+#endif
+
+// C features should not be available.
+#if __has_extension (c_alignas) || __has_feature (c_alignof)
+#error
+#endif
+
+// C++ features should be available (given the right standard).
+#if __has_feature (cxx_constexpr) != CXX11
+#error
+#endif
diff --git a/gcc/testsuite/objc.dg/has-feature.m b/gcc/testsuite/objc.dg/has-feature.m
new file mode 100644
index 0000000..168b0ce
--- /dev/null
+++ b/gcc/testsuite/objc.dg/has-feature.m
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+
+#define HAVE_C11 (__STDC_VERSION__ >= 201112L)
+
+#if !__has_feature (objc_instancetype)
+#error
+#endif
+
+#if !__has_feature (objc_default_synthesize_properties)
+#error
+#endif
+
+/* C features should be available as extensions. */
+#if !__has_extension (c_alignas)
+#error
+#endif
+
+/* And as features given the appropriate C standard. */
+#if __has_feature (c_alignas) != HAVE_C11
+#error
+#endif
+
+/* Shouldn't have C++ features even as extensions. */
+#if __has_feature (cxx_constexpr) || __has_extension (cxx_constexpr)
+#error
+#endif
diff --git a/gcc/toplev.cc b/gcc/toplev.cc
index 8c3fcd3..85450d9 100644
--- a/gcc/toplev.cc
+++ b/gcc/toplev.cc
@@ -1568,6 +1568,13 @@ process_options ()
flag_associative_math = 0;
}
+ if (flag_hardened && !HAVE_FHARDENED_SUPPORT)
+ {
+ warning_at (UNKNOWN_LOCATION, 0,
+ "%<-fhardened%> not supported for this target");
+ flag_hardened = 0;
+ }
+
/* -fstack-clash-protection is not currently supported on targets
where the stack grows up. */
if (flag_stack_clash_protection && !STACK_GROWS_DOWNWARD)
@@ -1577,6 +1584,19 @@ process_options ()
"where the stack grows from lower to higher addresses");
flag_stack_clash_protection = 0;
}
+ else if (flag_hardened)
+ {
+ if (!flag_stack_clash_protection
+ /* Don't enable -fstack-clash-protection when -fstack-check=
+ is used: it would result in confusing errors. */
+ && flag_stack_check == NO_STACK_CHECK)
+ flag_stack_clash_protection = 1;
+ else if (flag_stack_check != NO_STACK_CHECK)
+ warning_at (UNKNOWN_LOCATION, OPT_Whardened,
+ "%<-fstack-clash-protection%> is not enabled by "
+ "%<-fhardened%> because %<-fstack-check%> was "
+ "specified on the command line");
+ }
/* We cannot support -fstack-check= and -fstack-clash-protection at
the same time. */
@@ -1592,8 +1612,9 @@ process_options ()
target already uses a soft frame pointer, the transition is trivial. */
if (!FRAME_GROWS_DOWNWARD && flag_stack_protect)
{
- warning_at (UNKNOWN_LOCATION, 0,
- "%<-fstack-protector%> not supported for this target");
+ if (!flag_stack_protector_set_by_fhardened_p)
+ warning_at (UNKNOWN_LOCATION, 0,
+ "%<-fstack-protector%> not supported for this target");
flag_stack_protect = 0;
}
if (!flag_stack_protect)
diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc
index 2f67581..e2864e8 100644
--- a/gcc/tree-chrec.cc
+++ b/gcc/tree-chrec.cc
@@ -613,32 +613,54 @@ chrec_apply (unsigned var,
if (evolution_function_is_affine_p (chrec))
{
tree chrecr = CHREC_RIGHT (chrec);
+ tree chrecl = CHREC_LEFT (chrec);
if (CHREC_VARIABLE (chrec) != var)
- res = build_polynomial_chrec
- (CHREC_VARIABLE (chrec),
- chrec_apply (var, CHREC_LEFT (chrec), x),
- chrec_apply (var, chrecr, x));
+ res = build_polynomial_chrec (CHREC_VARIABLE (chrec),
+ chrec_apply (var, chrecl, x),
+ chrec_apply (var, chrecr, x));
- /* "{a, +, b} (x)" -> "a + b*x". */
- else if (operand_equal_p (CHREC_LEFT (chrec), chrecr)
+ /* "{a, +, a}" (x-1) -> "a*x". */
+ else if (operand_equal_p (chrecl, chrecr)
&& TREE_CODE (x) == PLUS_EXPR
&& integer_all_onesp (TREE_OPERAND (x, 1))
&& !POINTER_TYPE_P (type)
&& TYPE_PRECISION (TREE_TYPE (x))
>= TYPE_PRECISION (type))
{
- /* We know the number of iterations can't be negative.
- So {a, +, a} (x-1) -> "a*x". */
+ /* We know the number of iterations can't be negative. */
res = build_int_cst (TREE_TYPE (x), 1);
res = chrec_fold_plus (TREE_TYPE (x), x, res);
res = chrec_convert_rhs (type, res, NULL);
res = chrec_fold_multiply (type, chrecr, res);
}
+ /* "{a, +, b} (x)" -> "a + b*x". */
else
{
- res = chrec_convert_rhs (TREE_TYPE (chrecr), x, NULL);
- res = chrec_fold_multiply (TREE_TYPE (chrecr), chrecr, res);
- res = chrec_fold_plus (type, CHREC_LEFT (chrec), res);
+ /* The overall increment might not fit in a signed type so
+ use an unsigned computation to get at the final value
+ and avoid undefined signed overflow. */
+ tree utype = TREE_TYPE (chrecr);
+ if (INTEGRAL_TYPE_P (utype) && !TYPE_OVERFLOW_WRAPS (utype))
+ utype = unsigned_type_for (TREE_TYPE (chrecr));
+ res = chrec_convert_rhs (utype, x, NULL);
+ res = chrec_fold_multiply (utype,
+ chrec_convert (utype, chrecr, NULL),
+ res);
+ /* When the resulting increment fits the original type
+ do the increment in it. */
+ if (TREE_CODE (res) == INTEGER_CST
+ && int_fits_type_p (res, TREE_TYPE (chrecr)))
+ {
+ res = chrec_convert (TREE_TYPE (chrecr), res, NULL);
+ res = chrec_fold_plus (type, chrecl, res);
+ }
+ else
+ {
+ res = chrec_fold_plus (utype,
+ chrec_convert (utype, chrecl, NULL),
+ res);
+ res = chrec_convert (type, res, NULL);
+ }
}
}
else if (TREE_CODE (x) == INTEGER_CST
diff --git a/gcc/tree-loop-distribution.cc b/gcc/tree-loop-distribution.cc
index ffca535..95c1eea 100644
--- a/gcc/tree-loop-distribution.cc
+++ b/gcc/tree-loop-distribution.cc
@@ -2155,9 +2155,6 @@ loop_distribution::pg_add_dependence_edges (struct graph *rdg, int dir,
}
else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
{
- if (DDR_REVERSED_P (ddr))
- this_dir = -this_dir;
-
/* Known dependences can still be unordered througout the
iteration space, see gcc.dg/tree-ssa/ldist-16.c and
gcc.dg/tree-ssa/pr94969.c. */
@@ -2170,7 +2167,20 @@ loop_distribution::pg_add_dependence_edges (struct graph *rdg, int dir,
/* Else as the distance vector is lexicographic positive swap
the dependence direction. */
else
- this_dir = -this_dir;
+ {
+ if (DDR_REVERSED_P (ddr))
+ this_dir = -this_dir;
+ this_dir = -this_dir;
+
+ /* When then dependence distance of the innermost common
+ loop of the DRs is zero we have a conflict. */
+ auto l1 = gimple_bb (DR_STMT (dr1))->loop_father;
+ auto l2 = gimple_bb (DR_STMT (dr2))->loop_father;
+ int idx = index_in_loop_nest (find_common_loop (l1, l2)->num,
+ DDR_LOOP_NEST (ddr));
+ if (DDR_DIST_VECT (ddr, 0)[idx] == 0)
+ this_dir = 2;
+ }
}
else
this_dir = 0;
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index 7d3cb1e..9c8fdb8 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -281,10 +281,13 @@ gen_assign_counter_update (gimple_stmt_iterator *gsi, gcall *call, tree func,
if (result)
{
tree result_type = TREE_TYPE (TREE_TYPE (func));
- tree tmp = make_temp_ssa_name (result_type, NULL, name);
- gimple_set_lhs (call, tmp);
+ tree tmp1 = make_temp_ssa_name (result_type, NULL, name);
+ gimple_set_lhs (call, tmp1);
gsi_insert_after (gsi, call, GSI_NEW_STMT);
- gassign *assign = gimple_build_assign (result, tmp);
+ tree tmp2 = make_temp_ssa_name (TREE_TYPE (result), NULL, name);
+ gassign *assign = gimple_build_assign (tmp2, NOP_EXPR, tmp1);
+ gsi_insert_after (gsi, assign, GSI_NEW_STMT);
+ assign = gimple_build_assign (result, tmp2);
gsi_insert_after (gsi, assign, GSI_NEW_STMT);
}
else
@@ -304,18 +307,18 @@ gen_counter_update (gimple_stmt_iterator *gsi, tree counter, tree result,
tree one = build_int_cst (type, 1);
tree relaxed = build_int_cst (integer_type_node, MEMMODEL_RELAXED);
- if (counter_update == COUNTER_UPDATE_ATOMIC_BUILTIN ||
- (result && counter_update == COUNTER_UPDATE_ATOMIC_SPLIT))
+ if (counter_update == COUNTER_UPDATE_ATOMIC_BUILTIN
+ || (result && counter_update == COUNTER_UPDATE_ATOMIC_SPLIT))
{
/* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
tree f = builtin_decl_explicit (TYPE_PRECISION (type) > 32
- ? BUILT_IN_ATOMIC_ADD_FETCH_8:
- BUILT_IN_ATOMIC_ADD_FETCH_4);
+ ? BUILT_IN_ATOMIC_ADD_FETCH_8
+ : BUILT_IN_ATOMIC_ADD_FETCH_4);
gcall *call = gimple_build_call (f, 3, addr, one, relaxed);
gen_assign_counter_update (gsi, call, f, result, name);
}
- else if (!result && (counter_update == COUNTER_UPDATE_ATOMIC_SPLIT ||
- counter_update == COUNTER_UPDATE_ATOMIC_PARTIAL))
+ else if (!result && (counter_update == COUNTER_UPDATE_ATOMIC_SPLIT
+ || counter_update == COUNTER_UPDATE_ATOMIC_PARTIAL))
{
/* low = __atomic_add_fetch_4 (addr, 1, MEMMODEL_RELAXED);
high_inc = low == 0 ? 1 : 0;
@@ -354,7 +357,7 @@ gen_counter_update (gimple_stmt_iterator *gsi, tree counter, tree result,
tree tmp2 = make_temp_ssa_name (type, NULL, name);
gassign *assign2 = gimple_build_assign (tmp2, PLUS_EXPR, tmp1, one);
gsi_insert_after (gsi, assign2, GSI_NEW_STMT);
- gassign *assign3 = gimple_build_assign (counter, tmp2);
+ gassign *assign3 = gimple_build_assign (unshare_expr (counter), tmp2);
gsi_insert_after (gsi, assign3, GSI_NEW_STMT);
if (result)
{
@@ -764,6 +767,7 @@ tree_profiling (void)
= HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
bool have_atomic_8
= HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
+ bool needs_split = gcov_type_size == 8 && !have_atomic_8 && have_atomic_4;
if (!can_support_atomic)
{
if (gcov_type_size == 4)
@@ -772,6 +776,9 @@ tree_profiling (void)
can_support_atomic = have_atomic_8;
}
+ if (flag_profile_update != PROFILE_UPDATE_SINGLE && needs_split)
+ counter_update = COUNTER_UPDATE_ATOMIC_PARTIAL;
+
if (flag_profile_update == PROFILE_UPDATE_ATOMIC
&& !can_support_atomic)
{
@@ -780,18 +787,16 @@ tree_profiling (void)
flag_profile_update = PROFILE_UPDATE_SINGLE;
}
else if (flag_profile_update == PROFILE_UPDATE_PREFER_ATOMIC)
- flag_profile_update = can_support_atomic
- ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
+ flag_profile_update
+ = can_support_atomic ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
{
- if (gcov_type_size == 8 && !have_atomic_8 && have_atomic_4)
+ if (needs_split)
counter_update = COUNTER_UPDATE_ATOMIC_SPLIT;
else
counter_update = COUNTER_UPDATE_ATOMIC_BUILTIN;
}
- else if (gcov_type_size == 8 && have_atomic_4)
- counter_update = COUNTER_UPDATE_ATOMIC_PARTIAL;
/* This is a small-ipa pass that gets called only once, from
cgraphunit.cc:ipa_passes(). */
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index b985dee..3a0d5267 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -337,6 +337,9 @@ static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
because this would produce non-constant expressions (e.g. Ada). */
static bitmap disqualified_constants;
+/* Bitmap of candidates which are passed by reference in call arguments. */
+static bitmap passed_by_ref_in_call;
+
/* Obstack for creation of fancy names. */
static struct obstack name_obstack;
@@ -717,6 +720,7 @@ sra_initialize (void)
should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
disqualified_constants = BITMAP_ALLOC (NULL);
+ passed_by_ref_in_call = BITMAP_ALLOC (NULL);
gcc_obstack_init (&name_obstack);
base_access_vec = new hash_map<tree, auto_vec<access_p> >;
memset (&sra_stats, 0, sizeof (sra_stats));
@@ -733,6 +737,7 @@ sra_deinitialize (void)
BITMAP_FREE (should_scalarize_away_bitmap);
BITMAP_FREE (cannot_scalarize_away_bitmap);
BITMAP_FREE (disqualified_constants);
+ BITMAP_FREE (passed_by_ref_in_call);
access_pool.release ();
assign_link_pool.release ();
obstack_free (&name_obstack, NULL);
@@ -905,9 +910,9 @@ create_access (tree expr, gimple *stmt, bool write)
&reverse);
/* For constant-pool entries, check we can substitute the constant value. */
- if (constant_decl_p (base))
+ if (constant_decl_p (base)
+ && !bitmap_bit_p (disqualified_constants, DECL_UID (base)))
{
- gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base)));
if (expr != base
&& !is_gimple_reg_type (TREE_TYPE (expr))
&& dump_file && (dump_flags & TDF_DETAILS))
@@ -1135,6 +1140,17 @@ sra_handled_bf_read_p (tree expr)
static struct access *
build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
{
+ /* We only allow ADDR_EXPRs in arguments of function calls and those must
+ have been dealt with in build_access_from_call_arg. Any other address
+ taking should have been caught by scan_visit_addr. */
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ tree base = get_base_address (TREE_OPERAND (expr, 0));
+ gcc_assert (!DECL_P (base)
+ || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)));
+ return NULL;
+ }
+
struct access *ret = NULL;
bool partial_ref;
@@ -1223,6 +1239,77 @@ build_access_from_expr (tree expr, gimple *stmt, bool write)
return false;
}
+enum out_edge_check { SRA_OUTGOING_EDGES_UNCHECKED, SRA_OUTGOING_EDGES_OK,
+ SRA_OUTGOING_EDGES_FAIL };
+
+/* Return true if STMT terminates BB and there is an abnormal edge going out of
+ the BB and remember the decision in OE_CHECK. */
+
+static bool
+abnormal_edge_after_stmt_p (gimple *stmt, enum out_edge_check *oe_check)
+{
+ if (*oe_check == SRA_OUTGOING_EDGES_OK)
+ return false;
+ if (*oe_check == SRA_OUTGOING_EDGES_FAIL)
+ return true;
+ if (stmt_ends_bb_p (stmt))
+ {
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
+ if (e->flags & EDGE_ABNORMAL)
+ {
+ *oe_check = SRA_OUTGOING_EDGES_FAIL;
+ return true;
+ }
+ }
+ *oe_check = SRA_OUTGOING_EDGES_OK;
+ return false;
+}
+
+/* Scan expression EXPR which is an argument of a call and create access
+ structures for all accesses to candidates for scalarization. Return true if
+ any access has been inserted. STMT must be the statement from which the
+ expression is taken. */
+
+static bool
+build_access_from_call_arg (tree expr, gimple *stmt,
+ enum out_edge_check *oe_check)
+{
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ tree base = get_base_address (TREE_OPERAND (expr, 0));
+
+ if (abnormal_edge_after_stmt_p (stmt, oe_check))
+ {
+ disqualify_base_of_expr (base, "May lead to need to add statements "
+ "to abnormal edge.");
+ return false;
+ }
+
+ bool read = build_access_from_expr (base, stmt, false);
+ bool write = build_access_from_expr (base, stmt, true);
+ if (read || write)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Allowed ADDR_EXPR of ");
+ print_generic_expr (dump_file, base);
+ fprintf (dump_file, " because of ");
+ print_gimple_stmt (dump_file, stmt, 0);
+ fprintf (dump_file, "\n");
+ }
+ bitmap_set_bit (passed_by_ref_in_call, DECL_UID (base));
+ return true;
+ }
+ else
+ return false;
+ }
+
+ return build_access_from_expr (expr, stmt, false);
+}
+
+
/* Return the single non-EH successor edge of BB or NULL if there is none or
more than one. */
@@ -1364,16 +1451,18 @@ build_accesses_from_assign (gimple *stmt)
return lacc || racc;
}
-/* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
- GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
+/* Callback of walk_stmt_load_store_addr_ops visit_addr used to detect taking
+ addresses of candidates a places which are not call arguments. Such
+ candidates are disqalified from SRA. This also applies to GIMPLE_ASM
+ operands with memory constrains which cannot be scalarized. */
static bool
-asm_visit_addr (gimple *, tree op, tree, void *)
+scan_visit_addr (gimple *, tree op, tree, void *)
{
op = get_base_address (op);
if (op
&& DECL_P (op))
- disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
+ disqualify_candidate (op, "Address taken in a non-call-argument context.");
return false;
}
@@ -1390,12 +1479,20 @@ scan_function (void)
FOR_EACH_BB_FN (bb, cfun)
{
gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ walk_stmt_load_store_addr_ops (gsi_stmt (gsi), NULL, NULL, NULL,
+ scan_visit_addr);
+
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple *stmt = gsi_stmt (gsi);
tree t;
unsigned i;
+ if (gimple_code (stmt) != GIMPLE_CALL)
+ walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
+ scan_visit_addr);
+
switch (gimple_code (stmt))
{
case GIMPLE_RETURN:
@@ -1409,9 +1506,15 @@ scan_function (void)
break;
case GIMPLE_CALL:
- for (i = 0; i < gimple_call_num_args (stmt); i++)
- ret |= build_access_from_expr (gimple_call_arg (stmt, i),
- stmt, false);
+ {
+ enum out_edge_check oe_check = SRA_OUTGOING_EDGES_UNCHECKED;
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ ret |= build_access_from_call_arg (gimple_call_arg (stmt, i),
+ stmt, &oe_check);
+ if (gimple_call_chain(stmt))
+ ret |= build_access_from_call_arg (gimple_call_chain(stmt),
+ stmt, &oe_check);
+ }
t = gimple_call_lhs (stmt);
if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
@@ -1428,8 +1531,6 @@ scan_function (void)
case GIMPLE_ASM:
{
gasm *asm_stmt = as_a <gasm *> (stmt);
- walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
- asm_visit_addr);
for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
{
t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
@@ -1920,10 +2021,19 @@ maybe_add_sra_candidate (tree var)
reject (var, "not aggregate");
return false;
}
- /* Allow constant-pool entries that "need to live in memory". */
- if (needs_to_live_in_memory (var) && !constant_decl_p (var))
+
+ if ((is_global_var (var)
+ /* There are cases where non-addressable variables fail the
+ pt_solutions_check test, e.g in gcc.dg/uninit-40.c. */
+ || (TREE_ADDRESSABLE (var)
+ && pt_solution_includes (&cfun->gimple_df->escaped, var))
+ || (TREE_CODE (var) == RESULT_DECL
+ && !DECL_BY_REFERENCE (var)
+ && aggregate_value_p (var, current_function_decl)))
+ /* Allow constant-pool entries that "need to live in memory". */
+ && !constant_decl_p (var))
{
- reject (var, "needs to live in memory");
+ reject (var, "needs to live in memory and escapes or global");
return false;
}
if (TREE_THIS_VOLATILE (var))
@@ -2122,6 +2232,23 @@ sort_and_splice_var_accesses (tree var)
gcc_assert (access->offset >= low
&& access->offset + access->size <= high);
+ if (INTEGRAL_TYPE_P (access->type)
+ && TYPE_PRECISION (access->type) != access->size
+ && bitmap_bit_p (passed_by_ref_in_call, DECL_UID (access->base)))
+ {
+ /* This can lead to performance regressions because we can generate
+ excessive zero extensions. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Won't scalarize ");
+ print_generic_expr (dump_file, access->base);
+ fprintf (dump_file, "(%d), it is passed by reference to a call "
+ "and there are accesses with precision not covering "
+ "their type size.", DECL_UID (access->base));
+ }
+ return NULL;
+ }
+
grp_same_access_path = path_comparable_for_same_access (access->expr);
j = i + 1;
@@ -3774,12 +3901,18 @@ get_access_for_expr (tree expr)
/* Replace the expression EXPR with a scalar replacement if there is one and
generate other statements to do type conversion or subtree copying if
- necessary. GSI is used to place newly created statements, WRITE is true if
- the expression is being written to (it is on a LHS of a statement or output
- in an assembly statement). */
+ necessary. WRITE is true if the expression is being written to (it is on a
+ LHS of a statement or output in an assembly statement). STMT_GSI is used to
+ place newly created statements before the processed statement, REFRESH_GSI
+ is used to place them afterwards - unless the processed statement must end a
+ BB in which case it is placed on the outgoing non-EH edge. REFRESH_GSI and
+ is then used to continue iteration over the BB. If sra_modify_expr is
+ called only once with WRITE equal to true on a given statement, both
+ iterator parameters can point to the same one. */
static bool
-sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
+sra_modify_expr (tree *expr, bool write, gimple_stmt_iterator *stmt_gsi,
+ gimple_stmt_iterator *refresh_gsi)
{
location_t loc;
struct access *access;
@@ -3806,12 +3939,12 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
type = TREE_TYPE (*expr);
orig_expr = *expr;
- loc = gimple_location (gsi_stmt (*gsi));
+ loc = gimple_location (gsi_stmt (*stmt_gsi));
gimple_stmt_iterator alt_gsi = gsi_none ();
- if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
+ if (write && stmt_ends_bb_p (gsi_stmt (*stmt_gsi)))
{
- alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
- gsi = &alt_gsi;
+ alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*stmt_gsi)));
+ refresh_gsi = &alt_gsi;
}
if (access->grp_to_be_replaced)
@@ -3831,7 +3964,8 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
{
tree ref;
- ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
+ ref = build_ref_for_model (loc, orig_expr, 0, access, stmt_gsi,
+ false);
if (partial_cplx_access)
{
@@ -3847,7 +3981,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
tree tmp = make_ssa_name (type);
gassign *stmt = gimple_build_assign (tmp, t);
/* This is always a read. */
- gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ gsi_insert_before (stmt_gsi, stmt, GSI_SAME_STMT);
t = tmp;
}
*expr = t;
@@ -3857,22 +3991,23 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
gassign *stmt;
if (access->grp_partial_lhs)
- ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
- false, GSI_NEW_STMT);
+ ref = force_gimple_operand_gsi (refresh_gsi, ref, true,
+ NULL_TREE, false, GSI_NEW_STMT);
stmt = gimple_build_assign (repl, ref);
gimple_set_location (stmt, loc);
- gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ gsi_insert_after (refresh_gsi, stmt, GSI_NEW_STMT);
}
else
{
gassign *stmt;
if (access->grp_partial_lhs)
- repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
- true, GSI_SAME_STMT);
+ repl = force_gimple_operand_gsi (stmt_gsi, repl, true,
+ NULL_TREE, true,
+ GSI_SAME_STMT);
stmt = gimple_build_assign (ref, repl);
gimple_set_location (stmt, loc);
- gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ gsi_insert_before (stmt_gsi, stmt, GSI_SAME_STMT);
}
}
else
@@ -3899,8 +4034,8 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
{
gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
NULL_TREE,
- gsi_stmt (*gsi));
- gsi_insert_after (gsi, ds, GSI_NEW_STMT);
+ gsi_stmt (*stmt_gsi));
+ gsi_insert_after (stmt_gsi, ds, GSI_NEW_STMT);
}
if (access->first_child && !TREE_READONLY (access->base))
@@ -3918,8 +4053,57 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
start_offset = chunk_size = 0;
generate_subtree_copies (access->first_child, orig_expr, access->offset,
- start_offset, chunk_size, gsi, write, write,
- loc);
+ start_offset, chunk_size,
+ write ? refresh_gsi : stmt_gsi,
+ write, write, loc);
+ }
+ return true;
+}
+
+/* If EXPR, which must be a call argument, is an ADDR_EXPR, generate writes and
+ reads from its base before and after the call statement given in CALL_GSI
+ and return true if any copying took place. Otherwise call sra_modify_expr
+ on EXPR and return its value. FLAGS is what the gimple_call_arg_flags
+ return for the given parameter. */
+
+static bool
+sra_modify_call_arg (tree *expr, gimple_stmt_iterator *call_gsi,
+ gimple_stmt_iterator *refresh_gsi, int flags)
+{
+ if (TREE_CODE (*expr) != ADDR_EXPR)
+ return sra_modify_expr (expr, false, call_gsi, refresh_gsi);
+
+ if (flags & EAF_UNUSED)
+ return false;
+
+ tree base = get_base_address (TREE_OPERAND (*expr, 0));
+ if (!DECL_P (base))
+ return false;
+ struct access *access = get_access_for_expr (base);
+ if (!access)
+ return false;
+
+ gimple *stmt = gsi_stmt (*call_gsi);
+ location_t loc = gimple_location (stmt);
+ generate_subtree_copies (access, base, 0, 0, 0, call_gsi, false, false,
+ loc);
+
+ if (flags & EAF_NO_DIRECT_CLOBBER)
+ return true;
+
+ if (!stmt_ends_bb_p (stmt))
+ generate_subtree_copies (access, base, 0, 0, 0, refresh_gsi, true,
+ true, loc);
+ else
+ {
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, gsi_bb (*call_gsi)->succs)
+ {
+ gimple_stmt_iterator alt_gsi = gsi_start_edge (e);
+ generate_subtree_copies (access, base, 0, 0, 0, &alt_gsi, true,
+ true, loc);
+ }
}
return true;
}
@@ -4279,9 +4463,9 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|| TREE_CODE (lhs) == BIT_FIELD_REF)
{
modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
- gsi, false);
+ false, gsi, gsi);
modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
- gsi, true);
+ true, gsi, gsi);
return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
}
@@ -4603,7 +4787,7 @@ sra_modify_function_body (void)
case GIMPLE_RETURN:
t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
if (*t != NULL_TREE)
- modified |= sra_modify_expr (t, &gsi, false);
+ modified |= sra_modify_expr (t, false, &gsi, &gsi);
break;
case GIMPLE_ASSIGN:
@@ -4622,33 +4806,44 @@ sra_modify_function_body (void)
}
else
{
+ gcall *call = as_a <gcall *> (stmt);
+ gimple_stmt_iterator call_gsi = gsi;
+
/* Operands must be processed before the lhs. */
- for (i = 0; i < gimple_call_num_args (stmt); i++)
+ for (i = 0; i < gimple_call_num_args (call); i++)
{
- t = gimple_call_arg_ptr (stmt, i);
- modified |= sra_modify_expr (t, &gsi, false);
+ int flags = gimple_call_arg_flags (call, i);
+ t = gimple_call_arg_ptr (call, i);
+ modified |= sra_modify_call_arg (t, &call_gsi, &gsi, flags);
}
-
- if (gimple_call_lhs (stmt))
+ if (gimple_call_chain (call))
+ {
+ t = gimple_call_chain_ptr (call);
+ int flags = gimple_call_static_chain_flags (call);
+ modified |= sra_modify_call_arg (t, &call_gsi, &gsi,
+ flags);
+ }
+ if (gimple_call_lhs (call))
{
- t = gimple_call_lhs_ptr (stmt);
- modified |= sra_modify_expr (t, &gsi, true);
+ t = gimple_call_lhs_ptr (call);
+ modified |= sra_modify_expr (t, true, &call_gsi, &gsi);
}
}
break;
case GIMPLE_ASM:
{
+ gimple_stmt_iterator stmt_gsi = gsi;
gasm *asm_stmt = as_a <gasm *> (stmt);
for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
{
t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
- modified |= sra_modify_expr (t, &gsi, false);
+ modified |= sra_modify_expr (t, false, &stmt_gsi, &gsi);
}
for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
{
t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
- modified |= sra_modify_expr (t, &gsi, true);
+ modified |= sra_modify_expr (t, true, &stmt_gsi, &gsi);
}
}
break;
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index d39dfc1..0fb21e5 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-cfgcleanup.h"
#include "cfganal.h"
#include "optabs-tree.h"
+#include "insn-config.h"
+#include "recog.h"
#include "tree-vector-builder.h"
#include "vec-perm-indices.h"
#include "internal-fn.h"
@@ -2978,6 +2980,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
/* Only few targets implement direct conversion patterns so try
some simple special cases via VEC_[UN]PACK[_FLOAT]_LO_EXPR. */
optab optab;
+ insn_code icode;
tree halfvectype, dblvectype;
enum tree_code unpack_op;
@@ -3015,8 +3018,9 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
&& (optab = optab_for_tree_code (unpack_op,
dblvectype,
optab_default))
- && (optab_handler (optab, TYPE_MODE (dblvectype))
- != CODE_FOR_nothing))
+ && ((icode = optab_handler (optab, TYPE_MODE (dblvectype)))
+ != CODE_FOR_nothing)
+ && (insn_data[icode].operand[0].mode == TYPE_MODE (type)))
{
gimple_seq stmts = NULL;
tree dbl;
@@ -3054,8 +3058,9 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
&& (optab = optab_for_tree_code (VEC_PACK_TRUNC_EXPR,
halfvectype,
optab_default))
- && (optab_handler (optab, TYPE_MODE (halfvectype))
- != CODE_FOR_nothing))
+ && ((icode = optab_handler (optab, TYPE_MODE (halfvectype)))
+ != CODE_FOR_nothing)
+ && (insn_data[icode].operand[0].mode == TYPE_MODE (type)))
{
gimple_seq stmts = NULL;
tree low = gimple_build (&stmts, BIT_FIELD_REF, halfvectype,
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 95eda43..bcc02ae 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -5154,6 +5154,81 @@ match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
return true;
}
+/* Replace .POPCOUNT (x) == 1 or .POPCOUNT (x) != 1 with
+ (x & (x - 1)) > x - 1 or (x & (x - 1)) <= x - 1 if .POPCOUNT
+ isn't a direct optab. */
+
+static void
+match_single_bit_test (gimple_stmt_iterator *gsi, gimple *stmt)
+{
+ tree clhs, crhs;
+ enum tree_code code;
+ if (gimple_code (stmt) == GIMPLE_COND)
+ {
+ clhs = gimple_cond_lhs (stmt);
+ crhs = gimple_cond_rhs (stmt);
+ code = gimple_cond_code (stmt);
+ }
+ else
+ {
+ clhs = gimple_assign_rhs1 (stmt);
+ crhs = gimple_assign_rhs2 (stmt);
+ code = gimple_assign_rhs_code (stmt);
+ }
+ if (code != EQ_EXPR && code != NE_EXPR)
+ return;
+ if (TREE_CODE (clhs) != SSA_NAME || !integer_onep (crhs))
+ return;
+ gimple *call = SSA_NAME_DEF_STMT (clhs);
+ combined_fn cfn = gimple_call_combined_fn (call);
+ switch (cfn)
+ {
+ CASE_CFN_POPCOUNT:
+ break;
+ default:
+ return;
+ }
+ if (!has_single_use (clhs))
+ return;
+ tree arg = gimple_call_arg (call, 0);
+ tree type = TREE_TYPE (arg);
+ if (!INTEGRAL_TYPE_P (type))
+ return;
+ if (direct_internal_fn_supported_p (IFN_POPCOUNT, type, OPTIMIZE_FOR_BOTH))
+ {
+ /* Tell expand_POPCOUNT the popcount result is only used in equality
+ comparison with one, so that it can decide based on rtx costs. */
+ gimple *g = gimple_build_call_internal (IFN_POPCOUNT, 2, arg,
+ integer_one_node);
+ gimple_call_set_lhs (g, gimple_call_lhs (call));
+ gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
+ gsi_replace (&gsi2, g, true);
+ return;
+ }
+ tree argm1 = make_ssa_name (type);
+ gimple *g = gimple_build_assign (argm1, PLUS_EXPR, arg,
+ build_int_cst (type, -1));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (make_ssa_name (type), BIT_XOR_EXPR, arg, argm1);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ if (gcond *cond = dyn_cast <gcond *> (stmt))
+ {
+ gimple_cond_set_lhs (cond, gimple_assign_lhs (g));
+ gimple_cond_set_rhs (cond, argm1);
+ gimple_cond_set_code (cond, code == EQ_EXPR ? GT_EXPR : LE_EXPR);
+ }
+ else
+ {
+ gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (g));
+ gimple_assign_set_rhs2 (stmt, argm1);
+ gimple_assign_set_rhs_code (stmt, code == EQ_EXPR ? GT_EXPR : LE_EXPR);
+ }
+ update_stmt (stmt);
+ gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
+ gsi_remove (&gsi2, true);
+ release_defs (call);
+}
+
/* Return true if target has support for divmod. */
static bool
@@ -5807,6 +5882,11 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
match_uaddc_usubc (&gsi, stmt, code);
break;
+ case EQ_EXPR:
+ case NE_EXPR:
+ match_single_bit_test (&gsi, stmt);
+ break;
+
default:;
}
}
@@ -5872,7 +5952,10 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
}
}
else if (gimple_code (stmt) == GIMPLE_COND)
- optimize_spaceship (as_a <gcond *> (stmt));
+ {
+ match_single_bit_test (&gsi, stmt);
+ optimize_spaceship (as_a <gcond *> (stmt));
+ }
gsi_next (&gsi);
}
if (fma_state.m_deferring_p
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 26321aa..07fc8e2 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -5431,16 +5431,19 @@ get_required_cycles (int ops_num, int cpu_width)
}
/* Returns an optimal number of registers to use for computation of
- given statements. */
+ given statements.
+
+ LHS is the result ssa name of OPS. */
static int
-get_reassociation_width (int ops_num, enum tree_code opc,
- machine_mode mode)
+get_reassociation_width (vec<operand_entry *> *ops, tree lhs,
+ enum tree_code opc, machine_mode mode)
{
int param_width = param_tree_reassoc_width;
int width;
int width_min;
int cycles_best;
+ int ops_num = ops->length ();
if (param_width > 0)
width = param_width;
@@ -5471,6 +5474,61 @@ get_reassociation_width (int ops_num, enum tree_code opc,
break;
}
+ /* If there's loop dependent FMA result, return width=2 to avoid it. This is
+ better than skipping these FMA candidates in widening_mul. */
+ if (width == 1
+ && maybe_le (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (lhs))),
+ param_avoid_fma_max_bits))
+ {
+ /* Look for cross backedge dependency:
+ 1. LHS is a phi argument in the same basic block it is defined.
+ 2. And the result of the phi node is used in OPS. */
+ basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (lhs));
+
+ use_operand_p use_p;
+ imm_use_iterator iter;
+ FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
+ if (gphi *phi = dyn_cast<gphi *> (USE_STMT (use_p)))
+ {
+ if (gimple_phi_arg_edge (phi, phi_arg_index_from_use (use_p))->src
+ != bb)
+ continue;
+ tree phi_result = gimple_phi_result (phi);
+ operand_entry *oe;
+ unsigned int j;
+ FOR_EACH_VEC_ELT (*ops, j, oe)
+ {
+ if (TREE_CODE (oe->op) != SSA_NAME)
+ continue;
+
+ /* Result of phi is operand of PLUS_EXPR. */
+ if (oe->op == phi_result)
+ return 2;
+
+ /* Check is result of phi is operand of MULT_EXPR. */
+ gimple *def_stmt = SSA_NAME_DEF_STMT (oe->op);
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR)
+ {
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ if (rhs == phi_result)
+ return 2;
+ def_stmt = SSA_NAME_DEF_STMT (rhs);
+ }
+ }
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == MULT_EXPR)
+ {
+ if (gimple_assign_rhs1 (def_stmt) == phi_result
+ || gimple_assign_rhs2 (def_stmt) == phi_result)
+ return 2;
+ }
+ }
+ }
+ }
+
return width;
}
@@ -7031,8 +7089,9 @@ reassociate_bb (basic_block bb)
with initial linearization. */
if (!reassoc_insert_powi_p
&& ops.length () > 3
- && (width = get_reassociation_width (ops_num, rhs_code,
- mode)) > 1)
+ && (width
+ = get_reassociation_width (&ops, lhs, rhs_code, mode))
+ > 1)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
@@ -7049,7 +7108,13 @@ reassociate_bb (basic_block bb)
to make sure the ones that get the double
binary op are chosen wisely. */
int len = ops.length ();
- if (len >= 3 && !has_fma)
+ if (len >= 3
+ && (!has_fma
+ /* width > 1 means ranking ops results in better
+ parallelism. */
+ || get_reassociation_width (&ops, lhs, rhs_code,
+ mode)
+ > 1))
swap_ops_for_binary_stmt (ops, len - 3);
new_lhs = rewrite_expr_tree (stmt, rhs_code, 0, ops,
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index b7675d8..3df020d 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -2817,9 +2817,6 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal,
"can't determine vectorization factor.\n");
return ok;
}
- if (max_vf != MAX_VECTORIZATION_FACTOR
- && maybe_lt (max_vf, LOOP_VINFO_VECT_FACTOR (loop_vinfo)))
- return opt_result::failure_at (vect_location, "bad data dependence.\n");
/* Compute the scalar iteration cost. */
vect_compute_single_scalar_iteration_cost (loop_vinfo);
@@ -2881,6 +2878,10 @@ start_over:
LOOP_VINFO_INT_NITERS (loop_vinfo));
}
+ if (max_vf != MAX_VECTORIZATION_FACTOR
+ && maybe_lt (max_vf, LOOP_VINFO_VECT_FACTOR (loop_vinfo)))
+ return opt_result::failure_at (vect_location, "bad data dependence.\n");
+
loop_vinfo->vector_costs = init_cost (loop_vinfo, false);
/* Analyze the alignment of the data-refs in the loop.
@@ -7070,7 +7071,7 @@ vectorize_fold_left_reduction (loop_vec_info loop_vinfo,
op0 = ops[1 - reduc_index];
else
{
- op0 = ops[2];
+ op0 = ops[2 + (1 - reduc_index)];
opmask = ops[0];
gcc_assert (!slp_node);
}
@@ -7384,7 +7385,6 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
stmt_vector_for_cost *cost_vec)
{
tree vectype_in = NULL_TREE;
- tree vectype_op[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
enum vect_def_type cond_reduc_dt = vect_unknown_def_type;
stmt_vec_info cond_stmt_vinfo = NULL;
@@ -7616,6 +7616,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
assumption is not true: we use reduc_index to record the index of the
reduction variable. */
slp_tree *slp_op = XALLOCAVEC (slp_tree, op.num_ops);
+ tree *vectype_op = XALLOCAVEC (tree, op.num_ops);
/* We need to skip an extra operand for COND_EXPRs with embedded
comparison. */
unsigned opno_adjust = 0;
@@ -8455,7 +8456,9 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
gcc_assert (code == IFN_COND_ADD || code == IFN_COND_SUB
|| code == IFN_COND_MUL || code == IFN_COND_AND
|| code == IFN_COND_IOR || code == IFN_COND_XOR);
- gcc_assert (op.num_ops == 4 && (op.ops[1] == op.ops[3]));
+ gcc_assert (op.num_ops == 4
+ && (op.ops[reduc_index]
+ == op.ops[internal_fn_else_index ((internal_fn) code)]));
}
bool masked_loop_p = LOOP_VINFO_FULLY_MASKED_P (loop_vinfo);
@@ -8498,12 +8501,14 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
{
/* For a conditional operation pass the truth type as mask
vectype. */
- gcc_assert (single_defuse_cycle && reduc_index == 1);
+ gcc_assert (single_defuse_cycle
+ && (reduc_index == 1 || reduc_index == 2));
vect_get_vec_defs (loop_vinfo, stmt_info, slp_node, ncopies,
- op.ops[0], &vec_oprnds0,
- truth_type_for (vectype_in),
- NULL_TREE, &vec_oprnds1, NULL_TREE,
- op.ops[2], &vec_oprnds2, NULL_TREE);
+ op.ops[0], &vec_oprnds0, truth_type_for (vectype_in),
+ reduc_index == 1 ? NULL_TREE : op.ops[1],
+ &vec_oprnds1, NULL_TREE,
+ reduc_index == 2 ? NULL_TREE : op.ops[2],
+ &vec_oprnds2, NULL_TREE);
}
/* For single def-use cycles get one copy of the vectorized reduction
@@ -11361,7 +11366,16 @@ vect_transform_loop_stmt (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
if (!STMT_VINFO_RELEVANT_P (stmt_info)
&& !STMT_VINFO_LIVE_P (stmt_info))
- return false;
+ {
+ if (is_gimple_call (stmt_info->stmt)
+ && gimple_call_internal_p (stmt_info->stmt, IFN_MASK_CALL))
+ {
+ gcc_assert (!gimple_call_lhs (stmt_info->stmt));
+ *seen_store = stmt_info;
+ return false;
+ }
+ return false;
+ }
if (STMT_VINFO_VECTYPE (stmt_info))
{
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 7debe7f..696b70b 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -5830,7 +5830,8 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
tree rhs1_op0 = NULL_TREE, rhs1_op1 = NULL_TREE;
tree rhs1_op0_type = NULL_TREE, rhs1_op1_type = NULL_TREE;
- /* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion. */
+ /* Check for MASK_LOAD and MASK_STORE as well as COND_OP calls requiring mask
+ conversion. */
if (is_gimple_call (last_stmt)
&& gimple_call_internal_p (last_stmt))
{
@@ -5842,6 +5843,7 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
return NULL;
bool store_p = internal_store_fn_p (ifn);
+ bool load_p = internal_store_fn_p (ifn);
if (store_p)
{
int rhs_index = internal_fn_stored_value_index (ifn);
@@ -5856,15 +5858,21 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
vectype1 = get_vectype_for_scalar_type (vinfo, TREE_TYPE (lhs));
}
+ if (!vectype1)
+ return NULL;
+
tree mask_arg = gimple_call_arg (last_stmt, mask_argno);
tree mask_arg_type = integer_type_for_mask (mask_arg, vinfo);
- if (!mask_arg_type)
- return NULL;
- vectype2 = get_mask_type_for_scalar_type (vinfo, mask_arg_type);
+ if (mask_arg_type)
+ {
+ vectype2 = get_mask_type_for_scalar_type (vinfo, mask_arg_type);
- if (!vectype1 || !vectype2
- || known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
- TYPE_VECTOR_SUBPARTS (vectype2)))
+ if (!vectype2
+ || known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
+ TYPE_VECTOR_SUBPARTS (vectype2)))
+ return NULL;
+ }
+ else if (store_p || load_p)
return NULL;
tmp = build_mask_conversion (vinfo, mask_arg, vectype1, stmt_vinfo);
@@ -5883,7 +5891,9 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
gimple_call_set_lhs (pattern_stmt, lhs);
}
- gimple_call_set_nothrow (pattern_stmt, true);
+
+ if (load_p || store_p)
+ gimple_call_set_nothrow (pattern_stmt, true);
pattern_stmt_info = vinfo->add_stmt (pattern_stmt);
if (STMT_VINFO_DATA_REF (stmt_vinfo))
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 4a09b3c..6799b93 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -763,18 +763,6 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char swap,
{
tree type = TREE_TYPE (oprnd);
dt = dts[i];
- if ((dt == vect_constant_def
- || dt == vect_external_def)
- && !GET_MODE_SIZE (vinfo->vector_mode).is_constant ()
- && TREE_CODE (type) != BOOLEAN_TYPE
- && !can_duplicate_and_interleave_p (vinfo, stmts.length (), type))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "Build SLP failed: invalid type of def "
- "for variable-length SLP %T\n", oprnd);
- return -1;
- }
/* For the swapping logic below force vect_reduction_def
for the reduction op in a SLP reduction group. */
@@ -2395,7 +2383,7 @@ out:
/* Create SLP_TREE nodes for the definition node/s. */
FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
{
- slp_tree child;
+ slp_tree child = nullptr;
unsigned int j;
/* We're skipping certain operands from processing, for example
@@ -2443,6 +2431,29 @@ out:
if (oprnd_info->first_dt == vect_external_def
|| oprnd_info->first_dt == vect_constant_def)
{
+ if (!GET_MODE_SIZE (vinfo->vector_mode).is_constant ())
+ {
+ tree op0;
+ tree uniform_val = op0 = oprnd_info->ops[0];
+ for (j = 1; j < oprnd_info->ops.length (); ++j)
+ if (!operand_equal_p (uniform_val, oprnd_info->ops[j]))
+ {
+ uniform_val = NULL_TREE;
+ break;
+ }
+ if (!uniform_val
+ && !can_duplicate_and_interleave_p (vinfo,
+ oprnd_info->ops.length (),
+ TREE_TYPE (op0)))
+ {
+ matches[j] = false;
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: invalid type of def "
+ "for variable-length SLP %T\n", op0);
+ goto fail;
+ }
+ }
slp_tree invnode = vect_create_new_slp_node (oprnd_info->ops);
SLP_TREE_DEF_TYPE (invnode) = oprnd_info->first_dt;
oprnd_info->ops = vNULL;
@@ -8157,6 +8168,7 @@ vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node)
number_of_places_left_in_vector = nunits;
constant_p = true;
+ tree uniform_elt = NULL_TREE;
tree_vector_builder elts (vector_type, nunits, 1);
elts.quick_grow (nunits);
stmt_vec_info insert_after = NULL;
@@ -8166,8 +8178,14 @@ vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node)
for (i = group_size - 1; op_node->ops.iterate (i, &op); i--)
{
/* Create 'vect_ = {op0,op1,...,opn}'. */
- number_of_places_left_in_vector--;
tree orig_op = op;
+ if (number_of_places_left_in_vector == nunits)
+ uniform_elt = op;
+ else if (uniform_elt && operand_equal_p (uniform_elt, op))
+ op = elts[number_of_places_left_in_vector];
+ else
+ uniform_elt = NULL_TREE;
+ number_of_places_left_in_vector--;
if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
{
if (CONSTANT_CLASS_P (op))
@@ -8236,9 +8254,13 @@ vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node)
if (number_of_places_left_in_vector == 0)
{
- if (constant_p
- ? multiple_p (TYPE_VECTOR_SUBPARTS (vector_type), nunits)
- : known_eq (TYPE_VECTOR_SUBPARTS (vector_type), nunits))
+ auto type_nunits = TYPE_VECTOR_SUBPARTS (vector_type);
+ if (uniform_elt)
+ vec_cst = gimple_build_vector_from_val (&ctor_seq, vector_type,
+ elts[0]);
+ else if (constant_p
+ ? multiple_p (type_nunits, nunits)
+ : known_eq (type_nunits, nunits))
vec_cst = gimple_build_vector (&ctor_seq, &elts);
else
{
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 96e4a6cf..bf8c997 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -9188,7 +9188,8 @@ vectorizable_store (vec_info *vinfo,
unsigned HOST_WIDE_INT factor
= const_offset_nunits / const_nunits;
vec_offset = vec_offsets[(vec_num * j + i) / factor];
- unsigned elt_offset = (j % factor) * const_nunits;
+ unsigned elt_offset
+ = ((vec_num * j + i) % factor) * const_nunits;
tree idx_type = TREE_TYPE (TREE_TYPE (vec_offset));
tree scale = size_int (gs_info.scale);
align = get_object_alignment (DR_REF (first_dr_info->dr));
@@ -11150,7 +11151,8 @@ vectorizable_load (vec_info *vinfo,
unsigned HOST_WIDE_INT factor
= const_offset_nunits / const_nunits;
vec_offset = vec_offsets[(vec_num * j + i) / factor];
- unsigned elt_offset = (j % factor) * const_nunits;
+ unsigned elt_offset
+ = ((vec_num * j + i) % factor) * const_nunits;
tree idx_type = TREE_TYPE (TREE_TYPE (vec_offset));
tree scale = size_int (gs_info.scale);
align = get_object_alignment (DR_REF (first_dr_info->dr));
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 917fa87..82001ef 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -52,6 +52,12 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-fold.h"
#include "tree-dfa.h"
#include "tree-ssa-dce.h"
+#include "alloc-pool.h"
+#include "cgraph.h"
+#include "symbol-summary.h"
+#include "ipa-utils.h"
+#include "ipa-prop.h"
+#include "attribs.h"
// This class is utilized by VRP and ranger to remove __builtin_unreachable
// calls, and reflect any resulting global ranges.
@@ -1081,6 +1087,51 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p,
array_checker.check ();
}
+
+ if (Value_Range::supports_type_p (TREE_TYPE
+ (TREE_TYPE (current_function_decl)))
+ && flag_ipa_vrp
+ && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl)))
+ {
+ edge e;
+ edge_iterator ei;
+ bool found = false;
+ Value_Range return_range (TREE_TYPE (TREE_TYPE (current_function_decl)));
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
+ if (greturn *ret = dyn_cast <greturn *> (*gsi_last_bb (e->src)))
+ {
+ tree retval = gimple_return_retval (ret);
+ if (!retval)
+ {
+ return_range.set_varying (TREE_TYPE (TREE_TYPE (current_function_decl)));
+ found = true;
+ continue;
+ }
+ Value_Range r (TREE_TYPE (retval));
+ if (ranger->range_of_expr (r, retval, ret)
+ && !r.undefined_p ()
+ && !r.varying_p ())
+ {
+ if (!found)
+ return_range = r;
+ else
+ return_range.union_ (r);
+ }
+ else
+ return_range.set_varying (TREE_TYPE (retval));
+ found = true;
+ }
+ if (found && !return_range.varying_p ())
+ {
+ ipa_record_return_value_range (return_range);
+ if (POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
+ && return_range.nonzero_p ()
+ && cgraph_node::get (current_function_decl)
+ ->add_detected_attribute ("returns_nonnull"))
+ warn_function_returns_nonnull (current_function_decl);
+ }
+ }
+
phi_analysis_finalize ();
disable_ranger (fun);
scev_finalize ();
diff --git a/gcc/tree.cc b/gcc/tree.cc
index a3d907a..e9f703e 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -12573,6 +12573,24 @@ try_catch_may_fallthru (const_tree stmt)
if (block_may_fallthru (TREE_OPERAND (stmt, 0)))
return true;
+ switch (TREE_CODE (TREE_OPERAND (stmt, 1)))
+ {
+ case CATCH_EXPR:
+ /* See below. */
+ return block_may_fallthru (CATCH_BODY (TREE_OPERAND (stmt, 1)));
+
+ case EH_FILTER_EXPR:
+ /* See below. */
+ return block_may_fallthru (EH_FILTER_FAILURE (TREE_OPERAND (stmt, 1)));
+
+ case STATEMENT_LIST:
+ break;
+
+ default:
+ /* See below. */
+ return false;
+ }
+
i = tsi_start (TREE_OPERAND (stmt, 1));
switch (TREE_CODE (tsi_stmt (i)))
{
diff --git a/gcc/typeclass.h b/gcc/typeclass.h
index 4b162e1..2723c65 100644
--- a/gcc/typeclass.h
+++ b/gcc/typeclass.h
@@ -38,7 +38,7 @@ enum type_class
record_type_class, union_type_class,
array_type_class, string_type_class,
lang_type_class, opaque_type_class,
- bitint_type_class
+ bitint_type_class, vector_type_class
};
#endif /* GCC_TYPECLASS_H */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 5247b80..d0ba0f6 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,29 @@
+2023-11-24 Alexander Monakov <amonakov@ispras.ru>
+
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac (ENABLE_VALGRIND_CHECKING): Delete.
+ (ENABLE_VALGRIND_ANNOTATIONS): Rename to
+ ENABLE_VALGRIND_WORKAROUNDS. Delete Valgrind header checks.
+ * lex.cc (new_buff): Adjust for renaming.
+ (_cpp_free_buff): Ditto.
+
+2023-11-20 Marc Poulhiès <dkm@kataplop.net>
+
+ * macro.cc (parse_params): Fix typo in variadic.
+ (create_iso_definition): Likewise.
+
+2023-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (TAGS_SOURCES): Add "include/rich-location.h".
+ * include/cpplib.h (class rich_location): New forward decl.
+ * include/line-map.h (class range_label)
+ (enum range_display_kind, struct location_range)
+ (class semi_embedded_vec, class rich_location, class label_text)
+ (class range_label, class fixit_hint): Move to...
+ * include/rich-location.h: ...this new file.
+ * internal.h: Include "rich-location.h".
+
2023-11-14 Jakub Jelinek <jakub@redhat.com>
* makeucnid.cc (write_copyright): Update copyright year.
diff --git a/libcpp/config.in b/libcpp/config.in
index df4fd44..253ef03 100644
--- a/libcpp/config.in
+++ b/libcpp/config.in
@@ -24,12 +24,9 @@
language is requested. */
#undef ENABLE_NLS
-/* Define to get calls to the valgrind runtime enabled. */
-#undef ENABLE_VALGRIND_ANNOTATIONS
-
-/* Define if you want to workaround valgrind (a memory checker) warnings about
- possible memory leaks because of libcpp use of interior pointers. */
-#undef ENABLE_VALGRIND_CHECKING
+/* Define if you want to workaround Valgrind warnings about possible memory
+ leaks because of libcpp use of interior pointers. */
+#undef ENABLE_VALGRIND_WORKAROUNDS
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
@@ -201,9 +198,6 @@
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
-/* Define if valgrind's memcheck.h header is installed. */
-#undef HAVE_MEMCHECK_H
-
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -252,9 +246,6 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
-/* Define if valgrind's valgrind/memcheck.h header is installed. */
-#undef HAVE_VALGRIND_MEMCHECK_H
-
/* Define as const if the declaration of iconv() needs const. */
#undef ICONV_CONST
diff --git a/libcpp/configure b/libcpp/configure
index 452e4c1..8a38c05 100755
--- a/libcpp/configure
+++ b/libcpp/configure
@@ -9116,12 +9116,6 @@ $as_echo "#define ENABLE_ASSERT_CHECKING 1" >>confdefs.h
fi
-if test x$ac_valgrind_checking != x ; then
-
-$as_echo "#define ENABLE_VALGRIND_CHECKING 1" >>confdefs.h
-
-fi
-
# Check whether --enable-canonical-system-headers was given.
if test "${enable_canonical_system_headers+set}" = set; then :
enableval=$enable_canonical_system_headers;
@@ -9405,62 +9399,6 @@ case x$enable_languages in
esac
-ac_fn_c_check_header_mongrel "$LINENO" "valgrind.h" "ac_cv_header_valgrind_h" "$ac_includes_default"
-if test "x$ac_cv_header_valgrind_h" = xyes; then :
- have_valgrind_h=yes
-else
- have_valgrind_h=no
-fi
-
-
-
-# It is certainly possible that there's valgrind but no valgrind.h.
-# GCC relies on making annotations so we must have both.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <valgrind/memcheck.h>" >&5
-$as_echo_n "checking for VALGRIND_DISCARD in <valgrind/memcheck.h>... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <valgrind/memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- gcc_cv_header_valgrind_memcheck_h=yes
-else
- gcc_cv_header_valgrind_memcheck_h=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_valgrind_memcheck_h" >&5
-$as_echo "$gcc_cv_header_valgrind_memcheck_h" >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <memcheck.h>" >&5
-$as_echo_n "checking for VALGRIND_DISCARD in <memcheck.h>... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- gcc_cv_header_memcheck_h=yes
-else
- gcc_cv_header_memcheck_h=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_memcheck_h" >&5
-$as_echo "$gcc_cv_header_memcheck_h" >&6; }
-if test $gcc_cv_header_valgrind_memcheck_h = yes; then
-
-$as_echo "#define HAVE_VALGRIND_MEMCHECK_H 1" >>confdefs.h
-
-fi
-if test $gcc_cv_header_memcheck_h = yes; then
-
-$as_echo "#define HAVE_MEMCHECK_H 1" >>confdefs.h
-
-fi
-
# Check whether --enable-valgrind-annotations was given.
if test "${enable_valgrind_annotations+set}" = set; then :
enableval=$enable_valgrind_annotations;
@@ -9470,14 +9408,8 @@ fi
if test x$enable_valgrind_annotations != xno \
|| test x$ac_valgrind_checking != x; then
- if (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- as_fn_error $? "*** valgrind annotations requested, but" "$LINENO" 5
- as_fn_error $? "*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5
- fi
-$as_echo "#define ENABLE_VALGRIND_ANNOTATIONS 1" >>confdefs.h
+$as_echo "#define ENABLE_VALGRIND_WORKAROUNDS 1" >>confdefs.h
fi
diff --git a/libcpp/configure.ac b/libcpp/configure.ac
index b29b4d6..b883fec 100644
--- a/libcpp/configure.ac
+++ b/libcpp/configure.ac
@@ -185,12 +185,6 @@ if test x$ac_assert_checking != x ; then
[Define if you want assertions enabled. This is a cheap check.])
fi
-if test x$ac_valgrind_checking != x ; then
- AC_DEFINE(ENABLE_VALGRIND_CHECKING, 1,
-[Define if you want to workaround valgrind (a memory checker) warnings about
- possible memory leaks because of libcpp use of interior pointers.])
-fi
-
AC_ARG_ENABLE(canonical-system-headers,
[ --enable-canonical-system-headers
enable or disable system headers canonicalization],
@@ -241,54 +235,15 @@ case x$enable_languages in
esac
AC_SUBST(CET_HOST_FLAGS)
-dnl # This check AC_REQUIREs various stuff, so it *must not* be inside
-dnl # an if statement. This was the source of very frustrating bugs
-dnl # in converting to autoconf 2.5x!
-AC_CHECK_HEADER(valgrind.h, have_valgrind_h=yes, have_valgrind_h=no)
-
-# It is certainly possible that there's valgrind but no valgrind.h.
-# GCC relies on making annotations so we must have both.
-AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
-AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <valgrind/memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif]])],
- [gcc_cv_header_valgrind_memcheck_h=yes],
- [gcc_cv_header_valgrind_memcheck_h=no])
-AC_MSG_RESULT($gcc_cv_header_valgrind_memcheck_h)
-AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
-AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif]])],
- [gcc_cv_header_memcheck_h=yes],
- [gcc_cv_header_memcheck_h=no])
-AC_MSG_RESULT($gcc_cv_header_memcheck_h)
-if test $gcc_cv_header_valgrind_memcheck_h = yes; then
- AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
- [Define if valgrind's valgrind/memcheck.h header is installed.])
-fi
-if test $gcc_cv_header_memcheck_h = yes; then
- AC_DEFINE(HAVE_MEMCHECK_H, 1,
- [Define if valgrind's memcheck.h header is installed.])
-fi
-
AC_ARG_ENABLE(valgrind-annotations,
[AS_HELP_STRING([--enable-valgrind-annotations],
[enable valgrind runtime interaction])], [],
[enable_valgrind_annotations=no])
if test x$enable_valgrind_annotations != xno \
|| test x$ac_valgrind_checking != x; then
- if (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- AC_MSG_ERROR([*** valgrind annotations requested, but])
- AC_MSG_ERROR([*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h])
- fi
- AC_DEFINE(ENABLE_VALGRIND_ANNOTATIONS, 1,
-[Define to get calls to the valgrind runtime enabled.])
+ AC_DEFINE(ENABLE_VALGRIND_WORKAROUNDS, 1,
+[Define if you want to workaround Valgrind warnings about
+ possible memory leaks because of libcpp use of interior pointers.])
fi
# Output.
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index bc7eed7..f52bc44 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -764,6 +764,9 @@ struct cpp_callbacks
/* Callback to determine whether a built-in function is recognized. */
int (*has_builtin) (cpp_reader *);
+ /* Callback to determine whether a feature is available. */
+ int (*has_feature) (cpp_reader *, bool);
+
/* Callback that can change a user lazy into normal macro. */
void (*user_lazy_macro) (cpp_reader *, cpp_macro *, unsigned);
@@ -968,7 +971,9 @@ enum cpp_builtin_type
BT_HAS_STD_ATTRIBUTE, /* `__has_c_attribute(x)' */
BT_HAS_BUILTIN, /* `__has_builtin(x)' */
BT_HAS_INCLUDE, /* `__has_include(x)' */
- BT_HAS_INCLUDE_NEXT /* `__has_include_next(x)' */
+ BT_HAS_INCLUDE_NEXT, /* `__has_include_next(x)' */
+ BT_HAS_FEATURE, /* `__has_feature(x)' */
+ BT_HAS_EXTENSION /* `__has_extension(x)' */
};
#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE))
diff --git a/libcpp/init.cc b/libcpp/init.cc
index 250a02a..5dfce4b 100644
--- a/libcpp/init.cc
+++ b/libcpp/init.cc
@@ -435,6 +435,8 @@ static const struct builtin_macro builtin_array[] =
B("__has_builtin", BT_HAS_BUILTIN, true),
B("__has_include", BT_HAS_INCLUDE, true),
B("__has_include_next",BT_HAS_INCLUDE_NEXT, true),
+ B("__has_feature", BT_HAS_FEATURE, true),
+ B("__has_extension", BT_HAS_EXTENSION, true),
/* Keep builtins not used for -traditional-cpp at the end, and
update init_builtins() if any more are added. */
B("_Pragma", BT_PRAGMA, true),
diff --git a/libcpp/lex.cc b/libcpp/lex.cc
index 0b1b936..a5d2f31 100644
--- a/libcpp/lex.cc
+++ b/libcpp/lex.cc
@@ -4762,7 +4762,7 @@ new_buff (size_t len)
len = MIN_BUFF_SIZE;
len = CPP_ALIGN (len);
-#ifdef ENABLE_VALGRIND_ANNOTATIONS
+#ifdef ENABLE_VALGRIND_WORKAROUNDS
/* Valgrind warns about uses of interior pointers, so put _cpp_buff
struct first. */
size_t slen = CPP_ALIGN2 (sizeof (_cpp_buff), 2 * DEFAULT_ALIGNMENT);
@@ -4859,7 +4859,7 @@ _cpp_free_buff (_cpp_buff *buff)
for (; buff; buff = next)
{
next = buff->next;
-#ifdef ENABLE_VALGRIND_ANNOTATIONS
+#ifdef ENABLE_VALGRIND_WORKAROUNDS
free (buff);
#else
free (buff->base);
diff --git a/libcpp/macro.cc b/libcpp/macro.cc
index a1a134a..6f24a9d 100644
--- a/libcpp/macro.cc
+++ b/libcpp/macro.cc
@@ -677,6 +677,12 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
number = builtin_has_include (pfile, node,
node->value.builtin == BT_HAS_INCLUDE_NEXT);
break;
+
+ case BT_HAS_FEATURE:
+ case BT_HAS_EXTENSION:
+ number = pfile->cb.has_feature (pfile,
+ node->value.builtin == BT_HAS_FEATURE);
+ break;
}
if (result == NULL)
@@ -3431,7 +3437,7 @@ _cpp_unsave_parameters (cpp_reader *pfile, unsigned n)
*/
static bool
-parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr)
+parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *variadic_ptr)
{
unsigned nparms = 0;
bool ok = false;
@@ -3462,7 +3468,7 @@ parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr)
};
unsigned ix = prev_ident;
const unsigned char *as_text = NULL;
- if (*varadic_ptr)
+ if (*variadic_ptr)
ix = 4;
else if (token->type == CPP_EOF)
ix += 2;
@@ -3473,7 +3479,7 @@ parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr)
goto out;
case CPP_NAME:
- if (prev_ident || *varadic_ptr)
+ if (prev_ident || *variadic_ptr)
goto bad;
prev_ident = true;
@@ -3484,7 +3490,7 @@ parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr)
break;
case CPP_CLOSE_PAREN:
- if (prev_ident || !nparms || *varadic_ptr)
+ if (prev_ident || !nparms || *variadic_ptr)
{
ok = true;
goto out;
@@ -3492,15 +3498,15 @@ parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr)
/* FALLTHRU */
case CPP_COMMA:
- if (!prev_ident || *varadic_ptr)
+ if (!prev_ident || *variadic_ptr)
goto bad;
prev_ident = false;
break;
case CPP_ELLIPSIS:
- if (*varadic_ptr)
+ if (*variadic_ptr)
goto bad;
- *varadic_ptr = true;
+ *variadic_ptr = true;
if (!prev_ident)
{
/* An ISO bare ellipsis. */
@@ -3577,7 +3583,7 @@ create_iso_definition (cpp_reader *pfile)
unsigned int num_extra_tokens = 0;
unsigned nparms = 0;
cpp_hashnode **params = NULL;
- bool varadic = false;
+ bool variadic = false;
bool ok = false;
cpp_macro *macro = NULL;
@@ -3594,7 +3600,7 @@ create_iso_definition (cpp_reader *pfile)
else if (token->type == CPP_OPEN_PAREN)
{
/* An open-paren, get a parameter list. */
- if (!parse_params (pfile, &nparms, &varadic))
+ if (!parse_params (pfile, &nparms, &variadic))
goto out;
params = (cpp_hashnode **)_cpp_commit_buff
@@ -3645,7 +3651,7 @@ create_iso_definition (cpp_reader *pfile)
if (!token)
{
- macro->variadic = varadic;
+ macro->variadic = variadic;
macro->paramc = nparms;
macro->parm.params = params;
macro->fun_like = true;
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index fdeb85f..d47e28e 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,23 @@
+2023-11-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * config.host (arm*-*-eabi* | arm*-*-rtems*):
+ Add arm/t-sync to the makefile rules.
+ * config/arm/lib1funcs.S (__sync_synchronize_none)
+ (__sync_synchronize_cp15dmb, __sync_synchronize_dmb)
+ (__sync_synchronize): New functions.
+ * config/arm/t-sync: New file.
+ * config/arm/sync-none.specs: Likewise.
+ * config/arm/sync-dmb.specs: Likewise.
+ * config/arm/sync-cp15dmb.specs: Likewise.
+
+2023-11-23 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * hardcfr.c (__hardcfr_check_fail): Mark as always_inline.
+
+2023-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ * libgcov.h (GCOV_SUPPORTS_ATOMIC): Formatting fixes.
+
2023-11-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
* libgcov.h (GCOV_SUPPORTS_ATOMIC): Always define it.
diff --git a/libgcc/config.host b/libgcc/config.host
index 6afe8e5..694e3e9 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -554,7 +554,7 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
tm_file="$tm_file arm/bpabi-lib.h"
case ${host} in
arm*-*-eabi* | arm*-*-rtems*)
- tmake_file="${tmake_file} arm/t-bpabi t-crtfm"
+ tmake_file="${tmake_file} arm/t-bpabi arm/t-sync t-crtfm"
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
;;
arm*-*-symbianelf*)
diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
index d02a57c..7888786 100644
--- a/libgcc/config/arm/lib1funcs.S
+++ b/libgcc/config/arm/lib1funcs.S
@@ -2147,6 +2147,78 @@ LSYM(Lchange_\register):
SIZE (__gnu_thumb1_case_uhi)
#endif
+#ifdef L_sync_none
+ /* Null implementation of __sync_synchronize, for use when
+ it is known that the system is single threaded. */
+ .text
+ .align 0
+ FUNC_START sync_synchronize_none
+ bx lr
+ FUNC_END sync_synchronize_none
+#endif
+
+#ifdef L_sync_dmb
+ /* Full memory barrier using DMB. Requires Armv7 (all profiles)
+ or armv6-m, or later. */
+ .text
+ .align 0
+#if __ARM_ARCH_PROFILE == 'M'
+ .arch armv6-m
+#else
+ .arch armv7-a
+#endif
+ FUNC_START sync_synchronize_dmb
+ /* M-profile devices only support SY as the synchronization level,
+ but that's probably what we want here anyway. */
+ dmb
+ RET
+ FUNC_END sync_synchronize_dmb
+#endif
+
+#ifdef L_sync_cp15dmb
+#ifndef NOT_ISA_TARGET_32BIT
+ /* Implementation of DMB using CP15 operations. This was first
+ defined in Armv6, but deprecated in Armv7 and can give
+ sub-optimal performance. */
+ .text
+ .align 0
+ ARM_FUNC_START sync_synchronize_cp15dmb
+ mcr p15, 0, r0, c7, c10, 5
+ RET
+ FUNC_END sync_synchronize_cp15dmb
+#endif
+#endif
+
+#ifdef L_sync_synchronize
+ /* Generic version of the synchronization primitive. If we know
+ that DMB exists, then use it. Otherwise, arrange for a link
+ time warning explaining how to pick a suitable alternative.
+ We choose not to use CP15DMB because it is performance
+ deprecated. We only define this function if generating
+ ELF binaries as otherwise we can't rely on the warning being
+ generated. */
+
+#ifdef __ELF__
+ .text
+ .align 0
+ FUNC_START sync_synchronize
+#if __ARM_ARCH >= 7 || __ARM_ARCH_PROFILE == 'M'
+ dmb
+#endif
+ RET
+ FUNC_END sync_synchronize
+#if !(__ARM_ARCH >= 7 || __ARM_ARCH_PROFILE == 'M')
+ .section .gnu.warning.__sync_synchronize
+ .align 0
+ .ascii "This implementation of __sync_synchronize is a stub with "
+ .ascii "no effect. Relink with\n"
+ .ascii " -specs=sync-{none,dmb,cp15dmb}.specs\n"
+ .ascii "to specify exactly which barrier format to use and avoid "
+ .ascii "this warning.\n\0"
+#endif
+#endif
+#endif
+
#ifdef L_thumb1_case_si
.text
diff --git a/libgcc/config/arm/sync-cp15dmb.specs b/libgcc/config/arm/sync-cp15dmb.specs
new file mode 100644
index 0000000..0bb64b9
--- /dev/null
+++ b/libgcc/config/arm/sync-cp15dmb.specs
@@ -0,0 +1,4 @@
+%rename link sync_sync_link
+
+*link:
+--defsym=__sync_synchronize=__sync_synchronize_cp15dmb %(sync_sync_link)
diff --git a/libgcc/config/arm/sync-dmb.specs b/libgcc/config/arm/sync-dmb.specs
new file mode 100644
index 0000000..13e59bd
--- /dev/null
+++ b/libgcc/config/arm/sync-dmb.specs
@@ -0,0 +1,4 @@
+%rename link sync_sync_link
+
+*link:
+--defsym=__sync_synchronize=__sync_synchronize_dmb %(sync_sync_link)
diff --git a/libgcc/config/arm/sync-none.specs b/libgcc/config/arm/sync-none.specs
new file mode 100644
index 0000000..0aa4960
--- /dev/null
+++ b/libgcc/config/arm/sync-none.specs
@@ -0,0 +1,4 @@
+%rename link sync_sync_link
+
+*link:
+--defsym=__sync_synchronize=__sync_synchronize_none %(sync_sync_link)
diff --git a/libgcc/config/arm/t-sync b/libgcc/config/arm/t-sync
new file mode 100644
index 0000000..5fd050e
--- /dev/null
+++ b/libgcc/config/arm/t-sync
@@ -0,0 +1,13 @@
+LIB1ASMFUNCS += _sync_none _sync_dmb _sync_cp15dmb _sync_synchronize
+
+EXTRA_PARTS += sync-none.specs sync-dmb.specs sync-cp15dmb.specs
+
+sync-none.specs: $(srcdir)/config/arm/sync-none.specs
+ cp $< .
+
+sync-dmb.specs: $(srcdir)/config/arm/sync-dmb.specs
+ cp $< .
+
+sync-cp15dmb.specs: $(srcdir)/config/arm/sync-cp15dmb.specs
+ cp $< .
+
diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 25ff067..376a362 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -206,6 +206,10 @@ __hardcfr_debug_cfg (size_t const blocks,
enabled, it also forces __hardcfr_debug_cfg (above) to be compiled into an
out-of-line function, that could be called from a debugger.
*/
+
+#ifdef __BPF__
+__attribute__((__always_inline__))
+#endif
static inline void
__hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
vword const *const visited ATTRIBUTE_UNUSED,
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index d04c070..f5959a8 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -96,9 +96,9 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
#endif
/* Detect whether target can support atomic update of profilers. */
-#if (__SIZEOF_LONG_LONG__ == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || \
- (__SIZEOF_LONG_LONG__ == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || \
- defined (__LIBGCC_HAVE_LIBATOMIC)
+#if (__SIZEOF_LONG_LONG__ == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) \
+ || (__SIZEOF_LONG_LONG__ == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) \
+ || defined (__LIBGCC_HAVE_LIBATOMIC)
#define GCOV_SUPPORTS_ATOMIC 1
#else
#define GCOV_SUPPORTS_ATOMIC 0
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 8d2b812..d5a6ade 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,15 @@
+2023-11-24 Tobias Burnus <tobias@codesourcery.com>
+
+ * libgomp.texi (5.2 Impl. Status): An argument to the destroy clause
+ is now supported.
+
+2023-11-22 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.c/declare-variant-3.h (f30, f35, f53, f70)
+ (f75, f80, f): Add '__attribute__ ((noipa))'.
+ * testsuite/libgomp.c/declare-variant-4.h (gfx803, gfx900, gfx906)
+ (gfx908, gfx90a, f): Likewise.
+
2023-11-15 Andrew Stubbs <ams@codesourcery.com>
Andrew Jenner <andrew@codesourcery.com>
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 2f6227c..e5fe7af 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -387,7 +387,7 @@ to address of matching mapped list item per 5.1, Sect. 2.21.7.2 @tab N @tab
@code{-Wall}). Unknown clauses are always rejected with an error.}
@item Clauses on @code{end} directive can be on directive @tab Y @tab
@item @code{destroy} clause with destroy-var argument on @code{depobj}
- @tab N @tab
+ @tab Y @tab
@item Deprecation of no-argument @code{destroy} clause on @code{depobj}
@tab N @tab
@item @code{linear} clause syntax changes and @code{step} modifier @tab Y @tab
diff --git a/libgomp/testsuite/libgomp.c/declare-variant-3.h b/libgomp/testsuite/libgomp.c/declare-variant-3.h
index 772fc20..646e15e 100644
--- a/libgomp/testsuite/libgomp.c/declare-variant-3.h
+++ b/libgomp/testsuite/libgomp.c/declare-variant-3.h
@@ -1,34 +1,41 @@
#pragma omp declare target
+
+__attribute__ ((noipa))
int
f30 (void)
{
return 30;
}
+__attribute__ ((noipa))
int
f35 (void)
{
return 35;
}
+__attribute__ ((noipa))
int
f53 (void)
{
return 53;
}
+__attribute__ ((noipa))
int
f70 (void)
{
return 70;
}
+__attribute__ ((noipa))
int
f75 (void)
{
return 75;
}
+__attribute__ ((noipa))
int
f80 (void)
{
@@ -41,6 +48,7 @@ f80 (void)
#pragma omp declare variant (f70) match (device={isa("sm_70")})
#pragma omp declare variant (f75) match (device={isa("sm_75")})
#pragma omp declare variant (f80) match (device={isa("sm_80")})
+__attribute__ ((noipa))
int
f (void)
{
diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4.h b/libgomp/testsuite/libgomp.c/declare-variant-4.h
index 2d7c1ef..47517b7 100644
--- a/libgomp/testsuite/libgomp.c/declare-variant-4.h
+++ b/libgomp/testsuite/libgomp.c/declare-variant-4.h
@@ -1,28 +1,34 @@
#pragma omp declare target
+
+__attribute__ ((noipa))
int
gfx803 (void)
{
return 0x803;
}
+__attribute__ ((noipa))
int
gfx900 (void)
{
return 0x900;
}
+__attribute__ ((noipa))
int
gfx906 (void)
{
return 0x906;
}
+__attribute__ ((noipa))
int
gfx908 (void)
{
return 0x908;
}
+__attribute__ ((noipa))
int
gfx90a (void)
{
@@ -38,6 +44,7 @@ gfx90a (void)
#pragma omp declare variant(gfx906) match(device = {isa("gfx906")})
#pragma omp declare variant(gfx908) match(device = {isa("gfx908")})
#pragma omp declare variant(gfx90a) match(device = {isa("gfx90a")})
+__attribute__ ((noipa))
int
f (void)
{
diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog
index b28b9f4..6f437e4 100644
--- a/libphobos/ChangeLog
+++ b/libphobos/ChangeLog
@@ -1,3 +1,12 @@
+2023-11-21 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/MERGE: Merge upstream druntime ff57fec515.
+ * src/MERGE: Merge upstream phobos 17bafda79.
+
+2023-11-21 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * src/MERGE: Merge upstream phobos fc06c514a.
+
2023-11-02 Iain Buclaw <ibuclaw@gdcproject.org>
* libdruntime/MERGE: Merge upstream druntime 643b1261bb.
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 235db4b..aa0062c 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-643b1261bba0757d97efa3ff1f63e461271eb000
+ff57fec51558013b25cadb7e83da9f4675915d56
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/core/cpuid.d b/libphobos/libdruntime/core/cpuid.d
index b79bd1d..9c57357 100644
--- a/libphobos/libdruntime/core/cpuid.d
+++ b/libphobos/libdruntime/core/cpuid.d
@@ -666,10 +666,12 @@ void getAMDcacheinfo()
// to determine number of processors.
void getCpuInfo0B()
{
- int level=0;
int threadsPerCore;
uint a, b, c, d;
- do {
+ // I'm not sure about this. The docs state that there
+ // are 2 hyperthreads per core if HT is factory enabled.
+ for (int level = 0; level < 2; level++)
+ {
version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (0x0B), "c" (level);
} else asm pure nothrow @nogc {
@@ -681,19 +683,20 @@ void getCpuInfo0B()
mov c, ECX;
mov d, EDX;
}
- if (b!=0) {
- // I'm not sure about this. The docs state that there
- // are 2 hyperthreads per core if HT is factory enabled.
- if (level==0)
+ if (b != 0)
+ {
+ if (level == 0)
threadsPerCore = b & 0xFFFF;
- else if (level==1) {
+ else if (level == 1)
+ {
cpuFeatures.maxThreads = b & 0xFFFF;
cpuFeatures.maxCores = cpuFeatures.maxThreads / threadsPerCore;
}
-
}
- ++level;
- } while (a!=0 || b!=0);
+ // Got "invalid domain" returned from cpuid
+ if (a == 0 && b == 0)
+ break;
+ }
}
void cpuidX86()
diff --git a/libphobos/libdruntime/core/internal/array/appending.d b/libphobos/libdruntime/core/internal/array/appending.d
index bb24813..ba34727 100644
--- a/libphobos/libdruntime/core/internal/array/appending.d
+++ b/libphobos/libdruntime/core/internal/array/appending.d
@@ -14,56 +14,55 @@ private extern (C) byte[] _d_arrayappendcTX(const TypeInfo ti, ref return scope
private enum isCopyingNothrow(T) = __traits(compiles, (ref T rhs) nothrow { T lhs = rhs; });
-/// Implementation of `_d_arrayappendcTX` and `_d_arrayappendcTXTrace`
-template _d_arrayappendcTXImpl(Tarr : T[], T)
+/**
+ * Extend an array `px` by `n` elements.
+ * Caller must initialize those elements.
+ * Params:
+ * px = the array that will be extended, taken as a reference
+ * n = how many new elements to extend it with
+ * Returns:
+ * The new value of `px`
+ * Bugs:
+ * This function template was ported from a much older runtime hook that bypassed safety,
+ * purity, and throwabilty checks. To prevent breaking existing code, this function template
+ * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations.
+ */
+ref Tarr _d_arrayappendcTX(Tarr : T[], T)(return ref scope Tarr px, size_t n) @trusted
{
- private enum errorMessage = "Cannot append to array if compiling without support for runtime type information!";
+ // needed for CTFE: https://github.com/dlang/druntime/pull/3870#issuecomment-1178800718
+ version (DigitalMars) pragma(inline, false);
+ version (D_TypeInfo)
+ {
+ auto ti = typeid(Tarr);
+
+ // _d_arrayappendcTX takes the `px` as a ref byte[], but its length
+ // should still be the original length
+ auto pxx = (cast(byte*)px.ptr)[0 .. px.length];
+ ._d_arrayappendcTX(ti, pxx, n);
+ px = (cast(T*)pxx.ptr)[0 .. pxx.length];
+
+ return px;
+ }
+ else
+ assert(0, "Cannot append to array if compiling without support for runtime type information!");
+}
+version (D_ProfileGC)
+{
/**
- * Extend an array `px` by `n` elements.
- * Caller must initialize those elements.
- * Params:
- * px = the array that will be extended, taken as a reference
- * n = how many new elements to extend it with
- * Returns:
- * The new value of `px`
- * Bugs:
- * This function template was ported from a much older runtime hook that bypassed safety,
- * purity, and throwabilty checks. To prevent breaking existing code, this function template
- * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations.
+ * TraceGC wrapper around $(REF _d_arrayappendT, core,internal,array,appending).
*/
- ref Tarr _d_arrayappendcTX(return ref scope Tarr px, size_t n) @trusted pure nothrow
+ ref Tarr _d_arrayappendcTXTrace(Tarr : T[], T)(string file, int line, string funcname, return ref scope Tarr px, size_t n) @trusted
{
- // needed for CTFE: https://github.com/dlang/druntime/pull/3870#issuecomment-1178800718
- version (DigitalMars) pragma(inline, false);
version (D_TypeInfo)
{
- auto ti = typeid(Tarr);
-
- // _d_arrayappendcTX takes the `px` as a ref byte[], but its length
- // should still be the original length
- auto pxx = (cast(byte*)px.ptr)[0 .. px.length];
- ._d_arrayappendcTX(ti, pxx, n);
- px = (cast(T*)pxx.ptr)[0 .. pxx.length];
+ import core.internal.array.utils: TraceHook, gcStatsPure, accumulatePure;
+ mixin(TraceHook!(Tarr.stringof, "_d_arrayappendcTX"));
- return px;
+ return _d_arrayappendcTX(px, n);
}
else
- assert(0, errorMessage);
- }
-
- version (D_ProfileGC)
- {
- import core.internal.array.utils : _d_HookTraceImpl;
-
- /**
- * TraceGC wrapper around $(REF _d_arrayappendcTX, rt,array,appending,_d_arrayappendcTXImpl).
- * Bugs:
- * This function template was ported from a much older runtime hook that bypassed safety,
- * purity, and throwabilty checks. To prevent breaking existing code, this function template
- * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations.
- */
- alias _d_arrayappendcTXTrace = _d_HookTraceImpl!(Tarr, _d_arrayappendcTX, errorMessage);
+ static assert(0, "Cannot append to array if compiling without support for runtime type information!");
}
}
@@ -78,7 +77,7 @@ ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @
enum hasPostblit = __traits(hasPostblit, T);
auto length = x.length;
- _d_arrayappendcTXImpl!Tarr._d_arrayappendcTX(x, y.length);
+ _d_arrayappendcTX(x, y.length);
// Only call `copyEmplace` if `T` has a copy ctor and no postblit.
static if (hasElaborateCopyConstructor!T && !hasPostblit)
@@ -126,7 +125,7 @@ version (D_ProfileGC)
return _d_arrayappendT(x, y);
}
else
- assert(0, "Cannot append to array if compiling without support for runtime type information!");
+ static assert(0, "Cannot append to array if compiling without support for runtime type information!");
}
}
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index 54f8767..655acc8 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -486,3 +486,111 @@ version (D_ProfileGC)
assert(0, "Cannot create new array if compiling without support for runtime type information!");
}
}
+
+/**
+ * Create a new multi-dimensional array. Also initalize elements if their type has an initializer.
+ * Otherwise, not zero-initialize the array.
+ *
+ * ---
+ * void main()
+ * {
+ * S[][] s = new S[][](2, 3)
+ *
+ * // lowering:
+ * S[] s = _d_newarraymTX!(S[][], S)([2, 3]);
+ * }
+ * ---
+ *
+ * Params:
+ * dims = array length values for each dimension
+ * isShared = whether the array should be shared
+ *
+ * Returns:
+ * newly allocated array
+ */
+Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trusted
+{
+ debug(PRINTF) printf("_d_newarraymTX(dims.length = %d)\n", dims.length);
+
+ if (dims.length == 0)
+ return null;
+
+ alias UnqT = Unqual!(T);
+
+ void[] __allocateInnerArray(size_t[] dims)
+ {
+ import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
+
+ auto dim = dims[0];
+
+ debug(PRINTF) printf("__allocateInnerArray(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, dims.length);
+ if (dims.length == 1)
+ {
+ auto r = _d_newarrayT!UnqT(dim, isShared);
+ return *cast(void[]*)(&r);
+ }
+
+ auto allocSize = (void[]).sizeof * dim;
+ auto info = __arrayAlloc!UnqT(allocSize);
+ __setArrayAllocLength!UnqT(info, allocSize, isShared);
+ auto p = __arrayStart(info)[0 .. dim];
+
+ foreach (i; 0..dim)
+ {
+ (cast(void[]*)p.ptr)[i] = __allocateInnerArray(dims[1..$]);
+ }
+ return p;
+ }
+
+ auto result = __allocateInnerArray(dims);
+ debug(PRINTF) printf("result = %llx\n", result.ptr);
+
+ return (cast(U*) result.ptr)[0 .. dims[0]];
+}
+
+unittest
+{
+ int[][] a = _d_newarraymTX!(int[][], int)([2, 3]);
+
+ assert(a.length == 2);
+ for (size_t i = 0; i < a.length; i++)
+ {
+ assert(a[i].length == 3);
+ for (size_t j = 0; j < a[i].length; j++)
+ assert(a[i][j] == 0);
+ }
+}
+
+unittest
+{
+ struct S { int x = 1; }
+
+ S[][] a = _d_newarraymTX!(S[][], S)([2, 3]);
+
+ assert(a.length == 2);
+ for (size_t i = 0; i < a.length; i++)
+ {
+ assert(a[i].length == 3);
+ for (size_t j = 0; j < a[i].length; j++)
+ assert(a[i][j].x == 1);
+ }
+}
+
+version (D_ProfileGC)
+{
+ /**
+ * TraceGC wrapper around $(REF _d_newarraymT, core,internal,array,construction).
+ */
+ Tarr _d_newarraymTXTrace(Tarr : U[], T, U)(string file, int line, string funcname, size_t[] dims, bool isShared=false) @trusted
+ {
+ version (D_TypeInfo)
+ {
+ import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
+ mixin(TraceHook!(T.stringof, "_d_newarraymTX"));
+
+ return _d_newarraymTX!(Tarr, T)(dims, isShared);
+ }
+ else
+ assert(0, "Cannot create new multi-dimensional array if compiling without support for runtime type information!");
+ }
+}
diff --git a/libphobos/libdruntime/core/internal/atomic.d b/libphobos/libdruntime/core/internal/atomic.d
index 5daab89..eebf94e 100644
--- a/libphobos/libdruntime/core/internal/atomic.d
+++ b/libphobos/libdruntime/core/internal/atomic.d
@@ -656,7 +656,7 @@ version (DigitalMars)
asm pure nothrow @nogc @trusted
{
naked;
- rep; nop;
+ pause;
ret;
}
}
@@ -665,8 +665,7 @@ version (DigitalMars)
asm pure nothrow @nogc @trusted
{
naked;
- // pause; // TODO: DMD should add this opcode to its inline asm
- rep; nop;
+ pause;
ret;
}
}
diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
index 39cd30a..6f19412 100644
--- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
@@ -3336,7 +3336,7 @@ Lmark:
busyThreads.atomicOp!"+="(1); // main thread is busy
- evStart.set();
+ evStart.setIfInitialized();
debug(PARALLEL_PRINTF) printf("mark %lld roots\n", cast(ulong)(ptop - pbot));
@@ -3438,7 +3438,7 @@ Lmark:
stopGC = true;
while (atomicLoad(stoppedThreads) < startedThreads && !allThreadsDead)
{
- evStart.set();
+ evStart.setIfInitialized();
evDone.wait(dur!"msecs"(1));
}
@@ -3467,7 +3467,7 @@ Lmark:
{
evStart.wait();
pullFromScanStack();
- evDone.set();
+ evDone.setIfInitialized();
}
stoppedThreads.atomicOp!"+="(1);
}
diff --git a/libphobos/libdruntime/core/internal/newaa.d b/libphobos/libdruntime/core/internal/newaa.d
index 314f255..2fd9365 100644
--- a/libphobos/libdruntime/core/internal/newaa.d
+++ b/libphobos/libdruntime/core/internal/newaa.d
@@ -50,6 +50,7 @@ struct Impl
immutable uint valsz;
immutable uint valoff;
Flags flags;
+ size_t delegate(scope const void*) nothrow hashFn;
enum Flags : ubyte
{
@@ -76,15 +77,19 @@ private size_t mix(size_t h) @safe pure nothrow @nogc
struct Entry(K, V)
{
- /*const*/ K key; // this really should be const, but legacy issues.
+ // can make this const, because we aren't really going to use it aside from
+ // construction.
+ const K key;
V value;
}
// create a binary-compatible AA structure that can be used directly as an
// associative array.
-AAShell makeAA(K, V)(V[K] src)
+// NOTE: this must only be called during CTFE
+AAShell makeAA(K, V)(V[K] src) @trusted
{
+ assert(__ctfe, "makeAA Must only be called at compile time");
immutable srclen = src.length;
assert(srclen <= uint.max);
alias E = Entry!(K, V);
@@ -96,6 +101,12 @@ AAShell makeAA(K, V)(V[K] src)
while (srclen * GROW_DEN > dim * GROW_NUM)
dim = dim * GROW_FAC;
+ // used during runtime.
+ size_t delegate(scope const void *) nothrow hashFn = (scope const void* val) {
+ auto x = cast(K*)val;
+ return hashOf(*x);
+ };
+
Bucket[] buckets;
// Allocate and fill the buckets
if (__ctfe)
@@ -140,5 +151,19 @@ AAShell makeAA(K, V)(V[K] src)
} ();
// return the new implementation
return AAShell(new Impl(buckets, cast(uint)srclen, 0, typeid(E), firstUsed,
- K.sizeof, V.sizeof, E.value.offsetof, flags));
+ K.sizeof, V.sizeof, E.value.offsetof, flags, hashFn));
+}
+
+unittest
+{
+ static struct Foo
+ {
+ ubyte x;
+ double d;
+ }
+ static int[Foo] utaa = [Foo(1, 2.0) : 5];
+ auto k = Foo(1, 2.0);
+ // verify that getHash doesn't match hashOf for Foo
+ assert(typeid(Foo).getHash(&k) != hashOf(k));
+ assert(utaa[Foo(1, 2.0)] == 5);
}
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
index 288f9c2..0051ecd 100644
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -797,7 +797,7 @@ else
}
else version (LoongArch64)
{
- // Define bits representing exceptions in the FPSR status word.
+ // Define bits representing exceptions in the Flags field in FCSR{0,2}.
enum
{
FE_INEXACT = 0x010000, ///
@@ -808,13 +808,13 @@ else
FE_ALL_EXCEPT = 0x1f0000, ///
}
- // Define bits representing rounding modes in the FPCR Rmode field.
+ // Define bits representing rounding modes in the RM field in FCSR{0,3}.
enum
{
FE_TONEAREST = 0x000, ///
FE_TOWARDZERO = 0x100, ///
- FE_DOWNWARD = 0x200, ///
- FE_UPWARD = 0x300, ///
+ FE_UPWARD = 0x200, ///
+ FE_DOWNWARD = 0x300, ///
}
}
else
diff --git a/libphobos/libdruntime/core/stdc/stdarg.d b/libphobos/libdruntime/core/stdc/stdarg.d
index 5b79813..0ba1ebe 100644
--- a/libphobos/libdruntime/core/stdc/stdarg.d
+++ b/libphobos/libdruntime/core/stdc/stdarg.d
@@ -257,6 +257,12 @@ T va_arg(T)(ref va_list ap)
ap += T.sizeof.alignUp;
return *p;
}
+ else version (LoongArch64)
+ {
+ auto p = cast(T*) ap;
+ ap += T.sizeof.alignUp;
+ return *p;
+ }
else version (MIPS_Any)
{
auto p = cast(T*) ap;
diff --git a/libphobos/libdruntime/core/sync/event.d b/libphobos/libdruntime/core/sync/event.d
index 3795106..048607f 100644
--- a/libphobos/libdruntime/core/sync/event.d
+++ b/libphobos/libdruntime/core/sync/event.d
@@ -61,7 +61,7 @@ struct ProcessFile
group.create(&doProcess);
buffer = std.file.read(filename);
- event.set();
+ event.setIfInitialized();
group.joinAll();
event.terminate();
}
@@ -162,9 +162,13 @@ nothrow @nogc:
}
}
+ deprecated ("Use setIfInitialized() instead") void set()
+ {
+ setIfInitialized();
+ }
/// Set the event to "signaled", so that waiting clients are resumed
- void set()
+ void setIfInitialized()
{
version (Windows)
{
@@ -302,7 +306,7 @@ private:
// auto-reset, initial state false
Event ev1 = Event(false, false);
assert(!ev1.wait(1.dur!"msecs"));
- ev1.set();
+ ev1.setIfInitialized();
assert(ev1.wait());
assert(!ev1.wait(1.dur!"msecs"));
@@ -336,7 +340,7 @@ unittest
auto start = MonoTime.currTime;
assert(numRunning == 0);
- event.set();
+ event.setIfInitialized();
group.joinAll();
assert(numRunning == numThreads);
diff --git a/libphobos/libdruntime/core/sys/elf/package.d b/libphobos/libdruntime/core/sys/elf/package.d
index b120ee5..60e05d9 100644
--- a/libphobos/libdruntime/core/sys/elf/package.d
+++ b/libphobos/libdruntime/core/sys/elf/package.d
@@ -339,6 +339,8 @@ enum EM_CSKY = 252;
enum EM_NUM = 253;
+enum EM_LOONGARCH = 258;
+
enum EM_ALPHA = 0x9026;
enum EV_NONE = 0;
diff --git a/libphobos/libdruntime/core/sys/linux/sys/auxv.d b/libphobos/libdruntime/core/sys/linux/sys/auxv.d
index 5f098e9..1099fae 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/auxv.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/auxv.d
@@ -13,6 +13,7 @@ extern (C):
version (MIPS32) version = MIPS_Any;
version (MIPS64) version = MIPS_Any;
+version (LoongArch64) version = LoongArch_Any;
version (PPC) version = PPC_Any;
version (PPC64) version = PPC_Any;
version (S390) version = IBMZ_Any;
@@ -156,3 +157,19 @@ else version (IBMZ_Any)
enum HWCAP_S390_TE = 1024;
enum HWCAP_S390_VX = 2048;
}
+else version (LoongArch_Any)
+{
+ enum HWCAP_LOONGARCH_CPUCFG = 0x00000001;
+ enum HWCAP_LOONGARCH_LAM = 0x00000002;
+ enum HWCAP_LOONGARCH_UAL = 0x00000004;
+ enum HWCAP_LOONGARCH_FPU = 0x00000008;
+ enum HWCAP_LOONGARCH_LSX = 0x00000010;
+ enum HWCAP_LOONGARCH_LASX = 0x00000020;
+ enum HWCAP_LOONGARCH_CRC32 = 0x00000040;
+ enum HWCAP_LOONGARCH_COMPLEX = 0x00000080;
+ enum HWCAP_LOONGARCH_CRYPTO = 0x00000100;
+ enum HWCAP_LOONGARCH_LVZ = 0x00000200;
+ enum HWCAP_LOONGARCH_LBT_X86 = 0x00000400;
+ enum HWCAP_LOONGARCH_LBT_ARM = 0x00000800;
+ enum HWCAP_LOONGARCH_LBT_MIPS = 0x00001000;
+}
diff --git a/libphobos/libdruntime/core/sys/linux/sys/mman.d b/libphobos/libdruntime/core/sys/linux/sys/mman.d
index 7ed78ef..e4765af 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/mman.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/mman.d
@@ -432,6 +432,7 @@ else version (MIPS_Any)
MAP_HUGETLB = 0x80000,
}
}
+// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/bits/mman-map-flags-generic.h
else version (LoongArch64)
{
static if (_DEFAULT_SOURCE) enum
diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d
index 65878bc..8bbd6e1 100644
--- a/libphobos/libdruntime/core/thread/fiber.d
+++ b/libphobos/libdruntime/core/thread/fiber.d
@@ -178,8 +178,12 @@ private
}
else version (LoongArch64)
{
- version = AsmLoongArch64_Posix;
- version = AsmExternal;
+ version (Posix)
+ {
+ version = AsmLoongArch64_Posix;
+ version = AsmExternal;
+ version = AlignFiberStackTo16Byte;
+ }
}
version (Posix)
@@ -1444,24 +1448,28 @@ private:
}
else version (AsmLoongArch64_Posix)
{
+ // Like others, FP registers and return address ($r1) are kept
+ // below the saved stack top (tstack) to hide from GC scanning.
+ // fiber_switchContext expects newp sp to look like this:
+ // 10: $r21 (reserved)
+ // 9: $r22 (frame pointer)
+ // 8: $r23
+ // ...
+ // 0: $r31 <-- newp tstack
+ // -1: $r1 (return address) [&fiber_entryPoint]
+ // -2: $f24
+ // ...
+ // -9: $f31
+
version (StackGrowsDown) {}
- else static assert(0);
+ else
+ static assert(false, "Only full descending stacks supported on LoongArch64");
- // Like others, FP registers and return address (ra) are kept
- // below the saved stack top (tstack) to hide from GC scanning.
- // The newp stack should look like this on LoongArch64:
- // 18: fp <- pstack
- // ...
- // 9: s0 <- newp tstack
- // 8: ra [&fiber_entryPoint]
- // 7: fs7
- // ...
- // 1: fs1
- // 0: fs0
- pstack -= 10 * size_t.sizeof; // skip s0-s8 and fp
- // set $ra
- push( cast(size_t) &fiber_entryPoint );
- pstack += size_t.sizeof;
+ // Only need to set return address ($r1). Everything else is fine
+ // zero initialized.
+ pstack -= size_t.sizeof * 11; // skip past space reserved for $r21-$r31
+ push (cast(size_t) &fiber_entryPoint);
+ pstack += size_t.sizeof; // adjust sp (newp) above lr
}
else version (AsmAArch64_Posix)
{
diff --git a/libphobos/libdruntime/core/vararg.d b/libphobos/libdruntime/core/vararg.d
index 2c3e965..e6dd47d 100644
--- a/libphobos/libdruntime/core/vararg.d
+++ b/libphobos/libdruntime/core/vararg.d
@@ -129,6 +129,13 @@ void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
ap += tsize.alignUp;
parmn[0..tsize] = p[0..tsize];
}
+ else version (LoongArch64)
+ {
+ const tsize = ti.tsize;
+ auto p = cast(void*) ap;
+ ap += tsize.alignUp;
+ parmn[0..tsize] = p[0..tsize];
+ }
else version (MIPS_Any)
{
const tsize = ti.tsize;
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index 0111be0..5589c0a 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -642,7 +642,8 @@ class TypeInfo
*/
size_t getHash(scope const void* p) @trusted nothrow const
{
- return hashOf(p);
+ // by default, do not assume anything about the type
+ return 0;
}
/// Compares two instances for equality.
@@ -2918,19 +2919,19 @@ alias AssociativeArray(Key, Value) = Value[Key];
* Params:
* aa = The associative array.
*/
-void clear(Value, Key)(Value[Key] aa)
+void clear(Value, Key)(Value[Key] aa) @trusted
{
_aaClear(*cast(AA *) &aa);
}
/** ditto */
-void clear(Value, Key)(Value[Key]* aa)
+void clear(Value, Key)(Value[Key]* aa) @trusted
{
_aaClear(*cast(AA *) aa);
}
///
-@system unittest
+@safe unittest
{
auto aa = ["k1": 2];
aa.clear;
@@ -4666,11 +4667,13 @@ public import core.internal.array.appending : _d_arrayappendT;
version (D_ProfileGC)
{
public import core.internal.array.appending : _d_arrayappendTTrace;
+ public import core.internal.array.appending : _d_arrayappendcTXTrace;
public import core.internal.array.concatenation : _d_arraycatnTXTrace;
public import core.lifetime : _d_newitemTTrace;
public import core.internal.array.construction : _d_newarrayTTrace;
+ public import core.internal.array.construction : _d_newarraymTXTrace;
}
-public import core.internal.array.appending : _d_arrayappendcTXImpl;
+public import core.internal.array.appending : _d_arrayappendcTX;
public import core.internal.array.comparison : __cmp;
public import core.internal.array.equality : __equals;
public import core.internal.array.casting: __ArrayCast;
@@ -4678,6 +4681,7 @@ public import core.internal.array.concatenation : _d_arraycatnTX;
public import core.internal.array.construction : _d_arrayctor;
public import core.internal.array.construction : _d_arraysetctor;
public import core.internal.array.construction : _d_newarrayT;
+public import core.internal.array.construction : _d_newarraymTX;
public import core.internal.array.arrayassign : _d_arrayassign_l;
public import core.internal.array.arrayassign : _d_arrayassign_r;
public import core.internal.array.arrayassign : _d_arraysetassign;
diff --git a/libphobos/libdruntime/rt/aaA.d b/libphobos/libdruntime/rt/aaA.d
index 4014862..36f2555 100644
--- a/libphobos/libdruntime/rt/aaA.d
+++ b/libphobos/libdruntime/rt/aaA.d
@@ -41,7 +41,7 @@ struct AA
Impl* impl;
alias impl this;
- private @property bool empty() const pure nothrow @nogc
+ private @property bool empty() const pure nothrow @nogc @safe
{
return impl is null || !impl.length;
}
@@ -57,6 +57,7 @@ private:
buckets = allocBuckets(sz);
firstUsed = cast(uint) buckets.length;
valoff = cast(uint) talign(keysz, ti.value.talign);
+ hashFn = &ti.key.getHash;
import rt.lifetime : hasPostblit, unqualify;
@@ -78,6 +79,10 @@ private:
immutable uint valoff;
Flags flags;
+ // function that calculates hash of a key. Set on creation
+ // the parameter is a pointer to the key.
+ size_t delegate(scope const void*) nothrow hashFn;
+
enum Flags : ubyte
{
none = 0x0,
@@ -85,7 +90,7 @@ private:
hasPointers = 0x2,
}
- @property size_t length() const pure nothrow @nogc
+ @property size_t length() const pure nothrow @nogc @safe
{
assert(used >= deleted);
return used - deleted;
@@ -156,7 +161,7 @@ private:
GC.free(obuckets.ptr); // safe to free b/c impossible to reference
}
- void clear() pure nothrow
+ void clear() pure nothrow @trusted
{
import core.stdc.string : memset;
// clear all data, but don't change bucket array length
@@ -457,9 +462,9 @@ private size_t mix(size_t h) @safe pure nothrow @nogc
return h;
}
-private size_t calcHash(scope const void* pkey, scope const TypeInfo keyti) nothrow
+private size_t calcHash(scope const void *pkey, scope const Impl* impl) nothrow
{
- immutable hash = keyti.getHash(pkey);
+ immutable hash = impl.hashFn(pkey);
// highest bit is set to distinguish empty/deleted from filled buckets
return mix(hash) | HASH_FILLED_MARK;
}
@@ -550,7 +555,7 @@ extern (C) void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti,
}
// get hash and bucket for key
- immutable hash = calcHash(pkey, ti.key);
+ immutable hash = calcHash(pkey, aa);
// found a value => return it
if (auto p = aa.findSlotLookup(hash, pkey, ti.key))
@@ -617,7 +622,7 @@ extern (C) inout(void)* _aaInX(inout AA aa, scope const TypeInfo keyti, scope co
if (aa.empty)
return null;
- immutable hash = calcHash(pkey, keyti);
+ immutable hash = calcHash(pkey, aa);
if (auto p = aa.findSlotLookup(hash, pkey, keyti))
return p.entry + aa.valoff;
return null;
@@ -629,7 +634,7 @@ extern (C) bool _aaDelX(AA aa, scope const TypeInfo keyti, scope const void* pke
if (aa.empty)
return false;
- immutable hash = calcHash(pkey, keyti);
+ immutable hash = calcHash(pkey, aa);
if (auto p = aa.findSlotLookup(hash, pkey, keyti))
{
// clear entry
@@ -648,7 +653,7 @@ extern (C) bool _aaDelX(AA aa, scope const TypeInfo keyti, scope const void* pke
}
/// Remove all elements from AA.
-extern (C) void _aaClear(AA aa) pure nothrow
+extern (C) void _aaClear(AA aa) pure nothrow @safe
{
if (!aa.empty)
{
@@ -778,7 +783,7 @@ extern (C) Impl* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void
uint actualLength = 0;
foreach (_; 0 .. length)
{
- immutable hash = calcHash(pkey, ti.key);
+ immutable hash = calcHash(pkey, aa);
auto p = aa.findSlotLookup(hash, pkey, ti.key);
if (p is null)
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index af3c6bb..8ce2d56 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -1041,98 +1041,6 @@ extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow @
}
}
-
-/*
- * Helper for creating multi-dimensional arrays
- */
-private void[] _d_newarrayOpT(alias op)(const TypeInfo ti, size_t[] dims)
-{
- debug(PRINTF) printf("_d_newarrayOpT(ndims = %d)\n", dims.length);
- if (dims.length == 0)
- return null;
-
- void[] foo(const TypeInfo ti, size_t[] dims)
- {
- auto tinext = unqualify(ti.next);
- auto dim = dims[0];
-
- debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, dims.length);
- if (dims.length == 1)
- {
- auto r = op(ti, dim);
- return *cast(void[]*)(&r);
- }
-
- auto allocsize = (void[]).sizeof * dim;
- auto info = __arrayAlloc(allocsize, ti, tinext);
- auto isshared = typeid(ti) is typeid(TypeInfo_Shared);
- __setArrayAllocLength(info, allocsize, isshared, tinext);
- auto p = __arrayStart(info)[0 .. dim];
-
- foreach (i; 0..dim)
- {
- (cast(void[]*)p.ptr)[i] = foo(tinext, dims[1..$]);
- }
- return p;
- }
-
- auto result = foo(ti, dims);
- debug(PRINTF) printf("result = %llx\n", result.ptr);
-
- return result;
-}
-
-
-/**
-Create a new multi-dimensional array
-
-Has two variants:
-- `_d_newarraymTX` which initializes to 0
-- `_d_newarraymiTX` which initializes elements based on `TypeInfo`
-
----
-void main()
-{
- new int[][](10, 20);
- // _d_newarraymTX(typeid(float), [10, 20]);
-
- new float[][][](10, 20, 30);
- // _d_newarraymiTX(typeid(float), [10, 20, 30]);
-}
----
-
-Params:
- ti = `TypeInfo` of the array type
- dims = array length values for each dimension
-
-Returns:
- newly allocated array
-*/
-extern (C) void[] _d_newarraymTX(const TypeInfo ti, size_t[] dims) @weak
-{
- debug(PRINTF) printf("_d_newarraymT(dims.length = %d)\n", dims.length);
-
- if (dims.length == 0)
- return null;
- else
- {
- return _d_newarrayOpT!(_d_newarrayT)(ti, dims);
- }
-}
-
-/// ditto
-extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims) @weak
-{
- debug(PRINTF) printf("_d_newarraymiT(dims.length = %d)\n", dims.length);
-
- if (dims.length == 0)
- return null;
- else
- {
- return _d_newarrayOpT!(_d_newarrayiT)(ti, dims);
- }
-}
-
/**
Non-template version of $(REF _d_newitemT, core,lifetime) that does not perform
initialization. Needed for $(REF allocEntry, rt,aaA).
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 8c536ce..1b20d58 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-1c98326e787e504d9045004e593273ec99b13121
+17bafda797296e04f40f16a9660e5a9685392db4
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d
index 0adb88b..ef11706 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -4809,26 +4809,41 @@ private template ReduceSeedType(E)
/++
Implements the homonym function (also known as `accumulate`, $(D
compress), `inject`, or `foldl`) present in various programming
-languages of functional flavor. The call `fold!(fun)(range, seed)`
-first assigns `seed` to an internal variable `result`,
-also called the accumulator. Then, for each element `x` in $(D
-range), `result = fun(result, x)` gets evaluated. Finally, $(D
-result) is returned. The one-argument version `fold!(fun)(range)`
+languages of functional flavor, iteratively calling one or more predicates.
+
+$(P Each predicate in `fun` must take two arguments:)
+* An accumulator value
+* An element of the range `r`
+$(P Each predicate must return a value which implicitly converts to the
+type of the accumulator.)
+
+$(P For a single predicate,
+the call `fold!(fun)(range, seed)` will:)
+
+* Use `seed` to initialize an internal variable `result` (also called
+ the accumulator).
+* For each element `e` in $(D range), evaluate `result = fun(result, e)`.
+* Return $(D result).
+
+$(P The one-argument version `fold!(fun)(range)`
works similarly, but it uses the first element of the range as the
-seed (the range must be non-empty).
+seed (the range must be non-empty) and iterates over the remaining
+elements.)
+
+Multiple results are produced when using multiple predicates.
Params:
fun = the predicate function(s) to apply to the elements
See_Also:
- $(HTTP en.wikipedia.org/wiki/Fold_(higher-order_function), Fold (higher-order function))
+ * $(HTTP en.wikipedia.org/wiki/Fold_(higher-order_function), Fold (higher-order function))
- $(LREF sum) is similar to `fold!((a, b) => a + b)` that offers
- precise summing of floating point numbers.
+ * $(LREF sum) is similar to `fold!((a, b) => a + b)` that offers
+ precise summing of floating point numbers.
- This is functionally equivalent to $(LREF reduce) with the argument order
- reversed, and without the need to use $(REF_ALTTEXT `tuple`,tuple,std,typecons)
- for multiple seeds.
+ * `fold` is functionally equivalent to $(LREF reduce) with the argument order
+ reversed, and without the need to use $(REF_ALTTEXT `tuple`,tuple,std,typecons)
+ for multiple seeds.
+/
template fold(fun...)
if (fun.length >= 1)
@@ -4836,20 +4851,21 @@ if (fun.length >= 1)
/**
Params:
r = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to fold
- seed = the initial value of the accumulator
+ seeds = the initial values of each accumulator (optional), one for each predicate
Returns:
- the accumulated `result`
+ Either the accumulated result for a single predicate, or a
+ $(REF_ALTTEXT `Tuple`,Tuple,std,typecons) of results.
*/
- auto fold(R, S...)(R r, S seed)
+ auto fold(R, S...)(R r, S seeds)
{
static if (S.length < 2)
{
- return reduce!fun(seed, r);
+ return reduce!fun(seeds, r);
}
else
{
import std.typecons : tuple;
- return reduce!fun(tuple(seed), r);
+ return reduce!fun(tuple(seeds), r);
}
}
}
@@ -4860,10 +4876,10 @@ if (fun.length >= 1)
immutable arr = [1, 2, 3, 4, 5];
// Sum all elements
- assert(arr.fold!((a, b) => a + b) == 15);
+ assert(arr.fold!((a, e) => a + e) == 15);
// Sum all elements with explicit seed
- assert(arr.fold!((a, b) => a + b)(6) == 21);
+ assert(arr.fold!((a, e) => a + e)(6) == 21);
import std.algorithm.comparison : min, max;
import std.typecons : tuple;
@@ -4875,10 +4891,10 @@ if (fun.length >= 1)
assert(arr.fold!(min, max)(0, 7) == tuple(0, 7));
// Can be used in a UFCS chain
- assert(arr.map!(a => a + 1).fold!((a, b) => a + b) == 20);
+ assert(arr.map!(a => a + 1).fold!((a, e) => a + e) == 20);
// Return the last element of any range
- assert(arr.fold!((a, b) => b) == 5);
+ assert(arr.fold!((a, e) => e) == 5);
}
@safe @nogc pure nothrow unittest
diff --git a/libphobos/src/std/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d
index 37a08de..6897905 100644
--- a/libphobos/src/std/algorithm/searching.d
+++ b/libphobos/src/std/algorithm/searching.d
@@ -1547,27 +1547,95 @@ if (isInputRange!Range && !isInfinite!Range &&
// find
/**
+Finds an element `e` of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
+where `pred(e)` is `true`.
+$(P
+$(PANEL
+$(UL
+$(LI `find` behaves similarly to `dropWhile` in other languages.)
+$(LI To _find the *last* matching element in a
+$(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives) `haystack`,
+call `find!pred(retro(haystack))`. See $(REF retro, std,range).)
+)))
+
+Complexity:
+ `find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.
+
+Params:
+
+ pred = The predicate to match an element.
+ haystack = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
+ searched in.
+
+Returns:
+ `haystack` advanced such that the front element satisfies `pred`.
+ If no such element exists, returns an empty `haystack`.
+*/
+InputRange find(alias pred, InputRange)(InputRange haystack)
+if (isInputRange!InputRange)
+{
+ alias R = InputRange;
+ alias predFun = unaryFun!pred;
+ static if (isNarrowString!R)
+ {
+ import std.utf : decode;
+
+ immutable len = haystack.length;
+ size_t i = 0, next = 0;
+ while (next < len)
+ {
+ if (predFun(decode(haystack, next)))
+ return haystack[i .. $];
+ i = next;
+ }
+ return haystack[$ .. $];
+ }
+ else
+ {
+ //standard range
+ for ( ; !haystack.empty; haystack.popFront() )
+ {
+ if (predFun(haystack.front))
+ break;
+ }
+ return haystack;
+ }
+}
+
+///
+@safe unittest
+{
+ auto arr = [ 1, 2, 3, 4, 1 ];
+ assert(find!("a > 2")(arr) == [ 3, 4, 1 ]);
+
+ // with predicate alias
+ bool pred(int e) => e + 1 > 1.5;
+ assert(find!(pred)(arr) == arr);
+}
+
+@safe pure unittest
+{
+ int[] r = [ 1, 2, 3 ];
+ assert(find!(a=>a > 2)(r) == [3]);
+ bool pred(int x) { return x + 1 > 1.5; }
+ assert(find!(pred)(r) == r);
+
+ assert(find!(a=>a > 'v')("hello world") == "world");
+ assert(find!(a=>a%4 == 0)("日本語") == "本語");
+}
+
+/**
Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
Elements of `haystack` are compared with `needle` by using predicate
`pred` with `pred(haystack.front, needle)`.
-`find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.
-
The predicate is passed to $(REF binaryFun, std, functional), and can either accept a
string, or any callable that can be executed via `pred(element, element)`.
-To _find the last occurrence of `needle` in a
-$(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives) `haystack`,
-call `find(retro(haystack), needle)`. See $(REF retro, std,range).
-
-If no `needle` is provided, `pred(haystack.front)` will be evaluated on each
-element of the input range.
-
-If `input` is a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives),
+If `haystack` is a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives),
`needle` can be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) too.
In this case `startsWith!pred(haystack, needle)` is evaluated on each evaluation.
-Note:
- `find` behaves similar to `dropWhile` in other languages.
+$(NOTE To find the first element $(I not) matching the needle, use predicate `"a != b"`.)
Complexity:
`find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.
@@ -1579,21 +1647,16 @@ Complexity:
Params:
pred = The predicate for comparing each element with the needle, defaulting to equality `"a == b"`.
- The negated predicate `"a != b"` can be used to search instead for the first
- element $(I not) matching the needle.
-
haystack = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
searched in.
-
needle = The element searched for.
Returns:
-
`haystack` advanced such that the front element is the one searched for;
that is, until `binaryFun!pred(haystack.front, needle)` is `true`. If no
such position exists, returns an empty `haystack`.
-See_ALso: $(LREF findAdjacent), $(LREF findAmong), $(LREF findSkip), $(LREF findSplit), $(LREF startsWith)
+See_Also: $(LREF findAdjacent), $(LREF findAmong), $(LREF findSkip), $(LREF findSplit), $(LREF startsWith)
*/
InputRange find(alias pred = "a == b", InputRange, Element)(InputRange haystack, scope Element needle)
if (isInputRange!InputRange &&
@@ -1754,8 +1817,8 @@ if (isInputRange!InputRange &&
assert(arr.find(4) == [4, 4, 4, 4, 5, 6, 9]);
assert(arr.find(1) == arr);
assert(arr.find(9) == [9]);
- assert(arr.find!((a, b) => a > b)(4) == [5, 6, 9]);
- assert(arr.find!((a, b) => a < b)(4) == arr);
+ assert(arr.find!((e, n) => e > n)(4) == [5, 6, 9]);
+ assert(arr.find!((e, n) => e < n)(4) == arr);
assert(arr.find(0).empty);
assert(arr.find(10).empty);
assert(arr.find(8).empty);
@@ -1770,7 +1833,7 @@ if (isInputRange!InputRange &&
import std.uni : toLower;
string[] s = ["Hello", "world", "!"];
- assert(s.find!((a, b) => toLower(a) == b)("hello") == s);
+ assert(s.find!((e, n) => toLower(e) == n)("hello") == s);
}
@safe unittest
@@ -1863,60 +1926,6 @@ if (isInputRange!InputRange &&
}
/// ditto
-InputRange find(alias pred, InputRange)(InputRange haystack)
-if (isInputRange!InputRange)
-{
- alias R = InputRange;
- alias predFun = unaryFun!pred;
- static if (isNarrowString!R)
- {
- import std.utf : decode;
-
- immutable len = haystack.length;
- size_t i = 0, next = 0;
- while (next < len)
- {
- if (predFun(decode(haystack, next)))
- return haystack[i .. $];
- i = next;
- }
- return haystack[$ .. $];
- }
- else
- {
- //standard range
- for ( ; !haystack.empty; haystack.popFront() )
- {
- if (predFun(haystack.front))
- break;
- }
- return haystack;
- }
-}
-
-///
-@safe unittest
-{
- auto arr = [ 1, 2, 3, 4, 1 ];
- assert(find!("a > 2")(arr) == [ 3, 4, 1 ]);
-
- // with predicate alias
- bool pred(int x) { return x + 1 > 1.5; }
- assert(find!(pred)(arr) == arr);
-}
-
-@safe pure unittest
-{
- int[] r = [ 1, 2, 3 ];
- assert(find!(a=>a > 2)(r) == [3]);
- bool pred(int x) { return x + 1 > 1.5; }
- assert(find!(pred)(r) == r);
-
- assert(find!(a=>a > 'v')("hello world") == "world");
- assert(find!(a=>a%4 == 0)("日本語") == "本語");
-}
-
-/// ditto
R1 find(alias pred = "a == b", R1, R2)(R1 haystack, scope R2 needle)
if (isForwardRange!R1 && isForwardRange!R2
&& is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
@@ -2376,9 +2385,9 @@ is considered to be 1.) The strategy used in searching several
subranges at once maximizes cache usage by moving in `haystack` as
few times as possible.
*/
-Tuple!(Range, size_t) find(alias pred = "a == b", Range, Ranges...)
-(Range haystack, Ranges needles)
-if (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles))))
+Tuple!(Range, size_t) find(alias pred = "a == b", Range, Needles...)
+(Range haystack, Needles needles)
+if (Needles.length > 1 && is(typeof(startsWith!pred(haystack, needles))))
{
for (;; haystack.popFront())
{
@@ -2536,13 +2545,13 @@ was successful.
For more information about `pred` see $(LREF find).
See_Also:
-$(REF among, std,algorithm,comparison) for checking a value against multiple possibilities.
+$(REF among, std,algorithm,comparison) for checking a value against multiple arguments.
+/
template canFind(alias pred="a == b")
{
/++
- Returns `true` if and only if any value `v` found in the
- input range `range` satisfies the predicate `pred`.
+ Returns `true` if and only if `pred(e)` is true for any value `e` in the
+ input range `range`.
Performs (at most) $(BIGOH haystack.length) evaluations of `pred`.
+/
bool canFind(Range)(Range haystack)
@@ -2565,16 +2574,15 @@ template canFind(alias pred="a == b")
Returns the 1-based index of the first needle found in `haystack`. If no
needle is found, then `0` is returned.
- So, if used directly in the condition of an if statement or loop, the result
+ So, if used directly in the condition of an `if` statement or loop, the result
will be `true` if one of the needles is found and `false` if none are
found, whereas if the result is used elsewhere, it can either be cast to
`bool` for the same effect or used to get which needle was found first
- without having to deal with the tuple that `LREF find` returns for the
+ without having to deal with the tuple that $(LREF find) returns for the
same operation.
+/
- size_t canFind(Range, Ranges...)(Range haystack, scope Ranges needles)
- if (Ranges.length > 1 &&
- allSatisfy!(isForwardRange, Ranges) &&
+ size_t canFind(Range, Needles...)(Range haystack, scope Needles needles)
+ if (Needles.length > 1 &&
is(typeof(find!pred(haystack, needles))))
{
return find!pred(haystack, needles)[1];
@@ -2584,15 +2592,21 @@ template canFind(alias pred="a == b")
///
@safe unittest
{
- assert(canFind([0, 1, 2, 3], 2) == true);
- assert(canFind([0, 1, 2, 3], [1, 2], [2, 3]));
- assert(canFind([0, 1, 2, 3], [1, 2], [2, 3]) == 1);
- assert(canFind([0, 1, 2, 3], [1, 7], [2, 3]));
- assert(canFind([0, 1, 2, 3], [1, 7], [2, 3]) == 2);
+ const arr = [0, 1, 2, 3];
+ assert(canFind(arr, 2));
+ assert(!canFind(arr, 4));
+
+ // find one of several needles
+ assert(arr.canFind(3, 2));
+ assert(arr.canFind(3, 2) == 2); // second needle found
+ assert(arr.canFind([1, 3], 2) == 2);
- assert(canFind([0, 1, 2, 3], 4) == false);
- assert(!canFind([0, 1, 2, 3], [1, 3], [2, 4]));
- assert(canFind([0, 1, 2, 3], [1, 3], [2, 4]) == 0);
+ assert(canFind(arr, [1, 2], [2, 3]));
+ assert(canFind(arr, [1, 2], [2, 3]) == 1);
+ assert(canFind(arr, [1, 7], [2, 3]));
+ assert(canFind(arr, [1, 7], [2, 3]) == 2);
+ assert(!canFind(arr, [1, 3], [2, 4]));
+ assert(canFind(arr, [1, 3], [2, 4]) == 0);
}
/**
@@ -2607,10 +2621,10 @@ template canFind(alias pred="a == b")
"cardboard"
];
assert(!canFind(words, "bees"));
- assert( canFind!((string a, string b) => a.startsWith(b))(words, "bees"));
+ assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));
}
-/// Search for mutliple items in an array of items (search for needles in an array of hay stacks)
+/// Search for multiple items in an array of items (search for needles in an array of haystacks)
@safe unittest
{
string s1 = "aaa111aaa";
@@ -2618,7 +2632,7 @@ template canFind(alias pred="a == b")
string s3 = "aaa333aaa";
string s4 = "aaa444aaa";
const hay = [s1, s2, s3, s4];
- assert(hay.canFind!(e => (e.canFind("111", "222"))));
+ assert(hay.canFind!(e => e.canFind("111", "222")));
}
@safe unittest
@@ -2736,7 +2750,7 @@ Returns:
`seq` advanced to the first matching element, or until empty if there are no
matching elements.
-See_Also: $(LREF find), $(REF std,algorithm,comparison,among)
+See_Also: $(LREF find), $(REF among, std,algorithm,comparison)
*/
InputRange findAmong(alias pred = "a == b", InputRange, ForwardRange)(
InputRange seq, ForwardRange choices)
diff --git a/libphobos/src/std/array.d b/libphobos/src/std/array.d
index a613a8d..494fa29 100644
--- a/libphobos/src/std/array.d
+++ b/libphobos/src/std/array.d
@@ -1201,7 +1201,7 @@ private auto arrayAllocImpl(bool minimallyInitialized, T, I...)(I sizes) nothrow
auto a2 = minimallyInitializedArray!(S2[][])(2, 2);
assert(a2);
enum b2 = minimallyInitializedArray!(S2[][])(2, 2);
- assert(b2);
+ assert(b2 !is null);
static struct S3
{
//this() @disable;
@@ -1210,7 +1210,7 @@ private auto arrayAllocImpl(bool minimallyInitialized, T, I...)(I sizes) nothrow
auto a3 = minimallyInitializedArray!(S3[][])(2, 2);
assert(a3);
enum b3 = minimallyInitializedArray!(S3[][])(2, 2);
- assert(b3);
+ assert(b3 !is null);
}
/++
diff --git a/libphobos/src/std/container/array.d b/libphobos/src/std/container/array.d
index 0d6be93..ad120c1 100644
--- a/libphobos/src/std/container/array.d
+++ b/libphobos/src/std/container/array.d
@@ -594,6 +594,10 @@ if (!is(immutable T == immutable bool))
assert(capacity == values.length); // We check that reserve has been called before the loop.
}
+ /// ditto
+ // needed when T is an array and only one argument is passed
+ this(T single) { __ctor!T(single); }
+
/**
* Constructor taking an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
*/
@@ -1282,6 +1286,13 @@ if (!is(immutable T == immutable bool))
}
}
+@system unittest
+{
+ import std.algorithm.comparison : equal;
+ auto a = Array!string("test");
+ assert(a[].equal(["test"]));
+}
+
@safe unittest
{
// https://issues.dlang.org/show_bug.cgi?id=13621
diff --git a/libphobos/src/std/logger/package.d b/libphobos/src/std/logger/package.d
index 4f4183c..14a4394 100644
--- a/libphobos/src/std/logger/package.d
+++ b/libphobos/src/std/logger/package.d
@@ -54,6 +54,7 @@ $(UL
$(LI `trace`)
$(LI `info`)
$(LI `warning`)
+ $(LI `error`)
$(LI `critical`)
$(LI `fatal`)
)
diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d
index 81c7302..cb6cb87 100644
--- a/libphobos/src/std/math/hardware.d
+++ b/libphobos/src/std/math/hardware.d
@@ -33,6 +33,7 @@ version (SPARC64) version = SPARC_Any;
version (SystemZ) version = IBMZ_Any;
version (RISCV32) version = RISCV_Any;
version (RISCV64) version = RISCV_Any;
+version (LoongArch64) version = LoongArch_Any;
version (D_InlineAsm_X86) version = InlineAsm_X86_Any;
version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
@@ -60,6 +61,7 @@ else version (X86_Any) version = IeeeFlagsSupport;
else version (PPC_Any) version = IeeeFlagsSupport;
else version (RISCV_Any) version = IeeeFlagsSupport;
else version (MIPS_Any) version = IeeeFlagsSupport;
+else version (LoongArch_Any) version = IeeeFlagsSupport;
else version (ARM_Any) version = IeeeFlagsSupport;
// Struct FloatingPointControl is only available if hardware FP units are available.
@@ -90,6 +92,7 @@ private:
// The ARM and PowerPC FPSCR is a 32-bit register.
// The SPARC FSR is a 32bit register (64 bits for SPARC 7 & 8, but high bits are uninteresting).
// The RISC-V (32 & 64 bit) fcsr is 32-bit register.
+ // THe LoongArch fcsr (fcsr0) is a 32-bit register.
uint flags;
version (CRuntime_Microsoft)
@@ -216,6 +219,15 @@ private:
return result;
`);
}
+ else version (LoongArch_Any)
+ {
+ uint result = void;
+ asm pure nothrow @nogc
+ {
+ "movfcsr2gr %0,$r2" : "=r" (result);
+ }
+ return result & EXCEPTIONS_MASK;
+ }
else
assert(0, "Not yet supported");
}
@@ -303,6 +315,13 @@ private:
}
`);
}
+ else version (LoongArch_Any)
+ {
+ asm nothrow @nogc
+ {
+ "movgr2fcsr $r2,$r0";
+ }
+ }
else
{
/* SPARC:
@@ -725,6 +744,21 @@ nothrow @nogc:
| inexactException,
}
}
+ else version (LoongArch_Any)
+ {
+ enum : ExceptionMask
+ {
+ inexactException = 0x00,
+ divByZeroException = 0x01,
+ overflowException = 0x02,
+ underflowException = 0x04,
+ invalidException = 0x08,
+ severeExceptions = overflowException | divByZeroException
+ | invalidException,
+ allExceptions = severeExceptions | underflowException
+ | inexactException,
+ }
+ }
else version (MIPS_Any)
{
enum : ExceptionMask
@@ -812,6 +846,8 @@ nothrow @nogc:
return true;
else version (MIPS_Any)
return true;
+ else version (LoongArch_Any)
+ return true;
else version (ARM_Any)
{
// The hasExceptionTraps_impl function is basically pure,
@@ -885,6 +921,10 @@ private:
{
alias ControlState = uint;
}
+ else version (LoongArch_Any)
+ {
+ alias ControlState = uint;
+ }
else version (MIPS_Any)
{
alias ControlState = uint;
@@ -1008,6 +1048,16 @@ private:
return cont;
`);
}
+ else version (LoongArch_Any)
+ {
+ ControlState cont;
+ asm pure nothrow @nogc
+ {
+ "movfcsr2gr %0,$r0" : "=r" (cont);
+ }
+ cont &= (roundingMask | allExceptions);
+ return cont;
+ }
else
assert(0, "Not yet supported");
}
@@ -1120,6 +1170,14 @@ private:
}
`);
}
+ else version (LoongArch_Any)
+ {
+ asm nothrow @nogc
+ {
+ "movgr2fcsr $r0,%0" :
+ : "r" (newState & (roundingMask | allExceptions));
+ }
+ }
else
assert(0, "Not yet supported");
}
diff --git a/libphobos/src/std/range/primitives.d b/libphobos/src/std/range/primitives.d
index 89cfa07..fec5c85 100644
--- a/libphobos/src/std/range/primitives.d
+++ b/libphobos/src/std/range/primitives.d
@@ -1015,12 +1015,27 @@ See_Also:
enum bool isForwardRange(R) = isInputRange!R
&& is(typeof((R r) { return r.save; } (R.init)) == R);
+/// ditto
+enum bool isForwardRange(R, E) =
+ .isForwardRange!R && isQualifierConvertible!(ElementType!R, E);
+
///
@safe unittest
{
static assert(!isForwardRange!(int));
static assert( isForwardRange!(int[]));
static assert( isForwardRange!(inout(int)[]));
+
+ static assert( isForwardRange!(int[], const int));
+ static assert(!isForwardRange!(int[], immutable int));
+
+ static assert(!isForwardRange!(const(int)[], int));
+ static assert( isForwardRange!(const(int)[], const int));
+ static assert(!isForwardRange!(const(int)[], immutable int));
+
+ static assert(!isForwardRange!(immutable(int)[], int));
+ static assert( isForwardRange!(immutable(int)[], const int));
+ static assert( isForwardRange!(immutable(int)[], immutable int));
}
@safe unittest
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index f4b9f5f..bb1feca 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,10 @@
+2023-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/112562
+ * sanitizer_common/sanitizer_asm.h: Cherry-pick llvm-project revision
+ a855a16a02e76a0f4192c038bb64f3773947a2f7.
+ * interception/interception.h: Likewise.
+
2023-11-18 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* asan/asan_mac.cpp: Protect Apple blocks behind the
diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h
index 069f73d..9d8b60b 100644
--- a/libsanitizer/interception/interception.h
+++ b/libsanitizer/interception/interception.h
@@ -185,6 +185,11 @@ const interpose_substitution substitution_##func_name[] \
# else
# define __ASM_WEAK_WRAPPER(func) ".weak " #func "\n"
# endif // SANITIZER_FREEBSD || SANITIZER_NETBSD
+# if defined(__arm__) || defined(__aarch64__)
+# define ASM_TYPE_FUNCTION_STR "%function"
+# else
+# define ASM_TYPE_FUNCTION_STR "@function"
+# endif
// Keep trampoline implementation in sync with sanitizer_common/sanitizer_asm.h
# define DECLARE_WRAPPER(ret_type, func, ...) \
extern "C" ret_type func(__VA_ARGS__); \
@@ -196,7 +201,8 @@ const interpose_substitution substitution_##func_name[] \
__ASM_WEAK_WRAPPER(func) \
".set " #func ", " SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \
".globl " SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \
- ".type " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", %function\n" \
+ ".type " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \
+ ASM_TYPE_FUNCTION_STR "\n" \
SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n" \
SANITIZER_STRINGIFY(CFI_STARTPROC) "\n" \
SANITIZER_STRINGIFY(ASM_TAIL_CALL) " __interceptor_" \
diff --git a/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h
index 3c9bbdc..bbb18cf 100644
--- a/libsanitizer/sanitizer_common/sanitizer_asm.h
+++ b/libsanitizer/sanitizer_common/sanitizer_asm.h
@@ -62,7 +62,11 @@
#if !defined(__APPLE__)
# define ASM_HIDDEN(symbol) .hidden symbol
-# define ASM_TYPE_FUNCTION(symbol) .type symbol, %function
+# if defined(__arm__) || defined(__aarch64__)
+# define ASM_TYPE_FUNCTION(symbol) .type symbol, %function
+# else
+# define ASM_TYPE_FUNCTION(symbol) .type symbol, @function
+# endif
# define ASM_SIZE(symbol) .size symbol, .-symbol
# define ASM_SYMBOL(symbol) symbol
# define ASM_SYMBOL_INTERCEPTOR(symbol) symbol
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f636961..fb48d2d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,106 @@
+2023-11-24 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/109849
+ * include/bits/stl_uninitialized.h (__relocate_a_1): Use memcpy instead
+ of memmove.
+
+2023-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/111055
+ * include/bits/ranges_base.h (from_range_t): Define new tag
+ type.
+ (from_range): Define new tag object.
+ * include/bits/version.def (ranges_to_container): Define.
+ * include/bits/version.h: Regenerate.
+ * include/std/ranges (ranges::to): Define.
+ * testsuite/std/ranges/conv/1.cc: New test.
+ * testsuite/std/ranges/conv/2_neg.cc: New test.
+ * testsuite/std/ranges/conv/version.cc: New test.
+
+2023-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/util/testsuite_allocator.h (uneq_allocator): Fix
+ equality operator for heterogeneous comparisons.
+
+2023-11-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/version.def (freestanding_cstring): Add.
+ * include/bits/version.h: Regenerate.
+ * include/c_compatibility/string.h (strtok): Do not declare for
+ C++26 freestanding.
+ * include/c_global/cstring (strtok): Likewise.
+ * testsuite/21_strings/headers/cstring/version.cc: New test.
+
+2023-11-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/version.def (freestanding_algorithm)
+ (freestanding_array, freestanding_optional)
+ (freestanding_string_view, freestanding_variant): Add.
+ * include/bits/version.h: Regenerate.
+ * include/std/algorithm (__glibcxx_want_freestanding_algorithm):
+ Define.
+ * include/std/array (__glibcxx_want_freestanding_array):
+ Define.
+ * include/std/optional (__glibcxx_want_freestanding_optional):
+ Define.
+ * include/std/string_view
+ (__glibcxx_want_freestanding_string_view): Define.
+ * include/std/variant (__glibcxx_want_freestanding_variant):
+ Define.
+ * testsuite/20_util/optional/version.cc: Add checks for
+ __cpp_lib_freestanding_optional.
+ * testsuite/20_util/variant/version.cc: Add checks for
+ __cpp_lib_freestanding_variant.
+ * testsuite/23_containers/array/tuple_interface/get_neg.cc:
+ Adjust dg-error line numbers.
+ * testsuite/21_strings/basic_string_view/requirements/version.cc:
+ New test.
+ * testsuite/23_containers/array/requirements/version.cc: New
+ test.
+ * testsuite/25_algorithms/fill_n/requirements/version.cc: New
+ test.
+ * testsuite/25_algorithms/swap_ranges/requirements/version.cc:
+ New test.
+
+2023-11-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/version.def (freestanding_expected): New macro.
+ (span): Add C++26 value.
+ * include/bits/version.h: Regenerate.
+ * include/std/expected (__glibcxx_want_freestanding_expected):
+ Define.
+ * include/std/span (span::at): New member function.
+ * testsuite/20_util/expected/version.cc: Add checks for
+ __cpp_lib_freestanding_expected.
+ * testsuite/23_containers/span/2.cc: Moved to...
+ * testsuite/23_containers/span/version.cc: ...here. Add checks
+ for __cpp_lib_span in <span> as well as in <version>.
+ * testsuite/23_containers/span/1.cc: Removed.
+ * testsuite/23_containers/span/at.cc: New test.
+
+2023-11-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/tr2/dynamic_bitset (dynamic_bitset): Pass zero and one
+ characters to _M_copy_from_string.
+ * testsuite/tr2/dynamic_bitset/string.cc: New test.
+
+2023-11-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/html/*: Regenerate.
+ * doc/xml/faq.xml: Remove reference to buildstat.html pages.
+ * doc/xml/manual/test.xml: Likewise
+
+2023-11-21 Jan Hubicka <jh@suse.cz>
+
+ PR libstdc++/110287
+ PR middle-end/109811
+ PR middle-end/109849
+ * include/bits/stl_vector.h (_M_realloc_append): New member function.
+ (push_back): Use it.
+ * include/bits/vector.tcc: (emplace_back): Use it.
+ (_M_realloc_insert): Let compiler know that new vector size is non-zero.
+ (_M_realloc_append): New member function.
+
2023-11-18 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/112607
diff --git a/libstdc++-v3/doc/html/faq.html b/libstdc++-v3/doc/html/faq.html
index d08f039..e84e455 100644
--- a/libstdc++-v3/doc/html/faq.html
+++ b/libstdc++-v3/doc/html/faq.html
@@ -131,9 +131,8 @@
(<span class="command"><strong>gcc</strong></span>, <span class="command"><strong>g++</strong></span>, etc) is widely
considered to be one of the leading compilers in the world. Its
development is overseen by the
- <a class="link" href="https://gcc.gnu.org/" target="_top">GCC team</a>. All of
- the rapid development and near-legendary
- <a class="link" href="https://gcc.gnu.org/buildstat.html" target="_top">portability</a>
+ <a class="link" href="https://gcc.gnu.org/" target="_top">GCC team</a>.
+ All of the rapid development and near-legendary portability
that are the hallmarks of an open-source project are applied to libstdc++.
</p><p>
All of the standard classes and functions from C++98/C++03, C++11 and C++14
diff --git a/libstdc++-v3/doc/html/manual/test.html b/libstdc++-v3/doc/html/manual/test.html
index b29c2eb..4b7f60c 100644
--- a/libstdc++-v3/doc/html/manual/test.html
+++ b/libstdc++-v3/doc/html/manual/test.html
@@ -139,10 +139,8 @@ cat 27_io/objects/char/3_xin.in | a.out</pre></dd><dt><span class="term"><code c
output, and the executable output (if any) for each test.
</p><p>
Archives of test results for various versions and platforms are
- available on the GCC website in the <a class="link" href="http://gcc.gnu.org/gcc-4.3/buildstat.html" target="_top">build
- status</a> section of each individual release, and are also
archived on a daily basis on the <a class="link" href="http://gcc.gnu.org/ml/gcc-testresults/current" target="_top">gcc-testresults</a>
- mailing list. Please check either of these places for a similar
+ mailing list. Please check there for a similar
combination of source version, operating system, and host CPU.
</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="test.run.variations"></a>Variations</h4></div></div></div><p>
There are several options for running tests, including testing
diff --git a/libstdc++-v3/doc/xml/faq.xml b/libstdc++-v3/doc/xml/faq.xml
index da41199..79edb02 100644
--- a/libstdc++-v3/doc/xml/faq.xml
+++ b/libstdc++-v3/doc/xml/faq.xml
@@ -64,9 +64,8 @@
(<command>gcc</command>, <command>g++</command>, etc) is widely
considered to be one of the leading compilers in the world. Its
development is overseen by the
- <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/">GCC team</link>. All of
- the rapid development and near-legendary
- <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/buildstat.html">portability</link>
+ <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/">GCC team</link>.
+ All of the rapid development and near-legendary portability
that are the hallmarks of an open-source project are applied to libstdc++.
</para>
<para>
diff --git a/libstdc++-v3/doc/xml/manual/test.xml b/libstdc++-v3/doc/xml/manual/test.xml
index 936f974..f2c709b 100644
--- a/libstdc++-v3/doc/xml/manual/test.xml
+++ b/libstdc++-v3/doc/xml/manual/test.xml
@@ -266,10 +266,8 @@ cat 27_io/objects/char/3_xin.in | a.out</programlisting>
<para>
Archives of test results for various versions and platforms are
- available on the GCC website in the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/gcc-4.3/buildstat.html">build
- status</link> section of each individual release, and are also
archived on a daily basis on the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/ml/gcc-testresults/current">gcc-testresults</link>
- mailing list. Please check either of these places for a similar
+ mailing list. Please check there for a similar
combination of source version, operating system, and host CPU.
</para>
</section>
diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index 7fa43d1..1ca2c5c 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -37,6 +37,7 @@
#include <bits/stl_iterator.h>
#include <ext/numeric_traits.h>
#include <bits/max_size_type.h>
+#include <bits/version.h>
#ifdef __cpp_lib_concepts
namespace std _GLIBCXX_VISIBILITY(default)
@@ -1056,8 +1057,13 @@ namespace ranges
using borrowed_iterator_t = __conditional_t<borrowed_range<_Range>,
iterator_t<_Range>,
dangling>;
-
} // namespace ranges
+
+#if __glibcxx_ranges_to_container // C++ >= 23
+ struct from_range_t { explicit from_range_t() = default; };
+ inline constexpr from_range_t from_range{};
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // library concepts
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index 1282af3..a9b8027 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -1119,14 +1119,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
{
- // Can't use memmove. Wrap the pointer so that __relocate_a_1
+ // Can't use memcpu. Wrap the pointer so that __relocate_a_1
// resolves to the non-trivial overload above.
__gnu_cxx::__normal_iterator<_Tp*, void> __out(__result);
__out = std::__relocate_a_1(__first, __last, __out, __alloc);
return __out.base();
}
#endif
- __builtin_memmove(__result, __first, __count * sizeof(_Tp));
+ __builtin_memcpy(__result, __first, __count * sizeof(_Tp));
}
return __result + __count;
}
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 5e18f6e..973f4d7 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1288,7 +1288,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX_ASAN_ANNOTATE_GREW(1);
}
else
- _M_realloc_insert(end(), __x);
+ _M_realloc_append(__x);
}
#if __cplusplus >= 201103L
@@ -1822,6 +1822,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
_M_realloc_insert(iterator __position, const value_type& __x);
+
+ void
+ _M_realloc_append(const value_type& __x);
#else
// A value_type object constructed with _Alloc_traits::construct()
// and destroyed with _Alloc_traits::destroy().
@@ -1871,6 +1874,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
_M_realloc_insert(iterator __position, _Args&&... __args);
+ template<typename... _Args>
+ _GLIBCXX20_CONSTEXPR
+ void
+ _M_realloc_append(_Args&&... __args);
+
// Either move-construct at the end, or forward to _M_insert_aux.
_GLIBCXX20_CONSTEXPR
iterator
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 80631d1..0ccef79 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -120,7 +120,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX_ASAN_ANNOTATE_GREW(1);
}
else
- _M_realloc_insert(end(), std::forward<_Args>(__args)...);
+ _M_realloc_append(std::forward<_Args>(__args)...);
#if __cplusplus > 201402L
return back();
#endif
@@ -459,6 +459,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
{
const size_type __len = _M_check_len(1u, "vector::_M_realloc_insert");
+ if (__len <= 0)
+ __builtin_unreachable ();
pointer __old_start = this->_M_impl._M_start;
pointer __old_finish = this->_M_impl._M_finish;
const size_type __elems_before = __position - begin();
@@ -571,6 +573,127 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
this->_M_impl._M_end_of_storage = __new_start + __len;
}
+#if __cplusplus >= 201103L
+ template<typename _Tp, typename _Alloc>
+ template<typename... _Args>
+ _GLIBCXX20_CONSTEXPR
+ void
+ vector<_Tp, _Alloc>::
+ _M_realloc_append(_Args&&... __args)
+#else
+ template<typename _Tp, typename _Alloc>
+ void
+ vector<_Tp, _Alloc>::
+ _M_realloc_append(const _Tp& __x)
+#endif
+ {
+ const size_type __len = _M_check_len(1u, "vector::_M_realloc_append");
+ if (__len <= 0)
+ __builtin_unreachable ();
+ pointer __old_start = this->_M_impl._M_start;
+ pointer __old_finish = this->_M_impl._M_finish;
+ const size_type __elems = end() - begin();
+ pointer __new_start(this->_M_allocate(__len));
+ pointer __new_finish(__new_start);
+
+ // RAII guard for allocated storage.
+ struct _Guard
+ {
+ pointer _M_storage; // Storage to deallocate
+ size_type _M_len;
+ _Tp_alloc_type& _M_alloc;
+
+ _GLIBCXX20_CONSTEXPR
+ _Guard(pointer __s, size_type __l, _Tp_alloc_type& __a)
+ : _M_storage(__s), _M_len(__l), _M_alloc(__a)
+ { }
+
+ _GLIBCXX20_CONSTEXPR
+ ~_Guard()
+ {
+ if (_M_storage)
+ __gnu_cxx::__alloc_traits<_Tp_alloc_type>::
+ deallocate(_M_alloc, _M_storage, _M_len);
+ }
+
+ private:
+ _Guard(const _Guard&);
+ };
+
+ {
+ _Guard __guard(__new_start, __len, _M_impl);
+
+ // The order of the three operations is dictated by the C++11
+ // case, where the moves could alter a new element belonging
+ // to the existing vector. This is an issue only for callers
+ // taking the element by lvalue ref (see last bullet of C++11
+ // [res.on.arguments]).
+
+ // If this throws, the existing elements are unchanged.
+#if __cplusplus >= 201103L
+ _Alloc_traits::construct(this->_M_impl,
+ std::__to_address(__new_start + __elems),
+ std::forward<_Args>(__args)...);
+#else
+ _Alloc_traits::construct(this->_M_impl,
+ __new_start + __elems,
+ __x);
+#endif
+
+#if __cplusplus >= 201103L
+ if _GLIBCXX17_CONSTEXPR (_S_use_relocate())
+ {
+ // Relocation cannot throw.
+ __new_finish = _S_relocate(__old_start, __old_finish,
+ __new_start, _M_get_Tp_allocator());
+ ++__new_finish;
+ }
+ else
+#endif
+ {
+ // RAII type to destroy initialized elements.
+ struct _Guard_elts
+ {
+ pointer _M_first, _M_last; // Elements to destroy
+ _Tp_alloc_type& _M_alloc;
+
+ _GLIBCXX20_CONSTEXPR
+ _Guard_elts(pointer __elt, _Tp_alloc_type& __a)
+ : _M_first(__elt), _M_last(__elt + 1), _M_alloc(__a)
+ { }
+
+ _GLIBCXX20_CONSTEXPR
+ ~_Guard_elts()
+ { std::_Destroy(_M_first, _M_last, _M_alloc); }
+
+ private:
+ _Guard_elts(const _Guard_elts&);
+ };
+
+ // Guard the new element so it will be destroyed if anything throws.
+ _Guard_elts __guard_elts(__new_start + __elems, _M_impl);
+
+ __new_finish = std::__uninitialized_move_if_noexcept_a(
+ __old_start, __old_finish,
+ __new_start, _M_get_Tp_allocator());
+
+ ++__new_finish;
+
+ // New storage has been fully initialized, destroy the old elements.
+ __guard_elts._M_first = __old_start;
+ __guard_elts._M_last = __old_finish;
+ }
+ __guard._M_storage = __old_start;
+ __guard._M_len = this->_M_impl._M_end_of_storage - __old_start;
+ }
+ // deallocate should be called before assignments to _M_impl,
+ // to avoid call-clobbering
+
+ this->_M_impl._M_start = __new_start;
+ this->_M_impl._M_finish = __new_finish;
+ this->_M_impl._M_end_of_storage = __new_start + __len;
+ }
+
template<typename _Tp, typename _Alloc>
_GLIBCXX20_CONSTEXPR
void
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 447fdeb..1407778 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -960,6 +960,11 @@ ftms = {
ftms = {
name = span;
values = {
+ v = 202311;
+ cxxmin = 26;
+ extra_cond = "__glibcxx_concepts";
+ };
+ values = {
v = 202002;
cxxmin = 20;
extra_cond = "__glibcxx_concepts";
@@ -1344,6 +1349,70 @@ ftms = {
};
ftms = {
+ name = freestanding_algorithm;
+ values = {
+ v = 202311;
+ // This is a C++26 feature, but we support it in C++23.
+ cxxmin = 23;
+ };
+};
+
+ftms = {
+ name = freestanding_array;
+ values = {
+ v = 202311;
+ // This is a C++26 feature, but we support it in C++23.
+ cxxmin = 23;
+ };
+};
+
+ftms = {
+ name = freestanding_cstring;
+ values = {
+ v = 202311;
+ // This is a C++26 feature, but we support it in C++23.
+ cxxmin = 23;
+ };
+};
+
+ftms = {
+ name = freestanding_expected;
+ values = {
+ v = 202311;
+ cxxmin = 23;
+ // This is a C++26 feature, but we support it in C++23.
+ extra_cond = "__cpp_lib_expected";
+ };
+};
+
+ftms = {
+ name = freestanding_optional;
+ values = {
+ v = 202311;
+ // This is a C++26 feature, but we support it in C++23.
+ cxxmin = 23;
+ };
+};
+
+ftms = {
+ name = freestanding_string_view;
+ values = {
+ v = 202311;
+ // This is a C++26 feature, but we support it in C++23.
+ cxxmin = 23;
+ };
+};
+
+ftms = {
+ name = freestanding_variant;
+ values = {
+ v = 202311;
+ // This is a C++26 feature, but we support it in C++23.
+ cxxmin = 23;
+ };
+};
+
+ftms = {
name = invoke_r;
values = {
v = 202106;
@@ -1370,19 +1439,21 @@ ftms = {
};
};
-ftms = {
- name = to_underlying;
- values = {
- v = 202102;
- cxxmin = 23;
- };
-};
+//ftms = {
+// name = container_ranges;
+// values = {
+// v = 202202;
+// cxxmin = 23;
+// hosted = yes;
+// };
+//};
ftms = {
- name = unreachable;
+ name = ranges_to_container;
values = {
v = 202202;
cxxmin = 23;
+ hosted = yes;
};
};
@@ -1571,7 +1642,7 @@ ftms = {
ftms = {
name = out_ptr;
values = {
- v = 202106;
+ v = 202311;
cxxmin = 23;
};
};
@@ -1615,6 +1686,22 @@ ftms = {
};
ftms = {
+ name = to_underlying;
+ values = {
+ v = 202102;
+ cxxmin = 23;
+ };
+};
+
+ftms = {
+ name = unreachable;
+ values = {
+ v = 202202;
+ cxxmin = 23;
+ };
+};
+
+ftms = {
name = fstream_native_handle;
values = {
v = 202306;
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 97c6d85..1fb1d14 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1173,7 +1173,12 @@
// from version.def line 961
#if !defined(__cpp_lib_span)
-# if (__cplusplus >= 202002L) && (__glibcxx_concepts)
+# if (__cplusplus > 202302L) && (__glibcxx_concepts)
+# define __glibcxx_span 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_span)
+# define __cpp_lib_span 202311L
+# endif
+# elif (__cplusplus >= 202002L) && (__glibcxx_concepts)
# define __glibcxx_span 202002L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_span)
# define __cpp_lib_span 202002L
@@ -1182,7 +1187,7 @@
#endif /* !defined(__cpp_lib_span) && defined(__glibcxx_want_span) */
#undef __glibcxx_want_span
-// from version.def line 970
+// from version.def line 975
#if !defined(__cpp_lib_ssize)
# if (__cplusplus >= 202002L)
# define __glibcxx_ssize 201902L
@@ -1193,7 +1198,7 @@
#endif /* !defined(__cpp_lib_ssize) && defined(__glibcxx_want_ssize) */
#undef __glibcxx_want_ssize
-// from version.def line 978
+// from version.def line 983
#if !defined(__cpp_lib_three_way_comparison)
# if (__cplusplus >= 202002L) && (__cpp_impl_three_way_comparison >= 201907L && __glibcxx_concepts)
# define __glibcxx_three_way_comparison 201907L
@@ -1204,7 +1209,7 @@
#endif /* !defined(__cpp_lib_three_way_comparison) && defined(__glibcxx_want_three_way_comparison) */
#undef __glibcxx_want_three_way_comparison
-// from version.def line 988
+// from version.def line 993
#if !defined(__cpp_lib_to_address)
# if (__cplusplus >= 202002L)
# define __glibcxx_to_address 201711L
@@ -1215,7 +1220,7 @@
#endif /* !defined(__cpp_lib_to_address) && defined(__glibcxx_want_to_address) */
#undef __glibcxx_want_to_address
-// from version.def line 996
+// from version.def line 1001
#if !defined(__cpp_lib_to_array)
# if (__cplusplus >= 202002L) && (__cpp_generic_lambdas >= 201707L)
# define __glibcxx_to_array 201907L
@@ -1226,7 +1231,7 @@
#endif /* !defined(__cpp_lib_to_array) && defined(__glibcxx_want_to_array) */
#undef __glibcxx_want_to_array
-// from version.def line 1005
+// from version.def line 1010
#if !defined(__cpp_lib_type_identity)
# if (__cplusplus >= 202002L)
# define __glibcxx_type_identity 201806L
@@ -1237,7 +1242,7 @@
#endif /* !defined(__cpp_lib_type_identity) && defined(__glibcxx_want_type_identity) */
#undef __glibcxx_want_type_identity
-// from version.def line 1013
+// from version.def line 1018
#if !defined(__cpp_lib_unwrap_ref)
# if (__cplusplus >= 202002L)
# define __glibcxx_unwrap_ref 201811L
@@ -1248,7 +1253,7 @@
#endif /* !defined(__cpp_lib_unwrap_ref) && defined(__glibcxx_want_unwrap_ref) */
#undef __glibcxx_want_unwrap_ref
-// from version.def line 1021
+// from version.def line 1026
#if !defined(__cpp_lib_constexpr_iterator)
# if (__cplusplus >= 202002L)
# define __glibcxx_constexpr_iterator 201811L
@@ -1259,7 +1264,7 @@
#endif /* !defined(__cpp_lib_constexpr_iterator) && defined(__glibcxx_want_constexpr_iterator) */
#undef __glibcxx_want_constexpr_iterator
-// from version.def line 1029
+// from version.def line 1034
#if !defined(__cpp_lib_interpolate)
# if (__cplusplus >= 202002L)
# define __glibcxx_interpolate 201902L
@@ -1270,7 +1275,7 @@
#endif /* !defined(__cpp_lib_interpolate) && defined(__glibcxx_want_interpolate) */
#undef __glibcxx_want_interpolate
-// from version.def line 1037
+// from version.def line 1042
#if !defined(__cpp_lib_constexpr_utility)
# if (__cplusplus >= 202002L)
# define __glibcxx_constexpr_utility 201811L
@@ -1281,7 +1286,7 @@
#endif /* !defined(__cpp_lib_constexpr_utility) && defined(__glibcxx_want_constexpr_utility) */
#undef __glibcxx_want_constexpr_utility
-// from version.def line 1045
+// from version.def line 1050
#if !defined(__cpp_lib_shift)
# if (__cplusplus >= 202002L)
# define __glibcxx_shift 201806L
@@ -1292,7 +1297,7 @@
#endif /* !defined(__cpp_lib_shift) && defined(__glibcxx_want_shift) */
#undef __glibcxx_want_shift
-// from version.def line 1053
+// from version.def line 1058
#if !defined(__cpp_lib_ranges)
# if (__cplusplus >= 202100L) && (__glibcxx_concepts)
# define __glibcxx_ranges 202211L
@@ -1308,7 +1313,7 @@
#endif /* !defined(__cpp_lib_ranges) && defined(__glibcxx_want_ranges) */
#undef __glibcxx_want_ranges
-// from version.def line 1067
+// from version.def line 1072
#if !defined(__cpp_lib_constexpr_numeric)
# if (__cplusplus >= 202002L)
# define __glibcxx_constexpr_numeric 201911L
@@ -1319,7 +1324,7 @@
#endif /* !defined(__cpp_lib_constexpr_numeric) && defined(__glibcxx_want_constexpr_numeric) */
#undef __glibcxx_want_constexpr_numeric
-// from version.def line 1075
+// from version.def line 1080
#if !defined(__cpp_lib_constexpr_functional)
# if (__cplusplus >= 202002L)
# define __glibcxx_constexpr_functional 201907L
@@ -1330,7 +1335,7 @@
#endif /* !defined(__cpp_lib_constexpr_functional) && defined(__glibcxx_want_constexpr_functional) */
#undef __glibcxx_want_constexpr_functional
-// from version.def line 1083
+// from version.def line 1088
#if !defined(__cpp_lib_constexpr_algorithms)
# if (__cplusplus >= 202002L)
# define __glibcxx_constexpr_algorithms 201806L
@@ -1341,7 +1346,7 @@
#endif /* !defined(__cpp_lib_constexpr_algorithms) && defined(__glibcxx_want_constexpr_algorithms) */
#undef __glibcxx_want_constexpr_algorithms
-// from version.def line 1091
+// from version.def line 1096
#if !defined(__cpp_lib_constexpr_tuple)
# if (__cplusplus >= 202002L)
# define __glibcxx_constexpr_tuple 201811L
@@ -1352,7 +1357,7 @@
#endif /* !defined(__cpp_lib_constexpr_tuple) && defined(__glibcxx_want_constexpr_tuple) */
#undef __glibcxx_want_constexpr_tuple
-// from version.def line 1099
+// from version.def line 1104
#if !defined(__cpp_lib_constexpr_memory)
# if (__cplusplus >= 202100L) && (__cpp_constexpr_dynamic_alloc)
# define __glibcxx_constexpr_memory 202202L
@@ -1368,7 +1373,7 @@
#endif /* !defined(__cpp_lib_constexpr_memory) && defined(__glibcxx_want_constexpr_memory) */
#undef __glibcxx_want_constexpr_memory
-// from version.def line 1112
+// from version.def line 1117
#if !defined(__cpp_lib_atomic_shared_ptr)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_atomic_shared_ptr 201711L
@@ -1379,7 +1384,7 @@
#endif /* !defined(__cpp_lib_atomic_shared_ptr) && defined(__glibcxx_want_atomic_shared_ptr) */
#undef __glibcxx_want_atomic_shared_ptr
-// from version.def line 1121
+// from version.def line 1126
#if !defined(__cpp_lib_atomic_wait)
# if (__cplusplus >= 202002L) && defined(_GLIBCXX_HAS_GTHREADS) && _GLIBCXX_HOSTED
# define __glibcxx_atomic_wait 201907L
@@ -1395,7 +1400,7 @@
#endif /* !defined(__cpp_lib_atomic_wait) && defined(__glibcxx_want_atomic_wait) */
#undef __glibcxx_want_atomic_wait
-// from version.def line 1139
+// from version.def line 1144
#if !defined(__cpp_lib_barrier)
# if (__cplusplus >= 202002L) && (__cpp_aligned_new && __glibcxx_atomic_wait)
# define __glibcxx_barrier 201907L
@@ -1406,7 +1411,7 @@
#endif /* !defined(__cpp_lib_barrier) && defined(__glibcxx_want_barrier) */
#undef __glibcxx_want_barrier
-// from version.def line 1156
+// from version.def line 1161
#if !defined(__cpp_lib_format)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_format 202106L
@@ -1417,7 +1422,7 @@
#endif /* !defined(__cpp_lib_format) && defined(__glibcxx_want_format) */
#undef __glibcxx_want_format
-// from version.def line 1169
+// from version.def line 1174
#if !defined(__cpp_lib_constexpr_complex)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_constexpr_complex 201711L
@@ -1428,7 +1433,7 @@
#endif /* !defined(__cpp_lib_constexpr_complex) && defined(__glibcxx_want_constexpr_complex) */
#undef __glibcxx_want_constexpr_complex
-// from version.def line 1178
+// from version.def line 1183
#if !defined(__cpp_lib_constexpr_dynamic_alloc)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_constexpr_dynamic_alloc 201907L
@@ -1439,7 +1444,7 @@
#endif /* !defined(__cpp_lib_constexpr_dynamic_alloc) && defined(__glibcxx_want_constexpr_dynamic_alloc) */
#undef __glibcxx_want_constexpr_dynamic_alloc
-// from version.def line 1187
+// from version.def line 1192
#if !defined(__cpp_lib_constexpr_string)
# if (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED && (defined(__glibcxx_is_constant_evaluated))
# define __glibcxx_constexpr_string 201907L
@@ -1460,7 +1465,7 @@
#endif /* !defined(__cpp_lib_constexpr_string) && defined(__glibcxx_want_constexpr_string) */
#undef __glibcxx_want_constexpr_string
-// from version.def line 1211
+// from version.def line 1216
#if !defined(__cpp_lib_constexpr_vector)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_constexpr_vector 201907L
@@ -1471,7 +1476,7 @@
#endif /* !defined(__cpp_lib_constexpr_vector) && defined(__glibcxx_want_constexpr_vector) */
#undef __glibcxx_want_constexpr_vector
-// from version.def line 1220
+// from version.def line 1225
#if !defined(__cpp_lib_erase_if)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_erase_if 202002L
@@ -1482,7 +1487,7 @@
#endif /* !defined(__cpp_lib_erase_if) && defined(__glibcxx_want_erase_if) */
#undef __glibcxx_want_erase_if
-// from version.def line 1229
+// from version.def line 1234
#if !defined(__cpp_lib_generic_unordered_lookup)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_generic_unordered_lookup 201811L
@@ -1493,7 +1498,7 @@
#endif /* !defined(__cpp_lib_generic_unordered_lookup) && defined(__glibcxx_want_generic_unordered_lookup) */
#undef __glibcxx_want_generic_unordered_lookup
-// from version.def line 1238
+// from version.def line 1243
#if !defined(__cpp_lib_jthread)
# if (__cplusplus >= 202002L) && defined(_GLIBCXX_HAS_GTHREADS) && _GLIBCXX_HOSTED
# define __glibcxx_jthread 201911L
@@ -1504,7 +1509,7 @@
#endif /* !defined(__cpp_lib_jthread) && defined(__glibcxx_want_jthread) */
#undef __glibcxx_want_jthread
-// from version.def line 1248
+// from version.def line 1253
#if !defined(__cpp_lib_latch)
# if (__cplusplus >= 202002L) && (__glibcxx_atomic_wait)
# define __glibcxx_latch 201907L
@@ -1515,7 +1520,7 @@
#endif /* !defined(__cpp_lib_latch) && defined(__glibcxx_want_latch) */
#undef __glibcxx_want_latch
-// from version.def line 1257
+// from version.def line 1262
#if !defined(__cpp_lib_list_remove_return_type)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_list_remove_return_type 201806L
@@ -1526,7 +1531,7 @@
#endif /* !defined(__cpp_lib_list_remove_return_type) && defined(__glibcxx_want_list_remove_return_type) */
#undef __glibcxx_want_list_remove_return_type
-// from version.def line 1266
+// from version.def line 1271
#if !defined(__cpp_lib_polymorphic_allocator)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_polymorphic_allocator 201902L
@@ -1537,7 +1542,7 @@
#endif /* !defined(__cpp_lib_polymorphic_allocator) && defined(__glibcxx_want_polymorphic_allocator) */
#undef __glibcxx_want_polymorphic_allocator
-// from version.def line 1275
+// from version.def line 1280
#if !defined(__cpp_lib_move_iterator_concept)
# if (__cplusplus >= 202002L) && (__glibcxx_concepts)
# define __glibcxx_move_iterator_concept 202207L
@@ -1548,7 +1553,7 @@
#endif /* !defined(__cpp_lib_move_iterator_concept) && defined(__glibcxx_want_move_iterator_concept) */
#undef __glibcxx_want_move_iterator_concept
-// from version.def line 1285
+// from version.def line 1290
#if !defined(__cpp_lib_semaphore)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED && (__glibcxx_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE)
# define __glibcxx_semaphore 201907L
@@ -1559,7 +1564,7 @@
#endif /* !defined(__cpp_lib_semaphore) && defined(__glibcxx_want_semaphore) */
#undef __glibcxx_want_semaphore
-// from version.def line 1295
+// from version.def line 1300
#if !defined(__cpp_lib_smart_ptr_for_overwrite)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_smart_ptr_for_overwrite 202002L
@@ -1570,7 +1575,7 @@
#endif /* !defined(__cpp_lib_smart_ptr_for_overwrite) && defined(__glibcxx_want_smart_ptr_for_overwrite) */
#undef __glibcxx_want_smart_ptr_for_overwrite
-// from version.def line 1304
+// from version.def line 1309
#if !defined(__cpp_lib_syncbuf)
# if (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED
# define __glibcxx_syncbuf 201803L
@@ -1581,7 +1586,7 @@
#endif /* !defined(__cpp_lib_syncbuf) && defined(__glibcxx_want_syncbuf) */
#undef __glibcxx_want_syncbuf
-// from version.def line 1314
+// from version.def line 1319
#if !defined(__cpp_lib_byteswap)
# if (__cplusplus >= 202100L)
# define __glibcxx_byteswap 202110L
@@ -1592,7 +1597,7 @@
#endif /* !defined(__cpp_lib_byteswap) && defined(__glibcxx_want_byteswap) */
#undef __glibcxx_want_byteswap
-// from version.def line 1322
+// from version.def line 1327
#if !defined(__cpp_lib_constexpr_charconv)
# if (__cplusplus >= 202100L)
# define __glibcxx_constexpr_charconv 202207L
@@ -1603,7 +1608,7 @@
#endif /* !defined(__cpp_lib_constexpr_charconv) && defined(__glibcxx_want_constexpr_charconv) */
#undef __glibcxx_want_constexpr_charconv
-// from version.def line 1330
+// from version.def line 1335
#if !defined(__cpp_lib_constexpr_typeinfo)
# if (__cplusplus >= 202100L)
# define __glibcxx_constexpr_typeinfo 202106L
@@ -1614,7 +1619,7 @@
#endif /* !defined(__cpp_lib_constexpr_typeinfo) && defined(__glibcxx_want_constexpr_typeinfo) */
#undef __glibcxx_want_constexpr_typeinfo
-// from version.def line 1338
+// from version.def line 1343
#if !defined(__cpp_lib_expected)
# if (__cplusplus >= 202100L) && (__cpp_concepts >= 202002L)
# define __glibcxx_expected 202211L
@@ -1625,7 +1630,84 @@
#endif /* !defined(__cpp_lib_expected) && defined(__glibcxx_want_expected) */
#undef __glibcxx_want_expected
-// from version.def line 1347
+// from version.def line 1352
+#if !defined(__cpp_lib_freestanding_algorithm)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_freestanding_algorithm 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_freestanding_algorithm)
+# define __cpp_lib_freestanding_algorithm 202311L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_freestanding_algorithm) && defined(__glibcxx_want_freestanding_algorithm) */
+#undef __glibcxx_want_freestanding_algorithm
+
+// from version.def line 1361
+#if !defined(__cpp_lib_freestanding_array)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_freestanding_array 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_freestanding_array)
+# define __cpp_lib_freestanding_array 202311L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_freestanding_array) && defined(__glibcxx_want_freestanding_array) */
+#undef __glibcxx_want_freestanding_array
+
+// from version.def line 1370
+#if !defined(__cpp_lib_freestanding_cstring)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_freestanding_cstring 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_freestanding_cstring)
+# define __cpp_lib_freestanding_cstring 202311L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_freestanding_cstring) && defined(__glibcxx_want_freestanding_cstring) */
+#undef __glibcxx_want_freestanding_cstring
+
+// from version.def line 1379
+#if !defined(__cpp_lib_freestanding_expected)
+# if (__cplusplus >= 202100L) && (__cpp_lib_expected)
+# define __glibcxx_freestanding_expected 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_freestanding_expected)
+# define __cpp_lib_freestanding_expected 202311L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_freestanding_expected) && defined(__glibcxx_want_freestanding_expected) */
+#undef __glibcxx_want_freestanding_expected
+
+// from version.def line 1389
+#if !defined(__cpp_lib_freestanding_optional)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_freestanding_optional 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_freestanding_optional)
+# define __cpp_lib_freestanding_optional 202311L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_freestanding_optional) && defined(__glibcxx_want_freestanding_optional) */
+#undef __glibcxx_want_freestanding_optional
+
+// from version.def line 1398
+#if !defined(__cpp_lib_freestanding_string_view)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_freestanding_string_view 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_freestanding_string_view)
+# define __cpp_lib_freestanding_string_view 202311L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_freestanding_string_view) && defined(__glibcxx_want_freestanding_string_view) */
+#undef __glibcxx_want_freestanding_string_view
+
+// from version.def line 1407
+#if !defined(__cpp_lib_freestanding_variant)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_freestanding_variant 202311L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_freestanding_variant)
+# define __cpp_lib_freestanding_variant 202311L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_freestanding_variant) && defined(__glibcxx_want_freestanding_variant) */
+#undef __glibcxx_want_freestanding_variant
+
+// from version.def line 1416
#if !defined(__cpp_lib_invoke_r)
# if (__cplusplus >= 202100L)
# define __glibcxx_invoke_r 202106L
@@ -1636,7 +1718,7 @@
#endif /* !defined(__cpp_lib_invoke_r) && defined(__glibcxx_want_invoke_r) */
#undef __glibcxx_want_invoke_r
-// from version.def line 1355
+// from version.def line 1424
#if !defined(__cpp_lib_is_scoped_enum)
# if (__cplusplus >= 202100L)
# define __glibcxx_is_scoped_enum 202011L
@@ -1647,7 +1729,7 @@
#endif /* !defined(__cpp_lib_is_scoped_enum) && defined(__glibcxx_want_is_scoped_enum) */
#undef __glibcxx_want_is_scoped_enum
-// from version.def line 1363
+// from version.def line 1432
#if !defined(__cpp_lib_reference_from_temporary)
# if (__cplusplus >= 202100L) && (__has_builtin(__reference_constructs_from_temporary) && __has_builtin(__reference_converts_from_temporary))
# define __glibcxx_reference_from_temporary 202202L
@@ -1658,29 +1740,18 @@
#endif /* !defined(__cpp_lib_reference_from_temporary) && defined(__glibcxx_want_reference_from_temporary) */
#undef __glibcxx_want_reference_from_temporary
-// from version.def line 1374
-#if !defined(__cpp_lib_to_underlying)
-# if (__cplusplus >= 202100L)
-# define __glibcxx_to_underlying 202102L
-# if defined(__glibcxx_want_all) || defined(__glibcxx_want_to_underlying)
-# define __cpp_lib_to_underlying 202102L
-# endif
-# endif
-#endif /* !defined(__cpp_lib_to_underlying) && defined(__glibcxx_want_to_underlying) */
-#undef __glibcxx_want_to_underlying
-
-// from version.def line 1382
-#if !defined(__cpp_lib_unreachable)
-# if (__cplusplus >= 202100L)
-# define __glibcxx_unreachable 202202L
-# if defined(__glibcxx_want_all) || defined(__glibcxx_want_unreachable)
-# define __cpp_lib_unreachable 202202L
+// from version.def line 1452
+#if !defined(__cpp_lib_ranges_to_container)
+# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
+# define __glibcxx_ranges_to_container 202202L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges_to_container)
+# define __cpp_lib_ranges_to_container 202202L
# endif
# endif
-#endif /* !defined(__cpp_lib_unreachable) && defined(__glibcxx_want_unreachable) */
-#undef __glibcxx_want_unreachable
+#endif /* !defined(__cpp_lib_ranges_to_container) && defined(__glibcxx_want_ranges_to_container) */
+#undef __glibcxx_want_ranges_to_container
-// from version.def line 1390
+// from version.def line 1461
#if !defined(__cpp_lib_ranges_zip)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_zip 202110L
@@ -1691,7 +1762,7 @@
#endif /* !defined(__cpp_lib_ranges_zip) && defined(__glibcxx_want_ranges_zip) */
#undef __glibcxx_want_ranges_zip
-// from version.def line 1398
+// from version.def line 1469
#if !defined(__cpp_lib_ranges_chunk)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_chunk 202202L
@@ -1702,7 +1773,7 @@
#endif /* !defined(__cpp_lib_ranges_chunk) && defined(__glibcxx_want_ranges_chunk) */
#undef __glibcxx_want_ranges_chunk
-// from version.def line 1406
+// from version.def line 1477
#if !defined(__cpp_lib_ranges_slide)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_slide 202202L
@@ -1713,7 +1784,7 @@
#endif /* !defined(__cpp_lib_ranges_slide) && defined(__glibcxx_want_ranges_slide) */
#undef __glibcxx_want_ranges_slide
-// from version.def line 1414
+// from version.def line 1485
#if !defined(__cpp_lib_ranges_chunk_by)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_chunk_by 202202L
@@ -1724,7 +1795,7 @@
#endif /* !defined(__cpp_lib_ranges_chunk_by) && defined(__glibcxx_want_ranges_chunk_by) */
#undef __glibcxx_want_ranges_chunk_by
-// from version.def line 1422
+// from version.def line 1493
#if !defined(__cpp_lib_ranges_join_with)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_join_with 202202L
@@ -1735,7 +1806,7 @@
#endif /* !defined(__cpp_lib_ranges_join_with) && defined(__glibcxx_want_ranges_join_with) */
#undef __glibcxx_want_ranges_join_with
-// from version.def line 1430
+// from version.def line 1501
#if !defined(__cpp_lib_ranges_repeat)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_repeat 202207L
@@ -1746,7 +1817,7 @@
#endif /* !defined(__cpp_lib_ranges_repeat) && defined(__glibcxx_want_ranges_repeat) */
#undef __glibcxx_want_ranges_repeat
-// from version.def line 1438
+// from version.def line 1509
#if !defined(__cpp_lib_ranges_stride)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_stride 202207L
@@ -1757,7 +1828,7 @@
#endif /* !defined(__cpp_lib_ranges_stride) && defined(__glibcxx_want_ranges_stride) */
#undef __glibcxx_want_ranges_stride
-// from version.def line 1446
+// from version.def line 1517
#if !defined(__cpp_lib_ranges_cartesian_product)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_cartesian_product 202207L
@@ -1768,7 +1839,7 @@
#endif /* !defined(__cpp_lib_ranges_cartesian_product) && defined(__glibcxx_want_ranges_cartesian_product) */
#undef __glibcxx_want_ranges_cartesian_product
-// from version.def line 1454
+// from version.def line 1525
#if !defined(__cpp_lib_ranges_as_rvalue)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_as_rvalue 202207L
@@ -1779,7 +1850,7 @@
#endif /* !defined(__cpp_lib_ranges_as_rvalue) && defined(__glibcxx_want_ranges_as_rvalue) */
#undef __glibcxx_want_ranges_as_rvalue
-// from version.def line 1462
+// from version.def line 1533
#if !defined(__cpp_lib_ranges_as_const)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_as_const 202207L
@@ -1790,7 +1861,7 @@
#endif /* !defined(__cpp_lib_ranges_as_const) && defined(__glibcxx_want_ranges_as_const) */
#undef __glibcxx_want_ranges_as_const
-// from version.def line 1470
+// from version.def line 1541
#if !defined(__cpp_lib_ranges_enumerate)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_enumerate 202302L
@@ -1801,7 +1872,7 @@
#endif /* !defined(__cpp_lib_ranges_enumerate) && defined(__glibcxx_want_ranges_enumerate) */
#undef __glibcxx_want_ranges_enumerate
-// from version.def line 1478
+// from version.def line 1549
#if !defined(__cpp_lib_ranges_fold)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_fold 202207L
@@ -1812,7 +1883,7 @@
#endif /* !defined(__cpp_lib_ranges_fold) && defined(__glibcxx_want_ranges_fold) */
#undef __glibcxx_want_ranges_fold
-// from version.def line 1486
+// from version.def line 1557
#if !defined(__cpp_lib_ranges_contains)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_contains 202207L
@@ -1823,7 +1894,7 @@
#endif /* !defined(__cpp_lib_ranges_contains) && defined(__glibcxx_want_ranges_contains) */
#undef __glibcxx_want_ranges_contains
-// from version.def line 1494
+// from version.def line 1565
#if !defined(__cpp_lib_ranges_iota)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_iota 202202L
@@ -1834,7 +1905,7 @@
#endif /* !defined(__cpp_lib_ranges_iota) && defined(__glibcxx_want_ranges_iota) */
#undef __glibcxx_want_ranges_iota
-// from version.def line 1502
+// from version.def line 1573
#if !defined(__cpp_lib_ranges_find_last)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_find_last 202207L
@@ -1845,7 +1916,7 @@
#endif /* !defined(__cpp_lib_ranges_find_last) && defined(__glibcxx_want_ranges_find_last) */
#undef __glibcxx_want_ranges_find_last
-// from version.def line 1510
+// from version.def line 1581
#if !defined(__cpp_lib_constexpr_bitset)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (__cpp_constexpr_dynamic_alloc)
# define __glibcxx_constexpr_bitset 202202L
@@ -1856,7 +1927,7 @@
#endif /* !defined(__cpp_lib_constexpr_bitset) && defined(__glibcxx_want_constexpr_bitset) */
#undef __glibcxx_want_constexpr_bitset
-// from version.def line 1520
+// from version.def line 1591
#if !defined(__cpp_lib_stdatomic_h)
# if (__cplusplus >= 202100L)
# define __glibcxx_stdatomic_h 202011L
@@ -1867,7 +1938,7 @@
#endif /* !defined(__cpp_lib_stdatomic_h) && defined(__glibcxx_want_stdatomic_h) */
#undef __glibcxx_want_stdatomic_h
-// from version.def line 1528
+// from version.def line 1599
#if !defined(__cpp_lib_adaptor_iterator_pair_constructor)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
# define __glibcxx_adaptor_iterator_pair_constructor 202106L
@@ -1878,7 +1949,7 @@
#endif /* !defined(__cpp_lib_adaptor_iterator_pair_constructor) && defined(__glibcxx_want_adaptor_iterator_pair_constructor) */
#undef __glibcxx_want_adaptor_iterator_pair_constructor
-// from version.def line 1537
+// from version.def line 1608
#if !defined(__cpp_lib_formatters)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
# define __glibcxx_formatters 202302L
@@ -1889,7 +1960,7 @@
#endif /* !defined(__cpp_lib_formatters) && defined(__glibcxx_want_formatters) */
#undef __glibcxx_want_formatters
-// from version.def line 1546
+// from version.def line 1617
#if !defined(__cpp_lib_forward_like)
# if (__cplusplus >= 202100L)
# define __glibcxx_forward_like 202207L
@@ -1900,7 +1971,7 @@
#endif /* !defined(__cpp_lib_forward_like) && defined(__glibcxx_want_forward_like) */
#undef __glibcxx_want_forward_like
-// from version.def line 1554
+// from version.def line 1625
#if !defined(__cpp_lib_ios_noreplace)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
# define __glibcxx_ios_noreplace 202207L
@@ -1911,7 +1982,7 @@
#endif /* !defined(__cpp_lib_ios_noreplace) && defined(__glibcxx_want_ios_noreplace) */
#undef __glibcxx_want_ios_noreplace
-// from version.def line 1563
+// from version.def line 1634
#if !defined(__cpp_lib_move_only_function)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
# define __glibcxx_move_only_function 202110L
@@ -1922,18 +1993,18 @@
#endif /* !defined(__cpp_lib_move_only_function) && defined(__glibcxx_want_move_only_function) */
#undef __glibcxx_want_move_only_function
-// from version.def line 1572
+// from version.def line 1643
#if !defined(__cpp_lib_out_ptr)
# if (__cplusplus >= 202100L)
-# define __glibcxx_out_ptr 202106L
+# define __glibcxx_out_ptr 202311L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_out_ptr)
-# define __cpp_lib_out_ptr 202106L
+# define __cpp_lib_out_ptr 202311L
# endif
# endif
#endif /* !defined(__cpp_lib_out_ptr) && defined(__glibcxx_want_out_ptr) */
#undef __glibcxx_want_out_ptr
-// from version.def line 1580
+// from version.def line 1651
#if !defined(__cpp_lib_spanstream)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (__glibcxx_span)
# define __glibcxx_spanstream 202106L
@@ -1944,7 +2015,7 @@
#endif /* !defined(__cpp_lib_spanstream) && defined(__glibcxx_want_spanstream) */
#undef __glibcxx_want_spanstream
-// from version.def line 1590
+// from version.def line 1661
#if !defined(__cpp_lib_stacktrace)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (_GLIBCXX_HAVE_STACKTRACE)
# define __glibcxx_stacktrace 202011L
@@ -1955,7 +2026,7 @@
#endif /* !defined(__cpp_lib_stacktrace) && defined(__glibcxx_want_stacktrace) */
#undef __glibcxx_want_stacktrace
-// from version.def line 1600
+// from version.def line 1671
#if !defined(__cpp_lib_string_contains)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
# define __glibcxx_string_contains 202011L
@@ -1966,7 +2037,7 @@
#endif /* !defined(__cpp_lib_string_contains) && defined(__glibcxx_want_string_contains) */
#undef __glibcxx_want_string_contains
-// from version.def line 1609
+// from version.def line 1680
#if !defined(__cpp_lib_string_resize_and_overwrite)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
# define __glibcxx_string_resize_and_overwrite 202110L
@@ -1977,7 +2048,29 @@
#endif /* !defined(__cpp_lib_string_resize_and_overwrite) && defined(__glibcxx_want_string_resize_and_overwrite) */
#undef __glibcxx_want_string_resize_and_overwrite
-// from version.def line 1618
+// from version.def line 1689
+#if !defined(__cpp_lib_to_underlying)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_to_underlying 202102L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_to_underlying)
+# define __cpp_lib_to_underlying 202102L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_to_underlying) && defined(__glibcxx_want_to_underlying) */
+#undef __glibcxx_want_to_underlying
+
+// from version.def line 1697
+#if !defined(__cpp_lib_unreachable)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_unreachable 202202L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_unreachable)
+# define __cpp_lib_unreachable 202202L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_unreachable) && defined(__glibcxx_want_unreachable) */
+#undef __glibcxx_want_unreachable
+
+// from version.def line 1705
#if !defined(__cpp_lib_fstream_native_handle)
# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED
# define __glibcxx_fstream_native_handle 202306L
@@ -1988,7 +2081,7 @@
#endif /* !defined(__cpp_lib_fstream_native_handle) && defined(__glibcxx_want_fstream_native_handle) */
#undef __glibcxx_want_fstream_native_handle
-// from version.def line 1627
+// from version.def line 1714
#if !defined(__cpp_lib_ratio)
# if (__cplusplus > 202302L)
# define __glibcxx_ratio 202306L
@@ -1999,7 +2092,7 @@
#endif /* !defined(__cpp_lib_ratio) && defined(__glibcxx_want_ratio) */
#undef __glibcxx_want_ratio
-// from version.def line 1635
+// from version.def line 1722
#if !defined(__cpp_lib_saturation_arithmetic)
# if (__cplusplus > 202302L)
# define __glibcxx_saturation_arithmetic 202311L
@@ -2010,7 +2103,7 @@
#endif /* !defined(__cpp_lib_saturation_arithmetic) && defined(__glibcxx_want_saturation_arithmetic) */
#undef __glibcxx_want_saturation_arithmetic
-// from version.def line 1643
+// from version.def line 1730
#if !defined(__cpp_lib_to_string)
# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED && (__glibcxx_to_chars)
# define __glibcxx_to_string 202306L
diff --git a/libstdc++-v3/include/c_compatibility/string.h b/libstdc++-v3/include/c_compatibility/string.h
index 1d9e0d2..06529af 100644
--- a/libstdc++-v3/include/c_compatibility/string.h
+++ b/libstdc++-v3/include/c_compatibility/string.h
@@ -50,7 +50,9 @@ using std::strpbrk;
using std::strrchr;
using std::strspn;
using std::strstr;
+#if _GLIBCXX_HOSTED || __cplusplus <= 202302L
using std::strtok;
+#endif
using std::memset;
using std::strerror;
using std::strlen;
diff --git a/libstdc++-v3/include/c_global/cstring b/libstdc++-v3/include/c_global/cstring
index d0a129a..f39aae1 100644
--- a/libstdc++-v3/include/c_global/cstring
+++ b/libstdc++-v3/include/c_global/cstring
@@ -38,7 +38,8 @@
#pragma GCC system_header
-#include <bits/c++config.h>
+#define __glibcxx_want_freestanding_cstring
+#include <bits/version.h>
#include <string.h>
#ifndef _GLIBCXX_CSTRING
@@ -90,7 +91,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::strncmp;
using ::strncpy;
using ::strspn;
+#if _GLIBCXX_HOSTED || __cplusplus <= 202302L
using ::strtok;
+#endif
using ::strxfrm;
using ::strchr;
using ::strpbrk;
diff --git a/libstdc++-v3/include/std/algorithm b/libstdc++-v3/include/std/algorithm
index d7fab41..40aff50 100644
--- a/libstdc++-v3/include/std/algorithm
+++ b/libstdc++-v3/include/std/algorithm
@@ -65,6 +65,7 @@
#define __glibcxx_want_clamp
#define __glibcxx_want_constexpr_algorithms
+#define __glibcxx_want_freestanding_algorithm
#define __glibcxx_want_parallel_algorithm
#define __glibcxx_want_ranges_contains
#define __glibcxx_want_ranges_find_last
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index d34ec5c..ddc15b6 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -46,6 +46,7 @@
#include <debug/assertions.h>
#define __glibcxx_want_array_constexpr
+#define __glibcxx_want_freestanding_array
#define __glibcxx_want_nonmember_container_access
#define __glibcxx_want_to_array
#include <bits/version.h>
diff --git a/libstdc++-v3/include/std/expected b/libstdc++-v3/include/std/expected
index a176d4c..86026c3 100644
--- a/libstdc++-v3/include/std/expected
+++ b/libstdc++-v3/include/std/expected
@@ -32,6 +32,7 @@
#pragma GCC system_header
#define __glibcxx_want_expected
+#define __glibcxx_want_freestanding_expected
#include <bits/version.h>
#ifdef __cpp_lib_expected // C++ >= 23 && __cpp_concepts >= 202002L
diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional
index a8c9771..937486f 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -32,6 +32,7 @@
#pragma GCC system_header
+#define __glibcxx_want_freestanding_optional
#define __glibcxx_want_optional
#include <bits/version.h>
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 26d6c01..63bea86 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -64,6 +64,7 @@
#define __glibcxx_want_ranges_repeat
#define __glibcxx_want_ranges_slide
#define __glibcxx_want_ranges_stride
+#define __glibcxx_want_ranges_to_container
#define __glibcxx_want_ranges_zip
#include <bits/version.h>
@@ -9213,8 +9214,366 @@ namespace views::__adaptor
namespace views = ranges::views;
+#if __cpp_lib_ranges_to_container // C++ >= 23
+namespace ranges
+{
+/// @cond undocumented
+namespace __detail
+{
+ template<typename _Container>
+ constexpr bool __reservable_container
+ = sized_range<_Container>
+ && requires(_Container& __c, range_size_t<_Container> __n) {
+ __c.reserve(__n);
+ { __c.capacity() } -> same_as<decltype(__n)>;
+ { __c.max_size() } -> same_as<decltype(__n)>;
+ };
+
+ template<typename _Container, typename _Ref>
+ constexpr bool __container_insertable
+ = requires(_Container& __c, _Ref&& __ref) {
+ typename _Container::value_type;
+ requires (
+ requires { __c.push_back(std::forward<_Ref>(__ref)); }
+ || requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); }
+ );
+ };
+
+ template<typename _Ref, typename _Container>
+ constexpr auto
+ __container_inserter(_Container& __c)
+ {
+ if constexpr (requires { __c.push_back(std::declval<_Ref>()); })
+ return std::back_inserter(__c);
+ else
+ return std::inserter(__c, __c.end());
+ }
+
+ template<typename _Cont, typename _Range>
+ constexpr bool __toable = requires {
+ requires (!input_range<_Range>
+ || convertible_to<range_reference_t<_Range>,
+ range_value_t<_Cont>>);
+ };
+} // namespace __detail
+/// @endcond
+
+ /// Convert a range to a container.
+ /**
+ * @tparam _Cont A container type.
+ * @param __r A range that models the `input_range` concept.
+ * @param __args... Arguments to pass to the container constructor.
+ * @since C++23
+ *
+ * This function converts a range to the `_Cont` type.
+ *
+ * For example, `std::ranges::to<std::vector<int>>(some_view)`
+ * will convert the view to `std::vector<int>`.
+ *
+ * Additional constructor arguments for the container can be supplied after
+ * the input range argument, e.g.
+ * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
+ */
+ template<typename _Cont, input_range _Rg, typename... _Args>
+ requires (!view<_Cont>)
+ constexpr _Cont
+ to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
+ {
+ static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
+ static_assert(is_class_v<_Cont>);
+
+ if constexpr (__detail::__toable<_Cont, _Rg>)
+ {
+ if constexpr (constructible_from<_Cont, _Rg, _Args...>)
+ return _Cont(std::forward<_Rg>(__r),
+ std::forward<_Args>(__args)...);
+ else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
+ return _Cont(from_range, std::forward<_Rg>(__r),
+ std::forward<_Args>(__args)...);
+ else if constexpr (requires { common_range<_Rg>;
+ typename __iter_category_t<iterator_t<_Rg>>;
+ requires derived_from<__iter_category_t<iterator_t<_Rg>>,
+ input_iterator_tag>;
+ requires constructible_from<_Cont, iterator_t<_Rg>,
+ sentinel_t<_Rg>, _Args...>;
+ })
+ return _Cont(ranges::begin(__r), ranges::end(__r),
+ std::forward<_Args>(__args)...);
+ else
+ {
+ using __detail::__container_insertable;
+ using __detail::__reservable_container;
+ using _RefT = range_reference_t<_Rg>;
+ static_assert(constructible_from<_Cont, _Args...>);
+ static_assert(__container_insertable<_Cont, _RefT>);
+ _Cont __c(std::forward<_Args>(__args)...);
+ if constexpr (sized_range<_Rg> && __reservable_container<_Cont>)
+ __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
+ auto __ins = __detail::__container_inserter<_RefT>(__c);
+ for (auto&& __e : __r)
+ *__ins++ = std::forward<decltype(__e)>(__e);
+ return __c;
+ }
+ }
+ else
+ {
+ static_assert(input_range<range_reference_t<_Rg>>);
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3984. ranges::to's recursion branch may be ill-formed
+ return ranges::to<_Cont>(ref_view(__r) | views::transform(
+ []<typename _Elt>(_Elt&& __elem) {
+ using _ValT = range_value_t<_Cont>;
+ return ranges::to<_ValT>(std::forward<_Elt>(__elem));
+ }), std::forward<_Args>(__args)...);
+ }
+ }
+
+/// @cond undocumented
+namespace __detail
+{
+ template<typename _Rg>
+ struct _InputIter
+ {
+ using iterator_category = input_iterator_tag;
+ using value_type = range_value_t<_Rg>;
+ using difference_type = ptrdiff_t;
+ using pointer = add_pointer_t<range_reference_t<_Rg>>;
+ using reference = range_reference_t<_Rg>;
+ reference operator*() const;
+ pointer operator->() const;
+ _InputIter& operator++();
+ _InputIter operator++(int);
+ bool operator==(const _InputIter&) const;
+ };
+
+#if 0
+ template<template<typename...> typename _Cont, typename _Rg,
+ typename... _Args>
+ concept __deduce_expr_1 = requires {
+ _Cont(std::declval<_Rg>(), std::declval<_Args>()...);
+ };
+
+ template<template<typename...> typename _Cont, typename _Rg,
+ typename... _Args>
+ concept __deduce_expr_2 = requires {
+ _Cont(from_range, std::declval<_Rg>(), std::declval<_Args>()...);
+ };
+
+ template<template<typename...> typename _Cont, typename _Rg,
+ typename... _Args>
+ concept __deduce_expr_3 = requires(_InputIter<_Rg> __i) {
+ _Cont(std::move(__i), std::move(__i), std::declval<_Args>()...);
+ };
+#endif
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ using _DeduceExpr1
+ = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ using _DeduceExpr2
+ = decltype(_Cont(from_range, std::declval<_Rg>(),
+ std::declval<_Args>()...));
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ using _DeduceExpr3
+ = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
+ std::declval<_InputIter<_Rg>>(),
+ std::declval<_Args>()...));
+
+} // namespace __detail
+/// @endcond
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ constexpr auto
+ to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
+ {
+ using __detail::_DeduceExpr1;
+ using __detail::_DeduceExpr2;
+ using __detail::_DeduceExpr3;
+ if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
+ return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
+ std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
+ else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
+ return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
+ std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
+ else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
+ return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
+ std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
+ else
+ static_assert(false); // Cannot deduce container specialization.
+ }
+
+/// @cond undocumented
+namespace __detail
+{
+ template<typename _Cont, typename... _Args>
+ class _ToClosure
+ : public views::__adaptor::_RangeAdaptorClosure<_ToClosure<_Cont, _Args...>>
+ {
+ tuple<decay_t<_Args>...> _M_bound_args;
+
+ public:
+ _ToClosure(_Args&&... __args)
+ : _M_bound_args(std::forward<_Args>(__args)...)
+ { }
+
+ // TODO: use explicit object functions ("deducing this").
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+ };
+} // namespace __detail
+/// @endcond
+
+ /// ranges::to adaptor for converting a range to a container type
+ /**
+ * @tparam _Cont A container type.
+ * @param __args... Arguments to pass to the container constructor.
+ * @since C++23
+ *
+ * This range adaptor returns a range adaptor closure object that converts
+ * a range to the `_Cont` type.
+ *
+ * For example, `some_view | std::ranges::to<std::vector<int>>()`
+ * will convert the view to `std::vector<int>`.
+ *
+ * Additional constructor arguments for the container can be supplied, e.g.
+ * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
+ */
+ template<typename _Cont, typename... _Args>
+ requires (!view<_Cont>)
+ constexpr __detail::_ToClosure<_Cont, _Args...>
+ to [[nodiscard]] (_Args&&... __args)
+ { return {std::forward<_Args>(__args)...}; }
+
+/// @cond undocumented
+namespace __detail
+{
+ template<template<typename...> typename _Cont, typename... _Args>
+ class _ToClosure2
+ : public views::__adaptor::_RangeAdaptorClosure<_ToClosure2<_Cont, _Args...>>
+ {
+ tuple<decay_t<_Args>...> _M_bound_args;
+
+ public:
+ _ToClosure2(_Args&&... __args)
+ : _M_bound_args(std::forward<_Args>(__args)...)
+ { }
+
+ // TODO: use explicit object functions ("deducing this").
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+ };
+} // namespace __detail
+/// @endcond
+
+ /// ranges::to adaptor for converting a range to a deduced container type.
+ /**
+ * @tparam _Cont A container template.
+ * @param __args... Arguments to pass to the container constructor.
+ * @since C++23
+ *
+ * This range adaptor returns a range adaptor closure object that converts
+ * a range to a specialization of the `_Cont` class template. The specific
+ * specialization of `_Cont` to be used is deduced automatically.
+ *
+ * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
+ * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
+ * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
+ *
+ * Additional constructor arguments for the container can be supplied, e.g.
+ * `r | std::ranges::to<std::vector>(an_allocator)`.
+ */
+ template<template<typename...> typename _Cont, typename... _Args>
+ constexpr __detail::_ToClosure2<_Cont, _Args...>
+ to [[nodiscard]] (_Args&&... __args)
+ { return {std::forward<_Args>(__args)...}; }
+
+} // namespace ranges
+#endif // __cpp_lib_ranges_to_container
+
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
#endif // library concepts
#endif // C++2a
#endif /* _GLIBCXX_RANGES */
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 90d08f1..57222a5 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -288,6 +288,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
[[nodiscard]]
+ constexpr reference
+ at(size_type __idx) const
+ {
+ if (__idx >= size())
+ __throw_out_of_range_fmt(__N("span::at(%zu) out-of-range for span "
+ "of size %zu"), __idx, this->size());
+ return *(this->_M_ptr + __idx);
+ }
+
+ [[nodiscard]]
constexpr pointer
data() const noexcept
{ return this->_M_ptr; }
diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index cbb6bb0..44d13b4 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -36,8 +36,9 @@
#pragma GCC system_header
#define __glibcxx_want_constexpr_char_traits
-#define __glibcxx_want_string_view
#define __glibcxx_want_constexpr_string_view
+#define __glibcxx_want_freestanding_string_view
+#define __glibcxx_want_string_view
#define __glibcxx_want_starts_ends_with
#define __glibcxx_want_string_contains
#include <bits/version.h>
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 7f24e76..36bb37c 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -31,6 +31,7 @@
#pragma GCC system_header
+#define __glibcxx_want_freestanding_variant
#define __glibcxx_want_variant
#include <bits/version.h>
diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset
index dd2845b..ffdce82 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset
+++ b/libstdc++-v3/include/tr2/dynamic_bitset
@@ -622,7 +622,7 @@ namespace tr2
// Watch for npos.
this->_M_Nb = (__n > __str.size() ? __str.size() - __pos : __n);
this->resize(this->_M_Nb);
- this->_M_copy_from_string(__str, __pos, __n);
+ this->_M_copy_from_string(__str, __pos, __n, __zero, __one);
}
/**
diff --git a/libstdc++-v3/testsuite/20_util/expected/version.cc b/libstdc++-v3/testsuite/20_util/expected/version.cc
index 6deaa68..682835c 100644
--- a/libstdc++-v3/testsuite/20_util/expected/version.cc
+++ b/libstdc++-v3/testsuite/20_util/expected/version.cc
@@ -8,3 +8,25 @@
#elif __cpp_lib_expected != 202211L
# error "Feature-test macro for expected has wrong value in <version>"
#endif
+
+#ifndef __cpp_lib_freestanding_expected
+# error "Feature-test macro for freestanding expected missing in <version>"
+#elif __cpp_lib_freestanding_expected != 202311L
+# error "Feature-test macro for freestanding expected has wrong value in <version>"
+#endif
+
+#undef __cpp_lib_expected
+#undef __cpp_lib_freestanding_expected
+#include <expected>
+
+#ifndef __cpp_lib_expected
+# error "Feature-test macro for expected missing in <expected>"
+#elif __cpp_lib_expected != 202211L
+# error "Feature-test macro for expected has wrong value in <expected>"
+#endif
+
+#ifndef __cpp_lib_freestanding_expected
+# error "Feature-test macro for freestanding expected missing in <expected>"
+#elif __cpp_lib_freestanding_expected != 202311L
+# error "Feature-test macro for freestanding expected has wrong value in <expected>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/optional/version.cc b/libstdc++-v3/testsuite/20_util/optional/version.cc
index 7e63d42..657a399 100644
--- a/libstdc++-v3/testsuite/20_util/optional/version.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/version.cc
@@ -12,3 +12,23 @@
#elif __cplusplus > 202002L && __cpp_lib_optional != 202110L
# error "Feature test macro for optional has wrong value for C++23 in <version>"
#endif
+
+#if __cplusplus >= 202302L
+#ifndef __cpp_lib_freestanding_optional
+# error "Feature test macro for freestanding std::optional is missing in <version>"
+#elif __cpp_lib_freestanding_optional < 202311L
+# error "Feature test macro for freestanding std::optional has wrong value in <version>"
+#endif
+#endif
+
+#undef __cpp_lib_optional
+#undef __cpp_lib_freestanding_optional
+#include <optional>
+
+#if __cplusplus >= 202302L
+#ifndef __cpp_lib_freestanding_optional
+# error "Feature test macro for freestanding std::optional is missing in <optional>"
+#elif __cpp_lib_freestanding_optional < 202311L
+# error "Feature test macro for freestanding std::optional has wrong value in <optional>"
+#endif
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/variant/version.cc b/libstdc++-v3/testsuite/20_util/variant/version.cc
index fd251dd..f798532 100644
--- a/libstdc++-v3/testsuite/20_util/variant/version.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/version.cc
@@ -10,3 +10,23 @@
#elif __cplusplus >= 202002L && __cpp_lib_variant < 202106L
# error "Feature test macro for variant has wrong value for C++20 in <version>"
#endif
+
+#if __cplusplus >= 202302L
+#ifndef __cpp_lib_freestanding_variant
+# error "Feature test macro for freestanding std::variant is missing in <version>"
+#elif __cpp_lib_freestanding_variant < 202311L
+# error "Feature test macro for freestanding std::variant has wrong value in <version>"
+#endif
+#endif
+
+#undef __cpp_lib_variant
+#undef __cpp_lib_freestanding_variant
+#include <variant>
+
+#if __cplusplus >= 202302L
+#ifndef __cpp_lib_freestanding_variant
+# error "Feature test macro for freestanding std::variant is missing in <variant>"
+#elif __cpp_lib_freestanding_variant < 202311L
+# error "Feature test macro for freestanding std::variant has wrong value in <variant>"
+#endif
+#endif
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/requirements/version.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/requirements/version.cc
new file mode 100644
index 0000000..cc36699
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/requirements/version.cc
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <string_view>
+
+#ifndef __cpp_lib_freestanding_string_view
+# error "Feature test macro for freestanding std::string_view is missing in <string_view>"
+#elif __cpp_lib_freestanding_string_view < 202311L
+# error "Feature test macro for freestanding std::string_view has wrong value in <string_view>"
+#endif
+
+#undef __cpp_lib_freestanding_string_view
+#include <version>
+
+#ifndef __cpp_lib_freestanding_string_view
+# error "Feature test macro for freestanding std::string_view is missing in <version>"
+#elif __cpp_lib_freestanding_string_view < 202311L
+# error "Feature test macro for freestanding std::string_view has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/21_strings/headers/cstring/version.cc b/libstdc++-v3/testsuite/21_strings/headers/cstring/version.cc
new file mode 100644
index 0000000..06735e8
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/headers/cstring/version.cc
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++26 } }
+// { dg-add-options no_pch }
+
+#include <cstring>
+
+#ifndef __cpp_lib_freestanding_cstring
+# error "Feature test macro for freestanding <cstring> is missing in <cstring>"
+#elif __cpp_lib_freestanding_cstring < 202311L
+# error "Feature test macro for freestanding <cstring> has wrong value in <cstring>"
+#endif
+
+#undef __cpp_lib_freestanding_cstring
+#include <version>
+
+#ifndef __cpp_lib_freestanding_cstring
+# error "Feature test macro for freestanding <cstring> is missing in <version>"
+#elif __cpp_lib_freestanding_cstring < 202311L
+# error "Feature test macro for freestanding <cstring> has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/23_containers/array/requirements/version.cc b/libstdc++-v3/testsuite/23_containers/array/requirements/version.cc
new file mode 100644
index 0000000..1930805
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/requirements/version.cc
@@ -0,0 +1,19 @@
+// { dg-do preprocess { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <array>
+
+#ifndef __cpp_lib_freestanding_array
+# error "Feature test macro for freestanding std::array is missing in <array>"
+#elif __cpp_lib_freestanding_array < 202311L
+# error "Feature test macro for freestanding std::array has wrong value in <array>"
+#endif
+
+#undef __cpp_lib_freestanding_array
+#include <version>
+
+#ifndef __cpp_lib_freestanding_array
+# error "Feature test macro for freestanding std::array is missing in <version>"
+#elif __cpp_lib_freestanding_array < 202311L
+# error "Feature test macro for freestanding std::array has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
index bf64d29..e1c92f8 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
@@ -26,6 +26,6 @@ int n1 = std::get<1>(a);
int n2 = std::get<1>(std::move(a));
int n3 = std::get<1>(ca);
-// { dg-error "static assertion failed" "" { target *-*-* } 391 }
-// { dg-error "static assertion failed" "" { target *-*-* } 400 }
-// { dg-error "static assertion failed" "" { target *-*-* } 409 }
+// { dg-error "static assertion failed" "" { target *-*-* } 392 }
+// { dg-error "static assertion failed" "" { target *-*-* } 401 }
+// { dg-error "static assertion failed" "" { target *-*-* } 410 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/1.cc b/libstdc++-v3/testsuite/23_containers/span/1.cc
deleted file mode 100644
index c1c0a7e..0000000
--- a/libstdc++-v3/testsuite/23_containers/span/1.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2019-2023 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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.
-
-// This library 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 this library; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-do compile { target c++20 } }
-// { dg-add-options no_pch }
-
-#include <span>
-
-#ifndef __cpp_lib_span
-# error "Feature-test macro for span missing in <span>"
-#elif __cpp_lib_span != 202002L
-# error "Feature-test macro for span has wrong value in <span>"
-#endif
diff --git a/libstdc++-v3/testsuite/23_containers/span/at.cc b/libstdc++-v3/testsuite/23_containers/span/at.cc
new file mode 100644
index 0000000..dc4d8e3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/at.cc
@@ -0,0 +1,36 @@
+// { dg-do run { target c++26 } }
+
+#include <span>
+#include <stdexcept>
+#include <testsuite_hooks.h>
+
+void
+test_at()
+{
+ int arr[4]{0, 1, 2, 3};
+ std::span<int> s(arr);
+ VERIFY(s.at(2) == 2);
+#if __cpp_exceptions
+ try {
+ s.at(4); // { dg-warning "ignoring return value" }
+ VERIFY(false);
+ } catch (const std::out_of_range&) {
+ }
+#endif
+
+ auto s2 = s.subspan(1, 2);
+ VERIFY(s2.at(0) == 1);
+ VERIFY(s2.at(1) == 2);
+#if __cpp_exceptions
+ try {
+ s2.at(2); // { dg-warning "ignoring return value" }
+ VERIFY(false);
+ } catch (const std::out_of_range&) {
+ }
+#endif
+}
+
+int main()
+{
+ test_at();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/2.cc b/libstdc++-v3/testsuite/23_containers/span/version.cc
index 2931c0b..7441812 100644
--- a/libstdc++-v3/testsuite/23_containers/span/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/version.cc
@@ -18,10 +18,23 @@
// { dg-do compile { target c++20 } }
// { dg-add-options no_pch }
+#include <span>
+
+#ifndef __cpp_lib_span
+# error "Feature-test macro for span missing in <span>"
+#elif __cplusplus <= 202302L && __cpp_lib_span != 202002L
+# error "Feature-test macro for span has wrong value in <span>"
+#elif __cplusplus > 202302L && __cpp_lib_span != 202311L
+# error "Feature-test macro for span has wrong value in <span>"
+#endif
+
+#undef __cpp_lib_span
#include <version>
#ifndef __cpp_lib_span
# error "Feature-test macro for span missing in <version>"
-#elif __cpp_lib_span != 202002L
+#elif __cplusplus <= 202302L && __cpp_lib_span != 202002L
+# error "Feature-test macro for span has wrong value in <version>"
+#elif __cplusplus > 202302L && __cpp_lib_span != 202311L
# error "Feature-test macro for span has wrong value in <version>"
#endif
diff --git a/libstdc++-v3/testsuite/25_algorithms/fill_n/requirements/version.cc b/libstdc++-v3/testsuite/25_algorithms/fill_n/requirements/version.cc
new file mode 100644
index 0000000..6691aff
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/fill_n/requirements/version.cc
@@ -0,0 +1,19 @@
+// { dg-do preprocess { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <algorithm>
+
+#ifndef __cpp_lib_freestanding_algorithm
+# error "Feature test macro for freestanding fill_n is missing in <algorithm>"
+#elif __cpp_lib_freestanding_algorithm < 202311L
+# error "Feature test macro for freestanding fill_n has wrong value in <algorithm>"
+#endif
+
+#undef __cpp_lib_freestanding_algorithm
+#include <version>
+
+#ifndef __cpp_lib_freestanding_algorithm
+# error "Feature test macro for freestanding fill_n is missing in <version>"
+#elif __cpp_lib_freestanding_algorithm < 202311L
+# error "Feature test macro for freestanding fill_n has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/25_algorithms/swap_ranges/requirements/version.cc b/libstdc++-v3/testsuite/25_algorithms/swap_ranges/requirements/version.cc
new file mode 100644
index 0000000..2a65e7c
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/swap_ranges/requirements/version.cc
@@ -0,0 +1,19 @@
+// { dg-do preprocess { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <algorithm>
+
+#ifndef __cpp_lib_freestanding_algorithm
+# error "Feature test macro for freestanding swap_ranges is missing in <algorithm>"
+#elif __cpp_lib_freestanding_algorithm < 202311L
+# error "Feature test macro for freestanding swap_ranges has wrong value in <algorithm>"
+#endif
+
+#undef __cpp_lib_freestanding_algorithm
+#include <version>
+
+#ifndef __cpp_lib_freestanding_algorithm
+# error "Feature test macro for freestanding swap_ranges is missing in <version>"
+#elif __cpp_lib_freestanding_algorithm < 202311L
+# error "Feature test macro for freestanding swap_ranges has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/std/ranges/conv/1.cc b/libstdc++-v3/testsuite/std/ranges/conv/1.cc
new file mode 100644
index 0000000..0032cf32
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/conv/1.cc
@@ -0,0 +1,369 @@
+// { dg-do run { target c++23 } }
+
+// C++23 26.5.7 Range conversions [range.utility.conv]
+
+#include <ranges>
+#include <vector>
+#include <string>
+#include <deque>
+#include <list>
+#include <forward_list>
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+#include <testsuite_iterators.h>
+
+void
+test_p1206r7_examples()
+{
+ using Alloc = __gnu_test::uneq_allocator<int>;
+ const Alloc alloc(303);
+ const std::map<int, const char*> m{{1, "one"}, {2, "two"}, {3, "three"}};
+ namespace ranges = std::ranges;
+
+ auto l = std::views::iota(1, 10);
+ // create a vector with the elements of l
+ auto vec = ranges::to<std::vector<int>>(l); // or vector{std::from_range, l};
+ //Specify an allocator
+ auto b = ranges::to<std::vector<int, Alloc>>(l, alloc); // or vector{std::from_range, l, alloc};
+ //deducing value_type
+ auto c = ranges::to<std::vector>(l);
+ // explicit conversion int -> long
+ auto d = ranges::to<std::vector<long>>(l);
+ //Supports converting associative container to sequence containers
+ auto f = ranges::to<std::vector>(m);
+ //Supports converting sequence containers to associative ones
+ auto g = ranges::to<std::map>(f);
+ //Pipe syntax
+ auto g2 = l | ranges::views::take(42) | ranges::to<std::vector>();
+ //Pipe syntax with allocator
+ auto h = l | ranges::views::take(42) | ranges::to<std::vector>(alloc);
+ //The pipe syntax also support specifying the type and conversions
+ auto i = l | ranges::views::take(42) | ranges::to<std::vector<long>>();
+ // Nested ranges
+ std::list<std::forward_list<int>> lst = {{0, 1, 2, 3}, {4, 5, 6, 7}};
+ auto vec1 = ranges::to<std::vector<std::vector<int>>>(lst);
+ auto vec2 = ranges::to<std::vector<std::deque<double>>>(lst);
+
+ VERIFY( vec == std::vector<int>(std::ranges::begin(l), std::ranges::end(l)) );
+ static_assert(std::is_same_v<decltype(b), std::vector<int, Alloc>>);
+ VERIFY( b == (std::vector<int, Alloc>(vec.begin(), vec.end())) );
+ VERIFY( b.get_allocator() == alloc );
+ static_assert(std::is_same_v<decltype(c), std::vector<int>>);
+ VERIFY( c == vec );
+ static_assert(std::is_same_v<decltype(d), std::vector<long>>);
+ VERIFY( d == std::vector<long>(vec.begin(), vec.end()) );
+ VERIFY( g == m );
+ static_assert(std::is_same_v<decltype(g2), std::vector<int>>);
+ VERIFY( g2 == vec );
+ static_assert(std::is_same_v<decltype(h), std::vector<int, Alloc>>);
+ VERIFY( h == b );
+ VERIFY( h.get_allocator() == alloc );
+ VERIFY( i == d );
+ static_assert(std::is_same_v<decltype(vec1), std::vector<std::vector<int>>>);
+ VERIFY( vec1[1][1] == 5 );
+ static_assert(std::is_same_v<decltype(vec2), std::vector<std::deque<double>>>);
+ VERIFY( vec2[1][2] == 6.0 );
+}
+
+void
+test_example_1()
+{
+ using namespace std;
+ using ranges::to;
+
+ // Example 1 from C++23 [range.utility.conv.general]
+ string_view str = "the quick brown fox";
+ auto words = views::split(str, ' ') | to<vector<string>>();
+
+ VERIFY( (is_same_v<decltype(words), vector<string>>) );
+ VERIFY( words == vector<string>({"the", "quick", "brown", "fox"}) );
+}
+
+template<typename C>
+struct Cont1
+{
+ template<typename R, typename... Args>
+ requires std::constructible_from<C, R&, Args&...>
+ Cont1(R&& r, Args&&... args)
+ : c(r, args...)
+ { }
+
+ typename C::iterator begin();
+ typename C::iterator end();
+
+ C c;
+};
+
+void
+test_2_1_1()
+{
+ // (2.1.1) constructible_from<C, R, Args...>
+
+ std::vector<int> v{1, 2, 3, 4};
+ auto v2 = std::ranges::to<std::vector<int>>(v);
+ static_assert(std::is_same_v<decltype(v2), decltype(v)>);
+ VERIFY( v2 == v );
+
+ std::initializer_list<int> il{5, 6, 7, 8};
+ v2 = std::ranges::to<std::vector<int>>(il);
+ VERIFY( v2 == std::vector<int>(il) );
+
+ v2 = std::ranges::to<std::vector<int>>(il, std::allocator<int>{});
+ VERIFY( v2 == std::vector<int>(il) );
+
+ using Alloc = __gnu_test::uneq_allocator<int>;
+ using V = std::vector<int, Alloc>;
+
+ V v3({10, 11, 12, 13}, Alloc(14));
+ auto v4 = std::ranges::to<V>(v3);
+ static_assert(std::is_same_v<decltype(v4), V>);
+ VERIFY( v4 == v3 );
+ VERIFY( v4.get_allocator() == v3.get_allocator() );
+
+ auto v5 = std::ranges::to<V>(v3, Alloc(33));
+ VERIFY( v5 == v3 );
+ VERIFY( v5.get_allocator() == Alloc(33) );
+
+ auto v6 = std::ranges::to<V>(il, Alloc(44));
+ VERIFY( v6 == V(il) );
+ VERIFY( v6.get_allocator() == Alloc(44) );
+
+ auto c = std::ranges::to<Cont1<V>>(V{1, 2, 3});
+ static_assert(std::is_same_v<decltype(c), Cont1<V>>);
+ VERIFY( c.c == V({1, 2, 3}) );
+
+ auto c2 = std::ranges::to<Cont1<V>>(V{4, 5, 6}, Alloc(55));
+ static_assert(std::is_same_v<decltype(c2), Cont1<V>>);
+ VERIFY( c2.c == V({4, 5, 6}) );
+ VERIFY( c2.c.get_allocator() == Alloc(55) );
+
+ auto c3 = std::ranges::to<Cont1<V>>(il, Alloc(66));
+ static_assert(std::is_same_v<decltype(c2), Cont1<V>>);
+ VERIFY( c3.c == V(v2.begin(), v2.end()) );
+ VERIFY( c3.c.get_allocator() == Alloc(66) );
+}
+
+template<typename C>
+struct Cont2
+{
+ template<typename R, typename... Args>
+ requires std::constructible_from<C, R&, Args&...>
+ Cont2(std::from_range_t, R&& r, Args&&... args)
+ : c(r, args...)
+ { }
+
+ typename C::iterator begin();
+ typename C::iterator end();
+
+ C c;
+};
+
+void
+test_2_1_2()
+{
+ // (2.1.2) constructible_from<C, from_range_t, R, Args...>
+
+ using Alloc = __gnu_test::uneq_allocator<int>;
+ using V = std::vector<int, Alloc>;
+ auto c = std::ranges::to<Cont2<V>>(V{1, 2, 3});
+ static_assert(std::is_same_v<decltype(c), Cont2<V>>);
+ VERIFY( c.c == V({1, 2, 3}) );
+
+ auto c2 = std::ranges::to<Cont2<V>>(V{4, 5, 6}, Alloc(7));
+ static_assert(std::is_same_v<decltype(c2), Cont2<V>>);
+ VERIFY( c2.c == V({4, 5, 6}) );
+ VERIFY( c2.c.get_allocator() == Alloc(7) );
+}
+
+template<typename C>
+struct Cont3
+{
+ template<typename It, typename Sent, typename... Args>
+ requires std::same_as<It, Sent>
+ && std::constructible_from<C, It&, Sent&, Args&...>
+ Cont3(It first, Sent last, Args&&... args)
+ : c(first, last, args...)
+ { }
+
+ typename C::iterator begin();
+ typename C::iterator end();
+
+ C c;
+};
+
+void
+test_2_1_3()
+{
+ // (2.1.3) constructible_from<C, iterator_t<R>, sentinel_t<R<, Args...>
+
+ using Alloc = __gnu_test::uneq_allocator<int>;
+ using V = std::vector<int, Alloc>;
+
+ std::list<unsigned> l{1u, 2u, 3u};
+ auto c = std::ranges::to<Cont3<V>>(l);
+ static_assert(std::is_same_v<decltype(c), Cont3<V>>);
+ VERIFY( c.c == V(l.begin(), l.end()) );
+
+ std::list<long> l2{4l, 5l, 6l};
+ auto c2 = std::ranges::to<Cont3<V>>(l2, Alloc(78));
+ static_assert(std::is_same_v<decltype(c2), Cont3<V>>);
+ VERIFY( c2.c == V(l2.begin(), l2.end()) );
+ VERIFY( c2.c.get_allocator() == Alloc(78) );
+}
+
+template<typename C, bool UsePushBack = true>
+struct Cont4
+{
+ using value_type = typename C::value_type;
+
+ // Only support construction with no args or an allocator.
+ // This forces the use of either push_back or insert to fill the container.
+ Cont4() { }
+ Cont4(typename C::allocator_type a) : c(a) { }
+
+ // Required to satisfy range
+ typename C::iterator begin() { return c.begin(); }
+ typename C::iterator end() { return c.end(); }
+
+ // Satisfying container-insertable requires either this ...
+ template<typename T>
+ requires UsePushBack
+ && requires(C& c, T&& t) { c.push_back(std::forward<T>(t)); }
+ void
+ push_back(T&& t)
+ {
+ c.push_back(std::forward<T>(t));
+ used_push_back = true;
+ }
+
+ // ... or this:
+ template<typename T>
+ typename C::iterator
+ insert(typename C::iterator, T&& t)
+ {
+ used_push_back = false;
+ return c.insert(c.end(), std::forward<T>(t));
+ }
+
+ // Required to satisfy reservable-container
+ void
+ reserve(typename C::size_type n) requires requires(C& c) { c.reserve(n); }
+ {
+ c.reserve(n);
+ used_reserve = true;
+ }
+
+ // Required to satisfy reservable-container
+ auto size() const { return c.size(); }
+
+ // Required to satisfy reservable-container
+ auto capacity() const requires requires(C& c) { c.capacity(); }
+ { return c.capacity(); }
+
+ // Required to satisfy reservable-container
+ auto max_size() const { return c.max_size(); }
+
+ C c;
+ bool used_push_back = false;
+ bool used_reserve = false;
+};
+
+void
+test_2_1_4()
+{
+ // (2.1.4) constructible_from<C, Args...> and
+ // container-insertable<C, range_reference_t<R>>
+
+ using Alloc = __gnu_test::uneq_allocator<int>;
+ using V = std::vector<int, Alloc>;
+
+ std::list<unsigned> l{1u, 2u, 3u};
+ auto c = std::ranges::to<Cont4<V>>(l);
+ static_assert(std::is_same_v<decltype(c), Cont4<V>>);
+ VERIFY( c.c == V(l.begin(), l.end()) );
+ VERIFY( c.used_push_back );
+ VERIFY( c.used_reserve );
+
+ std::list<long> l2{4l, 5l, 6l};
+ auto c2 = std::ranges::to<Cont4<V>>(l2, Alloc(78));
+ static_assert(std::is_same_v<decltype(c2), Cont4<V>>);
+ VERIFY( c2.c == V(l2.begin(), l2.end()) );
+ VERIFY( c2.c.get_allocator() == Alloc(78) );
+ VERIFY( c2.used_push_back );
+ VERIFY( c2.used_reserve );
+
+ using Alloc2 = __gnu_test::uneq_allocator<short>;
+ using List = std::list<short, Alloc2>;
+ auto c3 = std::ranges::to<Cont4<List>>(c.c, Alloc2(99));
+ static_assert(std::is_same_v<decltype(c3), Cont4<List>>);
+ VERIFY( c3.c == List(l.begin(), l.end()) );
+ VERIFY( c3.c.get_allocator() == Alloc(99) );
+ VERIFY( c3.used_push_back );
+ VERIFY( ! c3.used_reserve );
+
+ auto c4 = std::ranges::to<Cont4<List, false>>(c.c, Alloc2(111));
+ static_assert(std::is_same_v<decltype(c4), Cont4<List, false>>);
+ VERIFY( c4.c == List(l.begin(), l.end()) );
+ VERIFY( c4.c.get_allocator() == Alloc(111) );
+ VERIFY( ! c4.used_push_back );
+ VERIFY( ! c4.used_reserve );
+}
+
+void
+test_2_2()
+{
+ // (2.2) input_range<range_reference_t<R>>
+
+ std::string s1[]{ "one", "two", "three", "four" };
+ std::string s2[]{ "V", "VI", "VII", "VIII" };
+ std::string s3[]{ "0x09", "0x0a", "0x0b", "0x0c" };
+ using R = __gnu_test::test_input_range<std::string>;
+ R input_ranges[]{R(s1), R(s2), R(s3)};
+ __gnu_test::test_input_range<R> rr(input_ranges);
+ namespace pmr = std::pmr;
+ __gnu_test::memory_resource res;
+#if _GLIBCXX_USE_CXX11_ABI
+ auto vvs = std::ranges::to<pmr::vector<pmr::vector<pmr::string>>>(rr, &res);
+ auto str_alloc = pmr::polymorphic_allocator<char>(&res);
+#else
+ auto vvs = std::ranges::to<pmr::vector<pmr::vector<std::string>>>(rr, &res);
+ auto str_alloc = std::allocator<char>();
+#endif
+ VERIFY( vvs[1][1] == "VI" );
+ VERIFY( vvs[2][2] == "0x0b" );
+ VERIFY( vvs[0].get_allocator().resource() == &res );
+ VERIFY( vvs[2][2].get_allocator() == str_alloc );
+}
+
+void
+test_lwg3984()
+{
+ std::vector<std::vector<int>> v;
+ auto r = std::views::all(std::move(v));
+ auto l = std::ranges::to<std::list<std::list<int>>>(r);
+ VERIFY(l.empty());
+}
+
+void
+test_nodiscard()
+{
+ std::vector<int> v;
+ std::ranges::to<std::vector<long>>(v); // { dg-warning "ignoring return" }
+ std::ranges::to<std::vector>(v); // { dg-warning "ignoring return" }
+ std::ranges::to<std::vector<long>>(); // { dg-warning "ignoring return" }
+ std::ranges::to<std::vector>(); // { dg-warning "ignoring return" }
+}
+
+int main()
+{
+ test_p1206r7_examples();
+ test_example_1();
+ test_2_1_1();
+ test_2_1_2();
+ test_2_1_3();
+ test_2_1_4();
+ test_2_2();
+ test_lwg3984();
+ test_nodiscard();
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/conv/2_neg.cc b/libstdc++-v3/testsuite/std/ranges/conv/2_neg.cc
new file mode 100644
index 0000000..1e5f6f1
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/conv/2_neg.cc
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++23 } }
+
+// C++23 26.5.7 Range conversions [range.utility.conv]
+
+#include <ranges>
+#include <vector>
+#include <testsuite_allocator.h>
+
+void
+test_2_1_5()
+{
+ // (2.1.5) Otherwise, the program is ill-formed.
+
+ using Alloc = __gnu_test::uneq_allocator<int>;
+ using Vec = std::vector<int, Alloc>;
+
+ std::vector<int> v;
+ (void) std::ranges::to<Vec>(v, v.get_allocator()); // { dg-error "here" }
+
+ (void) std::ranges::to<Vec>(Vec{}, 1, 2, 3, 4, 5, 6); // { dg-error "here" }
+}
+
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
+// { dg-prune-output "no matching function" }
diff --git a/libstdc++-v3/testsuite/std/ranges/conv/version.cc b/libstdc++-v3/testsuite/std/ranges/conv/version.cc
new file mode 100644
index 0000000..3373680
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/conv/version.cc
@@ -0,0 +1,19 @@
+// { dg-do preprocess { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <ranges>
+
+#ifndef __cpp_lib_ranges_to_container
+# error "Feature test macro for ranges_to_container is missing in <ranges>"
+#elif __cpp_lib_ranges_to_container < 202202L
+# error "Feature test macro for ranges_to_container has wrong value in <ranges>"
+#endif
+
+#undef __cpp_lib_ranges_to_container
+#include <version>
+
+#ifndef __cpp_lib_ranges_to_container
+# error "Feature test macro for ranges_to_container is missing in <version>"
+#elif __cpp_lib_ranges_to_container < 202202L
+# error "Feature test macro for ranges_to_container has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/string.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/string.cc
new file mode 100644
index 0000000..c7d0efa
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/string.cc
@@ -0,0 +1,36 @@
+// { dg-do run { target c++11 } }
+
+#include <tr2/dynamic_bitset>
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test_string_ctor()
+{
+ std::tr2::dynamic_bitset<> b("101001");
+ VERIFY( b[0] == true );
+ VERIFY( b[1] == false );
+ VERIFY( b[2] == false );
+ VERIFY( b[3] == true );
+ VERIFY( b[4] == false );
+ VERIFY( b[5] == true );
+}
+
+void
+test_alt_chars()
+{
+ std::string str = "xOIOIOIOx";
+ std::tr2::dynamic_bitset<> b(str, 1, 6, 'I', 'O');
+ VERIFY( b[0] == false );
+ VERIFY( b[1] == true );
+ VERIFY( b[2] == false );
+ VERIFY( b[3] == true );
+ VERIFY( b[4] == false );
+ VERIFY( b[5] == true );
+}
+
+int main()
+{
+ test_string_ctor();
+ test_alt_chars();
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index 70dacb3..1773b72 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -418,7 +418,7 @@ namespace __gnu_test
operator==(const uneq_allocator& a,
const uneq_allocator<Tp1,
typename AllocTraits::template rebind<Tp1>::other>& b)
- { return a.personality == b.personality; }
+ { return a.personality == b.get_personality(); }
template<typename Tp1>
friend inline bool
diff --git a/libtool.m4 b/libtool.m4
index 7f8ae26..add2d4a 100644
--- a/libtool.m4
+++ b/libtool.m4
@@ -4312,7 +4312,6 @@ _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
[Compiler flag to prevent dynamic linking])
])# _LT_COMPILER_PIC
-_LT_TAGVAR(enable_darwin_at_rpath, $1)=no
# _LT_LINKER_SHLIBS([TAGNAME])
# ----------------------------