aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@baylibre.com>2024-03-16 23:32:07 +0100
committerThomas Schwinge <tschwinge@baylibre.com>2024-03-16 23:32:07 +0100
commit595789c2c33ea9fbb894cef4cf8ec576a9989e93 (patch)
tree094dac15265223346423c555d381a317c2af80fb
parente86610f33d67631a00847af88444c8371ef72f63 (diff)
parent80b1a371008c31982d35cff9b85ca6affd3ac949 (diff)
downloadgcc-595789c2c33ea9fbb894cef4cf8ec576a9989e93.zip
gcc-595789c2c33ea9fbb894cef4cf8ec576a9989e93.tar.gz
gcc-595789c2c33ea9fbb894cef4cf8ec576a9989e93.tar.bz2
Merge commit '2b9778c8d9d33174de63716b74b2f114d700e104^' into HEAD
-rw-r--r--ChangeLog9
-rw-r--r--fixincludes/ChangeLog4
-rwxr-xr-xfixincludes/configure2
-rw-r--r--gcc/ChangeLog1451
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in41
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/analyzer/ChangeLog35
-rw-r--r--gcc/analyzer/record-layout.cc125
-rw-r--r--gcc/analyzer/record-layout.h91
-rw-r--r--gcc/analyzer/region-model.cc312
-rw-r--r--gcc/analyzer/region-model.h27
-rw-r--r--gcc/c-family/ChangeLog26
-rw-r--r--gcc/c-family/c-attribs.cc17
-rw-r--r--gcc/c-family/c-opts.cc2
-rw-r--r--gcc/c-family/c-pragma.cc49
-rw-r--r--gcc/c-family/c-pragma.h2
-rw-r--r--gcc/c-family/c-warn.cc2
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog27
-rw-r--r--gcc/c/c-parser.cc60
-rw-r--r--gcc/c/c-typeck.cc31
-rw-r--r--gcc/combine.cc4
-rw-r--r--gcc/common/config/i386/cpuinfo.h6
-rw-r--r--gcc/common/config/i386/i386-common.cc10
-rw-r--r--gcc/common/config/i386/i386-cpuinfo.h1
-rw-r--r--gcc/config.gcc26
-rw-r--r--gcc/config.in13
-rw-r--r--gcc/config/aarch64/aarch64.cc50
-rw-r--r--gcc/config/aarch64/aarch64.md47
-rw-r--r--gcc/config/aarch64/atomics.md2
-rw-r--r--gcc/config/arc/arc-protos.h7
-rw-r--r--gcc/config/arc/arc.cc506
-rw-r--r--gcc/config/arc/arc.h15
-rw-r--r--gcc/config/arc/arc.md293
-rw-r--r--gcc/config/arc/predicates.md16
-rw-r--r--gcc/config/arm/aout.h23
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.cc56
-rw-r--r--gcc/config/arm/arm.h37
-rw-r--r--gcc/config/arm/arm.md29
-rw-r--r--gcc/config/arm/elf.h18
-rw-r--r--gcc/config/bpf/bpf-passes.def20
-rw-r--r--gcc/config/bpf/bpf-protos.h4
-rw-r--r--gcc/config/bpf/bpf.cc12
-rw-r--r--gcc/config/bpf/bpf.md4
-rw-r--r--gcc/config/bpf/core-builtins.cc1021
-rw-r--r--gcc/config/bpf/core-builtins.h28
-rw-r--r--gcc/config/bpf/t-bpf2
-rw-r--r--gcc/config/darwin.cc15
-rw-r--r--gcc/config/darwin.h16
-rw-r--r--gcc/config/gcn/gcn-valu.md6
-rw-r--r--gcc/config/gcn/gcn.cc6
-rw-r--r--gcc/config/gcn/gcn.md2
-rw-r--r--gcc/config/i386/avx512cdintrin.h2
-rw-r--r--gcc/config/i386/avx512vlintrin.h556
-rw-r--r--gcc/config/i386/driver-i386.cc5
-rw-r--r--gcc/config/i386/i386-builtin.def4
-rw-r--r--gcc/config/i386/i386-c.cc7
-rw-r--r--gcc/config/i386/i386-expand.cc68
-rw-r--r--gcc/config/i386/i386-features.cc32
-rw-r--r--gcc/config/i386/i386-options.cc3
-rw-r--r--gcc/config/i386/i386.cc9
-rw-r--r--gcc/config/i386/i386.h11
-rw-r--r--gcc/config/i386/i386.md290
-rw-r--r--gcc/config/i386/lujiazui.md2
-rw-r--r--gcc/config/i386/mmx.md239
-rw-r--r--gcc/config/i386/predicates.md1
-rw-r--r--gcc/config/i386/sse.md61
-rw-r--r--gcc/config/i386/x86-tune-costs.h116
-rw-r--r--gcc/config/i386/x86-tune-sched.cc27
-rw-r--r--gcc/config/i386/x86-tune.def83
-rw-r--r--gcc/config/i386/yongfeng.md848
-rw-r--r--gcc/config/loongarch/genopts/loongarch-strings6
-rw-r--r--gcc/config/loongarch/genopts/loongarch.opt.in21
-rw-r--r--gcc/config/loongarch/lasx.md14
-rw-r--r--gcc/config/loongarch/lasxintrin.h16
-rw-r--r--gcc/config/loongarch/loongarch-def.h6
-rw-r--r--gcc/config/loongarch/loongarch-opts.h4
-rw-r--r--gcc/config/loongarch/loongarch-protos.h1
-rw-r--r--gcc/config/loongarch/loongarch-str.h5
-rw-r--r--gcc/config/loongarch/loongarch.cc75
-rw-r--r--gcc/config/loongarch/loongarch.h8
-rw-r--r--gcc/config/loongarch/loongarch.md135
-rw-r--r--gcc/config/loongarch/loongarch.opt21
-rw-r--r--gcc/config/loongarch/lsx.md14
-rw-r--r--gcc/config/loongarch/lsxintrin.h16
-rw-r--r--gcc/config/loongarch/predicates.md15
-rw-r--r--gcc/config/microblaze/microblaze.cc2
-rw-r--r--gcc/config/riscv/autovec.md108
-rw-r--r--gcc/config/riscv/constraints.md26
-rw-r--r--gcc/config/riscv/riscv-avlprop.cc419
-rw-r--r--gcc/config/riscv/riscv-opts.h4
-rw-r--r--gcc/config/riscv/riscv-passes.def1
-rw-r--r--gcc/config/riscv/riscv-protos.h49
-rw-r--r--gcc/config/riscv/riscv-string.cc302
-rw-r--r--gcc/config/riscv/riscv-v.cc435
-rw-r--r--gcc/config/riscv/riscv-vector-builtins-bases.cc4
-rw-r--r--gcc/config/riscv/riscv-vector-builtins-functions.def1
-rw-r--r--gcc/config/riscv/riscv-vector-builtins.cc8
-rw-r--r--gcc/config/riscv/riscv-vsetvl.cc120
-rw-r--r--gcc/config/riscv/riscv.cc35
-rw-r--r--gcc/config/riscv/riscv.h6
-rw-r--r--gcc/config/riscv/riscv.md26
-rw-r--r--gcc/config/riscv/sync-rvwmo.md4
-rw-r--r--gcc/config/riscv/sync-ztso.md4
-rw-r--r--gcc/config/riscv/sync.md45
-rw-r--r--gcc/config/riscv/t-riscv6
-rw-r--r--gcc/config/riscv/thead.cc515
-rw-r--r--gcc/config/riscv/thead.md594
-rw-r--r--gcc/config/riscv/vector-iterators.md8
-rw-r--r--gcc/config/riscv/vector.md270
-rw-r--r--gcc/config/rs6000/rs6000.cc8
-rw-r--r--gcc/config/sh/sh_treg_combine.cc9
-rw-r--r--gcc/config/xtensa/xtensa.h2
-rwxr-xr-xgcc/configure48
-rw-r--r--gcc/configure.ac26
-rw-r--r--gcc/convert.cc21
-rw-r--r--gcc/cp/ChangeLog91
-rw-r--r--gcc/cp/cp-gimplify.cc9
-rw-r--r--gcc/cp/cp-tree.def15
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/init.cc15
-rw-r--r--gcc/cp/module.cc6
-rw-r--r--gcc/cp/parser.cc69
-rw-r--r--gcc/cp/pt.cc3
-rw-r--r--gcc/cp/semantics.cc60
-rw-r--r--gcc/cp/tree.cc4
-rw-r--r--gcc/cp/typeck.cc22
-rw-r--r--gcc/d/ChangeLog60
-rw-r--r--gcc/d/Make-lang.in2
-rw-r--r--gcc/d/d-builtins.cc3
-rw-r--r--gcc/d/d-codegen.cc62
-rw-r--r--gcc/d/d-convert.cc137
-rw-r--r--gcc/d/d-tree.h17
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/README.md1
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/aggregate.d8
-rw-r--r--gcc/d/dmd/aggregate.h8
-rw-r--r--gcc/d/dmd/aliasthis.h2
-rw-r--r--gcc/d/dmd/arraytypes.d2
-rw-r--r--gcc/d/dmd/ast_node.d2
-rw-r--r--gcc/d/dmd/attrib.h1
-rw-r--r--gcc/d/dmd/blockexit.d20
-rw-r--r--gcc/d/dmd/canthrow.d2
-rw-r--r--gcc/d/dmd/cond.d4
-rw-r--r--gcc/d/dmd/cond.h2
-rw-r--r--gcc/d/dmd/cparse.d17
-rw-r--r--gcc/d/dmd/cppmangle.d2
-rw-r--r--gcc/d/dmd/dcast.d2
-rw-r--r--gcc/d/dmd/dclass.d8
-rw-r--r--gcc/d/dmd/declaration.d3
-rw-r--r--gcc/d/dmd/declaration.h12
-rw-r--r--gcc/d/dmd/denum.d2
-rw-r--r--gcc/d/dmd/dimport.d2
-rw-r--r--gcc/d/dmd/dinterpret.d21
-rw-r--r--gcc/d/dmd/dmodule.d4
-rw-r--r--gcc/d/dmd/doc.h4
-rw-r--r--gcc/d/dmd/dscope.d8
-rw-r--r--gcc/d/dmd/dstruct.d2
-rw-r--r--gcc/d/dmd/dsymbol.d9
-rw-r--r--gcc/d/dmd/dsymbolsem.d23
-rw-r--r--gcc/d/dmd/dtemplate.d10
-rw-r--r--gcc/d/dmd/dtoh.d2
-rw-r--r--gcc/d/dmd/escape.d2
-rw-r--r--gcc/d/dmd/expression.d374
-rw-r--r--gcc/d/dmd/expression.h89
-rw-r--r--gcc/d/dmd/expressionsem.d353
-rw-r--r--gcc/d/dmd/foreachvar.d2
-rw-r--r--gcc/d/dmd/func.d32
-rw-r--r--gcc/d/dmd/globals.h6
-rw-r--r--gcc/d/dmd/hdrgen.d40
-rw-r--r--gcc/d/dmd/id.d2
-rw-r--r--gcc/d/dmd/identifier.d2
-rw-r--r--gcc/d/dmd/import.h1
-rw-r--r--gcc/d/dmd/init.d2
-rw-r--r--gcc/d/dmd/init.h1
-rw-r--r--gcc/d/dmd/json.d2
-rw-r--r--gcc/d/dmd/location.d2
-rw-r--r--gcc/d/dmd/module.h1
-rw-r--r--gcc/d/dmd/mtype.d18
-rw-r--r--gcc/d/dmd/mtype.h12
-rw-r--r--gcc/d/dmd/mustuse.d23
-rw-r--r--gcc/d/dmd/nogc.d2
-rw-r--r--gcc/d/dmd/ob.d2
-rw-r--r--gcc/d/dmd/objc.h2
-rw-r--r--gcc/d/dmd/parse.d2
-rw-r--r--gcc/d/dmd/rootobject.d (renamed from gcc/d/dmd/root/rootobject.d)8
-rw-r--r--gcc/d/dmd/scope.h2
-rw-r--r--gcc/d/dmd/semantic2.d2
-rw-r--r--gcc/d/dmd/semantic3.d2
-rw-r--r--gcc/d/dmd/sideeffect.d39
-rw-r--r--gcc/d/dmd/statement.d8
-rw-r--r--gcc/d/dmd/statement.h7
-rw-r--r--gcc/d/dmd/template.h5
-rw-r--r--gcc/d/dmd/templateparamsem.d2
-rw-r--r--gcc/d/dmd/tokens.d2
-rw-r--r--gcc/d/dmd/tokens.h3
-rw-r--r--gcc/d/dmd/traits.d2
-rw-r--r--gcc/d/dmd/transitivevisitor.d2
-rw-r--r--gcc/d/dmd/typesem.d2
-rw-r--r--gcc/d/dmd/visitor.d2
-rw-r--r--gcc/d/expr.cc51
-rw-r--r--gcc/d/modules.cc4
-rw-r--r--gcc/d/runtime.def9
-rw-r--r--gcc/d/toir.cc32
-rw-r--r--gcc/doc/extend.texi69
-rw-r--r--gcc/doc/install.texi6
-rw-r--r--gcc/doc/invoke.texi63
-rw-r--r--gcc/doc/md.texi18
-rw-r--r--gcc/dwarf2out.cc4
-rw-r--r--gcc/expr.cc98
-rw-r--r--gcc/fortran/ChangeLog64
-rw-r--r--gcc/fortran/decl.cc21
-rw-r--r--gcc/fortran/dump-parse-tree.cc42
-rw-r--r--gcc/fortran/expr.cc3
-rw-r--r--gcc/fortran/frontend-passes.cc4
-rw-r--r--gcc/fortran/gfortran.h3
-rw-r--r--gcc/fortran/interface.cc16
-rw-r--r--gcc/fortran/match.cc22
-rw-r--r--gcc/fortran/misc.cc7
-rw-r--r--gcc/fortran/openmp.cc67
-rw-r--r--gcc/fortran/resolve.cc35
-rw-r--r--gcc/fortran/trans-openmp.cc18
-rw-r--r--gcc/gcov-io.h2
-rw-r--r--gcc/genautomata.cc2
-rw-r--r--gcc/genemit.cc542
-rw-r--r--gcc/gensupport.cc55
-rw-r--r--gcc/gensupport.h1
-rw-r--r--gcc/gimple-harden-conditionals.cc12
-rw-r--r--gcc/gimple-harden-control-flow.cc80
-rw-r--r--gcc/gimple-match.h72
-rw-r--r--gcc/gimplify.cc2
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc1302
-rw-r--r--gcc/go/gofrontend/expressions.h174
-rw-r--r--gcc/go/gofrontend/gogo.cc88
-rw-r--r--gcc/go/gofrontend/gogo.h10
-rw-r--r--gcc/go/gofrontend/parse.cc2
-rw-r--r--gcc/go/gofrontend/runtime.cc4
-rw-r--r--gcc/go/gofrontend/runtime.h2
-rw-r--r--gcc/go/gofrontend/statements.cc285
-rw-r--r--gcc/go/gofrontend/statements.h122
-rw-r--r--gcc/go/gofrontend/types.cc22
-rw-r--r--gcc/go/gofrontend/types.h24
-rw-r--r--gcc/go/gofrontend/wb.cc17
-rw-r--r--gcc/input.cc4
-rw-r--r--gcc/internal-fn.cc2
-rw-r--r--gcc/ipa-cp.cc8
-rw-r--r--gcc/ipa-icf.cc1
-rw-r--r--gcc/ipa-modref.cc61
-rw-r--r--gcc/ipa-prop.cc17
-rw-r--r--gcc/ipa-prop.h37
-rw-r--r--gcc/ipa-sra.cc33
-rw-r--r--gcc/ipa-visibility.cc54
-rw-r--r--gcc/ira-costs.cc174
-rw-r--r--gcc/jit/ChangeLog9
-rw-r--r--gcc/jit/jit-recording.cc2
-rw-r--r--gcc/lra-constraints.cc9
-rw-r--r--gcc/m2/ChangeLog46
-rw-r--r--gcc/m2/gm2-compiler/SymbolTable.mod10
-rw-r--r--gcc/m2/gm2-gcc/m2builtins.cc25
-rw-r--r--gcc/m2/gm2-gcc/m2decl.cc31
-rw-r--r--gcc/m2/gm2-gcc/m2decl.def9
-rw-r--r--gcc/m2/gm2-gcc/m2decl.h3
-rw-r--r--gcc/m2/gm2-gcc/m2expr.cc66
-rw-r--r--gcc/m2/gm2-gcc/m2expr.def9
-rw-r--r--gcc/m2/gm2-gcc/m2expr.h2
-rw-r--r--gcc/m2/gm2-libs-ch/cgetopt.c10
-rw-r--r--gcc/m2/gm2-libs-ch/wrapc.c27
-rw-r--r--gcc/m2/gm2-libs/Builtins.def4
-rw-r--r--gcc/m2/gm2-libs/Builtins.mod16
-rw-r--r--gcc/m2/gm2-libs/GetOpt.def13
-rw-r--r--gcc/m2/gm2-libs/GetOpt.mod84
-rw-r--r--gcc/m2/gm2-libs/M2Dependent.mod18
-rw-r--r--gcc/m2/gm2-libs/cgetopt.def3
-rw-r--r--gcc/m2/gm2-libs/wrapc.def29
-rw-r--r--gcc/match.pd153
-rw-r--r--gcc/objc/ChangeLog7
-rw-r--r--gcc/objc/objc-gnu-runtime-abi-01.cc3
-rw-r--r--gcc/objc/objc-next-runtime-abi-01.cc3
-rw-r--r--gcc/objc/objc-next-runtime-abi-02.cc3
-rw-r--r--gcc/objcp/ChangeLog6
-rw-r--r--gcc/objcp/objcp-lang.cc10
-rw-r--r--gcc/omp-expand.cc51
-rw-r--r--gcc/omp-low.cc2
-rw-r--r--gcc/omp-oacc-kernels-decompose.cc15
-rw-r--r--gcc/omp-simd-clone.cc241
-rw-r--r--gcc/opts.cc10
-rw-r--r--gcc/pretty-print.cc57
-rw-r--r--gcc/pretty-print.h4
-rw-r--r--gcc/range-op-float.cc159
-rw-r--r--gcc/range-op-mixed.h9
-rw-r--r--gcc/range-op.h4
-rw-r--r--gcc/read-md.cc4
-rw-r--r--gcc/read-md.h2
-rw-r--r--gcc/recog.cc42
-rw-r--r--gcc/reload.cc6
-rw-r--r--gcc/rtl-ssa.h1
-rw-r--r--gcc/rtl-ssa/access-utils.h68
-rw-r--r--gcc/rtl-ssa/accesses.cc125
-rw-r--r--gcc/rtl-ssa/blocks.cc65
-rw-r--r--gcc/rtl-ssa/changes.cc91
-rw-r--r--gcc/rtl-ssa/functions.cc2
-rw-r--r--gcc/rtl-ssa/functions.h19
-rw-r--r--gcc/rtl-ssa/insns.cc2
-rw-r--r--gcc/rtl-ssa/internals.h4
-rw-r--r--gcc/rtl-ssa/member-fns.inl11
-rw-r--r--gcc/rtl-ssa/movement.cc40
-rw-r--r--gcc/rtl-ssa/movement.h7
-rw-r--r--gcc/stringpool.cc45
-rw-r--r--gcc/testsuite/ChangeLog955
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-read_write.c15
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-without-size.c54
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-multiple.c52
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-2.c33
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-sized.c69
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull.c34
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable-sized.c69
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable.c34
-rw-r--r--gcc/testsuite/c-c++-common/attr-null_terminated_string_arg.c16
-rw-r--r--gcc/testsuite/c-c++-common/cpp/diagnostic-poison.c13
-rw-r--r--gcc/testsuite/c-c++-common/goacc/if-clause-1.c6
-rw-r--r--gcc/testsuite/c-c++-common/goacc/if-clause-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/goacc/self-clause-1.c34
-rw-r--r--gcc/testsuite/c-c++-common/goacc/self-clause-2.c43
-rw-r--r--gcc/testsuite/c-c++-common/pragma-target-1.c19
-rw-r--r--gcc/testsuite/c-c++-common/pragma-target-2.c27
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/scoped_enum12.C8
-rw-r--r--gcc/testsuite/g++.dg/pch/pr36887.C3
-rw-r--r--gcc/testsuite/g++.dg/pch/pr36887.Hs1
-rw-r--r--gcc/testsuite/g++.dg/template/enum9.C12
-rw-r--r--gcc/testsuite/g++.dg/template/new14.C20
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent27.C8
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent28.C6
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent28a.C8
-rw-r--r--gcc/testsuite/g++.dg/torture/harden-comp-pr111520.cc17
-rw-r--r--gcc/testsuite/g++.dg/warn/Wparentheses-13.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wparentheses-23.C3
-rw-r--r--gcc/testsuite/g++.dg/warn/Wparentheses-32.C8
-rw-r--r--gcc/testsuite/g++.target/i386/mv32.C5
-rw-r--r--gcc/testsuite/g++.target/i386/part-vect-vcondhf.C44
-rw-r--r--gcc/testsuite/g++.target/i386/pr87299-1.C8
-rw-r--r--gcc/testsuite/g++.target/i386/pr87299-2.C8
-rw-r--r--gcc/testsuite/g++.target/riscv/rvv/rvv.exp4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c13
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/builtins/pr93262-chk.c1
-rw-r--r--gcc/testsuite/gcc.dg/Walloc-size-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/Walloc-size-2.c18
-rw-r--r--gcc/testsuite/gcc.dg/Wtrampolines.c3
-rw-r--r--gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c14
-rw-r--r--gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c49
-rw-r--r--gcc/testsuite/gcc.dg/fold-popcount-8a.c33
-rw-r--r--gcc/testsuite/gcc.dg/harden-cfr-pr111943.c33
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr111157_0.c24
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr111157_1.c10
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-1b.c1
-rw-r--r--gcc/testsuite/gcc.dg/pie-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr104970.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr111914.c14
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr111916.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr111917.c23
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr112305.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/peel-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bitcmp-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bitcmp-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bitcmp-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bitcmp-4.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bitcmp-5.c43
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bitcmp-6.c41
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cond-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c45
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-39.c43
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-40.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr111860-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr111860-3.c17
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr111915.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-gather-6.c15
-rw-r--r--gcc/testsuite/gcc.misc-tests/godump-1.c12
-rw-r--r--gcc/testsuite/gcc.misc-tests/godump-2.c18
-rw-r--r--gcc/testsuite/gcc.target/aarch64/aarch64.exp9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cond_op-1.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/imm_choice_comparison.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/moveor_imm.c68
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr106583.c74
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1b.c3
-rw-r--r--gcc/testsuite/gcc.target/arc/lsl16-1.c10
-rw-r--r--gcc/testsuite/gcc.target/arc/lsr16-1.c10
-rw-r--r--gcc/testsuite/gcc.target/arc/pr101955.c10
-rw-r--r--gcc/testsuite/gcc.target/arc/swap-1.c9
-rw-r--r--gcc/testsuite/gcc.target/arc/swap-2.c11
-rw-r--r--gcc/testsuite/gcc.target/arm/arm-switchstatement.c155
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/mve_vadcq_vsbcq_fpscr_overwrite.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/pragma_arch_attribute_1b.c6
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-attr-5.c62
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-attr-6.c46
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-1.c4
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c4
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c8
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-1.c76
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-2.c35
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-3.c37
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-4.c31
-rw-r--r--gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-offset-1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-interrupt-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-push2pop2_force_drap-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/float16-8.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-56.inc6
-rw-r--r--gcc/testsuite/gcc.target/i386/large-data.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/part-vect-vec_cmphf.c26
-rw-r--r--gcc/testsuite/gcc.target/i386/pr103144-mul-1.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr103144-mul-2.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr104610-2.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr105554.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr110551-2.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr110551.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr111698.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/pr111753.c69
-rw-r--r--gcc/testsuite/gcc.target/i386/pr111820-1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr111820-2.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr111820-3.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112276.c36
-rw-r--r--gcc/testsuite/gcc.target/i386/pr87299-1.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr87299-2.c8
-rw-r--r--gcc/testsuite/gcc.target/loongarch/builtin_thread_pointer.c10
-rw-r--r--gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-lto.c26
-rw-r--r--gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c6
-rw-r--r--gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c14
-rw-r--r--gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c9
-rw-r--r--gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-le-ie.c6
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-1.c64
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-2.c87
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-1.c64
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-2.c87
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/bshift.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/div.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/fcmp1.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/fcmp2.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/fcmp3.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/fcmp4.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/fcvt.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/float.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/fsqrt.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/mul-bshift-pcmp.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/mul-bshift.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/mul.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/mulh-bshift-pcmp.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/mulh.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/nofcmp.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/nofloat.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/pcmp.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/isa/vanilla.c2
-rw-r--r--gcc/testsuite/gcc.target/microblaze/microblaze.exp2
-rw-r--r--gcc/testsuite/gcc.target/msp430/pr91865.c8
-rw-r--r--gcc/testsuite/gcc.target/nios2/custom-fp-2b.c26
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bcd-3.c22
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-3b.c4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr111971.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-5.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-5.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-6.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-7.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-5.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-1.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-2.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-3.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-4.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-5.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-7.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-1.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-2.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-3.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-4.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-5.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-1.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-2.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-3.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-1.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-2.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-3.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/inline-atomics-2.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/inline-atomics-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/inline-atomics-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/inline-atomics-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/inline-atomics-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/inline-atomics-7.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/inline-atomics-8.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c47
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c23
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c48
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/builtin/rawmemchr-1.c99
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-10.c63
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-11.c31
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-10.c34
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-11.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-1.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-2.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv64gcv.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c39
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c38
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c32
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-5.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-5.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c7
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-1.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-2.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-1.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-2.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111318.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111888.c33
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c41
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c41
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-1.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-run-1.c31
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/bswap16-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-0.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-1.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-irint-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iround-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llrint-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llround-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-0.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-1.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-2.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-3.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c49
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount.c1464
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vv_constraint-1.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-1.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-10.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-11.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-12.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-129.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-13.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-130.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-131.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-133.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-134.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-135.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-14.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-15.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-153.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-154.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-155.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-158.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-16.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-17.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-171.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-172.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-173.c8
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-174.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-18.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-19.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-2.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-20.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-21.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-22.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-23.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-24.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-25.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-26.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-27.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-28.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-29.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-3.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-30.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-31.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-32.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-33.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-34.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-35.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-36.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-37.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-38.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-39.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-4.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-40.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-41.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-42.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-43.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-44.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-5.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-6.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-7.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-8.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-9.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/shift_vx_constraint-1.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-1.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-2.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-3.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-4.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-5.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-6.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-1.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-8.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-9.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c73
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-1.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-2.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/rvv.exp2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111927.c170
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h152
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-update.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-index.c36
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c74
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify.c74
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-update.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb-update.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb.c44
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex.c44
-rw-r--r--gcc/testsuite/gcc.target/s390/target-attribute/tattr-2b.c51
-rw-r--r--gcc/testsuite/gdc.dg/Wunused_value.d29
-rw-r--r--gcc/testsuite/gdc.dg/pr110712.d23
-rw-r--r--gcc/testsuite/gdc.dg/pr112270.d7
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail3882.d31
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice10727a.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice10727b.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/issue24168.d31
-rw-r--r--gcc/testsuite/gfortran.dg/associate_55.f902
-rw-r--r--gcc/testsuite/gfortran.dg/coarray/caf.exp16
-rw-r--r--gcc/testsuite/gfortran.dg/dg.exp32
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/if.f9510
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/kernels-tree.f957
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/parallel-tree.f953
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/self.f9561
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_20.f9056
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_21.f9056
-rw-r--r--gcc/testsuite/gfortran.dg/pr104555.f9032
-rw-r--r--gcc/testsuite/gfortran.dg/pr104625.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/pr104649.f9044
-rw-r--r--gcc/testsuite/gm2/pim/fail/largeconst.mod2
-rw-r--r--gcc/testsuite/gm2/pim/fail/largeconst2.mod7
-rw-r--r--gcc/testsuite/gm2/pimlib/run/pass/testgetopt.mod74
-rw-r--r--gcc/testsuite/gm2/pimlib/run/pass/testnan.mod17
-rw-r--r--gcc/testsuite/lib/asan-dg.exp2
-rw-r--r--gcc/testsuite/lib/atomic-dg.exp2
-rw-r--r--gcc/testsuite/lib/dg-pch.exp24
-rw-r--r--gcc/testsuite/lib/target-libpath.exp23
-rw-r--r--gcc/testsuite/lib/target-supports-dg.exp40
-rw-r--r--gcc/testsuite/lib/target-supports.exp96
-rw-r--r--gcc/toplev.cc21
-rw-r--r--gcc/toplev.h3
-rw-r--r--gcc/tree-cfg.cc6
-rw-r--r--gcc/tree-core.h8
-rw-r--r--gcc/tree-diagnostic.cc2
-rw-r--r--gcc/tree-eh.cc4
-rw-r--r--gcc/tree-eh.h2
-rw-r--r--gcc/tree-inline.cc28
-rw-r--r--gcc/tree-nested.cc2
-rw-r--r--gcc/tree-object-size.cc12
-rw-r--r--gcc/tree-pretty-print.cc8
-rw-r--r--gcc/tree-scalar-evolution.cc59
-rw-r--r--gcc/tree-scalar-evolution.h2
-rw-r--r--gcc/tree-sra.cc3
-rw-r--r--gcc/tree-ssa-loop-ivopts.cc3
-rw-r--r--gcc/tree-ssa-loop-unswitch.cc5
-rw-r--r--gcc/tree-ssa-phiopt.cc16
-rw-r--r--gcc/tree-vect-loop-manip.cc49
-rw-r--r--gcc/tree-vect-loop.cc13
-rw-r--r--gcc/tree-vect-slp.cc11
-rw-r--r--gcc/tree-vect-stmts.cc149
-rw-r--r--gcc/tree.cc2
-rw-r--r--gcc/tree.h2
-rw-r--r--gcc/value-range.cc45
-rw-r--r--gcc/value-range.h1
-rw-r--r--gcc/var-tracking.cc14
-rw-r--r--gcc/varasm.cc13
-rw-r--r--include/ChangeLog4
-rw-r--r--include/gomp-constants.h2
-rw-r--r--libatomic/ChangeLog30
-rw-r--r--libatomic/Makefile.am3
-rw-r--r--libatomic/Makefile.in4
-rwxr-xr-xlibatomic/configure7
-rw-r--r--libatomic/configure.ac2
-rw-r--r--libatomic/testsuite/Makefile.in1
-rw-r--r--libatomic/testsuite/lib/libatomic.exp13
-rw-r--r--libatomic/testsuite/libatomic-site-extra.exp.in2
-rw-r--r--libbacktrace/ChangeLog5
-rw-r--r--libcc1/ChangeLog4
-rw-r--r--libcpp/ChangeLog30
-rw-r--r--libcpp/directives.cc3
-rw-r--r--libcpp/identifiers.cc42
-rw-r--r--libcpp/include/cpplib.h21
-rw-r--r--libcpp/include/line-map.h19
-rw-r--r--libcpp/include/symtab.h6
-rw-r--r--libcpp/init.cc4
-rw-r--r--libcpp/internal.h8
-rw-r--r--libcpp/lex.cc10
-rw-r--r--libcpp/line-map.cc4
-rw-r--r--libffi/ChangeLog25
-rw-r--r--libffi/Makefile.in1
-rwxr-xr-xlibffi/configure10
-rw-r--r--libffi/configure.ac5
-rw-r--r--libffi/include/Makefile.in1
-rw-r--r--libffi/man/Makefile.in1
-rw-r--r--libffi/testsuite/Makefile.in1
-rw-r--r--libffi/testsuite/lib/libffi.exp18
-rw-r--r--libgcc/ChangeLog36
-rw-r--r--libgcc/config/aarch64/heap-trampoline.c5
-rw-r--r--libgcc/config/i386/heap-trampoline.c5
-rw-r--r--libgcc/hardcfr.c2
-rw-r--r--libgfortran/ChangeLog7
-rw-r--r--libgm2/ChangeLog49
-rw-r--r--libgm2/Makefile.in10
-rw-r--r--libgm2/aclocal.m410
-rw-r--r--libgm2/config.h.in9
-rwxr-xr-xlibgm2/configure147
-rw-r--r--libgm2/configure.ac7
-rw-r--r--libgm2/libm2cor/Makefile.in10
-rw-r--r--libgm2/libm2iso/Makefile.in10
-rw-r--r--libgm2/libm2iso/wrapclock.cc9
-rw-r--r--libgm2/libm2log/Makefile.in10
-rw-r--r--libgm2/libm2min/Makefile.in10
-rw-r--r--libgm2/libm2pim/Makefile.in10
-rw-r--r--libgm2/libm2pim/cgetopt.cc1028
-rw-r--r--libgm2/libm2pim/wrapc.cc39
-rw-r--r--libgo/go/syscall/errstr.go2
-rw-r--r--libgomp/ChangeLog33
-rw-r--r--libgomp/oacc-parallel.c8
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-8.c29
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/if-self-1.c36
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/self-1.c967
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/if-1.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/self-1.f90995
-rw-r--r--libitm/ChangeLog12
-rw-r--r--libitm/testsuite/lib/libitm.exp1
-rw-r--r--libitm/testsuite/libitm.c++/c++.exp4
-rw-r--r--libobjc/ChangeLog5
-rw-r--r--libphobos/ChangeLog14
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d167
-rw-r--r--libphobos/libdruntime/core/internal/array/utils.d236
-rw-r--r--libphobos/libdruntime/core/lifetime.d13
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/ifaddrs.d41
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/net/if_dl.d42
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/socket.d131
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/types.d58
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/types.d4
-rw-r--r--libphobos/libdruntime/object.d2
-rw-r--r--libphobos/libdruntime/rt/lifetime.d26
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/parallelism.d2
-rw-r--r--libphobos/src/std/range/primitives.d10
-rw-r--r--libphobos/src/std/traits.d57
-rw-r--r--libquadmath/ChangeLog14
-rw-r--r--libquadmath/Makefile.in1
-rwxr-xr-xlibquadmath/configure147
-rw-r--r--libquadmath/configure.ac2
-rw-r--r--libsanitizer/ChangeLog14
-rw-r--r--libssp/ChangeLog7
-rw-r--r--libstdc++-v3/ChangeLog72
-rw-r--r--libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver4
-rw-r--r--libstdc++-v3/include/Makefile.am6
-rw-r--r--libstdc++-v3/include/Makefile.in6
-rw-r--r--libstdc++-v3/include/std/shared_mutex2
-rw-r--r--libstdc++-v3/src/experimental/contract.cc9
-rw-r--r--libstdc++-v3/src/libbacktrace/Makefile.am8
-rw-r--r--libstdc++-v3/src/libbacktrace/Makefile.in7
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/io.cc1
-rw-r--r--libstdc++-v3/testsuite/30_threads/shared_lock/locking/112089.cc23
-rw-r--r--libstdc++-v3/testsuite/std/time/day/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/format.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/month/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/month_day/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/month_day_last/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/month_weekday/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/month_weekday_last/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/weekday/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/weekday_indexed/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/weekday_last/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/year/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/year_month/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/year_month_day/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/year_month_day_last/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/year_month_weekday/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/year_month_weekday_last/io.cc1
-rw-r--r--libstdc++-v3/testsuite/std/time/zoned_time/io.cc1
-rw-r--r--libvtv/ChangeLog5
-rw-r--r--lto-plugin/ChangeLog5
-rw-r--r--zlib/ChangeLog5
976 files changed, 27240 insertions, 6185 deletions
diff --git a/ChangeLog b/ChangeLog
index af92edb..d813f52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Do not add default runpaths to GCC exes
+ when we are building -static-libstdc++/-static-libgcc (the
+ default).
+ * libtool.m4: Add 'enable-darwin-at-runpath'. Act on the
+ enable flag to alter Darwin libraries to use @rpath names.
+
2023-10-15 Mike Frysinger <vapier@gentoo.org>
* Makefile.def: Add distclean-sim dependency on distclean-gnulib.
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index 5b49d87..3d5b2d2 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,7 @@
+2023-10-30 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+
2023-08-17 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* inclhack.def (darwin_flt_eval_method): Handle macOS 14 guard
diff --git a/fixincludes/configure b/fixincludes/configure
index b977048..1bb547a 100755
--- a/fixincludes/configure
+++ b/fixincludes/configure
@@ -3027,6 +3027,7 @@ 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])
# ----------------------------
@@ -3049,7 +3050,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# the compiler configuration to `libtool'.
# _LT_LANG_CXX_CONFIG
-
# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
# ---------------------------------
# Figure out "hidden" library dependencies from verbose
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9b4542e..f2a6852 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,1454 @@
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (ANALYZER_OBJS): Add analyzer/record-layout.o.
+
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * input.cc (dump_location_info): Update for removal of
+ MACRO_MAP_EXPANSION_POINT_LOCATION.
+ * tree-diagnostic.cc (maybe_unwind_expanded_macro_loc):
+ Likewise.
+
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * opts.cc (get_option_url): Update comment; the requirement to
+ pass DOCUMENTATION_ROOT_URL's value via -D was removed in
+ r10-8065-ge33a1eae25b8a8.
+
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * pretty-print.cc (pretty_printer::pretty_printer): Initialize
+ m_skipping_null_url.
+ (pp_begin_url): Handle URL being null.
+ (pp_end_url): Likewise.
+ (selftest::test_null_urls): New.
+ (selftest::pretty_print_cc_tests): Call it.
+ * pretty-print.h (pretty_printer::m_skipping_null_url): New.
+
+2023-10-31 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * tree-vect-slp.cc (vect_get_operand_map): Add MASK_LEN_GATHER_LOAD.
+ (vect_build_slp_tree_1): Ditto.
+ (vect_build_slp_tree_2): Ditto.
+
+2023-10-31 Cupertino Miranda <cupertino.miranda@oracle.com>
+
+ * config/bpf/bpf-passes.def (pass_lower_bpf_core): Added pass.
+ * config/bpf/bpf-protos.h: Added prototype for new pass.
+ * config/bpf/bpf.cc (bpf_delegitimize_address): New function.
+ * config/bpf/bpf.md (mov_reloc_core<MM:mode>): Prefixed
+ name with '*'.
+ * config/bpf/core-builtins.cc (cr_builtins) Added access_node to
+ struct.
+ (is_attr_preserve_access): Improved check.
+ (core_field_info): Make use of root_for_core_field_info
+ function.
+ (process_field_expr): Adapted to new functions.
+ (pack_type): Small improvement.
+ (bpf_handle_plugin_finish_type): Adapted to GTY(()).
+ (bpf_init_core_builtins): Changed to new function names.
+ (construct_builtin_core_reloc): Improved implementation.
+ (bpf_resolve_overloaded_core_builtin): Changed how
+ __builtin_preserve_access_index is converted.
+ (compute_field_expr): Corrected implementation. Added
+ access_node argument.
+ (bpf_core_get_index): Added valid argument.
+ (root_for_core_field_info, pack_field_expr)
+ (core_expr_with_field_expr_plus_base, make_core_safe_access_index)
+ (replace_core_access_index_comp_expr, maybe_get_base_for_field_expr)
+ (core_access_clean, core_is_access_index, core_mark_as_access_index)
+ (make_gimple_core_safe_access_index, execute_lower_bpf_core)
+ (make_pass_lower_bpf_core): Added functions.
+ (pass_data_lower_bpf_core): New pass struct.
+ (pass_lower_bpf_core): New gimple_opt_pass class.
+ (pack_field_expr_for_preserve_field)
+ (bpf_replace_core_move_operands): Removed function.
+ (bpf_enum_value_kind): Added GTY(()).
+ * config/bpf/core-builtins.h (bpf_field_info_kind, bpf_type_id_kind)
+ (bpf_type_info_kind, bpf_enum_value_kind): New enum.
+ * config/bpf/t-bpf: Added pass bpf-passes.def to PASSES_EXTRA.
+
+2023-10-31 Neal Frager <neal.frager@amd.com>
+
+ * config/microblaze/microblaze.cc: Fix mcpu version check.
+
+2023-10-31 Patrick O'Neill <patrick@rivosinc.com>
+
+ * config/riscv/sync-rvwmo.md (atomic_load_rvwmo<mode>): Remove
+ TARGET_ATOMIC constraint
+ (atomic_store_rvwmo<mode>): Ditto.
+ * config/riscv/sync-ztso.md (atomic_load_ztso<mode>): Ditto.
+ (atomic_store_ztso<mode>): Ditto.
+ * config/riscv/sync.md (atomic_load<mode>): Ditto.
+ (atomic_store<mode>): Ditto.
+
+2023-10-31 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * config/riscv/riscv.cc (riscv_index_reg_class):
+ Return GR_REGS for XTheadFMemIdx.
+ (riscv_regno_ok_for_index_p): Add support for XTheadFMemIdx.
+ * config/riscv/riscv.h (HARDFP_REG_P): New macro.
+ * config/riscv/thead.cc (is_fmemidx_mode): New function.
+ (th_memidx_classify_address_index): Add support for XTheadFMemIdx.
+ (th_fmemidx_output_index): New function.
+ (th_output_move): Add support for XTheadFMemIdx.
+ * config/riscv/thead.md (TH_M_ANYF): New mode iterator.
+ (TH_M_NOEXTF): Likewise.
+ (*th_fmemidx_movsf_hardfloat): New INSN.
+ (*th_fmemidx_movdf_hardfloat_rv64): Likewise.
+ (*th_fmemidx_I_a): Likewise.
+ (*th_fmemidx_I_c): Likewise.
+ (*th_fmemidx_US_a): Likewise.
+ (*th_fmemidx_US_c): Likewise.
+ (*th_fmemidx_UZ_a): Likewise.
+ (*th_fmemidx_UZ_c): Likewise.
+
+2023-10-31 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * config/riscv/constraints.md (th_m_mia): New constraint.
+ (th_m_mib): Likewise.
+ (th_m_mir): Likewise.
+ (th_m_miu): Likewise.
+ * config/riscv/riscv-protos.h (enum riscv_address_type):
+ Add new address types ADDRESS_REG_REG, ADDRESS_REG_UREG,
+ and ADDRESS_REG_WB and their documentation.
+ (struct riscv_address_info): Add new field 'shift' and
+ document the field usage for the new address types.
+ (riscv_valid_base_register_p): New prototype.
+ (th_memidx_legitimate_modify_p): Likewise.
+ (th_memidx_legitimate_index_p): Likewise.
+ (th_classify_address): Likewise.
+ (th_output_move): Likewise.
+ (th_print_operand_address): Likewise.
+ * config/riscv/riscv.cc (riscv_index_reg_class):
+ Return GR_REGS for XTheadMemIdx.
+ (riscv_regno_ok_for_index_p): Add support for XTheadMemIdx.
+ (riscv_classify_address): Call th_classify_address() on top.
+ (riscv_output_move): Call th_output_move() on top.
+ (riscv_print_operand_address): Call th_print_operand_address()
+ on top.
+ * config/riscv/riscv.h (HAVE_POST_MODIFY_DISP): New macro.
+ (HAVE_PRE_MODIFY_DISP): Likewise.
+ * config/riscv/riscv.md (zero_extendqi<SUPERQI:mode>2): Disable
+ for XTheadMemIdx.
+ (*zero_extendqi<SUPERQI:mode>2_internal): Convert to expand,
+ create INSN with same name and disable it for XTheadMemIdx.
+ (extendsidi2): Likewise.
+ (*extendsidi2_internal): Disable for XTheadMemIdx.
+ * config/riscv/thead.cc (valid_signed_immediate): New helper
+ function.
+ (th_memidx_classify_address_modify): New function.
+ (th_memidx_legitimate_modify_p): Likewise.
+ (th_memidx_output_modify): Likewise.
+ (is_memidx_mode): Likewise.
+ (th_memidx_classify_address_index): Likewise.
+ (th_memidx_legitimate_index_p): Likewise.
+ (th_memidx_output_index): Likewise.
+ (th_classify_address): Likewise.
+ (th_output_move): Likewise.
+ (th_print_operand_address): Likewise.
+ * config/riscv/thead.md (*th_memidx_operand): New splitter.
+ (*th_memidx_zero_extendqi<SUPERQI:mode>2): New INSN.
+ (*th_memidx_extendsidi2): Likewise.
+ (*th_memidx_zero_extendsidi2): Likewise.
+ (*th_memidx_zero_extendhi<GPR:mode>2): Likewise.
+ (*th_memidx_extend<SHORT:mode><SUPERQI:mode>2): Likewise.
+ (*th_memidx_bb_zero_extendsidi2): Likewise.
+ (*th_memidx_bb_zero_extendhi<GPR:mode>2): Likewise.
+ (*th_memidx_bb_extendhi<GPR:mode>2): Likewise.
+ (*th_memidx_bb_extendqi<SUPERQI:mode>2): Likewise.
+ (TH_M_ANYI): New mode iterator.
+ (TH_M_NOEXTI): Likewise.
+ (*th_memidx_I_a): New combiner optimization.
+ (*th_memidx_I_b): Likewise.
+ (*th_memidx_I_c): Likewise.
+ (*th_memidx_US_a): Likewise.
+ (*th_memidx_US_b): Likewise.
+ (*th_memidx_US_c): Likewise.
+ (*th_memidx_UZ_a): Likewise.
+ (*th_memidx_UZ_b): Likewise.
+ (*th_memidx_UZ_c): Likewise.
+
+2023-10-31 Carl Love <cel@us.ibm.com>
+
+ * doc/extend.texi (__builtin_bcdsub_le, __builtin_bcdsub_ge): Add
+ documentation for the builti-ins.
+
+2023-10-31 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/111971
+ * lra-constraints.cc: (process_alt_operands): Don't check start
+ hard regs for regs originated from register variables.
+
+2023-10-31 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md (<ieee_fmaxmin_op><mode>3): fmax/fmin
+ expanders.
+ (cond_<ieee_fmaxmin_op><mode>): Ditto.
+ (cond_len_<ieee_fmaxmin_op><mode>): Ditto.
+ (reduc_fmax_scal_<mode>): Ditto.
+ (reduc_fmin_scal_<mode>): Ditto.
+ * config/riscv/riscv-v.cc (needs_fp_rounding): Add fmin/fmax.
+ * config/riscv/vector-iterators.md (fmin): New UNSPEC.
+ (UNSPEC_VFMIN): Ditto.
+ * config/riscv/vector.md (@pred_<ieee_fmaxmin_op><mode>): Add
+ UNSPEC insn patterns.
+ (@pred_<ieee_fmaxmin_op><mode>_scalar): Ditto.
+
+2023-10-31 Robin Dapp <rdapp@ventanamicro.com>
+
+ PR bootstrap/84402
+ PR target/111600
+ * Makefile.in: Handle split insn-emit.cc.
+ * configure: Regenerate.
+ * configure.ac: Add --with-insnemit-partitions.
+ * genemit.cc (output_peephole2_scratches): Print to file instead
+ of stdout.
+ (print_code): Ditto.
+ (gen_rtx_scratch): Ditto.
+ (gen_exp): Ditto.
+ (gen_emit_seq): Ditto.
+ (emit_c_code): Ditto.
+ (gen_insn): Ditto.
+ (gen_expand): Ditto.
+ (gen_split): Ditto.
+ (output_add_clobbers): Ditto.
+ (output_added_clobbers_hard_reg_p): Ditto.
+ (print_overload_arguments): Ditto.
+ (print_overload_test): Ditto.
+ (handle_overloaded_code_for): Ditto.
+ (handle_overloaded_gen): Ditto.
+ (print_header): New function.
+ (handle_arg): New function.
+ (main): Split output into 10 files.
+ * gensupport.cc (count_patterns): New function.
+ * gensupport.h (count_patterns): Define.
+ * read-md.cc (md_reader::print_md_ptr_loc): Add file argument.
+ * read-md.h (class md_reader): Change definition.
+
+2023-10-31 Alexandre Oliva <oliva@adacore.com>
+
+ PR tree-optimization/111943
+ * gimple-harden-control-flow.cc: Adjust copyright year.
+ (rt_bb_visited): Add vfalse and vtrue data members.
+ Zero-initialize them in the ctor.
+ (rt_bb_visited::insert_exit_check_on_edge): Upon encountering
+ abnormal edges, insert initializers for vfalse and vtrue on
+ entry, and insert the check sequence guarded by a conditional
+ in the dest block.
+
+2023-10-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112305
+ * tree-scalar-evolution.h (expression_expensive): Adjust.
+ * tree-scalar-evolution.cc (expression_expensive): Record
+ when we see a COND_EXPR.
+ (final_value_replacement_loop): When the replacement contains
+ a COND_EXPR, rewrite it to defined overflow.
+ * tree-ssa-loop-ivopts.cc (may_eliminate_iv): Adjust.
+
+2023-10-31 Xi Ruoyao <xry111@xry111.site>
+
+ PR target/112299
+ * config/loongarch/loongarch-opts.h (HAVE_AS_TLS): Define to 0
+ if not defined yet.
+
+2023-10-31 Lehua Ding <lehua.ding@rivai.ai>
+
+ * gimple-match.h (gimple_match_op::gimple_match_op):
+ Add interfaces for more arguments.
+ (gimple_match_op::set_op): Add interfaces for more arguments.
+ * match.pd: Add support of combining cond_len_op + vec_cond
+
+2023-10-31 Haochen Jiang <haochen.jiang@intel.com>
+
+ * config/i386/avx512cdintrin.h (target): Push evex512 for
+ avx512cd.
+ * config/i386/avx512vlintrin.h (target): Split avx512cdvl part
+ out from avx512vl.
+ * config/i386/i386-builtin.def (BDESC): Do not check evex512
+ for builtins not needed.
+
+2023-10-31 Lehua Ding <lehua.ding@rivai.ai>
+
+ * config/riscv/autovec.md (<float_cvt><mode><vnnconvert>2):
+ Change to define_expand.
+
+2023-10-31 liuhongt <hongtao.liu@intel.com>
+
+ PR target/112276
+ * config/i386/mmx.md (*mmx_pblendvb_v8qi_1): Change
+ define_split to define_insn_and_split to handle
+ immediate_operand for comparison.
+ (*mmx_pblendvb_v8qi_2): Ditto.
+ (*mmx_pblendvb_<mode>_1): Ditto.
+ (*mmx_pblendvb_v4qi_2): Ditto.
+ (<code><mode>3): Remove define_split after it.
+ (<code>v8qi3): Ditto.
+ (<code><mode>3): Ditto.
+ (<ode>v2hi3): Ditto.
+
+2023-10-31 Andrew Pinski <pinskia@gmail.com>
+
+ * match.pd (`a == 1 ? b : a OP b`): New pattern.
+ (`a == -1 ? b : a & b`): New pattern.
+
+2023-10-31 Andrew Pinski <pinskia@gmail.com>
+
+ * match.pd: (`a == 0 ? b : b + a`,
+ `a == 0 ? b : b - a`): New patterns.
+
+2023-10-31 Neal Frager <neal.frager@amd.com>
+
+ * config/microblaze/microblaze.cc: Fix mcpu version check.
+
+2023-10-30 Mayshao <mayshao-oc@zhaoxin.com>
+
+ * common/config/i386/cpuinfo.h (get_zhaoxin_cpu): Recognize yongfeng.
+ * common/config/i386/i386-common.cc: Add yongfeng.
+ * common/config/i386/i386-cpuinfo.h (enum processor_subtypes):
+ Add ZHAOXIN_FAM7H_YONGFENG.
+ * config.gcc: Add yongfeng.
+ * config/i386/driver-i386.cc (host_detect_local_cpu):
+ Let -march=native recognize yongfeng processors.
+ * config/i386/i386-c.cc (ix86_target_macros_internal): Add yongfeng.
+ * config/i386/i386-options.cc (m_YONGFENG): New definition.
+ (m_ZHAOXIN): Ditto.
+ * config/i386/i386.h (enum processor_type): Add PROCESSOR_YONGFENG.
+ * config/i386/i386.md: Add yongfeng.
+ * config/i386/lujiazui.md: Fix typo.
+ * config/i386/x86-tune-costs.h (struct processor_costs):
+ Add yongfeng costs.
+ * config/i386/x86-tune-sched.cc (ix86_issue_rate): Add yongfeng.
+ (ix86_adjust_cost): Ditto.
+ * config/i386/x86-tune.def (X86_TUNE_SCHEDULE): Replace
+ m_LUJIAZUI with m_ZHAOXIN.
+ (X86_TUNE_PARTIAL_REG_DEPENDENCY): Ditto.
+ (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY): Ditto.
+ (X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY): Ditto.
+ (X86_TUNE_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY): Ditto.
+ (X86_TUNE_MOVX): Ditto.
+ (X86_TUNE_MEMORY_MISMATCH_STALL): Ditto.
+ (X86_TUNE_FUSE_CMP_AND_BRANCH_32): Ditto.
+ (X86_TUNE_FUSE_CMP_AND_BRANCH_64): Ditto.
+ (X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS): Ditto.
+ (X86_TUNE_FUSE_ALU_AND_BRANCH): Ditto.
+ (X86_TUNE_ACCUMULATE_OUTGOING_ARGS): Ditto.
+ (X86_TUNE_USE_LEAVE): Ditto.
+ (X86_TUNE_PUSH_MEMORY): Ditto.
+ (X86_TUNE_LCP_STALL): Ditto.
+ (X86_TUNE_INTEGER_DFMODE_MOVES): Ditto.
+ (X86_TUNE_OPT_AGU): Ditto.
+ (X86_TUNE_PREFER_KNOWN_REP_MOVSB_STOSB): Ditto.
+ (X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES): Ditto.
+ (X86_TUNE_USE_SAHF): Ditto.
+ (X86_TUNE_USE_BT): Ditto.
+ (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI): Ditto.
+ (X86_TUNE_ONE_IF_CONV_INSN): Ditto.
+ (X86_TUNE_AVOID_MFENCE): Ditto.
+ (X86_TUNE_EXPAND_ABS): Ditto.
+ (X86_TUNE_USE_SIMODE_FIOP): Ditto.
+ (X86_TUNE_USE_FFREEP): Ditto.
+ (X86_TUNE_EXT_80387_CONSTANTS): Ditto.
+ (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL): Ditto.
+ (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL): Ditto.
+ (X86_TUNE_SSE_TYPELESS_STORES): Ditto.
+ (X86_TUNE_SSE_LOAD0_BY_PXOR): Ditto.
+ (X86_TUNE_USE_GATHER_2PARTS): Add m_YONGFENG.
+ (X86_TUNE_USE_GATHER_4PARTS): Ditto.
+ (X86_TUNE_USE_GATHER_8PARTS): Ditto.
+ (X86_TUNE_AVOID_128FMA_CHAINS): Ditto.
+ * doc/extend.texi: Add details about yongfeng.
+ * doc/invoke.texi: Ditto.
+ * config/i386/yongfeng.md: New file to describe yongfeng processor.
+
+2023-10-30 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/111157
+ * ipa-prop.h (struct ipa_argagg_value): Newf flag killed.
+ * ipa-modref.cc (ipcp_argagg_and_kill_overlap_p): New function.
+ (update_signature): Mark any any IPA-CP aggregate constants at
+ positions known to be killed as killed. Move check that there is
+ clone_info after this pruning.
+ * ipa-cp.cc (ipa_argagg_value_list::dump): Dump the killed flag.
+ (ipa_argagg_value_list::push_adjusted_values): Clear the new flag.
+ (push_agg_values_from_plats): Likewise.
+ (ipa_push_agg_values_from_jfunc): Likewise.
+ (estimate_local_effects): Likewise.
+ (push_agg_values_for_index_from_edge): Likewise.
+ * ipa-prop.cc (write_ipcp_transformation_info): Stream the killed
+ flag.
+ (read_ipcp_transformation_info): Likewise.
+ (ipcp_get_aggregate_const): Update comment, assert that encountered
+ record does not have killed flag set.
+ (ipcp_transform_function): Prune all aggregate constants with killed
+ set.
+
+2023-10-30 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/111157
+ * ipa-prop.h (ipcp_transformation): New member function template
+ remove_argaggs_if.
+ * ipa-sra.cc (zap_useless_ipcp_results): Use remove_argaggs_if to
+ filter aggreagate constants.
+
+2023-10-30 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR middle-end/101955
+ * config/arc/arc.md (*extvsi_1_0): New define_insn_and_split
+ to convert sign extract of the least significant bit into an
+ AND $1 then a NEG when !TARGET_BARREL_SHIFTER.
+
+2023-10-30 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/arc/arc.cc (arc_rtx_costs): Improve cost estimates.
+ Provide reasonable values for SHIFTS and ROTATES by constant
+ bit counts depending upon TARGET_BARREL_SHIFTER.
+ (arc_insn_cost): Use insn attributes if the instruction is
+ recognized. Avoid calling get_attr_length for type "multi",
+ i.e. define_insn_and_split patterns without explicit type.
+ Fall-back to set_rtx_cost for single_set and pattern_cost
+ otherwise.
+ * config/arc/arc.h (COSTS_N_BYTES): Define helper macro.
+ (BRANCH_COST): Improve/correct definition.
+ (LOGICAL_OP_NON_SHORT_CIRCUIT): Preserve previous behavior.
+
+2023-10-30 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/arc/arc.cc (arc_split_ashl): Use lsl16 on TARGET_SWAP.
+ (arc_split_ashr): Use swap and sign-extend on TARGET_SWAP.
+ (arc_split_lshr): Use lsr16 on TARGET_SWAP.
+ (arc_split_rotl): Use swap on TARGET_SWAP.
+ (arc_split_rotr): Likewise.
+ * config/arc/arc.md (ANY_ROTATE): New code iterator.
+ (<ANY_ROTATE>si2_cnt16): New define_insn for alternate form of
+ swap instruction on TARGET_SWAP.
+ (ashlsi2_cnt16): Rename from *ashlsi16_cnt16 and move earlier.
+ (lshrsi2_cnt16): New define_insn for LSR16 instruction.
+ (*ashlsi2_cnt16): See above.
+
+2023-10-30 Richard Ball <richard.ball@arm.com>
+
+ * config/arm/aout.h: Change to use the Lrtx label.
+ * config/arm/arm.h (CASE_VECTOR_PC_RELATIVE): Remove arm targets
+ from (!target_pure_code) condition.
+ (ADDR_VEC_ALIGN): Add align for tables in rodata section.
+ * config/arm/arm.cc (arm_output_casesi): Alter the function to include
+ .Lrtx label and remove adr instructions.
+ * config/arm/arm.md
+ (arm_casesi_internal): Use force_reg to generate ldr instructions that
+ would otherwise be out of range, and change rtl to accommodate force reg.
+ Additionally remove unnecessary register temp.
+ (casesi): Remove pure code check for Arm.
+ * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Remove arm
+ targets from JUMP_TABLES_IN_TEXT_SECTION definition.
+
+2023-10-30 Jeevitha Palanisamy <jeevitha@linux.ibm.com>
+
+ PR target/106907
+ * config/rs6000/rs6000.cc (altivec_expand_vec_perm_const): Change bitwise
+ xor to an equality and fix comment indentation.
+
+2023-10-30 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-protos.h (sew64_scalar_helper): Fix bug.
+ * config/riscv/riscv-v.cc (sew64_scalar_helper): Ditto.
+ * config/riscv/vector.md: Ditto.
+
+2023-10-30 liuhongt <hongtao.liu@intel.com>
+
+ PR target/104610
+ * config/i386/i386-expand.cc (ix86_expand_branch): Handle
+ 512-bit vector with vpcmpeq + kortest.
+ * config/i386/i386.md (cbranchxi4): New expander.
+ * config/i386/sse.md: (cbranch<mode>4): Extend to V16SImode
+ and V8DImode.
+
+2023-10-30 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ PR target/111449
+ * expr.cc (qi_vector_mode_supported_p): Rename to...
+ (by_pieces_mode_supported_p): ...this, and extends it to do
+ the checking for both scalar and vector mode.
+ (widest_fixed_size_mode_for_size): Call
+ by_pieces_mode_supported_p to examine the mode.
+ (op_by_pieces_d::smallest_fixed_size_mode_for_size): Likewise.
+
+2023-10-29 Martin Uecker <uecker@tugraz.at>
+
+ PR tree-optimization/109334
+ * tree-object-size.cc (parm_object_size): Allow size
+ computation for implicit access attributes.
+
+2023-10-29 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config/xtensa/xtensa.h (TARGET_SALT): Change HW version from
+ 260000 (which corresponds to RF-2014.0) to 270000 (which
+ corresponds to RG-2015.0, the release where salt/saltu opcodes
+ were introduced).
+
+2023-10-29 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/riscv-avlprop.cc (pass_avlprop::execute): Use
+ reference type to prevent copying.
+
+2023-10-27 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/112107
+ * ira-costs.cc: (calculate_equiv_gains): Use NONDEBUG_INSN_P
+ instead of INSN_P.
+
+2023-10-27 Andrew Stubbs <ams@codesourcery.com>
+
+ PR target/112088
+ * config/gcn/gcn.cc (gcn_expand_epilogue): Fix kernel epilogue register
+ conflict.
+
+2023-10-27 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/gcn-valu.md
+ (vec_extract<V_1REG:mode><V_1REG_ALT:mode>_nop): Mention "operands" in
+ condition to silence the warnings.
+ (vec_extract<V_2REG:mode><V_2REG_ALT:mode>_nop): Likewise.
+ * config/gcn/gcn.md (*movti_insn): Likewise.
+
+2023-10-27 Richard Sandiford <richard.sandiford@arm.com>
+
+ * recog.cc (insn_propagation::apply_to_pattern_1): Handle shared
+ ASM_OPERANDS.
+
+2023-10-27 Yangyu Chen <chenyangyu@isrc.iscas.ac.cn>
+
+ * config/riscv/riscv.cc (rocket_tune_info): Fix int_div cost.
+ (sifive_7_tune_info, thead_c906_tune_info): Likewise.
+
+2023-10-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md (rawmemchr<ANYI:mode>): New expander.
+ * config/riscv/riscv-protos.h (gen_no_side_effects_vsetvl_rtx):
+ Define.
+ (expand_rawmemchr): Define.
+ * config/riscv/riscv-v.cc (force_vector_length_operand): Remove
+ static.
+ (expand_block_move): Move from here...
+ * config/riscv/riscv-string.cc (expand_block_move): ...to here.
+ (expand_rawmemchr): Add vectorized expander.
+ * internal-fn.cc (expand_RAWMEMCHR): Fix typo.
+
+2023-10-27 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * ira-costs.cc: (get_equiv_regno, calculate_equiv_gains):
+ Process reg equivalence invariants.
+
+2023-10-27 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/x86-tune.def (X86_TUNE_PARTIAL_MEMORY_READ_STALL):
+ i386: Fiy typo in "partial_memory_read_stall" tune option.
+
+2023-10-27 Victor Do Nascimento <victor.donascimento@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_print_operand): Add
+ support for CONST_STRING.
+
+2023-10-27 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR target/110551
+ * config/i386/i386.md (<u>mul<mode><dwi>3): Make operands 1 and
+ 2 take "regiser_operand" and "nonimmediate_operand" respectively.
+ (<u>mulqihi3): Likewise.
+ (*bmi2_umul<mode><dwi>3_1): Operand 2 needs to be register_operand
+ matching the %d constraint. Use umul_highpart RTX to represent
+ the highpart multiplication.
+ (*umul<mode><dwi>3_1): Operand 2 should use regiser_operand
+ predicate, and "a" rather than "0" as operands 0 and 2 have
+ different modes.
+ (define_split): For mul to mulx conversion, use the new
+ umul_highpart RTX representation.
+ (*mul<mode><dwi>3_1): Operand 1 should be register_operand
+ and the constraint %a as operands 0 and 1 have different modes.
+ (*<u>mulqihi3_1): Operand 1 should be register_operand matching
+ the constraint %0.
+ (define_peephole2): Providing widening multiplication variants
+ of the peephole2s that tweak highpart multiplication register
+ allocation.
+
+2023-10-27 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/87299
+ * toplev.cc (no_backend): New static global.
+ (finalize): Remove argument no_backend, which is now a
+ static global.
+ (process_options): Likewise.
+ (do_compile): Likewise.
+ (target_reinit): Don't do anything in preprocess-only mode.
+ (toplev::main): Adapt to no_backend change.
+ (toplev::finalize): Likewise.
+
+2023-10-27 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/101590
+ PR tree-optimization/94884
+ * match.pd (`(X BIT_OP Y) CMP X`): New pattern.
+
+2023-10-27 liuhongt <hongtao.liu@intel.com>
+
+ PR target/103861
+ * config/i386/i386-expand.cc (ix86_expand_sse_movcc): Handle
+ V2HF/V2BF/V4HF/V4BFmode.
+ * config/i386/i386.cc (ix86_get_mask_mode): Return QImode when
+ data_mode is V4HF/V2HFmode.
+ * config/i386/mmx.md (vec_cmpv4hfqi): New expander.
+ (vcond_mask_<mode>v4hi): Ditto.
+ (vcond_mask_<mode>qi): Ditto.
+ (vec_cmpv2hfqi): Ditto.
+ (vcond_mask_<mode>v2hi): Ditto.
+ (mmx_plendvb_<mode>): Add 2 combine splitters after the
+ patterns.
+ (mmx_pblendvb_v8qi): Ditto.
+ (<code>v2hi3): Add a combine splitter after the pattern.
+ (<code><mode>3): Ditto.
+ (<code>v8qi3): Ditto.
+ (<code><mode>3): Ditto.
+ * config/i386/sse.md (vcond<mode><mode>): Merge this with ..
+ (vcond<sseintvecmodelower><mode>): .. this into ..
+ (vcond<VI2HFBF_AVX512VL:mode><VHF_AVX512VL:mode>): .. this,
+ and extend to V8BF/V16BF/V32BFmode.
+
+2023-10-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-opts.h (TARGET_MAX_LMUL): New macro.
+ * config/riscv/riscv-v.cc (preferred_simd_mode): Adapt macro.
+ (autovectorize_vector_modes): Ditto.
+ (can_find_related_mode_p): Ditto.
+
+2023-10-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/111318
+ PR target/111888
+ * config.gcc: Add AVL propagation pass.
+ * config/riscv/riscv-passes.def (INSERT_PASS_AFTER): Ditto.
+ * config/riscv/riscv-protos.h (make_pass_avlprop): Ditto.
+ * config/riscv/t-riscv: Ditto.
+ * config/riscv/riscv-avlprop.cc: New file.
+
+2023-10-26 David Malcolm <dmalcolm@redhat.com>
+
+ * doc/extend.texi (Common Function Attributes): Add
+ null_terminated_string_arg.
+
+2023-10-26 Andrew Pinski <pinskia@gmail.com>
+
+ PR tree-optimization/111957
+ * match.pd (`a != C1 ? abs(a) : C2`): New pattern.
+
+2023-10-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (range_operator::fold_range): Delete unused
+ variable.
+
+2023-10-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (range_operator::fold_range): Remove
+ superfluous code.
+ (range_operator::rv_fold): Remove unneeded arguments.
+ (operator_plus::rv_fold): Same.
+ (operator_minus::rv_fold): Same.
+ (operator_mult::rv_fold): Same.
+ (operator_div::rv_fold): Same.
+ * range-op-mixed.h: Remove lb, ub, and maybe_nan arguments from
+ rv_fold methods.
+ * range-op.h: Same.
+
+2023-10-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (range_operator::fold_range): Pass frange
+ argument to rv_fold.
+ (range_operator::rv_fold): Add frange argument.
+ (operator_plus::rv_fold): Same.
+ (operator_minus::rv_fold): Same.
+ (operator_mult::rv_fold): Same.
+ (operator_div::rv_fold): Same.
+ * range-op-mixed.h: Add frange argument to rv_fold methods.
+ * range-op.h: Same.
+
+2023-10-26 Richard Ball <richard.ball@arm.com>
+
+ * config/arm/aout.h (ASM_OUTPUT_ADDR_DIFF_ELT): Add table output
+ for different machine modes for arm.
+ * config/arm/arm-protos.h (arm_output_casesi): New prototype.
+ * config/arm/arm.h (CASE_VECTOR_PC_RELATIVE): Make arm use
+ ASM_OUTPUT_ADDR_DIFF_ELT.
+ (CASE_VECTOR_SHORTEN_MODE): Change table size calculation for
+ TARGET_ARM.
+ (LABEL_ALIGN_AFTER_BARRIER): Change to accommodate .p2align 2
+ for TARGET_ARM.
+ * config/arm/arm.cc (arm_output_casesi): New function.
+ * config/arm/arm.md (arm_casesi_internal): Change casesi expand
+ and insn.
+ for arm to use new function arm_output_casesi.
+
+2023-10-26 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.h
+ (darwin_label_is_anonymous_local_objc_name): Make metadata names
+ linker-visibile for GNU objective C.
+
+2023-10-26 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * dwarf2out.cc (reg_loc_descriptor): Use lra_eliminate_regs when
+ LRA is used.
+ * ira-costs.cc: Include regset.h.
+ (equiv_can_be_consumed_p, get_equiv_regno, calculate_equiv_gains):
+ New functions.
+ (find_costs_and_classes): Call calculate_equiv_gains and redefine
+ mem_cost of pseudos with equivs when LRA is used.
+ * var-tracking.cc: Include ira.h and lra.h.
+ (vt_initialize): Use lra_eliminate_regs when LRA is used.
+
+2023-10-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * doc/md.texi: Adapt COND_LEN pseudo code.
+
+2023-10-26 Roger Sayle <roger@nextmovesoftware.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR rtl-optimization/91865
+ * combine.cc (make_compound_operation): Avoid creating a
+ ZERO_EXTEND of a ZERO_EXTEND.
+
+2023-10-26 Jiahao Xu <xujiahao@loongson.cn>
+
+ * config/loongarch/lasx.md (vcond_mask_<ILASX:mode><ILASX:mode>): Change to
+ (vcond_mask_<mode><mode256_i>): this.
+ * config/loongarch/lsx.md (vcond_mask_<ILSX:mode><ILSX:mode>): Change to
+ (vcond_mask_<mode><mode_i>): this.
+
+2023-10-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ * ipa-icf.cc (sem_item::target_supports_symbol_aliases_p):
+ 'gcc_checking_assert (TARGET_SUPPORTS_ALIASES);' before
+ 'return true;'.
+ * ipa-visibility.cc (function_and_variable_visibility): Change
+ '#ifdef ASM_OUTPUT_DEF' to 'if (TARGET_SUPPORTS_ALIASES)'.
+ * varasm.cc (output_constant_pool_contents)
+ [#ifdef ASM_OUTPUT_DEF]:
+ 'gcc_checking_assert (TARGET_SUPPORTS_ALIASES);'.
+ (do_assemble_alias) [#ifdef ASM_OUTPUT_DEF]:
+ 'if (!TARGET_SUPPORTS_ALIASES)',
+ 'gcc_checking_assert (seen_error ());'.
+ (assemble_alias): Change '#if !defined (ASM_OUTPUT_DEF)' to
+ 'if (!TARGET_SUPPORTS_ALIASES)'.
+ (default_asm_output_anchor):
+ 'gcc_checking_assert (TARGET_SUPPORTS_ALIASES);'.
+
+2023-10-26 Alexandre Oliva <oliva@adacore.com>
+
+ PR tree-optimization/111520
+ * gimple-harden-conditionals.cc
+ (pass_harden_compares::execute): Set EH edge probability and
+ EH block execution count.
+
+2023-10-26 Alexandre Oliva <oliva@adacore.com>
+
+ * tree-eh.h (make_eh_edges): Rename to...
+ (make_eh_edge): ... this.
+ * tree-eh.cc: Likewise. Adjust all callers...
+ * gimple-harden-conditionals.cc: ... here, ...
+ * gimple-harden-control-flow.cc: ... here, ...
+ * tree-cfg.cc: ... here, ...
+ * tree-inline.cc: ... and here.
+
+2023-10-25 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.cc (darwin_override_options): Handle fPIE.
+
+2023-10-25 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config.gcc: Use -E to to sed to indicate that we are using
+ extended REs.
+
+2023-10-25 Jason Merrill <jason@redhat.com>
+
+ * tree-core.h (struct tree_base): Update address_space comment.
+
+2023-10-25 Wilco Dijkstra <wilco.dijkstra@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_internal_mov_immediate)
+ Add support for immediates using MOV/EOR bitmask.
+
+2023-10-25 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/111698
+ * config/i386/x86-tune.def (X86_TUNE_PARTIAL_MEMORY_READ_STALL):
+ New tune.
+ * config/i386/i386.h (TARGET_PARTIAL_MEMORY_READ_STALL): New macro.
+ * config/i386/i386.md: New peephole pattern to narrow test
+ instructions with immediate operands that test memory locations
+ for zero.
+
+2023-10-25 Andrew MacLeod <amacleod@redhat.com>
+
+ * value-range.cc (irange::union_append): New.
+ (irange::union_): Call union_append when appropriate.
+ * value-range.h (irange::union_append): New prototype.
+
+2023-10-25 Chenghui Pan <panchenghui@loongson.cn>
+
+ * config/loongarch/lasxintrin.h (__lasx_xvftintrnel_l_s): Fix comments.
+ (__lasx_xvfrintrne_s): Ditto.
+ (__lasx_xvfrintrne_d): Ditto.
+ (__lasx_xvfrintrz_s): Ditto.
+ (__lasx_xvfrintrz_d): Ditto.
+ (__lasx_xvfrintrp_s): Ditto.
+ (__lasx_xvfrintrp_d): Ditto.
+ (__lasx_xvfrintrm_s): Ditto.
+ (__lasx_xvfrintrm_d): Ditto.
+ * config/loongarch/lsxintrin.h (__lsx_vftintrneh_l_s): Ditto.
+ (__lsx_vfrintrne_s): Ditto.
+ (__lsx_vfrintrne_d): Ditto.
+ (__lsx_vfrintrz_s): Ditto.
+ (__lsx_vfrintrz_d): Ditto.
+ (__lsx_vfrintrp_s): Ditto.
+ (__lsx_vfrintrp_d): Ditto.
+ (__lsx_vfrintrm_s): Ditto.
+ (__lsx_vfrintrm_d): Ditto.
+
+2023-10-25 chenxiaolong <chenxiaolong@loongson.cn>
+
+ * config/loongarch/loongarch.md (get_thread_pointer<mode>):Adds the
+ instruction template corresponding to the __builtin_thread_pointer
+ function.
+ * doc/extend.texi:Add the __builtin_thread_pointer function support
+ description to the documentation.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * Makefile.in (OBJS): Add rtl-ssa/movement.o.
+ * rtl-ssa/access-utils.h (accesses_include_nonfixed_hard_registers)
+ (single_set_info): New functions.
+ (remove_uses_of_def, accesses_reference_same_resource): Declare.
+ (insn_clobbers_resources): Likewise.
+ * rtl-ssa/accesses.cc (rtl_ssa::remove_uses_of_def): New function.
+ (rtl_ssa::accesses_reference_same_resource): Likewise.
+ (rtl_ssa::insn_clobbers_resources): Likewise.
+ * rtl-ssa/movement.h (can_move_insn_p): Declare.
+ * rtl-ssa/movement.cc: New file.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/functions.h (function_info::remains_available_at_insn):
+ New member function.
+ * rtl-ssa/accesses.cc (function_info::remains_available_at_insn):
+ Likewise.
+ (function_info::make_use_available): Avoid false negatives for
+ queries within an EBB.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/changes.cc: Include sreal.h.
+ (rtl_ssa::changes_are_worthwhile): When optimizing for speed,
+ scale the cost of each instruction by its execution frequency.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/access-utils.h (next_call_clobbers): New function.
+ (is_single_dominating_def, remains_available_on_exit): Replace with...
+ * rtl-ssa/functions.h (function_info::is_single_dominating_def)
+ (function_info::remains_available_on_exit): ...these new member
+ functions.
+ (function_info::m_clobbered_by_calls): New member variable.
+ * rtl-ssa/functions.cc (function_info::function_info): Explicitly
+ initialize m_clobbered_by_calls.
+ * rtl-ssa/insns.cc (function_info::record_call_clobbers): Update
+ m_clobbered_by_calls for each call-clobber note.
+ * rtl-ssa/member-fns.inl (function_info::is_single_dominating_def):
+ New function. Check for call clobbers.
+ * rtl-ssa/accesses.cc (function_info::remains_available_on_exit):
+ Likewise.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/internals.h (build_info::exit_block_dominator): New
+ member variable.
+ * rtl-ssa/blocks.cc (build_info::build_info): Initialize it.
+ (bb_walker::bb_walker): Use it, moving the computation of the
+ dominator to...
+ (function_info::process_all_blocks): ...here.
+ (function_info::place_phis): Add dominance frontiers for the
+ exit block.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/functions.h (function_info::process_uses_of_deleted_def):
+ New member function.
+ * rtl-ssa/changes.cc (function_info::process_uses_of_deleted_def):
+ Likewise.
+ (function_info::change_insns): Use it.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/changes.cc (function_info::finalize_new_accesses):
+ If a change describes a set of memory, ensure that that set
+ is kept, regardless of the insn pattern.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/changes.cc (function_info::apply_changes_to_insn): Remove
+ call to add_reg_unused_notes and instead...
+ (function_info::change_insns): ...use a separate loop here.
+
+2023-10-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/blocks.cc (function_info::add_artificial_accesses): Force
+ global registers to be live on exit. Handle any block with zero
+ successors like an exit block.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * omp-oacc-kernels-decompose.cc (omp_oacc_kernels_decompose_1):
+ Handle 'OMP_CLAUSE_SELF' like 'OMP_CLAUSE_IF'.
+ * omp-expand.cc (expand_omp_target): Handle 'OMP_CLAUSE_SELF' for
+ 'GF_OMP_TARGET_KIND_OACC_DATA_KERNELS'.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * tree-core.h (omp_clause_code): Move 'OMP_CLAUSE_SELF' after
+ 'OMP_CLAUSE_IF'.
+ * tree-pretty-print.cc (dump_omp_clause): Adjust.
+ * tree.cc (omp_clause_num_ops, omp_clause_code_name): Likewise.
+ * tree.h: Likewise.
+
+2023-10-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-protos.h (has_vl_op): Export from riscv-vsetvl to riscv-v
+ (tail_agnostic_p): Ditto.
+ (validate_change_or_fail): Ditto.
+ (nonvlmax_avl_type_p): Ditto.
+ (vlmax_avl_p): Ditto.
+ (get_sew): Ditto.
+ (enum vlmul_type): Ditto.
+ (count_regno_occurrences): Ditto.
+ * config/riscv/riscv-v.cc (has_vl_op): Ditto.
+ (get_default_ta): Ditto.
+ (tail_agnostic_p): Ditto.
+ (validate_change_or_fail): Ditto.
+ (nonvlmax_avl_type_p): Ditto.
+ (vlmax_avl_p): Ditto.
+ (get_sew): Ditto.
+ (enum vlmul_type): Ditto.
+ (get_vlmul): Ditto.
+ (count_regno_occurrences): Ditto.
+ * config/riscv/riscv-vsetvl.cc (vlmax_avl_p): Ditto.
+ (has_vl_op): Ditto.
+ (get_sew): Ditto.
+ (get_vlmul): Ditto.
+ (get_default_ta): Ditto.
+ (tail_agnostic_p): Ditto.
+ (count_regno_occurrences): Ditto.
+ (validate_change_or_fail): Ditto.
+
+2023-10-25 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * gimplify.cc (gimplify_scan_omp_clauses): Add OMP_CLAUSE_SELF case.
+ (gimplify_adjust_omp_clauses): Likewise.
+ * omp-expand.cc (expand_omp_target): Add OMP_CLAUSE_SELF expansion code,
+ * omp-low.cc (scan_sharing_clauses): Add OMP_CLAUSE_SELF case.
+ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_SELF enum.
+ * tree-nested.cc (convert_nonlocal_omp_clauses): Add OMP_CLAUSE_SELF
+ case.
+ (convert_local_omp_clauses): Likewise.
+ * tree-pretty-print.cc (dump_omp_clause): Add OMP_CLAUSE_SELF case.
+ * tree.cc (omp_clause_num_ops): Add OMP_CLAUSE_SELF entry.
+ (omp_clause_code_name): Likewise.
+ * tree.h (OMP_CLAUSE_SELF_EXPR): New macro.
+
+2023-10-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-protos.h (vlmax_avl_type_p): New function.
+ * config/riscv/riscv-v.cc (vlmax_avl_type_p): Ditto.
+ * config/riscv/riscv-vsetvl.cc (get_avl): Adapt function.
+ * config/riscv/vector.md: Change avl_type into avl_type_idx.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * recog.cc (constrain_operands): Remove UNARY_P handling.
+ * reload.cc (find_reloads): Likewise.
+
+2023-10-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * gcov-io.h: Fix record length encoding in comment.
+
+2023-10-24 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/i386/i386-features.cc (compute_convert_gain): Provide
+ more accurate values (sizes) for inter-unit moves with -Os.
+
+2023-10-24 Roger Sayle <roger@nextmovesoftware.com>
+ Claudiu Zissulescu <claziss@gmail.com>
+
+ * config/arc/arc-protos.h (output_shift): Rename to...
+ (output_shift_loop): Tweak API to take an explicit rtx_code.
+ (arc_split_ashl): Prototype new function here.
+ (arc_split_ashr): Likewise.
+ (arc_split_lshr): Likewise.
+ (arc_split_rotl): Likewise.
+ (arc_split_rotr): Likewise.
+ * config/arc/arc.cc (output_shift): Delete local prototype. Rename.
+ (output_shift_loop): New function replacing output_shift to output
+ a zero overheap loop for SImode shifts and rotates on ARC targets
+ without barrel shifter (i.e. no hardware support for these insns).
+ (arc_split_ashl): New helper function to split *ashlsi3_nobs.
+ (arc_split_ashr): New helper function to split *ashrsi3_nobs.
+ (arc_split_lshr): New helper function to split *lshrsi3_nobs.
+ (arc_split_rotl): New helper function to split *rotlsi3_nobs.
+ (arc_split_rotr): New helper function to split *rotrsi3_nobs.
+ (arc_print_operand): Correct whitespace.
+ (arc_rtx_costs): Likewise.
+ (hwloop_optimize): Likewise.
+ * config/arc/arc.md (ANY_SHIFT_ROTATE): New define_code_iterator.
+ (define_code_attr insn): New code attribute to map to pattern name.
+ (<ANY_SHIFT_ROTATE>si3): New expander unifying previous ashlsi3,
+ ashrsi3 and lshrsi3 define_expands. Adds rotlsi3 and rotrsi3.
+ (*<ANY_SHIFT_ROTATE>si3_nobs): New define_insn_and_split that
+ unifies the previous *ashlsi3_nobs, *ashrsi3_nobs and *lshrsi3_nobs.
+ We now call arc_split_<insn> in arc.cc to implement each split.
+ (shift_si3): Delete define_insn, all shifts/rotates are now split.
+ (shift_si3_loop): Rename to...
+ (<insn>si3_loop): define_insn to handle loop implementations of
+ SImode shifts and rotates, calling ouput_shift_loop for template.
+ (rotrsi3): Rename to...
+ (*rotrsi3_insn): define_insn for TARGET_BARREL_SHIFTER's ror.
+ (*rotlsi3): New define_insn_and_split to transform left rotates
+ into right rotates before reload.
+ (rotlsi3_cnt1): New define_insn_and_split to implement a left
+ rotate by one bit using an add.f followed by an adc.
+ * config/arc/predicates.md (shiftr4_operator): Delete.
+
+2023-10-24 Claudiu Zissulescu <claziss@gmail.com>
+
+ * config/arc/arc.md (mulsi3_700): Update pattern.
+ (mulsi3_v2): Likewise.
+ * config/arc/predicates.md (mpy_dest_reg_operand): Remove it.
+
+2023-10-24 Andrew Pinski <pinskia@gmail.com>
+
+ PR tree-optimization/104376
+ PR tree-optimization/101541
+ * tree-ssa-phiopt.cc (factor_out_conditional_operation):
+ Allow nop conversions even if it is defined by a statement
+ inside the conditional.
+
+2023-10-24 Andrew Pinski <pinskia@gmail.com>
+
+ PR tree-optimization/111913
+ * match.pd (`popcount(X&Y) + popcount(X|Y)`): Add the resulting
+ type for popcount.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/blocks.cc (function_info::create_degenerate_phi): Check
+ whether the requested phi already exists.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa.h: Include cfgbuild.h.
+ * rtl-ssa/movement.h (can_insert_after): Replace is_jump with the
+ more comprehensive control_flow_insn_p.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/changes.cc (function_info::perform_pending_updates): Check
+ whether an insn has been replaced by a note.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * rtl-ssa/member-fns.inl (first_any_insn_use): Handle null
+ m_first_use.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/i386/i386-expand.cc (ix86_split_mmx_punpck): Allow the
+ destination to be wider than the sources. Take the mode from the
+ first source.
+ (ix86_expand_sse_extend): Pass the destination directly to
+ ix86_split_mmx_punpck, rather than using a fresh register that
+ is half the size.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/i386/predicates.md (aeswidekl_operation): Protect
+ REGNO check with REG_P.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_insn_cost): New function.
+ (TARGET_INSN_COST): Define.
+
+2023-10-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/atomics.md (aarch64_atomic_exchange<mode>): Require
+ !TARGET_LSE.
+
+2023-10-24 xuli <xuli1@eswincomputing.com>
+
+ PR target/111935
+ * config/riscv/riscv-vector-builtins-bases.cc: fix bug.
+
+2023-10-24 Mark Harmstone <mark@harmstone.com>
+
+ * opts.cc (debug_type_names): Remove stabs and xcoff.
+ (df_set_names): Adjust.
+
+2023-10-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/111947
+ * config/riscv/riscv-vsetvl.cc (pre_vsetvl::compute_lcm_local_properties): Add REGNO check.
+
+2023-10-23 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/36887
+ * toplev.h (ident_hash_extra): Declare...
+ * stringpool.cc (ident_hash_extra): ...this new global variable.
+ (init_stringpool): Handle ident_hash_extra as well as ident_hash.
+ (ggc_mark_stringpool): Likewise.
+ (ggc_purge_stringpool): Likewise.
+ (struct string_pool_data_extra): New struct.
+ (spd2): New GC root variable.
+ (gt_pch_save_stringpool): Use spd2 to handle ident_hash_extra,
+ analogous to how spd is used to handle ident_hash.
+ (gt_pch_restore_stringpool): Likewise.
+
+2023-10-23 Robin Dapp <rdapp@ventanamicro.com>
+
+ PR tree-optimization/111794
+ * tree-vect-stmts.cc (vectorizable_assignment): Add
+ same-precision exception for dest and source.
+
+2023-10-23 Robin Dapp <rdapp@ventanamicro.com>
+
+ * config/riscv/autovec.md (popcount<mode>2): New expander.
+ * config/riscv/riscv-protos.h (expand_popcount): Define.
+ * config/riscv/riscv-v.cc (expand_popcount): Vectorize popcount
+ with the WWG algorithm.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/111916
+ * tree-sra.cc (sra_modify_assign): Do not lower all
+ BIT_FIELD_REF reads that are sra_handled_bf_read_p.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/111915
+ * tree-vect-slp.cc (vect_build_slp_tree_1): Check all
+ accesses are either grouped or not.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR ipa/111914
+ * tree-inline.cc (setup_one_parameter): Move code emitting
+ a dummy load when not optimizing ...
+ (initialize_inlined_parameters): ... here to after when
+ we remapped the parameter type.
+
+2023-10-23 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/111001
+ * config/sh/sh_treg_combine.cc (sh_treg_combine::record_set_of_reg):
+ Skip over nop move insns.
+
+2023-10-23 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/111860
+ * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg):
+ Drop .MEM nodes only.
+
+2023-10-23 Andrew Pinski <apinski@marvell.com>
+
+ * match.pd (`(A - B) CMP 0 ? (A - B) : (B - A)`):
+ New patterns.
+
+2023-10-23 Andrew Pinski <pinskia@gmail.com>
+
+ * convert.cc (convert_to_pointer_1): Return error_mark_node
+ after an error.
+ (convert_to_real_1): Likewise.
+ (convert_to_integer_1): Likewise.
+ (convert_to_complex_1): Likewise.
+
+2023-10-23 Andrew Pinski <pinskia@gmail.com>
+
+ PR c/111903
+ * convert.cc (convert_to_complex_1): Return
+ error_mark_node if either convert was an error
+ when converting from a scalar.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/111917
+ * tree-ssa-loop-unswitch.cc (hoist_guard): Always insert
+ new conditional after last stmt.
+
+2023-10-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/111927
+ * config/riscv/riscv-vsetvl.cc: Fix bug.
+
+2023-10-23 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/riscv-v.cc (emit_vec_cvt_x_f_rtz): Add insn type
+ arg.
+ (expand_vec_trunc): Take MA instead of MU for cvt_x_f_rtz.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * doc/invoke.texi (-mexplicit-relocs=style): Document.
+ (-mexplicit-relocs): Document as an alias of
+ -mexplicit-relocs=always.
+ (-mno-explicit-relocs): Document as an alias of
+ -mexplicit-relocs=none.
+ (-mcmodel=extreme): Mention -mexplicit-relocs=always instead of
+ -mexplicit-relocs.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/predicates.md (symbolic_pcrel_operand): New
+ predicate.
+ * config/loongarch/loongarch.md (define_peephole2): Optimize
+ la.local + ld/st to pcalau12i + ld/st if the address is only used
+ once if -mexplicit-relocs=auto and -mcmodel=normal or medium.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.cc (loongarch_explicit_relocs_p):
+ Return true for TLS symbol types if -mexplicit-relocs=auto.
+ (loongarch_call_tls_get_addr): Replace TARGET_EXPLICIT_RELOCS
+ with la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE.
+ (loongarch_legitimize_tls_address): Likewise.
+ * config/loongarch/loongarch.md (@tls_low<mode>): Remove
+ TARGET_EXPLICIT_RELOCS from insn condition.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch-protos.h
+ (loongarch_explicit_relocs_p): Declare new function.
+ * config/loongarch/loongarch.cc (loongarch_explicit_relocs_p):
+ Implement.
+ (loongarch_symbol_insns): Call loongarch_explicit_relocs_p for
+ SYMBOL_GOT_DISP, instead of using TARGET_EXPLICIT_RELOCS.
+ (loongarch_split_symbol): Call loongarch_explicit_relocs_p for
+ deciding if return early, instead of using
+ TARGET_EXPLICIT_RELOCS.
+ (loongarch_output_move): CAll loongarch_explicit_relocs_p
+ instead of using TARGET_EXPLICIT_RELOCS.
+ * config/loongarch/loongarch.md (*low<mode>): Remove
+ TARGET_EXPLICIT_RELOCS from insn condition.
+ (@ld_from_got<mode>): Likewise.
+ * config/loongarch/predicates.md (move_operand): Call
+ loongarch_explicit_relocs_p instead of using
+ TARGET_EXPLICIT_RELOCS.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/genopts/loongarch-strings: Add strings for
+ -mexplicit-relocs={auto,none,always}.
+ * config/loongarch/genopts/loongarch.opt.in: Add options for
+ -mexplicit-relocs={auto,none,always}.
+ * config/loongarch/loongarch-str.h: Regenerate.
+ * config/loongarch/loongarch.opt: Regenerate.
+ * config/loongarch/loongarch-def.h
+ (EXPLICIT_RELOCS_AUTO): Define.
+ (EXPLICIT_RELOCS_NONE): Define.
+ (EXPLICIT_RELOCS_ALWAYS): Define.
+ (N_EXPLICIT_RELOCS_TYPES): Define.
+ * config/loongarch/loongarch.cc
+ (loongarch_option_override_internal): Error out if the old-style
+ -m[no-]explicit-relocs option is used with
+ -mexplicit-relocs={auto,none,always} together. Map
+ -mno-explicit-relocs to -mexplicit-relocs=none and
+ -mexplicit-relocs to -mexplicit-relocs=always for backward
+ compatibility. Set a proper default for -mexplicit-relocs=
+ based on configure-time probed linker capability. Update a
+ diagnostic message to mention -mexplicit-relocs=always instead
+ of the old-style -mexplicit-relocs.
+ (loongarch_handle_model_attribute): Update a diagnostic message
+ to mention -mexplicit-relocs=always instead of the old-style
+ -mexplicit-relocs.
+ * config/loongarch/loongarch.h (TARGET_EXPLICIT_RELOCS): Define.
+
+2023-10-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-vsetvl.cc (pre_vsetvl::fuse_local_vsetvl_info): Fix typo.
+ (pre_vsetvl::pre_global_vsetvl_info): Ditto.
+
+2023-10-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/vector.md: Fix avl_type attribute of tuple mov<mode>.
+
+2023-10-23 Kewen Lin <linkw@linux.ibm.com>
+
+ PR tree-optimization/111784
+ * tree-vect-stmts.cc (vectorizable_store): Adjust costing way for
+ adjacent vector stores, by costing them with the total number
+ rather than costing them one by one.
+ (vectorizable_load): Adjust costing way for adjacent vector
+ loads, by costing them with the total number rather than costing
+ them one by one.
+
+2023-10-23 Haochen Jiang <haochen.jiang@intel.com>
+
+ PR target/111753
+ * config/i386/i386.cc (ix86_standard_x87sse_constant_load_p):
+ Do not split to xmm16+ when !TARGET_AVX512VL.
+
+2023-10-23 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/riscv-protos.h (enum insn_type): Add new type
+ values.
+ * config/riscv/riscv-v.cc (emit_vec_cvt_x_f): Add undef merge
+ operand handling.
+ (expand_vec_ceil): Take MA instead of MU for tmp register.
+ (expand_vec_floor): Ditto.
+ (expand_vec_nearbyint): Ditto.
+ (expand_vec_rint): Ditto.
+ (expand_vec_round): Ditto.
+ (expand_vec_roundeven): Ditto.
+
+2023-10-23 Lulu Cheng <chenglulu@loongson.cn>
+
+ * config/loongarch/loongarch.h (CLEAR_INSN_CACHE): New definition.
+
+2023-10-23 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ PR target/111449
+ * expr.cc (can_use_qi_vectors): New function to return true if
+ we know how to implement OP using vectors of bytes.
+ (qi_vector_mode_supported_p): New function to check if optabs
+ exists for the mode and certain by pieces operations.
+ (widest_fixed_size_mode_for_size): Replace the second argument
+ with the type of by pieces operations. Call can_use_qi_vectors
+ and qi_vector_mode_supported_p to do the check. Call
+ scalar_mode_supported_p to check if the scalar mode is supported.
+ (by_pieces_ninsns): Pass the type of by pieces operation to
+ widest_fixed_size_mode_for_size.
+ (class op_by_pieces_d): Remove m_qi_vector_mode. Add m_op to
+ record the type of by pieces operations.
+ (op_by_pieces_d::op_by_pieces_d): Change last argument to the
+ type of by pieces operations, initialize m_op with it. Pass
+ m_op to function widest_fixed_size_mode_for_size.
+ (op_by_pieces_d::get_usable_mode): Pass m_op to function
+ widest_fixed_size_mode_for_size.
+ (op_by_pieces_d::smallest_fixed_size_mode_for_size): Call
+ can_use_qi_vectors and qi_vector_mode_supported_p to do the
+ check.
+ (op_by_pieces_d::run): Pass m_op to function
+ widest_fixed_size_mode_for_size.
+ (move_by_pieces_d::move_by_pieces_d): Set m_op to MOVE_BY_PIECES.
+ (store_by_pieces_d::store_by_pieces_d): Set m_op with the op.
+ (can_store_by_pieces): Pass the type of by pieces operations to
+ widest_fixed_size_mode_for_size.
+ (clear_by_pieces): Initialize class store_by_pieces_d with
+ CLEAR_BY_PIECES.
+ (compare_by_pieces_d::compare_by_pieces_d): Set m_op to
+ COMPARE_BY_PIECES.
+
+2023-10-23 liuhongt <hongtao.liu@intel.com>
+
+ PR tree-optimization/111820
+ PR tree-optimization/111833
+ * tree-vect-loop-manip.cc (vect_can_peel_nonlinear_iv_p): Give
+ up vectorization for nonlinear iv vect_step_op_mul when
+ step_expr is not exact_log2 and niters is greater than
+ TYPE_PRECISION (TREE_TYPE (step_expr)). Also don't vectorize
+ for nagative niters_skip which will be used by fully masked
+ loop.
+ (vect_can_advance_ivs_p): Pass whole phi_info to
+ vect_can_peel_nonlinear_iv_p.
+ * tree-vect-loop.cc (vect_peel_nonlinear_iv_init): Optimize
+ init_expr * pow (step_expr, skipn) to init_expr
+ << (log2 (step_expr) * skipn) when step_expr is exact_log2.
+
+2023-10-23 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/mmx.md (mmx_pinsrw): Remove.
+
+2023-10-22 Andrew Pinski <pinskia@gmail.com>
+
+ PR target/110986
+ * config/aarch64/aarch64.md (*cmov<mode>_insn_insv): New pattern.
+ (*cmov_uxtw_insn_insv): Likewise.
+
+2023-10-22 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * doc/invoke.texi: Document the new -nodefaultrpaths option.
+ * doc/install.texi: Document the new --with-darwin-extra-rpath
+ option.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.in: set ENABLE_DARWIN_AT_RPATH in site.tmp.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure.ac: Add --with-darwin-extra-rpath option.
+ * config/darwin.h: Handle DARWIN_EXTRA_RPATH.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+ * config/darwin.h: Handle Darwin rpaths.
+ * config/darwin.opt: Handle Darwin rpaths.
+ * Makefile.in: Handle Darwin rpaths.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.cc (RUNPATH_OPTION): New.
+ (do_spec_1): Provide '%P' as a spec to insert rpaths for
+ each compiler startfile path.
+
+2023-10-22 Andrew Burgess <andrew.burgess@embecosm.com>
+ Maxim Blinov <maxim.blinov@embecosm.com>
+ Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+ Iain Sandoe <iain@sandoe.co.uk>
+
+ * config.gcc: Default to heap trampolines on macOS 11 and above.
+ * config/i386/darwin.h: Define X86_CUSTOM_FUNCTION_TEST.
+ * config/i386/i386.h: Define X86_CUSTOM_FUNCTION_TEST.
+ * config/i386/i386.cc: Use X86_CUSTOM_FUNCTION_TEST.
+
+2023-10-22 Andrew Burgess <andrew.burgess@embecosm.com>
+ Maxim Blinov <maxim.blinov@embecosm.com>
+ Iain Sandoe <iain@sandoe.co.uk>
+ Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * builtins.def (BUILT_IN_NESTED_PTR_CREATED): Define.
+ (BUILT_IN_NESTED_PTR_DELETED): Ditto.
+ * common.opt (ftrampoline-impl): Add option to control
+ generation of trampoline instantiation (heap or stack).
+ * coretypes.h: Define enum trampoline_impl.
+ * tree-nested.cc (convert_tramp_reference_op): Don't bother calling
+ __builtin_adjust_trampoline for heap trampolines.
+ (finalize_nesting_tree_1): Emit calls to
+ __builtin_nested_...{created,deleted} if we're generating with
+ -ftrampoline-impl=heap.
+ * tree.cc (build_common_builtin_nodes): Build
+ __builtin_nested_...{created,deleted}.
+ * doc/invoke.texi (-ftrampoline-impl): Document.
+
+2023-10-22 Tsukasa OI <research_trasio@irq.a4lg.com>
+
+ * common/config/riscv/riscv-common.cc (riscv_subset_list::parse):
+ Prohibit 'E' and 'H' combinations.
+
+2023-10-22 Tsukasa OI <research_trasio@irq.a4lg.com>
+
+ * common/config/riscv/riscv-common.cc (riscv_ext_version_table):
+ Change version number of the 'Zfa' extension to 1.0.
+
2023-10-21 Pan Li <pan2.li@intel.com>
PR target/111857
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 244ba03..7166a6c 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20231022
+20231101
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index bc6a76f..83f2946 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -236,6 +236,13 @@ GIMPLE_MATCH_PD_SEQ_O = $(patsubst %, gimple-match-%.o, $(MATCH_SPLITS_SEQ))
GENERIC_MATCH_PD_SEQ_SRC = $(patsubst %, generic-match-%.cc, $(MATCH_SPLITS_SEQ))
GENERIC_MATCH_PD_SEQ_O = $(patsubst %, generic-match-%.o, $(MATCH_SPLITS_SEQ))
+# The number of splits to be made for the insn-emit files.
+NUM_INSNEMIT_SPLITS = @DEFAULT_INSNEMIT_PARTITIONS@
+INSNEMIT_SPLITS_SEQ = $(wordlist 1,$(NUM_INSNEMIT_SPLITS),$(one_to_9999))
+INSNEMIT_SEQ_SRC = $(patsubst %, insn-emit-%.cc, $(INSNEMIT_SPLITS_SEQ))
+INSNEMIT_SEQ_TMP = $(patsubst %, tmp-emit-%.cc, $(INSNEMIT_SPLITS_SEQ))
+INSNEMIT_SEQ_O = $(patsubst %, insn-emit-%.o, $(INSNEMIT_SPLITS_SEQ))
+
# These files are to have specific diagnostics suppressed, or are not to
# be subject to -Werror:
# flex output may yield harmless "no previous prototype" warnings
@@ -1324,6 +1331,7 @@ ANALYZER_OBJS = \
analyzer/program-point.o \
analyzer/program-state.o \
analyzer/ranges.o \
+ analyzer/record-layout.o \
analyzer/region.o \
analyzer/region-model.o \
analyzer/region-model-asm.o \
@@ -1356,7 +1364,7 @@ OBJS = \
insn-attrtab.o \
insn-automata.o \
insn-dfatab.o \
- insn-emit.o \
+ $(INSNEMIT_SEQ_O) \
insn-extract.o \
insn-latencytab.o \
insn-modes.o \
@@ -1635,6 +1643,7 @@ OBJS = \
rtl-ssa/changes.o \
rtl-ssa/functions.o \
rtl-ssa/insns.o \
+ rtl-ssa/movement.o \
rtl-tests.o \
rtl.o \
rtlhash.o \
@@ -1856,7 +1865,8 @@ TREECHECKING = @TREECHECKING@
FULL_DRIVER_NAME=$(target_noncanonical)-gcc-$(version)$(exeext)
MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
- insn-output.cc insn-recog.cc insn-emit.cc insn-extract.cc insn-peep.cc \
+ insn-output.cc insn-recog.cc $(INSNEMIT_SEQ_SRC) \
+ insn-extract.cc insn-peep.cc \
insn-attr.h insn-attr-common.h insn-attrtab.cc insn-dfatab.cc \
insn-latencytab.cc insn-opinit.cc insn-opinit.h insn-preds.cc insn-constants.h \
tm-preds.h tm-constrs.h checksum-options $(GIMPLE_MATCH_PD_SEQ_SRC) \
@@ -2488,11 +2498,11 @@ $(common_out_object_file): $(common_out_file)
# and compile them.
.PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \
- insn-emit.cc insn-recog.cc insn-extract.cc insn-output.cc insn-peep.cc \
- insn-attr.h insn-attr-common.h insn-attrtab.cc insn-dfatab.cc \
- insn-latencytab.cc insn-preds.cc $(GIMPLE_MATCH_PD_SEQ_SRC) \
- $(GENERIC_MATCH_PD_SEQ_SRC) gimple-match-auto.h generic-match-auto.h \
- insn-target-def.h
+ $(INSNEMIT_SEQ_SRC) insn-recog.cc insn-extract.cc insn-output.cc \
+ insn-peep.cc insn-attr.h insn-attr-common.h insn-attrtab.cc \
+ insn-dfatab.cc insn-latencytab.cc insn-preds.cc \
+ $(GIMPLE_MATCH_PD_SEQ_SRC) $(GENERIC_MATCH_PD_SEQ_SRC) \
+ gimple-match-auto.h generic-match-auto.h insn-target-def.h
# Dependencies for the md file. The first time through, we just assume
# the md file itself and the generated dependency file (in order to get
@@ -2515,7 +2525,7 @@ s-mddeps: $(md_file) $(MD_INCLUDES) build/genmddeps$(build_exeext)
simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \
insn-config.h insn-flags.h insn-target-def.h
-simple_rtl_generated_c = insn-automata.cc insn-emit.cc \
+simple_rtl_generated_c = insn-automata.cc \
insn-extract.cc insn-output.cc \
insn-peep.cc insn-recog.cc
@@ -2544,8 +2554,20 @@ $(simple_generated_c:insn-%.cc=s-%): s-%: build/gen%$(build_exeext)
$(SHELL) $(srcdir)/../move-if-change tmp-$*.cc insn-$*.cc
$(STAMP) s-$*
+# genemit splits its output into different files and doesn't write to
+# stdout. (but rather to tmp-emit-01.cc..tmp-emit-10.cc)
+$(INSNEMIT_SEQ_SRC): s-tmp-emit; @true
+s-tmp-emit: build/genemit$(build_exeext) $(MD_DEPS) insn-conditions.md
+ $(RUN_GEN) build/genemit$(build_exeext) $(md_file) insn-conditions.md \
+ $(addprefix -O,${INSNEMIT_SEQ_TMP})
+ $(foreach id, $(INSNEMIT_SPLITS_SEQ), \
+ $(SHELL) $(srcdir)/../move-if-change tmp-emit-$(id).cc \
+ insn-emit-$(id).cc;)
+ $(STAMP) s-tmp-emit
+
# gencheck doesn't read the machine description, and the file produced
# doesn't use the insn-* convention.
+
tree-check.h: s-check ; @true
s-check : build/gencheck$(build_exeext)
$(RUN_GEN) build/gencheck$(build_exeext) > tmp-check.h
@@ -4245,6 +4267,9 @@ site.exp: ./config.status Makefile
echo "set COMPAT_OPTIONS \"$(COMPAT_OPTIONS)\"" >> ./site.tmp; \
else true; \
fi
+ @if test "x@enable_darwin_at_rpath@" = "xyes" ; then \
+ echo "set ENABLE_DARWIN_AT_RPATH 1" >> ./site.tmp; \
+ fi
@echo "## All variables above are generated by configure. Do Not Edit ##" >> ./site.tmp
@cat ./site.tmp > site.exp
@cat site.bak | sed \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 5b5a9ec..e628a73 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,7 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc-interface/Makefile.in: Handle Darwin rpaths.
+
2023-10-20 Alexandre Oliva <oliva@adacore.com>
* gcc-interface/trans.cc (gigi): Mark __gnat_reraise_zcx with
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 840de8c..8eecacf 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,38 @@
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * record-layout.cc: New file, based on material in region-model.cc.
+ * record-layout.h: Likewise.
+ * region-model.cc: Include "analyzer/record-layout.h".
+ (class record_layout): Move to record-layout.cc and .h
+
+2023-10-26 David Malcolm <dmalcolm@redhat.com>
+
+ * region-model.cc
+ (region_model::check_external_function_for_access_attr): Split
+ out, replacing with...
+ (region_model::check_function_attr_access): ...this new function
+ and...
+ (region_model::check_function_attrs): ...this new function.
+ (region_model::check_one_function_attr_null_terminated_string_arg):
+ New.
+ (region_model::check_function_attr_null_terminated_string_arg):
+ New.
+ (region_model::handle_unrecognized_call): Update for renaming of
+ check_external_function_for_access_attr to check_function_attrs.
+ (region_model::check_for_null_terminated_string_arg): Add return
+ value to one overload. Make both overloads const.
+ * region-model.h: Include "stringpool.h" and "attribs.h".
+ (region_model::check_for_null_terminated_string_arg): Add return
+ value to one overload. Make both overloads const.
+ (region_model::check_external_function_for_access_attr): Delete
+ decl.
+ (region_model::check_function_attr_access): New decl.
+ (region_model::check_function_attr_null_terminated_string_arg):
+ New decl.
+ (region_model::check_one_function_attr_null_terminated_string_arg):
+ New decl.
+ (region_model::check_function_attrs): New decl.
+
2023-10-09 David Malcolm <dmalcolm@redhat.com>
* access-diagram.cc (boundaries::add): Explicitly state
diff --git a/gcc/analyzer/record-layout.cc b/gcc/analyzer/record-layout.cc
new file mode 100644
index 0000000..1369bfb
--- /dev/null
+++ b/gcc/analyzer/record-layout.cc
@@ -0,0 +1,125 @@
+/* Implementation of class record_layout.
+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "diagnostic.h"
+#include "tree-diagnostic.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/record-layout.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* class record_layout. */
+
+record_layout::record_layout (tree record_type)
+{
+ gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
+
+ for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
+ iter = DECL_CHAIN (iter))
+ {
+ if (TREE_CODE (iter) == FIELD_DECL)
+ {
+ int iter_field_offset = int_bit_position (iter);
+ bit_size_t size_in_bits;
+ if (!int_size_in_bits (TREE_TYPE (iter), &size_in_bits))
+ size_in_bits = 0;
+
+ maybe_pad_to (iter_field_offset);
+
+ /* Add field. */
+ m_items.safe_push (item (bit_range (iter_field_offset,
+ size_in_bits),
+ iter, false));
+ }
+ }
+
+ /* Add any trailing padding. */
+ bit_size_t size_in_bits;
+ if (int_size_in_bits (record_type, &size_in_bits))
+ maybe_pad_to (size_in_bits);
+}
+
+void
+record_layout::dump_to_pp (pretty_printer *pp) const
+{
+ unsigned i;
+ item *it;
+ FOR_EACH_VEC_ELT (m_items, i, it)
+ {
+ it->dump_to_pp (pp);
+ pp_newline (pp);
+ }
+}
+
+void
+record_layout::dump () const
+{
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ pp.buffer->stream = stderr;
+ dump_to_pp (&pp);
+ pp_flush (&pp);
+}
+
+const record_layout::item *
+record_layout::get_item_at (bit_offset_t offset) const
+{
+ unsigned i;
+ item *it;
+ FOR_EACH_VEC_ELT (m_items, i, it)
+ if (it->contains_p (offset))
+ return it;
+ return NULL;
+}
+
+/* Subroutine of ctor. Add padding item to NEXT_OFFSET if necessary. */
+
+void
+record_layout::maybe_pad_to (bit_offset_t next_offset)
+{
+ if (m_items.length () > 0)
+ {
+ const item &last_item = m_items[m_items.length () - 1];
+ bit_offset_t offset_after_last_item
+ = last_item.get_next_bit_offset ();
+ if (next_offset > offset_after_last_item)
+ {
+ bit_size_t padding_size
+ = next_offset - offset_after_last_item;
+ m_items.safe_push (item (bit_range (offset_after_last_item,
+ padding_size),
+ last_item.m_field, true));
+ }
+ }
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/record-layout.h b/gcc/analyzer/record-layout.h
new file mode 100644
index 0000000..b63e7b0
--- /dev/null
+++ b/gcc/analyzer/record-layout.h
@@ -0,0 +1,91 @@
+/* Declaration of class record_layout.
+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_ANALYZER_RECORD_LAYOUT_H
+#define GCC_ANALYZER_RECORD_LAYOUT_H
+
+#include "analyzer/store.h"
+
+namespace ana {
+
+/* Information of the layout of a RECORD_TYPE, capturing it as a vector
+ of items, where each item is either a field or padding. */
+
+class record_layout
+{
+public:
+ /* An item within a record; either a field, or padding after a field. */
+ struct item
+ {
+ public:
+ item (const bit_range &br,
+ tree field,
+ bool is_padding)
+ : m_bit_range (br),
+ m_field (field),
+ m_is_padding (is_padding)
+ {
+ }
+
+ bit_offset_t get_start_bit_offset () const
+ {
+ return m_bit_range.get_start_bit_offset ();
+ }
+ bit_offset_t get_next_bit_offset () const
+ {
+ return m_bit_range.get_next_bit_offset ();
+ }
+
+ bool contains_p (bit_offset_t offset) const
+ {
+ return m_bit_range.contains_p (offset);
+ }
+
+ void dump_to_pp (pretty_printer *pp) const
+ {
+ if (m_is_padding)
+ pp_printf (pp, "padding after %qD", m_field);
+ else
+ pp_printf (pp, "%qD", m_field);
+ pp_string (pp, ", ");
+ m_bit_range.dump_to_pp (pp);
+ }
+
+ bit_range m_bit_range;
+ tree m_field;
+ bool m_is_padding;
+ };
+
+ record_layout (tree record_type);
+
+ void dump_to_pp (pretty_printer *pp) const;
+ DEBUG_FUNCTION void dump () const;
+
+ const record_layout::item *get_item_at (bit_offset_t offset) const;
+
+private:
+ void maybe_pad_to (bit_offset_t next_offset);
+
+ auto_vec<item> m_items;
+};
+
+} // namespace ana
+
+#endif /* GCC_ANALYZER_RECORD_LAYOUT_H */
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index c4e68661..9479bcf 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -78,6 +78,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/checker-event.h"
#include "analyzer/checker-path.h"
#include "analyzer/feasible-graph.h"
+#include "analyzer/record-layout.h"
#if ENABLE_ANALYZER
@@ -1781,26 +1782,17 @@ private:
attribute. */
void
-region_model::
-check_external_function_for_access_attr (const gcall *call,
- tree callee_fndecl,
- region_model_context *ctxt) const
+region_model::check_function_attr_access (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt,
+ rdwr_map &rdwr_idx) const
{
gcc_assert (call);
gcc_assert (callee_fndecl);
gcc_assert (ctxt);
tree fntype = TREE_TYPE (callee_fndecl);
- if (!fntype)
- return;
-
- if (!TYPE_ATTRIBUTES (fntype))
- return;
-
- /* Initialize a map of attribute access specifications for arguments
- to the function call. */
- rdwr_map rdwr_idx;
- init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
+ gcc_assert (fntype);
unsigned argno = 0;
@@ -1854,6 +1846,151 @@ check_external_function_for_access_attr (const gcall *call,
}
}
+/* Subroutine of region_model::check_function_attr_null_terminated_string_arg,
+ checking one instance of __attribute__((null_terminated_string_arg)). */
+
+void
+region_model::
+check_one_function_attr_null_terminated_string_arg (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt,
+ rdwr_map &rdwr_idx,
+ tree attr)
+{
+ gcc_assert (call);
+ gcc_assert (callee_fndecl);
+ gcc_assert (ctxt);
+ gcc_assert (attr);
+
+ tree arg = TREE_VALUE (attr);
+ if (!arg)
+ return;
+
+ /* Convert from 1-based to 0-based index. */
+ unsigned int arg_idx = TREE_INT_CST_LOW (TREE_VALUE (arg)) - 1;
+
+ /* If there's also an "access" attribute on the ptr param
+ for reading with a size param specified, then that size
+ limits the size of the possible read from the pointer. */
+ if (const attr_access* access = rdwr_idx.get (arg_idx))
+ if ((access->mode == access_read_only
+ || access->mode == access_read_write)
+ && access->sizarg != UINT_MAX)
+ {
+ /* First, check for a null-terminated string *without*
+ emitting warnings (via a null context), to get an
+ svalue for the strlen of the buffer (possibly
+ nullptr if there would be an issue). */
+ call_details cd_unchecked (call, this, nullptr);
+ const svalue *strlen_sval
+ = check_for_null_terminated_string_arg (cd_unchecked,
+ arg_idx);
+
+ /* Get svalue for the size limit argument. */
+ call_details cd_checked (call, this, ctxt);
+ const svalue *limit_sval
+ = cd_checked.get_arg_svalue (access->sizarg);
+ const svalue *ptr_sval
+ = cd_checked.get_arg_svalue (arg_idx);
+ /* Try reading all of the bytes expressed by the size param,
+ but without checking (via a null context). */
+ const svalue *limited_sval
+ = read_bytes (deref_rvalue (ptr_sval, NULL_TREE, nullptr),
+ NULL_TREE,
+ limit_sval,
+ nullptr);
+ if (limited_sval->get_kind () == SK_POISONED)
+ {
+ /* Reading up to the truncation limit caused issues.
+ Assume that the string is meant to be terminated
+ before then, so perform a *checked* check for the
+ terminator. */
+ check_for_null_terminated_string_arg (cd_checked,
+ arg_idx);
+ }
+ else
+ {
+ /* Reading up to the truncation limit seems OK; repeat
+ the read, but with checking enabled. */
+ const svalue *limited_sval
+ = read_bytes (deref_rvalue (ptr_sval, NULL_TREE, ctxt),
+ NULL_TREE,
+ limit_sval,
+ ctxt);
+ }
+ return;
+ }
+
+ /* Otherwise, we don't have an access-attribute limiting the read.
+ Simulate a read up to the null terminator (if any). */
+
+ call_details cd (call, this, ctxt);
+ check_for_null_terminated_string_arg (cd, arg_idx);
+}
+
+/* Check CALL a call to external function CALLEE_FNDECL for any uses
+ of __attribute__ ((null_terminated_string_arg)), compaining
+ to CTXT about any issues.
+
+ Use RDWR_IDX for tracking uses of __attribute__ ((access, ....). */
+
+void
+region_model::
+check_function_attr_null_terminated_string_arg (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt,
+ rdwr_map &rdwr_idx)
+{
+ gcc_assert (call);
+ gcc_assert (callee_fndecl);
+ gcc_assert (ctxt);
+
+ tree fntype = TREE_TYPE (callee_fndecl);
+ gcc_assert (fntype);
+
+ /* A function declaration can specify multiple attribute
+ null_terminated_string_arg, each with one argument. */
+ for (tree attr = TYPE_ATTRIBUTES (fntype); attr; attr = TREE_CHAIN (attr))
+ {
+ attr = lookup_attribute ("null_terminated_string_arg", attr);
+ if (!attr)
+ return;
+
+ check_one_function_attr_null_terminated_string_arg (call, callee_fndecl,
+ ctxt, rdwr_idx,
+ attr);
+ }
+}
+
+/* Check CALL a call to external function CALLEE_FNDECL for any
+ function attributes, complaining to CTXT about any issues. */
+
+void
+region_model::check_function_attrs (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt)
+{
+ gcc_assert (call);
+ gcc_assert (callee_fndecl);
+ gcc_assert (ctxt);
+
+ tree fntype = TREE_TYPE (callee_fndecl);
+ if (!fntype)
+ return;
+
+ if (!TYPE_ATTRIBUTES (fntype))
+ return;
+
+ /* Initialize a map of attribute access specifications for arguments
+ to the function call. */
+ rdwr_map rdwr_idx;
+ init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
+
+ check_function_attr_access (call, callee_fndecl, ctxt, rdwr_idx);
+ check_function_attr_null_terminated_string_arg (call, callee_fndecl,
+ ctxt, rdwr_idx);
+}
+
/* Handle a call CALL to a function with unknown behavior.
Traverse the regions in this model, determining what regions are
@@ -1870,7 +2007,7 @@ region_model::handle_unrecognized_call (const gcall *call,
tree fndecl = get_fndecl_for_call (call, ctxt);
if (fndecl && ctxt)
- check_external_function_for_access_attr (call, fndecl, ctxt);
+ check_function_attrs (call, fndecl, ctxt);
reachable_regions reachable_regs (this);
@@ -3768,14 +3905,14 @@ region_model::scan_for_null_terminator (const region *reg,
TODO: we should also complain if:
- the pointer is NULL (or could be). */
-void
+const svalue *
region_model::check_for_null_terminated_string_arg (const call_details &cd,
- unsigned arg_idx)
+ unsigned arg_idx) const
{
- check_for_null_terminated_string_arg (cd,
- arg_idx,
- false, /* include_terminator */
- nullptr); // out_sval
+ return check_for_null_terminated_string_arg (cd,
+ arg_idx,
+ false, /* include_terminator */
+ nullptr); // out_sval
}
@@ -3805,7 +3942,7 @@ const svalue *
region_model::check_for_null_terminated_string_arg (const call_details &cd,
unsigned arg_idx,
bool include_terminator,
- const svalue **out_sval)
+ const svalue **out_sval) const
{
class null_terminator_check_event : public custom_event
{
@@ -5987,137 +6124,6 @@ region_model::unset_dynamic_extents (const region *reg)
m_dynamic_extents.remove (reg);
}
-/* Information of the layout of a RECORD_TYPE, capturing it as a vector
- of items, where each item is either a field or padding. */
-
-class record_layout
-{
-public:
- /* An item within a record; either a field, or padding after a field. */
- struct item
- {
- public:
- item (const bit_range &br,
- tree field,
- bool is_padding)
- : m_bit_range (br),
- m_field (field),
- m_is_padding (is_padding)
- {
- }
-
- bit_offset_t get_start_bit_offset () const
- {
- return m_bit_range.get_start_bit_offset ();
- }
- bit_offset_t get_next_bit_offset () const
- {
- return m_bit_range.get_next_bit_offset ();
- }
-
- bool contains_p (bit_offset_t offset) const
- {
- return m_bit_range.contains_p (offset);
- }
-
- void dump_to_pp (pretty_printer *pp) const
- {
- if (m_is_padding)
- pp_printf (pp, "padding after %qD", m_field);
- else
- pp_printf (pp, "%qD", m_field);
- pp_string (pp, ", ");
- m_bit_range.dump_to_pp (pp);
- }
-
- bit_range m_bit_range;
- tree m_field;
- bool m_is_padding;
- };
-
- record_layout (tree record_type)
- {
- gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
-
- for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
- iter = DECL_CHAIN (iter))
- {
- if (TREE_CODE (iter) == FIELD_DECL)
- {
- int iter_field_offset = int_bit_position (iter);
- bit_size_t size_in_bits;
- if (!int_size_in_bits (TREE_TYPE (iter), &size_in_bits))
- size_in_bits = 0;
-
- maybe_pad_to (iter_field_offset);
-
- /* Add field. */
- m_items.safe_push (item (bit_range (iter_field_offset,
- size_in_bits),
- iter, false));
- }
- }
-
- /* Add any trailing padding. */
- bit_size_t size_in_bits;
- if (int_size_in_bits (record_type, &size_in_bits))
- maybe_pad_to (size_in_bits);
- }
-
- void dump_to_pp (pretty_printer *pp) const
- {
- unsigned i;
- item *it;
- FOR_EACH_VEC_ELT (m_items, i, it)
- {
- it->dump_to_pp (pp);
- pp_newline (pp);
- }
- }
-
- DEBUG_FUNCTION void dump () const
- {
- pretty_printer pp;
- pp_format_decoder (&pp) = default_tree_printer;
- pp.buffer->stream = stderr;
- dump_to_pp (&pp);
- pp_flush (&pp);
- }
-
- const record_layout::item *get_item_at (bit_offset_t offset) const
- {
- unsigned i;
- item *it;
- FOR_EACH_VEC_ELT (m_items, i, it)
- if (it->contains_p (offset))
- return it;
- return NULL;
- }
-
-private:
- /* Subroutine of ctor. Add padding item to NEXT_OFFSET if necessary. */
-
- void maybe_pad_to (bit_offset_t next_offset)
- {
- if (m_items.length () > 0)
- {
- const item &last_item = m_items[m_items.length () - 1];
- bit_offset_t offset_after_last_item
- = last_item.get_next_bit_offset ();
- if (next_offset > offset_after_last_item)
- {
- bit_size_t padding_size
- = next_offset - offset_after_last_item;
- m_items.safe_push (item (bit_range (offset_after_last_item,
- padding_size),
- last_item.m_field, true));
- }
- }
- }
-
- auto_vec<item> m_items;
-};
-
/* A subclass of pending_diagnostic for complaining about uninitialized data
being copied across a trust boundary to an untrusted output
(e.g. copy_to_user infoleaks in the Linux kernel). */
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 6946c68..8bfb068 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
http://lcs.ios.ac.cn/~xuzb/canalyze/memmodel.pdf */
#include "bitmap.h"
+#include "stringpool.h"
+#include "attribs.h" // for rdwr_map
#include "selftest.h"
#include "analyzer/svalue.h"
#include "analyzer/region.h"
@@ -527,14 +529,14 @@ class region_model
const svalue *sval_hint,
region_model_context *ctxt) const;
- void
+ const svalue *
check_for_null_terminated_string_arg (const call_details &cd,
- unsigned idx);
+ unsigned idx) const;
const svalue *
check_for_null_terminated_string_arg (const call_details &cd,
unsigned idx,
bool include_terminator,
- const svalue **out_sval);
+ const svalue **out_sval) const;
const builtin_known_function *
get_builtin_kf (const gcall *call,
@@ -644,9 +646,22 @@ private:
void check_call_args (const call_details &cd) const;
void check_call_format_attr (const call_details &cd,
tree format_attr) const;
- void check_external_function_for_access_attr (const gcall *call,
- tree callee_fndecl,
- region_model_context *ctxt) const;
+ void check_function_attr_access (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt,
+ rdwr_map &rdwr_idx) const;
+ void check_function_attr_null_terminated_string_arg (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt,
+ rdwr_map &rdwr_idx);
+ void check_one_function_attr_null_terminated_string_arg (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt,
+ rdwr_map &rdwr_idx,
+ tree attr);
+ void check_function_attrs (const gcall *call,
+ tree callee_fndecl,
+ region_model_context *ctxt);
static auto_vec<pop_frame_callback> pop_frame_callbacks;
/* Storing this here to avoid passing it around everywhere. */
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 25f583c..af8b9ed 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,29 @@
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * c-warn.cc (warn_for_multistatement_macros): Update for removal
+ of MACRO_MAP_EXPANSION_POINT_LOCATION.
+
+2023-10-27 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/87299
+ * c-pragma.cc (init_pragma): Register `#pragma GCC target' and
+ related pragmas in preprocess-only mode, and enable early handling.
+ (c_reset_target_pragmas): New function refactoring code from...
+ (handle_pragma_reset_options): ...here.
+ * c-pragma.h (c_reset_target_pragmas): Declare.
+
+2023-10-26 David Malcolm <dmalcolm@redhat.com>
+
+ * c-attribs.cc (c_common_attribute_table): Add
+ "null_terminated_string_arg".
+ (handle_null_terminated_string_arg_attribute): New.
+
+2023-10-23 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/36887
+ * c-opts.cc (c_common_init_options): Pass new extra hash map
+ argument to cpp_create_reader().
+
2023-10-20 Marek Polacek <polacek@redhat.com>
PR c/111884
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index abf44d5..a041c3b 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -178,6 +178,7 @@ static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int,
bool *);
static tree handle_retain_attribute (tree *, tree, tree, int, bool *);
static tree handle_fd_arg_attribute (tree *, tree, tree, int, bool *);
+static tree handle_null_terminated_string_arg_attribute (tree *, tree, tree, int, bool *);
/* Helper to define attribute exclusions. */
#define ATTR_EXCL(name, function, type, variable) \
@@ -572,6 +573,8 @@ const struct attribute_spec c_common_attribute_table[] =
handle_fd_arg_attribute, NULL},
{ "fd_arg_write", 1, 1, false, true, true, false,
handle_fd_arg_attribute, NULL},
+ { "null_terminated_string_arg", 1, 1, false, true, true, false,
+ handle_null_terminated_string_arg_attribute, NULL},
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
@@ -4660,6 +4663,20 @@ handle_fd_arg_attribute (tree *node, tree name, tree args,
return NULL_TREE;
}
+/* Handle the "null_terminated_string_arg" attribute. */
+
+static tree
+handle_null_terminated_string_arg_attribute (tree *node, tree name, tree args,
+ int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ if (positional_argument (*node, name, TREE_VALUE (args), POINTER_TYPE))
+ return NULL_TREE;
+
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
/* Handle the "nonstring" variable attribute. */
static tree
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index ce2e021..e9f7e6d 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -238,7 +238,7 @@ c_common_init_options (unsigned int decoded_options_count,
= new (ggc_alloc <string_concat_db> ()) string_concat_db ();
parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
- ident_hash, line_table);
+ ident_hash, line_table, ident_hash_extra);
cb = cpp_get_callbacks (parse_in);
cb->diagnostic = c_cpp_diagnostic;
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index 98dfb0f..df3e3e6 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1289,24 +1289,16 @@ handle_pragma_pop_options (cpp_reader *)
current_optimize_pragma = p->optimize_strings;
}
-/* Handle #pragma GCC reset_options to restore the current target and
- optimization options to the original options used on the command line. */
+/* This is mostly a helper for handle_pragma_reset_options () to do the actual
+ work, but the C++ frontend, for example, needs an external interface to
+ perform this operation, since it processes target pragmas twice. (Once for
+ preprocessing purposes, and then again during compilation.) */
-static void
-handle_pragma_reset_options (cpp_reader *)
+void
+c_reset_target_pragmas ()
{
- enum cpp_ttype token;
- tree x = 0;
tree new_optimize = optimization_default_node;
tree new_target = target_option_default_node;
-
- token = pragma_lex (&x);
- if (token != CPP_EOF)
- {
- warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
- return;
- }
-
if (new_target != target_option_current_node)
{
(void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
@@ -1326,6 +1318,19 @@ handle_pragma_reset_options (cpp_reader *)
current_optimize_pragma = NULL_TREE;
}
+/* Handle #pragma GCC reset_options to restore the current target and
+ optimization options to the original options used on the command line. */
+
+static void
+handle_pragma_reset_options (cpp_reader *)
+{
+ tree x;
+ if (pragma_lex (&x) != CPP_EOF)
+ warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
+ else
+ c_reset_target_pragmas ();
+}
+
/* Print a plain user-specified message. */
static void
@@ -1844,11 +1849,19 @@ init_pragma (void)
c_register_pragma_with_early_handler ("GCC", "diagnostic",
handle_pragma_diagnostic,
handle_pragma_diagnostic_early);
- c_register_pragma ("GCC", "target", handle_pragma_target);
+ c_register_pragma_with_early_handler ("GCC", "target",
+ handle_pragma_target,
+ handle_pragma_target);
c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
- c_register_pragma ("GCC", "push_options", handle_pragma_push_options);
- c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
- c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
+ c_register_pragma_with_early_handler ("GCC", "push_options",
+ handle_pragma_push_options,
+ handle_pragma_push_options);
+ c_register_pragma_with_early_handler ("GCC", "pop_options",
+ handle_pragma_pop_options,
+ handle_pragma_pop_options);
+ c_register_pragma_with_early_handler ("GCC", "reset_options",
+ handle_pragma_reset_options,
+ handle_pragma_reset_options);
c_register_pragma (0, "region", handle_pragma_ignore);
c_register_pragma (0, "endregion", handle_pragma_ignore);
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 603c515..682157a 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -256,7 +256,7 @@ c_register_pragma_with_early_handler (const char *space, const char *name,
pragma_handler_1arg early_handler);
extern void c_invoke_early_pragma_handler (unsigned int);
extern void c_pp_invoke_early_pragma_handler (unsigned int);
-
+extern void c_reset_target_pragmas ();
extern void maybe_apply_pragma_weak (tree);
extern void maybe_apply_pending_pragma_weaks (void);
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index 9ab83a9..bc889ce 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -2951,7 +2951,7 @@ warn_for_multistatement_macros (location_t body_loc, location_t next_loc,
while (linemap_macro_expansion_map_p (guard_map))
{
const line_map_macro *mm = linemap_check_macro (guard_map);
- guard_loc_exp = MACRO_MAP_EXPANSION_POINT_LOCATION (mm);
+ guard_loc_exp = mm->get_expansion_point_location ();
guard_map = linemap_lookup (line_table, guard_loc_exp);
if (guard_map == body_map)
return;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44b9c86..29d3d78 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -331,6 +331,10 @@ Walloca
C ObjC C++ ObjC++ Var(warn_alloca) Warning
Warn on any use of alloca.
+Walloc-size
+C ObjC Var(warn_alloc_size) Warning LangEnabledBy(C ObjC, Wextra)
+Warn when allocating insufficient storage for the target type of the assigned pointer.
+
Walloc-size-larger-than=
C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Joined Host_Wide_Int ByteSize Warning Init(HOST_WIDE_INT_MAX)
-Walloc-size-larger-than=<bytes> Warn for calls to allocation functions that
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 2fb67af..c6dccf8 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,30 @@
+2023-10-26 liuhongt <hongtao.liu@intel.com>
+
+ * c-typeck.cc (build_vec_cmp): Pass type of arg0 to
+ truth_type_for.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-parser.cc (c_parser_omp_clause_name): Return
+ 'PRAGMA_OACC_CLAUSE_SELF' for "self".
+ (c_parser_oacc_data_clause, OACC_UPDATE_CLAUSE_MASK): Adjust.
+ (c_parser_oacc_all_clauses): Remove 'bool compute_p' formal
+ parameter, and instead locally determine whether we're called for
+ an OpenACC compute construct or OpenACC 'update' directive.
+ (c_parser_oacc_compute): Adjust.
+
+2023-10-25 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * c-parser.cc (c_parser_oacc_compute_clause_self): New function.
+ (c_parser_oacc_all_clauses): Add new 'bool compute_p = false'
+ parameter, add parsing of self clause when compute_p is true.
+ (OACC_KERNELS_CLAUSE_MASK): Add PRAGMA_OACC_CLAUSE_SELF.
+ (OACC_PARALLEL_CLAUSE_MASK): Likewise,
+ (OACC_SERIAL_CLAUSE_MASK): Likewise.
+ (c_parser_oacc_compute): Adjust call to c_parser_oacc_all_clauses to
+ set compute_p argument to true.
+ * c-typeck.cc (c_finish_omp_clauses): Add OMP_CLAUSE_SELF case.
+
2023-10-20 Florian Weimer <fweimer@redhat.com>
PR c/109827
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 0d468b8..5213a57 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -14061,8 +14061,8 @@ c_parser_omp_clause_name (c_parser *parser)
result = PRAGMA_OMP_CLAUSE_SCHEDULE;
else if (!strcmp ("sections", p))
result = PRAGMA_OMP_CLAUSE_SECTIONS;
- else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
- result = PRAGMA_OACC_CLAUSE_HOST;
+ else if (!strcmp ("self", p))
+ result = PRAGMA_OACC_CLAUSE_SELF;
else if (!strcmp ("seq", p))
result = PRAGMA_OACC_CLAUSE_SEQ;
else if (!strcmp ("shared", p))
@@ -14583,9 +14583,6 @@ c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
kind = GOMP_MAP_DEVICE_RESIDENT;
break;
- case PRAGMA_OACC_CLAUSE_HOST:
- kind = GOMP_MAP_FORCE_FROM;
- break;
case PRAGMA_OACC_CLAUSE_LINK:
kind = GOMP_MAP_LINK;
break;
@@ -14595,6 +14592,11 @@ c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
case PRAGMA_OACC_CLAUSE_PRESENT:
kind = GOMP_MAP_FORCE_PRESENT;
break;
+ case PRAGMA_OACC_CLAUSE_SELF:
+ /* "The 'host' clause is a synonym for the 'self' clause." */
+ case PRAGMA_OACC_CLAUSE_HOST:
+ kind = GOMP_MAP_FORCE_FROM;
+ break;
default:
gcc_unreachable ();
}
@@ -15923,6 +15925,41 @@ c_parser_oacc_clause_wait (c_parser *parser, tree list)
return list;
}
+/* OpenACC 2.7:
+ self [( expression )] */
+
+static tree
+c_parser_oacc_compute_clause_self (c_parser *parser, tree list)
+{
+ tree t;
+ location_t location = c_parser_peek_token (parser)->location;
+ if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
+ {
+ matching_parens parens;
+ parens.consume_open (parser);
+
+ location_t loc = c_parser_peek_token (parser)->location;
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ expr = convert_lvalue_to_rvalue (loc, expr, true, true);
+ t = c_objc_common_truthvalue_conversion (loc, expr.value);
+ t = c_fully_fold (t, false, NULL);
+ parens.skip_until_found_close (parser);
+ }
+ else
+ t = truthvalue_true_node;
+
+ for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
+ {
+ error_at (location, "too many %<self%> clauses");
+ return list;
+ }
+
+ tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
+ OMP_CLAUSE_SELF_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
/* OpenMP 5.0:
order ( concurrent )
@@ -18196,6 +18233,15 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
false, clauses);
c_name = "reduction";
break;
+ case PRAGMA_OACC_CLAUSE_SELF:
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
+ /* OpenACC compute construct */
+ clauses = c_parser_oacc_compute_clause_self (parser, clauses);
+ else
+ /* OpenACC 'update' directive */
+ clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
+ c_name = "self";
+ break;
case PRAGMA_OACC_CLAUSE_SEQ:
clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
clauses);
@@ -19032,6 +19078,7 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
@@ -19052,6 +19099,7 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
@@ -19070,6 +19118,7 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
static tree
@@ -19312,6 +19361,7 @@ c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
static void
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 112d28f..16fadfb 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -7347,6 +7347,34 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
"request for implicit conversion "
"from %qT to %qT not permitted in C++", rhstype, type);
+ /* Warn of new allocations that are not big enough for the target
+ type. */
+ tree fndecl;
+ if (warn_alloc_size
+ && TREE_CODE (rhs) == CALL_EXPR
+ && (fndecl = get_callee_fndecl (rhs)) != NULL_TREE
+ && DECL_IS_MALLOC (fndecl))
+ {
+ tree fntype = TREE_TYPE (fndecl);
+ tree fntypeattrs = TYPE_ATTRIBUTES (fntype);
+ tree alloc_size = lookup_attribute ("alloc_size", fntypeattrs);
+ if (alloc_size)
+ {
+ tree args = TREE_VALUE (alloc_size);
+ int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
+ /* For calloc only use the second argument. */
+ if (TREE_CHAIN (args))
+ idx = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1;
+ tree arg = CALL_EXPR_ARG (rhs, idx);
+ if (TREE_CODE (arg) == INTEGER_CST
+ && INTEGER_CST == TREE_CODE (TYPE_SIZE_UNIT (ttl))
+ && tree_int_cst_lt (arg, TYPE_SIZE_UNIT (ttl)))
+ warning_at (location, OPT_Walloc_size, "allocation of "
+ "insufficient size %qE for type %qT with "
+ "size %qE", arg, ttl, TYPE_SIZE_UNIT (ttl));
+ }
+ }
+
/* See if the pointers point to incompatible address spaces. */
asl = TYPE_ADDR_SPACE (ttl);
asr = TYPE_ADDR_SPACE (ttr);
@@ -11986,7 +12014,7 @@ build_vec_cmp (tree_code code, tree type,
{
tree zero_vec = build_zero_cst (type);
tree minus_one_vec = build_minus_one_cst (type);
- tree cmp_type = truth_type_for (type);
+ tree cmp_type = truth_type_for (TREE_TYPE (arg0));
tree cmp = build2 (code, cmp_type, arg0, arg1);
return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
}
@@ -15845,6 +15873,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
continue;
case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
diff --git a/gcc/combine.cc b/gcc/combine.cc
index cb48e7f..6344cd3 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -8449,8 +8449,8 @@ make_compound_operation (rtx x, enum rtx_code in_code)
if (code == ZERO_EXTEND)
{
new_rtx = make_compound_operation (XEXP (x, 0), next_code);
- tem = simplify_const_unary_operation (ZERO_EXTEND, GET_MODE (x),
- new_rtx, GET_MODE (XEXP (x, 0)));
+ tem = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
+ new_rtx, GET_MODE (XEXP (x, 0)));
if (tem)
return tem;
SUBST (XEXP (x, 0), new_rtx);
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index f721888..7d25479 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -663,6 +663,12 @@ get_zhaoxin_cpu (struct __processor_model *cpu_model,
reset_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C);
cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_LUJIAZUI;
}
+ else if (model >= 0x5b)
+ {
+ cpu = "yongfeng";
+ CHECK___builtin_cpu_is ("yongfeng");
+ cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_YONGFENG;
+ }
break;
default:
break;
diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc
index 79b1b35..1b09499 100644
--- a/gcc/common/config/i386/i386-common.cc
+++ b/gcc/common/config/i386/i386-common.cc
@@ -2098,6 +2098,7 @@ const char *const processor_names[] =
"pantherlake",
"intel",
"lujiazui",
+ "yongfeng",
"geode",
"k6",
"athlon",
@@ -2305,12 +2306,11 @@ const pta processor_alias_table[] =
PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
| PTA_SSSE3 | PTA_SSE4_1 | PTA_FXSR, 0, P_NONE},
{"lujiazui", PROCESSOR_LUJIAZUI, CPU_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 | PTA_PCLMUL | PTA_BMI | PTA_BMI2
- | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE
- | PTA_RDRND | PTA_MOVBE | PTA_ADX | PTA_RDSEED | PTA_POPCNT,
+ PTA_LUJIAZUI,
M_CPU_SUBTYPE (ZHAOXIN_FAM7H_LUJIAZUI), P_NONE},
+ {"yongfeng", PROCESSOR_YONGFENG, CPU_YONGFENG,
+ PTA_YONGFENG,
+ M_CPU_SUBTYPE (ZHAOXIN_FAM7H_YONGFENG), P_NONE},
{"k8", PROCESSOR_K8, CPU_K8,
PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
| PTA_SSE2 | PTA_NO_SAHF | PTA_FXSR, 0, P_NONE},
diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h
index 533b748..a0552ef 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -103,6 +103,7 @@ enum processor_subtypes
INTEL_COREI7_ARROWLAKE,
INTEL_COREI7_ARROWLAKE_S,
INTEL_COREI7_PANTHERLAKE,
+ ZHAOXIN_FAM7H_YONGFENG,
CPU_SUBTYPE_MAX
};
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 606d3a8..ba6d63e 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -544,7 +544,7 @@ pru-*-*)
riscv*)
cpu_type=riscv
extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o riscv-shorten-memrefs.o riscv-selftests.o riscv-string.o"
- extra_objs="${extra_objs} riscv-v.o riscv-vsetvl.o riscv-vector-costs.o"
+ extra_objs="${extra_objs} riscv-v.o riscv-vsetvl.o riscv-vector-costs.o riscv-avlprop.o"
extra_objs="${extra_objs} riscv-vector-builtins.o riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o"
extra_objs="${extra_objs} thead.o"
d_target_objs="riscv-d.o"
@@ -706,7 +706,7 @@ slm nehalem westmere sandybridge ivybridge haswell broadwell bonnell \
silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \
skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \
sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 \
-nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \
+nano-x2 eden-x4 nano-x4 lujiazui yongfeng x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \
sierraforest graniterapids graniterapids-d grandridge arrowlake arrowlake-s \
clearwaterforest pantherlake native"
@@ -3811,6 +3811,10 @@ case ${target} in
arch=lujiazui
cpu=lujiazui
;;
+ yongfeng-*)
+ arch=yongfeng
+ cpu=yongfeng
+ ;;
pentium2-*)
arch=pentium2
cpu=pentium2
@@ -3924,10 +3928,14 @@ case ${target} in
arch=k8
cpu=k8
;;
- lujiazui-*)
+ lujiazui-*)
arch=lujiazui
cpu=lujiazui
;;
+ yongfeng-*)
+ arch=yongfeng
+ cpu=yongfeng
+ ;;
nocona-*)
arch=nocona
cpu=nocona
@@ -4199,8 +4207,8 @@ case "${target}" in
fi
for which in cpu arch tune; do
eval "val=\$with_$which"
- base_val=`echo $val | sed -e 's/\+.*//'`
- ext_val=`echo $val | sed -e 's/[a-z0-9.-]\+//'`
+ base_val=`echo $val | sed -E -e 's/\+.*//'`
+ ext_val=`echo $val | sed -E -e 's/[a-z0-9.-]+//'`
if [ $which = arch ]; then
def=aarch64-arches.def
@@ -4232,9 +4240,9 @@ case "${target}" in
while [ x"$ext_val" != x ]
do
- ext_val=`echo $ext_val | sed -e 's/\+//'`
- ext=`echo $ext_val | sed -e 's/\+.*//'`
- base_ext=`echo $ext | sed -e 's/^no//'`
+ ext_val=`echo $ext_val | sed -E -e 's/\+//'`
+ ext=`echo $ext_val | sed -E -e 's/\+.*//'`
+ base_ext=`echo $ext | sed -E -e 's/^no//'`
opt_line=`echo -e "$options_parsed" | \
grep "^\"$base_ext\""`
@@ -4245,7 +4253,7 @@ case "${target}" in
echo "Unknown extension used in --with-$which=$val" 1>&2
exit 1
fi
- ext_val=`echo $ext_val | sed -e 's/[a-z0-9]\+//'`
+ ext_val=`echo $ext_val | sed -E -e 's/[a-z0-9]+//'`
done
true
diff --git a/gcc/config.in b/gcc/config.in
index 98ddddf..03faee1 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -49,6 +49,19 @@
#endif
+/* Specify a runpath directory, additional to those provided by the compiler
+ */
+#ifndef USED_FOR_TARGET
+#undef DARWIN_ADD_RPATH
+#endif
+
+
+/* Should add an extra runpath directory */
+#ifndef USED_FOR_TARGET
+#undef DARWIN_DO_EXTRA_RPATH
+#endif
+
+
/* Define to enable the use of a default assembler. */
#ifndef USED_FOR_TARGET
#undef DEFAULT_ASSEMBLER
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index a28b66a..5fd7063 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -5748,6 +5748,26 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
}
return 2;
}
+
+ /* Try 2 bitmask immediates which are xor'd together. */
+ for (i = 0; i < 64; i += 16)
+ {
+ val2 = (val >> i) & mask;
+ val2 |= val2 << 16;
+ val2 |= val2 << 32;
+ if (aarch64_bitmask_imm (val2) && aarch64_bitmask_imm (val ^ val2))
+ break;
+ }
+
+ if (i != 64)
+ {
+ if (generate)
+ {
+ emit_insn (gen_rtx_SET (dest, GEN_INT (val2)));
+ emit_insn (gen_xordi3 (dest, dest, GEN_INT (val ^ val2)));
+ }
+ return 2;
+ }
}
/* Try a bitmask plus 2 movk to generate the immediate in 3 instructions. */
@@ -12346,6 +12366,11 @@ aarch64_print_operand (FILE *f, rtx x, int code)
switch (GET_CODE (x))
{
+ case CONST_STRING:
+ {
+ asm_fprintf (f, "%s", XSTR (x, 0));
+ break;
+ }
case REG:
if (aarch64_sve_data_mode_p (GET_MODE (x)))
{
@@ -15541,6 +15566,28 @@ aarch64_memory_move_cost (machine_mode mode, reg_class_t rclass_i, bool in)
: aarch64_tune_params.memmov_cost.store_int);
}
+/* Implement TARGET_INSN_COST. We have the opportunity to do something
+ much more productive here, such as using insn attributes to cost things.
+ But we don't, not yet.
+
+ The main point of this current definition is to make calling insn_cost
+ on one instruction equivalent to calling seq_cost on a sequence that
+ contains only that instruction. The default definition would instead
+ only look at SET_SRCs, ignoring SET_DESTs.
+
+ This ensures that, for example, storing a 128-bit zero vector is more
+ expensive than storing a 128-bit vector register. A move of zero
+ into a 128-bit vector register followed by multiple stores of that
+ register is then cheaper than multiple stores of zero (which would
+ use STP of XZR). This in turn allows STP Qs to be formed. */
+static int
+aarch64_insn_cost (rtx_insn *insn, bool speed)
+{
+ if (rtx set = single_set (insn))
+ return set_rtx_cost (set, speed);
+ return pattern_cost (PATTERN (insn), speed);
+}
+
/* Implement TARGET_INIT_BUILTINS. */
static void
aarch64_init_builtins ()
@@ -28399,6 +28446,9 @@ aarch64_libgcc_floating_mode_supported_p
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS aarch64_rtx_costs_wrapper
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST aarch64_insn_cost
+
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P aarch64_scalar_mode_supported_p
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index e6af09c..5bb8c77 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4413,6 +4413,53 @@
[(set_attr "type" "csel")]
)
+;; There are two canonical forms for `cmp ? ~a : a`.
+;; This is the second form and is here to help combine.
+;; Support `-(cmp) ^ a` into `cmp ? ~a : a`
+;; The second pattern is to support the zero extend'ed version.
+
+(define_insn_and_split "*cmov<mode>_insn_insv"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (xor:GPI
+ (neg:GPI
+ (match_operator:GPI 1 "aarch64_comparison_operator"
+ [(match_operand 2 "cc_register" "") (const_int 0)]))
+ (match_operand:GPI 3 "general_operand" "r")))]
+ ""
+ "#"
+ "&& true"
+ [(set (match_dup 0)
+ (if_then_else:GPI (match_dup 1)
+ (not:GPI (match_dup 3))
+ (match_dup 3)))]
+ {
+ /* After reload this will be a nop due to the constraint. */
+ operands[3] = force_reg (<MODE>mode, operands[3]);
+ }
+ [(set_attr "type" "csel")]
+)
+
+(define_insn_and_split "*cmov_uxtw_insn_insv"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (xor:SI
+ (neg:SI
+ (match_operator:SI 1 "aarch64_comparison_operator"
+ [(match_operand 2 "cc_register" "") (const_int 0)]))
+ (match_operand:SI 3 "general_operand" "r"))))]
+ "can_create_pseudo_p ()"
+ "#"
+ "&& true"
+ [(set (match_dup 0)
+ (if_then_else:DI (match_dup 1)
+ (zero_extend:DI (not:SI (match_dup 3)))
+ (zero_extend:DI (match_dup 3))))]
+ {
+ operands[3] = force_reg (SImode, operands[3]);
+ }
+ [(set_attr "type" "csel")]
+)
+
;; If X can be loaded by a single CNT[BHWD] instruction,
;;
;; A = UMAX (B, X)
diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md
index 2b6f04e..055a873 100644
--- a/gcc/config/aarch64/atomics.md
+++ b/gcc/config/aarch64/atomics.md
@@ -224,7 +224,7 @@
UNSPECV_ATOMIC_EXCHG))
(clobber (reg:CC CC_REGNUM))
(clobber (match_scratch:SI 4 "=&r"))]
- ""
+ "!TARGET_LSE"
"#"
"&& epilogue_completed"
[(const_int 0)]
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 026ea99..a48d850 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -25,7 +25,12 @@ extern machine_mode arc_select_cc_mode (enum rtx_code, rtx, rtx);
extern struct rtx_def *gen_compare_reg (rtx, machine_mode);
/* Declarations for various fns used in the .md file. */
-extern const char *output_shift (rtx *);
+extern const char *output_shift_loop (enum rtx_code, rtx *);
+extern void arc_split_ashl (rtx *);
+extern void arc_split_ashr (rtx *);
+extern void arc_split_lshr (rtx *);
+extern void arc_split_rotl (rtx *);
+extern void arc_split_rotr (rtx *);
extern bool compact_sda_memory_operand (rtx, machine_mode, bool);
extern bool arc_double_limm_p (rtx);
extern void arc_print_operand (FILE *, rtx, int);
diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index 00427d8..e209ad2 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -241,7 +241,6 @@ static int branch_dest (rtx);
static void arc_output_pic_addr_const (FILE *, rtx, int);
static bool arc_function_ok_for_sibcall (tree, tree);
static rtx arc_function_value (const_tree, const_tree, bool);
-const char * output_shift (rtx *);
static void arc_reorg (void);
static bool arc_in_small_data_p (const_tree);
@@ -4151,143 +4150,340 @@ arc_pre_reload_split (void)
&& !(cfun->curr_properties & PROP_rtl_split_insns));
}
-/* Output the assembler code for doing a shift.
- We go to a bit of trouble to generate efficient code as the ARC601 only has
- single bit shifts. This is taken from the h8300 port. We only have one
- mode of shifting and can't access individual bytes like the h8300 can, so
- this is greatly simplified (at the expense of not generating hyper-
- efficient code).
-
- This function is not used if the variable shift insns are present. */
-
-/* FIXME: This probably can be done using a define_split in arc.md.
- Alternately, generate rtx rather than output instructions. */
+/* Output the assembler code for a zero-overhead loop doing a shift
+ or rotate. We know OPERANDS[0] == OPERANDS[1], and the bit count
+ is OPERANDS[2]. */
const char *
-output_shift (rtx *operands)
+output_shift_loop (enum rtx_code code, rtx *operands)
{
- /* static int loopend_lab;*/
- rtx shift = operands[3];
- machine_mode mode = GET_MODE (shift);
- enum rtx_code code = GET_CODE (shift);
- const char *shift_one;
-
- gcc_assert (mode == SImode);
-
- switch (code)
- {
- case ASHIFT: shift_one = "add %0,%1,%1"; break;
- case ASHIFTRT: shift_one = "asr %0,%1"; break;
- case LSHIFTRT: shift_one = "lsr %0,%1"; break;
- default: gcc_unreachable ();
- }
+ bool twice_p = false;
+ gcc_assert (GET_MODE (operands[0]) == SImode);
if (GET_CODE (operands[2]) != CONST_INT)
{
- output_asm_insn ("and.f lp_count,%2, 0x1f", operands);
- goto shiftloop;
+ output_asm_insn ("and.f\tlp_count,%2,0x1f", operands);
+ output_asm_insn ("lpnz\t2f", operands);
}
else
{
- int n;
+ int n = INTVAL (operands[2]) & 31;
+ if (!n)
+ {
+ output_asm_insn ("mov\t%0,%1",operands);
+ return "";
+ }
- n = INTVAL (operands[2]);
+ if ((n & 1) == 0 && code != ROTATE)
+ {
+ twice_p = true;
+ n >>= 1;
+ }
+ operands[2] = GEN_INT (n);
+ output_asm_insn ("mov\tlp_count,%2", operands);
+ output_asm_insn ("lp\t2f", operands);
+ }
- /* Only consider the lower 5 bits of the shift count. */
- n = n & 0x1f;
+ switch (code)
+ {
+ case ASHIFT:
+ output_asm_insn ("add\t%0,%1,%1", operands);
+ if (twice_p)
+ output_asm_insn ("add\t%0,%1,%1", operands);
+ break;
+ case ASHIFTRT:
+ output_asm_insn ("asr\t%0,%1", operands);
+ if (twice_p)
+ output_asm_insn ("asr\t%0,%1", operands);
+ break;
+ case LSHIFTRT:
+ output_asm_insn ("lsr\t%0,%1", operands);
+ if (twice_p)
+ output_asm_insn ("lsr\t%0,%1", operands);
+ break;
+ case ROTATERT:
+ output_asm_insn ("ror\t%0,%1", operands);
+ if (twice_p)
+ output_asm_insn ("ror\t%0,%1", operands);
+ break;
+ case ROTATE:
+ output_asm_insn ("add.f\t%0,%1,%1", operands);
+ output_asm_insn ("adc\t%0,%0,0", operands);
+ twice_p = true;
+ break;
+ default:
+ gcc_unreachable ();
+ }
- /* First see if we can do them inline. */
- /* ??? We could get better scheduling & shorter code (using short insns)
- by using splitters. Alas, that'd be even more verbose. */
- if (code == ASHIFT && n <= 9 && n > 2
- && dest_reg_operand (operands[4], SImode))
+ if (!twice_p)
+ output_asm_insn ("nop", operands);
+ fprintf (asm_out_file, "2:\t%s end single insn loop\n", ASM_COMMENT_START);
+ return "";
+}
+
+
+/* Split SImode left shift instruction. */
+void
+arc_split_ashl (rtx *operands)
+{
+ if (CONST_INT_P (operands[2]))
+ {
+ int n = INTVAL (operands[2]) & 0x1f;
+ if (n <= 9)
{
- output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands);
- for (n -=3 ; n >= 3; n -= 3)
- output_asm_insn ("add3 %0,%4,%0", operands);
- if (n == 2)
- output_asm_insn ("add2 %0,%4,%0", operands);
- else if (n)
- output_asm_insn ("add %0,%0,%0", operands);
+ if (n == 0)
+ emit_move_insn (operands[0], operands[1]);
+ else if (n <= 2)
+ {
+ emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[1]));
+ if (n == 2)
+ emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
+ }
+ else
+ {
+ rtx zero = gen_reg_rtx (SImode);
+ emit_move_insn (zero, const0_rtx);
+ emit_insn (gen_add_shift (operands[0], operands[1],
+ GEN_INT (3), zero));
+ for (n -= 3; n >= 3; n -= 3)
+ emit_insn (gen_add_shift (operands[0], operands[0],
+ GEN_INT (3), zero));
+ if (n == 2)
+ emit_insn (gen_add_shift (operands[0], operands[0],
+ const2_rtx, zero));
+ else if (n)
+ emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
+ }
+ return;
}
- else if (n <= 4)
+ else if (n >= 16 && n <= 22 && TARGET_SWAP && TARGET_V2)
{
- while (--n >= 0)
+ emit_insn (gen_ashlsi2_cnt16 (operands[0], operands[1]));
+ if (n > 16)
{
- output_asm_insn (shift_one, operands);
operands[1] = operands[0];
+ operands[2] = GEN_INT (n - 16);
+ arc_split_ashl (operands);
}
+ return;
}
- /* See if we can use a rotate/and. */
- else if (n == BITS_PER_WORD - 1)
+ else if (n >= 29)
{
- switch (code)
+ if (n < 31)
{
- case ASHIFT :
- output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands);
- break;
- case ASHIFTRT :
- /* The ARC doesn't have a rol insn. Use something else. */
- output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands);
- break;
- case LSHIFTRT :
- /* The ARC doesn't have a rol insn. Use something else. */
- output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands);
- break;
- default:
- break;
+ if (n == 29)
+ {
+ emit_insn (gen_andsi3_i (operands[0], operands[1],
+ GEN_INT (7)));
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+ }
+ else
+ emit_insn (gen_andsi3_i (operands[0], operands[1],
+ GEN_INT (3)));
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
}
+ else
+ emit_insn (gen_andsi3_i (operands[0], operands[1], const1_rtx));
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+ return;
}
- else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode))
+ }
+
+ emit_insn (gen_ashlsi3_loop (operands[0], operands[1], operands[2]));
+}
+
+/* Split SImode arithmetic right shift instruction. */
+void
+arc_split_ashr (rtx *operands)
+{
+ if (CONST_INT_P (operands[2]))
+ {
+ int n = INTVAL (operands[2]) & 0x1f;
+ if (n <= 4)
{
- switch (code)
+ if (n != 0)
{
- case ASHIFT :
- output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands);
- break;
- case ASHIFTRT :
-#if 1 /* Need some scheduling comparisons. */
- output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
- "add.f 0,%4,%4\n\trlc %0,%0", operands);
-#else
- output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
- "sbc.f %0,%0,%4\n\trlc %0,%0", operands);
-#endif
- break;
- case LSHIFTRT :
-#if 1
- output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
- "add.f 0,%4,%4\n\trlc %0,%0", operands);
-#else
- output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
- "and %0,%0,1\n\trlc %0,%0", operands);
-#endif
- break;
- default:
- break;
+ emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[1]));
+ while (--n > 0)
+ emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
}
+ else
+ emit_move_insn (operands[0], operands[1]);
+ return;
}
- else if (n == BITS_PER_WORD - 3 && code == ASHIFT)
- output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
- operands);
- /* Must loop. */
- else
+ else if (n >= 16 && n <= 18 && TARGET_SWAP)
+ {
+ emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
+ emit_insn (gen_extendhisi2 (operands[0],
+ gen_lowpart (HImode, operands[0])));
+ while (--n >= 16)
+ emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
+ return;
+ }
+ else if (n == 30)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_add_f (tmp, operands[1], operands[1]));
+ emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
+ emit_insn (gen_addsi_compare_2 (tmp, tmp));
+ emit_insn (gen_adc (operands[0], operands[0], operands[0]));
+ return;
+ }
+ else if (n == 31)
{
- operands[2] = GEN_INT (n);
- output_asm_insn ("mov.f lp_count, %2", operands);
+ emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
+ emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
+ return;
+ }
+ }
+
+ emit_insn (gen_ashrsi3_loop (operands[0], operands[1], operands[2]));
+}
- shiftloop:
+/* Split SImode logical right shift instruction. */
+void
+arc_split_lshr (rtx *operands)
+{
+ if (CONST_INT_P (operands[2]))
+ {
+ int n = INTVAL (operands[2]) & 0x1f;
+ if (n <= 4)
+ {
+ if (n != 0)
{
- output_asm_insn ("lpnz\t2f", operands);
- output_asm_insn (shift_one, operands);
- output_asm_insn ("nop", operands);
- fprintf (asm_out_file, "2:\t%s end single insn loop\n",
- ASM_COMMENT_START);
+ emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[1]));
+ while (--n > 0)
+ emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
}
+ else
+ emit_move_insn (operands[0], operands[1]);
+ return;
+ }
+ else if (n >= 16 && n <= 19 && TARGET_SWAP && TARGET_V2)
+ {
+ emit_insn (gen_lshrsi2_cnt16 (operands[0], operands[1]));
+ while (--n >= 16)
+ emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
+ return;
+ }
+ else if (n == 30)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_add_f (tmp, operands[1], operands[1]));
+ emit_insn (gen_scc_ltu_cc_c (operands[0]));
+ emit_insn (gen_addsi_compare_2 (tmp, tmp));
+ emit_insn (gen_adc (operands[0], operands[0], operands[0]));
+ return;
+ }
+ else if (n == 31)
+ {
+ emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
+ emit_insn (gen_scc_ltu_cc_c (operands[0]));
+ return;
}
}
- return "";
+ emit_insn (gen_lshrsi3_loop (operands[0], operands[1], operands[2]));
+}
+
+/* Split SImode rotate left instruction. */
+void
+arc_split_rotl (rtx *operands)
+{
+ if (CONST_INT_P (operands[2]))
+ {
+ int n = INTVAL (operands[2]) & 0x1f;
+ if (n <= 2)
+ {
+ if (n != 0)
+ {
+ emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
+ if (n == 2)
+ emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
+ }
+ else
+ emit_move_insn (operands[0], operands[1]);
+ return;
+ }
+ else if (n >= 28)
+ {
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
+ while (++n < 32)
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+ return;
+ }
+ else if (n >= 13 && n <= 16 && TARGET_SWAP)
+ {
+ emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
+ while (++n <= 16)
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+ return;
+ }
+ else if (n == 17 && TARGET_SWAP)
+ {
+ emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
+ emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
+ return;
+ }
+ else if (n >= 16 || n == 12 || n == 14)
+ {
+ emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
+ GEN_INT (32 - n)));
+ return;
+ }
+ }
+
+ emit_insn (gen_rotlsi3_loop (operands[0], operands[1], operands[2]));
+}
+
+/* Split SImode rotate right instruction. */
+void
+arc_split_rotr (rtx *operands)
+{
+ if (CONST_INT_P (operands[2]))
+ {
+ int n = INTVAL (operands[2]) & 0x1f;
+ if (n <= 4)
+ {
+ if (n != 0)
+ {
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
+ while (--n > 0)
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+ }
+ else
+ emit_move_insn (operands[0], operands[1]);
+ return;
+ }
+ else if (n == 15 && TARGET_SWAP)
+ {
+ emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
+ emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
+ return;
+ }
+ else if (n >= 16 && n <= 19 && TARGET_SWAP)
+ {
+ emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
+ while (--n >= 16)
+ emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+ return;
+ }
+ else if (n >= 30)
+ {
+ emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
+ if (n == 31)
+ emit_insn (gen_rotlsi3_cnt1 (operands[1], operands[1]));
+ return;
+ }
+ else if (n >= 21 || n == 17 || n == 19)
+ {
+ emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
+ GEN_INT (32 - n)));
+ return;
+ }
+ }
+
+ emit_insn (gen_rotrsi3_loop (operands[0], operands[1], operands[2]));
}
/* Nested function support. */
@@ -4459,9 +4655,9 @@ arc_print_operand (FILE *file, rtx x, int code)
case 'c':
if (GET_CODE (x) == CONST_INT)
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) );
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) );
else
- output_operand_lossage ("invalid operands to %%c code");
+ output_operand_lossage ("invalid operands to %%c code");
return;
@@ -5349,7 +5545,7 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
case CONST:
case LABEL_REF:
case SYMBOL_REF:
- *total = speed ? COSTS_N_INSNS (1) : COSTS_N_INSNS (4);
+ *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (4);
return true;
case CONST_DOUBLE:
@@ -5373,26 +5569,32 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
case ASHIFT:
case ASHIFTRT:
case LSHIFTRT:
+ case ROTATE:
+ case ROTATERT:
+ if (mode == DImode)
+ return false;
if (TARGET_BARREL_SHIFTER)
{
- if (CONSTANT_P (XEXP (x, 0)))
+ *total = COSTS_N_INSNS (1);
+ if (CONSTANT_P (XEXP (x, 1)))
{
- *total += rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
+ *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
0, speed);
return true;
}
- *total = COSTS_N_INSNS (1);
}
else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
- *total = COSTS_N_INSNS (16);
+ *total = speed ? COSTS_N_INSNS (16) : COSTS_N_INSNS (4);
else
{
- *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
- /* ??? want_to_gcse_p can throw negative shift counts at us,
- and then panics when it gets a negative cost as result.
- Seen for gcc.c-torture/compile/20020710-1.c -Os . */
- if (*total < 0)
- *total = 0;
+ int n = INTVAL (XEXP (x, 1)) & 31;
+ if (n < 4)
+ *total = COSTS_N_INSNS (n);
+ else
+ *total = speed ? COSTS_N_INSNS (n + 2) : COSTS_N_INSNS (4);
+ *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
+ 0, speed);
+ return true;
}
return false;
@@ -5424,6 +5626,8 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
return false;
case PLUS:
+ if (mode == DImode)
+ return false;
if (outer_code == MEM && CONST_INT_P (XEXP (x, 1))
&& RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1)))
{
@@ -5433,8 +5637,8 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
if ((GET_CODE (XEXP (x, 0)) == ASHIFT
&& _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
- || (GET_CODE (XEXP (x, 0)) == MULT
- && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
+ || (GET_CODE (XEXP (x, 0)) == MULT
+ && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
{
if (CONSTANT_P (XEXP (x, 1)) && !speed)
*total += COSTS_N_INSNS (4);
@@ -5445,8 +5649,8 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
case MINUS:
if ((GET_CODE (XEXP (x, 1)) == ASHIFT
&& _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
- || (GET_CODE (XEXP (x, 1)) == MULT
- && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
+ || (GET_CODE (XEXP (x, 1)) == MULT
+ && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
{
if (CONSTANT_P (XEXP (x, 0)) && !speed)
*total += COSTS_N_INSNS (4);
@@ -7546,9 +7750,9 @@ hwloop_optimize (hwloop_info loop)
if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
{
if (dump_file)
- fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
+ fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
" iterator\n",
- loop->loop_no);
+ loop->loop_no);
/* This loop doesn't use the lp_count, check though if we can
fix it. */
if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
@@ -7721,7 +7925,7 @@ hwloop_optimize (hwloop_info loop)
/* Make sure we don't split a call and its corresponding
CALL_ARG_LOCATION note. */
&& NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
- entry_after = NEXT_INSN (entry_after);
+ entry_after = NEXT_INSN (entry_after);
#endif
entry_after = next_nonnote_insn_bb (entry_after);
@@ -10958,35 +11162,37 @@ static int
arc_insn_cost (rtx_insn *insn, bool speed)
{
int cost;
- if (recog_memoized (insn) < 0)
- return 0;
-
- /* If optimizing for size, we want the insn size. */
- if (!speed)
- return get_attr_length (insn);
-
- /* Use cost if provided. */
- cost = get_attr_cost (insn);
- if (cost > 0)
- return cost;
-
- /* For speed make a simple cost model: memory access is more
- expensive than any other instruction. */
- enum attr_type type = get_attr_type (insn);
-
- switch (type)
+ enum attr_type type;
+ if (recog_memoized (insn) >= 0)
{
- case TYPE_LOAD:
- case TYPE_STORE:
- cost = COSTS_N_INSNS (2);
- break;
-
- default:
- cost = COSTS_N_INSNS (1);
- break;
+ if (speed)
+ {
+ /* Use cost if provided. */
+ cost = get_attr_cost (insn);
+ if (cost > 0)
+ return cost;
+ /* For speed make a simple cost model: memory access is more
+ expensive than any other instruction. */
+ type = get_attr_type (insn);
+ if (type == TYPE_LOAD || type == TYPE_STORE)
+ return COSTS_N_INSNS (2);
+ }
+ else
+ {
+ /* If optimizing for size, we want the insn size. */
+ type = get_attr_type (insn);
+ if (type != TYPE_MULTI)
+ return get_attr_length (insn);
+ }
}
- return cost;
+ if (rtx set = single_set (insn))
+ cost = set_rtx_cost (set, speed);
+ else
+ cost = pattern_cost (PATTERN (insn), speed);
+ /* If the cost is zero, then it's likely a complex insn. We don't
+ want the cost of these to be less than something we know about. */
+ return cost ? cost : COSTS_N_INSNS (2);
}
static unsigned
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 5877389..b34f0b2 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -956,10 +956,16 @@ arc_select_cc_mode (OP, X, Y)
/* Costs. */
+/* Analog of COSTS_N_INSNS when optimizing for size. */
+#ifndef COSTS_N_BYTES
+#define COSTS_N_BYTES(N) (N)
+#endif
+
/* The cost of a branch insn. */
/* ??? What's the right value here? Branches are certainly more
expensive than reg->reg moves. */
-#define BRANCH_COST(speed_p, predictable_p) 2
+#define BRANCH_COST(speed_p, predictable_p) \
+ (speed_p ? COSTS_N_INSNS (2) : COSTS_N_INSNS (1))
/* Scc sets the destination to 1 and then conditionally zeroes it.
Best case, ORed SCCs can be made into clear - condset - condset.
@@ -971,11 +977,8 @@ arc_select_cc_mode (OP, X, Y)
beging decisive of p0, we want:
p0 * (branch_cost - 4) > (1 - p0) * 5
??? We don't get to see that probability to evaluate, so we can
- only wildly guess that it might be 50%.
- ??? The compiler also lacks the notion of branch predictability. */
-#define LOGICAL_OP_NON_SHORT_CIRCUIT \
- (BRANCH_COST (optimize_function_for_speed_p (cfun), \
- false) > 9)
+ only wildly guess that it might be 50%. */
+#define LOGICAL_OP_NON_SHORT_CIRCUIT false
/* Nonzero if access to memory by bytes is slow and undesirable.
For RISC chips, it means that access to memory by bytes is no
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 22af0bf..96ff62d 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -2293,7 +2293,7 @@ archs4x, archs4xd"
; registers, since it cannot be the destination of a multi-cycle insn
; like MPY or MPYU.
(define_insn "mulsi3_700"
- [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=r, r,r, r,r")
+ [(set (match_operand:SI 0 "register_operand" "=r, r,r, r,r")
(mult:SI (match_operand:SI 1 "register_operand" "%0, r,0, 0,r")
(match_operand:SI 2 "nonmemory_operand" "rL,rL,I,Cal,Cal")))]
"TARGET_ARC700_MPY"
@@ -2306,8 +2306,8 @@ archs4x, archs4xd"
; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
; short variant. LP_COUNT constraints are still valid.
(define_insn "mulsi3_v2"
- [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=q,q, r, r,r, r, r")
- (mult:SI (match_operand:SI 1 "register_operand" "%0,q, 0, r,0, 0, c")
+ [(set (match_operand:SI 0 "register_operand" "=q,q, r, r,r, r, r")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0,q, 0, r,0, 0, r")
(match_operand:SI 2 "nonmemory_operand" "q,0,rL,rL,I,Cal,Cal")))]
"TARGET_MULTI"
"@
@@ -3353,22 +3353,17 @@ archs4x, archs4xd"
;; Shift instructions.
-(define_expand "ashlsi3"
- [(set (match_operand:SI 0 "dest_reg_operand" "")
- (ashift:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- "")
+(define_code_iterator ANY_ROTATE [rotate rotatert])
+(define_code_iterator ANY_SHIFT_ROTATE [ashift ashiftrt lshiftrt
+ rotate rotatert])
-(define_expand "ashrsi3"
- [(set (match_operand:SI 0 "dest_reg_operand" "")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- "")
+(define_code_attr insn [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")
+ (rotate "rotl") (rotatert "rotr")])
-(define_expand "lshrsi3"
+(define_expand "<insn>si3"
[(set (match_operand:SI 0 "dest_reg_operand" "")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
"")
; asl, asr, lsr patterns:
@@ -3421,6 +3416,37 @@ archs4x, archs4xd"
(set_attr "predicable" "no,no,yes,no,no")
(set_attr "cond" "nocond,canuse,canuse,nocond,nocond")])
+(define_insn "<insn>si2_cnt16"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ANY_ROTATE:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 16)))]
+ "TARGET_SWAP"
+ "swap\\t%0,%1"
+ [(set_attr "length" "4")
+ (set_attr "type" "two_cycle_core")])
+
+(define_insn "ashlsi2_cnt16"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
+ (const_int 16)))]
+ "TARGET_SWAP && TARGET_V2"
+ "lsl16\\t%0,%1"
+ [(set_attr "type" "shift")
+ (set_attr "iscompact" "false")
+ (set_attr "length" "4")
+ (set_attr "predicable" "no")])
+
+(define_insn "lshrsi2_cnt16"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "rL")
+ (const_int 16)))]
+ "TARGET_SWAP && TARGET_V2"
+ "lsr16\\t%0,%1"
+ [(set_attr "type" "shift")
+ (set_attr "iscompact" "false")
+ (set_attr "length" "4")
+ (set_attr "predicable" "no")])
+
;; Split asl dst,1,src into bset dst,0,src.
(define_insn_and_split "*ashlsi3_1"
[(set (match_operand:SI 0 "dest_reg_operand")
@@ -3437,79 +3463,10 @@ archs4x, archs4xd"
[(set_attr "type" "shift")
(set_attr "length" "8")])
-(define_insn_and_split "*ashlsi3_nobs"
- [(set (match_operand:SI 0 "dest_reg_operand")
- (ashift:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "nonmemory_operand")))]
- "!TARGET_BARREL_SHIFTER
- && operands[2] != const1_rtx
- && arc_pre_reload_split ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- if (CONST_INT_P (operands[2]))
- {
- int n = INTVAL (operands[2]) & 0x1f;
- if (n <= 9)
- {
- if (n == 0)
- emit_move_insn (operands[0], operands[1]);
- else if (n <= 2)
- {
- emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[1]));
- if (n == 2)
- emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
- }
- else
- {
- rtx zero = gen_reg_rtx (SImode);
- emit_move_insn (zero, const0_rtx);
- emit_insn (gen_add_shift (operands[0], operands[1],
- GEN_INT (3), zero));
- for (n -= 3; n >= 3; n -= 3)
- emit_insn (gen_add_shift (operands[0], operands[0],
- GEN_INT (3), zero));
- if (n == 2)
- emit_insn (gen_add_shift (operands[0], operands[0],
- const2_rtx, zero));
- else if (n)
- emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
- }
- DONE;
- }
- else if (n >= 29)
- {
- if (n < 31)
- {
- if (n == 29)
- {
- emit_insn (gen_andsi3_i (operands[0], operands[1],
- GEN_INT (7)));
- emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
- }
- else
- emit_insn (gen_andsi3_i (operands[0], operands[1],
- GEN_INT (3)));
- emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
- }
- else
- emit_insn (gen_andsi3_i (operands[0], operands[1], const1_rtx));
- emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
- DONE;
- }
- }
-
- rtx shift = gen_rtx_fmt_ee (ASHIFT, SImode, operands[1], operands[2]);
- emit_insn (gen_shift_si3_loop (operands[0], operands[1],
- operands[2], shift));
- DONE;
-})
-
-(define_insn_and_split "*ashlri3_nobs"
+(define_insn_and_split "*<insn>si3_nobs"
[(set (match_operand:SI 0 "dest_reg_operand")
- (ashiftrt:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "nonmemory_operand")))]
+ (ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "nonmemory_operand")))]
"!TARGET_BARREL_SHIFTER
&& operands[2] != const1_rtx
&& arc_pre_reload_split ()"
@@ -3517,104 +3474,28 @@ archs4x, archs4xd"
"&& 1"
[(const_int 0)]
{
- if (CONST_INT_P (operands[2]))
- {
- int n = INTVAL (operands[2]) & 0x1f;
- if (n <= 4)
- {
- if (n != 0)
- {
- emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[1]));
- while (--n > 0)
- emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
- }
- else
- emit_move_insn (operands[0], operands[1]);
- DONE;
- }
- }
-
- rtx pat;
- rtx shift = gen_rtx_fmt_ee (ASHIFTRT, SImode, operands[1], operands[2]);
- if (shiftr4_operator (shift, SImode))
- pat = gen_shift_si3 (operands[0], operands[1], operands[2], shift);
- else
- pat = gen_shift_si3_loop (operands[0], operands[1], operands[2], shift);
- emit_insn (pat);
+ arc_split_<insn> (operands);
DONE;
})
-(define_insn_and_split "*lshrsi3_nobs"
- [(set (match_operand:SI 0 "dest_reg_operand")
- (lshiftrt:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "nonmemory_operand")))]
- "!TARGET_BARREL_SHIFTER
- && operands[2] != const1_rtx
- && arc_pre_reload_split ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- if (CONST_INT_P (operands[2]))
- {
- int n = INTVAL (operands[2]) & 0x1f;
- if (n <= 4)
- {
- if (n != 0)
- {
- emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[1]));
- while (--n > 0)
- emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
- }
- else
- emit_move_insn (operands[0], operands[1]);
- DONE;
- }
- }
-
- rtx pat;
- rtx shift = gen_rtx_fmt_ee (LSHIFTRT, SImode, operands[1], operands[2]);
- if (shiftr4_operator (shift, SImode))
- pat = gen_shift_si3 (operands[0], operands[1], operands[2], shift);
- else
- pat = gen_shift_si3_loop (operands[0], operands[1], operands[2], shift);
- emit_insn (pat);
- DONE;
-})
-
-;; shift_si3 appears after {ashr,lshr}si3_nobs
-(define_insn "shift_si3"
- [(set (match_operand:SI 0 "dest_reg_operand" "=r")
- (match_operator:SI 3 "shiftr4_operator"
- [(match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "const_int_operand" "n")]))
- (clobber (match_scratch:SI 4 "=&r"))
- (clobber (reg:CC CC_REG))
- ]
- "!TARGET_BARREL_SHIFTER
- && operands[2] != const1_rtx"
- "* return output_shift (operands);"
- [(set_attr "type" "shift")
- (set_attr "length" "16")])
-
-;; shift_si3_loop appears after {ashl,ashr,lshr}si3_nobs
-(define_insn "shift_si3_loop"
+;; <ANY_SHIFT_ROTATE>si3_loop appears after <ANY_SHIFT_ROTATE>si3_nobs
+(define_insn "<insn>si3_loop"
[(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
- (match_operator:SI 3 "shift_operator"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
+ (ANY_SHIFT_ROTATE:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rn,Cal")))
(clobber (reg:SI LP_COUNT))
(clobber (reg:CC CC_REG))
]
"!TARGET_BARREL_SHIFTER
&& operands[2] != const1_rtx"
- "* return output_shift (operands);"
+ "* return output_shift_loop (<CODE>, operands);"
[(set_attr "type" "shift")
(set_attr "length" "16,20")])
;; Rotate instructions.
-(define_insn "rotrsi3"
+(define_insn "rotrsi3_insn"
[(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
(rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand" " 0,rL,rCsz")
(match_operand:SI 2 "nonmemory_operand" "rL,rL,rCal")))]
@@ -3624,6 +3505,35 @@ archs4x, archs4xd"
(set_attr "predicable" "yes,no,no")
(set_attr "length" "4,4,8")])
+(define_insn_and_split "*rotlsi3"
+ [(set (match_operand:SI 0 "dest_reg_operand")
+ (rotate:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "nonmemory_operand")))]
+ "TARGET_BARREL_SHIFTER
+ && arc_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 0) (rotatert:SI (match_dup 1) (match_dup 3)))]
+{
+ if (CONST_INT_P (operands[2]))
+ {
+ int n = INTVAL (operands[2]) & 31;
+ if (n == 0)
+ {
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+ }
+ else operands[3] = GEN_INT (32 - n);
+ }
+ else
+ {
+ if (!register_operand (operands[2], SImode))
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[3] = gen_reg_rtx (SImode);
+ emit_insn (gen_negsi2 (operands[3], operands[2]));
+ }
+})
+
;; Compare / branch instructions.
(define_expand "cbranchsi4"
@@ -5995,6 +5905,34 @@ archs4x, archs4xd"
(zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
(match_dup 1)])
+;; Split sign-extension of single least significant bit as and x,$1;neg x
+(define_insn_and_split "*extvsi_1_0"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extract:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 1)
+ (const_int 0)))]
+ "!TARGET_BARREL_SHIFTER"
+ "#"
+ "&& 1"
+ [(set (match_dup 0) (and:SI (match_dup 1) (const_int 1)))
+ (set (match_dup 0) (neg:SI (match_dup 0)))]
+ ""
+ [(set_attr "length" "8")])
+
+(define_insn_and_split "rotlsi3_cnt1"
+ [(set (match_operand:SI 0 "dest_reg_operand" "=r")
+ (rotate:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 1)))]
+ "!TARGET_BARREL_SHIFTER"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ emit_insn (gen_add_f (operands[0], operands[1], operands[1]));
+ emit_insn (gen_adc (operands[0], operands[0], const0_rtx));
+ DONE;
+})
+
(define_insn "rotrsi3_cnt1"
[(set (match_operand:SI 0 "dest_reg_operand" "=r")
(rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
@@ -6037,17 +5975,6 @@ archs4x, archs4xd"
(set_attr "length" "4")
(set_attr "predicable" "no")])
-(define_insn "*ashlsi2_cnt16"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
- (const_int 16)))]
- "TARGET_SWAP && TARGET_V2"
- "lsl16\\t%0,%1"
- [(set_attr "type" "shift")
- (set_attr "iscompact" "false")
- (set_attr "length" "4")
- (set_attr "predicable" "no")])
-
(define_insn "lshrsi3_cnt1"
[(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index e37d884..6070750 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -23,13 +23,6 @@
return register_operand (op, mode);
})
-(define_predicate "mpy_dest_reg_operand"
- (match_code "reg,subreg")
-{
- return register_operand (op, mode);
-})
-
-
;; Returns 1 if OP is a symbol reference.
(define_predicate "symbolic_operand"
(match_code "symbol_ref, label_ref, const")
@@ -549,15 +542,6 @@
(match_code "ashiftrt, lshiftrt, ashift")
)
-;; Return true if OP is a right shift operator that can be implemented in
-;; four insn words or less without a barrel shifter or multiplier.
-(define_predicate "shiftr4_operator"
- (and (match_code "ashiftrt, lshiftrt")
- (match_test "const_int_operand (XEXP (op, 1), VOIDmode) ")
- (match_test "UINTVAL (XEXP (op, 1)) <= 4U
- || INTVAL (XEXP (op, 1)) == 30
- || INTVAL (XEXP (op, 1)) == 31")))
-
(define_predicate "mult_operator"
(and (match_code "mult") (match_test "TARGET_MPY"))
)
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 57c3b9b..49896bb 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -183,7 +183,28 @@
do \
{ \
if (TARGET_ARM) \
- asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE); \
+ { \
+ switch (GET_MODE (body)) \
+ { \
+ case E_QImode: \
+ asm_fprintf (STREAM, "\t.byte\t(%LL%d-%LLrtx%d-4)/4\n", \
+ VALUE, REL); \
+ break; \
+ case E_HImode: \
+ asm_fprintf (STREAM, "\t.2byte\t(%LL%d-%LLrtx%d-4)/4\n", \
+ VALUE, REL); \
+ break; \
+ case E_SImode: \
+ if (flag_pic) \
+ asm_fprintf (STREAM, "\t.word\t%LL%d-%LLrtx%d-4\n", \
+ VALUE, REL); \
+ else \
+ asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE); \
+ break; \
+ default: \
+ gcc_unreachable (); \
+ } \
+ } \
else if (TARGET_THUMB1) \
{ \
if (flag_pic || optimize_size) \
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 77e7633..2f5ca79 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -261,6 +261,7 @@ extern void thumb_expand_cpymemqi (rtx *);
extern rtx arm_return_addr (int, rtx);
extern void thumb_reload_out_hi (rtx *);
extern void thumb_set_return_address (rtx, rtx);
+extern const char *arm_output_casesi (rtx *);
extern const char *thumb1_output_casesi (rtx *);
extern const char *thumb2_output_casesi (rtx *);
#endif
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 6e933c8..620ef7b 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -30464,6 +30464,62 @@ arm_output_iwmmxt_tinsr (rtx *operands)
return "";
}
+/* Output an arm casesi dispatch sequence. Used by arm_casesi_internal insn.
+ Responsible for the handling of switch statements in arm. */
+const char *
+arm_output_casesi (rtx *operands)
+{
+ char label[100];
+ rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
+ gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
+ output_asm_insn ("cmp\t%0, %1", operands);
+ output_asm_insn ("bhi\t%l3", operands);
+ ASM_GENERATE_INTERNAL_LABEL (label, "Lrtx", CODE_LABEL_NUMBER (operands[2]));
+ switch (GET_MODE (diff_vec))
+ {
+ case E_QImode:
+ if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
+ output_asm_insn ("ldrb\t%4, [%5, %0]", operands);
+ else
+ output_asm_insn ("ldrsb\t%4, [%5, %0]", operands);
+ output_asm_insn ("add\t%|pc, %|pc, %4, lsl #2", operands);
+ break;
+ case E_HImode:
+ if (REGNO (operands[4]) != REGNO (operands[5]))
+ {
+ output_asm_insn ("add\t%4, %0, %0", operands);
+ if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
+ output_asm_insn ("ldrh\t%4, [%5, %4]", operands);
+ else
+ output_asm_insn ("ldrsh\t%4, [%5, %4]", operands);
+ }
+ else
+ {
+ output_asm_insn ("add\t%4, %5, %0", operands);
+ if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
+ output_asm_insn ("ldrh\t%4, [%4, %0]", operands);
+ else
+ output_asm_insn ("ldrsh\t%4, [%4, %0]", operands);
+ }
+ output_asm_insn ("add\t%|pc, %|pc, %4, lsl #2", operands);
+ break;
+ case E_SImode:
+ if (flag_pic)
+ {
+ output_asm_insn ("ldr\t%4, [%5, %0, lsl #2]", operands);
+ output_asm_insn ("add\t%|pc, %|pc, %4", operands);
+ }
+ else
+ output_asm_insn ("ldr\t%|pc, [%5, %0, lsl #2]", operands);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ assemble_label (asm_out_file, label);
+ output_asm_insn ("nop", operands);
+ return "";
+}
+
/* Output a Thumb-1 casesi dispatch sequence. */
const char *
thumb1_output_casesi (rtx *operands)
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 4f54530..a9c2752 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2092,10 +2092,11 @@ enum arm_auto_incmodes
for the index in the tablejump instruction. */
#define CASE_VECTOR_MODE Pmode
-#define CASE_VECTOR_PC_RELATIVE ((TARGET_THUMB2 \
- || (TARGET_THUMB1 \
- && (optimize_size || flag_pic))) \
- && (!target_pure_code))
+#define CASE_VECTOR_PC_RELATIVE \
+ (TARGET_ARM \
+ || (!target_pure_code \
+ && (TARGET_THUMB2 \
+ || (TARGET_THUMB1 && (optimize_size || flag_pic)))))
#define CASE_VECTOR_SHORTEN_MODE(min, max, body) \
@@ -2109,9 +2110,19 @@ enum arm_auto_incmodes
: min >= -4096 && max < 4096 \
? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, HImode) \
: SImode) \
- : ((min < 0 || max >= 0x20000 || !TARGET_THUMB2) ? SImode \
- : (max >= 0x200) ? HImode \
- : QImode))
+ : (TARGET_THUMB2 \
+ ? ((min > 0 && max < 0x200) ? QImode \
+ : (min > 0 && max <= 0x20000) ? HImode \
+ : SImode) \
+ : ((min >= 0 && max < 1024) \
+ ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, QImode) \
+ : (min >= -512 && max <= 508) \
+ ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, QImode) \
+ :(min >= 0 && max < 262144) \
+ ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, HImode) \
+ : (min >= -131072 && max <=131068) \
+ ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, HImode) \
+ : SImode)))
/* signed 'char' is most compatible, but RISC OS wants it unsigned.
unsigned is probably best, but may break some code. */
@@ -2291,8 +2302,14 @@ extern int making_const_table;
asm_fprintf (STREAM, "\tpop {%r}\n", REGNO); \
} while (0)
-#define ADDR_VEC_ALIGN(JUMPTABLE) \
- ((TARGET_THUMB && GET_MODE (PATTERN (JUMPTABLE)) == SImode) ? 2 : 0)
+/* If the switch table is in the code segment, additional alignment is
+ needed for Thumb SImode tables. Otherwise, tables in RO data have
+ natural alignment. */
+#define ADDR_VEC_ALIGN(TABLE) \
+ (JUMP_TABLES_IN_TEXT_SECTION \
+ ? ((TARGET_THUMB && GET_MODE (PATTERN (TABLE)) == SImode) ? 2 : 0) \
+ : (exact_log2 (GET_MODE_ALIGNMENT (GET_MODE (PATTERN (TABLE))) \
+ / BITS_PER_UNIT)))
/* Alignment for case labels comes from ADDR_VEC_ALIGN; avoid the
default alignment from elfos.h. */
@@ -2301,7 +2318,7 @@ extern int making_const_table;
#define LABEL_ALIGN_AFTER_BARRIER(LABEL) \
(GET_CODE (PATTERN (prev_active_insn (LABEL))) == ADDR_DIFF_VEC \
- ? 1 : 0)
+ ? (TARGET_ARM ? 2 : 1) : 0)
#define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
arm_declare_function_name ((STREAM), (NAME), (DECL));
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 2ac9723..07eaf06 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -9514,7 +9514,9 @@
(match_operand:SI 2 "const_int_operand") ; total range
(match_operand:SI 3 "" "") ; table label
(match_operand:SI 4 "" "")] ; Out of range label
- "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
+ "(TARGET_ARM
+ || (!target_pure_code
+ && (TARGET_THUMB2 || optimize_size || flag_pic)))"
"
{
enum insn_code code;
@@ -9556,13 +9558,15 @@
(match_dup 4)
(label_ref:SI (match_operand 3 ""))))
(clobber (reg:CC CC_REGNUM))
+ (clobber (match_scratch:SI 5))
(use (label_ref:SI (match_operand 2 "")))])]
"TARGET_ARM"
{
- operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
- operands[4] = gen_rtx_PLUS (SImode, operands[4],
- gen_rtx_LABEL_REF (SImode, operands[2]));
- operands[4] = gen_rtx_MEM (SImode, operands[4]);
+ rtx vec_table_ref = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[2]));
+ rtx tmp = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
+ tmp = gen_rtx_PLUS (SImode, tmp,
+ vec_table_ref);
+ operands[4] = gen_rtx_MEM (SImode, tmp);
MEM_READONLY_P (operands[4]) = 1;
MEM_NOTRAP_P (operands[4]) = 1;
})
@@ -9573,18 +9577,17 @@
(leu (match_operand:SI 0 "s_register_operand" "r")
(match_operand:SI 1 "arm_rhs_operand" "rI"))
(mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
- (label_ref:SI (match_operand 2 "" ""))))
+ (match_operand:SI 5 "s_register_operand" "r")))
(label_ref:SI (match_operand 3 "" ""))))
(clobber (reg:CC CC_REGNUM))
- (use (label_ref:SI (match_dup 2)))])]
+ (clobber (match_scratch:SI 4 "=r"))
+ (use (label_ref:SI (match_operand 2 "")))])]
"TARGET_ARM"
- "*
- if (flag_pic)
- return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
- return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
- "
+ {
+ return arm_output_casesi (operands);
+ }
[(set_attr "conds" "clob")
- (set_attr "length" "12")
+ (set_attr "length" "24")
(set_attr "type" "multiple")]
)
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 5766cb4..f766828 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -91,11 +91,21 @@
/* Define this macro if jump tables (for `tablejump' insns) should be
output in the text section, along with the assembler instructions.
Otherwise, the readonly data section is used. */
-/* We put ARM and Thumb-2 jump tables in the text section, because it makes
- the code more efficient, but for Thumb-1 it's better to put them out of
- band unless we are generating compressed tables. */
+/* The choice of placement for jump tables is nuanced. For cores with
+ Harvard caches (pretty much all cases these days), there is a
+ benefit of maintaing a separation between I- and D-cache candidates
+ and that favors having jump tables in the RO data section. This
+ makes the dispatch sequence slightly longer as we need to load the
+ address of the jump table first, but we often save elsewhere as the
+ content of the code section becomes better packed and we need
+ fewer long-range branch operations. We also require the dispatch
+ table to be in the RO section when compiling for pure code. We
+ currently place jump tables in the RO-data section for Arm or
+ whenever pure code is required; we also do it for Thumb-1 when
+ using an ADDR_VEC. The remaining cases put the jump table in the
+ text section, but we should revisit this choice. */
#define JUMP_TABLES_IN_TEXT_SECTION \
- ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
+ ((TARGET_THUMB2 || (TARGET_THUMB && (optimize_size || flag_pic))) \
&& !target_pure_code)
#ifndef LINK_SPEC
diff --git a/gcc/config/bpf/bpf-passes.def b/gcc/config/bpf/bpf-passes.def
new file mode 100644
index 0000000..0ec20ea
--- /dev/null
+++ b/gcc/config/bpf/bpf-passes.def
@@ -0,0 +1,20 @@
+/* Declaration of target-specific passes for eBPF.
+ 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/>. */
+
+INSERT_PASS_BEFORE (pass_lower_omp, 1, pass_lower_bpf_core);
diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
index fbe0d8a..ecbbd78 100644
--- a/gcc/config/bpf/bpf-protos.h
+++ b/gcc/config/bpf/bpf-protos.h
@@ -31,6 +31,8 @@ extern void bpf_expand_prologue (void);
extern void bpf_expand_epilogue (void);
extern void bpf_expand_cbranch (machine_mode, rtx *);
const char *bpf_add_core_reloc (rtx *operands, const char *templ);
-void bpf_replace_core_move_operands (rtx *operands);
+
+class gimple_opt_pass;
+gimple_opt_pass *make_pass_lower_bpf_core (gcc::context *ctxt);
#endif /* ! GCC_BPF_PROTOS_H */
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 437bd65..63637ec 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1034,6 +1034,18 @@ bpf_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
#undef TARGET_RESOLVE_OVERLOADED_BUILTIN
#define TARGET_RESOLVE_OVERLOADED_BUILTIN bpf_resolve_overloaded_builtin
+static rtx
+bpf_delegitimize_address (rtx rtl)
+{
+ if (GET_CODE (rtl) == UNSPEC
+ && XINT (rtl, 1) == UNSPEC_CORE_RELOC)
+ return XVECEXP (rtl, 0, 0);
+
+ return rtl;
+}
+
+#undef TARGET_DELEGITIMIZE_ADDRESS
+#define TARGET_DELEGITIMIZE_ADDRESS bpf_delegitimize_address
/* Initialize target-specific function library calls. This is mainly
used to call library-provided soft-fp operations, since eBPF
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index e87d721..0e2ad8d 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -374,8 +374,6 @@
""
"
{
- bpf_replace_core_move_operands (operands);
-
if (!register_operand(operands[0], <MM:MODE>mode)
&& !register_operand(operands[1], <MM:MODE>mode))
operands[1] = force_reg (<MM:MODE>mode, operands[1]);
@@ -393,7 +391,7 @@
{st<mop>\t%0,%1|*(<smop> *) (%0) = %1}"
[(set_attr "type" "ldx,alu,alu,stx,st")])
-(define_insn "mov_reloc_core<MM:mode>"
+(define_insn "*mov_reloc_core<MM:mode>"
[(set (match_operand:MM 0 "nonimmediate_operand" "=r,q,r")
(unspec:MM [
(match_operand:MM 1 "immediate_operand" " I,I,B")
diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc
index 60d21a8..a224847 100644
--- a/gcc/config/bpf/core-builtins.cc
+++ b/gcc/config/bpf/core-builtins.cc
@@ -38,97 +38,96 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
+#include "gimple-fold.h"
#include "tree-pass.h"
#include "plugin.h"
+#include "gimplify.h"
#include "ctfc.h"
#include "btf.h"
#include "coreout.h"
#include "core-builtins.h"
-/*
- * BPF CO-RE builtins definition.
-
- The expansion of CO-RE builtins occur in three steps:
- 1. - bpf_resolve_overloaded_core_builtin (pack step)
- Right after the front-end, all of the CO-RE builtins are converted to an
- internal builtin __builtin_core_reloc, which takes a single argument and
- has polymorphic return value to fit the particular expected return type
- from the original builtin. The first argument contains an index argument
- which points to the information stored in a vec<struct cr_builtins>
- which collects the required information from the original CO-RE builtin in
- order to use it later on in the __builtin_core_reloc expansion (the next
- step).
-
- 2. - bpf_expand_core_builtin
- In this step, the __builtin_core_reloc is expanded to a unspec:UNSPEC_CORE_RELOC
- with 3 operands, destination, source and the index. The index operand
- is the index in the vec constructed in the previous step.
-
- 3. - final asm output (process step)
- This is the output of the unspec:UNSPEC_CORE_RELOC. The index passed in
- the third operand is read and extracted as a integer from the rtx node.
- The data is collected from the vec and it is used to create
- the proper CO-RE relocation as well as do the final assembly output.
- It also creates a label to mark the location of the move instruction that
- is used in the CO-RE relocation.
-
- The initialization of the CO-RE builtins infrastructure occurs in
- bpf_is function. It creates a struct
- builtin_helpers_t arrays which defines the kind argument position,
- the callback helpers, kind, compare, pack and process, for each individual
- type of builtin argument possible in the original CO-RE builtins.
-
- More precisely, field expression, type and enum value, used in the following
- relocations:
- - __builtin_core_preserve_access_index (<field_expr>)
- - __builtin_core_field_info (<field_expr>, <kind>)
- - __builtin_core_type_id (<type>, <kind>)
- - __builtin_core_type_info (<type>, <kind>)
- - __builtin_core_enum_value (<enum_value>, <kind>)
-
- The kind helper allows to identify the proper relocation for the builtin
- call based on the value within the kind argument.
-
- The compare helper is used to identify if a new builtin call has similar
- arguments to any other builtin call with the compiling unit.
- This enables the possibility to optimize consecutive similar calls of the
- builtins.
-
- The pack helper callbacks are suppose to decode the original CO-RE builtin
- call arguments, verify that it is a valid tree node for the particular
- builtin, allocate a struct cr_local in vector and write it with the
- relevant data for the particular builtin type.
-
- The process helper should take the data constructed in the pack helper and
- create a struct cr_final element which contains the essential
- information to create a CO-RE relocation.
- This information is further used by the final assembly output step to define
- the CO-RE relocation and pass-through the default value for the original
- CO-RE builtin.
-
-
- BPF CO-RE preserve access is supported in two forms:
- - A target builtin, __builtin_preserve_access_index
-
- This builtin accepts a single argument. Any access to an aggregate data
- structure (struct, union or array) within the argument will be recorded by
- the CO-RE machinery, resulting in a relocation record being placed in the
- .BTF.ext section of the output.
-
- It is implemented in bpf_resolve_overloaded_builtin () and
- bpf_expand_builtin (), using the supporting routines below.
-
- - An attribute, __attribute__((preserve_access_index))
-
- This attribute can be applied to struct and union types. Any access to a
- type with this attribute will be recorded by the CO-RE machinery.
- In the expand, any move matching is checked if any of its operands is
- an expression to an attributed type, and if so, the expand will emit a
- unspec:UNSPEC_CORE_RELOC that later on, in final assembly output, will
- create the CO-RE relocation, just like it would happen if it was defined
- as a builtin. */
-
+/* BPF CO-RE builtins definition.
+
+ The expansion of CO-RE builtins occur in three steps:
+ 1. - bpf_resolve_overloaded_core_builtin (pack step)
+ Right after the front-end, all of the CO-RE builtins are converted to an
+ internal builtin __builtin_core_reloc, which takes a single argument and
+ has polymorphic return value to fit the particular expected return type
+ from the original builtin. The first argument contains an index argument
+ which points to the information stored in a vec<struct cr_builtins> which
+ collects the required information from the original CO-RE builtin in
+ order to use it later on in the __builtin_core_reloc expansion (the next
+ step).
+
+ 2. - bpf_expand_core_builtin
+ In this step, the __builtin_core_reloc is expanded to a
+ unspec:UNSPEC_CORE_RELOC with 3 operands, destination, source and the
+ index. The index operand is the index in the vec constructed in the
+ previous step.
+
+ 3. - final asm output (process step)
+ This is the output of the unspec:UNSPEC_CORE_RELOC. The index passed in
+ the third operand is read and extracted as a integer from the rtx node.
+ The data is collected from the vec and it is used to create the proper
+ CO-RE relocation as well as do the final assembly output. It also
+ creates a label to mark the location of the move instruction that is used
+ in the CO-RE relocation.
+
+ The initialization of the CO-RE builtins infrastructure occurs in
+ bpf_init_core_builtins function. It creates a struct builtin_helpers_t
+ arrays which defines the kind argument position, the callback helpers,
+ kind, compare, pack and process, for each individual type of builtin
+ argument possible in the original CO-RE builtins.
+
+ More precisely, field expression, type and enum value, used in the
+ following relocations:
+ - __builtin_core_field_info (<field_expr>, <kind>)
+ - __builtin_core_type_id (<type>, <kind>)
+ - __builtin_core_type_info (<type>, <kind>)
+ - __builtin_core_enum_value (<enum_value>, <kind>)
+
+ The kind helper allows to identify the proper relocation for the builtin
+ call based on the value within the kind argument.
+
+ The compare helper is used to identify if a new builtin call has similar
+ arguments to any other builtin call with the compiling unit. This enables
+ the possibility to optimize consecutive similar calls of the builtins.
+
+ The pack helper callbacks are suppose to decode the original CO-RE builtin
+ call arguments, verify that it is a valid tree node for the particular
+ builtin, allocate a struct cr_local in vector and write it with the
+ relevant data for the particular builtin type.
+
+ The process helper should take the data constructed in the pack helper and
+ create a struct cr_final element which contains the essential information
+ to create a CO-RE relocation.
+ This information is further used by the final assembly output step to
+ define the CO-RE relocation and pass-through the default value for the
+ original CO-RE builtin.
+
+ BPF CO-RE preserve access is supported in two forms:
+ - A target builtin, __builtin_preserve_access_index
+
+ This builtin accepts a single argument. Any access to an aggregate data
+ structure (struct, union or array), also referred through the document as
+ an field expression, within the argument will be recorded by the CO-RE
+ machinery, resulting in one or more relocations being inserted in the
+ .BTF.ext section of the output.
+
+ - An attribute, __attribute__((preserve_access_index))
+
+ This attribute can be applied to struct and union types. Any access done
+ through a node typed with this attribute will be recorded by the CO-RE
+ machinery. This conversion is done in an independent gimple pass very
+ early in compilation, making sure that the field expression is
+ originating from a tree node which his type is attributed.
+
+ Both these variants of preserve_access_index rely on a tree walker that
+ identifies and converts any CO-RE valid field expressions. Apart from the
+ gimple specific requirements for the attribute implementation both builtin
+ and attribute implementations rely on the same mechanism. */
struct GTY(()) cr_builtins
{
@@ -139,12 +138,13 @@ struct GTY(()) cr_builtins
enum btf_core_reloc_kind kind;
enum bpf_builtins orig_builtin_code;
tree orig_arg_expr;
+ tree access_node;
};
typedef struct cr_builtins *cr_builtins_ref;
#define CORE_BUILTINS_DATA_EMPTY \
{ NULL_TREE, NULL_TREE, NULL_TREE, NULL_RTX, BPF_RELO_INVALID, \
- BPF_BUILTIN_UNUSED, NULL }
+ BPF_BUILTIN_UNUSED, NULL_TREE, NULL_TREE}
/* Vector definition and its access function. */
static GTY(()) vec<cr_builtins_ref, va_gc> *builtins_data = NULL;
@@ -189,7 +189,6 @@ search_builtin_data (builtin_local_data_compare_fn callback,
enum cr_decision
{
FAILED_VALIDATION = 0,
- KEEP_ORIGINAL_NO_RELOCATION,
REPLACE_CREATE_RELOCATION,
REPLACE_NO_RELOCATION
};
@@ -286,7 +285,7 @@ compare_same_ptr_type (struct cr_builtins *a, struct cr_builtins *b)
/* Handling for __attribute__((preserve_access_index)) for BPF CO-RE support.
- This attribute marks a structure/union/array type as "preseve", so that
+ This attribute marks a structure/union/array type as "preserve", so that
every access to that type should be recorded and replayed by the BPF loader;
this is just the same functionality as __builtin_preserve_access_index,
but in the form of an attribute for an entire aggregate type.
@@ -300,7 +299,7 @@ compare_same_ptr_type (struct cr_builtins *a, struct cr_builtins *b)
will record access all the way to 'a', even though struct X does not have
the preserve_access_index attribute.
- This is to follow LLVM behavior. */
+ This is to follow LLVM behavior. */
/* True if tree T accesses any member of a struct/union/class which is marked
with the PRESERVE_ACCESS_INDEX attribute. */
@@ -319,11 +318,14 @@ is_attr_preserve_access (tree t)
tree base = get_inner_reference (t, &bitsize, &bitpos, &var_off, &mode,
&sign, &reverse, &vol);
+ if (TREE_CODE (t) == SSA_NAME
+ || TREE_CODE (t) == VAR_DECL)
+ return lookup_attribute ("preserve_access_index",
+ TYPE_ATTRIBUTES (TREE_TYPE (base)));
+
if (TREE_CODE (base) == MEM_REF)
- {
- return lookup_attribute ("preserve_access_index",
- TYPE_ATTRIBUTES (TREE_TYPE (base)));
- }
+ return lookup_attribute ("preserve_access_index",
+ TYPE_ATTRIBUTES (TREE_TYPE (base)));
if (TREE_CODE (t) == COMPONENT_REF)
{
@@ -339,7 +341,8 @@ is_attr_preserve_access (tree t)
const tree container = DECL_CONTEXT (TREE_OPERAND (t, 1));
return lookup_attribute ("preserve_access_index",
- TYPE_ATTRIBUTES (container));
+ TYPE_ATTRIBUTES (container))
+ || is_attr_preserve_access (op);
}
else if (TREE_CODE (t) == ADDR_EXPR)
@@ -348,6 +351,25 @@ is_attr_preserve_access (tree t)
return false;
}
+static tree
+root_for_core_field_info (tree node)
+{
+ bool done = false;
+ while (!done)
+ {
+ switch (TREE_CODE (node))
+ {
+ case ADDR_EXPR:
+ case NOP_EXPR:
+ node = TREE_OPERAND (node, 0);
+ break;
+ default:
+ done = true;
+ break;
+ }
+ }
+ return node;
+}
/* Expand a call to __builtin_preserve_field_info by evaluating the requested
information about SRC according to KIND, and return a tree holding
@@ -364,6 +386,8 @@ core_field_info (tree src, enum btf_core_reloc_kind kind)
location_t loc = EXPR_LOCATION (src);
tree type = TREE_TYPE (src);
+ src = root_for_core_field_info (src);
+
get_inner_reference (src, &bitsize, &bitpos, &var_off, &mode, &unsignedp,
&reversep, &volatilep);
@@ -499,7 +523,7 @@ core_field_info (tree src, enum btf_core_reloc_kind kind)
NODE should be a FIELD_DECL (i.e. of struct or union), or an ARRAY_REF. */
static int
-bpf_core_get_index (const tree node)
+bpf_core_get_index (const tree node, bool *valid)
{
enum tree_code code = TREE_CODE (node);
@@ -539,66 +563,104 @@ bpf_core_get_index (const tree node)
}
}
- gcc_unreachable ();
+ if (valid != NULL)
+ *valid = false;
return -1;
}
-/* This function takes a possible field expression (node) and verifies it is
- valid, extracts what should be the root of the valid field expression and
- composes the accessors array of indices. The accessors are later used in the
- CO-RE relocation in the string field. */
+#define PREPARE_FAKE_PTR(P) \
+ _fake_##P; \
+ if (P == NULL) \
+ P = &_fake_##P; \
+ _fake_##P
+
+#define MAX_NR_ACCESSORS 100
+
+/* This function validates and extracts information for CO-RE field expression.
+ Any parametric expression is allowed to be passed in argument NODE.
+
+ If NODE is a valid CO-RE expression VALID boolean pointer would be set to
+ true.
+
+ A CO-RE field expression is an expression accessing structures, arrays and
+ unions.
+ An examples of CO-RE valid expression is:
+ A->B[2].UNION_C.D
+
+ This function traverses the tree structure to verify if the expression in
+ NODE is valid and extracts other characteristics of the expression, and
+ returns it by updating the pointer arguments:
+
+ ACCESSORS: is an array with the indexes of the particular fields
+ within the expression. The indexes are related to actual index on the
+ struct/union type, or the array access index. The RETURN of the function
+ is the number of accessors required to represent this expression in CO-RE
+ access string.
+ VALID - boolean pointer that sets if expression is valid or not for CO-RE.
+ ACCESS_NODE - It is the base of the expression. Using the example below is
+ the node that represents the A in the expression.
+
+ ALLOW_ENTRY_CAST is an input arguments and specifies if the function should
+ consider as valid expressions in which NODE entry is a cast expression (or
+ tree code nop_expr). */
static unsigned char
-compute_field_expr (tree node, unsigned int *accessors, bool *valid,
- tree *root)
+compute_field_expr (tree node, unsigned int *accessors,
+ bool *valid,
+ tree *access_node,
+ bool allow_entry_cast = true)
{
unsigned char n = 0;
+ unsigned int fake_accessors[MAX_NR_ACCESSORS];
+ if (accessors == NULL)
+ accessors = fake_accessors;
+ bool PREPARE_FAKE_PTR (valid) = true;
+ tree PREPARE_FAKE_PTR (access_node) = NULL_TREE;
+
if (node == NULL_TREE)
{
*valid = false;
return 0;
}
+ *access_node = node;
+
switch (TREE_CODE (node))
{
- case INDIRECT_REF:
case ADDR_EXPR:
+ return 0;
+ case INDIRECT_REF:
accessors[0] = 0;
- n = compute_field_expr (TREE_OPERAND (node, 0), &accessors[0], valid,
- root);
- *root = node;
- return n + 1;
+ return 1;
case POINTER_PLUS_EXPR:
- accessors[0] = bpf_core_get_index (node);
- *root = node;
+ accessors[0] = bpf_core_get_index (node, valid);
return 1;
case COMPONENT_REF:
- n = compute_field_expr (TREE_OPERAND (node, 0), accessors, valid,
- root);
- accessors[n] = bpf_core_get_index (TREE_OPERAND (node, 1));
- *root = node;
+ n = compute_field_expr (TREE_OPERAND (node, 0), accessors,
+ valid,
+ access_node, false);
+ accessors[n] = bpf_core_get_index (TREE_OPERAND (node, 1), valid);
return n + 1;
case ARRAY_REF:
case ARRAY_RANGE_REF:
case MEM_REF:
- n = compute_field_expr (TREE_OPERAND (node, 0), accessors, valid, root);
- accessors[n] = bpf_core_get_index (node);
- *root = node;
- return n + 1;
+ n = compute_field_expr (TREE_OPERAND (node, 0), accessors,
+ valid,
+ access_node, false);
+ accessors[n++] = bpf_core_get_index (node, valid);
+ return n;
case NOP_EXPR:
- n = compute_field_expr (TREE_OPERAND (node, 0), accessors, valid, root);
- *root = node;
+ if (allow_entry_cast == true)
+ {
+ *valid = false;
+ return 0;
+ }
+ n = compute_field_expr (TREE_OPERAND (node, 0), accessors,
+ valid,
+ access_node, false);
return n;
- case TARGET_EXPR:
- {
- tree value = TREE_OPERAND (node, 1);
- if (TREE_CODE (value) == BIND_EXPR
- && TREE_CODE (value = BIND_EXPR_BODY (value)) == MODIFY_EXPR)
- return compute_field_expr (TREE_OPERAND (value, 1), accessors, valid,
- root);
- }
- *root = node;
- return 0;
+
+ case CALL_EXPR:
case SSA_NAME:
case VAR_DECL:
case PARM_DECL:
@@ -608,81 +670,46 @@ compute_field_expr (tree node, unsigned int *accessors, bool *valid,
return 0;
}
}
+#undef PREPARE_FAKE_PTR
-static struct cr_local
-pack_field_expr_for_access_index (tree *args,
- enum btf_core_reloc_kind kind,
- enum bpf_builtins code ATTRIBUTE_UNUSED)
-{
- struct cr_local ret = CR_LOCAL_EMPTY;
- ret.fail = false;
-
- tree arg = args[0];
- tree root = arg;
-
- /* Avoid double-recording information if argument is an access to
- a struct/union marked __attribute__((preserve_access_index)). This
- Will be handled by the attribute handling pass. */
- if (is_attr_preserve_access (arg))
- {
- ret.reloc_decision = REPLACE_NO_RELOCATION;
- ret.reloc_data.expr = arg;
- }
- else
- {
- ret.reloc_decision = REPLACE_CREATE_RELOCATION;
- unsigned int accessors[100];
- bool valid = true;
- compute_field_expr (arg, accessors, &valid, &root);
-
- if (valid == true)
- ret.reloc_data.expr = root;
- else
- {
- bpf_error_at (EXPR_LOC_OR_LOC (arg, UNKNOWN_LOCATION),
- "Cannot compute index for field argument");
- ret.fail = true;
- }
- }
-
- /* Note: the type of default_value is used to define the return type of
- __builtin_core_reloc in bpf_resolve_overloaded_core_builtin. */
- ret.reloc_data.type = TREE_TYPE (root);
- ret.reloc_data.default_value = build_int_cst (ret.reloc_data.type, 0);
- ret.reloc_data.kind = kind;
-
- if (TREE_CODE (ret.reloc_data.default_value) == ERROR_MARK)
- ret.fail = true;
-
- return ret;
-}
+/* Pack helper for the __builtin_preserve_field_info. */
static struct cr_local
-pack_field_expr_for_preserve_field (tree *args,
- enum btf_core_reloc_kind kind,
- enum bpf_builtins code ATTRIBUTE_UNUSED)
+pack_field_expr (tree *args,
+ enum btf_core_reloc_kind kind,
+ enum bpf_builtins code ATTRIBUTE_UNUSED)
{
struct cr_local ret = CR_LOCAL_EMPTY;
ret.fail = false;
tree arg = args[0];
- tree tmp;
tree root = arg;
+ tree access_node = NULL_TREE;
+ tree type = NULL_TREE;
- /* Remove cast to void * created by front-end to fit builtin type, when passed
- * a simple expression like f->u. */
- if (TREE_CODE (arg) == NOP_EXPR && (tmp = TREE_OPERAND (arg, 0))
- && TREE_CODE (tmp) == ADDR_EXPR && (tmp = TREE_OPERAND (tmp, 0))
- && arg != NULL_TREE)
- arg = tmp;
+ ret.reloc_decision = REPLACE_CREATE_RELOCATION;
unsigned int accessors[100];
bool valid = true;
- compute_field_expr (arg, accessors, &valid, &root);
+ compute_field_expr (root, accessors, &valid, &access_node, false);
+
+ type = TREE_TYPE (access_node);
if (valid == true)
- ret.reloc_data.expr = root;
+ {
+ ret.reloc_data.expr = root;
+
+ /* Note: the type of default_value is used to define the return type of
+ __builtin_core_reloc in bpf_resolve_overloaded_core_builtin. */
+ ret.reloc_data.access_node = access_node;
+ ret.reloc_data.type = type;
+ ret.reloc_data.default_value = core_field_info (root, kind);
+ ret.reloc_data.kind = kind;
+
+ if (TREE_CODE (ret.reloc_data.default_value) == ERROR_MARK)
+ ret.fail = true;
+ }
else
{
bpf_error_at (EXPR_LOC_OR_LOC (arg, UNKNOWN_LOCATION),
@@ -690,17 +717,11 @@ pack_field_expr_for_preserve_field (tree *args,
ret.fail = true;
}
- ret.reloc_decision = REPLACE_CREATE_RELOCATION;
- ret.reloc_data.type = TREE_TYPE (root);
- ret.reloc_data.default_value = core_field_info (root, kind);
- ret.reloc_data.kind = kind;
-
- if (TREE_CODE (ret.reloc_data.default_value) == ERROR_MARK)
- ret.fail = true;
-
return ret;
}
+/* Process helper for the __builtin_preserve_field_info. */
+
static struct cr_final
process_field_expr (struct cr_builtins *data)
{
@@ -711,19 +732,18 @@ process_field_expr (struct cr_builtins *data)
|| data->kind == BPF_RELO_FIELD_SIGNED
|| data->kind == BPF_RELO_FIELD_EXISTS);
- unsigned int accessors[100];
+ unsigned int accessors[MAX_NR_ACCESSORS];
unsigned char nr_accessors = 0;
- bool valid = true;
- tree root = NULL_TREE;
tree expr = data->expr;
- tree type = TREE_TYPE (data->expr);
+ tree type = data->type;
if (TREE_CODE (expr) == ADDR_EXPR)
expr = TREE_OPERAND (expr, 0);
- nr_accessors = compute_field_expr (expr, accessors, &valid, &root);
+ expr = root_for_core_field_info (expr);
+ nr_accessors = compute_field_expr (expr, accessors, NULL, NULL, false);
- struct cr_final ret = { NULL, type, data->kind};
+ struct cr_final ret = { NULL, type, data->kind };
char str[100];
if (nr_accessors > 0)
@@ -740,9 +760,11 @@ process_field_expr (struct cr_builtins *data)
return ret;
}
-hash_map <tree, tree> bpf_enum_mappings;
-
+static GTY(()) hash_map<tree, tree> *bpf_enum_mappings;
tree enum_value_type = NULL_TREE;
+
+/* Pack helper for the __builtin_preserve_enum_value. */
+
static struct cr_local
pack_enum_value (tree *args, enum btf_core_reloc_kind kind,
enum bpf_builtins code ATTRIBUTE_UNUSED)
@@ -757,7 +779,7 @@ pack_enum_value (tree *args, enum btf_core_reloc_kind kind,
tree type = NULL_TREE;
/* Deconstructing "*(typeof (enum_type) *) enum_value" to collect both the
- * enum_type and enum_value. */
+ enum_type and enum_value. */
if (TREE_CODE (tmp) != TARGET_EXPR
|| (type = TREE_TYPE (tmp)) == NULL_TREE
|| (TREE_CODE (type) != POINTER_TYPE)
@@ -771,7 +793,7 @@ pack_enum_value (tree *args, enum btf_core_reloc_kind kind,
if (TREE_CODE (enum_value) != INTEGER_CST)
goto pack_enum_value_fail;
- result = bpf_enum_mappings.get (enum_value);
+ result = bpf_enum_mappings->get (enum_value);
if (result == NULL)
goto pack_enum_value_fail;
@@ -797,6 +819,8 @@ pack_enum_value_fail:
return ret;
}
+/* Process helper for the __builtin_preserve_enum_value. */
+
static struct cr_final
process_enum_value (struct cr_builtins *data)
{
@@ -829,6 +853,8 @@ process_enum_value (struct cr_builtins *data)
return ret;
}
+/* Pack helper for the __builtin_preserve_type_info. */
+
static struct cr_local
pack_type (tree *args, enum btf_core_reloc_kind kind,
enum bpf_builtins code ATTRIBUTE_UNUSED)
@@ -842,12 +868,12 @@ pack_type (tree *args, enum btf_core_reloc_kind kind,
tree tmp = args[0];
HOST_WIDE_INT type_size_i;
+ if (TYPE_P (tmp))
+ goto is_already_type;
/* Typical structure to match:
- * *({ extern typeof (TYPE) *<tmp_name>; <tmp_name>; })
- */
+ *({ extern typeof (TYPE) *<tmp_name>; <tmp_name>; }) */
/* Extract Pointer dereference from the construct. */
-
while (tmp != NULL_TREE
&& (TREE_CODE (tmp) == INDIRECT_REF
|| TREE_CODE (tmp) == NOP_EXPR))
@@ -865,6 +891,7 @@ pack_type (tree *args, enum btf_core_reloc_kind kind,
tmp = TREE_TYPE (tmp);
+is_already_type:
if (TREE_CODE (tmp) == POINTER_TYPE)
tmp = TREE_TYPE (tmp);
@@ -884,7 +911,7 @@ pack_type (tree *args, enum btf_core_reloc_kind kind,
ret.reloc_data.type = root_type;
ret.reloc_decision = REPLACE_CREATE_RELOCATION;
- /* Force this type to be marked as used in dwarf2out. */
+ /* Force this type to be marked as used in dwarf2out. */
gcc_assert (cfun);
if (cfun->used_types_hash == NULL)
cfun->used_types_hash = hash_set<tree>::create_ggc (37);
@@ -915,11 +942,13 @@ pack_type (tree *args, enum btf_core_reloc_kind kind,
pack_type_fail:
bpf_error_at (EXPR_LOC_OR_LOC (args[0], UNKNOWN_LOCATION),
- "invelid first argument format for enum value builtin");
+ "invalid first argument format for enum value builtin");
ret.fail = true;
return ret;
}
+/* Process helper for the __builtin_preserve_type_info. */
+
static struct cr_final
process_type (struct cr_builtins *data)
{
@@ -1075,30 +1104,8 @@ kind_preserve_type_info (tree *args, int nargs)
return BPF_RELO_INVALID;
}
-
-/* Required to overcome having different return type builtins to avoid warnings
- at front-end and be able to share the same builtin definition and permitting
- the PURE attribute to work. */
-hash_map<tree, tree> core_builtin_type_defs;
-
-static tree
-get_core_builtin_fndecl_for_type (tree ret_type)
-{
- tree *def = core_builtin_type_defs.get (ret_type);
- if (def)
- return *def;
-
- tree rettype = build_function_type_list (ret_type, integer_type_node, NULL);
- tree new_fndecl = add_builtin_function_ext_scope ("__builtin_core_reloc",
- rettype,
- BPF_BUILTIN_CORE_RELOC,
- BUILT_IN_MD, NULL, NULL);
- DECL_PURE_P (new_fndecl) = 1;
-
- core_builtin_type_defs.put (ret_type, new_fndecl);
-
- return new_fndecl;
-}
+/* Plugin handler used in the parser that allows to collect enum value
+ information that other wise would be folded and non recoverable. */
void
bpf_handle_plugin_finish_type (void *event_data,
@@ -1106,6 +1113,9 @@ bpf_handle_plugin_finish_type (void *event_data,
{
tree type = (tree) event_data;
+ if (bpf_enum_mappings == NULL)
+ bpf_enum_mappings = hash_map<tree, tree>::create_ggc (10);
+
if (TREE_CODE (type) == ENUMERAL_TYPE)
for (tree l = TYPE_VALUES (type); l; l = TREE_CHAIN (l))
{
@@ -1115,12 +1125,12 @@ bpf_handle_plugin_finish_type (void *event_data,
initial = copy_node (initial);
DECL_INITIAL (value) = initial;
- bpf_enum_mappings.put (initial, value);
+ tree *found = bpf_enum_mappings->get (initial);
+ if (found == NULL)
+ bpf_enum_mappings->put (initial, value);
}
}
-/* -- Header file exposed functions -- */
-
/* Initializes support information to process CO-RE builtins.
Defines information for the builtin processing, such as helper functions to
support the builtin convertion. */
@@ -1133,13 +1143,13 @@ bpf_init_core_builtins (void)
core_builtin_helpers[BPF_BUILTIN_PRESERVE_ACCESS_INDEX] =
BPF_CORE_HELPER_SET (kind_access_index,
NULL,
- pack_field_expr_for_access_index,
- process_field_expr,
+ NULL,
+ NULL,
true);
core_builtin_helpers[BPF_BUILTIN_PRESERVE_FIELD_INFO] =
BPF_CORE_HELPER_SET (kind_preserve_field_info,
NULL,
- pack_field_expr_for_preserve_field,
+ pack_field_expr,
process_field_expr,
true);
core_builtin_helpers[BPF_BUILTIN_BTF_TYPE_ID] =
@@ -1167,13 +1177,17 @@ bpf_init_core_builtins (void)
BPF_CORE_HELPER_SET (NULL, NULL, NULL, NULL, true);
/* Initialize plugin handler to record enums value for use in
- * __builtin_preserve_enum_value. */
+ __builtin_preserve_enum_value. */
plugin_state = (enum bpf_plugin_states) flag_plugin_added;
flag_plugin_added = true;
register_callback ("bpf_collect_enum_info", PLUGIN_FINISH_TYPE,
bpf_handle_plugin_finish_type, NULL);
}
+/* This function returns the related __builtin_core_reloc call tree node to a
+ particular CO-RE builtin definition in FNDECL when called with
+ arguments ARGS. */
+
static tree
construct_builtin_core_reloc (location_t loc, tree fndecl, tree *args,
int nargs)
@@ -1200,14 +1214,12 @@ construct_builtin_core_reloc (location_t loc, tree fndecl, tree *args,
local_data.reloc_data.orig_arg_expr = args[0];
}
else
- local_data.reloc_decision = KEEP_ORIGINAL_NO_RELOCATION;
+ gcc_unreachable ();
if (local_data.fail == true)
return error_mark_node;
- if (local_data.reloc_decision == REPLACE_NO_RELOCATION)
- return local_data.reloc_data.expr;
- else if (local_data.reloc_decision == REPLACE_CREATE_RELOCATION)
+ if (local_data.reloc_decision == REPLACE_CREATE_RELOCATION)
{
int index = search_builtin_data (helper.compare,
&local_data.reloc_data);
@@ -1216,37 +1228,253 @@ construct_builtin_core_reloc (location_t loc, tree fndecl, tree *args,
struct cr_builtins *data = get_builtin_data (index);
memcpy (data, &local_data.reloc_data, sizeof (struct cr_builtins));
- tree new_fndecl = bpf_builtins[BPF_BUILTIN_CORE_RELOC];
+ tree fndecl = bpf_builtins[BPF_BUILTIN_CORE_RELOC];
+ return build_call_expr_loc (loc,
+ fndecl, 1,
+ build_int_cst (integer_type_node, index));
+ }
+ }
+ return NULL_TREE;
+}
+
+/* This function constructs the CO-RE safe code around field expressions.
+ If the expression is an array access, create an offset by multiplying the
+ index access by the __builtin_type_info call requesting the size of the
+ array element and multiplying by the index. The offset is added to the
+ base pointer.
+ In a more formal way:
+ - base + (__blt_preserve_type_info (typeof(expr), SIZEOF) * array_i)
+
+ Please notice that __builtin_preserve_type_info is never really created, but
+ rather a call to __builtin_core_reloc that represents it.
+
+ Any other case, it is assumed to be a field access and instead a CO-RE field
+ expressions offset relocation is created and added to the base node.
+ More precisely:
+ - base + __builtin_preserve_field_expr (expr, SIZEOF) */
+
+static tree
+core_expr_with_field_expr_plus_base (tree base, tree expr, bool leaf_node)
+{
+ tree type = TREE_TYPE (expr);
+ tree args[2];
- tree ret_type = TREE_TYPE (local_data.reloc_data.default_value);
- if (ret_type != ptr_type_node)
- new_fndecl = get_core_builtin_fndecl_for_type (ret_type);
- return build_call_expr_loc (loc,
- new_fndecl, 1,
- build_int_cst (integer_type_node,
- index));
+ if (base == expr)
+ return expr;
+ else if (TREE_CODE (expr) == ARRAY_REF
+ && leaf_node == false)
+ {
+ if (TREE_CODE (base) == MEM_REF)
+ base = TREE_OPERAND (base, 0);
+
+ tree array_index = TREE_OPERAND (expr, 1);
+ tree fndecl = bpf_builtins[BPF_BUILTIN_PRESERVE_TYPE_INFO];
+
+ tree type = TREE_TYPE (base);
+ gcc_assert (POINTER_TYPE_P (type)
+ && TREE_CODE (type = TREE_TYPE (type)) == ARRAY_TYPE
+ && (type = TREE_TYPE (type)) != NULL_TREE);
+ args[0] = type;
+ args[1] = build_int_cst (integer_type_node, BPF_TYPE_SIZE);
+ tree builtin_call = construct_builtin_core_reloc (UNKNOWN_LOCATION,
+ fndecl,
+ args, 2);
+
+ tree offset = fold_build2 (MULT_EXPR, size_type_node,
+ fold_build1 (NOP_EXPR, size_type_node, builtin_call),
+ fold_build1 (NOP_EXPR, size_type_node, array_index));
+
+ if (!POINTER_TYPE_P (TREE_TYPE (base)))
+ base = fold_build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (base)), base);
+
+ tree tmp = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+ fold_build1 (NOP_EXPR, ptr_type_node, base),
+ offset);
+
+ tmp = fold_build1 (NOP_EXPR, build_pointer_type (type), tmp);
+ return tmp;
+ }
+ else
+ {
+ tree fndecl = bpf_builtins[BPF_BUILTIN_PRESERVE_FIELD_INFO];
+ args[0] = expr;
+ args[1] = build_int_cst (integer_type_node, BPF_FIELD_BYTE_OFFSET);
+ tree builtin_call = construct_builtin_core_reloc (UNKNOWN_LOCATION,
+ fndecl,
+ args, 2);
+
+ if (!POINTER_TYPE_P (TREE_TYPE (base)))
+ base = fold_build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (base)), base);
+
+ tree tmp = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+ fold_build1 (NOP_EXPR, ptr_type_node, base),
+ fold_build1 (NOP_EXPR, size_type_node, builtin_call));
+ tmp = fold_build1 (NOP_EXPR, build_pointer_type (type), tmp);
+ return tmp;
+ }
+}
+
+/* This function takes arbitrary field expression and returns a CO-RE
+ compatible version by introducing CO-RE relocations.
+
+ In cases where the expression is not supported in CO-RE with a single
+ relocation, it creates multiple levels of access, i.e. if the expression
+ contains multiple indirections.
+ For example:
+ - A->B->C
+
+ It recursively traverses the expression to its leaf nodes and rollbacks
+ constructing the CO-RE relocations. It calls
+ core_expr_with_field_expr_plus_base that creates the necessary CO-RE
+ relocations.
+
+ Arguments:
+ - EXPR: is the expression to be converted. It should be validated by
+ compute_field_expr function before this function is called.
+ - CHANGED: is set to true if the returned tree node is different from
+ the input expr argument.
+ - ENTRY: internal only. Should not be set in a call. */
+
+static tree
+make_core_safe_access_index (tree expr, bool *changed, bool entry = true)
+{
+ poly_int64 bitsize, bitpos;
+ tree var_off;
+ machine_mode mode;
+ int sign, reverse, vol;
+
+ tree base = get_inner_reference (expr, &bitsize, &bitpos, &var_off, &mode,
+ &sign, &reverse, &vol);
+
+ if (base == NULL_TREE || base == expr)
+ return expr;
+
+ tree ret = NULL_TREE;
+ int n;
+ bool valid = true;
+ tree access_node = NULL_TREE;
+
+ /* In case the base is itself a valid field expression, first convert the
+ base in a CO-RE safe expression.
+ This seems to be a requirement since get_inner_reference not always
+ returns the true base of the expression. */
+ if ((n = compute_field_expr (base, NULL, &valid, &access_node)) > 0
+ && valid == true)
+ {
+ if (TREE_CODE (access_node) == INDIRECT_REF)
+ base = TREE_OPERAND (access_node, 0);
+
+ bool local_changed = false;
+ ret = make_core_safe_access_index (base, &local_changed, false);
+ if (local_changed == true)
+ {
+ if (TREE_CODE (access_node) == INDIRECT_REF)
+ base = fold_build1 (INDIRECT_REF,
+ TREE_TYPE (base),
+ ret);
+ else
+ base = ret;
+ }
+ }
+
+ /* The remaining is to traverse the field part of the field expression. */
+ if (mode != VOIDmode && var_off == NULL_TREE)
+ {
+ *changed = true;
+ return core_expr_with_field_expr_plus_base (base, expr, true);
+ }
+ else
+ {
+ switch (TREE_CODE (expr))
+ {
+ case COMPONENT_REF:
+ case ARRAY_REF:
+ case ADDR_EXPR:
+ {
+ bool local_changed = false;
+ tree type = TREE_TYPE (TREE_OPERAND (expr, 0));
+ ret = make_core_safe_access_index (TREE_OPERAND (expr, 0),
+ &local_changed, false);
+
+ /* This variable is a replaced in the expr for algorithmic purposes.
+ It reduces the expression just to the remaining sub-expression
+ that still was not processed. */
+ if (local_changed == true)
+ TREE_OPERAND (expr, 0) = create_tmp_var (type, "fake");
+ }
+ break;
+ default:
+ ret = expr;
+ break;
+ }
+ }
+
+ base = get_inner_reference (expr, &bitsize, &bitpos, &var_off, &mode,
+ &sign, &reverse, &vol);
+
+ if ((ret != NULL_TREE
+ && mode != VOIDmode && var_off != NULL_TREE)
+ || entry == true)
+ {
+ *changed = true;
+ ret = core_expr_with_field_expr_plus_base (ret, expr, false);
+ }
+ return ret;
+}
+
+/* This function verifies if the NODE expression is a field expression and
+ changes and converts it to CO-RE. This is used by a tree walker for any
+ __builtin_preserve_access_index argument expression from within
+ bpf_resolve_overloaded_core_builtin. */
+
+static tree
+replace_core_access_index_comp_expr (tree *node, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ bool valid = true;
+ gcc_assert (*node != NULL_TREE);
+
+ tree *expr = node;
+ bool should_indirect = false;
+ if (TREE_CODE (*expr) == ADDR_EXPR)
+ expr = &TREE_OPERAND (*expr, 0);
+ else
+ should_indirect = true;
+
+ int n = compute_field_expr (*node, NULL, &valid, NULL);
+ if (valid == true && n > 0)
+ {
+ bool changed = false;
+ tree expr_test = make_core_safe_access_index (*expr, &changed);
+ *walk_subtrees = 0;
+
+ if (changed == true)
+ {
+ if (should_indirect == true)
+ expr_test = fold_build1 (INDIRECT_REF,
+ TREE_TYPE (TREE_TYPE (expr_test)),
+ expr_test);
+
+ *expr = expr_test;
}
}
return NULL_TREE;
}
-/* This function is used by bpf_resolve_overloaded_builtin which is the
- implementation of the TARGET_RESOLVE_OVERLOADED_BUILTIN. It is executed in
- a very early stage and allows to adapt the builtin to different arguments
- allowing the compiler to make builtins polymorphic. In this particular
- implementation, it collects information of the specific builtin call,
- converts it to the internal __builtin_core_reloc, stores any required
- information from the original builtin call in a vec<cr_builtins> and assigns
- the index within the *vec*, replacing by __builtin_core_reloc. In the
- process we also adjust return type of the __builtin_core_reloc to permit
- polymorphic return type, as it is expected in some of the BPF CO-RE
- builtins. */
+/* This function is used by bpf_resolve_overloaded_builtin defined in bpf.cc.
+ It is executed in a very early stage and processes any CO-RE builtins,
+ adapting the code and creating the more generic __builtin_core_reloc calls.
+ */
#define MAX_CORE_BUILTIN_ARGS 3
tree
bpf_resolve_overloaded_core_builtin (location_t loc, tree fndecl,
void *arglist)
{
+ remove_parser_plugin ();
+
if (!bpf_require_core_support ())
return error_mark_node;
@@ -1255,29 +1483,43 @@ bpf_resolve_overloaded_core_builtin (location_t loc, tree fndecl,
for (unsigned int i = 0; i < argsvec->length (); i++)
args[i] = (*argsvec)[i];
- remove_parser_plugin ();
+ int code = DECL_MD_FUNCTION_CODE (fndecl);
+ if (code == BPF_BUILTIN_PRESERVE_ACCESS_INDEX)
+ {
+ walk_tree (&args[0], replace_core_access_index_comp_expr, NULL, NULL);
+ return args[0];
+ }
return construct_builtin_core_reloc (loc, fndecl, args, argsvec->length ());
}
/* Used in bpf_expand_builtin. This function is called in RTL expand stage to
convert the internal __builtin_core_reloc in unspec:UNSPEC_CORE_RELOC RTL,
- which will contain a third argument that is the index in the vec collected in
- bpf_resolve_overloaded_core_builtin. */
+ which will contain a third argument that is the index in the vec collected
+ in bpf_resolve_overloaded_core_builtin. */
rtx
bpf_expand_core_builtin (tree exp, enum bpf_builtins code)
{
- if (code == BPF_BUILTIN_CORE_RELOC)
+ if (!TARGET_BPF_CORE)
+ return NULL_RTX;
+
+ switch (code)
{
- tree index = CALL_EXPR_ARG (exp, 0);
- struct cr_builtins *data = get_builtin_data (TREE_INT_CST_LOW (index));
-
- rtx v = expand_normal (data->default_value);
- rtx i = expand_normal (index);
- return gen_rtx_UNSPEC (DImode,
- gen_rtvec (2, v, i),
- UNSPEC_CORE_RELOC);
+ case BPF_BUILTIN_CORE_RELOC:
+ {
+ tree index = CALL_EXPR_ARG (exp, 0);
+ struct cr_builtins *data = get_builtin_data (TREE_INT_CST_LOW (index));
+
+ rtx v = expand_normal (data->default_value);
+ rtx i = expand_normal (index);
+ return gen_rtx_UNSPEC (DImode,
+ gen_rtvec (2, v, i),
+ UNSPEC_CORE_RELOC);
+ }
+ break;
+ default:
+ break;
}
return NULL_RTX;
@@ -1287,8 +1529,8 @@ bpf_expand_core_builtin (tree exp, enum bpf_builtins code)
unspec:UNSPEC_CORE_RELOC. It recovers the vec index kept as the third
operand and collects the data from the vec. With that it calls the process
helper in order to construct the data required for the CO-RE relocation.
- Also it creates a label pointing to the unspec instruction and uses it
- in the CO-RE relocation creation. */
+ Also it creates a label pointing to the unspec instruction and uses it in
+ the CO-RE relocation creation. */
const char *
bpf_add_core_reloc (rtx *operands, const char *templ)
@@ -1306,67 +1548,198 @@ bpf_add_core_reloc (rtx *operands, const char *templ)
make_core_relo (&reloc_data, tmp_label);
/* Replace default value for later processing builtin types.
- Example if the type id builtins. */
+ Example if the type id builtins. */
if (data->rtx_default_value != NULL_RTX)
operands[1] = data->rtx_default_value;
return templ;
}
-/* This function is used within the defined_expand for mov in bpf.md file.
- It identifies if any of the operands in a move is a expression with a
- type with __attribute__((preserve_access_index)), which case it
- will emit an unspec:UNSPEC_CORE_RELOC such that it would later create a
- CO-RE relocation for this expression access. */
+static tree
+maybe_get_base_for_field_expr (tree expr)
+{
+ poly_int64 bitsize, bitpos;
+ tree var_off;
+ machine_mode mode;
+ int sign, reverse, vol;
-void
-bpf_replace_core_move_operands (rtx *operands)
+ if (expr == NULL_TREE)
+ return NULL_TREE;
+
+ return get_inner_reference (expr, &bitsize, &bitpos, &var_off, &mode,
+ &sign, &reverse, &vol);
+}
+
+/* Access functions to mark sub expressions as attributed with
+ __preserve_access_index.
+ This is required since in gimple format, in order to convert an expression as
+ CO-RE safe, we must create multiple gimple statements.
+ Also, only the type of the base of the expression might be attributed with
+ __preserve_access_index. Nevertheless all the consecutive accesses to this
+ attributed node should also be converted to CO-RE safe.
+ Any LHS assigned values with CO-RE converted expressions are marked and
+ any uses of these values are later checked for further convertion.
+ The core_access_index_map functions allow to mark this nodes for later
+ convertion to CO-RE.
+ This mechanism are used by make_gimple_core_safe_access_index. */
+
+static GTY(()) hash_map<tree, tree> *core_access_index_map = NULL;
+
+static void
+core_access_clean (void)
{
- for (int i = 0; i < 2; i++)
- if (MEM_P (operands[i]))
- {
- tree expr = MEM_EXPR (operands[i]);
+ if (core_access_index_map == NULL)
+ core_access_index_map = hash_map<tree, tree>::create_ggc (10);
+ core_access_index_map->empty ();
+}
- if (expr == NULL_TREE)
- continue;
+static bool
+core_is_access_index (tree expr)
+{
+ if (TREE_CODE (expr) == MEM_REF
+ || TREE_CODE (expr) == INDIRECT_REF)
+ expr = TREE_OPERAND (expr, 0);
- if (TREE_CODE (expr) == MEM_REF
- && TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME)
- {
- gimple *def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (expr, 0));
- if (def_stmt && is_gimple_assign (def_stmt))
- expr = gimple_assign_rhs1 (def_stmt);
- }
- if (is_attr_preserve_access (expr)
- && bpf_require_core_support ())
- {
- struct cr_local local_data = pack_field_expr_for_access_index (
- &expr,
- BPF_RELO_FIELD_BYTE_OFFSET,
- BPF_BUILTIN_PRESERVE_ACCESS_INDEX);
+ tree *def = core_access_index_map->get (expr);
+ if (def)
+ return true;
+ return false;
+}
- local_data.reloc_decision = REPLACE_CREATE_RELOCATION;
- local_data.reloc_data.orig_arg_expr = expr;
- local_data.reloc_data.orig_builtin_code = BPF_BUILTIN_PRESERVE_ACCESS_INDEX;
+static void
+core_mark_as_access_index (tree expr)
+{
+ if (TREE_CODE (expr) == MEM_REF
+ || TREE_CODE (expr) == INDIRECT_REF)
+ expr = TREE_OPERAND (expr, 0);
- int index = allocate_builtin_data ();
- struct cr_builtins *data = get_builtin_data (index);
- memcpy (data, &local_data.reloc_data, sizeof (struct cr_builtins));
+ if (bpf_enum_mappings->get (expr) == NULL)
+ core_access_index_map->put (expr, NULL_TREE);
+}
- rtx reg = XEXP (operands[i], 0);
- if (!REG_P (reg))
- {
- reg = gen_reg_rtx (Pmode);
- operands[i] = gen_rtx_MEM (GET_MODE (operands[i]), reg);
- }
+/* This function is an adaptation of make_core_safe_access_index but to be used
+ in gimple format trees. It is used by execute_lower_bpf_core, when
+ traversing the gimple tree looking for nodes that would have its type
+ attributed with __preserve_access_index. In this particular cases any of
+ the expressions using such attributed types must be made CO-RE safe. */
- emit_insn (
- gen_mov_reloc_coredi (reg,
- gen_rtx_CONST_INT (Pmode, 0),
- gen_rtx_CONST_INT (Pmode, index)));
- return;
- }
- }
+static tree
+make_gimple_core_safe_access_index (tree *tp,
+ int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data)
+{
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ bool valid = true;
+ int n = 0;
+
+ tree *patch = tp;
+ if (TREE_CODE (*patch) == ADDR_EXPR)
+ patch = &(TREE_OPERAND (*tp, 0));
+ tree orig_type = TREE_TYPE (*patch);
+
+ if ((is_attr_preserve_access (*patch)
+ || core_is_access_index (maybe_get_base_for_field_expr (*patch)))
+ && (n = compute_field_expr (*patch, NULL, &valid, NULL)) > 0
+ && valid == true)
+ {
+ bool changed = false;
+ tree expr_test = make_core_safe_access_index (*patch, &changed);
+
+
+ gimple_seq before = NULL;
+ push_gimplify_context ();
+ gimplify_expr (&expr_test, &before, NULL, is_gimple_val, fb_rvalue);
+
+ /* In case the ADDR_EXPR bypassed above is no longer needed. */
+ if (patch != tp && TREE_TYPE (expr_test) == TREE_TYPE (*tp))
+ *tp = expr_test;
+ /* For non pointer value accesses. */
+ else if (TREE_TYPE (expr_test) == build_pointer_type (orig_type))
+ *patch = fold_build2 (MEM_REF, TREE_TYPE (*patch),
+ expr_test, build_int_cst (ptr_type_node, 0));
+ else
+ *patch = expr_test;
+
+ *tp = fold (*tp);
+
+ gsi_insert_seq_before (&(wi->gsi), before, GSI_LAST_NEW_STMT);
+ pop_gimplify_context (NULL);
+
+ wi->changed = true;
+ *walk_subtrees = false;
+
+ tree lhs;
+ if (!wi->is_lhs
+ && (lhs = gimple_get_lhs (wi->stmt)) != NULL_TREE)
+ core_mark_as_access_index (lhs);
+ }
+ return NULL_TREE;
+}
+
+/* This is the entry point for the pass_data_lower_bpg_core. It walks all the
+ statements in gimple, looking for expressions that are suppose to be CO-RE
+ preserve_access_index attributed.
+ Those expressions are processed and split by
+ make_gimple_core_safe_access_index function, which will both create the
+ calls to __build_core_reloc and split the expression in smaller parts in
+ case it cannot be represented CO-RE safeguarded by a single CO-RE
+ relocation. */
+
+static unsigned int
+execute_lower_bpf_core (void)
+{
+ if (!TARGET_BPF_CORE)
+ return 0;
+
+ gimple_seq body = gimple_body (current_function_decl);
+
+ struct walk_stmt_info wi;
+ core_access_clean ();
+
+ memset (&wi, 0, sizeof (wi));
+ wi.info = NULL;
+
+ /* Split preserve_access_index expressions when needed. */
+ walk_gimple_seq_mod (&body, NULL, make_gimple_core_safe_access_index, &wi);
+ return 0;
+}
+
+namespace {
+
+const pass_data pass_data_lower_bpf_core =
+{
+ GIMPLE_PASS, /* type */
+ "bpf_core_lower", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_lower_bpf_core: public gimple_opt_pass
+{
+public:
+ pass_lower_bpf_core (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_lower_bpf_core, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute (function *) final override
+ {
+ return execute_lower_bpf_core ();
+ }
+
+}; /* class pass_lower_bpf_core */
+
+} /* anon namespace */
+
+gimple_opt_pass *
+make_pass_lower_bpf_core (gcc::context *ctxt)
+{
+ return new pass_lower_bpf_core (ctxt);
}
#include "gt-core-builtins.h"
diff --git a/gcc/config/bpf/core-builtins.h b/gcc/config/bpf/core-builtins.h
index 15cd3d3..c54f6dd 100644
--- a/gcc/config/bpf/core-builtins.h
+++ b/gcc/config/bpf/core-builtins.h
@@ -25,6 +25,34 @@ enum bpf_builtins
BPF_BUILTIN_MAX,
};
+enum bpf_field_info_kind {
+ BPF_FIELD_BYTE_OFFSET = 0, /* field byte offset */
+ BPF_FIELD_BYTE_SIZE = 1,
+ BPF_FIELD_EXISTS = 2, /* field existence in target kernel */
+ BPF_FIELD_SIGNED = 3,
+ BPF_FIELD_LSHIFT_U64 = 4,
+ BPF_FIELD_RSHIFT_U64 = 5,
+};
+
+/* second argument to __builtin_btf_type_id () built-in */
+enum bpf_type_id_kind {
+ BPF_TYPE_ID_LOCAL = 0, /* BTF type ID in local program */
+ BPF_TYPE_ID_TARGET = 1, /* BTF type ID in target kernel */
+};
+
+/* second argument to __builtin_preserve_type_info () built-in */
+enum bpf_type_info_kind {
+ BPF_TYPE_EXISTS = 0, /* type existence in target kernel */
+ BPF_TYPE_SIZE = 1, /* type size in target kernel */
+ BPF_TYPE_MATCHES = 2, /* type match in target kernel */
+};
+
+/* second argument to __builtin_preserve_enum_value () built-in */
+enum bpf_enum_value_kind {
+ BPF_ENUMVAL_EXISTS = 0, /* enum value existence in kernel */
+ BPF_ENUMVAL_VALUE = 1, /* enum value value relocation */
+};
+
extern GTY (()) tree bpf_builtins[(int) BPF_BUILTIN_MAX];
void bpf_init_core_builtins (void);
diff --git a/gcc/config/bpf/t-bpf b/gcc/config/bpf/t-bpf
index c289dde..18f1fa6 100644
--- a/gcc/config/bpf/t-bpf
+++ b/gcc/config/bpf/t-bpf
@@ -8,3 +8,5 @@ coreout.o: $(srcdir)/config/bpf/coreout.cc
core-builtins.o: $(srcdir)/config/bpf/core-builtins.cc
$(COMPILE) $<
$(POSTCOMPILE)
+
+PASSES_EXTRA += $(srcdir)/config/bpf/bpf-passes.def
diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc
index a80b6ca..621a94d 100644
--- a/gcc/config/darwin.cc
+++ b/gcc/config/darwin.cc
@@ -3325,6 +3325,8 @@ darwin_override_options (void)
{
if (strverscmp (darwin_macosx_version_min, "10.14") >= 0)
generating_for_darwin_version = 18;
+ else if (strverscmp (darwin_macosx_version_min, "10.8") >= 0)
+ generating_for_darwin_version = 12;
else if (strverscmp (darwin_macosx_version_min, "10.7") >= 0)
generating_for_darwin_version = 11;
else if (strverscmp (darwin_macosx_version_min, "10.6") >= 0)
@@ -3495,8 +3497,17 @@ darwin_override_options (void)
&& dwarf_debuginfo_p ())
flag_var_tracking_uninit = flag_var_tracking;
- /* Final check on PCI options; for Darwin these are not dependent on the PIE
- ones, although PIE does require PIC to support it. */
+ if (OPTION_SET_P (flag_pie) && flag_pie)
+ {
+ /* This is a little complicated, to match Xcode tools.
+ For Darwin, PIE requires PIC codegen, but otherwise is only a link-
+ time change. For almost all Darwin, we do not report __PIE__; the
+ exception is Darwin12-17 and for 32b only. */
+ flag_pie = generating_for_darwin_version >= 12 && !TARGET_64BIT ? 2 : 0;
+ flag_pic = 2; /* We always set this. */
+ }
+
+ /* Final check on PIC options. */
if (MACHO_DYNAMIC_NO_PIC_P)
{
if (flag_pic)
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index ae7d5c6..5db64a1 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -321,6 +321,19 @@ extern GTY(()) int darwin_ms_struct;
%:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w) "
#endif
+/* We might elect to add a path even when this compiler does not use embedded
+ run paths, so that we can use libraries from an alternate compiler that is
+ using embedded runpaths. */
+#if DARWIN_DO_EXTRA_RPATH
+# define DARWIN_EXTRA_RPATH \
+"%{!r:%{!nostdlib:%{!nodefaultrpaths:\
+ %:version-compare(>= 10.5 mmacosx-version-min= -rpath) \
+ %:version-compare(>= 10.5 mmacosx-version-min= " DARWIN_ADD_RPATH ") \
+ }}}"
+#else
+# define DARWIN_EXTRA_RPATH ""
+#endif
+
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
do { \
darwin_override_options (); \
@@ -415,6 +428,7 @@ extern GTY(()) int darwin_ms_struct;
DARWIN_NOPIE_SPEC \
DARWIN_RDYNAMIC \
DARWIN_NOCOMPACT_UNWIND \
+ DARWIN_EXTRA_RPATH \
DARWIN_RPATH_LINK \
"}}}}}}} %<pie %<no-pie %<rdynamic %<X %<rpath %<nodefaultrpaths "
@@ -854,7 +868,7 @@ int darwin_label_is_anonymous_local_objc_name (const char *name);
else if (xname[0] == '+' || xname[0] == '-') \
fprintf (FILE, "\"%s\"", xname); \
else if (darwin_label_is_anonymous_local_objc_name (xname)) \
- fprintf (FILE, "L%s", xname); \
+ fprintf (FILE, "%c%s", flag_next_runtime ? 'L' : 'l', xname); \
else if (xname[0] != '"' && name_needs_quotes (xname)) \
asm_fprintf (FILE, "\"%U%s\"", xname); \
else \
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index c128c81..39c1dc5 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -948,7 +948,8 @@
(match_operand:V_1REG 1 "register_operand" " 0,v")
(match_operand 2 "ascending_zero_int_parallel" "")))]
"MODE_VF (<V_1REG_ALT:MODE>mode) < MODE_VF (<V_1REG:MODE>mode)
- && <V_1REG_ALT:SCALAR_MODE>mode == <V_1REG:SCALAR_MODE>mode"
+ && <V_1REG_ALT:SCALAR_MODE>mode == <V_1REG:SCALAR_MODE>mode
+ /* This comment silences a warning for operands[2]. */"
"@
; in-place extract %0
v_mov_b32\t%L0, %L1"
@@ -961,7 +962,8 @@
(match_operand:V_2REG 1 "register_operand" " 0,v")
(match_operand 2 "ascending_zero_int_parallel" "")))]
"MODE_VF (<V_2REG_ALT:MODE>mode) < MODE_VF (<V_2REG:MODE>mode)
- && <V_2REG_ALT:SCALAR_MODE>mode == <V_2REG:SCALAR_MODE>mode"
+ && <V_2REG_ALT:SCALAR_MODE>mode == <V_2REG:SCALAR_MODE>mode
+ /* This comment silences a warning for operands[2]. */"
"@
; in-place extract %0
v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1"
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index 6f85f55..6a2aaef 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -3615,13 +3615,11 @@ gcn_expand_epilogue (void)
set_mem_addr_space (retptr_mem, ADDR_SPACE_SCALAR_FLAT);
emit_move_insn (kernarg_reg, retptr_mem);
- rtx retval_addr = gen_rtx_REG (DImode, FIRST_VPARM_REG);
+ rtx retval_addr = gen_rtx_REG (DImode, FIRST_VPARM_REG + 2);
emit_move_insn (retval_addr, kernarg_reg);
rtx retval_mem = gen_rtx_MEM (SImode, retval_addr);
- rtx scalar_retval = gen_rtx_REG (SImode, FIRST_VPARM_REG + 2);
set_mem_addr_space (retval_mem, ADDR_SPACE_FLAT);
- emit_move_insn (scalar_retval, gen_rtx_REG (SImode, RETURN_VALUE_REG));
- emit_move_insn (retval_mem, scalar_retval);
+ emit_move_insn (retval_mem, gen_rtx_REG (SImode, RETURN_VALUE_REG));
}
emit_jump_insn (gen_gcn_return ());
diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md
index a3d8bee..e6a9ac6 100644
--- a/gcc/config/gcn/gcn.md
+++ b/gcc/config/gcn/gcn.md
@@ -694,7 +694,7 @@
(define_insn "prologue_use"
[(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_PROLOGUE_USE)]
- ""
+ "1 /* This comment silences a warning for operands[2]. */"
""
[(set_attr "length" "0")])
diff --git a/gcc/config/i386/avx512cdintrin.h b/gcc/config/i386/avx512cdintrin.h
index a5f5eab..56a786a 100644
--- a/gcc/config/i386/avx512cdintrin.h
+++ b/gcc/config/i386/avx512cdintrin.h
@@ -30,7 +30,7 @@
#ifndef __AVX512CD__
#pragma GCC push_options
-#pragma GCC target("avx512cd")
+#pragma GCC target("avx512cd,evex512")
#define __DISABLE_AVX512CD__
#endif /* __AVX512CD__ */
diff --git a/gcc/config/i386/avx512vlintrin.h b/gcc/config/i386/avx512vlintrin.h
index 08e49e8..a40aa91 100644
--- a/gcc/config/i386/avx512vlintrin.h
+++ b/gcc/config/i386/avx512vlintrin.h
@@ -8396,284 +8396,6 @@ _mm_mask_min_epu32 (__m128i __W, __mmask8 __M, __m128i __A,
(__v4si) __W, __M);
}
-#ifndef __AVX512CD__
-#pragma GCC push_options
-#pragma GCC target("avx512vl,avx512cd")
-#define __DISABLE_AVX512VLCD__
-#endif
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_broadcastmb_epi64 (__mmask8 __A)
-{
- return (__m128i) __builtin_ia32_broadcastmb128 (__A);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_broadcastmb_epi64 (__mmask8 __A)
-{
- return (__m256i) __builtin_ia32_broadcastmb256 (__A);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_broadcastmw_epi32 (__mmask16 __A)
-{
- return (__m128i) __builtin_ia32_broadcastmw128 (__A);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_broadcastmw_epi32 (__mmask16 __A)
-{
- return (__m256i) __builtin_ia32_broadcastmw256 (__A);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_lzcnt_epi32 (__m256i __A)
-{
- return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A,
- (__v8si)
- _mm256_setzero_si256 (),
- (__mmask8) -1);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_lzcnt_epi32 (__m256i __W, __mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A,
- (__v8si) __W,
- (__mmask8) __U);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_maskz_lzcnt_epi32 (__mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A,
- (__v8si)
- _mm256_setzero_si256 (),
- (__mmask8) __U);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_lzcnt_epi64 (__m256i __A)
-{
- return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A,
- (__v4di)
- _mm256_setzero_si256 (),
- (__mmask8) -1);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_lzcnt_epi64 (__m256i __W, __mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A,
- (__v4di) __W,
- (__mmask8) __U);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_maskz_lzcnt_epi64 (__mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A,
- (__v4di)
- _mm256_setzero_si256 (),
- (__mmask8) __U);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_conflict_epi64 (__m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
- (__v4di)
- _mm256_setzero_si256 (),
- (__mmask8) -1);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_conflict_epi64 (__m256i __W, __mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
- (__v4di) __W,
- (__mmask8)
- __U);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_maskz_conflict_epi64 (__mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
- (__v4di)
- _mm256_setzero_si256 (),
- (__mmask8)
- __U);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_conflict_epi32 (__m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
- (__v8si)
- _mm256_setzero_si256 (),
- (__mmask8) -1);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_conflict_epi32 (__m256i __W, __mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
- (__v8si) __W,
- (__mmask8)
- __U);
-}
-
-extern __inline __m256i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_maskz_conflict_epi32 (__mmask8 __U, __m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
- (__v8si)
- _mm256_setzero_si256 (),
- (__mmask8)
- __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_lzcnt_epi32 (__m128i __A)
-{
- return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A,
- (__v4si)
- _mm_setzero_si128 (),
- (__mmask8) -1);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_lzcnt_epi32 (__m128i __W, __mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A,
- (__v4si) __W,
- (__mmask8) __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_maskz_lzcnt_epi32 (__mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A,
- (__v4si)
- _mm_setzero_si128 (),
- (__mmask8) __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_lzcnt_epi64 (__m128i __A)
-{
- return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A,
- (__v2di)
- _mm_setzero_si128 (),
- (__mmask8) -1);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_lzcnt_epi64 (__m128i __W, __mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A,
- (__v2di) __W,
- (__mmask8) __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_maskz_lzcnt_epi64 (__mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A,
- (__v2di)
- _mm_setzero_si128 (),
- (__mmask8) __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_conflict_epi64 (__m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
- (__v2di)
- _mm_setzero_si128 (),
- (__mmask8) -1);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_conflict_epi64 (__m128i __W, __mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
- (__v2di) __W,
- (__mmask8)
- __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_maskz_conflict_epi64 (__mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
- (__v2di)
- _mm_setzero_si128 (),
- (__mmask8)
- __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_conflict_epi32 (__m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
- (__v4si)
- _mm_setzero_si128 (),
- (__mmask8) -1);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_conflict_epi32 (__m128i __W, __mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
- (__v4si) __W,
- (__mmask8)
- __U);
-}
-
-extern __inline __m128i
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_maskz_conflict_epi32 (__mmask8 __U, __m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
- (__v4si)
- _mm_setzero_si128 (),
- (__mmask8)
- __U);
-}
-
-#ifdef __DISABLE_AVX512VLCD__
-#pragma GCC pop_options
-#endif
-
extern __inline __m256d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_unpacklo_pd (__m256d __W, __mmask8 __U, __m256d __A,
@@ -13861,4 +13583,282 @@ _mm256_permutex_pd (__m256d __X, const int __M)
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VL__ */
+#if !defined (__AVX512CD__) || !defined (__AVX512VL__)
+#pragma GCC push_options
+#pragma GCC target("avx512vl,avx512cd")
+#define __DISABLE_AVX512VLCD__
+#endif
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_broadcastmb_epi64 (__mmask8 __A)
+{
+ return (__m128i) __builtin_ia32_broadcastmb128 (__A);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_broadcastmb_epi64 (__mmask8 __A)
+{
+ return (__m256i) __builtin_ia32_broadcastmb256 (__A);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_broadcastmw_epi32 (__mmask16 __A)
+{
+ return (__m128i) __builtin_ia32_broadcastmw128 (__A);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_broadcastmw_epi32 (__mmask16 __A)
+{
+ return (__m256i) __builtin_ia32_broadcastmw256 (__A);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_lzcnt_epi32 (__m256i __A)
+{
+ return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A,
+ (__v8si)
+ _mm256_setzero_si256 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_mask_lzcnt_epi32 (__m256i __W, __mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A,
+ (__v8si) __W,
+ (__mmask8) __U);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_maskz_lzcnt_epi32 (__mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A,
+ (__v8si)
+ _mm256_setzero_si256 (),
+ (__mmask8) __U);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_lzcnt_epi64 (__m256i __A)
+{
+ return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A,
+ (__v4di)
+ _mm256_setzero_si256 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_mask_lzcnt_epi64 (__m256i __W, __mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A,
+ (__v4di) __W,
+ (__mmask8) __U);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_maskz_lzcnt_epi64 (__mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A,
+ (__v4di)
+ _mm256_setzero_si256 (),
+ (__mmask8) __U);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_conflict_epi64 (__m256i __A)
+{
+ return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
+ (__v4di)
+ _mm256_setzero_si256 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_mask_conflict_epi64 (__m256i __W, __mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
+ (__v4di) __W,
+ (__mmask8)
+ __U);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_maskz_conflict_epi64 (__mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
+ (__v4di)
+ _mm256_setzero_si256 (),
+ (__mmask8)
+ __U);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_conflict_epi32 (__m256i __A)
+{
+ return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
+ (__v8si)
+ _mm256_setzero_si256 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_mask_conflict_epi32 (__m256i __W, __mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
+ (__v8si) __W,
+ (__mmask8)
+ __U);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_maskz_conflict_epi32 (__mmask8 __U, __m256i __A)
+{
+ return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
+ (__v8si)
+ _mm256_setzero_si256 (),
+ (__mmask8)
+ __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_lzcnt_epi32 (__m128i __A)
+{
+ return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A,
+ (__v4si)
+ _mm_setzero_si128 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_mask_lzcnt_epi32 (__m128i __W, __mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A,
+ (__v4si) __W,
+ (__mmask8) __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_maskz_lzcnt_epi32 (__mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A,
+ (__v4si)
+ _mm_setzero_si128 (),
+ (__mmask8) __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_lzcnt_epi64 (__m128i __A)
+{
+ return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A,
+ (__v2di)
+ _mm_setzero_si128 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_mask_lzcnt_epi64 (__m128i __W, __mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A,
+ (__v2di) __W,
+ (__mmask8) __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_maskz_lzcnt_epi64 (__mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A,
+ (__v2di)
+ _mm_setzero_si128 (),
+ (__mmask8) __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_conflict_epi64 (__m128i __A)
+{
+ return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
+ (__v2di)
+ _mm_setzero_si128 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_mask_conflict_epi64 (__m128i __W, __mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
+ (__v2di) __W,
+ (__mmask8)
+ __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_maskz_conflict_epi64 (__mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
+ (__v2di)
+ _mm_setzero_si128 (),
+ (__mmask8)
+ __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_conflict_epi32 (__m128i __A)
+{
+ return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
+ (__v4si)
+ _mm_setzero_si128 (),
+ (__mmask8) -1);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_mask_conflict_epi32 (__m128i __W, __mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
+ (__v4si) __W,
+ (__mmask8)
+ __U);
+}
+
+extern __inline __m128i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_maskz_conflict_epi32 (__mmask8 __U, __m128i __A)
+{
+ return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
+ (__v4si)
+ _mm_setzero_si128 (),
+ (__mmask8)
+ __U);
+}
+
+#ifdef __DISABLE_AVX512VLCD__
+#pragma GCC pop_options
+#endif
+
#endif /* _AVX512VLINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc
index a9e54ef..55d4045 100644
--- a/gcc/config/i386/driver-i386.cc
+++ b/gcc/config/i386/driver-i386.cc
@@ -530,6 +530,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
case 7:
if (model == 0x3b)
processor = PROCESSOR_LUJIAZUI;
+ else if (model >= 0x5b)
+ processor = PROCESSOR_YONGFENG;
break;
default:
break;
@@ -817,6 +819,9 @@ const char *host_detect_local_cpu (int argc, const char **argv)
case PROCESSOR_LUJIAZUI:
cpu = "lujiazui";
break;
+ case PROCESSOR_YONGFENG:
+ cpu = "yongfeng";
+ break;
default:
/* Use something reasonable. */
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index b90d5cc..19fa5c1 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -1615,8 +1615,8 @@ BDESC (OPTION_MASK_ISA_AVX512DQ, 0, CODE_FOR_ktestqi, "__builtin_ia32_ktestcqi",
BDESC (OPTION_MASK_ISA_AVX512DQ, 0, CODE_FOR_ktestqi, "__builtin_ia32_ktestzqi", IX86_BUILTIN_KTESTZ8, UNKNOWN, (int) UQI_FTYPE_UQI_UQI)
BDESC (OPTION_MASK_ISA_AVX512DQ, 0, CODE_FOR_ktesthi, "__builtin_ia32_ktestchi", IX86_BUILTIN_KTESTC16, UNKNOWN, (int) UHI_FTYPE_UHI_UHI)
BDESC (OPTION_MASK_ISA_AVX512DQ, 0, CODE_FOR_ktesthi, "__builtin_ia32_ktestzhi", IX86_BUILTIN_KTESTZ16, UNKNOWN, (int) UHI_FTYPE_UHI_UHI)
-BDESC (OPTION_MASK_ISA_AVX512BW, OPTION_MASK_ISA2_EVEX512, CODE_FOR_ktestsi, "__builtin_ia32_ktestcsi", IX86_BUILTIN_KTESTC32, UNKNOWN, (int) USI_FTYPE_USI_USI)
-BDESC (OPTION_MASK_ISA_AVX512BW, OPTION_MASK_ISA2_EVEX512, CODE_FOR_ktestsi, "__builtin_ia32_ktestzsi", IX86_BUILTIN_KTESTZ32, UNKNOWN, (int) USI_FTYPE_USI_USI)
+BDESC (OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_ktestsi, "__builtin_ia32_ktestcsi", IX86_BUILTIN_KTESTC32, UNKNOWN, (int) USI_FTYPE_USI_USI)
+BDESC (OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_ktestsi, "__builtin_ia32_ktestzsi", IX86_BUILTIN_KTESTZ32, UNKNOWN, (int) USI_FTYPE_USI_USI)
BDESC (OPTION_MASK_ISA_AVX512BW, OPTION_MASK_ISA2_EVEX512, CODE_FOR_ktestdi, "__builtin_ia32_ktestcdi", IX86_BUILTIN_KTESTC64, UNKNOWN, (int) UDI_FTYPE_UDI_UDI)
BDESC (OPTION_MASK_ISA_AVX512BW, OPTION_MASK_ISA2_EVEX512, CODE_FOR_ktestdi, "__builtin_ia32_ktestzdi", IX86_BUILTIN_KTESTZ64, UNKNOWN, (int) UDI_FTYPE_UDI_UDI)
BDESC (OPTION_MASK_ISA_AVX512DQ, 0, CODE_FOR_kortestqi, "__builtin_ia32_kortestcqi", IX86_BUILTIN_KORTESTC8, UNKNOWN, (int) UQI_FTYPE_UQI_UQI)
diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc
index ebe6a63..be1d06b 100644
--- a/gcc/config/i386/i386-c.cc
+++ b/gcc/config/i386/i386-c.cc
@@ -148,6 +148,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__lujiazui");
def_or_undef (parse_in, "__lujiazui__");
break;
+ case PROCESSOR_YONGFENG:
+ def_or_undef (parse_in, "__yongfeng");
+ def_or_undef (parse_in, "__yongfeng__");
+ break;
case PROCESSOR_PENTIUM4:
def_or_undef (parse_in, "__pentium4");
def_or_undef (parse_in, "__pentium4__");
@@ -379,6 +383,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
case PROCESSOR_LUJIAZUI:
def_or_undef (parse_in, "__tune_lujiazui__");
break;
+ case PROCESSOR_YONGFENG:
+ def_or_undef (parse_in, "__tune_yongfeng__");
+ break;
case PROCESSOR_PENTIUM4:
def_or_undef (parse_in, "__tune_pentium4__");
break;
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 1eae9d7..6ae5830 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -1110,7 +1110,9 @@ ix86_split_mmx_pack (rtx operands[], enum rtx_code code)
ix86_move_vector_high_sse_to_mmx (op0);
}
-/* Split MMX punpcklXX/punpckhXX with SSE punpcklXX. */
+/* Split MMX punpcklXX/punpckhXX with SSE punpcklXX. This is also used
+ for a full unpack of OPERANDS[1] and OPERANDS[2] into a wider
+ OPERANDS[0]. */
void
ix86_split_mmx_punpck (rtx operands[], bool high_p)
@@ -1118,7 +1120,7 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
rtx op0 = operands[0];
rtx op1 = operands[1];
rtx op2 = operands[2];
- machine_mode mode = GET_MODE (op0);
+ machine_mode mode = GET_MODE (op1);
rtx mask;
/* The corresponding SSE mode. */
machine_mode sse_mode, double_sse_mode;
@@ -2411,30 +2413,53 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
rtx tmp;
/* Handle special case - vector comparsion with boolean result, transform
- it using ptest instruction. */
+ it using ptest instruction or vpcmpeq + kortest. */
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
|| (mode == TImode && !TARGET_64BIT)
- || mode == OImode)
+ || mode == OImode
+ || GET_MODE_SIZE (mode) == 64)
{
- rtx flag = gen_rtx_REG (CCZmode, FLAGS_REG);
- machine_mode p_mode = GET_MODE_SIZE (mode) == 32 ? V4DImode : V2DImode;
+ unsigned msize = GET_MODE_SIZE (mode);
+ machine_mode p_mode
+ = msize == 64 ? V16SImode : msize == 32 ? V4DImode : V2DImode;
+ /* kortest set CF when result is 0xFFFF (op0 == op1). */
+ rtx flag = gen_rtx_REG (msize == 64 ? CCCmode : CCZmode, FLAGS_REG);
gcc_assert (code == EQ || code == NE);
- if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+ /* Using vpcmpeq zmm zmm k + kortest for 512-bit vectors. */
+ if (msize == 64)
{
- op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
- op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
- mode = p_mode;
+ if (mode != V16SImode)
+ {
+ op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
+ op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
+ }
+
+ tmp = gen_reg_rtx (HImode);
+ emit_insn (gen_avx512f_cmpv16si3 (tmp, op0, op1, GEN_INT (0)));
+ emit_insn (gen_kortesthi_ccc (tmp, tmp));
+ }
+ /* Using ptest for 128/256-bit vectors. */
+ else
+ {
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+ {
+ op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
+ op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
+ mode = p_mode;
+ }
+
+ /* 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)));
+ tmp = gen_lowpart (p_mode, tmp);
+ emit_insn (gen_rtx_SET (gen_rtx_REG (CCZmode, FLAGS_REG),
+ gen_rtx_UNSPEC (CCZmode,
+ gen_rtvec (2, tmp, tmp),
+ UNSPEC_PTEST)));
}
- /* 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)));
- tmp = gen_lowpart (p_mode, tmp);
- emit_insn (gen_rtx_SET (gen_rtx_REG (CCZmode, FLAGS_REG),
- gen_rtx_UNSPEC (CCZmode,
- gen_rtvec (2, tmp, tmp),
- UNSPEC_PTEST)));
tmp = gen_rtx_fmt_ee (code, VOIDmode, flag, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
@@ -4198,6 +4223,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
break;
case E_V8QImode:
case E_V4HImode:
+ case E_V4HFmode:
+ case E_V4BFmode:
case E_V2SImode:
if (TARGET_SSE4_1)
{
@@ -4207,6 +4234,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
break;
case E_V4QImode:
case E_V2HImode:
+ case E_V2HFmode:
+ case E_V2BFmode:
if (TARGET_SSE4_1)
{
gen = gen_mmx_pblendvb_v4qi;
@@ -5660,7 +5689,7 @@ ix86_expand_sse_extend (rtx dest, rtx src, bool unsigned_p)
gcc_unreachable ();
}
- ops[0] = gen_reg_rtx (imode);
+ ops[0] = dest;
ops[1] = force_reg (imode, src);
@@ -5671,7 +5700,6 @@ ix86_expand_sse_extend (rtx dest, rtx src, bool unsigned_p)
ops[1], pc_rtx, pc_rtx);
ix86_split_mmx_punpck (ops, false);
- emit_move_insn (dest, lowpart_subreg (GET_MODE (dest), ops[0], imode));
}
/* Unpack SRC into the next wider integer vector type. UNSIGNED_P is
diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index cead397..6fac67e 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -752,11 +752,33 @@ general_scalar_chain::compute_convert_gain ()
fprintf (dump_file, " Instruction conversion gain: %d\n", gain);
/* Cost the integer to sse and sse to integer moves. */
- cost += n_sse_to_integer * ix86_cost->sse_to_integer;
- /* ??? integer_to_sse but we only have that in the RA cost table.
- Assume sse_to_integer/integer_to_sse are the same which they
- are at the moment. */
- cost += n_integer_to_sse * ix86_cost->sse_to_integer;
+ if (!optimize_function_for_size_p (cfun))
+ {
+ cost += n_sse_to_integer * ix86_cost->sse_to_integer;
+ /* ??? integer_to_sse but we only have that in the RA cost table.
+ Assume sse_to_integer/integer_to_sse are the same which they
+ are at the moment. */
+ cost += n_integer_to_sse * ix86_cost->sse_to_integer;
+ }
+ else if (TARGET_64BIT || smode == SImode)
+ {
+ cost += n_sse_to_integer * COSTS_N_BYTES (4);
+ cost += n_integer_to_sse * COSTS_N_BYTES (4);
+ }
+ else if (TARGET_SSE4_1)
+ {
+ /* vmovd (4 bytes) + vpextrd (6 bytes). */
+ cost += n_sse_to_integer * COSTS_N_BYTES (10);
+ /* vmovd (4 bytes) + vpinsrd (6 bytes). */
+ cost += n_integer_to_sse * COSTS_N_BYTES (10);
+ }
+ else
+ {
+ /* movd (4 bytes) + psrlq (5 bytes) + movd (4 bytes). */
+ cost += n_sse_to_integer * COSTS_N_BYTES (13);
+ /* movd (4 bytes) + movd (4 bytes) + unpckldq (4 bytes). */
+ cost += n_integer_to_sse * COSTS_N_BYTES (12);
+ }
if (dump_file)
fprintf (dump_file, " Registers conversion cost: %d\n", cost);
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index 072bbc6..df7d243 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -154,6 +154,8 @@ along with GCC; see the file COPYING3. If not see
| m_TIGERLAKE | m_COOPERLAKE | m_ROCKETLAKE)
#define m_LUJIAZUI (HOST_WIDE_INT_1U<<PROCESSOR_LUJIAZUI)
+#define m_YONGFENG (HOST_WIDE_INT_1U<<PROCESSOR_YONGFENG)
+#define m_ZHAOXIN (m_LUJIAZUI | m_YONGFENG)
#define m_GEODE (HOST_WIDE_INT_1U<<PROCESSOR_GEODE)
#define m_K6 (HOST_WIDE_INT_1U<<PROCESSOR_K6)
@@ -792,6 +794,7 @@ static const struct processor_costs *processor_cost_table[] =
&alderlake_cost,
&intel_cost,
&lujiazui_cost,
+ &yongfeng_cost,
&geode_cost,
&k6_cost,
&athlon_cost,
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index f4772e0..0f17f7d 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -5481,6 +5481,9 @@ ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
if (src == NULL
|| (SSE_REGNO_P (REGNO (dst))
&& standard_sse_constant_p (src, GET_MODE (dst)) != 1)
+ || (!TARGET_AVX512VL
+ && EXT_REX_SSE_REGNO_P (REGNO (dst))
+ && standard_sse_constant_p (src, GET_MODE (dst)) == 1)
|| (STACK_REGNO_P (REGNO (dst))
&& standard_80387_constant_p (src) < 1))
return false;
@@ -24360,7 +24363,11 @@ ix86_get_mask_mode (machine_mode data_mode)
/* Scalar mask case. */
if ((TARGET_AVX512F && TARGET_EVEX512 && vector_size == 64)
- || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16)))
+ || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16))
+ /* AVX512FP16 only supports vector comparison
+ to kmask for _Float16. */
+ || (TARGET_AVX512VL && TARGET_AVX512FP16
+ && GET_MODE_INNER (data_mode) == E_HFmode))
{
if (elem_size == 4
|| elem_size == 8
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7e66fa0..a56367a 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -311,6 +311,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST];
#define TARGET_USE_SAHF ix86_tune_features[X86_TUNE_USE_SAHF]
#define TARGET_MOVX ix86_tune_features[X86_TUNE_MOVX]
#define TARGET_PARTIAL_REG_STALL ix86_tune_features[X86_TUNE_PARTIAL_REG_STALL]
+#define TARGET_PARTIAL_MEMORY_READ_STALL \
+ ix86_tune_features[X86_TUNE_PARTIAL_MEMORY_READ_STALL]
#define TARGET_PARTIAL_FLAG_REG_STALL \
ix86_tune_features[X86_TUNE_PARTIAL_FLAG_REG_STALL]
#define TARGET_LCP_STALL \
@@ -2295,6 +2297,7 @@ enum processor_type
PROCESSOR_PANTHERLAKE,
PROCESSOR_INTEL,
PROCESSOR_LUJIAZUI,
+ PROCESSOR_YONGFENG,
PROCESSOR_GEODE,
PROCESSOR_K6,
PROCESSOR_ATHLON,
@@ -2433,6 +2436,14 @@ constexpr wide_int_bitmask PTA_ZNVER4 = PTA_ZNVER3 | PTA_AVX512F | PTA_AVX512DQ
| PTA_AVX512BF16 | PTA_AVX512VBMI | PTA_AVX512VBMI2 | PTA_GFNI
| PTA_AVX512VNNI | PTA_AVX512BITALG | PTA_AVX512VPOPCNTDQ;
+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
+ | PTA_PCLMUL | PTA_BMI | PTA_BMI2 | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT
+ | PTA_FSGSBASE | PTA_RDRND | PTA_MOVBE | PTA_ADX | PTA_RDSEED | PTA_POPCNT;
+
+constexpr wide_int_bitmask PTA_YONGFENG = PTA_LUJIAZUI | PTA_AVX | PTA_AVX2 | PTA_F16C
+ | PTA_FMA | PTA_SHA | PTA_LZCNT;
+
#ifndef GENERATOR_FILE
#include "insn-attr-common.h"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index abaf2f3..9027998 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -508,7 +508,7 @@
;; Processor type.
(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
- atom,slm,glm,haswell,generic,lujiazui,amdfam10,bdver1,
+ atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
(const (symbol_ref "ix86_schedule")))
@@ -1382,6 +1382,7 @@
(include "core2.md")
(include "haswell.md")
(include "lujiazui.md")
+(include "yongfeng.md")
;; Operand and operator predicates and constraints
@@ -1442,6 +1443,22 @@
DONE;
})
+(define_expand "cbranchxi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:XI 1 "nonimmediate_operand")
+ (match_operand:XI 2 "nonimmediate_operand")))
+ (set (pc) (if_then_else
+ (match_operator 0 "bt_comparison_operator"
+ [(reg:CC FLAGS_REG) (const_int 0)])
+ (label_ref (match_operand 3))
+ (pc)))]
+ "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
+{
+ ix86_expand_branch (GET_CODE (operands[0]),
+ operands[1], operands[2], operands[3]);
+ DONE;
+})
+
(define_expand "cstore<mode>4"
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
@@ -9725,44 +9742,64 @@
[(parallel [(set (match_operand:<DWI> 0 "register_operand")
(mult:<DWI>
(any_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand"))
+ (match_operand:DWIH 1 "register_operand"))
(any_extend:<DWI>
- (match_operand:DWIH 2 "register_operand"))))
+ (match_operand:DWIH 2 "nonimmediate_operand"))))
(clobber (reg:CC FLAGS_REG))])])
(define_expand "<u>mulqihi3"
[(parallel [(set (match_operand:HI 0 "register_operand")
(mult:HI
(any_extend:HI
- (match_operand:QI 1 "nonimmediate_operand"))
+ (match_operand:QI 1 "register_operand"))
(any_extend:HI
- (match_operand:QI 2 "register_operand"))))
+ (match_operand:QI 2 "nonimmediate_operand"))))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_QIMODE_MATH")
(define_insn "*bmi2_umul<mode><dwi>3_1"
[(set (match_operand:DWIH 0 "register_operand" "=r")
(mult:DWIH
- (match_operand:DWIH 2 "nonimmediate_operand" "%d")
+ (match_operand:DWIH 2 "register_operand" "%d")
(match_operand:DWIH 3 "nonimmediate_operand" "rm")))
(set (match_operand:DWIH 1 "register_operand" "=r")
- (truncate:DWIH
- (lshiftrt:<DWI>
- (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
- (zero_extend:<DWI> (match_dup 3)))
- (match_operand:QI 4 "const_int_operand"))))]
- "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
- && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
+ (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
+ "TARGET_BMI2"
"mulx\t{%3, %0, %1|%1, %0, %3}"
[(set_attr "type" "imulx")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
+;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
+(define_peephole2
+ [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
+ (mult:DWIH (match_operand:DWIH 2 "register_operand")
+ (match_operand:DWIH 3 "nonimmediate_operand")))
+ (set (match_operand:DWIH 1 "general_reg_operand")
+ (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
+ (set (match_operand:DWIH 4 "general_reg_operand")
+ (match_operand:DWIH 5 "general_reg_operand"))]
+ "TARGET_BMI2
+ && ((REGNO (operands[5]) == REGNO (operands[0])
+ && REGNO (operands[1]) != REGNO (operands[4]))
+ || (REGNO (operands[5]) == REGNO (operands[1])
+ && REGNO (operands[0]) != REGNO (operands[4])))
+ && peep2_reg_dead_p (2, operands[5])"
+ [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
+ (set (match_dup 1)
+ (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
+{
+ if (REGNO (operands[5]) == REGNO (operands[0]))
+ operands[0] = operands[4];
+ else
+ operands[1] = operands[4];
+})
+
(define_insn "*umul<mode><dwi>3_1"
[(set (match_operand:<DWI> 0 "register_operand" "=r,A")
(mult:<DWI>
(zero_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
+ (match_operand:DWIH 1 "register_operand" "%d,a"))
(zero_extend:<DWI>
(match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
(clobber (reg:CC FLAGS_REG))]
@@ -9798,11 +9835,7 @@
[(parallel [(set (match_dup 3)
(mult:DWIH (match_dup 1) (match_dup 2)))
(set (match_dup 4)
- (truncate:DWIH
- (lshiftrt:<DWI>
- (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
- (zero_extend:<DWI> (match_dup 2)))
- (match_dup 5))))])]
+ (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
{
split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
@@ -9813,7 +9846,7 @@
[(set (match_operand:<DWI> 0 "register_operand" "=A")
(mult:<DWI>
(sign_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
+ (match_operand:DWIH 1 "register_operand" "%a"))
(sign_extend:<DWI>
(match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
(clobber (reg:CC FLAGS_REG))]
@@ -9833,7 +9866,7 @@
[(set (match_operand:HI 0 "register_operand" "=a")
(mult:HI
(any_extend:HI
- (match_operand:QI 1 "nonimmediate_operand" "%0"))
+ (match_operand:QI 1 "register_operand" "%0"))
(any_extend:HI
(match_operand:QI 2 "nonimmediate_operand" "qm"))))
(clobber (reg:CC FLAGS_REG))]
@@ -9850,6 +9883,51 @@
(set_attr "bdver1_decode" "direct")
(set_attr "mode" "QI")])
+;; Widening multiplication peephole2s to tweak register allocation.
+;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
+(define_peephole2
+ [(set (match_operand:DWIH 0 "general_reg_operand")
+ (match_operand:DWIH 1 "immediate_operand"))
+ (set (match_operand:DWIH 2 "general_reg_operand")
+ (match_operand:DWIH 3 "general_reg_operand"))
+ (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
+ (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
+ (zero_extend:<DWI> (match_dup 0))))
+ (clobber (reg:CC FLAGS_REG))])]
+ "REGNO (operands[3]) != AX_REG
+ && REGNO (operands[0]) != REGNO (operands[2])
+ && REGNO (operands[0]) != REGNO (operands[3])
+ && (REGNO (operands[0]) == REGNO (operands[4])
+ || REGNO (operands[0]) == DX_REG
+ || peep2_reg_dead_p (3, operands[0]))"
+ [(set (match_dup 2) (match_dup 1))
+ (parallel [(set (match_dup 4)
+ (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
+ (zero_extend:<DWI> (match_dup 3))))
+ (clobber (reg:CC FLAGS_REG))])])
+
+;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
+(define_peephole2
+ [(set (match_operand:DWIH 0 "general_reg_operand")
+ (match_operand:DWIH 1 "immediate_operand"))
+ (set (match_operand:DWIH 2 "general_reg_operand")
+ (match_operand:DWIH 3 "general_reg_operand"))
+ (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
+ (mult:DWIH (match_dup 2) (match_dup 0)))
+ (set (match_operand:DWIH 5 "general_reg_operand")
+ (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
+ "REGNO (operands[3]) != DX_REG
+ && REGNO (operands[0]) != REGNO (operands[2])
+ && REGNO (operands[0]) != REGNO (operands[3])
+ && (REGNO (operands[0]) == REGNO (operands[4])
+ || REGNO (operands[0]) == REGNO (operands[5])
+ || peep2_reg_dead_p (3, operands[0]))"
+ [(set (match_dup 2) (match_dup 1))
+ (parallel [(set (match_dup 4)
+ (mult:DWIH (match_dup 2) (match_dup 3)))
+ (set (match_dup 5)
+ (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
+
;; Highpart multiplication patterns
(define_insn "<s>mul<mode>3_highpart"
[(set (match_operand:DWIH 0 "register_operand" "=d")
@@ -11115,6 +11193,57 @@
operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
})
+;; Narrow test instructions with immediate operands that test
+;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
+;; converted to testb $0xaa, mem+2. Reject volatile locations and
+;; targets where reading (possibly unaligned) part of memory
+;; location after a large write to the same address causes
+;; store-to-load forwarding stall.
+(define_peephole2
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ
+ (and:SWI248 (match_operand:SWI248 0 "memory_operand")
+ (match_operand 1 "const_int_operand"))
+ (const_int 0)))]
+ "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ (match_dup 2) (const_int 0)))]
+{
+ unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
+ int first_nonzero_byte, bitsize;
+ rtx new_addr, new_const;
+ machine_mode new_mode;
+
+ if (ival == 0)
+ FAIL;
+
+ /* Clear bits outside mode width. */
+ ival &= GET_MODE_MASK (<MODE>mode);
+
+ first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
+
+ ival >>= first_nonzero_byte * BITS_PER_UNIT;
+
+ bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
+
+ if (bitsize <= GET_MODE_BITSIZE (QImode))
+ new_mode = QImode;
+ else if (bitsize <= GET_MODE_BITSIZE (HImode))
+ new_mode = HImode;
+ else if (bitsize <= GET_MODE_BITSIZE (SImode))
+ new_mode = SImode;
+ else
+ new_mode = DImode;
+
+ if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
+ FAIL;
+
+ new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
+ new_const = gen_int_mode (ival, new_mode);
+
+ operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
+})
+
;; %%% This used to optimize known byte-wide and operations to memory,
;; and sometimes to QImode registers. If this is considered useful,
;; it should be done with splitters.
@@ -25548,40 +25677,58 @@
(match_operand 1 "memory_operand")]
""
{
+ rtx scratch = gen_reg_rtx (word_mode);
+
emit_insn (gen_stack_protect_set_1
- (ptr_mode, operands[0], operands[1]));
+ (ptr_mode, word_mode, operands[0], operands[1], scratch));
DONE;
})
-(define_insn "@stack_protect_set_1_<mode>"
+(define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
[(set (match_operand:PTR 0 "memory_operand" "=m")
(unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
UNSPEC_SP_SET))
- (set (match_scratch:PTR 2 "=&r") (const_int 0))
+ (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
(clobber (reg:CC FLAGS_REG))]
""
{
- output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
- output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
+ output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
+ operands);
+ output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
+ operands);
return "xor{l}\t%k2, %k2";
}
[(set_attr "type" "multi")])
;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
-;; immediately followed by *mov{s,d}i_internal to the same register,
-;; where we can avoid the xor{l} above. We don't split this, so that
-;; scheduling or anything else doesn't separate the *stack_protect_set*
-;; pattern from the set of the register that overwrites the register
-;; with a new value.
-(define_insn "*stack_protect_set_2_<mode>"
+;; immediately followed by *mov{s,d}i_internal, where we can avoid
+;; the xor{l} above. We don't split this, so that scheduling or
+;; anything else doesn't separate the *stack_protect_set* pattern from
+;; the set of the register that overwrites the register with a new value.
+
+(define_peephole2
+ [(parallel [(set (match_operand:PTR 0 "memory_operand")
+ (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+ UNSPEC_SP_SET))
+ (set (match_operand:W 2 "general_reg_operand") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
+ (match_operand:SWI48 4 "const0_operand"))
+ (clobber (reg:CC FLAGS_REG))])]
+ "peep2_reg_dead_p (0, operands[3])
+ && peep2_reg_dead_p (1, operands[2])"
+ [(parallel [(set (match_dup 0)
+ (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+ (set (match_dup 3) (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])])
+
+(define_insn "*stack_protect_set_2_<mode>_si"
[(set (match_operand:PTR 0 "memory_operand" "=m")
(unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
UNSPEC_SP_SET))
(set (match_operand:SI 1 "register_operand" "=&r")
- (match_operand:SI 2 "general_operand" "g"))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && !reg_overlap_mentioned_p (operands[1], operands[2])"
+ (match_operand:SI 2 "general_operand" "g"))]
+ "reload_completed"
{
output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
@@ -25594,38 +25741,16 @@
[(set_attr "type" "multi")
(set_attr "length" "24")])
-(define_peephole2
- [(parallel [(set (match_operand:PTR 0 "memory_operand")
- (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
- UNSPEC_SP_SET))
- (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_operand:SI 3 "general_reg_operand")
- (match_operand:SI 4))]
- "REGNO (operands[2]) == REGNO (operands[3])
- && general_operand (operands[4], SImode)
- && (general_reg_operand (operands[4], SImode)
- || memory_operand (operands[4], SImode)
- || immediate_operand (operands[4], SImode))
- && !reg_overlap_mentioned_p (operands[3], operands[4])"
- [(parallel [(set (match_dup 0)
- (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
- (set (match_dup 3) (match_dup 4))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_insn "*stack_protect_set_3"
- [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
- (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
- UNSPEC_SP_SET))
- (set (match_operand:DI 1 "register_operand" "=&r,r,r")
- (match_operand:DI 2 "general_operand" "Z,rem,i"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && reload_completed
- && !reg_overlap_mentioned_p (operands[1], operands[2])"
+(define_insn "*stack_protect_set_2_<mode>_di"
+ [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
+ (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
+ UNSPEC_SP_SET))
+ (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
+ (match_operand:DI 2 "general_operand" "Z,rem,i"))]
+ "TARGET_64BIT && reload_completed"
{
- output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
- output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
+ output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+ output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
if (pic_32bit_operand (operands[2], DImode))
return "lea{q}\t{%E2, %1|%1, %E2}";
else if (which_alternative == 0)
@@ -25641,25 +25766,18 @@
(set_attr "length" "24")])
(define_peephole2
- [(parallel [(set (match_operand:DI 0 "memory_operand")
- (unspec:DI [(match_operand:DI 1 "memory_operand")]
- UNSPEC_SP_SET))
- (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 2) (match_operand:DI 3))]
- "TARGET_64BIT
- && general_operand (operands[3], DImode)
- && (general_reg_operand (operands[3], DImode)
- || memory_operand (operands[3], DImode)
- || x86_64_zext_immediate_operand (operands[3], DImode)
- || x86_64_immediate_operand (operands[3], DImode)
- || (CONSTANT_P (operands[3])
- && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
- && !reg_overlap_mentioned_p (operands[2], operands[3])"
- [(parallel [(set (match_dup 0)
- (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
- (set (match_dup 2) (match_dup 3))
- (clobber (reg:CC FLAGS_REG))])])
+ [(parallel [(set (match_operand:PTR 0 "memory_operand")
+ (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+ UNSPEC_SP_SET))
+ (set (match_operand:W 2 "general_reg_operand") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (set (match_operand:SWI48 3 "general_reg_operand")
+ (match_operand:SWI48 4 "general_gr_operand"))]
+ "peep2_reg_dead_p (0, operands[3])
+ && peep2_reg_dead_p (1, operands[2])"
+ [(parallel [(set (match_dup 0)
+ (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+ (set (match_dup 3) (match_dup 4))])])
(define_expand "stack_protect_test"
[(match_operand 0 "memory_operand")
diff --git a/gcc/config/i386/lujiazui.md b/gcc/config/i386/lujiazui.md
index 2afd97a..daf4cde 100644
--- a/gcc/config/i386/lujiazui.md
+++ b/gcc/config/i386/lujiazui.md
@@ -137,7 +137,7 @@
(define_insn_reservation "lua_lea" 1
(and (eq_attr "cpu" "lujiazui")
(eq_attr "type" "lea"))
- "hsw_decodern,lua_p45")
+ "lua_decodern,lua_p45")
(define_insn_reservation "lua_shift_rotate" 1
(and (eq_attr "cpu" "lujiazui")
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 491a0a5..2b97bb8 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -61,6 +61,9 @@
(define_mode_iterator V_32 [V4QI V2HI V1SI V2HF V2BF])
(define_mode_iterator V2FI_32 [V2HF V2BF V2HI])
+(define_mode_iterator V4FI_64 [V4HF V4BF V4HI])
+(define_mode_iterator V4F_64 [V4HF V4BF])
+(define_mode_iterator V2F_32 [V2HF V2BF])
;; 4-byte integer vector modes
(define_mode_iterator VI_32 [V4QI V2HI])
@@ -1972,10 +1975,12 @@
[(V2HF "d") (V4HF "q") (V2HI "d") (V4HI "q")])
(define_mode_attr mmxxmmmode
- [(V2HF "V8HF") (V2HI "V8HI") (V2BF "V8BF")])
+ [(V2HF "V8HF") (V2HI "V8HI") (V2BF "V8BF")
+ (V4HF "V8HF") (V4HI "V8HI") (V4BF "V8BF")])
(define_mode_attr mmxxmmmodelower
- [(V2HF "v8hf") (V2HI "v8hi") (V2BF "v8bf")])
+ [(V2HF "v8hf") (V2HI "v8hi") (V2BF "v8bf")
+ (V4HF "v8hf") (V4HI "v8hi") (V4BF "v8bf")])
(define_expand "movd_<mode>_to_sse"
[(set (match_operand:<mmxxmmmode> 0 "register_operand")
@@ -2116,6 +2121,110 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
+;; Parallel half-precision floating point comparisons
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define_expand "vec_cmpv4hfqi"
+ [(set (match_operand:QI 0 "register_operand")
+ (match_operator:QI 1 ""
+ [(match_operand:V4HF 2 "nonimmediate_operand")
+ (match_operand:V4HF 3 "nonimmediate_operand")]))]
+ "TARGET_MMX_WITH_SSE && TARGET_AVX512FP16 && TARGET_AVX512VL
+ && ix86_partial_vec_fp_math"
+{
+ rtx ops[4];
+ ops[3] = gen_reg_rtx (V8HFmode);
+ ops[2] = gen_reg_rtx (V8HFmode);
+
+ emit_insn (gen_movq_v4hf_to_sse (ops[3], operands[3]));
+ emit_insn (gen_movq_v4hf_to_sse (ops[2], operands[2]));
+ emit_insn (gen_vec_cmpv8hfqi (operands[0], operands[1], ops[2], ops[3]));
+ DONE;
+})
+
+(define_expand "vcond_mask_<mode>v4hi"
+ [(set (match_operand:V4F_64 0 "register_operand")
+ (vec_merge:V4F_64
+ (match_operand:V4F_64 1 "register_operand")
+ (match_operand:V4F_64 2 "register_operand")
+ (match_operand:V4HI 3 "register_operand")))]
+ "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
+{
+ ix86_expand_sse_movcc (operands[0], operands[3],
+ operands[1], operands[2]);
+ DONE;
+})
+
+(define_expand "vcond_mask_<mode>qi"
+ [(set (match_operand:V4FI_64 0 "register_operand")
+ (vec_merge:V4FI_64
+ (match_operand:V4FI_64 1 "register_operand")
+ (match_operand:V4FI_64 2 "register_operand")
+ (match_operand:QI 3 "register_operand")))]
+ "TARGET_MMX_WITH_SSE && TARGET_AVX512BW && TARGET_AVX512VL"
+{
+ rtx op0 = gen_reg_rtx (<mmxxmmmode>mode);
+ operands[1] = lowpart_subreg (<mmxxmmmode>mode, operands[1], <MODE>mode);
+ operands[2] = lowpart_subreg (<mmxxmmmode>mode, operands[2], <MODE>mode);
+ emit_insn (gen_vcond_mask_<mmxxmmmodelower>qi (op0, operands[1],
+ operands[2], operands[3]));
+ emit_move_insn (operands[0],
+ lowpart_subreg (<MODE>mode, op0, <mmxxmmmode>mode));
+ DONE;
+})
+
+(define_expand "vec_cmpv2hfqi"
+ [(set (match_operand:QI 0 "register_operand")
+ (match_operator:QI 1 ""
+ [(match_operand:V2HF 2 "nonimmediate_operand")
+ (match_operand:V2HF 3 "nonimmediate_operand")]))]
+ "TARGET_AVX512FP16 && TARGET_AVX512VL
+ && ix86_partial_vec_fp_math"
+{
+ rtx ops[4];
+ ops[3] = gen_reg_rtx (V8HFmode);
+ ops[2] = gen_reg_rtx (V8HFmode);
+
+ emit_insn (gen_movd_v2hf_to_sse (ops[3], operands[3]));
+ emit_insn (gen_movd_v2hf_to_sse (ops[2], operands[2]));
+ emit_insn (gen_vec_cmpv8hfqi (operands[0], operands[1], ops[2], ops[3]));
+ DONE;
+})
+
+(define_expand "vcond_mask_<mode>v2hi"
+ [(set (match_operand:V2F_32 0 "register_operand")
+ (vec_merge:V2F_32
+ (match_operand:V2F_32 1 "register_operand")
+ (match_operand:V2F_32 2 "register_operand")
+ (match_operand:V2HI 3 "register_operand")))]
+ "TARGET_SSE4_1"
+{
+ ix86_expand_sse_movcc (operands[0], operands[3],
+ operands[1], operands[2]);
+ DONE;
+})
+
+(define_expand "vcond_mask_<mode>qi"
+ [(set (match_operand:V2FI_32 0 "register_operand")
+ (vec_merge:V2FI_32
+ (match_operand:V2FI_32 1 "register_operand")
+ (match_operand:V2FI_32 2 "register_operand")
+ (match_operand:QI 3 "register_operand")))]
+ "TARGET_AVX512BW && TARGET_AVX512VL"
+{
+ rtx op0 = gen_reg_rtx (<mmxxmmmode>mode);
+ operands[1] = lowpart_subreg (<mmxxmmmode>mode, operands[1], <MODE>mode);
+ operands[2] = lowpart_subreg (<mmxxmmmode>mode, operands[2], <MODE>mode);
+ emit_insn (gen_vcond_mask_<mmxxmmmodelower>qi (op0, operands[1],
+ operands[2], operands[3]));
+ emit_move_insn (operands[0],
+ lowpart_subreg (<MODE>mode, op0, <mmxxmmmode>mode));
+ DONE;
+})
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
;; Parallel half-precision floating point rounding operations.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -3785,6 +3894,62 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "TI")])
+(define_insn_and_split "*mmx_pblendvb_v8qi_1"
+ [(set (match_operand:V8QI 0 "register_operand")
+ (unspec:V8QI
+ [(match_operand:V8QI 1 "register_operand")
+ (match_operand:V8QI 2 "register_operand")
+ (eq:V8QI
+ (eq:V8QI
+ (match_operand:V8QI 3 "register_operand")
+ (match_operand:V8QI 4 "nonmemory_operand"))
+ (match_operand:V8QI 5 "const0_operand"))]
+ UNSPEC_BLENDV))]
+ "TARGET_MMX_WITH_SSE && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 6)
+ (eq:V8QI (match_dup 3) (match_dup 7)))
+ (set (match_dup 0)
+ (unspec:V8QI
+ [(match_dup 2)
+ (match_dup 1)
+ (match_dup 6)]
+ UNSPEC_BLENDV))]
+{
+ operands[6] = gen_reg_rtx (V8QImode);
+ operands[7] = force_reg (V8QImode, operands[4]);
+})
+
+(define_insn_and_split "*mmx_pblendvb_v8qi_2"
+ [(set (match_operand:V8QI 0 "register_operand")
+ (unspec:V8QI
+ [(match_operand:V8QI 1 "register_operand")
+ (match_operand:V8QI 2 "register_operand")
+ (subreg:V8QI
+ (eq:MMXMODE24
+ (eq:MMXMODE24
+ (match_operand:MMXMODE24 3 "register_operand")
+ (match_operand:MMXMODE24 4 "nonmemory_operand"))
+ (match_operand:MMXMODE24 5 "const0_operand")) 0)]
+ UNSPEC_BLENDV))]
+ "TARGET_MMX_WITH_SSE && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 6)
+ (eq:MMXMODE24 (match_dup 3) (match_dup 8)))
+ (set (match_dup 0)
+ (unspec:V8QI
+ [(match_dup 2)
+ (match_dup 1)
+ (match_dup 7)]
+ UNSPEC_BLENDV))]
+{
+ operands[6] = gen_reg_rtx (<MODE>mode);
+ operands[7] = lowpart_subreg (V8QImode, operands[6], <MODE>mode);
+ operands[8] = force_reg (<MODE>mode, operands[4]);
+})
+
(define_insn "mmx_pblendvb_<mode>"
[(set (match_operand:VI_16_32 0 "register_operand" "=Yr,*x,x")
(unspec:VI_16_32
@@ -3805,6 +3970,62 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "TI")])
+(define_insn_and_split "*mmx_pblendvb_<mode>_1"
+ [(set (match_operand:VI_16_32 0 "register_operand")
+ (unspec:VI_16_32
+ [(match_operand:VI_16_32 1 "register_operand")
+ (match_operand:VI_16_32 2 "register_operand")
+ (eq:VI_16_32
+ (eq:VI_16_32
+ (match_operand:VI_16_32 3 "register_operand")
+ (match_operand:VI_16_32 4 "nonmemory_operand"))
+ (match_operand:VI_16_32 5 "const0_operand"))]
+ UNSPEC_BLENDV))]
+ "TARGET_SSE2 && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 6)
+ (eq:VI_16_32 (match_dup 3) (match_dup 7)))
+ (set (match_dup 0)
+ (unspec:VI_16_32
+ [(match_dup 2)
+ (match_dup 1)
+ (match_dup 6)]
+ UNSPEC_BLENDV))]
+{
+ operands[6] = gen_reg_rtx (<MODE>mode);
+ operands[7] = force_reg (<MODE>mode, operands[4]);
+})
+
+(define_insn_and_split "*mmx_pblendvb_v4qi_2"
+ [(set (match_operand:V4QI 0 "register_operand")
+ (unspec:V4QI
+ [(match_operand:V4QI 1 "register_operand")
+ (match_operand:V4QI 2 "register_operand")
+ (subreg:V4QI
+ (eq:V2HI
+ (eq:V2HI
+ (match_operand:V2HI 3 "register_operand")
+ (match_operand:V2HI 4 "nonmemory_operand"))
+ (match_operand:V2HI 5 "const0_operand")) 0)]
+ UNSPEC_BLENDV))]
+ "TARGET_SSE2 && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 6)
+ (eq:V2HI (match_dup 3) (match_dup 8)))
+ (set (match_dup 0)
+ (unspec:V4QI
+ [(match_dup 2)
+ (match_dup 1)
+ (match_dup 7)]
+ UNSPEC_BLENDV))]
+{
+ operands[6] = gen_reg_rtx (V2HImode);
+ operands[7] = lowpart_subreg (V4QImode, operands[6], V2HImode);
+ operands[8] = force_reg (V2HImode, operands[4]);
+})
+
;; XOP parallel XMM conditional moves
(define_insn "*xop_pcmov_<mode>"
[(set (match_operand:MMXMODE124 0 "register_operand" "=x")
@@ -4574,20 +4795,6 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "TI")])
-(define_expand "mmx_pinsrw"
- [(set (match_operand:V4HI 0 "register_operand")
- (vec_merge:V4HI
- (vec_duplicate:V4HI
- (match_operand:SI 2 "nonimmediate_operand"))
- (match_operand:V4HI 1 "register_operand")
- (match_operand:SI 3 "const_0_to_3_operand")))]
- "(TARGET_MMX || TARGET_MMX_WITH_SSE)
- && (TARGET_SSE || TARGET_3DNOW_A)"
-{
- operands[2] = gen_lowpart (HImode, operands[2]);
- operands[3] = GEN_INT (1 << INTVAL (operands[3]));
-})
-
(define_insn "*mmx_pinsrw"
[(set (match_operand:V4HI 0 "register_operand" "=y,x,YW")
(vec_merge:V4HI
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index ef49efd..e3d55f0 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -2260,6 +2260,7 @@
|| GET_CODE (SET_SRC (elt)) != UNSPEC_VOLATILE
|| GET_MODE (SET_SRC (elt)) != V2DImode
|| XVECLEN (SET_SRC (elt), 0) != 1
+ || !REG_P (XVECEXP (SET_SRC (elt), 0, 0))
|| REGNO (XVECEXP (SET_SRC (elt), 0, 0)) != GET_SSE_REGNO (i))
return false;
}
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index c988935..906212f 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -2175,9 +2175,9 @@
(set_attr "type" "msklog")
(set_attr "prefix" "vex")])
-(define_insn "kortest<mode>"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC
+(define_insn "*kortest<mode>"
+ [(set (reg FLAGS_REG)
+ (unspec
[(match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "k")
(match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")]
UNSPEC_KORTEST))]
@@ -2187,6 +2187,30 @@
(set_attr "type" "msklog")
(set_attr "prefix" "vex")])
+(define_insn "kortest<mode>_ccc"
+ [(set (reg:CCC FLAGS_REG)
+ (unspec:CCC
+ [(match_operand:SWI1248_AVX512BWDQ 0 "register_operand")
+ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand")]
+ UNSPEC_KORTEST))]
+ "TARGET_AVX512F")
+
+(define_insn "kortest<mode>_ccz"
+ [(set (reg:CCZ FLAGS_REG)
+ (unspec:CCZ
+ [(match_operand:SWI1248_AVX512BWDQ 0 "register_operand")
+ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand")]
+ UNSPEC_KORTEST))]
+ "TARGET_AVX512F")
+
+(define_expand "kortest<mode>"
+ [(set (reg:CC FLAGS_REG)
+ (unspec:CC
+ [(match_operand:SWI1248_AVX512BWDQ 0 "register_operand")
+ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand")]
+ UNSPEC_KORTEST))]
+ "TARGET_AVX512F")
+
(define_insn "kunpckhi"
[(set (match_operand:HI 0 "register_operand" "=k")
(ior:HI
@@ -4644,29 +4668,14 @@
DONE;
})
-(define_expand "vcond<mode><mode>"
- [(set (match_operand:VHF_AVX512VL 0 "register_operand")
- (if_then_else:VHF_AVX512VL
- (match_operator 3 ""
- [(match_operand:VHF_AVX512VL 4 "vector_operand")
- (match_operand:VHF_AVX512VL 5 "vector_operand")])
- (match_operand:VHF_AVX512VL 1 "general_operand")
- (match_operand:VHF_AVX512VL 2 "general_operand")))]
- "TARGET_AVX512FP16"
-{
- bool ok = ix86_expand_fp_vcond (operands);
- gcc_assert (ok);
- DONE;
-})
-
-(define_expand "vcond<sseintvecmodelower><mode>"
- [(set (match_operand:<sseintvecmode> 0 "register_operand")
- (if_then_else:<sseintvecmode>
+(define_expand "vcond<VI2HFBF_AVX512VL:mode><VHF_AVX512VL:mode>"
+ [(set (match_operand:VI2HFBF_AVX512VL 0 "register_operand")
+ (if_then_else:VI2HFBF_AVX512VL
(match_operator 3 ""
[(match_operand:VHF_AVX512VL 4 "vector_operand")
(match_operand:VHF_AVX512VL 5 "vector_operand")])
- (match_operand:<sseintvecmode> 1 "general_operand")
- (match_operand:<sseintvecmode> 2 "general_operand")))]
+ (match_operand:VI2HFBF_AVX512VL 1 "general_operand")
+ (match_operand:VI2HFBF_AVX512VL 2 "general_operand")))]
"TARGET_AVX512FP16"
{
bool ok = ix86_expand_fp_vcond (operands);
@@ -27840,14 +27849,14 @@
(define_expand "cbranch<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:VI48_AVX 1 "register_operand")
- (match_operand:VI48_AVX 2 "nonimmediate_operand")))
+ (compare:CC (match_operand:VI48_AVX_AVX512F 1 "register_operand")
+ (match_operand:VI48_AVX_AVX512F 2 "nonimmediate_operand")))
(set (pc) (if_then_else
(match_operator 0 "bt_comparison_operator"
[(reg:CC FLAGS_REG) (const_int 0)])
(label_ref (match_operand 3))
(pc)))]
- "TARGET_SSE4_1"
+ "TARGET_SSE4_1 && (<MODE_SIZE> != 64 || !TARGET_PREFER_AVX256)"
{
ix86_expand_branch (GET_CODE (operands[0]),
operands[1], operands[2], operands[3]);
diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h
index 4f7a67c..12ec270 100644
--- a/gcc/config/i386/x86-tune-costs.h
+++ b/gcc/config/i386/x86-tune-costs.h
@@ -3393,6 +3393,122 @@ struct processor_costs lujiazui_cost = {
2, /* Small unroll factor. */
};
+/* yongfeng_cost should produce code tuned for ZHAOXIN yongfeng CPU. */
+static stringop_algs yongfeng_memcpy[2] = {
+ {libcall, {{6, unrolled_loop, true}, {256, unrolled_loop, false},
+ {-1, libcall, false}}},
+ {libcall, {{8, loop, false}, {512, unrolled_loop, false},
+ {-1, libcall, false}}}};
+static stringop_algs yongfeng_memset[2] = {
+ {libcall, {{6, loop_1_byte, false}, {128, loop, false},
+ {-1, libcall, false}}},
+ {libcall, {{2, rep_prefix_4_byte, false}, {64, loop, false},
+ {1024, vector_loop, false},
+ {-1, libcall, false}}}};
+static const
+struct processor_costs yongfeng_cost = {
+ {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 8, /* cost for loading QImode using movzbl. */
+ {8, 8, 8}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {8, 8, 8}, /* cost of storing integer registers. */
+ 2, /* cost of reg,reg fld/fst. */
+ {8, 8, 8}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode. */
+ {8, 8, 8}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode. */
+ 2, /* cost of moving MMX register. */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode. */
+ {8, 8}, /* cost of storing MMX registers
+ in SImode and DImode. */
+ 2, 3, 4, /* cost of moving XMM,YMM,ZMM register. */
+ {8, 8, 8, 10, 15}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit. */
+ {8, 8, 8, 10, 15}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit. */
+ 8, 8, /* SSE->integer and integer->SSE moves. */
+ 8, 8, /* mask->integer and integer->mask moves. */
+ {8, 8, 8}, /* cost of loading mask register
+ in QImode, HImode, SImode. */
+ {8, 8, 8}, /* cost if storing mask register
+ in QImode, HImode, SImode. */
+ 2, /* cost of moving mask register. */
+ /* End of register allocator costs. */
+ },
+
+ COSTS_N_INSNS (1), /* cost of an add instruction. */
+ COSTS_N_INSNS (1), /* cost of a lea instruction. */
+ COSTS_N_INSNS (1), /* variable shift costs. */
+ COSTS_N_INSNS (1), /* constant shift costs. */
+ {COSTS_N_INSNS (2), /* cost of starting multiply for QI. */
+ COSTS_N_INSNS (3), /* HI. */
+ COSTS_N_INSNS (2), /* SI. */
+ COSTS_N_INSNS (2), /* DI. */
+ COSTS_N_INSNS (3)}, /* other. */
+ 0, /* cost of multiply per each bit set. */
+ {COSTS_N_INSNS (8), /* cost of a divide/mod for QI. */
+ COSTS_N_INSNS (9), /* HI. */
+ COSTS_N_INSNS (8), /* SI. */
+ COSTS_N_INSNS (41), /* DI. */
+ COSTS_N_INSNS (41)}, /* other. */
+ COSTS_N_INSNS (1), /* cost of movsx. */
+ COSTS_N_INSNS (1), /* cost of movzx. */
+ 8, /* "large" insn. */
+ 17, /* MOVE_RATIO. */
+ 6, /* CLEAR_RATIO. */
+ {8, 8, 8}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {8, 8, 8}, /* cost of storing integer registers. */
+ {8, 8, 8, 12, 15}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit. */
+ {8, 8, 8, 12, 15}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit. */
+ {8, 8, 8, 12, 15}, /* cost of unaligned loads. */
+ {8, 8, 8, 12, 15}, /* cost of unaligned storess. */
+ 2, 3, 4, /* cost of moving XMM,YMM,ZMM register. */
+ 8, /* cost of moving SSE register to integer. */
+ 18, 6, /* Gather load static, per_elt. */
+ 18, 6, /* Gather store static, per_elt. */
+ 32, /* size of l1 cache. */
+ 256, /* size of l2 cache. */
+ 64, /* size of prefetch block. */
+ 12, /* number of parallel prefetches. */
+ 3, /* Branch cost. */
+ COSTS_N_INSNS (3), /* cost of FADD and FSUB insns. */
+ COSTS_N_INSNS (3), /* cost of FMUL instruction. */
+ COSTS_N_INSNS (14), /* cost of FDIV instruction. */
+ COSTS_N_INSNS (1), /* cost of FABS instruction. */
+ COSTS_N_INSNS (1), /* cost of FCHS instruction. */
+ COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
+
+ COSTS_N_INSNS (1), /* cost of cheap SSE instruction. */
+ COSTS_N_INSNS (3), /* cost of ADDSS/SD SUBSS/SD insns. */
+ COSTS_N_INSNS (3), /* cost of MULSS instruction. */
+ COSTS_N_INSNS (3), /* cost of MULSD instruction. */
+ COSTS_N_INSNS (5), /* cost of FMA SS instruction. */
+ COSTS_N_INSNS (5), /* cost of FMA SD instruction. */
+ COSTS_N_INSNS (10), /* cost of DIVSS instruction. */
+ COSTS_N_INSNS (14), /* cost of DIVSD instruction. */
+ COSTS_N_INSNS (20), /* cost of SQRTSS instruction. */
+ COSTS_N_INSNS (35), /* cost of SQRTSD instruction. */
+ 4, 4, 4, 4, /* reassoc int, fp, vec_int, vec_fp. */
+ yongfeng_memcpy,
+ yongfeng_memset,
+ COSTS_N_INSNS (3), /* cond_taken_branch_cost. */
+ COSTS_N_INSNS (1), /* cond_not_taken_branch_cost. */
+ "16:11:8", /* Loop alignment. */
+ "16:11:8", /* Jump alignment. */
+ "0:0:8", /* Label alignment. */
+ "16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
+};
+
+
/* Generic should produce code tuned for Core-i7 (and newer chips)
and btver1 (and newer chips). */
diff --git a/gcc/config/i386/x86-tune-sched.cc b/gcc/config/i386/x86-tune-sched.cc
index df4113d..4f4bf5b 100644
--- a/gcc/config/i386/x86-tune-sched.cc
+++ b/gcc/config/i386/x86-tune-sched.cc
@@ -79,6 +79,7 @@ ix86_issue_rate (void)
case PROCESSOR_CASCADELAKE:
case PROCESSOR_CANNONLAKE:
case PROCESSOR_ALDERLAKE:
+ case PROCESSOR_YONGFENG:
case PROCESSOR_GENERIC:
return 4;
@@ -384,7 +385,6 @@ ix86_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
case PROCESSOR_ATHLON:
case PROCESSOR_K8:
- case PROCESSOR_LUJIAZUI:
memory = get_attr_memory (insn);
/* Show ability of reorder buffer to hide latency of load by executing
@@ -445,6 +445,31 @@ ix86_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
}
break;
+ case PROCESSOR_YONGFENG:
+ /* Stack engine allows to execute push&pop instructions in parallel. */
+ if ((insn_type == TYPE_PUSH || insn_type == TYPE_POP)
+ && (dep_insn_type == TYPE_PUSH || dep_insn_type == TYPE_POP))
+ return 0;
+ /* FALLTHRU */
+
+ case PROCESSOR_LUJIAZUI:
+ memory = get_attr_memory (insn);
+
+ /* Show ability of reorder buffer to hide latency of load by executing
+ in parallel with previous instruction in case
+ previous instruction is not needed to compute the address. */
+ if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
+ && !ix86_agi_dependent (dep_insn, insn))
+ {
+ int loadcost = 4;
+
+ if (cost >= loadcost)
+ cost -= loadcost;
+ else
+ cost = 0;
+ }
+ break;
+
case PROCESSOR_CORE2:
case PROCESSOR_NEHALEM:
case PROCESSOR_SANDYBRIDGE:
diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def
index 53e177a..43fa9e8 100644
--- a/gcc/config/i386/x86-tune.def
+++ b/gcc/config/i386/x86-tune.def
@@ -41,7 +41,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* X86_TUNE_SCHEDULE: Enable scheduling. */
DEF_TUNE (X86_TUNE_SCHEDULE, "schedule",
m_PENT | m_LAKEMONT | m_PPRO | m_CORE_ALL | m_BONNELL | m_SILVERMONT
- | m_INTEL | m_KNL | m_KNM | m_K6_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
+ | m_INTEL | m_KNL | m_KNM | m_K6_GEODE | m_AMD_MULTIPLE | m_ZHAOXIN
| m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
| m_CORE_ATOM | m_GENERIC)
@@ -52,7 +52,7 @@ DEF_TUNE (X86_TUNE_SCHEDULE, "schedule",
DEF_TUNE (X86_TUNE_PARTIAL_REG_DEPENDENCY, "partial_reg_dependency",
m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2
| m_BONNELL | m_SILVERMONT | m_GOLDMONT | m_GOLDMONT_PLUS | m_INTEL
- | m_KNL | m_KNM | m_AMD_MULTIPLE | m_LUJIAZUI | m_TREMONT
+ | m_KNL | m_KNM | m_AMD_MULTIPLE | m_ZHAOXIN | m_TREMONT
| m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: This knob promotes all store
@@ -63,7 +63,7 @@ DEF_TUNE (X86_TUNE_PARTIAL_REG_DEPENDENCY, "partial_reg_dependency",
that can be partly masked by careful scheduling of moves. */
DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY, "sse_partial_reg_dependency",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_AMDFAM10
- | m_BDVER | m_ZNVER | m_LUJIAZUI | m_TREMONT | m_CORE_HYBRID
+ | m_BDVER | m_ZNVER | m_ZHAOXIN | m_TREMONT | m_CORE_HYBRID
| m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY: This knob avoids
@@ -72,7 +72,7 @@ DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY, "sse_partial_reg_dependency",
DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY,
"sse_partial_reg_fp_converts_dependency",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_AMDFAM10
- | m_BDVER | m_ZNVER | m_LUJIAZUI | m_CORE_HYBRID | m_CORE_ATOM
+ | m_BDVER | m_ZNVER | m_ZHAOXIN | m_CORE_HYBRID | m_CORE_ATOM
| m_GENERIC)
/* X86_TUNE_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY: This knob avoids partial
@@ -80,7 +80,7 @@ DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY,
DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY,
"sse_partial_reg_converts_dependency",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_AMDFAM10
- | m_BDVER | m_ZNVER | m_LUJIAZUI | m_CORE_HYBRID | m_CORE_ATOM
+ | m_BDVER | m_ZNVER | m_ZHAOXIN | m_CORE_HYBRID | m_CORE_ATOM
| m_GENERIC)
/* X86_TUNE_DEST_FALSE_DEP_FOR_GLC: This knob inserts zero-idiom before
@@ -113,7 +113,7 @@ DEF_TUNE (X86_TUNE_PARTIAL_FLAG_REG_STALL, "partial_flag_reg_stall",
DEF_TUNE (X86_TUNE_MOVX, "movx",
m_PPRO | m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE
| m_BONNELL | m_SILVERMONT | m_GOLDMONT | m_KNL | m_KNM | m_INTEL
- | m_GOLDMONT_PLUS | m_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
+ | m_GOLDMONT_PLUS | m_GEODE | m_AMD_MULTIPLE | m_ZHAOXIN
| m_CORE_AVX2 | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_MEMORY_MISMATCH_STALL: Avoid partial stores that are followed by
@@ -121,31 +121,31 @@ DEF_TUNE (X86_TUNE_MOVX, "movx",
DEF_TUNE (X86_TUNE_MEMORY_MISMATCH_STALL, "memory_mismatch_stall",
m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT | m_INTEL
| m_KNL | m_KNM | m_GOLDMONT | m_GOLDMONT_PLUS | m_AMD_MULTIPLE
- | m_LUJIAZUI | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
+ | m_ZHAOXIN | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_FUSE_CMP_AND_BRANCH_32: Fuse compare with a subsequent
conditional jump instruction for 32 bit TARGET. */
DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_32, "fuse_cmp_and_branch_32",
- m_CORE_ALL | m_BDVER | m_ZNVER | m_LUJIAZUI | m_GENERIC)
+ m_CORE_ALL | m_BDVER | m_ZNVER | m_ZHAOXIN | m_GENERIC)
/* X86_TUNE_FUSE_CMP_AND_BRANCH_64: Fuse compare with a subsequent
conditional jump instruction for TARGET_64BIT. */
DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_64, "fuse_cmp_and_branch_64",
m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_BDVER
- | m_ZNVER | m_LUJIAZUI | m_GENERIC)
+ | m_ZNVER | m_ZHAOXIN | m_GENERIC)
/* X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS: Fuse compare with a
subsequent conditional jump instruction when the condition jump
check sign flag (SF) or overflow flag (OF). */
DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS, "fuse_cmp_and_branch_soflags",
m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_BDVER
- | m_ZNVER | m_LUJIAZUI | m_GENERIC)
+ | m_ZNVER | m_ZHAOXIN | m_GENERIC)
/* X86_TUNE_FUSE_ALU_AND_BRANCH: Fuse alu with a subsequent conditional
jump instruction when the alu instruction produces the CCFLAG consumed by
the conditional jump instruction. */
DEF_TUNE (X86_TUNE_FUSE_ALU_AND_BRANCH, "fuse_alu_and_branch",
- m_SANDYBRIDGE | m_CORE_AVX2 | m_LUJIAZUI | m_GENERIC)
+ m_SANDYBRIDGE | m_CORE_AVX2 | m_ZHAOXIN | m_GENERIC)
/*****************************************************************************/
@@ -162,7 +162,7 @@ DEF_TUNE (X86_TUNE_FUSE_ALU_AND_BRANCH, "fuse_alu_and_branch",
DEF_TUNE (X86_TUNE_ACCUMULATE_OUTGOING_ARGS, "accumulate_outgoing_args",
m_PPRO | m_P4_NOCONA | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL
- | m_GOLDMONT | m_GOLDMONT_PLUS | m_ATHLON_K8 | m_LUJIAZUI)
+ | m_GOLDMONT | m_GOLDMONT_PLUS | m_ATHLON_K8 | m_ZHAOXIN)
/* X86_TUNE_PROLOGUE_USING_MOVE: Do not use push/pop in prologues that are
considered on critical path. */
@@ -176,7 +176,7 @@ DEF_TUNE (X86_TUNE_EPILOGUE_USING_MOVE, "epilogue_using_move",
/* X86_TUNE_USE_LEAVE: Use "leave" instruction in epilogues where it fits. */
DEF_TUNE (X86_TUNE_USE_LEAVE, "use_leave",
- m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
+ m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_ZHAOXIN
| m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_PUSH_MEMORY: Enable generation of "push mem" instructions.
@@ -184,7 +184,7 @@ DEF_TUNE (X86_TUNE_USE_LEAVE, "use_leave",
and push instructions. */
DEF_TUNE (X86_TUNE_PUSH_MEMORY, "push_memory",
m_386 | m_P4_NOCONA | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE
- | m_LUJIAZUI | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
+ | m_ZHAOXIN | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SINGLE_PUSH: Enable if single push insn is preferred
over esp subtraction. */
@@ -239,7 +239,7 @@ DEF_TUNE (X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL, "software_prefetching_benefi
/* X86_TUNE_LCP_STALL: Avoid an expensive length-changing prefix stall
on 16-bit immediate moves into memory on Core2 and Corei7. */
-DEF_TUNE (X86_TUNE_LCP_STALL, "lcp_stall", m_CORE_ALL | m_LUJIAZUI | m_GENERIC)
+DEF_TUNE (X86_TUNE_LCP_STALL, "lcp_stall", m_CORE_ALL | m_ZHAOXIN | m_GENERIC)
/* X86_TUNE_READ_MODIFY: Enable use of read-modify instructions such
as "add mem, reg". */
@@ -255,20 +255,20 @@ DEF_TUNE (X86_TUNE_USE_INCDEC, "use_incdec",
~(m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE
| m_BONNELL | m_SILVERMONT | m_INTEL | m_KNL | m_KNM | m_GOLDMONT
| m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM
- | m_LUJIAZUI | m_GENERIC))
+ | m_ZHAOXIN | m_GENERIC))
/* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
for DFmode copies */
DEF_TUNE (X86_TUNE_INTEGER_DFMODE_MOVES, "integer_dfmode_moves",
~(m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT
- | m_KNL | m_KNM | m_INTEL | m_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
+ | m_KNL | m_KNM | m_INTEL | m_GEODE | m_AMD_MULTIPLE | m_ZHAOXIN
| m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
| m_CORE_ATOM | m_GENERIC))
/* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
will impact LEA instruction selection. */
DEF_TUNE (X86_TUNE_OPT_AGU, "opt_agu", m_BONNELL | m_SILVERMONT | m_KNL
- | m_KNM | m_GOLDMONT | m_GOLDMONT_PLUS | m_INTEL | m_LUJIAZUI)
+ | m_KNM | m_GOLDMONT | m_GOLDMONT_PLUS | m_INTEL | m_ZHAOXIN)
/* X86_TUNE_AVOID_LEA_FOR_ADDR: Avoid lea for address computation. */
DEF_TUNE (X86_TUNE_AVOID_LEA_FOR_ADDR, "avoid_lea_for_addr",
@@ -302,7 +302,7 @@ DEF_TUNE (X86_TUNE_SINGLE_STRINGOP, "single_stringop", m_386 | m_P4_NOCONA)
DEF_TUNE (X86_TUNE_PREFER_KNOWN_REP_MOVSB_STOSB,
"prefer_known_rep_movsb_stosb",
m_SKYLAKE | m_CORE_HYBRID | m_CORE_ATOM | m_TREMONT | m_CORE_AVX512
- | m_LUJIAZUI)
+ | m_ZHAOXIN)
/* X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES: Enable generation of
compact prologues and epilogues by issuing a misaligned moves. This
@@ -311,14 +311,14 @@ DEF_TUNE (X86_TUNE_PREFER_KNOWN_REP_MOVSB_STOSB,
FIXME: This may actualy be a win on more targets than listed here. */
DEF_TUNE (X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES,
"misaligned_move_string_pro_epilogues",
- m_386 | m_486 | m_CORE_ALL | m_AMD_MULTIPLE | m_LUJIAZUI | m_TREMONT
+ m_386 | m_486 | m_CORE_ALL | m_AMD_MULTIPLE | m_ZHAOXIN | m_TREMONT
| m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_USE_SAHF: Controls use of SAHF. */
DEF_TUNE (X86_TUNE_USE_SAHF, "use_sahf",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT
| m_KNL | m_KNM | m_INTEL | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER
- | m_BTVER | m_ZNVER | m_LUJIAZUI | m_GOLDMONT | m_GOLDMONT_PLUS
+ | m_BTVER | m_ZNVER | m_ZHAOXIN | m_GOLDMONT | m_GOLDMONT_PLUS
| m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_USE_CLTD: Controls use of CLTD and CTQO instructions. */
@@ -329,7 +329,7 @@ DEF_TUNE (X86_TUNE_USE_CLTD, "use_cltd",
/* X86_TUNE_USE_BT: Enable use of BT (bit test) instructions. */
DEF_TUNE (X86_TUNE_USE_BT, "use_bt",
m_CORE_ALL | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL
- | m_LAKEMONT | m_AMD_MULTIPLE | m_LUJIAZUI | m_GOLDMONT
+ | m_LAKEMONT | m_AMD_MULTIPLE | m_ZHAOXIN | m_GOLDMONT
| m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM
| m_GENERIC)
@@ -338,7 +338,7 @@ DEF_TUNE (X86_TUNE_USE_BT, "use_bt",
DEF_TUNE (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI, "avoid_false_dep_for_bmi",
m_SANDYBRIDGE | m_HASWELL | m_SKYLAKE | m_SKYLAKE_AVX512
| m_CANNONLAKE | m_CASCADELAKE | m_COOPERLAKE
- | m_LUJIAZUI | m_GENERIC)
+ | m_ZHAOXIN | m_GENERIC)
/* X86_TUNE_ADJUST_UNROLL: This enables adjusting the unroll factor based
on hardware capabilities. Bdver3 hardware has a loop buffer which makes
@@ -351,11 +351,11 @@ DEF_TUNE (X86_TUNE_ADJUST_UNROLL, "adjust_unroll_factor", m_BDVER3 | m_BDVER4)
DEF_TUNE (X86_TUNE_ONE_IF_CONV_INSN, "one_if_conv_insn",
m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_CORE_ALL | m_GOLDMONT
| m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM
- | m_LUJIAZUI | m_GENERIC)
+ | m_ZHAOXIN | m_GENERIC)
/* X86_TUNE_AVOID_MFENCE: Use lock prefixed instructions instead of mfence. */
DEF_TUNE (X86_TUNE_AVOID_MFENCE, "avoid_mfence",
- m_CORE_ALL | m_BDVER | m_ZNVER | m_LUJIAZUI | m_TREMONT | m_CORE_HYBRID
+ m_CORE_ALL | m_BDVER | m_ZNVER | m_ZHAOXIN | m_TREMONT | m_CORE_HYBRID
| m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_EXPAND_ABS: This enables a new abs pattern by
@@ -363,7 +363,7 @@ DEF_TUNE (X86_TUNE_AVOID_MFENCE, "avoid_mfence",
(signed) x >> (W-1)) instead of cmove or SSE max/abs instructions. */
DEF_TUNE (X86_TUNE_EXPAND_ABS, "expand_abs",
m_CORE_ALL | m_SILVERMONT | m_KNL | m_KNM | m_GOLDMONT
- | m_GOLDMONT_PLUS | m_LUJIAZUI)
+ | m_GOLDMONT_PLUS | m_ZHAOXIN)
/*****************************************************************************/
/* 387 instruction selection tuning */
@@ -380,16 +380,16 @@ DEF_TUNE (X86_TUNE_USE_HIMODE_FIOP, "use_himode_fiop",
DEF_TUNE (X86_TUNE_USE_SIMODE_FIOP, "use_simode_fiop",
~(m_PENT | m_LAKEMONT | m_PPRO | m_CORE_ALL | m_BONNELL
| m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_AMD_MULTIPLE
- | m_LUJIAZUI | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT
+ | m_ZHAOXIN | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT
| m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC))
/* X86_TUNE_USE_FFREEP: Use freep instruction instead of fstp. */
-DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE | m_LUJIAZUI)
+DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE | m_ZHAOXIN)
/* X86_TUNE_EXT_80387_CONSTANTS: Use fancy 80387 constants, such as PI. */
DEF_TUNE (X86_TUNE_EXT_80387_CONSTANTS, "ext_80387_constants",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT
- | m_KNL | m_KNM | m_INTEL | m_K6_GEODE | m_ATHLON_K8 | m_LUJIAZUI
+ | m_KNL | m_KNM | m_INTEL | m_K6_GEODE | m_ATHLON_K8 | m_ZHAOXIN
| m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
| m_CORE_ATOM | m_GENERIC)
@@ -407,7 +407,7 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill",
DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal",
m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
| m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
- | m_CORE_ATOM | m_AMDFAM10 | m_BDVER | m_BTVER | m_ZNVER | m_LUJIAZUI
+ | m_CORE_ATOM | m_AMDFAM10 | m_BDVER | m_BTVER | m_ZNVER | m_ZHAOXIN
| m_GENERIC)
/* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL: Use movups for misaligned stores
@@ -415,7 +415,7 @@ DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal",
DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal",
m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
| m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
- | m_CORE_ATOM | m_BDVER | m_ZNVER | m_LUJIAZUI | m_GENERIC)
+ | m_CORE_ATOM | m_BDVER | m_ZNVER | m_ZHAOXIN | m_GENERIC)
/* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL: Use packed single
precision 128bit instructions instead of double where possible. */
@@ -424,14 +424,14 @@ DEF_TUNE (X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL, "sse_packed_single_insn_optim
/* X86_TUNE_SSE_TYPELESS_STORES: Always movaps/movups for 128bit stores. */
DEF_TUNE (X86_TUNE_SSE_TYPELESS_STORES, "sse_typeless_stores",
- m_AMD_MULTIPLE | m_LUJIAZUI | m_CORE_ALL | m_TREMONT | m_CORE_HYBRID
+ m_AMD_MULTIPLE | m_ZHAOXIN | m_CORE_ALL | m_TREMONT | m_CORE_HYBRID
| m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SSE_LOAD0_BY_PXOR: Always use pxor to load0 as opposed to
xorps/xorpd and other variants. */
DEF_TUNE (X86_TUNE_SSE_LOAD0_BY_PXOR, "sse_load0_by_pxor",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BDVER | m_BTVER | m_ZNVER
- | m_LUJIAZUI | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
+ | m_ZHAOXIN | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_INTER_UNIT_MOVES_TO_VEC: Enable moves in from integer
to SSE registers. If disabled, the moves will be done by storing
@@ -484,7 +484,7 @@ DEF_TUNE (X86_TUNE_AVOID_4BYTE_PREFIXES, "avoid_4byte_prefixes",
elements. */
DEF_TUNE (X86_TUNE_USE_GATHER_2PARTS, "use_gather_2parts",
~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ZNVER4 | m_CORE_HYBRID
- | m_CORE_ATOM | m_GENERIC | m_GDS))
+ | m_YONGFENG | m_CORE_ATOM | m_GENERIC | m_GDS))
/* X86_TUNE_USE_SCATTER_2PARTS: Use scater instructions for vectors with 2
elements. */
@@ -495,7 +495,7 @@ DEF_TUNE (X86_TUNE_USE_SCATTER_2PARTS, "use_scatter_2parts",
elements. */
DEF_TUNE (X86_TUNE_USE_GATHER_4PARTS, "use_gather_4parts",
~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ZNVER4 | m_CORE_HYBRID
- | m_CORE_ATOM | m_GENERIC | m_GDS))
+ | m_YONGFENG | m_CORE_ATOM | m_GENERIC | m_GDS))
/* X86_TUNE_USE_SCATTER_4PARTS: Use scater instructions for vectors with 4
elements. */
@@ -506,7 +506,7 @@ DEF_TUNE (X86_TUNE_USE_SCATTER_4PARTS, "use_scatter_4parts",
elements. */
DEF_TUNE (X86_TUNE_USE_GATHER_8PARTS, "use_gather_8parts",
~(m_ZNVER1 | m_ZNVER2 | m_ZNVER4 | m_CORE_HYBRID | m_CORE_ATOM
- | m_GENERIC | m_GDS))
+ | m_YONGFENG | m_GENERIC | m_GDS))
/* X86_TUNE_USE_SCATTER: Use scater instructions for vectors with 8 or more
elements. */
@@ -515,7 +515,8 @@ DEF_TUNE (X86_TUNE_USE_SCATTER_8PARTS, "use_scatter_8parts",
/* X86_TUNE_AVOID_128FMA_CHAINS: Avoid creating loops with tight 128bit or
smaller FMA chain. */
-DEF_TUNE (X86_TUNE_AVOID_128FMA_CHAINS, "avoid_fma_chains", m_ZNVER1 | m_ZNVER2 | m_ZNVER3)
+DEF_TUNE (X86_TUNE_AVOID_128FMA_CHAINS, "avoid_fma_chains", m_ZNVER1 | m_ZNVER2 | m_ZNVER3
+ | m_YONGFENG)
/* X86_TUNE_AVOID_256FMA_CHAINS: Avoid creating loops with tight 256bit or
smaller FMA chain. */
@@ -647,6 +648,14 @@ DEF_TUNE (X86_TUNE_NOT_UNPAIRABLE, "not_unpairable", m_PENT | m_LAKEMONT)
and can happen in caller/callee saving sequences. */
DEF_TUNE (X86_TUNE_PARTIAL_REG_STALL, "partial_reg_stall", m_PPRO)
+/* X86_TUNE_PARTIAL_MEMORY_READ_STALL: Reading (possible unaligned) part of
+ memory location after a large write to the same address causes
+ store-to-load forwarding stall. */
+DEF_TUNE (X86_TUNE_PARTIAL_MEMORY_READ_STALL, "partial_memory_read_stall",
+ m_386 | m_486 | m_PENT | m_LAKEMONT | m_PPRO | m_P4_NOCONA | m_CORE2
+ | m_SILVERMONT | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT
+ | m_K6_GEODE | m_ATHLON_K8 | m_AMDFAM10)
+
/* X86_TUNE_PROMOTE_QIMODE: When it is cheap, turn 8bit arithmetic to
corresponding 32bit arithmetic. */
DEF_TUNE (X86_TUNE_PROMOTE_QIMODE, "promote_qimode",
diff --git a/gcc/config/i386/yongfeng.md b/gcc/config/i386/yongfeng.md
new file mode 100644
index 0000000..a225b40
--- /dev/null
+++ b/gcc/config/i386/yongfeng.md
@@ -0,0 +1,848 @@
+;; Copyright (C) 2012-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/>.
+;;
+
+;; ZHAOXIN yongfeng processor Scheduling
+;; Modeling automatons for yongfeng decoders, integer execution pipes,
+;; FP execution pipes, AGU pipes, and dividers.
+(define_automaton "yongfeng_decoder,yongfeng_ieu,yongfeng_fp,yongfeng_agu,yongfeng_idiv,yongfeng_fdiv")
+
+;; The rules for the decoder are simple:
+;; - an instruction with 1 uop can be decoded by any of the four
+;; decoders in one cycle.
+;; - an instruction with 2 uops can be decoded by decoder 0 or decoder 1
+;; or decoder 2 but still in only one cycle.
+;; - a complex (microcode) instruction can only be decoded by
+;; decoder 0, and this takes an unspecified number of cycles.
+;;
+;; The goal is to schedule such that we have a few-one-two uops sequence
+;; in each cycle, to decode as many instructions per cycle as possible.
+(define_cpu_unit "yf_decoder0" "yongfeng_decoder")
+(define_cpu_unit "yf_decoder1" "yongfeng_decoder")
+(define_cpu_unit "yf_decoder2" "yongfeng_decoder")
+(define_cpu_unit "yf_decoder3" "yongfeng_decoder")
+
+;; We first wish to find an instruction for yf_decoder0, so exclude
+;; other decoders from being reserved until yf_decoder0 is
+;; reserved
+(presence_set "yf_decoder1" "yf_decoder0")
+(presence_set "yf_decoder2" "yf_decoder0")
+(presence_set "yf_decoder3" "yf_decoder0")
+
+;; Most instructions can be decoded on any of the three decoders.
+(define_reservation "yf_decodern" "yf_decoder0|yf_decoder1|yf_decoder2|yf_decoder3")
+(define_reservation "yf_decoder012" "yf_decoder0|yf_decoder1|yf_decoder2")
+
+;; The out-of-order core has ten pipelines. Port 0,1,2,3 are integer execution
+;; pipelines, port 4, 5 are responsible for address calculation, load and store,
+;; port 6,7,8,9 are FP pipelines.
+(define_cpu_unit "yf_p0,yf_p1,yf_p2,yf_p3" "yongfeng_ieu")
+(define_cpu_unit "yf_p4,yf_p5" "yongfeng_agu")
+(define_cpu_unit "yf_p6,yf_p7,yf_p8,yf_p9" "yongfeng_fp")
+
+(define_cpu_unit "yf_idiv" "yongfeng_idiv")
+(define_cpu_unit "yf_fdiv" "yongfeng_fdiv")
+
+(define_reservation "yf_ieu" "yf_p0|yf_p1|yf_p2|yf_p3")
+(define_reservation "yf_p01" "yf_p0|yf_p1")
+(define_reservation "yf_agu" "yf_p4|yf_p5")
+(define_reservation "yf_feu" "yf_p6|yf_p7|yf_p8|yf_p9")
+
+;; Only the irregular instructions have to be modeled here.
+
+;; Complex instruction.
+(define_insn_reservation "yongfeng_complex_insn" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (eq_attr "type" "other,multi,str"))
+ "yf_decoder0")
+
+;; Call instruction.
+(define_insn_reservation "yongfeng_call" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (eq_attr "type" "call,callv"))
+ "yf_decoder012,yf_agu,yf_ieu*3")
+;; Push and pop.
+(define_insn_reservation "yongfeng_push_reg" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "push")))
+ "yf_decodern,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_push_mem" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "both")
+ (eq_attr "type" "push")))
+ "yf_decoder012,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_pop_reg" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "pop")))
+ "yf_decoder012,yf_p01,yf_agu")
+
+(define_insn_reservation "yongfeng_pop_mem" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "both")
+ (eq_attr "type" "pop")))
+ "yf_decoder0,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_leave" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (eq_attr "type" "leave"))
+ "yf_decoder0,yf_agu,yf_p01*3")
+
+;; MOV - integer moves.
+(define_insn_reservation "yongfeng_imov" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "imov,imovx")))
+ "yf_decodern,yf_ieu")
+
+(define_insn_reservation "yongfeng_imov_load" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "imov")))
+ "yf_decodern,yf_agu")
+
+(define_insn_reservation "yongfeng_imovx_load" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "imovx")))
+ "yf_decoder012,yf_agu,yf_ieu|yf_ieu")
+
+(define_insn_reservation "yongfeng_imov_store" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "imov")))
+ "yf_decodern,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_int_insn" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none,unknown")
+ (eq_attr "type" "alu,alu1,icmov,icmp,test,lea,ishift1,rotate,rotate1,setcc,incdec")))
+ "yf_decodern,yf_ieu")
+
+(define_insn_reservation "yongfeng_int_insn_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "alu,alu1,icmov,icmp,test,ishift1,rotate,rotate1,setcc")))
+ "yf_decoder012,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_int_insn_store" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "alu,alu1,icmp,test,ishift1,rotate,rotate1,setcc")))
+ "yf_decoder012,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_int_insn_both" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "both")
+ (eq_attr "type" "alu,alu1,icmp,test,ishift1,rotate,rotate1,setcc,incdec")))
+ "yf_decoder012,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_shift_HI" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none,unknown")
+ (and (eq_attr "mode" "HI")
+ (eq_attr "type" "ishift"))))
+ "yf_decoder0,yf_ieu")
+
+(define_insn_reservation "yongfeng_shift_SIDI" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none,unknown")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "type" "ishift"))))
+ "yf_decoder0,yf_ieu")
+
+(define_insn_reservation "yongfeng_shift_HI_mem" 9
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "HI")
+ (eq_attr "type" "ishift"))))
+ "yf_decoder0,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_shift_SIDI_mem" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "type" "ishift"))))
+ "yf_decoder0,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_negnot_QIHI" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none,unknown")
+ (and (eq_attr "mode" "QI,HI")
+ (eq_attr "type" "negnot"))))
+ "yf_decoder012,yf_ieu|yf_ieu")
+
+(define_insn_reservation "yongfeng_negnot_SIDI" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none,unknown")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "type" "negnot"))))
+ "yf_decodern,yf_ieu")
+
+(define_insn_reservation "yongfeng_negnot_QIHI_mem" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "QI,HI")
+ (eq_attr "type" "negnot"))))
+ "yf_decoder012,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_negnot_SIDI_mem" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "type" "negnot"))))
+ "yf_decoder012,yf_agu,yf_ieu")
+
+;; branch instruction
+(define_insn_reservation "yongfeng_branch" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ibr")))
+ "yf_decodern,yf_p2*3")
+
+(define_insn_reservation "yongfeng_branch_mem" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (eq_attr "type" "ibr")))
+ "yf_decodern,yf_agu,yf_p2")
+
+;; Integer Multiplication instructions.
+
+(define_insn_reservation "yongfeng_imul_QI" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "QI")
+ (eq_attr "type" "imul"))))
+ "yf_decodern,yf_ieu|yf_ieu")
+
+(define_insn_reservation "yongfeng_imul_HI" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "HI")
+ (eq_attr "type" "imul"))))
+ "yf_decoder0,yf_ieu")
+
+(define_insn_reservation "yongfeng_imul_SIDI" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "type" "imul"))))
+ "yf_decoder0,yf_ieu|yf_ieu")
+
+(define_insn_reservation "yongfeng_imul_QI_mem" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "QI")
+ (eq_attr "type" "imul"))))
+ "yf_decoder012,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_imul_SIDI_mem" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "type" "imul"))))
+ "yf_decoder0,yf_agu,yf_ieu")
+
+(define_insn_reservation "yongfeng_imul_HI_mem" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "HI")
+ (eq_attr "type" "imul"))))
+ "yf_decoder0,yf_agu,yf_ieu")
+
+;; Integer Division instructions.
+
+(define_insn_reservation "yongfeng_idiv_DI" 41
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "DI")
+ (eq_attr "type" "idiv"))))
+ "yf_decoder0,yf_ieu,yf_feu,yf_idiv*41")
+
+(define_insn_reservation "yongfeng_idiv_HI" 9
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "HI")
+ (eq_attr "type" "idiv"))))
+ "yf_decoder0,yf_ieu,yf_feu,yf_idiv*3")
+
+(define_insn_reservation "yongfeng_idiv_QISI" 8
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "QI,SI")
+ (eq_attr "type" "idiv"))))
+ "yf_decoder0,yf_ieu,yf_feu,yf_idiv*3")
+
+
+(define_insn_reservation "yongfeng_idiv_mem_DI" 45
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (and (eq_attr "mode" "DI")
+ (eq_attr "type" "idiv"))))
+ "yf_decoder0,yf_agu,yf_ieu,yf_feu,yf_idiv*41")
+
+(define_insn_reservation "yongfeng_idiv_HI_mem" 13
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (and (eq_attr "mode" "HI")
+ (eq_attr "type" "idiv"))))
+ "yf_decoder0,yf_agu,yf_ieu,yf_feu,yf_idiv*3")
+
+
+(define_insn_reservation "yongfeng_idiv_QISI_mem" 12
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (and (eq_attr "mode" "QI,SI")
+ (eq_attr "type" "idiv"))))
+ "yf_decoder0,yf_agu,yf_ieu,yf_feu,yf_idiv*3")
+
+;; MMX,SSE,AVX,AVX2 instructions
+;; sse moves
+
+(define_insn_reservation "yongfeng_sse_mov" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssemov"))))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_mov_store" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "ssemov"))))
+ "yf_decodern,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_mov_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssemov"))))
+ "yf_decodern,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_mov" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssemov"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_mov_store" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "ssemov"))))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_mov_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssemov"))))
+ "yf_decoder012,yf_agu,yf_feu")
+
+;;sse general instructions
+(define_insn_reservation "yongfeng_sse_insns" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseadd,sseadd1,ssemul,ssecmp"))))
+ "yf_decodern,yf_feu|yf_feu")
+
+(define_insn_reservation "yongfeng_sse_insns_load" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseadd,sseadd1,ssemul,ssecmp"))))
+ "yf_decodern,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_insns" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseadd,sseadd1,ssemul,ssecmp"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_insns_load" 8
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseadd,sseadd1,ssemul,ssecmp"))))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_iadd" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DI,TI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseiadd"))))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_iadd_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DI,TI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseiadd"))))
+ "yf_decodern,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_iadd" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "OI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseiadd"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_iadd_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "OI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseiadd"))))
+ "yf_decoder0,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_iadd1" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseiadd1")))
+ "yf_decoder0,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_iadd1_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseiadd1")))
+ "yf_decoder0,yf_agu,yf_feu")
+
+;;sse imul
+(define_insn_reservation "yongfeng_sse_imul" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DI,TI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseimul"))))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_imul_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DI,TI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseimul"))))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_imul" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "OI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseimul"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_imul_load" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "OI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseimul"))))
+ "yf_decoder0,yf_agu,yf_feu")
+
+;; sse FMA
+(define_insn_reservation "yongfeng_sse_fma" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,DF,V4SF,V2DF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssemuladd"))))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_fma_load" 9
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,DF,V4SF,V2DF")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssemuladd"))))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_fma" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssemuladd"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_fma_load" 10
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssemuladd"))))
+ "yf_decoder0,yf_agu,yf_feu")
+;; sse div
+(define_insn_reservation "yongfeng_ssediv_s" 10
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,V4SF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssediv"))))
+ "yf_decodern,yf_fdiv*2")
+
+(define_insn_reservation "yongfeng_ssediv_s_load" 14
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SF,V4SF")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssediv"))))
+ "yf_decodern,yf_agu,yf_fdiv*2")
+
+(define_insn_reservation "yongfeng_ssediv_d" 14
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DF,V2DF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssediv"))))
+ "yf_decodern,yf_fdiv*3")
+
+(define_insn_reservation "yongfeng_ssediv_d_load" 18
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DF,V2DF")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssediv"))))
+ "yf_decodern,yf_agu,yf_fdiv*3")
+
+(define_insn_reservation "yongfeng_ssediv_avx256_s" 10
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssediv"))))
+ "yf_decoder012,yf_fdiv*10")
+
+(define_insn_reservation "yongfeng_ssediv_avx256_s_load" 15
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssediv"))))
+ "yf_decoder012,yf_agu,yf_fdiv*10")
+
+(define_insn_reservation "yongfeng_ssediv_avx256_d" 14
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V4DF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssediv"))))
+ "yf_decoder012,yf_fdiv*14")
+
+(define_insn_reservation "yongfeng_ssediv_avx256_d_load" 19
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V4DF")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssediv"))))
+ "yf_decoder012,yf_fdiv*14")
+
+;;sse logical and shuffle instructions
+(define_insn_reservation "yongfeng_avx256_log_shuf" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_log_shuf_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_log_shuf" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_log_shuf_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")))
+ "yf_decodern,yf_agu,yf_feu")
+;;sse shift
+
+(define_insn_reservation "yongfeng_avx256_shift" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseishft,sseishft1"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_avx256_shift_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseishft,sseishft1"))))
+ "yf_decoder0,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_shift" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseishft,sseishft1")))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_shift_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseishft,sseishft1")))
+ "yf_decodern,yf_agu,yf_feu")
+;;sse comi
+(define_insn_reservation "yongfeng_avx256_test" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "prefix_extra" "1")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssecomi")))))
+ "yf_decoder012,yf_ieu*3")
+
+(define_insn_reservation "yongfeng_avx256_test_load" 9
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V8SF,V4DF,OI")
+ (and (eq_attr "prefix_extra" "1")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssecomi")))))
+ "yf_decoder012,yf_agu,yf_ieu,yf_p6*3")
+
+(define_insn_reservation "yongfeng_sse_test" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "prefix_extra" "1")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssecomi"))))
+ "yf_decodern,yf_feu|yf_feu")
+
+(define_insn_reservation "yongfeng_sse_test_load" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "prefix_extra" "1")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssecomi"))))
+ "yf_decodern,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_comi" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "prefix_extra" "0")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssecomi"))))
+ "yf_decodern,yf_feu|yf_feu")
+
+(define_insn_reservation "yongfeng_sse_comi_load" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "prefix_extra" "0")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssecomi"))))
+ "yf_decodern,yf_agu,yf_feu")
+
+;;sse conversion
+(define_insn_reservation "yongfeng_avx_cvt_ps" 4
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V4SF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssecvt"))))
+ "yf_decoder0,yf_feu")
+
+(define_insn_reservation "yongfeng_avx_cvt_ps_load" 8
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V4SF")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssecvt"))))
+ "yf_decoder0,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_avx_cvt_pd" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V4DF")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssecvt"))))
+ "yf_decoder0,yf_feu")
+
+(define_insn_reservation "yongfeng_avx_cvt_pd_load" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "V4DF")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssecvt"))))
+ "yf_decoder0,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_cvt" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "ssecvt")))
+ "yf_decodern,yf_feu|yf_feu")
+
+(define_insn_reservation "yongfeng_sse_cvt_load" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "ssecvt")))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_icvt" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseicvt")))
+ "yf_decodern,yf_feu|yf_feu")
+
+(define_insn_reservation "yongfeng_sse_icvt_load" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseicvt")))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_icvt_SI" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseicvt"))))
+ "yf_decoder012,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_icvt_SI_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "SI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseicvt"))))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_icvt_DI" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DI")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "sseicvt"))))
+ "yf_decoder0,yf_feu")
+
+(define_insn_reservation "yongfeng_sse_icvt_DI_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "mode" "DI")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "sseicvt"))))
+ "yf_decoder0,yf_agu,yf_feu")
+;; MMX
+(define_insn_reservation "yongfeng_mmx_move" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "mmxmov")))
+ "yf_decodern,yf_p0")
+
+(define_insn_reservation "yongfeng_mmx_move_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "mmxmov")))
+ "yf_decodern,yf_agu,yf_p0")
+
+(define_insn_reservation "yongfeng_mmx_move_store" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "mmxmov")))
+ "yf_decodern,yf_agu,yf_p0")
+
+(define_insn_reservation "yongfeng_mmx_mul" 2
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "mmxmul")))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_mmx_mul_load" 6
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "mmxmul")))
+ "yf_decoder012,yf_agu,yf_feu")
+
+;; MMX general instructions
+(define_insn_reservation "yongfeng_mmx_insns" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "mmxadd,mmxshft,mmxcmp,mmx,mmxcvt")))
+ "yf_decodern,yf_feu|yf_feu")
+
+(define_insn_reservation "yongfeng_mmx_insns_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "mmxadd,mmxshft,mmxcmp,mmx,mmxcvt")))
+ "yf_decodern,yf_agu,yf_feu|yf_feu")
+
+(define_insn_reservation "yongfeng_mmx_insns_store" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "mmxadd,mmxshft,mmxcmp,mmx,mmxcvt")))
+ "yf_decodern,yf_agu,yf_feu")
+
+;; x87 floating point operations.
+
+(define_insn_reservation "yongfeng_fxch" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (eq_attr "type" "fxch"))
+ "yf_decodern,yf_p0|yf_p1")
+
+(define_insn_reservation "yongfeng_fcmov_sgn" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (eq_attr "type" "fcmov,fsgn"))
+ "yf_decodern,yf_p0|yf_p1,yf_feu")
+
+(define_insn_reservation "yongfeng_fcmp" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "fcmp")))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_fcmp_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "fcmp")))
+ "yf_decodern,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_fmov" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "fmov")))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_fmov_store" 1
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "fmov")))
+ "yf_decoder0,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_fmov_load" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "fmov")))
+ "yf_decoder0,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_fistp" 5
+ (and (eq_attr "cpu" "yongfeng")
+ (eq_attr "type" "fistp,fisttp"))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_fop_mul" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none,unknown")
+ (eq_attr "type" "fop,fmul")))
+ "yf_decodern,yf_feu")
+
+(define_insn_reservation "yongfeng_fop_mul_load" 7
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load,both")
+ (eq_attr "type" "fop,fmul")))
+ "yf_decoder012,yf_agu,yf_feu")
+
+(define_insn_reservation "yf_fop_store" 3
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "store")
+ (eq_attr "type" "fop")))
+ "yf_decodern,yf_agu,yf_feu")
+
+(define_insn_reservation "yongfeng_fdiv_fpspc" 14
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "none")
+ (eq_attr "type" "fdiv,fpspc")))
+ "yf_decodern,yf_fdiv*7")
+
+(define_insn_reservation "yongfeng_fdiv_fpspc_load" 18
+ (and (eq_attr "cpu" "yongfeng")
+ (and (eq_attr "memory" "load")
+ (eq_attr "type" "fdiv,fpspc")))
+ "yf_decoder012,yf_agu,yf_fdiv*7")
diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings
index adecaec..8e412f7 100644
--- a/gcc/config/loongarch/genopts/loongarch-strings
+++ b/gcc/config/loongarch/genopts/loongarch-strings
@@ -63,3 +63,9 @@ STR_CMODEL_TS tiny-static
STR_CMODEL_MEDIUM medium
STR_CMODEL_LARGE large
STR_CMODEL_EXTREME extreme
+
+# -mexplicit-relocs
+OPTSTR_EXPLICIT_RELOCS explicit-relocs
+STR_EXPLICIT_RELOCS_AUTO auto
+STR_EXPLICIT_RELOCS_NONE none
+STR_EXPLICIT_RELOCS_ALWAYS always
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index 4a2d743..e1fe0c7 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -170,10 +170,27 @@ mmax-inline-memcpy-size=
Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024)
-mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024.
-mexplicit-relocs
-Target Var(TARGET_EXPLICIT_RELOCS) Init(HAVE_AS_EXPLICIT_RELOCS & !HAVE_AS_MRELAX_OPTION)
+Enum
+Name(explicit_relocs) Type(int)
+The code model option names for -mexplicit-relocs:
+
+EnumValue
+Enum(explicit_relocs) String(@@STR_EXPLICIT_RELOCS_AUTO@@) Value(EXPLICIT_RELOCS_AUTO)
+
+EnumValue
+Enum(explicit_relocs) String(@@STR_EXPLICIT_RELOCS_NONE@@) Value(EXPLICIT_RELOCS_NONE)
+
+EnumValue
+Enum(explicit_relocs) String(@@STR_EXPLICIT_RELOCS_ALWAYS@@) Value(EXPLICIT_RELOCS_ALWAYS)
+
+mexplicit-relocs=
+Target RejectNegative Joined Enum(explicit_relocs) Var(la_opt_explicit_relocs) Init(M_OPT_UNSET)
Use %reloc() assembly operators.
+mexplicit-relocs
+Target Var(la_opt_explicit_relocs_backward) Init(M_OPT_UNSET)
+Use %reloc() assembly operators (for backward compatibility).
+
; The code model option names for -mcmodel.
Enum
Name(cmodel) Type(int)
diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 442fda2..f0f2dd0 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -906,15 +906,15 @@
})
;; Same as vcond_
-(define_expand "vcond_mask_<ILASX:mode><ILASX:mode>"
- [(match_operand:ILASX 0 "register_operand")
- (match_operand:ILASX 1 "reg_or_m1_operand")
- (match_operand:ILASX 2 "reg_or_0_operand")
- (match_operand:ILASX 3 "register_operand")]
+(define_expand "vcond_mask_<mode><mode256_i>"
+ [(match_operand:LASX 0 "register_operand")
+ (match_operand:LASX 1 "reg_or_m1_operand")
+ (match_operand:LASX 2 "reg_or_0_operand")
+ (match_operand:<VIMODE256> 3 "register_operand")]
"ISA_HAS_LASX"
{
- loongarch_expand_vec_cond_mask_expr (<ILASX:MODE>mode,
- <ILASX:VIMODE256>mode, operands);
+ loongarch_expand_vec_cond_mask_expr (<MODE>mode,
+ <VIMODE256>mode, operands);
DONE;
})
diff --git a/gcc/config/loongarch/lasxintrin.h b/gcc/config/loongarch/lasxintrin.h
index d393799..7bce2c7 100644
--- a/gcc/config/loongarch/lasxintrin.h
+++ b/gcc/config/loongarch/lasxintrin.h
@@ -3368,7 +3368,7 @@ __m256i __lasx_xvftintrnel_l_s (__m256 _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V8SI, V8SF. */
+/* Data types in instruction templates: V8SF, V8SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256 __lasx_xvfrintrne_s (__m256 _1)
{
@@ -3376,7 +3376,7 @@ __m256 __lasx_xvfrintrne_s (__m256 _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V4DI, V4DF. */
+/* Data types in instruction templates: V4DF, V4DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256d __lasx_xvfrintrne_d (__m256d _1)
{
@@ -3384,7 +3384,7 @@ __m256d __lasx_xvfrintrne_d (__m256d _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V8SI, V8SF. */
+/* Data types in instruction templates: V8SF, V8SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256 __lasx_xvfrintrz_s (__m256 _1)
{
@@ -3392,7 +3392,7 @@ __m256 __lasx_xvfrintrz_s (__m256 _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V4DI, V4DF. */
+/* Data types in instruction templates: V4DF, V4DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256d __lasx_xvfrintrz_d (__m256d _1)
{
@@ -3400,7 +3400,7 @@ __m256d __lasx_xvfrintrz_d (__m256d _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V8SI, V8SF. */
+/* Data types in instruction templates: V8SF, V8SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256 __lasx_xvfrintrp_s (__m256 _1)
{
@@ -3408,7 +3408,7 @@ __m256 __lasx_xvfrintrp_s (__m256 _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V4DI, V4DF. */
+/* Data types in instruction templates: V4DF, V4DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256d __lasx_xvfrintrp_d (__m256d _1)
{
@@ -3416,7 +3416,7 @@ __m256d __lasx_xvfrintrp_d (__m256d _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V8SI, V8SF. */
+/* Data types in instruction templates: V8SF, V8SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256 __lasx_xvfrintrm_s (__m256 _1)
{
@@ -3424,7 +3424,7 @@ __m256 __lasx_xvfrintrm_s (__m256 _1)
}
/* Assembly instruction format: xd, xj. */
-/* Data types in instruction templates: V4DI, V4DF. */
+/* Data types in instruction templates: V4DF, V4DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m256d __lasx_xvfrintrm_d (__m256d _1)
{
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index 769efcb..6e2a698 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -99,6 +99,12 @@ extern const char* loongarch_cmodel_strings[];
#define CMODEL_EXTREME 5
#define N_CMODEL_TYPES 6
+/* enum explicit_relocs */
+#define EXPLICIT_RELOCS_AUTO 0
+#define EXPLICIT_RELOCS_NONE 1
+#define EXPLICIT_RELOCS_ALWAYS 2
+#define N_EXPLICIT_RELOCS_TYPES 3
+
/* The common default value for variables whose assignments
are triggered by command-line options. */
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index 2756939..f204828 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -101,4 +101,8 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target,
#define HAVE_AS_MRELAX_OPTION 0
#endif
+#ifndef HAVE_AS_TLS
+#define HAVE_AS_TLS 0
+#endif
+
#endif /* LOONGARCH_OPTS_H */
diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h
index 72ae991..cb8fc36 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -220,4 +220,5 @@ extern rtx loongarch_gen_const_int_vector_shuffle (machine_mode, int);
extern tree loongarch_build_builtin_va_list (void);
extern rtx loongarch_build_signbit_mask (machine_mode, bool, bool);
+extern bool loongarch_explicit_relocs_p (enum loongarch_symbol_type);
#endif /* ! GCC_LOONGARCH_PROTOS_H */
diff --git a/gcc/config/loongarch/loongarch-str.h b/gcc/config/loongarch/loongarch-str.h
index a3e0510..072558c 100644
--- a/gcc/config/loongarch/loongarch-str.h
+++ b/gcc/config/loongarch/loongarch-str.h
@@ -62,4 +62,9 @@ along with GCC; see the file COPYING3. If not see
#define STR_CMODEL_LARGE "large"
#define STR_CMODEL_EXTREME "extreme"
+#define OPTSTR_EXPLICIT_RELOCS "explicit-relocs"
+#define STR_EXPLICIT_RELOCS_AUTO "auto"
+#define STR_EXPLICIT_RELOCS_NONE "none"
+#define STR_EXPLICIT_RELOCS_ALWAYS "always"
+
#endif /* LOONGARCH_STR_H */
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 73f0c16..c782f57 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1925,6 +1925,40 @@ loongarch_symbolic_constant_p (rtx x, enum loongarch_symbol_type *symbol_type)
gcc_unreachable ();
}
+/* If -mexplicit-relocs=auto, we use machine operations with reloc hints
+ for cases where the linker is unable to relax so we can schedule the
+ machine operations, otherwise use an assembler pseudo-op so the
+ assembler will generate R_LARCH_RELAX. */
+
+bool
+loongarch_explicit_relocs_p (enum loongarch_symbol_type type)
+{
+ if (la_opt_explicit_relocs != EXPLICIT_RELOCS_AUTO)
+ return la_opt_explicit_relocs == EXPLICIT_RELOCS_ALWAYS;
+
+ switch (type)
+ {
+ case SYMBOL_TLS_IE:
+ case SYMBOL_TLS_LE:
+ case SYMBOL_TLSGD:
+ case SYMBOL_TLSLDM:
+ /* The linker don't know how to relax TLS accesses. */
+ return true;
+ case SYMBOL_GOT_DISP:
+ /* If we are performing LTO for a final link, and we have the
+ linker plugin so we know the resolution of the symbols, then
+ all GOT references are binding to external symbols or
+ preemptable symbols. So the linker cannot relax them. */
+ return (in_lto_p
+ && !flag_incremental_link
+ && HAVE_LTO_PLUGIN == 2
+ && (!global_options_set.x_flag_use_linker_plugin
+ || global_options.x_flag_use_linker_plugin));
+ default:
+ return false;
+ }
+}
+
/* Returns the number of instructions necessary to reference a symbol. */
static int
@@ -1940,7 +1974,7 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode)
case SYMBOL_GOT_DISP:
/* The constant will have to be loaded from the GOT before it
is used in an address. */
- if (!TARGET_EXPLICIT_RELOCS && mode != MAX_MACHINE_MODE)
+ if (!loongarch_explicit_relocs_p (type) && mode != MAX_MACHINE_MODE)
return 0;
return 3;
@@ -2730,7 +2764,7 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
start_sequence ();
- if (TARGET_EXPLICIT_RELOCS)
+ if (la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE)
{
/* Split tls symbol to high and low. */
rtx high = gen_rtx_HIGH (Pmode, copy_rtx (loc));
@@ -2895,7 +2929,7 @@ loongarch_legitimize_tls_address (rtx loc)
tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
tmp1 = gen_reg_rtx (Pmode);
dest = gen_reg_rtx (Pmode);
- if (TARGET_EXPLICIT_RELOCS)
+ if (la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE)
{
tmp2 = loongarch_unspec_address (loc, SYMBOL_TLS_IE);
tmp3 = gen_reg_rtx (Pmode);
@@ -2932,7 +2966,7 @@ loongarch_legitimize_tls_address (rtx loc)
tmp1 = gen_reg_rtx (Pmode);
dest = gen_reg_rtx (Pmode);
- if (TARGET_EXPLICIT_RELOCS)
+ if (la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE)
{
tmp2 = loongarch_unspec_address (loc, SYMBOL_TLS_LE);
tmp3 = gen_reg_rtx (Pmode);
@@ -3038,7 +3072,7 @@ loongarch_symbol_extreme_p (enum loongarch_symbol_type type)
If so, and if LOW_OUT is nonnull, emit the high part and store the
low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
- Return false if build with '-mno-explicit-relocs'.
+ Return false if build with '-mexplicit-relocs=none'.
TEMP is as for loongarch_force_temporary and is used to load the high
part into a register.
@@ -3052,12 +3086,9 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out)
{
enum loongarch_symbol_type symbol_type;
- /* If build with '-mno-explicit-relocs', don't split symbol. */
- if (!TARGET_EXPLICIT_RELOCS)
- return false;
-
if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE)
|| !loongarch_symbolic_constant_p (addr, &symbol_type)
+ || !loongarch_explicit_relocs_p (symbol_type)
|| loongarch_symbol_insns (symbol_type, mode) == 0
|| !loongarch_split_symbol_type (symbol_type))
return false;
@@ -4797,7 +4828,7 @@ loongarch_output_move (rtx dest, rtx src)
}
}
- if (!TARGET_EXPLICIT_RELOCS
+ if (!loongarch_explicit_relocs_p (loongarch_classify_symbol (src))
&& dest_code == REG && symbolic_operand (src, VOIDmode))
{
if (loongarch_classify_symbol (src) == SYMBOL_PCREL)
@@ -7387,6 +7418,25 @@ loongarch_option_override_internal (struct gcc_options *opts,
loongarch_update_gcc_opt_status (&la_target, opts, opts_set);
loongarch_cpu_option_override (&la_target, opts, opts_set);
+ if (la_opt_explicit_relocs != M_OPT_UNSET
+ && la_opt_explicit_relocs_backward != M_OPT_UNSET)
+ error ("do not use %qs (with %qs) and %qs (without %qs) together",
+ "-mexplicit-relocs=", "=",
+ la_opt_explicit_relocs_backward ? "-mexplicit-relocs"
+ : "-mno-explicit-relocs", "=");
+
+ if (la_opt_explicit_relocs_backward != M_OPT_UNSET)
+ la_opt_explicit_relocs = (la_opt_explicit_relocs_backward
+ ? EXPLICIT_RELOCS_ALWAYS
+ : EXPLICIT_RELOCS_NONE);
+
+ if (la_opt_explicit_relocs == M_OPT_UNSET)
+ la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS
+ ? (HAVE_AS_MRELAX_OPTION
+ ? EXPLICIT_RELOCS_AUTO
+ : EXPLICIT_RELOCS_ALWAYS)
+ : EXPLICIT_RELOCS_NONE);
+
if (TARGET_ABI_LP64)
flag_pcc_struct_return = 0;
@@ -7417,7 +7467,7 @@ loongarch_option_override_internal (struct gcc_options *opts,
case CMODEL_EXTREME:
if (!TARGET_EXPLICIT_RELOCS)
error ("code model %qs needs %s",
- "extreme", "-mexplicit-relocs");
+ "extreme", "-mexplicit-relocs=always");
if (opts->x_flag_plt)
{
@@ -7721,7 +7771,8 @@ loongarch_handle_model_attribute (tree *node, tree name, tree arg, int,
if (!TARGET_EXPLICIT_RELOCS)
{
error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute requires %s", name, "-mexplicit-relocs");
+ "%qE attribute requires %s", name,
+ "-mexplicit-relocs=always");
*no_add_attrs = true;
return NULL_TREE;
}
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index da3ec2a..ddac8e9 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -1231,3 +1231,11 @@ struct GTY (()) machine_function
(TARGET_HARD_FLOAT_ABI ? (TARGET_DOUBLE_FLOAT_ABI ? 8 : 4) : 0)
#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN)
+
+/* LoongArch maintains ICache/DCache coherency by hardware,
+ we just need "ibar" to avoid instruction hazard here. */
+#undef CLEAR_INSN_CACHE
+#define CLEAR_INSN_CACHE(beg, end) __builtin_loongarch_ibar (0)
+
+#define TARGET_EXPLICIT_RELOCS \
+ (la_opt_explicit_relocs == EXPLICIT_RELOCS_ALWAYS)
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 365b412..4dd716e 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -65,6 +65,7 @@
UNSPEC_LOAD_FROM_GOT
UNSPEC_PCALAU12I
+ UNSPEC_PCALAU12I_GR
UNSPEC_ORI_L_LO12
UNSPEC_LUI_L_HI20
UNSPEC_LUI_H_LO20
@@ -112,6 +113,7 @@
(define_constants
[(RETURN_ADDR_REGNUM 1)
+ (TP_REGNUM 2)
(T0_REGNUM 12)
(T1_REGNUM 13)
(S0_REGNUM 23)
@@ -2247,7 +2249,7 @@
[(set (match_operand:P 0 "register_operand" "=r")
(lo_sum:P (match_operand:P 1 "register_operand" " r")
(match_operand:P 2 "symbolic_operand" "")))]
- "TARGET_EXPLICIT_RELOCS"
+ ""
"addi.<d>\t%0,%1,%L2"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
@@ -2257,7 +2259,7 @@
(unspec:P [(mem:P (lo_sum:P (match_operand:P 1 "register_operand" "r")
(match_operand:P 2 "symbolic_operand" "")))]
UNSPEC_TLS_LOW))]
- "TARGET_EXPLICIT_RELOCS"
+ ""
"addi.<d>\t%0,%1,%L2"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
@@ -2275,7 +2277,7 @@
(match_operand:P 1 "register_operand" "r")
(match_operand:P 2 "symbolic_operand")))]
UNSPEC_LOAD_FROM_GOT))]
- "TARGET_EXPLICIT_RELOCS"
+ ""
"ld.<d>\t%0,%1,%L2"
[(set_attr "type" "move")]
)
@@ -2297,6 +2299,16 @@
"pcalau12i\t%0,%%pc_hi20(%1)"
[(set_attr "type" "move")])
+;; @pcalau12i may be used for sibcall so it has a strict constraint. This
+;; allows any general register as the operand.
+(define_insn "@pcalau12i_gr<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
+ UNSPEC_PCALAU12I_GR))]
+ ""
+ "pcalau12i\t%0,%%pc_hi20(%1)"
+ [(set_attr "type" "move")])
+
(define_insn "@ori_l_lo12<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_operand" "r")
@@ -3636,6 +3648,12 @@
[(set_attr "length" "0")
(set_attr "type" "ghost")])
+;; Named pattern for expanding thread pointer reference.
+(define_expand "get_thread_pointer<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (reg:P TP_REGNUM))]
+ "HAVE_AS_TLS"
+ {})
(define_split
[(match_operand 0 "small_data_pattern")]
@@ -3748,6 +3766,117 @@
[(set_attr "type" "unknown")
(set_attr "mode" "<MODE>")])
+;; With normal or medium code models, if the only use of a pc-relative
+;; address is for loading or storing a value, then relying on linker
+;; relaxation is not better than emitting the machine instruction directly.
+;; Even if the la.local pseudo op can be relaxed, we get:
+;;
+;; pcaddi $t0, %pcrel_20(x)
+;; ld.d $t0, $t0, 0
+;;
+;; There are still two instructions, same as using the machine instructions
+;; and explicit relocs:
+;;
+;; pcalau12i $t0, %pc_hi20(x)
+;; ld.d $t0, $t0, %pc_lo12(x)
+;;
+;; And if the pseudo op cannot be relaxed, we'll get a worse result (with
+;; 3 instructions).
+(define_peephole2
+ [(set (match_operand:P 0 "register_operand")
+ (match_operand:P 1 "symbolic_pcrel_operand"))
+ (set (match_operand:GPR 2 "register_operand")
+ (mem:GPR (match_dup 0)))]
+ "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \
+ && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \
+ && (peep2_reg_dead_p (2, operands[0]) \
+ || REGNO (operands[0]) == REGNO (operands[2]))"
+ [(set (match_dup 2) (mem:GPR (lo_sum:P (match_dup 0) (match_dup 1))))]
+ {
+ emit_insn (gen_pcalau12i_gr<P:mode> (operands[0], operands[1]));
+ })
+
+(define_peephole2
+ [(set (match_operand:P 0 "register_operand")
+ (match_operand:P 1 "symbolic_pcrel_operand"))
+ (set (match_operand:GPR 2 "register_operand")
+ (mem:GPR (plus (match_dup 0)
+ (match_operand 3 "const_int_operand"))))]
+ "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \
+ && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \
+ && (peep2_reg_dead_p (2, operands[0]) \
+ || REGNO (operands[0]) == REGNO (operands[2]))"
+ [(set (match_dup 2) (mem:GPR (lo_sum:P (match_dup 0) (match_dup 1))))]
+ {
+ operands[1] = plus_constant (Pmode, operands[1], INTVAL (operands[3]));
+ emit_insn (gen_pcalau12i_gr<P:mode> (operands[0], operands[1]));
+ })
+
+(define_peephole2
+ [(set (match_operand:P 0 "register_operand")
+ (match_operand:P 1 "symbolic_pcrel_operand"))
+ (set (match_operand:GPR 2 "register_operand")
+ (any_extend:GPR (mem:SUBDI (match_dup 0))))]
+ "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \
+ && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \
+ && (peep2_reg_dead_p (2, operands[0]) \
+ || REGNO (operands[0]) == REGNO (operands[2]))"
+ [(set (match_dup 2)
+ (any_extend:GPR (mem:SUBDI (lo_sum:P (match_dup 0)
+ (match_dup 1)))))]
+ {
+ emit_insn (gen_pcalau12i_gr<P:mode> (operands[0], operands[1]));
+ })
+
+(define_peephole2
+ [(set (match_operand:P 0 "register_operand")
+ (match_operand:P 1 "symbolic_pcrel_operand"))
+ (set (match_operand:GPR 2 "register_operand")
+ (any_extend:GPR
+ (mem:SUBDI (plus (match_dup 0)
+ (match_operand 3 "const_int_operand")))))]
+ "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \
+ && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \
+ && (peep2_reg_dead_p (2, operands[0]) \
+ || REGNO (operands[0]) == REGNO (operands[2]))"
+ [(set (match_dup 2)
+ (any_extend:GPR (mem:SUBDI (lo_sum:P (match_dup 0)
+ (match_dup 1)))))]
+ {
+ operands[1] = plus_constant (Pmode, operands[1], INTVAL (operands[3]));
+ emit_insn (gen_pcalau12i_gr<P:mode> (operands[0], operands[1]));
+ })
+
+(define_peephole2
+ [(set (match_operand:P 0 "register_operand")
+ (match_operand:P 1 "symbolic_pcrel_operand"))
+ (set (mem:QHWD (match_dup 0))
+ (match_operand:QHWD 2 "register_operand"))]
+ "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \
+ && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \
+ && (peep2_reg_dead_p (2, operands[0])) \
+ && REGNO (operands[0]) != REGNO (operands[2])"
+ [(set (mem:QHWD (lo_sum:P (match_dup 0) (match_dup 1))) (match_dup 2))]
+ {
+ emit_insn (gen_pcalau12i_gr<P:mode> (operands[0], operands[1]));
+ })
+
+(define_peephole2
+ [(set (match_operand:P 0 "register_operand")
+ (match_operand:P 1 "symbolic_pcrel_operand"))
+ (set (mem:QHWD (plus (match_dup 0)
+ (match_operand 3 "const_int_operand")))
+ (match_operand:QHWD 2 "register_operand"))]
+ "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \
+ && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \
+ && (peep2_reg_dead_p (2, operands[0])) \
+ && REGNO (operands[0]) != REGNO (operands[2])"
+ [(set (mem:QHWD (lo_sum:P (match_dup 0) (match_dup 1))) (match_dup 2))]
+ {
+ operands[1] = plus_constant (Pmode, operands[1], INTVAL (operands[3]));
+ emit_insn (gen_pcalau12i_gr<P:mode> (operands[0], operands[1]));
+ })
+
;; Synchronization instructions.
(include "sync.md")
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index 6215abc..0294660 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -177,10 +177,27 @@ mmax-inline-memcpy-size=
Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024)
-mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024.
-mexplicit-relocs
-Target Var(TARGET_EXPLICIT_RELOCS) Init(HAVE_AS_EXPLICIT_RELOCS & !HAVE_AS_MRELAX_OPTION)
+Enum
+Name(explicit_relocs) Type(int)
+The code model option names for -mexplicit-relocs:
+
+EnumValue
+Enum(explicit_relocs) String(auto) Value(EXPLICIT_RELOCS_AUTO)
+
+EnumValue
+Enum(explicit_relocs) String(none) Value(EXPLICIT_RELOCS_NONE)
+
+EnumValue
+Enum(explicit_relocs) String(always) Value(EXPLICIT_RELOCS_ALWAYS)
+
+mexplicit-relocs=
+Target RejectNegative Joined Enum(explicit_relocs) Var(la_opt_explicit_relocs) Init(M_OPT_UNSET)
Use %reloc() assembly operators.
+mexplicit-relocs
+Target Var(la_opt_explicit_relocs_backward) Init(M_OPT_UNSET)
+Use %reloc() assembly operators (for backward compatibility).
+
; The code model option names for -mcmodel.
Enum
Name(cmodel) Type(int)
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index b4e92ae9..4af32c8 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -644,15 +644,15 @@
DONE;
})
-(define_expand "vcond_mask_<ILSX:mode><ILSX:mode>"
- [(match_operand:ILSX 0 "register_operand")
- (match_operand:ILSX 1 "reg_or_m1_operand")
- (match_operand:ILSX 2 "reg_or_0_operand")
- (match_operand:ILSX 3 "register_operand")]
+(define_expand "vcond_mask_<mode><mode_i>"
+ [(match_operand:LSX 0 "register_operand")
+ (match_operand:LSX 1 "reg_or_m1_operand")
+ (match_operand:LSX 2 "reg_or_0_operand")
+ (match_operand:<VIMODE> 3 "register_operand")]
"ISA_HAS_LSX"
{
- loongarch_expand_vec_cond_mask_expr (<ILSX:MODE>mode,
- <ILSX:VIMODE>mode, operands);
+ loongarch_expand_vec_cond_mask_expr (<MODE>mode,
+ <VIMODE>mode, operands);
DONE;
})
diff --git a/gcc/config/loongarch/lsxintrin.h b/gcc/config/loongarch/lsxintrin.h
index ec42069..29553c0 100644
--- a/gcc/config/loongarch/lsxintrin.h
+++ b/gcc/config/loongarch/lsxintrin.h
@@ -3412,7 +3412,7 @@ __m128i __lsx_vftintrneh_l_s (__m128 _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V4SI, V4SF. */
+/* Data types in instruction templates: V4SF, V4SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128 __lsx_vfrintrne_s (__m128 _1)
{
@@ -3420,7 +3420,7 @@ __m128 __lsx_vfrintrne_s (__m128 _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V2DI, V2DF. */
+/* Data types in instruction templates: V2DF, V2DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128d __lsx_vfrintrne_d (__m128d _1)
{
@@ -3428,7 +3428,7 @@ __m128d __lsx_vfrintrne_d (__m128d _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V4SI, V4SF. */
+/* Data types in instruction templates: V4SF, V4SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128 __lsx_vfrintrz_s (__m128 _1)
{
@@ -3436,7 +3436,7 @@ __m128 __lsx_vfrintrz_s (__m128 _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V2DI, V2DF. */
+/* Data types in instruction templates: V2DF, V2DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128d __lsx_vfrintrz_d (__m128d _1)
{
@@ -3444,7 +3444,7 @@ __m128d __lsx_vfrintrz_d (__m128d _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V4SI, V4SF. */
+/* Data types in instruction templates: V4SF, V4SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128 __lsx_vfrintrp_s (__m128 _1)
{
@@ -3452,7 +3452,7 @@ __m128 __lsx_vfrintrp_s (__m128 _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V2DI, V2DF. */
+/* Data types in instruction templates: V2DF, V2DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128d __lsx_vfrintrp_d (__m128d _1)
{
@@ -3460,7 +3460,7 @@ __m128d __lsx_vfrintrp_d (__m128d _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V4SI, V4SF. */
+/* Data types in instruction templates: V4SF, V4SF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128 __lsx_vfrintrm_s (__m128 _1)
{
@@ -3468,7 +3468,7 @@ __m128 __lsx_vfrintrm_s (__m128 _1)
}
/* Assembly instruction format: vd, vj. */
-/* Data types in instruction templates: V2DI, V2DF. */
+/* Data types in instruction templates: V2DF, V2DF. */
extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__m128d __lsx_vfrintrm_d (__m128d _1)
{
diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md
index 499518b..946ed0d 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -541,16 +541,14 @@
case SYMBOL_REF:
case LABEL_REF:
return (loongarch_symbolic_constant_p (op, &symbol_type)
- && (!TARGET_EXPLICIT_RELOCS
+ && (!loongarch_explicit_relocs_p (symbol_type)
|| !loongarch_split_symbol_type (symbol_type)));
case HIGH:
- /* '-mno-explicit-relocs' don't generate high/low pairs. */
- if (!TARGET_EXPLICIT_RELOCS)
- return false;
-
op = XEXP (op, 0);
+
return (loongarch_symbolic_constant_p (op, &symbol_type)
+ && loongarch_explicit_relocs_p (symbol_type)
&& loongarch_split_symbol_type (symbol_type));
default:
@@ -565,6 +563,13 @@
return loongarch_symbolic_constant_p (op, &type);
})
+(define_predicate "symbolic_pcrel_operand"
+ (match_code "const,symbol_ref,label_ref")
+{
+ enum loongarch_symbol_type type;
+ return loongarch_symbolic_constant_p (op, &type) && type == SYMBOL_PCREL;
+})
+
(define_predicate "equality_operator"
(match_code "eq,ne"))
diff --git a/gcc/config/microblaze/microblaze.cc b/gcc/config/microblaze/microblaze.cc
index c9f6c41..60ad551 100644
--- a/gcc/config/microblaze/microblaze.cc
+++ b/gcc/config/microblaze/microblaze.cc
@@ -56,7 +56,7 @@
/* This file should be included last. */
#include "target-def.h"
-#define MICROBLAZE_VERSION_COMPARE(VA,VB) strcasecmp (VA, VB)
+#define MICROBLAZE_VERSION_COMPARE(VA,VB) strverscmp (VA, VB)
/* Classifies an address.
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index c5b1e52..f5e3e34 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -977,14 +977,11 @@
;; This operation can be performed in the loop vectorizer but unfortunately
;; not applicable for now. We can remove this pattern after loop vectorizer
;; is able to take care of INT64 to FP16 conversion.
-(define_insn_and_split "<float_cvt><mode><vnnconvert>2"
+(define_expand "<float_cvt><mode><vnnconvert>2"
[(set (match_operand:<VNNCONVERT> 0 "register_operand")
(any_float:<VNNCONVERT>
(match_operand:VWWCONVERTI 1 "register_operand")))]
"TARGET_VECTOR && TARGET_ZVFH && can_create_pseudo_p () && !flag_trapping_math"
- "#"
- "&& 1"
- [(const_int 0)]
{
rtx single = gen_reg_rtx (<VNCONVERT>mode); /* Get vector SF mode. */
@@ -994,9 +991,7 @@
emit_insn (gen_trunc<vnconvert><vnnconvert>2 (operands[0], single));
DONE;
- }
- [(set_attr "type" "vfncvtitof")]
-)
+ })
;; =========================================================================
;; == Unary arithmetic
@@ -1441,6 +1436,22 @@
}
[(set_attr "type" "vfminmax")])
+(define_insn_and_split "<ieee_fmaxmin_op><mode>3"
+ [(set (match_operand:V_VLSF 0 "register_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 1 "register_operand")
+ (match_operand:V_VLSF 2 "register_operand")] UNSPEC_VFMAXMIN))]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode) && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ riscv_vector::emit_vlmax_insn (code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode),
+ riscv_vector::BINARY_OP, operands);
+ DONE;
+}
+[(set_attr "type" "vfminmax")])
+
;; -------------------------------------------------------------------------------
;; ---- [FP] Sign copying
;; -------------------------------------------------------------------------------
@@ -1484,6 +1495,20 @@
DONE;
})
+;; -------------------------------------------------------------------------------
+;; - [INT] POPCOUNT.
+;; -------------------------------------------------------------------------------
+
+(define_expand "popcount<mode>2"
+ [(match_operand:V_VLSI 0 "register_operand")
+ (match_operand:V_VLSI 1 "register_operand")]
+ "TARGET_VECTOR"
+{
+ riscv_vector::expand_popcount (operands);
+ DONE;
+})
+
+
;; -------------------------------------------------------------------------
;; ---- [INT] Highpart multiplication
;; -------------------------------------------------------------------------
@@ -1727,6 +1752,36 @@
DONE;
})
+(define_expand "cond_<ieee_fmaxmin_op><mode>"
+ [(match_operand:V_VLSF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 2 "register_operand")
+ (match_operand:V_VLSF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 4 "autovec_else_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_binop (icode, operands);
+ DONE;
+})
+
+(define_expand "cond_len_<ieee_fmaxmin_op><mode>"
+ [(match_operand:VF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:VF
+ [(match_operand:VF 2 "register_operand")
+ (match_operand:VF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:VF 4 "autovec_else_operand")
+ (match_operand 5 "autovec_length_operand")
+ (match_operand 6 "const_0_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_len_binop (icode, operands);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [INT] Conditional ternary operations
;; -------------------------------------------------------------------------
@@ -2083,6 +2138,32 @@
DONE;
})
+(define_expand "reduc_fmax_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, true);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
+(define_expand "reduc_fmin_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, false);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [FP] Left-to-right reductions
;; -------------------------------------------------------------------------
@@ -2353,3 +2434,16 @@
DONE;
}
)
+
+;; Implement rawmemchr[qi|si|hi].
+(define_expand "rawmemchr<ANYI:mode>"
+ [(match_operand 0 "register_operand")
+ (match_operand 1 "memory_operand")
+ (match_operand:ANYI 2 "const_int_operand")]
+ "TARGET_VECTOR"
+ {
+ riscv_vector::expand_rawmemchr(<MODE>mode, operands[0], operands[1],
+ operands[2]);
+ DONE;
+ }
+)
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 07ee14d..68be451 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -220,3 +220,29 @@
"Vector duplicate memory operand"
(and (match_code "mem")
(match_code "reg" "0")))
+
+;; Vendor ISA extension constraints.
+
+(define_memory_constraint "th_m_mia"
+ "@internal
+ A MEM with a valid address for th.[l|s]*ia instructions."
+ (and (match_code "mem")
+ (match_test "th_memidx_legitimate_modify_p (op, true)")))
+
+(define_memory_constraint "th_m_mib"
+ "@internal
+ A MEM with a valid address for th.[l|s]*ib instructions."
+ (and (match_code "mem")
+ (match_test "th_memidx_legitimate_modify_p (op, false)")))
+
+(define_memory_constraint "th_m_mir"
+ "@internal
+ A MEM with a valid address for th.[l|s]*r* instructions."
+ (and (match_code "mem")
+ (match_test "th_memidx_legitimate_index_p (op, false)")))
+
+(define_memory_constraint "th_m_miu"
+ "@internal
+ A MEM with a valid address for th.[l|s]*ur* instructions."
+ (and (match_code "mem")
+ (match_test "th_memidx_legitimate_index_p (op, true)")))
diff --git a/gcc/config/riscv/riscv-avlprop.cc b/gcc/config/riscv/riscv-avlprop.cc
new file mode 100644
index 0000000..c59eb7f
--- /dev/null
+++ b/gcc/config/riscv/riscv-avlprop.cc
@@ -0,0 +1,419 @@
+/* AVL propagation pass for RISC-V 'V' Extension for GNU compiler.
+ Copyright (C) 2023-2023 Free Software Foundation, Inc.
+ Contributed by Juzhe Zhong (juzhe.zhong@rivai.ai), RiVAI Technologies 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/>. */
+
+/* Pre-RA RTL_SSA-based pass propagates AVL for RVV instructions.
+ A standalone AVL propagation pass is designed because:
+
+ - Better code maintain:
+ Current LCM-based VSETVL pass is so complicated that codes
+ there will become even harder to maintain. A straight forward
+ AVL propagation PASS is much easier to maintain.
+
+ - Reduce scalar register pressure:
+ A type of AVL propagation is we propagate AVL from NON-VLMAX
+ instruction to VLMAX instruction.
+ Note: VLMAX instruction should be ignore tail elements (TA)
+ and the result should be used by the NON-VLMAX instruction.
+ This optimization is mostly for auto-vectorization codes:
+
+ vsetvli r136, r137 --- SELECT_VL
+ vle8.v (use avl = r136) --- IFN_MASK_LEN_LOAD
+ vadd.vv (use VLMAX) --- PLUS_EXPR
+ vse8.v (use avl = r136) --- IFN_MASK_LEN_STORE
+
+ NO AVL propation:
+
+ vsetvli a5, a4, ta
+ vle8.v v1
+ vsetvli t0, zero, ta
+ vadd.vv v2, v1, v1
+ vse8.v v2
+
+ We can propagate the AVL to 'vadd.vv' since its result
+ is consumed by a 'vse8.v' which has AVL = a5 and its
+ tail elements are agnostic.
+
+ We DON'T do this optimization on VSETVL pass since it is a
+ post-RA pass that consumed 't0' already wheras a standalone
+ pre-RA AVL propagation pass allows us elide the consumption
+ of the pseudo register of 't0' then we can reduce scalar
+ register pressure.
+
+ - More AVL propagation opportunities:
+ A pre-RA pass is more flexible for AVL REG def-use chain,
+ thus we will get more potential AVL propagation as long as
+ it doesn't increase the scalar register pressure.
+*/
+
+#define IN_TARGET_CODE 1
+#define INCLUDE_ALGORITHM
+#define INCLUDE_FUNCTIONAL
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "backend.h"
+#include "rtl.h"
+#include "target.h"
+#include "tree-pass.h"
+#include "df.h"
+#include "rtl-ssa.h"
+#include "cfgcleanup.h"
+#include "insn-attr.h"
+
+using namespace rtl_ssa;
+using namespace riscv_vector;
+
+enum avlprop_type
+{
+ /* VLMAX AVL and tail agnostic candidates. */
+ AVLPROP_VLMAX_TA,
+ AVLPROP_NONE
+};
+
+/* dump helper functions */
+static const char *
+avlprop_type_to_str (enum avlprop_type type)
+{
+ switch (type)
+ {
+ case AVLPROP_VLMAX_TA:
+ return "vlmax_ta";
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+static bool
+vlmax_ta_p (rtx_insn *rinsn)
+{
+ return vlmax_avl_type_p (rinsn) && tail_agnostic_p (rinsn);
+}
+
+const pass_data pass_data_avlprop = {
+ RTL_PASS, /* type */
+ "avlprop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_avlprop : public rtl_opt_pass
+{
+public:
+ pass_avlprop (gcc::context *ctxt) : rtl_opt_pass (pass_data_avlprop, ctxt) {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *) final override
+ {
+ return TARGET_VECTOR && optimize > 0;
+ }
+ virtual unsigned int execute (function *) final override;
+
+private:
+ /* The AVL propagation instructions and corresponding preferred AVL.
+ It will be updated during the analysis. */
+ hash_map<insn_info *, rtx> *m_avl_propagations;
+
+ /* Potential feasible AVL propagation candidates. */
+ auto_vec<std::pair<enum avlprop_type, insn_info *>> m_candidates;
+
+ rtx get_preferred_avl (const std::pair<enum avlprop_type, insn_info *>) const;
+ rtx get_vlmax_ta_preferred_avl (insn_info *) const;
+ rtx get_nonvlmax_avl (insn_info *) const;
+
+ void avlprop_init (function *);
+ void avlprop_done (void);
+}; // class pass_avlprop
+
+void
+pass_avlprop::avlprop_init (function *fn)
+{
+ calculate_dominance_info (CDI_DOMINATORS);
+ df_analyze ();
+ crtl->ssa = new function_info (fn);
+ m_avl_propagations = new hash_map<insn_info *, rtx>;
+}
+
+void
+pass_avlprop::avlprop_done (void)
+{
+ free_dominance_info (CDI_DOMINATORS);
+ if (crtl->ssa->perform_pending_updates ())
+ cleanup_cfg (0);
+ delete crtl->ssa;
+ crtl->ssa = nullptr;
+ delete m_avl_propagations;
+ m_avl_propagations = NULL;
+ if (!m_candidates.is_empty ())
+ m_candidates.release ();
+}
+
+/* If we have a preferred AVL to propagate, return the AVL.
+ Otherwise, return NULL_RTX as we don't need have any preferred
+ AVL. */
+
+rtx
+pass_avlprop::get_preferred_avl (
+ const std::pair<enum avlprop_type, insn_info *> candidate) const
+{
+ switch (candidate.first)
+ {
+ case AVLPROP_VLMAX_TA:
+ return get_vlmax_ta_preferred_avl (candidate.second);
+ default:
+ gcc_unreachable ();
+ }
+ return NULL_RTX;
+}
+
+/* This is a straight forward pattern ALWAYS in paritial auto-vectorization:
+
+ VL = SELECT_AVL (AVL, ...)
+ V0 = MASK_LEN_LOAD (..., VL)
+ V1 = MASK_LEN_LOAD (..., VL)
+ V2 = V0 + V1 --- Missed LEN information.
+ MASK_LEN_STORE (..., V2, VL)
+
+ We prefer PLUS_EXPR (V0 + V1) instead of COND_LEN_ADD (V0, V1, dummy LEN)
+ because:
+
+ - Few code changes in Loop Vectorizer.
+ - Reuse the current clean flow of partial vectorization, That is, apply
+ predicate LEN or MASK into LOAD/STORE operations and other special
+ arithmetic operations (e.d. DIV), then do the whole vector register
+ operation if it DON'T affect the correctness.
+ Such flow is used by all other targets like x86, sve, s390, ... etc.
+ - PLUS_EXPR has better gimple optimizations than COND_LEN_ADD.
+
+ We propagate AVL from NON-VLMAX to VLMAX for gimple IR like PLUS_EXPR which
+ generates the VLMAX instruction due to missed LEN information. The later
+ VSETVL PASS will elided the redundant vsetvls.
+*/
+
+rtx
+pass_avlprop::get_vlmax_ta_preferred_avl (insn_info *insn) const
+{
+ int sew = get_sew (insn->rtl ());
+ enum vlmul_type vlmul = get_vlmul (insn->rtl ());
+ int ratio = calculate_ratio (sew, vlmul);
+
+ rtx use_avl = NULL_RTX;
+ for (def_info *def : insn->defs ())
+ {
+ if (!is_a<set_info *> (def) || def->is_mem ())
+ return NULL_RTX;
+ const auto *set = dyn_cast<set_info *> (def);
+
+ /* FIXME: Stop AVL propagation if any USE is not a RVV real
+ instruction. It should be totally enough for vectorized codes since
+ they always locate at extended blocks.
+
+ TODO: We can extend PHI checking for intrinsic codes if it
+ necessary in the future. */
+ if (!set->is_local_to_ebb ())
+ return NULL_RTX;
+
+ for (use_info *use : set->nondebug_insn_uses ())
+ {
+ insn_info *use_insn = use->insn ();
+ if (!use_insn->can_be_optimized () || use_insn->is_asm ()
+ || use_insn->is_call () || use_insn->has_volatile_refs ()
+ || use_insn->has_pre_post_modify ()
+ || !has_vl_op (use_insn->rtl ())
+ || !tail_agnostic_p (use_insn->rtl ()))
+ return NULL_RTX;
+
+ int new_sew = get_sew (use_insn->rtl ());
+ enum vlmul_type new_vlmul = get_vlmul (use_insn->rtl ());
+ int new_ratio = calculate_ratio (new_sew, new_vlmul);
+ if (new_ratio != ratio)
+ return NULL_RTX;
+
+ rtx new_use_avl = get_nonvlmax_avl (use_insn);
+ if (!new_use_avl || SUBREG_P (new_use_avl))
+ return NULL_RTX;
+ if (REG_P (new_use_avl))
+ {
+ resource_info resource = full_register (REGNO (new_use_avl));
+ def_lookup dl = crtl->ssa->find_def (resource, use_insn);
+ if (dl.matching_set ())
+ return NULL_RTX;
+ def_info *def1 = dl.prev_def (insn);
+ def_info *def2 = dl.prev_def (use_insn);
+ if (!def1 || !def2 || def1 != def2)
+ return NULL_RTX;
+
+ /* FIXME: We only all AVL propation within a block which should
+ be totally enough for vectorized codes.
+
+ TODO: We can enhance it here for intrinsic codes in the future
+ if it is necessary. */
+ if (def1->insn ()->bb () != insn->bb ()
+ && !dominated_by_p (CDI_DOMINATORS, insn->bb ()->cfg_bb (),
+ def1->insn ()->bb ()->cfg_bb ()))
+ return NULL_RTX;
+ if (def1->insn ()->bb () == insn->bb ()
+ && def1->insn ()->compare_with (insn) >= 0)
+ return NULL_RTX;
+ }
+
+ if (!use_avl)
+ use_avl = new_use_avl;
+ else if (!rtx_equal_p (use_avl, new_use_avl))
+ return NULL_RTX;
+ }
+ }
+
+ return use_avl;
+}
+
+/* Try to get the NONVLMAX AVL of the INSN.
+ INSN can be either NON-VLMAX AVL itself or VLMAX AVL INSN
+ before the PASS but has been propagated a NON-VLMAX AVL
+ in the before round propagation. */
+rtx
+pass_avlprop::get_nonvlmax_avl (insn_info *insn) const
+{
+ if (m_avl_propagations->get (insn))
+ return (*m_avl_propagations->get (insn));
+ else if (nonvlmax_avl_type_p (insn->rtl ()))
+ {
+ extract_insn_cached (insn->rtl ());
+ return recog_data.operand[get_attr_vl_op_idx (insn->rtl ())];
+ }
+
+ return NULL_RTX;
+}
+
+/* Main entry point for this pass. */
+unsigned int
+pass_avlprop::execute (function *fn)
+{
+ avlprop_init (fn);
+
+ /* Iterate the whole function in reverse order (which could speed the
+ convergence) to collect all potential candidates that could be AVL
+ propagated.
+
+ Note that: **NOT** all the candidates will be successfully AVL propagated.
+ */
+ for (bb_info *bb : crtl->ssa->reverse_bbs ())
+ {
+ for (insn_info *insn : bb->reverse_real_nondebug_insns ())
+ {
+ /* We only forward AVL to the instruction that has AVL/VL operand
+ and can be optimized in RTL_SSA level. */
+ if (!insn->can_be_optimized () || !has_vl_op (insn->rtl ()))
+ continue;
+
+ /* TODO: We only do AVL propagation for VLMAX AVL with tail
+ agnostic policy since we have missed-LEN information partial
+ autovectorization. We could add more more AVL propagation
+ for intrinsic codes in the future. */
+ if (vlmax_ta_p (insn->rtl ()))
+ m_candidates.safe_push (std::make_pair (AVLPROP_VLMAX_TA, insn));
+ }
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nNumber of potential AVL propagations: %d\n",
+ m_candidates.length ());
+ for (const auto &candidate : m_candidates)
+ {
+ fprintf (dump_file, "\nAVL propagation type: %s\n",
+ avlprop_type_to_str (candidate.first));
+ print_rtl_single (dump_file, candidate.second->rtl ());
+ }
+ }
+
+ /* Go through all the candidates looking for AVL that we could propagate. */
+ bool change_p = true;
+ while (change_p)
+ {
+ change_p = false;
+ for (auto &candidate : m_candidates)
+ {
+ rtx new_avl = get_preferred_avl (candidate);
+ if (new_avl)
+ {
+ gcc_assert (!vlmax_avl_p (new_avl));
+ auto &update
+ = m_avl_propagations->get_or_insert (candidate.second);
+ change_p = !rtx_equal_p (update, new_avl);
+ update = new_avl;
+ }
+ }
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\nNumber of successful AVL propagations: %d\n\n",
+ (int) m_avl_propagations->elements ());
+
+ for (const auto prop : *m_avl_propagations)
+ {
+ rtx_insn *rinsn = prop.first->rtl ();
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nPropagating AVL: ");
+ print_rtl_single (dump_file, prop.second);
+ fprintf (dump_file, "into: ");
+ print_rtl_single (dump_file, rinsn);
+ }
+ /* Replace AVL operand. */
+ extract_insn_cached (rinsn);
+ rtx avl = recog_data.operand[get_attr_vl_op_idx (rinsn)];
+ int count = count_regno_occurrences (rinsn, REGNO (avl));
+ gcc_assert (count == 1);
+ rtx new_pat = simplify_replace_rtx (PATTERN (rinsn), avl, prop.second);
+ validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false);
+
+ /* Change AVL TYPE into NONVLMAX if it is VLMAX. */
+ if (vlmax_avl_type_p (rinsn))
+ {
+ int index = get_attr_avl_type_idx (rinsn);
+ gcc_assert (index != INVALID_ATTRIBUTE);
+ validate_change_or_fail (rinsn, recog_data.operand_loc[index],
+ get_avl_type_rtx (avl_type::NONVLMAX),
+ false);
+ }
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Successfully to match this instruction: ");
+ print_rtl_single (dump_file, rinsn);
+ }
+ }
+
+ avlprop_done ();
+ return 0;
+}
+
+rtl_opt_pass *
+make_pass_avlprop (gcc::context *ctxt)
+{
+ return new pass_avlprop (ctxt);
+}
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index e557f70..532b1b6 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -121,4 +121,8 @@ enum riscv_entity
/* TODO: Enable RVV movmisalign by default for now. */
#define TARGET_VECTOR_MISALIGN_SUPPORTED 1
+/* The maximmum LMUL according to user configuration. */
+#define TARGET_MAX_LMUL \
+ (int) (riscv_autovec_lmul == RVV_DYNAMIC ? RVV_M8 : riscv_autovec_lmul)
+
#endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/config/riscv/riscv-passes.def b/gcc/config/riscv/riscv-passes.def
index 4084122..b626093 100644
--- a/gcc/config/riscv/riscv-passes.def
+++ b/gcc/config/riscv/riscv-passes.def
@@ -18,4 +18,5 @@
<http://www.gnu.org/licenses/>. */
INSERT_PASS_AFTER (pass_rtl_store_motion, 1, pass_shorten_memrefs);
+INSERT_PASS_AFTER (pass_split_all_insns, 1, pass_avlprop);
INSERT_PASS_BEFORE (pass_fast_rtl_dce, 1, pass_vsetvl);
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index f7a9a02..fde3603 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -43,6 +43,15 @@ enum riscv_symbol_type {
A natural register + offset address. The register satisfies
riscv_valid_base_register_p and the offset is a const_arith_operand.
+ ADDRESS_REG_REG
+ A base register indexed by (optionally scaled) register.
+
+ ADDRESS_REG_UREG
+ A base register indexed by (optionally scaled) zero-extended register.
+
+ ADDRESS_REG_WB
+ A base register indexed by immediate offset with writeback.
+
ADDRESS_LO_SUM
A LO_SUM rtx. The first operand is a valid base register and
the second operand is a symbolic address.
@@ -54,6 +63,9 @@ enum riscv_symbol_type {
A constant symbolic address. */
enum riscv_address_type {
ADDRESS_REG,
+ ADDRESS_REG_REG,
+ ADDRESS_REG_UREG,
+ ADDRESS_REG_WB,
ADDRESS_LO_SUM,
ADDRESS_CONST_INT,
ADDRESS_SYMBOLIC
@@ -67,6 +79,13 @@ enum riscv_address_type {
ADDRESS_REG
REG is the base register and OFFSET is the constant offset.
+ ADDRESS_REG_REG and ADDRESS_REG_UREG
+ REG is the base register and OFFSET is the index register.
+
+ ADDRESS_REG_WB
+ REG is the base register, OFFSET is the constant offset, and
+ shift is the shift amount for the offset.
+
ADDRESS_LO_SUM
REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
is the type of symbol it references.
@@ -78,6 +97,7 @@ struct riscv_address_info {
rtx reg;
rtx offset;
enum riscv_symbol_type symbol_type;
+ int shift;
};
/* Routines implemented in riscv.cc. */
@@ -85,6 +105,7 @@ extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx);
extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *);
extern int riscv_float_const_rtx_index_for_fli (rtx);
extern int riscv_regno_mode_ok_for_base_p (int, machine_mode, bool);
+extern bool riscv_valid_base_register_p (rtx, machine_mode, bool);
extern enum reg_class riscv_index_reg_class ();
extern int riscv_regno_ok_for_index_p (int);
extern int riscv_address_insns (rtx, machine_mode, bool);
@@ -156,6 +177,7 @@ extern void riscv_parse_arch_string (const char *, struct gcc_options *, locatio
extern bool riscv_hard_regno_rename_ok (unsigned, unsigned);
rtl_opt_pass * make_pass_shorten_memrefs (gcc::context *ctxt);
+rtl_opt_pass * make_pass_avlprop (gcc::context *ctxt);
rtl_opt_pass * make_pass_vsetvl (gcc::context *ctxt);
/* Routines implemented in riscv-string.c. */
@@ -306,6 +328,11 @@ enum insn_type : unsigned int
UNARY_OP_FRM_RMM = UNARY_OP | FRM_RMM_P,
UNARY_OP_FRM_RUP = UNARY_OP | FRM_RUP_P,
UNARY_OP_FRM_RDN = UNARY_OP | FRM_RDN_P,
+ UNARY_OP_TAMA_FRM_DYN = UNARY_OP_TAMA | FRM_DYN_P,
+ UNARY_OP_TAMA_FRM_RUP = UNARY_OP_TAMA | FRM_RUP_P,
+ UNARY_OP_TAMA_FRM_RDN = UNARY_OP_TAMA | FRM_RDN_P,
+ UNARY_OP_TAMA_FRM_RMM = UNARY_OP_TAMA | FRM_RMM_P,
+ UNARY_OP_TAMA_FRM_RNE = UNARY_OP_TAMA | FRM_RNE_P,
UNARY_OP_TAMU_FRM_DYN = UNARY_OP_TAMU | FRM_DYN_P,
UNARY_OP_TAMU_FRM_RUP = UNARY_OP_TAMU | FRM_RUP_P,
UNARY_OP_TAMU_FRM_RDN = UNARY_OP_TAMU | FRM_RDN_P,
@@ -484,8 +511,9 @@ void expand_vec_lceil (rtx, rtx, machine_mode, machine_mode);
void expand_vec_lfloor (rtx, rtx, machine_mode, machine_mode);
#endif
bool sew64_scalar_helper (rtx *, rtx *, rtx, machine_mode,
- bool, void (*)(rtx *, rtx));
+ bool, void (*)(rtx *, rtx), enum avl_type);
rtx gen_scalar_move_mask (machine_mode);
+rtx gen_no_side_effects_vsetvl_rtx (machine_mode, rtx, rtx);
/* RVV vector register sizes.
TODO: Currently, we only add RVV_32/RVV_64/RVV_128, we may need to
@@ -516,6 +544,8 @@ void expand_fold_extract_last (rtx *);
void expand_cond_unop (unsigned, rtx *);
void expand_cond_binop (unsigned, rtx *);
void expand_cond_ternop (unsigned, rtx *);
+void expand_popcount (rtx *);
+void expand_rawmemchr (machine_mode, rtx, rtx, rtx);
/* Rounding mode bitfield for fixed point VXRM. */
enum fixed_point_rounding_mode
@@ -553,6 +583,15 @@ 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 *);
+bool tail_agnostic_p (rtx_insn *);
+void validate_change_or_fail (rtx, rtx *, rtx, bool);
+bool nonvlmax_avl_type_p (rtx_insn *);
+bool vlmax_avl_p (rtx);
+uint8_t get_sew (rtx_insn *);
+enum vlmul_type get_vlmul (rtx_insn *);
+int count_regno_occurrences (rtx_insn *, unsigned int);
}
/* We classify builtin types into two classes:
@@ -585,6 +624,14 @@ extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode);
#ifdef RTX_CODE
extern const char*
th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE);
+extern bool th_memidx_legitimate_modify_p (rtx);
+extern bool th_memidx_legitimate_modify_p (rtx, bool);
+extern bool th_memidx_legitimate_index_p (rtx);
+extern bool th_memidx_legitimate_index_p (rtx, bool);
+extern bool th_classify_address (struct riscv_address_info *,
+ rtx, machine_mode, bool);
+extern const char *th_output_move (rtx, rtx);
+extern bool th_print_operand_address (FILE *, machine_mode, rtx);
#endif
extern bool riscv_use_divmod_expander (void);
diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 0b4606a..57e8ad6 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -36,6 +36,9 @@
#include "target.h"
#include "predict.h"
#include "optabs.h"
+#include "riscv-protos.h"
+#include "recog.h"
+#include "tm-constrs.h"
/* Emit proper instruction depending on mode of dest. */
@@ -747,3 +750,302 @@ riscv_expand_block_move (rtx dest, rtx src, rtx length)
}
return false;
}
+
+/* --- Vector expanders --- */
+
+namespace riscv_vector {
+
+/* Used by cpymemsi in riscv.md . */
+
+bool
+expand_block_move (rtx dst_in, rtx src_in, rtx length_in)
+{
+ /*
+ memcpy:
+ mv a3, a0 # Copy destination
+ loop:
+ vsetvli t0, a2, e8, m8, ta, ma # Vectors of 8b
+ vle8.v v0, (a1) # Load bytes
+ add a1, a1, t0 # Bump pointer
+ sub a2, a2, t0 # Decrement count
+ vse8.v v0, (a3) # Store bytes
+ add a3, a3, t0 # Bump pointer
+ bnez a2, loop # Any more?
+ ret # Return
+ */
+ if (!TARGET_VECTOR)
+ return false;
+ HOST_WIDE_INT potential_ew
+ = (MIN (MIN (MEM_ALIGN (src_in), MEM_ALIGN (dst_in)), BITS_PER_WORD)
+ / BITS_PER_UNIT);
+ machine_mode vmode = VOIDmode;
+ bool need_loop = true;
+ bool size_p = optimize_function_for_size_p (cfun);
+ rtx src, dst;
+ rtx end = gen_reg_rtx (Pmode);
+ rtx vec;
+ rtx length_rtx = length_in;
+
+ if (CONST_INT_P (length_in))
+ {
+ HOST_WIDE_INT length = INTVAL (length_in);
+
+ /* By using LMUL=8, we can copy as many bytes in one go as there
+ are bits in a vector register. If the entire block thus fits,
+ we don't need a loop. */
+ if (length <= TARGET_MIN_VLEN)
+ {
+ need_loop = false;
+
+ /* If a single scalar load / store pair can do the job, leave it
+ to the scalar code to do that. */
+ /* ??? If fast unaligned access is supported, the scalar code could
+ use suitably sized scalars irrespective of alignemnt. If that
+ gets fixed, we have to adjust the test here. */
+
+ if (pow2p_hwi (length) && length <= potential_ew)
+ return false;
+ }
+
+ /* Find the vector mode to use. Using the largest possible element
+ size is likely to give smaller constants, and thus potentially
+ reducing code size. However, if we need a loop, we need to update
+ the pointers, and that is more complicated with a larger element
+ size, unless we use an immediate, which prevents us from dynamically
+ using the targets transfer size that the hart supports. And then,
+ unless we know the *exact* vector size of the hart, we'd need
+ multiple vsetvli / branch statements, so it's not even a size win.
+ If, in the future, we find an RISCV-V implementation that is slower
+ for small element widths, we might allow larger element widths for
+ loops too. */
+ if (need_loop)
+ potential_ew = 1;
+ for (; potential_ew; potential_ew >>= 1)
+ {
+ scalar_int_mode elem_mode;
+ unsigned HOST_WIDE_INT bits = potential_ew * BITS_PER_UNIT;
+ unsigned HOST_WIDE_INT per_iter;
+ HOST_WIDE_INT nunits;
+
+ if (need_loop)
+ per_iter = TARGET_MIN_VLEN;
+ else
+ per_iter = length;
+ nunits = per_iter / potential_ew;
+
+ /* Unless we get an implementation that's slow for small element
+ size / non-word-aligned accesses, we assume that the hardware
+ handles this well, and we don't want to complicate the code
+ with shifting word contents around or handling extra bytes at
+ the start and/or end. So we want the total transfer size and
+ alignment to fit with the element size. */
+ if (length % potential_ew != 0
+ || !int_mode_for_size (bits, 0).exists (&elem_mode))
+ continue;
+ /* Find the mode to use for the copy inside the loop - or the
+ sole copy, if there is no loop. */
+ if (!need_loop)
+ {
+ /* Try if we have an exact mode for the copy. */
+ if (riscv_vector::get_vector_mode (elem_mode,
+ nunits).exists (&vmode))
+ break;
+ /* Since we don't have a mode that exactlty matches the transfer
+ size, we'll need to use pred_store, which is not available
+ for all vector modes, but only iE_RVV_M* modes, hence trying
+ to find a vector mode for a merely rounded-up size is
+ pointless.
+ Still, by choosing a lower LMUL factor that still allows
+ an entire transfer, we can reduce register pressure. */
+ for (unsigned lmul = 1; lmul <= 4; lmul <<= 1)
+ if (TARGET_MIN_VLEN * lmul <= nunits * BITS_PER_UNIT
+ /* Avoid loosing the option of using vsetivli . */
+ && (nunits <= 31 * lmul || nunits > 31 * 8)
+ && (riscv_vector::get_vector_mode
+ (elem_mode, exact_div (BYTES_PER_RISCV_VECTOR * lmul,
+ potential_ew)).exists (&vmode)))
+ break;
+ }
+
+ /* The RVVM8?I modes are notionally 8 * BYTES_PER_RISCV_VECTOR bytes
+ wide. BYTES_PER_RISCV_VECTOR can't be eavenly divided by
+ the sizes of larger element types; the LMUL factor of 8 can at
+ the moment be divided by the SEW, with SEW of up to 8 bytes,
+ but there are reserved encodings so there might be larger
+ SEW in the future. */
+ if (riscv_vector::get_vector_mode
+ (elem_mode, exact_div (BYTES_PER_RISCV_VECTOR * 8,
+ potential_ew)).exists (&vmode))
+ break;
+
+ /* We may get here if we tried an element size that's larger than
+ the hardware supports, but we should at least find a suitable
+ byte vector mode. */
+ gcc_assert (potential_ew > 1);
+ }
+ if (potential_ew > 1)
+ length_rtx = GEN_INT (length / potential_ew);
+ }
+ else
+ {
+ vmode = E_RVVM8QImode;
+ }
+
+ /* A memcpy libcall in the worst case takes 3 instructions to prepare the
+ arguments + 1 for the call. When RVV should take 7 instructions and
+ we're optimizing for size a libcall may be preferable. */
+ if (size_p && need_loop)
+ return false;
+
+ /* length_rtx holds the (remaining) length of the required copy.
+ cnt holds the length we copy with the current load/store pair. */
+ rtx cnt = length_rtx;
+ rtx label = NULL_RTX;
+ rtx dst_addr = copy_addr_to_reg (XEXP (dst_in, 0));
+ rtx src_addr = copy_addr_to_reg (XEXP (src_in, 0));
+
+ if (need_loop)
+ {
+ length_rtx = copy_to_mode_reg (Pmode, length_rtx);
+ cnt = gen_reg_rtx (Pmode);
+ label = gen_label_rtx ();
+
+ emit_label (label);
+ emit_insn (riscv_vector::gen_no_side_effects_vsetvl_rtx (vmode, cnt,
+ length_rtx));
+ }
+
+ vec = gen_reg_rtx (vmode);
+ src = change_address (src_in, vmode, src_addr);
+ dst = change_address (dst_in, vmode, dst_addr);
+
+ /* If we don't need a loop and have a suitable mode to describe the size,
+ just do a load / store pair and leave it up to the later lazy code
+ motion pass to insert the appropriate vsetvli. */
+ if (!need_loop && known_eq (GET_MODE_SIZE (vmode), INTVAL (length_in)))
+ {
+ emit_move_insn (vec, src);
+ emit_move_insn (dst, vec);
+ }
+ else
+ {
+ machine_mode mask_mode = riscv_vector::get_vector_mode
+ (BImode, GET_MODE_NUNITS (vmode)).require ();
+ rtx mask = CONSTM1_RTX (mask_mode);
+ if (!satisfies_constraint_K (cnt))
+ cnt= force_reg (Pmode, cnt);
+ rtx m_ops[] = {vec, mask, src};
+ emit_nonvlmax_insn (code_for_pred_mov (vmode),
+ riscv_vector::UNARY_OP_TAMA, m_ops, cnt);
+ emit_insn (gen_pred_store (vmode, dst, mask, vec, cnt,
+ get_avl_type_rtx (riscv_vector::NONVLMAX)));
+ }
+
+ if (need_loop)
+ {
+ emit_insn (gen_rtx_SET (src_addr, gen_rtx_PLUS (Pmode, src_addr, cnt)));
+ emit_insn (gen_rtx_SET (dst_addr, gen_rtx_PLUS (Pmode, dst_addr, cnt)));
+ emit_insn (gen_rtx_SET (length_rtx, gen_rtx_MINUS (Pmode, length_rtx, cnt)));
+
+ /* Emit the loop condition. */
+ rtx test = gen_rtx_NE (VOIDmode, end, const0_rtx);
+ emit_jump_insn (gen_cbranch4 (Pmode, test, length_rtx, const0_rtx, label));
+ emit_insn (gen_nop ());
+ }
+
+ return true;
+}
+
+
+/* Implement rawmemchr<mode> using vector instructions.
+ It can be assumed that the needle is in the haystack, otherwise the
+ behavior is undefined. */
+
+void
+expand_rawmemchr (machine_mode mode, rtx dst, rtx src, rtx pat)
+{
+ /*
+ rawmemchr:
+ loop:
+ vsetvli a1, zero, e[8,16,32,64], m1, ta, ma
+ vle[8,16,32,64]ff.v v8, (a0) # Load.
+ csrr a1, vl # Get number of bytes read.
+ vmseq.vx v0, v8, pat # v0 = (v8 == {pat, pat, ...})
+ vfirst.m a2, v0 # Find first hit.
+ add a0, a0, a1 # Bump pointer.
+ bltz a2, loop # Not found?
+
+ sub a0, a0, a1 # Go back by a1.
+ shll a2, a2, [0,1,2,3] # Shift to get byte offset.
+ add a0, a0, a2 # Add the offset.
+
+ ret
+ */
+ gcc_assert (TARGET_VECTOR);
+
+ unsigned int isize = GET_MODE_SIZE (mode).to_constant ();
+ int lmul = TARGET_MAX_LMUL;
+ poly_int64 nunits = exact_div (BYTES_PER_RISCV_VECTOR * lmul, isize);
+
+ machine_mode vmode;
+ if (!riscv_vector::get_vector_mode (GET_MODE_INNER (mode),
+ nunits).exists (&vmode))
+ gcc_unreachable ();
+
+ machine_mode mask_mode = riscv_vector::get_mask_mode (vmode);
+
+ rtx cnt = gen_reg_rtx (Pmode);
+ rtx end = gen_reg_rtx (Pmode);
+ rtx vec = gen_reg_rtx (vmode);
+ rtx mask = gen_reg_rtx (mask_mode);
+
+ /* After finding the first vector element matching the needle, we
+ need to multiply by the vector element width (SEW) in order to
+ return a pointer to the matching byte. */
+ unsigned int shift = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
+
+ rtx src_addr = copy_addr_to_reg (XEXP (src, 0));
+
+ rtx loop = gen_label_rtx ();
+ emit_label (loop);
+
+ rtx vsrc = change_address (src, vmode, src_addr);
+
+ /* Emit a first-fault load. */
+ rtx vlops[] = {vec, vsrc};
+ emit_vlmax_insn (code_for_pred_fault_load (vmode),
+ riscv_vector::UNARY_OP, vlops);
+
+ /* Read how far we read. */
+ if (Pmode == SImode)
+ emit_insn (gen_read_vlsi (cnt));
+ else
+ emit_insn (gen_read_vldi_zero_extend (cnt));
+
+ /* Compare needle with haystack and store in a mask. */
+ rtx eq = gen_rtx_EQ (mask_mode, gen_const_vec_duplicate (vmode, pat), vec);
+ rtx vmsops[] = {mask, eq, vec, pat};
+ emit_nonvlmax_insn (code_for_pred_eqne_scalar (vmode),
+ riscv_vector::COMPARE_OP, vmsops, cnt);
+
+ /* Find the first bit in the mask. */
+ rtx vfops[] = {end, mask};
+ emit_nonvlmax_insn (code_for_pred_ffs (mask_mode, Pmode),
+ riscv_vector::CPOP_OP, vfops, cnt);
+
+ /* Bump the pointer. */
+ emit_insn (gen_rtx_SET (src_addr, gen_rtx_PLUS (Pmode, src_addr, cnt)));
+
+ /* Emit the loop condition. */
+ rtx test = gen_rtx_LT (VOIDmode, end, const0_rtx);
+ emit_jump_insn (gen_cbranch4 (Pmode, test, end, const0_rtx, loop));
+
+ /* We overran by CNT, subtract it. */
+ emit_insn (gen_rtx_SET (src_addr, gen_rtx_MINUS (Pmode, src_addr, cnt)));
+
+ /* We found something at SRC + END * [1,2,4,8]. */
+ emit_insn (gen_rtx_SET (end, gen_rtx_ASHIFT (Pmode, end, GEN_INT (shift))));
+ emit_insn (gen_rtx_SET (dst, gen_rtx_PLUS (Pmode, src_addr, end)));
+}
+
+}
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 383af55..3a49ae7 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -1641,7 +1641,7 @@ has_vi_variant_p (rtx_code code, rtx x)
bool
sew64_scalar_helper (rtx *operands, rtx *scalar_op, rtx vl,
machine_mode vector_mode, bool has_vi_variant_p,
- void (*emit_vector_func) (rtx *, rtx))
+ void (*emit_vector_func) (rtx *, rtx), enum avl_type type)
{
machine_mode scalar_mode = GET_MODE_INNER (vector_mode);
if (has_vi_variant_p)
@@ -1671,7 +1671,11 @@ sew64_scalar_helper (rtx *operands, rtx *scalar_op, rtx vl,
rtx tmp = gen_reg_rtx (vector_mode);
rtx ops[] = {tmp, *scalar_op};
- emit_nonvlmax_insn (code_for_pred_broadcast (vector_mode), UNARY_OP, ops, vl);
+ if (type == VLMAX)
+ emit_vlmax_insn (code_for_pred_broadcast (vector_mode), UNARY_OP, ops);
+ else
+ emit_nonvlmax_insn (code_for_pred_broadcast (vector_mode), UNARY_OP, ops,
+ vl);
emit_vector_func (operands, tmp);
return true;
@@ -1725,7 +1729,7 @@ force_vector_length_operand (rtx vl)
return vl;
}
-static rtx
+rtx
gen_no_side_effects_vsetvl_rtx (machine_mode vmode, rtx vl, rtx avl)
{
unsigned int sew = get_sew (vmode);
@@ -2015,206 +2019,6 @@ expand_tuple_move (rtx *ops)
}
}
-/* Used by cpymemsi in riscv.md . */
-
-bool
-expand_block_move (rtx dst_in, rtx src_in, rtx length_in)
-{
- /*
- memcpy:
- mv a3, a0 # Copy destination
- loop:
- vsetvli t0, a2, e8, m8, ta, ma # Vectors of 8b
- vle8.v v0, (a1) # Load bytes
- add a1, a1, t0 # Bump pointer
- sub a2, a2, t0 # Decrement count
- vse8.v v0, (a3) # Store bytes
- add a3, a3, t0 # Bump pointer
- bnez a2, loop # Any more?
- ret # Return
- */
- if (!TARGET_VECTOR)
- return false;
- HOST_WIDE_INT potential_ew
- = (MIN (MIN (MEM_ALIGN (src_in), MEM_ALIGN (dst_in)), BITS_PER_WORD)
- / BITS_PER_UNIT);
- machine_mode vmode = VOIDmode;
- bool need_loop = true;
- bool size_p = optimize_function_for_size_p (cfun);
- rtx src, dst;
- rtx end = gen_reg_rtx (Pmode);
- rtx vec;
- rtx length_rtx = length_in;
-
- if (CONST_INT_P (length_in))
- {
- HOST_WIDE_INT length = INTVAL (length_in);
-
- /* By using LMUL=8, we can copy as many bytes in one go as there
- are bits in a vector register. If the entire block thus fits,
- we don't need a loop. */
- if (length <= TARGET_MIN_VLEN)
- {
- need_loop = false;
-
- /* If a single scalar load / store pair can do the job, leave it
- to the scalar code to do that. */
- /* ??? If fast unaligned access is supported, the scalar code could
- use suitably sized scalars irrespective of alignemnt. If that
- gets fixed, we have to adjust the test here. */
-
- if (pow2p_hwi (length) && length <= potential_ew)
- return false;
- }
-
- /* Find the vector mode to use. Using the largest possible element
- size is likely to give smaller constants, and thus potentially
- reducing code size. However, if we need a loop, we need to update
- the pointers, and that is more complicated with a larger element
- size, unless we use an immediate, which prevents us from dynamically
- using the targets transfer size that the hart supports. And then,
- unless we know the *exact* vector size of the hart, we'd need
- multiple vsetvli / branch statements, so it's not even a size win.
- If, in the future, we find an RISCV-V implementation that is slower
- for small element widths, we might allow larger element widths for
- loops too. */
- if (need_loop)
- potential_ew = 1;
- for (; potential_ew; potential_ew >>= 1)
- {
- scalar_int_mode elem_mode;
- unsigned HOST_WIDE_INT bits = potential_ew * BITS_PER_UNIT;
- unsigned HOST_WIDE_INT per_iter;
- HOST_WIDE_INT nunits;
-
- if (need_loop)
- per_iter = TARGET_MIN_VLEN;
- else
- per_iter = length;
- nunits = per_iter / potential_ew;
-
- /* Unless we get an implementation that's slow for small element
- size / non-word-aligned accesses, we assume that the hardware
- handles this well, and we don't want to complicate the code
- with shifting word contents around or handling extra bytes at
- the start and/or end. So we want the total transfer size and
- alignment to fit with the element size. */
- if (length % potential_ew != 0
- || !int_mode_for_size (bits, 0).exists (&elem_mode))
- continue;
- /* Find the mode to use for the copy inside the loop - or the
- sole copy, if there is no loop. */
- if (!need_loop)
- {
- /* Try if we have an exact mode for the copy. */
- if (get_vector_mode (elem_mode, nunits).exists (&vmode))
- break;
- /* Since we don't have a mode that exactlty matches the transfer
- size, we'll need to use pred_store, which is not available
- for all vector modes, but only iE_RVV_M* modes, hence trying
- to find a vector mode for a merely rounded-up size is
- pointless.
- Still, by choosing a lower LMUL factor that still allows
- an entire transfer, we can reduce register pressure. */
- for (unsigned lmul = 1; lmul <= 4; lmul <<= 1)
- if (TARGET_MIN_VLEN * lmul <= nunits * BITS_PER_UNIT
- /* Avoid loosing the option of using vsetivli . */
- && (nunits <= 31 * lmul || nunits > 31 * 8)
- && (get_vector_mode
- (elem_mode,
- exact_div (BYTES_PER_RISCV_VECTOR * lmul,
- potential_ew)
- ).exists (&vmode)))
- break;
- }
-
- /* The RVVM8?I modes are notionally 8 * BYTES_PER_RISCV_VECTOR bytes
- wide. BYTES_PER_RISCV_VECTOR can't be eavenly divided by
- the sizes of larger element types; the LMUL factor of 8 can at
- the moment be divided by the SEW, with SEW of up to 8 bytes,
- but there are reserved encodings so there might be larger
- SEW in the future. */
- if (get_vector_mode (elem_mode,
- exact_div (BYTES_PER_RISCV_VECTOR * 8,
- potential_ew)).exists (&vmode))
- break;
-
- /* We may get here if we tried an element size that's larger than
- the hardware supports, but we should at least find a suitable
- byte vector mode. */
- gcc_assert (potential_ew > 1);
- }
- if (potential_ew > 1)
- length_rtx = GEN_INT (length / potential_ew);
- }
- else
- {
- vmode = E_RVVM8QImode;
- }
-
- /* A memcpy libcall in the worst case takes 3 instructions to prepare the
- arguments + 1 for the call. When RVV should take 7 instructions and
- we're optimizing for size a libcall may be preferable. */
- if (size_p && need_loop)
- return false;
-
- /* length_rtx holds the (remaining) length of the required copy.
- cnt holds the length we copy with the current load/store pair. */
- rtx cnt = length_rtx;
- rtx label = NULL_RTX;
- rtx dst_addr = copy_addr_to_reg (XEXP (dst_in, 0));
- rtx src_addr = copy_addr_to_reg (XEXP (src_in, 0));
-
- if (need_loop)
- {
- length_rtx = copy_to_mode_reg (Pmode, length_rtx);
- cnt = gen_reg_rtx (Pmode);
- label = gen_label_rtx ();
-
- emit_label (label);
- emit_insn (gen_no_side_effects_vsetvl_rtx (vmode, cnt, length_rtx));
- }
-
- vec = gen_reg_rtx (vmode);
- src = change_address (src_in, vmode, src_addr);
- dst = change_address (dst_in, vmode, dst_addr);
-
- /* If we don't need a loop and have a suitable mode to describe the size,
- just do a load / store pair and leave it up to the later lazy code
- motion pass to insert the appropriate vsetvli. */
- if (!need_loop && known_eq (GET_MODE_SIZE (vmode), INTVAL (length_in)))
- {
- emit_move_insn (vec, src);
- emit_move_insn (dst, vec);
- }
- else
- {
- machine_mode mask_mode = get_vector_mode (BImode, GET_MODE_NUNITS (vmode)).require ();
- rtx mask = CONSTM1_RTX (mask_mode);
- if (!satisfies_constraint_K (cnt))
- cnt= force_reg (Pmode, cnt);
- rtx m_ops[] = {vec, mask, src};
- emit_nonvlmax_insn (code_for_pred_mov (vmode), UNARY_OP_TAMA,
- m_ops, cnt);
- emit_insn (gen_pred_store (vmode, dst, mask, vec, cnt,
- get_avl_type_rtx (NONVLMAX)));
- }
-
- if (need_loop)
- {
- emit_insn (gen_rtx_SET (src_addr, gen_rtx_PLUS (Pmode, src_addr, cnt)));
- emit_insn (gen_rtx_SET (dst_addr, gen_rtx_PLUS (Pmode, dst_addr, cnt)));
- emit_insn (gen_rtx_SET (length_rtx, gen_rtx_MINUS (Pmode, length_rtx, cnt)));
-
- /* Emit the loop condition. */
- rtx test = gen_rtx_NE (VOIDmode, end, const0_rtx);
- emit_jump_insn (gen_cbranch4 (Pmode, test, length_rtx, const0_rtx, label));
- emit_insn (gen_nop ());
- }
-
- return true;
-}
-
/* Return the vectorization machine mode for RVV according to LMUL. */
machine_mode
preferred_simd_mode (scalar_mode mode)
@@ -2228,16 +2032,15 @@ preferred_simd_mode (scalar_mode mode)
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. */
- int lmul = riscv_autovec_lmul == RVV_DYNAMIC ? RVV_M8 : riscv_autovec_lmul;
if (autovec_use_vlmax_p ())
{
- if (TARGET_MIN_VLEN < 128 && lmul < RVV_M2)
+ 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 * lmul;
+ 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));
machine_mode rvv_mode;
@@ -2417,10 +2220,9 @@ get_cmp_insn_code (rtx_code code, machine_mode mode)
unsigned int
autovectorize_vector_modes (vector_modes *modes, bool)
{
- int lmul = riscv_autovec_lmul == RVV_DYNAMIC ? RVV_M8 : riscv_autovec_lmul;
if (autovec_use_vlmax_p ())
{
- poly_uint64 full_size = BYTES_PER_RISCV_VECTOR * lmul;
+ poly_uint64 full_size = BYTES_PER_RISCV_VECTOR * TARGET_MAX_LMUL;
/* Start with a RVV<LMUL>QImode where LMUL is the number of units that
fit a whole vector.
@@ -2448,7 +2250,7 @@ autovectorize_vector_modes (vector_modes *modes, bool)
}
/* Push all VLSmodes according to TARGET_MIN_VLEN. */
unsigned int i = 0;
- unsigned int base_size = TARGET_MIN_VLEN * lmul / 8;
+ unsigned int base_size = TARGET_MIN_VLEN * TARGET_MAX_LMUL / 8;
unsigned int size = base_size;
machine_mode mode;
while (size > 0 && get_vector_mode (QImode, size).exists (&mode))
@@ -2470,14 +2272,13 @@ can_find_related_mode_p (machine_mode vector_mode, scalar_mode element_mode,
{
if (!autovec_use_vlmax_p ())
return false;
- int lmul = riscv_autovec_lmul == RVV_DYNAMIC ? RVV_M8 : riscv_autovec_lmul;
if (riscv_v_ext_vector_mode_p (vector_mode)
- && multiple_p (BYTES_PER_RISCV_VECTOR * lmul,
+ && multiple_p (BYTES_PER_RISCV_VECTOR * TARGET_MAX_LMUL,
GET_MODE_SIZE (element_mode), nunits))
return true;
if (riscv_v_ext_vls_mode_p (vector_mode)
- && multiple_p (TARGET_MIN_VLEN * lmul, GET_MODE_SIZE (element_mode),
- nunits))
+ && multiple_p (TARGET_MIN_VLEN * TARGET_MAX_LMUL,
+ GET_MODE_SIZE (element_mode), nunits))
return true;
return false;
}
@@ -3410,7 +3211,9 @@ needs_fp_rounding (unsigned icode, machine_mode mode)
return false;
return icode != maybe_code_for_pred (SMIN, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMIN, mode)
&& icode != maybe_code_for_pred (SMAX, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMAX, mode)
&& icode != maybe_code_for_pred (NEG, mode)
&& icode != maybe_code_for_pred (ABS, mode)
/* narrower-FP -> FP */
@@ -4108,10 +3911,18 @@ static void
emit_vec_cvt_x_f (rtx op_dest, rtx op_src, rtx mask,
insn_type type, machine_mode vec_mode)
{
- rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_mode);
- emit_vlmax_insn (icode, type, cvt_x_ops);
+ if (type & USE_VUNDEF_MERGE_P)
+ {
+ rtx cvt_x_ops[] = {op_dest, mask, op_src};
+ emit_vlmax_insn (icode, type, cvt_x_ops);
+ }
+ else
+ {
+ rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+ emit_vlmax_insn (icode, type, cvt_x_ops);
+ }
}
static void
@@ -4136,12 +3947,20 @@ emit_vec_cvt_f_x (rtx op_dest, rtx op_src, rtx mask,
static void
emit_vec_cvt_x_f_rtz (rtx op_dest, rtx op_src, rtx mask,
- machine_mode vec_mode)
+ insn_type type, machine_mode vec_mode)
{
- rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
insn_code icode = code_for_pred (FIX, vec_mode);
- emit_vlmax_insn (icode, UNARY_OP_TAMU, cvt_x_ops);
+ if (type & USE_VUNDEF_MERGE_P)
+ {
+ rtx cvt_x_ops[] = {op_dest, mask, op_src};
+ emit_vlmax_insn (icode, type, cvt_x_ops);
+ }
+ else
+ {
+ rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+ emit_vlmax_insn (icode, type, cvt_x_ops);
+ }
}
void
@@ -4157,7 +3976,7 @@ expand_vec_ceil (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
/* Step-3: Convert to integer on mask, with rounding up (aka ceil). */
rtx tmp = gen_reg_rtx (vec_int_mode);
- emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
+ emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMA_FRM_RUP, vec_fp_mode);
/* Step-4: Convert to floating-point on mask for the final result.
To avoid unnecessary frm register access, we use RUP here and it will
@@ -4182,7 +4001,7 @@ expand_vec_floor (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
/* Step-3: Convert to integer on mask, with rounding down (aka floor). */
rtx tmp = gen_reg_rtx (vec_int_mode);
- emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RDN, vec_fp_mode);
+ emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMA_FRM_RDN, vec_fp_mode);
/* Step-4: Convert to floating-point on mask for the floor result. */
emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RDN, vec_fp_mode);
@@ -4208,7 +4027,7 @@ expand_vec_nearbyint (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
/* Step-4: Convert to integer on mask, with rounding down (aka nearbyint). */
rtx tmp = gen_reg_rtx (vec_int_mode);
- emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_DYN, vec_fp_mode);
+ emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMA_FRM_DYN, vec_fp_mode);
/* Step-5: Convert to floating-point on mask for the nearbyint result. */
emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_DYN, vec_fp_mode);
@@ -4233,7 +4052,7 @@ expand_vec_rint (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
/* Step-3: Convert to integer on mask, with dyn rounding (aka rint). */
rtx tmp = gen_reg_rtx (vec_int_mode);
- emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_DYN, vec_fp_mode);
+ emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMA_FRM_DYN, vec_fp_mode);
/* Step-4: Convert to floating-point on mask for the rint result. */
emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_DYN, vec_fp_mode);
@@ -4255,7 +4074,7 @@ expand_vec_round (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
/* Step-3: Convert to integer on mask, rounding to nearest (aka round). */
rtx tmp = gen_reg_rtx (vec_int_mode);
- emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RMM, vec_fp_mode);
+ emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMA_FRM_RMM, vec_fp_mode);
/* Step-4: Convert to floating-point on mask for the round result. */
emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RMM, vec_fp_mode);
@@ -4277,7 +4096,7 @@ expand_vec_trunc (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
/* Step-3: Convert to integer on mask, rounding to zero (aka truncate). */
rtx tmp = gen_reg_rtx (vec_int_mode);
- emit_vec_cvt_x_f_rtz (tmp, op_1, mask, vec_fp_mode);
+ emit_vec_cvt_x_f_rtz (tmp, op_1, mask, UNARY_OP_TAMA, vec_fp_mode);
/* Step-4: Convert to floating-point on mask for the rint result. */
emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_DYN, vec_fp_mode);
@@ -4299,7 +4118,7 @@ expand_vec_roundeven (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
/* Step-3: Convert to integer on mask, rounding to nearest, ties to even. */
rtx tmp = gen_reg_rtx (vec_int_mode);
- emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RNE, vec_fp_mode);
+ emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMA_FRM_RNE, vec_fp_mode);
/* Step-4: Convert to floating-point on mask for the rint result. */
emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RNE, vec_fp_mode);
@@ -4348,4 +4167,170 @@ expand_vec_lfloor (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
emit_vec_cvt_x_f (op_0, op_1, UNARY_OP_FRM_RDN, vec_fp_mode);
}
+/* Vectorize popcount by the Wilkes-Wheeler-Gill algorithm that libgcc uses as
+ well. */
+void
+expand_popcount (rtx *ops)
+{
+ rtx dst = ops[0];
+ rtx src = ops[1];
+ machine_mode mode = GET_MODE (dst);
+ scalar_mode imode = GET_MODE_INNER (mode);
+ static const uint64_t m5 = 0x5555555555555555ULL;
+ static const uint64_t m3 = 0x3333333333333333ULL;
+ static const uint64_t mf = 0x0F0F0F0F0F0F0F0FULL;
+ static const uint64_t m1 = 0x0101010101010101ULL;
+
+ rtx x1 = gen_reg_rtx (mode);
+ rtx x2 = gen_reg_rtx (mode);
+ rtx x3 = gen_reg_rtx (mode);
+ rtx x4 = gen_reg_rtx (mode);
+
+ /* x1 = src - (src >> 1) & 0x555...); */
+ rtx shift1 = expand_binop (mode, lshr_optab, src, GEN_INT (1), NULL, true,
+ OPTAB_DIRECT);
+
+ rtx and1 = gen_reg_rtx (mode);
+ rtx ops1[] = {and1, shift1, gen_int_mode (m5, imode)};
+ emit_vlmax_insn (code_for_pred_scalar (AND, mode), riscv_vector::BINARY_OP,
+ ops1);
+
+ x1 = expand_binop (mode, sub_optab, src, and1, NULL, true, OPTAB_DIRECT);
+
+ /* x2 = (x1 & 0x3333333333333333ULL) + ((x1 >> 2) & 0x3333333333333333ULL);
+ */
+ rtx and2 = gen_reg_rtx (mode);
+ rtx ops2[] = {and2, x1, gen_int_mode (m3, imode)};
+ emit_vlmax_insn (code_for_pred_scalar (AND, mode), riscv_vector::BINARY_OP,
+ ops2);
+
+ rtx shift2 = expand_binop (mode, lshr_optab, x1, GEN_INT (2), NULL, true,
+ OPTAB_DIRECT);
+
+ rtx and22 = gen_reg_rtx (mode);
+ rtx ops22[] = {and22, shift2, gen_int_mode (m3, imode)};
+ emit_vlmax_insn (code_for_pred_scalar (AND, mode), riscv_vector::BINARY_OP,
+ ops22);
+
+ x2 = expand_binop (mode, add_optab, and2, and22, NULL, true, OPTAB_DIRECT);
+
+ /* x3 = (x2 + (x2 >> 4)) & 0x0f0f0f0f0f0f0f0fULL; */
+ rtx shift3 = expand_binop (mode, lshr_optab, x2, GEN_INT (4), NULL, true,
+ OPTAB_DIRECT);
+
+ rtx plus3
+ = expand_binop (mode, add_optab, x2, shift3, NULL, true, OPTAB_DIRECT);
+
+ rtx ops3[] = {x3, plus3, gen_int_mode (mf, imode)};
+ emit_vlmax_insn (code_for_pred_scalar (AND, mode), riscv_vector::BINARY_OP,
+ ops3);
+
+ /* dest = (x3 * 0x0101010101010101ULL) >> 56; */
+ rtx mul4 = gen_reg_rtx (mode);
+ rtx ops4[] = {mul4, x3, gen_int_mode (m1, imode)};
+ emit_vlmax_insn (code_for_pred_scalar (MULT, mode), riscv_vector::BINARY_OP,
+ ops4);
+
+ x4 = expand_binop (mode, lshr_optab, mul4,
+ GEN_INT (GET_MODE_BITSIZE (imode) - 8), NULL, true,
+ OPTAB_DIRECT);
+
+ emit_move_insn (dst, x4);
+}
+
+/* Return true if it is VLMAX AVL TYPE. */
+bool
+vlmax_avl_type_p (rtx_insn *rinsn)
+{
+ extract_insn_cached (rinsn);
+ int index = get_attr_avl_type_idx (rinsn);
+ if (index == INVALID_ATTRIBUTE)
+ return false;
+ rtx avl_type = recog_data.operand[index];
+ return INTVAL (avl_type) == VLMAX;
+}
+
+/* Return true if it is an RVV instruction depends on VL global
+ status register. */
+bool
+has_vl_op (rtx_insn *rinsn)
+{
+ return recog_memoized (rinsn) >= 0 && get_attr_has_vl_op (rinsn);
+}
+
+/* Get default tail policy. */
+static bool
+get_default_ta ()
+{
+ /* For the instruction that doesn't require TA, we still need a default value
+ to emit vsetvl. We pick up the default value according to prefer policy. */
+ return (bool) (get_prefer_tail_policy () & 0x1
+ || (get_prefer_tail_policy () >> 1 & 0x1));
+}
+
+/* Helper function to get TA operand. */
+bool
+tail_agnostic_p (rtx_insn *rinsn)
+{
+ /* If it doesn't have TA, we return agnostic by default. */
+ extract_insn_cached (rinsn);
+ int ta = get_attr_ta (rinsn);
+ return ta == INVALID_ATTRIBUTE ? get_default_ta () : IS_AGNOSTIC (ta);
+}
+
+/* Change insn and Assert the change always happens. */
+void
+validate_change_or_fail (rtx object, rtx *loc, rtx new_rtx, bool in_group)
+{
+ bool change_p = validate_change (object, loc, new_rtx, in_group);
+ gcc_assert (change_p);
+}
+
+/* Return true if it is NONVLMAX AVL TYPE. */
+bool
+nonvlmax_avl_type_p (rtx_insn *rinsn)
+{
+ extract_insn_cached (rinsn);
+ int index = get_attr_avl_type_idx (rinsn);
+ if (index == INVALID_ATTRIBUTE)
+ return false;
+ rtx avl_type = recog_data.operand[index];
+ return INTVAL (avl_type) == NONVLMAX;
+}
+
+/* Return true if RTX is RVV VLMAX AVL. */
+bool
+vlmax_avl_p (rtx x)
+{
+ return x && rtx_equal_p (x, RVV_VLMAX);
+}
+
+/* Helper function to get SEW operand. We always have SEW value for
+ all RVV instructions that have VTYPE OP. */
+uint8_t
+get_sew (rtx_insn *rinsn)
+{
+ return get_attr_sew (rinsn);
+}
+
+/* Helper function to get VLMUL operand. We always have VLMUL value for
+ all RVV instructions that have VTYPE OP. */
+enum vlmul_type
+get_vlmul (rtx_insn *rinsn)
+{
+ return (enum vlmul_type) get_attr_vlmul (rinsn);
+}
+
+/* Count the number of REGNO in RINSN. */
+int
+count_regno_occurrences (rtx_insn *rinsn, unsigned int regno)
+{
+ int count = 0;
+ extract_insn (rinsn);
+ for (int i = 0; i < recog_data.n_operands; i++)
+ if (refers_to_regno_p (regno, recog_data.operand[i]))
+ count++;
+ return count;
+}
+
} // namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index ab12e13..0b1409a 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -1740,6 +1740,8 @@ public:
rtx expand (function_expander &e) const override
{
+ if (!e.target)
+ return NULL_RTX;
rtx dest = expand_normal (CALL_EXPR_ARG (e.exp, 0));
gcc_assert (riscv_v_ext_vector_mode_p (GET_MODE (dest)));
rtx index = expand_normal (CALL_EXPR_ARG (e.exp, 1));
@@ -1777,6 +1779,8 @@ public:
rtx expand (function_expander &e) const override
{
+ if (!e.target)
+ return NULL_RTX;
rtx src = expand_normal (CALL_EXPR_ARG (e.exp, 0));
gcc_assert (riscv_v_ext_vector_mode_p (GET_MODE (src)));
rtx index = expand_normal (CALL_EXPR_ARG (e.exp, 1));
diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def
index 18ed2c2..911fd52 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -622,6 +622,7 @@ DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_lmul4_x2_ops)
DEF_RVV_FUNCTION (vset, vset, none_preds, all_v_vset_tuple_ops)
DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_tuple_ops)
DEF_RVV_FUNCTION (vcreate, vcreate, none_preds, all_v_vcreate_tuple_ops)
+DEF_RVV_FUNCTION (vundefined, vundefined, none_preds, all_none_void_tuple_ops)
DEF_RVV_FUNCTION (vlseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ops)
DEF_RVV_FUNCTION (vsseg, seg_loadstore, none_m_preds, tuple_v_scalar_ptr_ops)
DEF_RVV_FUNCTION (vlsseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ptrdiff_ops)
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 5d4dc26..2e33bf7 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -2509,6 +2509,14 @@ static CONSTEXPR const rvv_op_info all_v_vcreate_tuple_ops
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
tuple_vcreate_args /* Args */};
+/* A static operand information for vector_type func () function registration.
+ */
+static CONSTEXPR const rvv_op_info all_none_void_tuple_ops
+ = {tuple_ops, /* Types */
+ OP_TYPE_none, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ void_args /* Args */};
+
/* A list of all RVV base function types. */
static CONSTEXPR const function_type_info function_types[] = {
#define DEF_RVV_TYPE_INDEX( \
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 5f26a9e..77dbf15 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -255,12 +255,6 @@ policy_to_str (bool agnostic_p)
return agnostic_p ? "agnostic" : "undisturbed";
}
-static bool
-vlmax_avl_p (rtx x)
-{
- return x && rtx_equal_p (x, RVV_VLMAX);
-}
-
/* Return true if it is an RVV instruction depends on VTYPE global
status register. */
static bool
@@ -269,14 +263,6 @@ has_vtype_op (rtx_insn *rinsn)
return recog_memoized (rinsn) >= 0 && get_attr_has_vtype_op (rinsn);
}
-/* Return true if it is an RVV instruction depends on VL global
- status register. */
-static bool
-has_vl_op (rtx_insn *rinsn)
-{
- return recog_memoized (rinsn) >= 0 && get_attr_has_vl_op (rinsn);
-}
-
/* Return true if the instruction ignores VLMUL field of VTYPE. */
static bool
ignore_vlmul_insn_p (rtx_insn *rinsn)
@@ -365,38 +351,12 @@ get_avl (rtx_insn *rinsn)
if (!has_vl_op (rinsn))
return NULL_RTX;
- if (get_attr_avl_type (rinsn) == VLMAX)
+ if (vlmax_avl_type_p (rinsn))
return RVV_VLMAX;
extract_insn_cached (rinsn);
return recog_data.operand[get_attr_vl_op_idx (rinsn)];
}
-/* Helper function to get SEW operand. We always have SEW value for
- all RVV instructions that have VTYPE OP. */
-static uint8_t
-get_sew (rtx_insn *rinsn)
-{
- return get_attr_sew (rinsn);
-}
-
-/* Helper function to get VLMUL operand. We always have VLMUL value for
- all RVV instructions that have VTYPE OP. */
-static enum vlmul_type
-get_vlmul (rtx_insn *rinsn)
-{
- return (enum vlmul_type) get_attr_vlmul (rinsn);
-}
-
-/* Get default tail policy. */
-static bool
-get_default_ta ()
-{
- /* For the instruction that doesn't require TA, we still need a default value
- to emit vsetvl. We pick up the default value according to prefer policy. */
- return (bool) (get_prefer_tail_policy () & 0x1
- || (get_prefer_tail_policy () >> 1 & 0x1));
-}
-
/* Get default mask policy. */
static bool
get_default_ma ()
@@ -407,16 +367,6 @@ get_default_ma ()
|| (get_prefer_mask_policy () >> 1 & 0x1));
}
-/* Helper function to get TA operand. */
-static bool
-tail_agnostic_p (rtx_insn *rinsn)
-{
- /* If it doesn't have TA, we return agnostic by default. */
- extract_insn_cached (rinsn);
- int ta = get_attr_ta (rinsn);
- return ta == INVALID_ATTRIBUTE ? get_default_ta () : IS_AGNOSTIC (ta);
-}
-
/* Helper function to get MA operand. */
static bool
mask_agnostic_p (rtx_insn *rinsn)
@@ -476,18 +426,6 @@ get_max_float_sew ()
gcc_unreachable ();
}
-/* Count the number of REGNO in RINSN. */
-static int
-count_regno_occurrences (rtx_insn *rinsn, unsigned int regno)
-{
- int count = 0;
- extract_insn (rinsn);
- for (int i = 0; i < recog_data.n_operands; i++)
- if (refers_to_regno_p (regno, recog_data.operand[i]))
- count++;
- return count;
-}
-
enum def_type
{
REAL_SET = 1 << 0,
@@ -696,14 +634,6 @@ has_no_uses (basic_block cfg_bb, rtx_insn *rinsn, int regno)
return true;
}
-/* Change insn and Assert the change always happens. */
-static void
-validate_change_or_fail (rtx object, rtx *loc, rtx new_rtx, bool in_group)
-{
- bool change_p = validate_change (object, loc, new_rtx, in_group);
- gcc_assert (change_p);
-}
-
/* This flags indicates the minimum demand of the vl and vtype values by the
RVV instruction. For example, DEMAND_RATIO_P indicates that this RVV
instruction only needs the SEW/LMUL ratio to remain the same, and does not
@@ -844,7 +774,7 @@ public:
bb_info *get_bb () const { return m_bb; }
uint8_t get_max_sew () const { return m_max_sew; }
insn_info *get_read_vl_insn () const { return m_read_vl_insn; }
- bool vl_use_by_non_rvv_insn_p () const { return m_vl_used_by_non_rvv_insn; }
+ bool vl_used_by_non_rvv_insn_p () const { return m_vl_used_by_non_rvv_insn; }
bool has_imm_avl () const { return m_avl && CONST_INT_P (m_avl); }
bool has_vlmax_avl () const { return vlmax_avl_p (m_avl); }
@@ -1270,7 +1200,7 @@ public:
if (get_read_vl_insn ())
fprintf (file, "%sread_vl_insn: insn %u\n", indent,
get_read_vl_insn ()->uid ());
- if (vl_use_by_non_rvv_insn_p ())
+ if (vl_used_by_non_rvv_insn_p ())
fprintf (file, "%suse_by_non_rvv_insn=true\n", indent);
}
};
@@ -1552,7 +1482,7 @@ private:
if (prev.get_ratio () != next.get_ratio ())
return false;
- if (next.has_vl () && next.vl_use_by_non_rvv_insn_p ())
+ if (next.has_vl () && next.vl_used_by_non_rvv_insn_p ())
return false;
if (vector_config_insn_p (prev.get_insn ()->rtl ()) && next.get_avl_def ()
@@ -1607,6 +1537,29 @@ private:
inline bool can_use_next_avl_p (const vsetvl_info &prev,
const vsetvl_info &next)
{
+ /* Forbid the AVL/VL propagation if VL of NEXT is used
+ by non-RVV instructions. This is because:
+
+ bb 2:
+ PREV: scalar move (no AVL)
+ bb 3:
+ NEXT: vsetvl a5(VL), a4(AVL) ...
+ branch a5,zero
+
+ Since user vsetvl instruction is no side effect instruction
+ which should be placed in the correct and optimal location
+ of the program by the previous PASS, it is unreasonable that
+ VSETVL PASS tries to move it to another places if it used by
+ non-RVV instructions.
+
+ Note: We only forbid the cases that VL is used by the following
+ non-RVV instructions which will cause issues. We don't forbid
+ other cases since it won't cause correctness issues and we still
+ more demand info are fused backward. The later LCM algorithm
+ should know the optimal location of the vsetvl. */
+ if (next.has_vl () && next.vl_used_by_non_rvv_insn_p ())
+ return false;
+
if (!next.has_nonvlmax_reg_avl () && !next.has_vl ())
return true;
@@ -2664,13 +2617,16 @@ pre_vsetvl::compute_lcm_local_properties ()
if (!info.has_nonvlmax_reg_avl () && !info.has_vl ())
continue;
- unsigned int regno;
- sbitmap_iterator sbi;
- EXECUTE_IF_SET_IN_BITMAP (m_reg_def_loc[bb->index ()], 0, regno,
- sbi)
+ if (info.has_nonvlmax_reg_avl ())
{
- if (regno == REGNO (info.get_avl ()))
- bitmap_clear_bit (m_transp[bb->index ()], i);
+ unsigned int regno;
+ sbitmap_iterator sbi;
+ EXECUTE_IF_SET_IN_BITMAP (m_reg_def_loc[bb->index ()], 0,
+ regno, sbi)
+ {
+ if (regno == REGNO (info.get_avl ()))
+ bitmap_clear_bit (m_transp[bb->index ()], i);
+ }
}
for (const insn_info *insn : bb->real_nondebug_insns ())
@@ -2787,7 +2743,7 @@ pre_vsetvl::fuse_local_vsetvl_info ()
curr_info.dump (dump_file, " ");
fprintf (dump_file, "\n");
}
- if (!curr_info.vl_use_by_non_rvv_insn_p ()
+ if (!curr_info.vl_used_by_non_rvv_insn_p ()
&& vsetvl_insn_p (curr_info.get_insn ()->rtl ()))
m_delete_list.safe_push (curr_info);
@@ -3199,7 +3155,7 @@ pre_vsetvl::pre_global_vsetvl_info ()
continue;
curr_info = block_info.local_infos[0];
}
- if (curr_info.valid_p () && !curr_info.vl_use_by_non_rvv_insn_p ()
+ if (curr_info.valid_p () && !curr_info.vl_used_by_non_rvv_insn_p ()
&& preds_has_same_avl_p (curr_info))
curr_info.set_change_vtype_only ();
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f2dcb0db..895a098 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -346,7 +346,7 @@ static const struct riscv_tune_param rocket_tune_info = {
{COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
{COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
{COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
- {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
+ {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
1, /* issue_rate */
3, /* branch_cost */
5, /* memory_cost */
@@ -361,7 +361,7 @@ static const struct riscv_tune_param sifive_7_tune_info = {
{COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
{COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
{COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
- {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
+ {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
2, /* issue_rate */
4, /* branch_cost */
3, /* memory_cost */
@@ -376,7 +376,7 @@ static const struct riscv_tune_param thead_c906_tune_info = {
{COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
{COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
{COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
- {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
+ {COSTS_N_INSNS (18), COSTS_N_INSNS (34)}, /* int_div */
1, /* issue_rate */
3, /* branch_cost */
5, /* memory_cost */
@@ -1084,6 +1084,9 @@ riscv_regno_mode_ok_for_base_p (int regno,
enum reg_class
riscv_index_reg_class ()
{
+ if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
+ return GR_REGS;
+
return NO_REGS;
}
@@ -1092,15 +1095,18 @@ riscv_index_reg_class ()
but extensions might support that. */
int
-riscv_regno_ok_for_index_p (int)
+riscv_regno_ok_for_index_p (int regno)
{
+ if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
+ return riscv_regno_mode_ok_for_base_p (regno, VOIDmode, 1);
+
return 0;
}
/* Return true if X is a valid base register for mode MODE.
STRICT_P is true if REG_OK_STRICT is in effect. */
-static bool
+bool
riscv_valid_base_register_p (rtx x, machine_mode mode, bool strict_p)
{
if (!strict_p && GET_CODE (x) == SUBREG)
@@ -1342,6 +1348,9 @@ static bool
riscv_classify_address (struct riscv_address_info *info, rtx x,
machine_mode mode, bool strict_p)
{
+ if (th_classify_address (info, x, mode, strict_p))
+ return true;
+
switch (GET_CODE (x))
{
case REG:
@@ -3386,6 +3395,10 @@ riscv_output_move (rtx dest, rtx src)
machine_mode mode;
bool dbl_p;
unsigned width;
+ const char *insn;
+
+ if ((insn = th_output_move (dest, src)))
+ return insn;
dest_code = GET_CODE (dest);
src_code = GET_CODE (src);
@@ -5581,6 +5594,9 @@ riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx
{
struct riscv_address_info addr;
+ if (th_print_operand_address (file, mode, x))
+ return;
+
if (riscv_classify_address (&addr, x, word_mode, true))
switch (addr.type)
{
@@ -5602,7 +5618,11 @@ riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx
case ADDRESS_SYMBOLIC:
output_addr_const (file, riscv_strip_unspec_address (x));
return;
+
+ default:
+ gcc_unreachable ();
}
+
gcc_unreachable ();
}
@@ -8610,9 +8630,10 @@ riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
return promote_mode (type, mode, punsignedp);
unsignedp = *punsignedp;
- PROMOTE_MODE (as_a <scalar_mode> (mode), unsignedp, type);
+ scalar_mode smode = as_a <scalar_mode> (mode);
+ PROMOTE_MODE (smode, unsignedp, type);
*punsignedp = unsignedp;
- return mode;
+ return smode;
}
/* Implement TARGET_MACHINE_DEPENDENT_REORG. */
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 0164514..1e9813b 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -372,6 +372,8 @@ ASM_MISA_SPEC
((unsigned int) ((int) (REGNO) - GP_REG_FIRST) < GP_REG_NUM)
#define FP_REG_P(REGNO) \
((unsigned int) ((int) (REGNO) - FP_REG_FIRST) < FP_REG_NUM)
+#define HARDFP_REG_P(REGNO) \
+ ((REGNO) >= FP_REG_FIRST && (REGNO) <= FP_REG_LAST)
#define V_REG_P(REGNO) \
((unsigned int) ((int) (REGNO) - V_REG_FIRST) < V_REG_NUM)
#define VL_REG_P(REGNO) ((REGNO) == VL_REGNUM)
@@ -1191,9 +1193,11 @@ extern void riscv_remove_unneeded_save_restore_calls (void);
#define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_VECTOR)
#define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE, riscv_vector::FRM_NONE}
-
/* The size difference between different RVV modes can be up to 64 times.
e.g. RVVMF64BI vs RVVMF1BI on zvl512b, which is [1, 1] vs [64, 64]. */
#define MAX_POLY_VARIANT 64
+#define HAVE_POST_MODIFY_DISP TARGET_XTHEADMEMIDX
+#define HAVE_PRE_MODIFY_DISP TARGET_XTHEADMEMIDX
+
#endif /* ! GCC_RISCV_H */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 23d9133..ae2217d 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1662,7 +1662,7 @@
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI
(match_operand:SI 1 "nonimmediate_operand" " r,m")))]
- "TARGET_64BIT && !TARGET_ZBA && !TARGET_XTHEADBB
+ "TARGET_64BIT && !TARGET_ZBA && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX
&& !(register_operand (operands[1], SImode)
&& reg_or_subregno (operands[1]) == VL_REGNUM)"
"@
@@ -1690,7 +1690,7 @@
[(set (match_operand:GPR 0 "register_operand" "=r,r")
(zero_extend:GPR
(match_operand:HI 1 "nonimmediate_operand" " r,m")))]
- "!TARGET_ZBB && !TARGET_XTHEADBB"
+ "!TARGET_ZBB && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX"
"@
#
lhu\t%0,%1"
@@ -1709,11 +1709,17 @@
(set_attr "type" "load")
(set_attr "mode" "<GPR:MODE>")])
-(define_insn "zero_extendqi<SUPERQI:mode>2"
+(define_expand "zero_extendqi<SUPERQI:mode>2"
+ [(set (match_operand:SUPERQI 0 "register_operand")
+ (zero_extend:SUPERQI
+ (match_operand:QI 1 "nonimmediate_operand")))]
+ "")
+
+(define_insn "*zero_extendqi<SUPERQI:mode>2_internal"
[(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
(zero_extend:SUPERQI
(match_operand:QI 1 "nonimmediate_operand" " r,m")))]
- ""
+ "!TARGET_XTHEADMEMIDX"
"@
andi\t%0,%1,0xff
lbu\t%0,%1"
@@ -1728,11 +1734,17 @@
;;
;; ....................
-(define_insn "extendsidi2"
+(define_expand "extendsidi2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(sign_extend:DI
(match_operand:SI 1 "nonimmediate_operand" " r,m")))]
- "TARGET_64BIT"
+ "TARGET_64BIT")
+
+(define_insn "*extendsidi2_internal"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (sign_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
+ "TARGET_64BIT && !TARGET_XTHEADMEMIDX"
"@
sext.w\t%0,%1
lw\t%0,%1"
@@ -1749,7 +1761,7 @@
[(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
(sign_extend:SUPERQI
(match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
- "!TARGET_ZBB && !TARGET_XTHEADBB"
+ "!TARGET_ZBB && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX"
"@
#
l<SHORT:size>\t%0,%1"
diff --git a/gcc/config/riscv/sync-rvwmo.md b/gcc/config/riscv/sync-rvwmo.md
index cb641ea..c35eae1 100644
--- a/gcc/config/riscv/sync-rvwmo.md
+++ b/gcc/config/riscv/sync-rvwmo.md
@@ -52,7 +52,7 @@
[(match_operand:GPR 1 "memory_operand" "A")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_LOAD))]
- "TARGET_ATOMIC && !TARGET_ZTSO"
+ "!TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);
@@ -78,7 +78,7 @@
[(match_operand:GPR 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_STORE))]
- "TARGET_ATOMIC && !TARGET_ZTSO"
+ "!TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);
diff --git a/gcc/config/riscv/sync-ztso.md b/gcc/config/riscv/sync-ztso.md
index 7bb15b7..6fdfa91 100644
--- a/gcc/config/riscv/sync-ztso.md
+++ b/gcc/config/riscv/sync-ztso.md
@@ -46,7 +46,7 @@
[(match_operand:GPR 1 "memory_operand" "A")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_LOAD))]
- "TARGET_ATOMIC && TARGET_ZTSO"
+ "TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);
@@ -66,7 +66,7 @@
[(match_operand:GPR 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_STORE))]
- "TARGET_ATOMIC && TARGET_ZTSO"
+ "TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);
diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
index 6ff3493..f05cccf 100644
--- a/gcc/config/riscv/sync.md
+++ b/gcc/config/riscv/sync.md
@@ -60,7 +60,7 @@
[(match_operand:GPR 0 "register_operand")
(match_operand:GPR 1 "memory_operand")
(match_operand:SI 2 "const_int_operand")] ;; model
- "TARGET_ATOMIC"
+ ""
{
if (TARGET_ZTSO)
emit_insn (gen_atomic_load_ztso<mode> (operands[0], operands[1],
@@ -75,7 +75,7 @@
[(match_operand:GPR 0 "memory_operand")
(match_operand:GPR 1 "reg_or_0_operand")
(match_operand:SI 2 "const_int_operand")] ;; model
- "TARGET_ATOMIC"
+ ""
{
if (TARGET_ZTSO)
emit_insn (gen_atomic_store_ztso<mode> (operands[0], operands[1],
@@ -504,43 +504,36 @@
(set (attr "length") (const_int 28))])
(define_expand "atomic_test_and_set"
- [(match_operand:QI 0 "register_operand" "") ;; bool output
+ [(match_operand:QI 0 "register_operand" "") ;; bool output
(match_operand:QI 1 "memory_operand" "+A") ;; memory
- (match_operand:SI 2 "const_int_operand" "")] ;; model
+ (match_operand:SI 2 "const_int_operand" "")] ;; model
"TARGET_ATOMIC"
{
/* We have no QImode atomics, so use the address LSBs to form a mask,
then use an aligned SImode atomic. */
- rtx result = operands[0];
+ rtx old = gen_reg_rtx (SImode);
rtx mem = operands[1];
rtx model = operands[2];
- rtx addr = force_reg (Pmode, XEXP (mem, 0));
-
- rtx aligned_addr = gen_reg_rtx (Pmode);
- emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, GEN_INT (-4)));
+ rtx set = gen_reg_rtx (QImode);
+ rtx aligned_mem = gen_reg_rtx (SImode);
+ rtx shift = gen_reg_rtx (SImode);
- rtx aligned_mem = change_address (mem, SImode, aligned_addr);
- set_mem_alias_set (aligned_mem, 0);
+ /* Unused. */
+ rtx _mask = gen_reg_rtx (SImode);
+ rtx _not_mask = gen_reg_rtx (SImode);
- rtx offset = gen_reg_rtx (SImode);
- emit_move_insn (offset, gen_rtx_AND (SImode, gen_lowpart (SImode, addr),
- GEN_INT (3)));
+ riscv_subword_address (mem, &aligned_mem, &shift, &_mask, &_not_mask);
- rtx tmp = gen_reg_rtx (SImode);
- emit_move_insn (tmp, GEN_INT (1));
+ emit_move_insn (set, GEN_INT (1));
+ rtx shifted_set = gen_reg_rtx (SImode);
+ riscv_lshift_subword (QImode, set, shift, &shifted_set);
- rtx shmt = gen_reg_rtx (SImode);
- emit_move_insn (shmt, gen_rtx_ASHIFT (SImode, offset, GEN_INT (3)));
+ emit_insn (gen_atomic_fetch_orsi (old, aligned_mem, shifted_set, model));
- rtx word = gen_reg_rtx (SImode);
- emit_move_insn (word, gen_rtx_ASHIFT (SImode, tmp,
- gen_lowpart (QImode, shmt)));
+ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old,
+ gen_lowpart (QImode, shift)));
- tmp = gen_reg_rtx (SImode);
- emit_insn (gen_atomic_fetch_orsi (tmp, aligned_mem, word, model));
+ emit_move_insn (operands[0], gen_lowpart (QImode, old));
- emit_move_insn (gen_lowpart (SImode, result),
- gen_rtx_LSHIFTRT (SImode, tmp,
- gen_lowpart (QImode, shmt)));
DONE;
})
diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv
index dd17056..f8ca3f4 100644
--- a/gcc/config/riscv/t-riscv
+++ b/gcc/config/riscv/t-riscv
@@ -78,6 +78,12 @@ riscv-vector-costs.o: $(srcdir)/config/riscv/riscv-vector-costs.cc \
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/riscv/riscv-vector-costs.cc
+riscv-avlprop.o: $(srcdir)/config/riscv/riscv-avlprop.cc \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
+ $(TARGET_H) tree-pass.h df.h rtl-ssa.h cfgcleanup.h insn-attr.h
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/riscv/riscv-avlprop.cc
+
riscv-d.o: $(srcdir)/config/riscv/riscv-d.cc \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
$(COMPILE) $<
diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index be0cd7c..a485fb1 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -25,11 +25,16 @@
#include "coretypes.h"
#include "target.h"
#include "backend.h"
+#include "tree.h"
#include "rtl.h"
+#include "explow.h"
#include "memmodel.h"
#include "emit-rtl.h"
+#include "optabs.h"
#include "poly-int.h"
#include "output.h"
+#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
@@ -430,3 +435,513 @@ th_mempair_save_restore_regs (rtx operands[4], bool load_p,
else
th_mempair_save_regs (operands);
}
+
+/* Return true if X can be represented as signed immediate of NBITS bits.
+ The immediate is assumed to be shifted by LSHAMT bits left. */
+
+static bool
+valid_signed_immediate (rtx x, unsigned nbits, unsigned lshamt)
+{
+ if (GET_CODE (x) != CONST_INT)
+ return false;
+
+ HOST_WIDE_INT v = INTVAL (x);
+
+ HOST_WIDE_INT vunshifted = v >> lshamt;
+
+ /* Make sure we did not shift out any bits. */
+ if (vunshifted << lshamt != v)
+ return false;
+
+ unsigned HOST_WIDE_INT imm_reach = 1LL << nbits;
+ return ((unsigned HOST_WIDE_INT) vunshifted + imm_reach/2 < imm_reach);
+}
+
+/* Return the address RTX of a move to/from memory
+ instruction. */
+
+static rtx
+th_get_move_mem_addr (rtx dest, rtx src, bool load)
+{
+ rtx mem;
+
+ if (load)
+ mem = src;
+ else
+ mem = dest;
+
+ gcc_assert (GET_CODE (mem) == MEM);
+ return XEXP (mem, 0);
+}
+
+/* Return true if X is a valid address for T-Head's memory addressing modes
+ with pre/post modification for machine mode MODE.
+ If it is, fill in INFO appropriately (if non-NULL).
+ If STRICT_P is true then REG_OK_STRICT is in effect. */
+
+static bool
+th_memidx_classify_address_modify (struct riscv_address_info *info, rtx x,
+ machine_mode mode, bool strict_p)
+{
+ if (!TARGET_XTHEADMEMIDX)
+ return false;
+
+ if (!TARGET_64BIT && mode == DImode)
+ return false;
+
+ if (!(INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode).to_constant () <= 8))
+ return false;
+
+ if (GET_CODE (x) != POST_MODIFY
+ && GET_CODE (x) != PRE_MODIFY)
+ return false;
+
+ rtx reg = XEXP (x, 0);
+ rtx exp = XEXP (x, 1);
+ rtx expreg = XEXP (exp, 0);
+ rtx expoff = XEXP (exp, 1);
+
+ if (GET_CODE (exp) != PLUS
+ || !rtx_equal_p (expreg, reg)
+ || !CONST_INT_P (expoff)
+ || !riscv_valid_base_register_p (reg, mode, strict_p))
+ return false;
+
+ /* The offset is calculated as (sign_extend(imm5) << imm2) */
+ const int shamt_bits = 2;
+ for (int shamt = 0; shamt < (1 << shamt_bits); shamt++)
+ {
+ const int nbits = 5;
+ if (valid_signed_immediate (expoff, nbits, shamt))
+ {
+ if (info)
+ {
+ info->type = ADDRESS_REG_WB;
+ info->reg = reg;
+ info->offset = expoff;
+ info->shift = shamt;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Return TRUE if X is a MEM with a legitimate modify address. */
+
+bool
+th_memidx_legitimate_modify_p (rtx x)
+{
+ if (!MEM_P (x))
+ return false;
+
+ /* Get the mode from the MEM and unpack it. */
+ machine_mode mode = GET_MODE (x);
+ x = XEXP (x, 0);
+
+ return th_memidx_classify_address_modify (NULL, x, mode, reload_completed);
+}
+
+/* Return TRUE if X is a MEM with a legitimate modify address
+ and the address is POST_MODIFY (if POST is true) or a PRE_MODIFY
+ (otherwise). */
+
+bool
+th_memidx_legitimate_modify_p (rtx x, bool post)
+{
+ if (!th_memidx_legitimate_modify_p (x))
+ return false;
+
+ /* Unpack the MEM and check the code. */
+ x = XEXP (x, 0);
+ if (post)
+ return GET_CODE (x) == POST_MODIFY;
+ else
+ return GET_CODE (x) == PRE_MODIFY;
+}
+
+/* Provide a buffer for a th.lXia/th.lXib/th.sXia/th.sXib instruction
+ for the given MODE. If LOAD is true, a load instruction will be
+ provided (otherwise, a store instruction). If X is not suitable
+ return NULL. */
+
+static const char *
+th_memidx_output_modify (rtx dest, rtx src, machine_mode mode, bool load)
+{
+ char format[24];
+ rtx output_operands[2];
+ rtx x = th_get_move_mem_addr (dest, src, load);
+
+ /* Validate x. */
+ if (!th_memidx_classify_address_modify (NULL, x, mode, reload_completed))
+ return NULL;
+
+ int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
+ bool post = GET_CODE (x) == POST_MODIFY;
+
+ const char *const insn[][4] = {
+ {
+ "th.sbi%s\t%%z1,%%0",
+ "th.shi%s\t%%z1,%%0",
+ "th.swi%s\t%%z1,%%0",
+ "th.sdi%s\t%%z1,%%0"
+ },
+ {
+ "th.lbui%s\t%%0,%%1",
+ "th.lhui%s\t%%0,%%1",
+ "th.lwi%s\t%%0,%%1",
+ "th.ldi%s\t%%0,%%1"
+ }
+ };
+
+ snprintf (format, sizeof (format), insn[load][index], post ? "a" : "b");
+ output_operands[0] = dest;
+ output_operands[1] = src;
+ output_asm_insn (format, output_operands);
+ return "";
+}
+
+static bool
+is_memidx_mode (machine_mode mode)
+{
+ if (mode == QImode || mode == HImode || mode == SImode)
+ return true;
+
+ if (mode == DImode && TARGET_64BIT)
+ return true;
+
+ return false;
+}
+
+static bool
+is_fmemidx_mode (machine_mode mode)
+{
+ if (mode == SFmode && TARGET_HARD_FLOAT)
+ return true;
+
+ if (mode == DFmode && TARGET_DOUBLE_FLOAT)
+ return true;
+
+ return false;
+}
+
+/* Return true if X is a valid address for T-Head's memory addressing modes
+ with scaled register offsets for machine mode MODE.
+ If it is, fill in INFO appropriately (if non-NULL).
+ If STRICT_P is true then REG_OK_STRICT is in effect. */
+
+static bool
+th_memidx_classify_address_index (struct riscv_address_info *info, rtx x,
+ machine_mode mode, bool strict_p)
+{
+ /* Ensure that the mode is supported. */
+ if (!(TARGET_XTHEADMEMIDX && is_memidx_mode (mode))
+ && !(TARGET_XTHEADFMEMIDX && is_fmemidx_mode (mode)))
+ return false;
+
+ if (GET_CODE (x) != PLUS)
+ return false;
+
+ rtx reg = XEXP (x, 0);
+ enum riscv_address_type type;
+ rtx offset = XEXP (x, 1);
+ int shift;
+
+ if (!riscv_valid_base_register_p (reg, mode, strict_p))
+ return false;
+
+ /* (reg:X) */
+ if (REG_P (offset)
+ && GET_MODE (offset) == Xmode)
+ {
+ type = ADDRESS_REG_REG;
+ shift = 0;
+ offset = offset;
+ }
+ /* (zero_extend:DI (reg:SI)) */
+ else if (GET_CODE (offset) == ZERO_EXTEND
+ && GET_MODE (offset) == DImode
+ && GET_MODE (XEXP (offset, 0)) == SImode)
+ {
+ type = ADDRESS_REG_UREG;
+ shift = 0;
+ offset = XEXP (offset, 0);
+ }
+ /* (ashift:X (reg:X) (const_int shift)) */
+ else if (GET_CODE (offset) == ASHIFT
+ && GET_MODE (offset) == Xmode
+ && REG_P (XEXP (offset, 0))
+ && GET_MODE (XEXP (offset, 0)) == Xmode
+ && CONST_INT_P (XEXP (offset, 1))
+ && IN_RANGE (INTVAL (XEXP (offset, 1)), 0, 3))
+ {
+ type = ADDRESS_REG_REG;
+ shift = INTVAL (XEXP (offset, 1));
+ offset = XEXP (offset, 0);
+ }
+ /* (ashift:DI (zero_extend:DI (reg:SI)) (const_int shift)) */
+ else if (GET_CODE (offset) == ASHIFT
+ && GET_MODE (offset) == DImode
+ && GET_CODE (XEXP (offset, 0)) == ZERO_EXTEND
+ && GET_MODE (XEXP (offset, 0)) == DImode
+ && GET_MODE (XEXP (XEXP (offset, 0), 0)) == SImode
+ && CONST_INT_P (XEXP (offset, 1))
+ && IN_RANGE(INTVAL (XEXP (offset, 1)), 0, 3))
+ {
+ type = ADDRESS_REG_UREG;
+ shift = INTVAL (XEXP (offset, 1));
+ offset = XEXP (XEXP (offset, 0), 0);
+ }
+ else
+ return false;
+
+ if (!strict_p && GET_CODE (offset) == SUBREG)
+ offset = SUBREG_REG (offset);
+
+ if (!REG_P (offset)
+ || !riscv_regno_mode_ok_for_base_p (REGNO (offset), mode, strict_p))
+ return false;
+
+ if (info)
+ {
+ info->reg = reg;
+ info->type = type;
+ info->offset = offset;
+ info->shift = shift;
+ }
+ return true;
+}
+
+/* Return TRUE if X is a MEM with a legitimate indexed address. */
+
+bool
+th_memidx_legitimate_index_p (rtx x)
+{
+ if (!MEM_P (x))
+ return false;
+
+ /* Get the mode from the MEM and unpack it. */
+ machine_mode mode = GET_MODE (x);
+ x = XEXP (x, 0);
+
+ return th_memidx_classify_address_index (NULL, x, mode, reload_completed);
+}
+
+/* Return TRUE if X is a MEM with a legitimate indexed address
+ and the offset register is zero-extended (if UINDEX is true)
+ or sign-extended (otherwise). */
+
+bool
+th_memidx_legitimate_index_p (rtx x, bool uindex)
+{
+ if (!MEM_P (x))
+ return false;
+
+ /* Get the mode from the MEM and unpack it. */
+ machine_mode mode = GET_MODE (x);
+ x = XEXP (x, 0);
+
+ struct riscv_address_info info;
+ if (!th_memidx_classify_address_index (&info, x, mode, reload_completed))
+ return false;
+
+ if (uindex)
+ return info.type == ADDRESS_REG_UREG;
+ else
+ return info.type == ADDRESS_REG_REG;
+}
+
+/* Provide a buffer for a th.lrX/th.lurX/th.srX/th.surX instruction
+ for the given MODE. If LOAD is true, a load instruction will be
+ provided (otherwise, a store instruction). If X is not suitable
+ return NULL. */
+
+static const char *
+th_memidx_output_index (rtx dest, rtx src, machine_mode mode, bool load)
+{
+ struct riscv_address_info info;
+ char format[24];
+ rtx output_operands[2];
+ rtx x = th_get_move_mem_addr (dest, src, load);
+
+ /* Validate x. */
+ if (!th_memidx_classify_address_index (&info, x, mode, reload_completed))
+ return NULL;
+
+ int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
+ bool uindex = info.type == ADDRESS_REG_UREG;
+
+ const char *const insn[][4] = {
+ {
+ "th.s%srb\t%%z1,%%0",
+ "th.s%srh\t%%z1,%%0",
+ "th.s%srw\t%%z1,%%0",
+ "th.s%srd\t%%z1,%%0"
+ },
+ {
+ "th.l%srbu\t%%0,%%1",
+ "th.l%srhu\t%%0,%%1",
+ "th.l%srw\t%%0,%%1",
+ "th.l%srd\t%%0,%%1"
+ }
+ };
+
+ snprintf (format, sizeof (format), insn[load][index], uindex ? "u" : "");
+ output_operands[0] = dest;
+ output_operands[1] = src;
+ output_asm_insn (format, output_operands);
+ return "";
+}
+
+/* Provide a buffer for a th.flX/th.fluX/th.fsX/th.fsuX instruction
+ for the given MODE. If LOAD is true, a load instruction will be
+ provided (otherwise, a store instruction). If X is not suitable
+ return NULL. */
+
+static const char *
+th_fmemidx_output_index (rtx dest, rtx src, machine_mode mode, bool load)
+{
+ struct riscv_address_info info;
+ char format[24];
+ rtx output_operands[2];
+ rtx x = th_get_move_mem_addr (dest, src, load);
+
+ /* Validate x. */
+ if (!th_memidx_classify_address_index (&info, x, mode, false))
+ return NULL;
+
+ int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ()) - 2;
+ bool uindex = info.type == ADDRESS_REG_UREG;
+
+ const char *const insn[][2] = {
+ {
+ "th.fs%srw\t%%z1,%%0",
+ "th.fs%srd\t%%z1,%%0"
+ },
+ {
+ "th.fl%srw\t%%0,%%1",
+ "th.fl%srd\t%%0,%%1"
+ }
+ };
+
+ snprintf (format, sizeof (format), insn[load][index], uindex ? "u" : "");
+ output_operands[0] = dest;
+ output_operands[1] = src;
+ output_asm_insn (format, output_operands);
+ return "";
+}
+
+/* Return true if X is a valid address for T-Head's memory addressing modes
+ for machine mode MODE. If it is, fill in INFO appropriately (if non-NULL).
+ If STRICT_P is true then REG_OK_STRICT is in effect. */
+
+bool
+th_classify_address (struct riscv_address_info *info, rtx x,
+ machine_mode mode, bool strict_p)
+{
+ switch (GET_CODE (x))
+ {
+ case PLUS:
+ if (th_memidx_classify_address_index (info, x, mode, strict_p))
+ return true;
+ break;
+
+ case POST_MODIFY:
+ case PRE_MODIFY:
+ if (th_memidx_classify_address_modify (info, x, mode, strict_p))
+ return true;
+ break;
+
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+/* Provide a string containing a XTheadMemIdx instruction for the given
+ MODE from the provided SRC to the provided DEST.
+ A pointer to a NULL-terminated string containing the instruction will
+ be returned if a suitable instruction is available. Otherwise, this
+ function returns NULL. */
+
+const char *
+th_output_move (rtx dest, rtx src)
+{
+ enum rtx_code dest_code, src_code;
+ machine_mode mode;
+ const char *insn = NULL;
+
+ dest_code = GET_CODE (dest);
+ src_code = GET_CODE (src);
+ mode = GET_MODE (dest);
+
+ if (!(mode == GET_MODE (src) || src == CONST0_RTX (mode)))
+ return NULL;
+
+ if (dest_code == REG && src_code == MEM)
+ {
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ || (GET_MODE_CLASS (mode) == MODE_FLOAT && GP_REG_P (REGNO (dest))))
+ {
+ if ((insn = th_memidx_output_index (dest, src, mode, true)))
+ return insn;
+ if ((insn = th_memidx_output_modify (dest, src, mode, true)))
+ return insn;
+ }
+ else if (GET_MODE_CLASS (mode) == MODE_FLOAT && HARDFP_REG_P (REGNO (dest)))
+ {
+ if ((insn = th_fmemidx_output_index (dest, src, mode, true)))
+ return insn;
+ }
+ }
+ else if (dest_code == MEM && (src_code == REG || src == CONST0_RTX (mode)))
+ {
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ || src == CONST0_RTX (mode)
+ || (GET_MODE_CLASS (mode) == MODE_FLOAT && GP_REG_P (REGNO (src))))
+ {
+ if ((insn = th_memidx_output_index (dest, src, mode, false)))
+ return insn;
+ if ((insn = th_memidx_output_modify (dest, src, mode, false)))
+ return insn;
+ }
+ else if (GET_MODE_CLASS (mode) == MODE_FLOAT && HARDFP_REG_P (REGNO (src)))
+ {
+ if ((insn = th_fmemidx_output_index (dest, src, mode, false)))
+ return insn;
+ }
+ }
+ return NULL;
+}
+
+/* Implement TARGET_PRINT_OPERAND_ADDRESS for XTheadMemIdx. */
+
+bool
+th_print_operand_address (FILE *file, machine_mode mode, rtx x)
+{
+ struct riscv_address_info addr;
+
+ if (!th_classify_address (&addr, x, mode, reload_completed))
+ return false;
+
+ switch (addr.type)
+ {
+ case ADDRESS_REG_REG:
+ case ADDRESS_REG_UREG:
+ fprintf (file, "%s,%s,%u", reg_names[REGNO (addr.reg)],
+ reg_names[REGNO (addr.offset)], addr.shift);
+ return true;
+
+ case ADDRESS_REG_WB:
+ fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)],
+ INTVAL (addr.offset) >> addr.shift, addr.shift);
+ return true;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ gcc_unreachable ();
+}
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 4bb731b..2babfaf 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -62,7 +62,7 @@
[(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
(sign_extend:SUPERQI
(match_operand:HI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_XTHEADBB"
+ "TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX"
"@
th.ext\t%0,%1,15,0
lh\t%0,%1"
@@ -73,7 +73,7 @@
[(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
(sign_extend:SUPERQI
(match_operand:QI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_XTHEADBB"
+ "TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX"
"@
th.ext\t%0,%1,7,0
lb\t%0,%1"
@@ -96,7 +96,7 @@
(define_insn "*zero_extendsidi2_th_extu"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_64BIT && TARGET_XTHEADBB"
+ "TARGET_64BIT && TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX"
"@
th.extu\t%0,%1,31,0
lwu\t%0,%1"
@@ -106,7 +106,7 @@
(define_insn "*zero_extendhi<GPR:mode>2_th_extu"
[(set (match_operand:GPR 0 "register_operand" "=r,r")
(zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_XTHEADBB"
+ "TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX"
"@
th.extu\t%0,%1,15,0
lhu\t%0,%1"
@@ -387,4 +387,590 @@
(set_attr "mode" "DI")
(set_attr "length" "8")])
+;; XTheadMemIdx
+
+;; Help reload to add a displacement for the base register.
+;; In the case `zext(*(uN*)(base+(zext(rN)<<1)))` LRA splits
+;; off two new instructions: a) `new_base = base + disp`, and
+;; b) `index = zext(rN)<<1`. The index calculation has no
+;; corresponding instruction pattern and needs this insn_and_split
+;; to recover.
+
+(define_insn_and_split "*th_memidx_operand"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashift:DI
+ (zero_extend:DI (subreg:SI (match_operand:DI 1 "register_operand" "r") 0))
+ (match_operand 2 "const_int_operand" "n")))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX && lra_in_progress"
+ "#"
+ ""
+ [(set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 1) 0)))
+ (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
+ ""
+ [(set_attr "type" "bitmanip")])
+
+(define_insn "*th_memidx_zero_extendqi<SUPERQI:mode>2"
+ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r,r,r,r,r")
+ (zero_extend:SUPERQI
+ (match_operand:QI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_XTHEADMEMIDX"
+ "@
+ andi\t%0,%1,0xff
+ th.lbuia\t%0,%1
+ th.lbuib\t%0,%1
+ th.lrbu\t%0,%1
+ th.lurbu\t%0,%1
+ lbu\t%0,%1"
+ [(set_attr "move_type" "andi,load,load,load,load,load")
+ (set_attr "mode" "<SUPERQI:MODE>")])
+
+(define_insn "*th_memidx_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
+ (sign_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX"
+ "@
+ sext.w\t%0,%1
+ th.lwia\t%0,%1
+ th.lwib\t%0,%1
+ th.lrw\t%0,%1
+ th.lurw\t%0,%1
+ lw\t%0,%1"
+ [(set_attr "move_type" "move,load,load,load,load,load")
+ (set_attr "mode" "DI")])
+
+;; XTheadMemIdx (without XTheadBb)
+
+(define_insn_and_split "*th_memidx_zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
+ (zero_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX && !TARGET_XTHEADBB"
+ "@
+ #
+ th.lwuia\t%0,%1
+ th.lwuib\t%0,%1
+ th.lrwu\t%0,%1
+ th.lurwu\t%0,%1
+ lwu\t%0,%1"
+ "&& reload_completed
+ && REG_P (operands[1])
+ && !paradoxical_subreg_p (operands[0])"
+ [(set (match_dup 0)
+ (ashift:DI (match_dup 1) (const_int 32)))
+ (set (match_dup 0)
+ (lshiftrt:DI (match_dup 0) (const_int 32)))]
+ { operands[1] = gen_lowpart (DImode, operands[1]); }
+ [(set_attr "move_type" "shift_shift,load,load,load,load,load")
+ (set_attr "mode" "DI")])
+
+(define_insn_and_split "*th_memidx_zero_extendhi<GPR:mode>2"
+ [(set (match_operand:GPR 0 "register_operand" "=r,r,r,r,r,r")
+ (zero_extend:GPR
+ (match_operand:HI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_XTHEADMEMIDX && !TARGET_XTHEADBB"
+ "@
+ #
+ th.lhuia\t%0,%1
+ th.lhuib\t%0,%1
+ th.lrhu\t%0,%1
+ th.lurhu\t%0,%1
+ lhu\t%0,%1"
+ "&& reload_completed
+ && REG_P (operands[1])
+ && !paradoxical_subreg_p (operands[0])"
+ [(set (match_dup 0)
+ (ashift:GPR (match_dup 1) (match_dup 2)))
+ (set (match_dup 0)
+ (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
+ {
+ operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
+ operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
+ }
+ [(set_attr "move_type" "shift_shift,load,load,load,load,load")
+ (set_attr "mode" "<GPR:MODE>")])
+
+(define_insn_and_split "*th_memidx_extend<SHORT:mode><SUPERQI:mode>2"
+ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r,r,r,r,r")
+ (sign_extend:SUPERQI
+ (match_operand:SHORT 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_XTHEADMEMIDX && !TARGET_XTHEADBB"
+ "@
+ #
+ th.l<SHORT:size>ia\t%0,%1
+ th.l<SHORT:size>ib\t%0,%1
+ th.lr<SHORT:size>\t%0,%1
+ th.lur<SHORT:size>\t%0,%1
+ l<SHORT:size>\t%0,%1"
+ "&& reload_completed
+ && REG_P (operands[1])
+ && !paradoxical_subreg_p (operands[0])"
+ [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
+{
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
+ - GET_MODE_BITSIZE (<SHORT:MODE>mode));
+}
+ [(set_attr "move_type" "shift_shift,load,load,load,load,load")
+ (set_attr "mode" "SI")])
+
+;; XTheadMemIdx (with XTheadBb)
+
+(define_insn "*th_memidx_bb_zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
+ (zero_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADBB"
+ "@
+ th.extu\t%0,%1,31,0
+ th.lwuia\t%0,%1
+ th.lwuib\t%0,%1
+ th.lrwu\t%0,%1
+ th.lurwu\t%0,%1
+ lwu\t%0,%1"
+ [(set_attr "move_type" "shift_shift,load,load,load,load,load")
+ (set_attr "mode" "DI")])
+
+(define_insn "*th_memidx_bb_zero_extendhi<GPR:mode>2"
+ [(set (match_operand:GPR 0 "register_operand" "=r,r,r,r,r,r")
+ (zero_extend:GPR
+ (match_operand:HI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_XTHEADMEMIDX && TARGET_XTHEADBB"
+ "@
+ th.extu\t%0,%1,15,0
+ th.lhuia\t%0,%1
+ th.lhuib\t%0,%1
+ th.lrhu\t%0,%1
+ th.lurhu\t%0,%1
+ lhu\t%0,%1"
+ [(set_attr "move_type" "shift_shift,load,load,load,load,load")
+ (set_attr "mode" "<GPR:MODE>")])
+
+(define_insn "*th_memidx_bb_extendhi<GPR:mode>2"
+ [(set (match_operand:GPR 0 "register_operand" "=r,r,r,r,r,r")
+ (sign_extend:GPR
+ (match_operand:HI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_XTHEADMEMIDX && TARGET_XTHEADBB"
+ "@
+ th.ext\t%0,%1,15,0
+ th.lhia\t%0,%1
+ th.lhib\t%0,%1
+ th.lrh\t%0,%1
+ th.lurh\t%0,%1
+ lh\t%0,%1"
+ [(set_attr "move_type" "shift_shift,load,load,load,load,load")
+ (set_attr "mode" "<GPR:MODE>")])
+
+(define_insn "*th_memidx_bb_extendqi<SUPERQI:mode>2"
+ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r,r,r,r,r")
+ (sign_extend:SUPERQI
+ (match_operand:QI 1 "nonimmediate_operand"
+ " r,th_m_mia,th_m_mib,th_m_mir,th_m_miu,m")))]
+ "TARGET_XTHEADMEMIDX && TARGET_XTHEADBB"
+ "@
+ th.ext\t%0,%1,7,0
+ th.lbia\t%0,%1
+ th.lbib\t%0,%1
+ th.lrb\t%0,%1
+ th.lurb\t%0,%1
+ lb\t%0,%1"
+ [(set_attr "move_type" "shift_shift,load,load,load,load,load")
+ (set_attr "mode" "<SUPERQI:MODE>")])
+
+;; All modes that are supported by XTheadMemIdx
+(define_mode_iterator TH_M_ANYI [(QI "TARGET_XTHEADMEMIDX")
+ (HI "TARGET_XTHEADMEMIDX")
+ (SI "TARGET_XTHEADMEMIDX")
+ (DI "TARGET_64BIT && TARGET_XTHEADMEMIDX")])
+
+;; All modes that are supported by XTheadFMemIdx
+(define_mode_iterator TH_M_ANYF [(SF "TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX")
+ (DF "TARGET_DOUBLE_FLOAT && TARGET_XTHEADFMEMIDX")])
+
+;; All non-extension modes that are supported by XTheadMemIdx
+(define_mode_iterator TH_M_NOEXTI [(SI "!TARGET_64BIT && TARGET_XTHEADMEMIDX")
+ (DI "TARGET_64BIT && TARGET_XTHEADMEMIDX")])
+
+;; All non-extension modes that are supported by XTheadFMemIdx
+(define_mode_iterator TH_M_NOEXTF [(SF "TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX")
+ (DF "TARGET_DOUBLE_FLOAT && TARGET_XTHEADFMEMIDX")])
+
+;; XTheadMemIdx optimizations
+;; All optimizations attempt to improve the operand utilization of
+;; XTheadMemIdx instructions, where one sign or zero extended
+;; register-index-operand can be shifted left by a 2-bit immediate.
+;;
+;; The basic idea is the following optimization:
+;; (set (reg 0) (op (reg 1) (imm 2)))
+;; (set (reg 3) (mem (plus (reg 0) (reg 4)))
+;; ==>
+;; (set (reg 3) (mem (plus (reg 4) (op2 (reg 1) (imm 2))))
+;; This optimization only valid if (reg 0) has no further uses.
+;;
+;; The three-instruction case is as follows:
+;; (set (reg 0) (op1 (reg 1) (imm 2)))
+;; (set (reg 3) (op2 (reg 0) (imm 4)))
+;; (set (reg 5) (mem (plus (reg 3) (reg 6)))
+;; ==>
+;; (set (reg 5) (mem (plus (reg 6) (op2 (reg 1) (imm 2/4)))))
+;; This optimization is only valid if (reg 0) and (reg 3) have no further uses.
+;;
+;; The optimization cases are:
+;; I) fold 2-bit ashift of register offset into mem-plus RTX
+;; US) fold 32-bit zero-extended (shift) offset into mem-plus
+;; UZ) fold 32-bit zero-extended (zext) offset into mem-plus
+;;
+;; The first optimization case is targeting the th.lr<MODE> instructions.
+;; The other optimization cases are targeting the th.lur<MODE> instructions
+;; and have to consider two forms of zero-extensions:
+;; - ashift-32 + lshiftrt-{29..32} if there are no zero-extension instructions.
+;; Left-shift amounts of 29..31 indicate a left-shifted zero-extended value.
+;; - zero-extend32 if there are zero-extension instructions (XTheadBb or Zbb).
+;;
+;; We always have three peephole passes per optimization case:
+;; a) no-extended (X) word-load
+;; b) any-extend (SUBX) word-load
+;; c) store
+;;
+;; Note, that SHIFTs will be converted to MULTs during combine.
+
+(define_insn_and_split "*th_memidx_I_a"
+ [(set (match_operand:TH_M_NOEXTI 0 "register_operand" "=r")
+ (mem:TH_M_NOEXTI (plus:X
+ (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:X 3 "register_operand" "r"))))]
+ "TARGET_XTHEADMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (mem:TH_M_NOEXTI (plus:X
+ (match_dup 3)
+ (ashift:X (match_dup 1) (match_dup 2)))))]
+ { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_memidx_I_b"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (any_extend:X (mem:SUBX (plus:X
+ (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:X 3 "register_operand" "r")))))]
+ "TARGET_XTHEADMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (any_extend:X (mem:SUBX (plus:X
+ (match_dup 3)
+ (ashift:X (match_dup 1) (match_dup 2))))))]
+ { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_memidx_I_c"
+ [(set (mem:TH_M_ANYI (plus:X
+ (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:X 3 "register_operand" "r")))
+ (match_operand:TH_M_ANYI 0 "register_operand" "r"))]
+ "TARGET_XTHEADMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
+ "#"
+ "&& 1"
+ [(set (mem:TH_M_ANYI (plus:X
+ (match_dup 3)
+ (ashift:X (match_dup 1) (match_dup 2))))
+ (match_dup 0))]
+ { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_memidx_US_a"
+ [(set (match_operand:TH_M_NOEXTI 0 "register_operand" "=r")
+ (mem:TH_M_NOEXTI (plus:DI
+ (and:DI
+ (mult:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:DI 3 "immediate_operand" "i"))
+ (match_operand:DI 4 "register_operand" "r"))))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
+ && CONST_INT_P (operands[3])
+ && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (mem:TH_M_NOEXTI (plus:DI
+ (match_dup 4)
+ (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))))]
+ { operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_memidx_US_b"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (any_extend:X (mem:SUBX (plus:DI
+ (and:DI
+ (mult:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:DI 3 "immediate_operand" "i"))
+ (match_operand:DI 4 "register_operand" "r")))))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
+ && CONST_INT_P (operands[3])
+ && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (any_extend:X (mem:SUBX (plus:DI
+ (match_dup 4)
+ (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2))))))]
+ { operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_memidx_US_c"
+ [(set (mem:TH_M_ANYI (plus:DI
+ (and:DI
+ (mult:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:DI 3 "immediate_operand" "i"))
+ (match_operand:DI 4 "register_operand" "r")))
+ (match_operand:TH_M_ANYI 0 "register_operand" "r"))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
+ && CONST_INT_P (operands[3])
+ && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
+ "#"
+ "&& 1"
+ [(set (mem:TH_M_ANYI (plus:DI
+ (match_dup 4)
+ (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2))))
+ (match_dup 0))]
+ { operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_memidx_UZ_a"
+ [(set (match_operand:TH_M_NOEXTI 0 "register_operand" "=r")
+ (mem:TH_M_NOEXTI (plus:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:DI 2 "register_operand" "r"))))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (mem:TH_M_NOEXTI (plus:DI
+ (match_dup 2)
+ (zero_extend:DI (match_dup 1)))))]
+)
+
+(define_insn_and_split "*th_memidx_UZ_b"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (any_extend:X (mem:SUBX (plus:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:DI 2 "register_operand" "r")))))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (any_extend:X (mem:SUBX (plus:DI
+ (match_dup 2)
+ (zero_extend:DI (match_dup 1))))))]
+)
+
+(define_insn_and_split "*th_memidx_UZ_c"
+ [(set (mem:TH_M_ANYI (plus:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:DI 2 "register_operand" "r")))
+ (match_operand:TH_M_ANYI 0 "register_operand" "r"))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX"
+ "#"
+ "&& 1"
+ [(set (mem:TH_M_ANYI (plus:DI
+ (match_dup 2)
+ (zero_extend:DI (match_dup 1))))
+ (match_dup 0))]
+)
+
+;; XTheadFMemIdx
+
+(define_insn "*th_fmemidx_movsf_hardfloat"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,th_m_mir,f,th_m_miu")
+ (match_operand:SF 1 "move_operand" " th_m_mir,f,th_m_miu,f"))]
+ "TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX
+ && (register_operand (operands[0], SFmode)
+ || reg_or_0_operand (operands[1], SFmode))"
+ { return riscv_output_move (operands[0], operands[1]); }
+ [(set_attr "move_type" "fpload,fpstore,fpload,fpstore")
+ (set_attr "mode" "SF")])
+
+(define_insn "*th_fmemidx_movdf_hardfloat_rv64"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,th_m_mir,f,th_m_miu")
+ (match_operand:DF 1 "move_operand" " th_m_mir,f,th_m_miu,f"))]
+ "TARGET_64BIT && TARGET_DOUBLE_FLOAT && TARGET_XTHEADFMEMIDX
+ && (register_operand (operands[0], DFmode)
+ || reg_or_0_operand (operands[1], DFmode))"
+ { return riscv_output_move (operands[0], operands[1]); }
+ [(set_attr "move_type" "fpload,fpstore,fpload,fpstore")
+ (set_attr "mode" "DF")])
+
+;; XTheadFMemIdx optimizations
+;; Similar like XTheadMemIdx optimizations, but less cases.
+;; Note, that we might get GP registers in FP-mode (reg:DF a2)
+;; which cannot be handled by the XTheadFMemIdx instructions.
+;; This might even happend after register allocation.
+;; We could implement splitters that undo the combiner results
+;; if "after_reload && !HARDFP_REG_P (operands[0])", but this
+;; raises even more questions (e.g. split into what?).
+;; So let's solve this by simply requiring XTheadMemIdx
+;; which provides the necessary instructions to cover this case.
+
+(define_insn_and_split "*th_fmemidx_I_a"
+ [(set (match_operand:TH_M_NOEXTF 0 "register_operand" "=f")
+ (mem:TH_M_NOEXTF (plus:X
+ (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:X 3 "register_operand" "r"))))]
+ "TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (mem:TH_M_NOEXTF (plus:X
+ (match_dup 3)
+ (ashift:X (match_dup 1) (match_dup 2)))))]
+ { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_fmemidx_I_c"
+ [(set (mem:TH_M_ANYF (plus:X
+ (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:X 3 "register_operand" "r")))
+ (match_operand:TH_M_ANYF 0 "register_operand" "f"))]
+ "TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
+ "#"
+ "&& 1"
+ [(set (mem:TH_M_ANYF (plus:X
+ (match_dup 3)
+ (ashift:X (match_dup 1) (match_dup 2))))
+ (match_dup 0))]
+ { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_fmemidx_US_a"
+ [(set (match_operand:TH_M_NOEXTF 0 "register_operand" "=f")
+ (mem:TH_M_NOEXTF (plus:DI
+ (and:DI
+ (mult:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:DI 3 "immediate_operand" "i"))
+ (match_operand:DI 4 "register_operand" "r"))))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
+ && CONST_INT_P (operands[3])
+ && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (mem:TH_M_NOEXTF (plus:DI
+ (match_dup 4)
+ (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))))]
+ { operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_fmemidx_US_c"
+ [(set (mem:TH_M_ANYF (plus:DI
+ (and:DI
+ (mult:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "i"))
+ (match_operand:DI 3 "immediate_operand" "i"))
+ (match_operand:DI 4 "register_operand" "r")))
+ (match_operand:TH_M_ANYF 0 "register_operand" "f"))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
+ && CONST_INT_P (operands[2])
+ && pow2p_hwi (INTVAL (operands[2]))
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
+ && CONST_INT_P (operands[3])
+ && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
+ "#"
+ "&& 1"
+ [(set (mem:TH_M_ANYF (plus:DI
+ (match_dup 4)
+ (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2))))
+ (match_dup 0))]
+ { operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
+ }
+)
+
+(define_insn_and_split "*th_fmemidx_UZ_a"
+ [(set (match_operand:TH_M_NOEXTF 0 "register_operand" "=f")
+ (mem:TH_M_NOEXTF (plus:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:DI 2 "register_operand" "r"))))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
+ && (!HARD_REGISTER_NUM_P (REGNO (operands[0])) || HARDFP_REG_P (REGNO (operands[0])))"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (mem:TH_M_NOEXTF (plus:DI
+ (match_dup 2)
+ (zero_extend:DI (match_dup 1)))))]
+)
+
+(define_insn_and_split "*th_fmemidx_UZ_c"
+ [(set (mem:TH_M_ANYF (plus:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:DI 2 "register_operand" "r")))
+ (match_operand:TH_M_ANYF 0 "register_operand" "f"))]
+ "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX"
+ "#"
+ "&& 1"
+ [(set (mem:TH_M_ANYF (plus:DI
+ (match_dup 2)
+ (zero_extend:DI (match_dup 1))))
+ (match_dup 0))]
+)
+
(include "thead-peephole.md")
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index e80a20d..d9b5dec 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -82,6 +82,9 @@
UNSPEC_VFFMA
+ UNSPEC_VFMAX
+ UNSPEC_VFMIN
+
;; Integer and Float Reduction
UNSPEC_REDUC
UNSPEC_REDUC_SUM
@@ -3479,6 +3482,11 @@
(define_int_attr UNSPEC [(UNSPEC_VSLIDE1UP "UNSPEC_VSLIDE1UP")
(UNSPEC_VSLIDE1DOWN "UNSPEC_VSLIDE1DOWN")])
+(define_int_iterator UNSPEC_VFMAXMIN [UNSPEC_VFMAX UNSPEC_VFMIN])
+
+(define_int_attr ieee_fmaxmin_op [(UNSPEC_VFMAX "fmax") (UNSPEC_VFMIN "fmin")])
+(define_int_attr IEEE_FMAXMIN_OP [(UNSPEC_VFMAX "UNSPEC_VFMAX") (UNSPEC_VFMIN "UNSPEC_VFMIN")])
+
(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
smax umax smin umin mult div udiv mod umod
])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 32955fb..35bb6c3 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -800,31 +800,22 @@
(const_int INVALID_ATTRIBUTE)))
;; The avl type value.
-(define_attr "avl_type" ""
- (cond [(eq_attr "mode" "V1QI,V2QI,V4QI,V8QI,V16QI,V32QI,V64QI,V128QI,V256QI,V512QI,V1024QI,V2048QI,V4096QI,
- V1BI,V2BI,V4BI,V8BI,V16BI,V32BI,V64BI,V128BI,V256BI,V512BI,V1024BI,V2048BI,V4096BI,
- V1HI,V2HI,V4HI,V8HI,V16HI,V32HI,V64HI,V128HI,V256HI,V512HI,V1024HI,V2048HI,
- V1SI,V2SI,V4SI,V8SI,V16SI,V32SI,V64SI,V128SI,V256SI,V512SI,V1024SI,
- V1DI,V2DI,V4DI,V8DI,V16DI,V32DI,V64DI,V128DI,V256DI,V512DI,
- V1HF,V2HF,V4HF,V8HF,V16HF,V32HF,V64HF,V128HF,V256HF,V512HF,V1024HF,V2048HF,
- V1SF,V2SF,V4SF,V8SF,V16SF,V32SF,V64SF,V128SF,V256SF,V512SF,V1024SF,
- V1DF,V2DF,V4DF,V8DF,V16DF,V32DF,V64DF,V128DF,V256DF,V512DF")
- (symbol_ref "riscv_vector::NONVLMAX")
- (eq_attr "type" "vlde,vldff,vste,vimov,vimov,vimov,vfmov,vext,vimerge,\
+(define_attr "avl_type_idx" ""
+ (cond [(eq_attr "type" "vlde,vldff,vste,vimov,vimov,vimov,vfmov,vext,vimerge,\
vfsqrt,vfrecp,vfmerge,vfcvtitof,vfcvtftoi,vfwcvtitof,\
vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,\
vfclass,vired,viwred,vfredu,vfredo,vfwredu,vfwredo,\
vimovxv,vfmovfv,vlsegde,vlsegdff")
- (symbol_ref "INTVAL (operands[7])")
+ (const_int 7)
(eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
- (symbol_ref "INTVAL (operands[5])")
+ (const_int 5)
;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
;; wheras it is pred_strided_load if operands[3] is vector mode.
(eq_attr "type" "vlds")
(if_then_else (match_test "VECTOR_MODE_P (GET_MODE (operands[3]))")
(const_int INVALID_ATTRIBUTE)
- (symbol_ref "INTVAL (operands[7])"))
+ (const_int 7))
(eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
viwalu,viwmul,vnshift,vaalu,vsmul,vsshift,\
@@ -832,18 +823,18 @@
vfsgnj,vfcmp,vslideup,vslidedown,vislide1up,\
vislide1down,vfslide1up,vfslide1down,vgather,viwmuladd,vfwmuladd,\
vlsegds,vlsegdux,vlsegdox")
- (symbol_ref "INTVAL (operands[8])")
+ (const_int 8)
(eq_attr "type" "vstux,vstox,vssegts,vssegtux,vssegtox")
- (symbol_ref "INTVAL (operands[5])")
+ (const_int 5)
(eq_attr "type" "vimuladd,vfmuladd")
- (symbol_ref "INTVAL (operands[9])")
+ (const_int 9)
(eq_attr "type" "vmsfs,vmidx,vcompress")
- (symbol_ref "INTVAL (operands[6])")
+ (const_int 6)
(eq_attr "type" "vmpop,vmffs,vssegte")
- (symbol_ref "INTVAL (operands[4])")]
+ (const_int 4)]
(const_int INVALID_ATTRIBUTE)))
;; Defines rounding mode of an fixed-point operation.
@@ -889,6 +880,13 @@
""
[(set_attr "type" "vector")])
+(define_insn "@vundefined<mode>"
+ [(set (match_operand:VT 0 "register_operand" "=vr")
+ (unspec:VT [(reg:SI X0_REGNUM)] UNSPEC_VUNDEF))]
+ "TARGET_VECTOR"
+ ""
+ [(set_attr "type" "vector")])
+
(define_expand "@vreinterpret<mode>"
[(set (match_operand:V 0 "register_operand")
(match_operand 1 "vector_any_register_operand"))]
@@ -1208,7 +1206,8 @@
DONE;
}
[(set_attr "type" "vmov,vlde,vste")
- (set_attr "mode" "<VT:MODE>")])
+ (set_attr "mode" "<VT:MODE>")
+ (set (attr "avl_type_idx") (const_int INVALID_ATTRIBUTE))])
;; -----------------------------------------------------------------
;; ---- VLS Moves Operations
@@ -1667,7 +1666,7 @@
"vse<sew>.v\t%2,%0%p1"
[(set_attr "type" "vste")
(set_attr "mode" "<MODE>")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))
+ (set (attr "avl_type_idx") (const_int 4))
(set_attr "vl_op_idx" "3")])
;; vlm.v/vsm.v/vmclr.m/vmset.m.
@@ -1718,7 +1717,7 @@
"vsm.v\t%2,%0"
[(set_attr "type" "vstm")
(set_attr "mode" "<MODE>")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))
+ (set (attr "avl_type_idx") (const_int 4))
(set_attr "vl_op_idx" "3")])
(define_insn "@pred_merge<mode>"
@@ -1787,7 +1786,8 @@
emit_insn (gen_pred_merge<mode> (operands[0], operands[1],
operands[2], boardcast_scalar, operands[4], operands[5],
operands[6], operands[7]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[7])))
DONE;
})
@@ -2104,7 +2104,7 @@
vse<sew>.v\t%3,%0%p1"
[(set_attr "type" "vsts")
(set_attr "mode" "<MODE>")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
;; -------------------------------------------------------------------------------
;; ---- Predicated indexed loads/stores
@@ -2545,7 +2545,8 @@
emit_insn (gen_pred_<optab><mode> (operands[0], operands[1],
operands[2], operands[3], boardcast_scalar, operands[5],
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -2620,7 +2621,8 @@
emit_insn (gen_pred_<optab><mode> (operands[0], operands[1],
operands[2], operands[3], boardcast_scalar, operands[5],
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -2695,7 +2697,8 @@
emit_insn (gen_pred_sub<mode> (operands[0], operands[1],
operands[2], boardcast_scalar, operands[3], operands[5],
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -2812,7 +2815,8 @@
emit_insn (gen_pred_mulh<v_su><mode> (operands[0], operands[1],
operands[2], operands[3], boardcast_scalar, operands[5],
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -2882,7 +2886,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "@pred_sbc<mode>"
[(set (match_operand:VI 0 "register_operand" "=vd,vd")
@@ -2906,7 +2910,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "@pred_adc<mode>_scalar"
[(set (match_operand:VI_QHS 0 "register_operand" "=vd,vd")
@@ -2931,7 +2935,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "@pred_sbc<mode>_scalar"
[(set (match_operand:VI_QHS 0 "register_operand" "=vd,vd")
@@ -2956,7 +2960,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_expand "@pred_adc<mode>_scalar"
[(set (match_operand:VI_D 0 "register_operand")
@@ -2986,7 +2990,8 @@
emit_insn (gen_pred_adc<mode> (operands[0], operands[1],
operands[2], boardcast_scalar, operands[4], operands[5],
operands[6], operands[7]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[7])))
DONE;
})
@@ -3013,7 +3018,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "*pred_adc<mode>_extended_scalar"
[(set (match_operand:VI_D 0 "register_operand" "=vd,vd")
@@ -3039,7 +3044,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_expand "@pred_sbc<mode>_scalar"
[(set (match_operand:VI_D 0 "register_operand")
@@ -3069,7 +3074,8 @@
emit_insn (gen_pred_sbc<mode> (operands[0], operands[1],
operands[2], boardcast_scalar, operands[4], operands[5],
operands[6], operands[7]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[7])))
DONE;
})
@@ -3096,7 +3102,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "*pred_sbc<mode>_extended_scalar"
[(set (match_operand:VI_D 0 "register_operand" "=vd,vd")
@@ -3122,7 +3128,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "@pred_madc<mode>"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr, &vr")
@@ -3141,7 +3147,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_insn "@pred_msbc<mode>"
[(set (match_operand:<VM> 0 "register_operand" "=vr, vr, &vr")
@@ -3160,7 +3166,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_insn "@pred_madc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3180,7 +3186,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_insn "@pred_msbc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3200,7 +3206,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_expand "@pred_madc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand")
@@ -3226,7 +3232,8 @@
[] (rtx *operands, rtx boardcast_scalar) {
emit_insn (gen_pred_madc<mode> (operands[0], operands[1],
boardcast_scalar, operands[3], operands[4], operands[5]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[5])))
DONE;
})
@@ -3248,7 +3255,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_insn "*pred_madc<mode>_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3269,7 +3276,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_expand "@pred_msbc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand")
@@ -3295,7 +3302,8 @@
[] (rtx *operands, rtx boardcast_scalar) {
emit_insn (gen_pred_msbc<mode> (operands[0], operands[1],
boardcast_scalar, operands[3], operands[4], operands[5]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[5])))
DONE;
})
@@ -3317,7 +3325,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_insn "*pred_msbc<mode>_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3338,7 +3346,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_insn "@pred_madc<mode>_overflow"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr, &vr")
@@ -3356,7 +3364,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
(define_insn "@pred_msbc<mode>_overflow"
[(set (match_operand:<VM> 0 "register_operand" "=vr, vr, &vr, &vr")
@@ -3374,7 +3382,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
(define_insn "@pred_madc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3393,7 +3401,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
(define_insn "@pred_msbc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3412,7 +3420,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
(define_expand "@pred_madc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand")
@@ -3437,7 +3445,8 @@
[] (rtx *operands, rtx boardcast_scalar) {
emit_insn (gen_pred_madc<mode>_overflow (operands[0], operands[1],
boardcast_scalar, operands[3], operands[4]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[4])))
DONE;
})
@@ -3458,7 +3467,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
(define_insn "*pred_madc<mode>_overflow_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3478,7 +3487,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
(define_expand "@pred_msbc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand")
@@ -3503,7 +3512,8 @@
[] (rtx *operands, rtx boardcast_scalar) {
emit_insn (gen_pred_msbc<mode>_overflow (operands[0], operands[1],
boardcast_scalar, operands[3], operands[4]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[4])))
DONE;
})
@@ -3524,7 +3534,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
(define_insn "*pred_msbc<mode>_overflow_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=vr, &vr")
@@ -3544,7 +3554,7 @@
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+ (set (attr "avl_type_idx") (const_int 4))])
;; -------------------------------------------------------------------------------
;; ---- Predicated integer unary operations
@@ -3574,7 +3584,7 @@
(set_attr "vl_op_idx" "4")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; -------------------------------------------------------------------------------
;; ---- Predicated integer widening binary operations
@@ -3825,7 +3835,7 @@
(set_attr "vl_op_idx" "4")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; -------------------------------------------------------------------------------
;; ---- Predicated integer Narrowing operations
@@ -3901,7 +3911,7 @@
(set_attr "vl_op_idx" "4")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; -------------------------------------------------------------------------------
;; ---- Predicated fixed-point operations
@@ -4014,7 +4024,8 @@
emit_insn (gen_pred_<optab><mode> (operands[0], operands[1],
operands[2], operands[3], boardcast_scalar, operands[5],
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -4089,7 +4100,8 @@
emit_insn (gen_pred_<optab><mode> (operands[0], operands[1],
operands[2], operands[3], boardcast_scalar, operands[5],
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -4234,7 +4246,8 @@
emit_insn (gen_pred_<sat_op><mode> (operands[0], operands[1],
operands[2], operands[3], boardcast_scalar, operands[5],
operands[6], operands[7], operands[8], operands[9]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -4373,7 +4386,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_cmp<mode>"
@@ -4453,7 +4466,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_ltge<mode>"
@@ -4535,7 +4548,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_cmp<mode>_scalar"
@@ -4619,7 +4632,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_eqne<mode>_scalar"
@@ -4700,7 +4713,8 @@
emit_insn (gen_pred_cmp<mode> (operands[0], operands[1],
operands[2], operands[3], operands[4], boardcast_scalar,
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -4732,7 +4746,8 @@
emit_insn (gen_pred_cmp<mode> (operands[0], operands[1],
operands[2], operands[3], operands[4], boardcast_scalar,
operands[6], operands[7], operands[8]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[8])))
DONE;
})
@@ -4758,7 +4773,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "*pred_eqne<mode>_scalar_merge_tie_mask"
[(set (match_operand:<VM> 0 "register_operand" "=vm")
@@ -4782,7 +4797,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_cmp<mode>_scalar"
@@ -4891,7 +4906,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_cmp<mode>_extended_scalar"
@@ -4959,7 +4974,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_eqne<mode>_extended_scalar"
@@ -5207,7 +5222,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_insn "*pred_macc<mode>"
[(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr")
@@ -5238,7 +5253,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_expand "@pred_mul_plus<mode>_scalar"
[(set (match_operand:V_VLSI_QHS 0 "register_operand")
@@ -5291,7 +5306,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_insn "*pred_macc<mode>_scalar"
[(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr")
@@ -5323,7 +5338,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_expand "@pred_mul_plus<mode>_scalar"
[(set (match_operand:V_VLSI_D 0 "register_operand")
@@ -5355,7 +5370,8 @@
emit_insn (gen_pred_mul_plus<mode> (operands[0], operands[1],
boardcast_scalar, operands[3], operands[4], operands[5],
operands[6], operands[7], operands[8], operands[9]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[9])))
DONE;
})
@@ -5390,7 +5406,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_insn "*pred_macc<mode>_extended_scalar"
[(set (match_operand:V_VLSI_D 0 "register_operand" "=vd,?&vd, vr,?&vr")
@@ -5423,7 +5439,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_expand "@pred_minus_mul<mode>"
[(set (match_operand:V_VLSI 0 "register_operand")
@@ -5504,7 +5520,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_insn "*pred_nmsac<mode>"
[(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr")
@@ -5535,7 +5551,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_expand "@pred_minus_mul<mode>_scalar"
[(set (match_operand:V_VLSI_QHS 0 "register_operand")
@@ -5588,7 +5604,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_insn "*pred_nmsac<mode>_scalar"
[(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr")
@@ -5620,7 +5636,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_expand "@pred_minus_mul<mode>_scalar"
[(set (match_operand:V_VLSI_D 0 "register_operand")
@@ -5652,7 +5668,8 @@
emit_insn (gen_pred_minus_mul<mode> (operands[0], operands[1],
boardcast_scalar, operands[3], operands[4], operands[5],
operands[6], operands[7], operands[8], operands[9]));
- }))
+ },
+ (riscv_vector::avl_type) INTVAL (operands[9])))
DONE;
})
@@ -5687,7 +5704,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
(define_insn "*pred_nmsac<mode>_extended_scalar"
[(set (match_operand:V_VLSI_D 0 "register_operand" "=vd,?&vd, vr,?&vr")
@@ -5720,7 +5737,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
+ (set (attr "avl_type_idx") (const_int 8))])
;; -------------------------------------------------------------------------------
;; ---- Predicated widen integer ternary operations
@@ -5887,7 +5904,7 @@
[(set_attr "type" "vmalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "5")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))])
+ (set (attr "avl_type_idx") (const_int 6))])
(define_insn "@pred_n<optab><mode>"
[(set (match_operand:VB_VLS 0 "register_operand" "=vr")
@@ -5908,7 +5925,7 @@
[(set_attr "type" "vmalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "5")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))])
+ (set (attr "avl_type_idx") (const_int 6))])
(define_insn "@pred_<optab>not<mode>"
[(set (match_operand:VB_VLS 0 "register_operand" "=vr")
@@ -5929,7 +5946,7 @@
[(set_attr "type" "vmalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "5")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))])
+ (set (attr "avl_type_idx") (const_int 6))])
(define_insn "@pred_not<mode>"
[(set (match_operand:VB_VLS 0 "register_operand" "=vr")
@@ -5948,7 +5965,7 @@
[(set_attr "type" "vmalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+ (set (attr "avl_type_idx") (const_int 5))])
(define_insn "@pred_popcount<VB:mode><P:mode>"
[(set (match_operand:P 0 "register_operand" "=r")
@@ -6093,6 +6110,27 @@
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>"
+ [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:V_VLSF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")
+ (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")]
+ UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
@@ -6139,6 +6177,28 @@
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>_scalar"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:VF
+ [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")
+ (vec_duplicate:VF
+ (match_operand:<VEL> 4 "register_operand" " f, f, f, f"))]
+ UNSPEC_VFMAXMIN)
+ (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vf\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
@@ -6367,7 +6427,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6402,7 +6462,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6461,7 +6521,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6497,7 +6557,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6591,7 +6651,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6627,7 +6687,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6688,7 +6748,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6725,7 +6785,7 @@
(set_attr "vl_op_idx" "5")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))
+ (set (attr "avl_type_idx") (const_int 8))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
@@ -6763,7 +6823,7 @@
(set_attr "vl_op_idx" "4")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))
+ (set (attr "avl_type_idx") (const_int 7))
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[8])"))])
@@ -6788,7 +6848,7 @@
(set_attr "vl_op_idx" "4")
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
(define_insn "@pred_<misc_op><mode>"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
@@ -7177,7 +7237,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We use early-clobber for source LMUL > dest LMUL.
(define_insn "*pred_cmp<mode>_narrow"
@@ -7239,7 +7299,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_cmp<mode>_scalar"
@@ -7323,7 +7383,7 @@
(set_attr "merge_op_idx" "1")
(set_attr "vl_op_idx" "5")
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+ (set (attr "avl_type_idx") (const_int 7))])
;; We don't use early-clobber for LMUL <= 1 to get better codegen.
(define_insn "*pred_eqne<mode>_scalar"
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index cc24dd5..9f75067 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -23647,10 +23647,10 @@ altivec_expand_vec_perm_const (rtx target, rtx op0, rtx op1,
&& GET_MODE (XEXP (op0, 0)) != V8HImode)))
continue;
- /* For little-endian, the two input operands must be swapped
- (or swapped back) to ensure proper right-to-left numbering
- from 0 to 2N-1. */
- if (swapped ^ !BYTES_BIG_ENDIAN
+ /* For little-endian, the two input operands must be swapped
+ (or swapped back) to ensure proper right-to-left numbering
+ from 0 to 2N-1. */
+ if (swapped == BYTES_BIG_ENDIAN
&& icode != CODE_FOR_vsx_xxpermdi_v16qi)
std::swap (op0, op1);
if (imode != V16QImode)
diff --git a/gcc/config/sh/sh_treg_combine.cc b/gcc/config/sh/sh_treg_combine.cc
index 9f6a89f..9b35960 100644
--- a/gcc/config/sh/sh_treg_combine.cc
+++ b/gcc/config/sh/sh_treg_combine.cc
@@ -729,7 +729,14 @@ sh_treg_combine::record_set_of_reg (rtx reg, rtx_insn *start_insn,
}
else if (REG_P (new_entry.cstore.set_src ()))
{
- // If it's a reg-reg copy follow the copied reg.
+ // If it's a reg-reg copy follow the copied reg, but ignore
+ // nop copies of the reg onto itself.
+ if (REGNO (new_entry.cstore.set_src ()) == REGNO (reg))
+ {
+ i = prev_nonnote_nondebug_insn_bb (i);
+ continue;
+ }
+
new_entry.cstore_reg_reg_copies.push_back (new_entry.cstore);
reg = new_entry.cstore.set_src ();
i = new_entry.cstore.insn;
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 5987681..49e6350 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -54,7 +54,7 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_WINDOWED_ABI xtensa_windowed_abi
#define TARGET_DEBUG XCHAL_HAVE_DEBUG
#define TARGET_L32R XCHAL_HAVE_L32R
-#define TARGET_SALT (XTENSA_MARCH_EARLIEST >= 260000)
+#define TARGET_SALT (XTENSA_MARCH_EARLIEST >= 270000)
#define TARGET_DEFAULT (MASK_SERIALIZE_VOLATILE)
diff --git a/gcc/configure b/gcc/configure
index 13085f3..d4ad988 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -844,6 +844,7 @@ enable_gcov
enable_shared
enable_fixed_point
enable_decimal_float
+DEFAULT_INSNEMIT_PARTITIONS
DEFAULT_MATCHPD_PARTITIONS
with_float
with_cpu
@@ -973,6 +974,7 @@ enable_multilib
enable_multiarch
with_stack_clash_protection_guard_size
with_matchpd_partitions
+with_insnemit_partitions
enable___cxa_atexit
enable_decimal_float
enable_fixed_point
@@ -1012,6 +1014,7 @@ with_pic
enable_fast_install
enable_libtool_lock
enable_darwin_at_rpath
+with_darwin_extra_rpath
enable_ld
enable_gold
with_plugin_ld
@@ -1845,6 +1848,9 @@ Optional Packages:
--with-matchpd-partitions=num
Set the number of partitions to make for gimple and
generic when splitting match.pd. [default=10]
+ --with-insnemit-partitions=num
+ Set the number of partitions of insn-emit.cc for
+ genemit to create. [default=10]
--with-dwarf2 force the default debug format to be DWARF 2 (or
later)
--with-specs=SPECS add SPECS to driver command-line processing
@@ -1873,6 +1879,9 @@ Optional Packages:
--with-pic try to use only PIC/non-PIC objects [default=use
both]
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-darwin-extra-rpath=[ARG]
+ Specify a runpath directory, additional to those
+ provided by the compiler
--with-plugin-ld=[ARG] specify the plugin linker
--with-glibc-version=M.N
assume GCC used with glibc version M.N or later
@@ -7944,6 +7953,21 @@ fi
+# Specify the number of splits of insn-emit.cc to generate.
+
+# Check whether --with-insnemit-partitions was given.
+if test "${with_insnemit_partitions+set}" = set; then :
+ withval=$with_insnemit_partitions; DEFAULT_INSNEMIT_PARTITIONS="$with_insnemit_partitions"
+else
+ DEFAULT_INSNEMIT_PARTITIONS=10
+fi
+
+if (test $DEFAULT_INSNEMIT_PARTITIONS -lt 1); then
+ as_fn_error $? "Invalid value $DEFAULT_INSNEMIT_PARTITIONS for --with-insnemit-partitions. Cannot be negative." "$LINENO" 5
+fi
+
+
+
# Enable __cxa_atexit for C++.
# Check whether --enable-__cxa_atexit was given.
if test "${enable___cxa_atexit+set}" = set; then :
@@ -19976,7 +20000,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19979 "configure"
+#line 19995 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -20082,7 +20106,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 20085 "configure"
+#line 20101 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -23410,6 +23434,26 @@ else
ENABLE_DARWIN_AT_RPATH_FALSE=
fi
+DARWIN_DO_EXTRA_RPATH=0
+
+# Check whether --with-darwin-extra-rpath was given.
+if test "${with_darwin_extra_rpath+set}" = set; then :
+ withval=$with_darwin_extra_rpath; if test x"$withval" != x; then
+ DARWIN_ADD_RPATH="$withval"
+ DARWIN_DO_EXTRA_RPATH=1
+ fi
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DARWIN_DO_EXTRA_RPATH $DARWIN_DO_EXTRA_RPATH
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DARWIN_ADD_RPATH "$DARWIN_ADD_RPATH"
+_ACEOF
+
# Identify the assembler which will work hand-in-glove with the newly
# built GCC, so that we can examine its features. This is the assembler
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 0ac589a..dc8cb6a 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -956,6 +956,19 @@ fi
AC_SUBST(DEFAULT_MATCHPD_PARTITIONS)
+# Specify the number of splits of insn-emit.cc to generate.
+AC_ARG_WITH(insnemit-partitions,
+[AS_HELP_STRING([--with-insnemit-partitions=num],
+[Set the number of partitions of insn-emit.cc for genemit to create. [default=10]])],
+[DEFAULT_INSNEMIT_PARTITIONS="$with_insnemit_partitions"], [DEFAULT_INSNEMIT_PARTITIONS=10])
+if (test $DEFAULT_INSNEMIT_PARTITIONS -lt 1); then
+ AC_MSG_ERROR(m4_normalize([
+ Invalid value $DEFAULT_INSNEMIT_PARTITIONS for --with-insnemit-partitions. \
+ Cannot be negative.]))
+fi
+
+AC_SUBST(DEFAULT_INSNEMIT_PARTITIONS)
+
# Enable __cxa_atexit for C++.
AC_ARG_ENABLE(__cxa_atexit,
[AS_HELP_STRING([--enable-__cxa_atexit], [enable __cxa_atexit for C++])],
@@ -2633,6 +2646,19 @@ AC_SUBST(objdir)
AC_SUBST(enable_fast_install)
AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes])
+DARWIN_DO_EXTRA_RPATH=0
+AC_ARG_WITH(darwin-extra-rpath,
+[AS_HELP_STRING(
+ [[--with-darwin-extra-rpath=[ARG]]],
+ [Specify a runpath directory, additional to those provided by the compiler])],
+[if test x"$withval" != x; then
+ DARWIN_ADD_RPATH="$withval"
+ DARWIN_DO_EXTRA_RPATH=1
+ fi])
+AC_DEFINE_UNQUOTED(DARWIN_DO_EXTRA_RPATH, $DARWIN_DO_EXTRA_RPATH,
+ [Should add an extra runpath directory])
+AC_DEFINE_UNQUOTED(DARWIN_ADD_RPATH, "$DARWIN_ADD_RPATH",
+ [Specify a runpath directory, additional to those provided by the compiler])
# Identify the assembler which will work hand-in-glove with the newly
# built GCC, so that we can examine its features. This is the assembler
diff --git a/gcc/convert.cc b/gcc/convert.cc
index 64b7001..ac6af70 100644
--- a/gcc/convert.cc
+++ b/gcc/convert.cc
@@ -96,7 +96,7 @@ convert_to_pointer_1 (tree type, tree expr, bool fold_p)
default:
error ("cannot convert to a pointer type");
- return convert_to_pointer_1 (type, integer_zero_node, fold_p);
+ return error_mark_node;
}
}
@@ -332,11 +332,11 @@ convert_to_real_1 (tree type, tree expr, bool fold_p)
case POINTER_TYPE:
case REFERENCE_TYPE:
error ("pointer value used where a floating-point was expected");
- return convert_to_real_1 (type, integer_zero_node, fold_p);
+ return error_mark_node;
default:
error ("aggregate value used where a floating-point was expected");
- return convert_to_real_1 (type, integer_zero_node, fold_p);
+ return error_mark_node;
}
}
@@ -959,7 +959,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
default:
error ("aggregate value used where an integer was expected");
- return convert (type, integer_zero_node);
+ return error_mark_node;
}
}
@@ -1006,8 +1006,13 @@ convert_to_complex_1 (tree type, tree expr, bool fold_p)
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
case BITINT_TYPE:
- return build2 (COMPLEX_EXPR, type, convert (subtype, expr),
- convert (subtype, integer_zero_node));
+ {
+ tree real = convert (subtype, expr);
+ tree imag = convert (subtype, integer_zero_node);
+ if (error_operand_p (real) || error_operand_p (imag))
+ return error_mark_node;
+ return build2 (COMPLEX_EXPR, type, real, imag);
+ }
case COMPLEX_TYPE:
{
@@ -1048,11 +1053,11 @@ convert_to_complex_1 (tree type, tree expr, bool fold_p)
case POINTER_TYPE:
case REFERENCE_TYPE:
error ("pointer value used where a complex was expected");
- return convert_to_complex_1 (type, integer_zero_node, fold_p);
+ return error_mark_node;
default:
error ("aggregate value used where a complex was expected");
- return convert_to_complex_1 (type, integer_zero_node, fold_p);
+ return error_mark_node;
}
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 95755e6..6f812e2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,94 @@
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * module.cc (ordinary_loc_of): Update for removal of
+ MACRO_MAP_EXPANSION_POINT_LOCATION.
+ (module_state::note_location): Update for renaming of field.
+ (module_state::write_macro_maps): Likewise.
+
+2023-10-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/111929
+ * init.cc (build_new_1): Remove unnecessary call to convert
+ on 'nelts'. Use build2 instead of fold_build2 for
+ 'outer_nelts_checks'.
+
+2023-10-27 Patrick Palka <ppalka@redhat.com>
+
+ * cp-tree.h (maybe_warn_unparenthesized_assignment): Declare.
+ * semantics.cc (is_assignment_op_expr_p): Generalize to return
+ true for any assignment operator expression, not just one that
+ has been resolved to an operator overload.
+ (maybe_warn_unparenthesized_assignment): Factored out from ...
+ (maybe_convert_cond): ... here.
+ (finish_parenthesized_expr): Mention
+ maybe_warn_unparenthesized_assignment.
+ * typeck.cc (convert_for_assignment): Replace -Wparentheses
+ warning logic with maybe_warn_unparenthesized_assignment.
+
+2023-10-27 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/87299
+ * parser.cc (cp_lexer_new_main): Call c_reset_target_pragmas ()
+ after preprocessing is complete, before starting compilation.
+
+2023-10-26 liuhongt <hongtao.liu@intel.com>
+
+ * typeck.cc (build_vec_cmp): Pass type of arg0 to
+ truth_type_for.
+
+2023-10-25 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.def: Improve OFFSET_REF comment.
+ * cp-gimplify.cc (cp_fold_immediate): Add to comment.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * parser.cc (cp_parser_omp_clause_name): Return
+ 'PRAGMA_OACC_CLAUSE_SELF' for "self".
+ (cp_parser_oacc_data_clause, OACC_UPDATE_CLAUSE_MASK): Adjust.
+ (cp_parser_oacc_all_clauses): Remove 'bool compute_p' formal
+ parameter, and instead locally determine whether we're called for
+ an OpenACC compute construct or OpenACC 'update' directive.
+ (cp_parser_oacc_compute): Adjust.
+
+2023-10-25 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * parser.cc (cp_parser_oacc_compute_clause_self): New function.
+ (cp_parser_oacc_all_clauses): Add new 'bool compute_p = false'
+ parameter, add parsing of self clause when compute_p is true.
+ (OACC_KERNELS_CLAUSE_MASK): Add PRAGMA_OACC_CLAUSE_SELF.
+ (OACC_PARALLEL_CLAUSE_MASK): Likewise,
+ (OACC_SERIAL_CLAUSE_MASK): Likewise.
+ (cp_parser_oacc_compute): Adjust call to c_parser_oacc_all_clauses to
+ set compute_p argument to true.
+ * pt.cc (tsubst_omp_clauses): Add OMP_CLAUSE_SELF case.
+ * semantics.cc (c_finish_omp_clauses): Add OMP_CLAUSE_SELF case, merged
+ with OMP_CLAUSE_IF case.
+
+2023-10-25 Marek Polacek <polacek@redhat.com>
+
+ PR c++/111895
+ * typeck.cc (build_static_cast_1): Call decay_conversion.
+
+2023-10-24 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/111929
+ * init.cc (build_new_1): Use convert, build2, build3 and
+ cp_fully_fold instead of fold_convert, size_binop and
+ fold_build3 when building up 'size'.
+
+2023-10-24 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/111919
+ * tree.cc (cp_stabilize_reference): Do nothing when
+ processing_template_decl.
+
+2023-10-22 Patrick Palka <ppalka@redhat.com>
+
+ PR objc++/111920
+ * pt.cc (tsubst_expr) <case AT_ENCODE_EXPR>: Use tsubst instead
+ of tsubst_expr.
+
2023-10-20 Jason Merrill <jason@redhat.com>
* call.cc (implicit_conversion_1): Rename...
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 33e9411..9375a11 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1132,7 +1132,14 @@ cp_fold_immediate (tree *tp, mce_value manifestly_const_eval)
Note: The folding of non-omp cases is something to move into
the middle-end. As for now we have most foldings only on GENERIC
in fold-const, we need to perform this before transformation to
- GIMPLE-form. */
+ GIMPLE-form.
+
+ ??? This is algorithmically weird because walk_tree works in pre-order, so
+ we see outer expressions before inner expressions. This isn't as much of an
+ issue because cp_fold recurses into subexpressions in many cases, but then
+ walk_tree walks back into those subexpressions again. We avoid the
+ resulting complexity problem by caching the result of cp_fold, but it's
+ inelegant. */
static tree
cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index d78005e..bf3bcd1 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -24,13 +24,14 @@ along with GCC; see the file COPYING3. If not see
/* An OFFSET_REF is used in two situations:
1. An expression of the form `A::m' where `A' is a class and `m' is
- a non-static member. In this case, operand 0 will be a TYPE
- (corresponding to `A') and operand 1 will be a FIELD_DECL,
- BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
-
- The expression is a pointer-to-member if its address is taken,
- but simply denotes a member of the object if its address is not
- taken.
+ a non-static member or an overload set. In this case, operand 0
+ will be a TYPE (corresponding to `A') and operand 1 will be a
+ FIELD_DECL, BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
+
+ The expression is a pointer-to-member if its address is taken (and
+ if, after any overload resolution, 'm' does not designate a
+ static or explicit object member function). It simply denotes a
+ member of the object if its address is not taken.
This form is only used during the parsing phase; once semantic
analysis has taken place they are eliminated.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 30fe716..98b29e9 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7875,6 +7875,7 @@ extern tree lambda_regenerating_args (tree);
extern tree most_general_lambda (tree);
extern tree finish_omp_target (location_t, tree, tree, bool);
extern void finish_omp_target_clauses (location_t, tree, tree *);
+extern void maybe_warn_unparenthesized_assignment (tree, tsubst_flags_t);
/* in tree.cc */
extern int cp_tree_operand_length (const_tree);
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index d48bb16..6444f0a 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -3261,7 +3261,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
max_outer_nelts = wi::udiv_trunc (max_size, inner_size);
max_outer_nelts_tree = wide_int_to_tree (sizetype, max_outer_nelts);
- size = size_binop (MULT_EXPR, size, fold_convert (sizetype, nelts));
+ size = build2 (MULT_EXPR, sizetype, size, nelts);
if (TREE_CODE (cst_outer_nelts) == INTEGER_CST)
{
@@ -3293,9 +3293,9 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
- wi::clz (max_outer_nelts);
max_outer_nelts = (max_outer_nelts >> shift) << shift;
- outer_nelts_check = fold_build2 (LE_EXPR, boolean_type_node,
- outer_nelts,
- max_outer_nelts_tree);
+ outer_nelts_check = build2 (LE_EXPR, boolean_type_node,
+ outer_nelts,
+ max_outer_nelts_tree);
}
}
@@ -3344,7 +3344,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
/* Use a class-specific operator new. */
/* If a cookie is required, add some extra space. */
if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
- size = size_binop (PLUS_EXPR, size, cookie_size);
+ size = build2 (PLUS_EXPR, sizetype, size, cookie_size);
else
{
cookie_size = NULL_TREE;
@@ -3358,8 +3358,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
if (cxx_dialect >= cxx11 && flag_exceptions)
errval = throw_bad_array_new_length ();
if (outer_nelts_check != NULL_TREE)
- size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
- size, errval);
+ size = build3 (COND_EXPR, sizetype, outer_nelts_check, size, errval);
+ size = cp_fully_fold (size);
/* Create the argument list. */
vec_safe_insert (*placement, 0, size);
/* Do name-lookup to find the appropriate operator. */
@@ -3415,6 +3415,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
outer_nelts_check = NULL_TREE;
}
+ size = cp_fully_fold (size);
/* If size is zero e.g. due to type having zero size, try to
preserve outer_nelts for constant expression evaluation
purposes. */
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 539518d..c1c8c22 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13937,7 +13937,7 @@ ordinary_loc_of (line_maps *lmaps, location_t from)
/* Find the ordinary location nearest FROM. */
const line_map *map = linemap_lookup (lmaps, from);
const line_map_macro *mac_map = linemap_check_macro (map);
- from = MACRO_MAP_EXPANSION_POINT_LOCATION (mac_map);
+ from = mac_map->get_expansion_point_location ();
}
}
return from;
@@ -15779,7 +15779,7 @@ module_state::note_location (location_t loc)
slot->remap = 0;
// Expansion locations could themselves be from a
// macro, we need to note them all.
- note_location (mac_map->expansion);
+ note_location (mac_map->m_expansion);
gcc_checking_assert (mac_map->n_tokens);
location_t tloc = UNKNOWN_LOCATION;
for (unsigned ix = mac_map->n_tokens * 2; ix--;)
@@ -16375,7 +16375,7 @@ module_state::write_macro_maps (elf_out *to, range_t &info, unsigned *crc_p)
sec.u (iter->remap);
sec.u (mac->n_tokens);
sec.cpp_node (mac->macro);
- write_location (sec, mac->expansion);
+ write_location (sec, mac->m_expansion);
const location_t *locs = mac->macro_locations;
/* There are lots of identical runs. */
location_t prev = UNKNOWN_LOCATION;
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 5483121..5f13904 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -766,6 +766,12 @@ cp_lexer_new_main (void)
maybe_check_all_macros (parse_in);
+ /* If we processed any #pragma GCC target directives, we handled them early so
+ any macros they defined would be effective during preprocessing. Now, we
+ need to reset to the default state to begin compilation, and we will
+ process them again at the correct time as needed. */
+ c_reset_target_pragmas ();
+
gcc_assert (!lexer->next_token->purged_p);
return lexer;
}
@@ -37566,8 +37572,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OMP_CLAUSE_SCHEDULE;
else if (!strcmp ("sections", p))
result = PRAGMA_OMP_CLAUSE_SECTIONS;
- else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
- result = PRAGMA_OACC_CLAUSE_HOST;
+ else if (!strcmp ("self", p))
+ result = PRAGMA_OACC_CLAUSE_SELF;
else if (!strcmp ("seq", p))
result = PRAGMA_OACC_CLAUSE_SEQ;
else if (!strcmp ("shared", p))
@@ -38004,9 +38010,6 @@ cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
kind = GOMP_MAP_DEVICE_RESIDENT;
break;
- case PRAGMA_OACC_CLAUSE_HOST:
- kind = GOMP_MAP_FORCE_FROM;
- break;
case PRAGMA_OACC_CLAUSE_LINK:
kind = GOMP_MAP_LINK;
break;
@@ -38016,6 +38019,11 @@ cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
case PRAGMA_OACC_CLAUSE_PRESENT:
kind = GOMP_MAP_FORCE_PRESENT;
break;
+ case PRAGMA_OACC_CLAUSE_SELF:
+ /* "The 'host' clause is a synonym for the 'self' clause." */
+ case PRAGMA_OACC_CLAUSE_HOST:
+ kind = GOMP_MAP_FORCE_FROM;
+ break;
default:
gcc_unreachable ();
}
@@ -41192,6 +41200,44 @@ cp_parser_oacc_clause_async (cp_parser *parser, tree list)
return list;
}
+/* OpenACC 2.7:
+ self [( expression )] */
+
+static tree
+cp_parser_oacc_compute_clause_self (cp_parser *parser, tree list)
+{
+ tree t;
+ location_t location = cp_lexer_peek_token (parser->lexer)->location;
+ if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
+ {
+ matching_parens parens;
+ parens.consume_open (parser);
+ t = cp_parser_assignment_expression (parser);
+ if (t == error_mark_node
+ || !parens.require_close (parser))
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+ }
+ }
+ else
+ t = truthvalue_true_node;
+
+ for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
+ {
+ error_at (location, "too many %<self%> clauses");
+ return list;
+ }
+
+ tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
+ OMP_CLAUSE_SELF_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
/* Parse all OpenACC clauses. The set clauses allowed by the directive
is a bitmask in MASK. Return the list of clauses found. */
@@ -41352,6 +41398,15 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
false, clauses);
c_name = "reduction";
break;
+ case PRAGMA_OACC_CLAUSE_SELF:
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
+ /* OpenACC compute construct */
+ clauses = cp_parser_oacc_compute_clause_self (parser, clauses);
+ else
+ /* OpenACC 'update' directive */
+ clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
+ c_name = "self";
+ break;
case PRAGMA_OACC_CLAUSE_SEQ:
clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
clauses);
@@ -46866,6 +46921,7 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
@@ -46886,6 +46942,7 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
@@ -46904,6 +46961,7 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
static tree
@@ -46968,6 +47026,7 @@ cp_parser_oacc_compute (cp_parser *parser, cp_token *pragma_tok,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT))
static tree
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 210c6cb..86c95b2 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -17418,6 +17418,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
/* FALLTHRU */
case OMP_CLAUSE_TILE:
case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_COLLAPSE:
@@ -20261,7 +20262,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
op1 = TREE_OPERAND (t, 0);
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
- op1 = tsubst_expr (op1, args, complain, in_decl);
+ op1 = tsubst (op1, args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
RETURN (objc_build_encode_expr (op1));
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index dc3c114..52044be 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -840,15 +840,20 @@ finish_goto_stmt (tree destination)
return add_stmt (build_stmt (input_location, GOTO_EXPR, destination));
}
-/* Returns true if CALL is a (possibly wrapped) CALL_EXPR or AGGR_INIT_EXPR
- to operator= () that is written as an operator expression. */
+/* Returns true if T corresponds to an assignment operator expression. */
+
static bool
-is_assignment_op_expr_p (tree call)
+is_assignment_op_expr_p (tree t)
{
- if (call == NULL_TREE)
+ if (t == NULL_TREE)
return false;
- call = extract_call_expr (call);
+ if (TREE_CODE (t) == MODIFY_EXPR
+ || (TREE_CODE (t) == MODOP_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR))
+ return true;
+
+ tree call = extract_call_expr (t);
if (call == NULL_TREE
|| call == error_mark_node
|| !CALL_EXPR_OPERATOR_SYNTAX (call))
@@ -860,6 +865,28 @@ is_assignment_op_expr_p (tree call)
&& DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR);
}
+/* Maybe warn about an unparenthesized 'a = b' (appearing in a
+ boolean context where 'a == b' might have been intended). */
+
+void
+maybe_warn_unparenthesized_assignment (tree t, tsubst_flags_t complain)
+{
+ if (REFERENCE_REF_P (t))
+ t = TREE_OPERAND (t, 0);
+
+ if ((complain & tf_warning)
+ && warn_parentheses
+ && is_assignment_op_expr_p (t)
+ /* A parenthesized expression would've had this warning
+ suppressed by finish_parenthesized_expr. */
+ && !warning_suppressed_p (t, OPT_Wparentheses))
+ {
+ warning_at (cp_expr_loc_or_input_loc (t), OPT_Wparentheses,
+ "suggest parentheses around assignment used as truth value");
+ suppress_warning (t, OPT_Wparentheses);
+ }
+}
+
/* COND is the condition-expression for an if, while, etc.,
statement. Convert it to a boolean value, if appropriate.
In addition, verify sequence points if -Wsequence-point is enabled. */
@@ -878,21 +905,10 @@ maybe_convert_cond (tree cond)
if (warn_sequence_point && !processing_template_decl)
verify_sequence_points (cond);
+ maybe_warn_unparenthesized_assignment (cond, tf_warning_or_error);
+
/* Do the conversion. */
cond = convert_from_reference (cond);
-
- tree inner = REFERENCE_REF_P (cond) ? TREE_OPERAND (cond, 0) : cond;
- if ((TREE_CODE (inner) == MODIFY_EXPR
- || (TREE_CODE (inner) == MODOP_EXPR
- && TREE_CODE (TREE_OPERAND (inner, 1)) == NOP_EXPR)
- || is_assignment_op_expr_p (inner))
- && warn_parentheses
- && !warning_suppressed_p (inner, OPT_Wparentheses)
- && warning_at (cp_expr_loc_or_input_loc (inner),
- OPT_Wparentheses, "suggest parentheses around "
- "assignment used as truth value"))
- suppress_warning (inner, OPT_Wparentheses);
-
return condition_conversion (cond);
}
@@ -2158,7 +2174,8 @@ finish_parenthesized_expr (cp_expr expr)
{
if (EXPR_P (expr))
{
- /* This inhibits warnings in c_common_truthvalue_conversion. */
+ /* This inhibits warnings in maybe_warn_unparenthesized_assignment
+ and c_common_truthvalue_conversion. */
tree inner = REFERENCE_REF_P (expr) ? TREE_OPERAND (expr, 0) : *expr;
suppress_warning (inner, OPT_Wparentheses);
}
@@ -7377,13 +7394,14 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
goto handle_field_decl;
case OMP_CLAUSE_IF:
- t = OMP_CLAUSE_IF_EXPR (c);
+ case OMP_CLAUSE_SELF:
+ t = OMP_CLAUSE_OPERAND (c, 0);
t = maybe_convert_cond (t);
if (t == error_mark_node)
remove = true;
else if (!processing_template_decl)
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
- OMP_CLAUSE_IF_EXPR (c) = t;
+ OMP_CLAUSE_OPERAND (c, 0) = t;
break;
case OMP_CLAUSE_FINAL:
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index a3d61d3..417c92b 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -408,6 +408,10 @@ bitfield_p (const_tree ref)
tree
cp_stabilize_reference (tree ref)
{
+ if (processing_template_decl)
+ /* As in cp_save_expr. */
+ return ref;
+
STRIP_ANY_LOCATION_WRAPPER (ref);
switch (TREE_CODE (ref))
{
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index f3dc80c..49afbd8 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4820,7 +4820,7 @@ build_vec_cmp (tree_code code, tree type,
{
tree zero_vec = build_zero_cst (type);
tree minus_one_vec = build_minus_one_cst (type);
- tree cmp_type = truth_type_for (type);
+ tree cmp_type = truth_type_for (TREE_TYPE (arg0));
tree cmp = build2 (code, cmp_type, arg0, arg1);
return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
}
@@ -8405,6 +8405,13 @@ build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
return expr;
if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
expr = TREE_OPERAND (expr, 0);
+ /* [expr.static.cast]: "If the value is not a bit-field, the result
+ refers to the object or the specified base class subobject thereof;
+ otherwise, the lvalue-to-rvalue conversion is applied to the
+ bit-field and the resulting prvalue is used as the operand of the
+ static_cast." There are no prvalue bit-fields; the l-to-r conversion
+ will give us an object of the underlying type of the bit-field. */
+ expr = decay_conversion (expr, complain);
return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
}
@@ -10331,16 +10338,9 @@ convert_for_assignment (tree type, tree rhs,
/* If -Wparentheses, warn about a = b = c when a has type bool and b
does not. */
- if (warn_parentheses
- && TREE_CODE (type) == BOOLEAN_TYPE
- && TREE_CODE (rhs) == MODIFY_EXPR
- && !warning_suppressed_p (rhs, OPT_Wparentheses)
- && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE
- && (complain & tf_warning)
- && warning_at (rhs_loc, OPT_Wparentheses,
- "suggest parentheses around assignment used as "
- "truth value"))
- suppress_warning (rhs, OPT_Wparentheses);
+ if (TREE_CODE (type) == BOOLEAN_TYPE
+ && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE)
+ maybe_warn_unparenthesized_assignment (rhs, complain);
if (complain & tf_warning)
warn_for_address_or_pointer_of_packed_member (type, rhs);
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 5c44bfe..fda82b1 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,63 @@
+2023-10-31 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * expr.cc (ExprVisitor::visit (NewExp *)): Remove unused assignments.
+
+2023-10-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110712
+ * d-codegen.cc (d_build_call): Update call to convert_for_argument.
+ * d-convert.cc (is_valist_parameter_type): New function.
+ (check_valist_conversion): New function.
+ (convert_for_assignment): Update signature. Add check whether
+ assigning va_list is permissible.
+ (convert_for_argument): Likewise.
+ * d-tree.h (convert_for_assignment): Update signature.
+ (convert_for_argument): Likewise.
+ * expr.cc (ExprVisitor::visit (AssignExp *)): Update call to
+ convert_for_assignment.
+
+2023-10-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd e48bc0987d.
+ * expr.cc (ExprVisitor::visit (NewExp *)): Update for new front-end
+ interface.
+ * runtime.def (NEWARRAYT): Remove.
+ (NEWARRAYIT): Remove.
+
+2023-10-28 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/112270
+ * d-builtins.cc (d_build_d_type_nodes): Initialize d_bool_false_node,
+ d_bool_true_node.
+ * d-codegen.cc (build_array_struct_comparison): Use d_bool_false_node
+ instead of boolean_false_node.
+ * d-convert.cc (d_truthvalue_conversion): Use d_bool_false_node and
+ d_bool_true_node instead of boolean_false_node and boolean_true_node.
+ * d-tree.h (enum d_tree_index): Add DTI_BOOL_FALSE and DTI_BOOL_TRUE.
+ (d_bool_false_node): New macro.
+ (d_bool_true_node): New macro.
+ * modules.cc (build_dso_cdtor_fn): Use d_bool_false_node and
+ d_bool_true_node instead of boolean_false_node and boolean_true_node.
+ (register_moduleinfo): Use d_bool_type instead of boolean_type_node.
+
+2023-10-28 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-codegen.cc (call_side_effect_free_p): New function.
+ * d-tree.h (CALL_EXPR_WARN_IF_UNUSED): New macro.
+ (call_side_effect_free_p): New prototype.
+ * expr.cc (ExprVisitor::visit (CallExp *)): Set
+ CALL_EXPR_WARN_IF_UNUSED on matched call expressions.
+ (ExprVisitor::visit (NewExp *)): Don't dereference the result of an
+ allocation call here.
+ * toir.cc (add_stmt): Emit warning when call expression added to
+ statement list without being used.
+
+2023-10-22 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd f4be7f6f7b.
+ * Make-lang.in (D_FRONTEND_OBJS): Rename d/root-rootobject.o to
+ d/rootobject.o.
+
2023-10-17 Iain Buclaw <ibuclaw@gdcproject.org>
* d-tree.h (intrinsic_code): Update define for DEF_D_INTRINSIC.
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index 264ae03..b3007a9 100644
--- a/gcc/d/Make-lang.in
+++ b/gcc/d/Make-lang.in
@@ -174,11 +174,11 @@ D_FRONTEND_OBJS = \
d/root-port.o \
d/root-region.o \
d/root-rmem.o \
- d/root-rootobject.o \
d/root-speller.o \
d/root-string.o \
d/root-stringtable.o \
d/root-utf.o \
+ d/rootobject.o \
d/safe.o \
d/sapply.o \
d/semantic2.o \
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index cf998d2..f6ea026 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -956,6 +956,9 @@ d_build_d_type_nodes (void)
d_bool_type = make_unsigned_type (1);
TREE_SET_CODE (d_bool_type, BOOLEAN_TYPE);
+ d_bool_false_node = TYPE_MIN_VALUE (d_bool_type);
+ d_bool_true_node = TYPE_MAX_VALUE (d_bool_type);
+
char8_type_node = make_unsigned_type (8);
TYPE_STRING_FLAG (char8_type_node) = 1;
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 155f5d0..5c53cf7 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1115,7 +1115,7 @@ build_array_struct_comparison (tree_code code, StructDeclaration *sd,
if (length == 0 || result OP 0) break; */
t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result,
- boolean_false_node));
+ d_bool_false_node));
t = build1 (EXIT_EXPR, void_type_node, t);
add_stmt (t);
@@ -2102,6 +2102,60 @@ get_function_type (Type *t)
return tf;
}
+/* Returns TRUE if calling the function FUNC, or calling a function or delegate
+ object of type TYPE is be free of side effects. */
+
+bool
+call_side_effect_free_p (FuncDeclaration *func, Type *type)
+{
+ gcc_assert (func != NULL || type != NULL);
+
+ if (func != NULL)
+ {
+ /* Constructor and invariant calls can't be `pure'. */
+ if (func->isCtorDeclaration () || func->isInvariantDeclaration ())
+ return false;
+
+ /* Must be a `nothrow' function. */
+ TypeFunction *tf = func->type->toTypeFunction ();
+ if (!tf->isnothrow ())
+ return false;
+
+ /* Return type can't be `void' or `noreturn', as that implies all work is
+ done via side effects. */
+ if (tf->next->ty == TY::Tvoid || tf->next->ty == TY::Tnoreturn)
+ return false;
+
+ /* Only consider it as `pure' if it can't modify its arguments. */
+ if (func->isPure () == PURE::const_)
+ return true;
+ }
+
+ if (type != NULL)
+ {
+ TypeFunction *tf = get_function_type (type);
+
+ /* Must be a `nothrow` function type. */
+ if (tf == NULL || !tf->isnothrow ())
+ return false;
+
+ /* Return type can't be `void' or `noreturn', as that implies all work is
+ done via side effects. */
+ if (tf->next->ty == TY::Tvoid || tf->next->ty == TY::Tnoreturn)
+ return false;
+
+ /* Delegates that can modify its context can't be `pure'. */
+ if (type->isTypeDelegate () && tf->isMutable ())
+ return false;
+
+ /* Only consider it as `pure' if it can't modify its arguments. */
+ if (tf->purity == PURE::const_)
+ return true;
+ }
+
+ return false;
+}
+
/* Returns TRUE if CALLEE is a plain nested function outside the scope of
CALLER. In which case, CALLEE is being called through an alias that was
passed to CALLER. */
@@ -2191,14 +2245,16 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
for (size_t i = 0; i < arguments->length; ++i)
{
Expression *arg = (*arguments)[i];
- tree targ = build_expr (arg);
+ tree targ;
if (i - varargs < nparams && i >= varargs)
{
/* Actual arguments for declared formal arguments. */
Parameter *parg = tf->parameterList[i - varargs];
- targ = convert_for_argument (targ, parg);
+ targ = convert_for_argument (arg, parg);
}
+ else
+ targ = build_expr (arg);
/* Don't pass empty aggregates by value. */
if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 2b9d8e7..4c5375c 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -132,13 +132,13 @@ d_truthvalue_conversion (tree expr)
return expr;
case INTEGER_CST:
- return integer_zerop (expr) ? boolean_false_node
- : boolean_true_node;
+ return integer_zerop (expr) ? d_bool_false_node
+ : d_bool_true_node;
case REAL_CST:
return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
- ? boolean_true_node
- : boolean_false_node;
+ ? d_bool_true_node
+ : d_bool_false_node;
case ADDR_EXPR:
/* If we are taking the address of a decl that can never be null,
@@ -148,7 +148,7 @@ d_truthvalue_conversion (tree expr)
warning (OPT_Waddress,
"the address of %qD will always evaluate as %<true%>",
TREE_OPERAND (expr, 0));
- return boolean_true_node;
+ return d_bool_true_node;
}
break;
@@ -694,16 +694,86 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
return result ? result : convert_expr (expr, etype, totype);
}
+/* Helper for convert_for_assigment and convert_for_argument.
+ Returns true if EXPR is a va_list static array parameter. */
+
+static bool
+is_valist_parameter_type (Expression *expr)
+{
+ Declaration *decl = NULL;
+
+ if (VarExp *ve = expr->isVarExp ())
+ decl = ve->var;
+ else if (SymOffExp *se = expr->isSymOffExp ())
+ decl = se->var;
+
+ if (decl != NULL && decl->isParameter () && valist_array_p (decl->type))
+ return true;
+
+ return false;
+}
+
+/* Helper for convert_for_assigment and convert_for_argument.
+ Report erroneous uses of assigning or passing a va_list parameter. */
+
+static void
+check_valist_conversion (Expression *expr, Type *totype, bool in_assignment)
+{
+ /* Parameter symbol and its converted type. */
+ Declaration *decl = NULL;
+ /* Type of parameter when evaluated in the expression. */
+ Type *type = NULL;
+
+ if (VarExp *ve = expr->isVarExp ())
+ {
+ decl = ve->var;
+ type = ve->var->type->nextOf ()->pointerTo ();
+ }
+ else if (SymOffExp *se = expr->isSymOffExp ())
+ {
+ decl = se->var;
+ type = se->var->type->nextOf ()->pointerTo ()->pointerTo ();
+ }
+
+ /* Should not be called unless is_valist_parameter_type also matched. */
+ gcc_assert (decl != NULL && decl->isParameter ()
+ && valist_array_p (decl->type));
+
+ /* OK if conversion between types is allowed. */
+ if (type->implicitConvTo (totype) != MATCH::nomatch)
+ return;
+
+ if (in_assignment)
+ {
+ error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
+ "from type %qs to type %qs in assignment",
+ expr->toChars(), type->toChars (), totype->toChars ());
+ }
+ else
+ {
+ error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
+ "from type %qs to type %qs in argument passing",
+ expr->toChars(), type->toChars (), totype->toChars ());
+ }
+
+ inform (make_location_t (decl->loc), "parameters of type %<va_list%> "
+ "{aka %qs} are decayed to pointer types, and require %<va_copy%> "
+ "to be converted back into a static array type",
+ decl->type->toChars ());
+}
+
/* Apply semantics of assignment to a value of type TOTYPE to EXPR
- (e.g., pointer = array -> pointer = &array[0])
+ For example: `pointer = array' gets lowered to `pointer = &array[0]'.
+ If LITERALP is true, then EXPR is a value used in the initialization
+ of another literal.
Return a TREE representation of EXPR implicitly converted to TOTYPE
for use in assignment expressions MODIFY_EXPR, INIT_EXPR. */
tree
-convert_for_assignment (tree expr, Type *etype, Type *totype)
+convert_for_assignment (Expression *expr, Type *totype, bool literalp)
{
- Type *ebtype = etype->toBasetype ();
+ Type *ebtype = expr->type->toBasetype ();
Type *tbtype = totype->toBasetype ();
/* Assuming this only has to handle converting a non Tsarray type to
@@ -723,8 +793,8 @@ convert_for_assignment (tree expr, Type *etype, Type *totype)
vec <constructor_elt, va_gc> *ce = NULL;
tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),
size_zero_node, size_int (count - 1));
- tree value = convert_for_assignment (expr, etype, sa_type->next);
-
+ tree value = convert_for_assignment (expr, sa_type->next,
+ literalp);
/* Can't use VAR_DECLs in CONSTRUCTORS. */
if (VAR_P (value))
{
@@ -745,38 +815,53 @@ convert_for_assignment (tree expr, Type *etype, Type *totype)
if ((tbtype->ty == TY::Tsarray || tbtype->ty == TY::Tstruct)
&& ebtype->isintegral ())
{
- if (!integer_zerop (expr))
- gcc_unreachable ();
-
- return expr;
+ tree ret = build_expr (expr, false, literalp);
+ gcc_assert (integer_zerop (ret));
+ return ret;
}
- return convert_for_rvalue (expr, etype, totype);
+ /* Assigning a va_list by value or reference, check whether RHS is a parameter
+ that has has been lowered by declaration_type or parameter_type. */
+ if (is_valist_parameter_type (expr))
+ check_valist_conversion (expr, totype, true);
+
+ return convert_for_rvalue (build_expr (expr, false, literalp),
+ expr->type, totype);
}
/* Return a TREE representation of EXPR converted to represent
the parameter type ARG. */
tree
-convert_for_argument (tree expr, Parameter *arg)
+convert_for_argument (Expression *expr, Parameter *arg)
{
+ tree targ = build_expr (expr);
+
/* Lazy arguments: expr should already be a delegate. */
if (arg->storageClass & STClazy)
- return expr;
+ return targ;
+ /* Passing a va_list by value, check whether the target requires it to
+ be decayed to a pointer type. */
if (valist_array_p (arg->type))
{
- /* Do nothing if the va_list has already been decayed to a pointer. */
- if (!POINTER_TYPE_P (TREE_TYPE (expr)))
- return build_address (expr);
- }
- else if (parameter_reference_p (arg))
- {
- /* Front-end shouldn't automatically take the address. */
- return convert (parameter_type (arg), build_address (expr));
+ if (!POINTER_TYPE_P (TREE_TYPE (targ)))
+ return build_address (targ);
+
+ /* Do nothing if the va_list has already been converted. */
+ return targ;
}
- return expr;
+ /* Passing a va_list by reference, check if types are really compatible
+ after conversion from static array to pointer type. */
+ if (is_valist_parameter_type (expr))
+ check_valist_conversion (expr, arg->type, false);
+
+ /* Front-end shouldn't automatically take the address of `ref' parameters. */
+ if (parameter_reference_p (arg))
+ return convert (parameter_type (arg), build_address (targ));
+
+ return targ;
}
/* Perform default promotions for data used in expressions.
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 66c2f24..d19c3f5 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -47,6 +47,7 @@ typedef Array <Expression *> Expressions;
/* Usage of TREE_LANG_FLAG_?:
0: METHOD_CALL_EXPR
+ 1: CALL_EXPR_WARN_IF_UNUSED (in CALL_EXPR).
Usage of TYPE_LANG_FLAG_?:
0: TYPE_SHARED
@@ -357,6 +358,11 @@ lang_tree_node
#define METHOD_CALL_EXPR(NODE) \
(TREE_LANG_FLAG_0 (NODE))
+/* True if the CALL_EXPR is free of side effects, and its return value
+ should not be discarded. */
+#define CALL_EXPR_WARN_IF_UNUSED(NODE) \
+ (TREE_LANG_FLAG_1 (CALL_EXPR_CHECK (NODE)))
+
/* True if the type was declared 'shared'. */
#define TYPE_SHARED(NODE) \
(TYPE_LANG_FLAG_0 (NODE))
@@ -438,6 +444,9 @@ enum d_tree_index
DTI_NULL_ARRAY,
DTI_BOTTOM_TYPE,
+ DTI_BOOL_FALSE,
+ DTI_BOOL_TRUE,
+
DTI_MAX
};
@@ -474,6 +483,9 @@ extern GTY(()) tree d_global_trees[DTI_MAX];
#define null_array_node d_global_trees[DTI_NULL_ARRAY]
/* The bottom type, referred to as `noreturn` in code. */
#define noreturn_type_node d_global_trees[DTI_BOTTOM_TYPE]
+/* D boolean values are always byte-sized, unlike boolean_type_node. */
+#define d_bool_false_node d_global_trees[DTI_BOOL_FALSE]
+#define d_bool_true_node d_global_trees[DTI_BOOL_TRUE]
/* A prefix for internal variables, which are not user-visible. */
#if !defined (NO_DOT_IN_LABEL)
@@ -594,6 +606,7 @@ extern tree build_bounds_slice_condition (SliceExp *, tree, tree, tree);
extern bool array_bounds_check (void);
extern bool checkaction_trap_p (void);
extern TypeFunction *get_function_type (Type *);
+extern bool call_side_effect_free_p (FuncDeclaration *, Type *);
extern bool call_by_alias_p (FuncDeclaration *, FuncDeclaration *);
extern tree d_build_call_expr (FuncDeclaration *, tree, Expressions *);
extern tree d_build_call (TypeFunction *, tree, tree, Expressions *);
@@ -612,8 +625,8 @@ extern tree d_truthvalue_conversion (tree);
extern tree d_convert (tree, tree);
extern tree convert_expr (tree, Type *, Type *);
extern tree convert_for_rvalue (tree, Type *, Type *);
-extern tree convert_for_assignment (tree, Type *, Type *);
-extern tree convert_for_argument (tree, Parameter *);
+extern tree convert_for_assignment (Expression *, Type *, bool = false);
+extern tree convert_for_argument (Expression *, Parameter *);
extern tree convert_for_condition (tree, Type *);
extern tree d_array_convert (Expression *);
extern tree d_array_convert (Type *, Expression *);
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 7946002..2a0baf0 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-4c18eed9674e04c1ca89fbc8bd5c4e483eb5477c
+e48bc0987dfec35bc76a3015ee3e85906ce86dfd
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/README.md b/gcc/d/dmd/README.md
index d0c75a5b..f8ac001 100644
--- a/gcc/d/dmd/README.md
+++ b/gcc/d/dmd/README.md
@@ -84,6 +84,7 @@ Note that these groups have no strict meaning, the category assignments are a bi
| [astcodegen.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/astcodegen.d) | Namespace of AST nodes of a AST ready for code generation |
| [astenums.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/astenums.d) | Enums common to DMD and AST |
| [expression.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/expression.d) | Define expression AST nodes |
+| [rootobject.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/rootobject.d) | Define an abstract root class |
| [statement.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/statement.d) | Define statement AST nodes |
| [staticassert.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/staticassert.d) | Define a `static assert` AST node |
| [aggregate.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/aggregate.d) | Define an aggregate (`struct`, `union` or `class`) AST node |
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index fd05dcf..b272d4b 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.105.2
+v2.106.0-beta.1
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index 68b5f1b..d9b48b5 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -192,7 +192,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
* Returns:
* The total number of fields minus the number of hidden fields.
*/
- final size_t nonHiddenFields()
+ extern (D) final size_t nonHiddenFields()
{
return fields.length - isNested() - (vthis2 !is null);
}
@@ -202,7 +202,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
* Returns:
* false if failed to determine the size.
*/
- final bool determineSize(const ref Loc loc)
+ extern (D) final bool determineSize(const ref Loc loc)
{
//printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok);
@@ -609,7 +609,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
}
/// Flag this aggregate as deprecated
- final void setDeprecated()
+ extern (D) final void setDeprecated()
{
this.storage_class |= STC.deprecated_;
}
@@ -745,7 +745,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
/*******************************************
* Look for constructor declaration.
*/
- final Dsymbol searchCtor()
+ extern (D) final Dsymbol searchCtor()
{
auto s = search(Loc.initial, Id.ctor);
if (s)
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index 4b107e0..58a0126 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -114,17 +114,13 @@ public:
virtual Scope *newScope(Scope *sc);
void setScope(Scope *sc) override final;
- size_t nonHiddenFields();
- bool determineSize(const Loc &loc);
virtual void finalizeSize() = 0;
uinteger_t size(const Loc &loc) override final;
bool fill(const Loc &loc, Expressions &elements, bool ctorinit);
Type *getType() override final;
bool isDeprecated() const override final; // is aggregate deprecated?
- void setDeprecated();
bool isNested() const;
bool isExport() const override final;
- Dsymbol *searchCtor();
Visibility visible() override final;
@@ -279,12 +275,10 @@ public:
ObjcClassDeclaration objc; // Data for a class declaration that is needed for the Objective-C integration
Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr
- void classError(const char* fmt, const char* arg);
static ClassDeclaration *create(const Loc &loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject);
const char *toPrettyChars(bool QualifyTypes = false) override;
ClassDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
- bool isBaseOf2(ClassDeclaration *cd);
#define OFFSET_RUNTIME 0x76543210
#define OFFSET_FWDREF 0x76543211
@@ -292,11 +286,9 @@ public:
bool isBaseInfoComplete();
Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
- ClassDeclaration *searchBase(Identifier *ident);
void finalizeSize() override;
bool hasMonitor();
bool isFuncHidden(FuncDeclaration *fd);
- FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
bool isCOMclass() const;
virtual bool isCOMinterface() const;
bool isCPPclass() const;
diff --git a/gcc/d/dmd/aliasthis.h b/gcc/d/dmd/aliasthis.h
index 389cff4..092490f 100644
--- a/gcc/d/dmd/aliasthis.h
+++ b/gcc/d/dmd/aliasthis.h
@@ -21,7 +21,7 @@ public:
// alias Identifier this;
Identifier *ident;
Dsymbol *sym;
- bool isDeprecated_;
+ d_bool isDeprecated_;
AliasThis *syntaxCopy(Dsymbol *) override;
const char *kind() const override;
diff --git a/gcc/d/dmd/arraytypes.d b/gcc/d/dmd/arraytypes.d
index 34ffa6e..6634a6a 100644
--- a/gcc/d/dmd/arraytypes.d
+++ b/gcc/d/dmd/arraytypes.d
@@ -22,7 +22,7 @@ import dmd.identifier;
import dmd.init;
import dmd.mtype;
import dmd.root.array;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.statement;
alias Strings = Array!(const(char)*);
diff --git a/gcc/d/dmd/ast_node.d b/gcc/d/dmd/ast_node.d
index c0dd186..313c2bd 100644
--- a/gcc/d/dmd/ast_node.d
+++ b/gcc/d/dmd/ast_node.d
@@ -10,7 +10,7 @@
*/
module dmd.ast_node;
-import dmd.root.rootobject : RootObject;
+import dmd.rootobject : RootObject;
import dmd.visitor : Visitor;
/// The base class of all AST nodes.
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index 1e75598..f47a1f6 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -123,7 +123,6 @@ public:
Expressions *alignExps;
structalign_t salign;
- AlignDeclaration(const Loc &loc, Expression *ealign, Dsymbols *decl);
AlignDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index 31a32cf..5108ecf 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -151,14 +151,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink)
}
}
- if (!(result & BE.fallthru) && !s.comeFrom())
- {
- version (none) // this warning is completely useless due to insane false positive rate in real life template code
- if (blockExit(s, func, eSink) != BE.halt && s.hasCode() &&
- s.loc != Loc.initial) // don't emit warning for generated code
- global.errorSink.warning(s.loc, "statement is not reachable");
- }
- else
+ if ((result & BE.fallthru) || s.comeFrom())
{
result &= ~BE.fallthru;
result |= blockExit(s, func, eSink);
@@ -447,17 +440,6 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink)
blockExit(s.finalbody, func, eSink);
}
- version (none)
- {
- // https://issues.dlang.org/show_bug.cgi?id=13201
- // Mask to prevent spurious warnings for
- // destructor call, exit of synchronized statement, etc.
- if (result == BE.halt && finalresult != BE.halt && s.finalbody && s.finalbody.hasCode())
- {
- eSink.warning(s.finalbody.loc, "statement is not reachable");
- }
- }
-
if (!(finalresult & BE.fallthru))
result &= ~BE.fallthru;
result |= finalresult & ~BE.fallthru;
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index bb1fd6f..8aece3b 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -55,7 +55,7 @@ enum CT : BE
* eSink = if !null, then send error messages to eSink
* Returns: `CT.exception` or `CT.error` if the expression may throw exceptions.
*/
-extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, ErrorSink eSink)
+CT canThrow(Expression e, FuncDeclaration func, ErrorSink eSink)
{
//printf("Expression::canThrow(%d) %s\n", mustNotThrow, e.toChars());
// stop walking if we determine this expression can throw
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index 70a7c88..9fa8a25 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -30,7 +30,7 @@ import dmd.location;
import dmd.mtype;
import dmd.typesem;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.tokens;
import dmd.utils;
@@ -133,7 +133,7 @@ extern (C++) final class StaticForeach : RootObject
this.rangefe = rangefe;
}
- StaticForeach syntaxCopy()
+ extern (D) StaticForeach syntaxCopy()
{
return new StaticForeach(
loc,
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index 45094d1..d02ae13 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -53,8 +53,6 @@ public:
ForeachRangeStatement *rangefe;
d_bool needExpansion;
-
- StaticForeach *syntaxCopy();
};
class DVCondition : public Condition
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index d183b82..0b738cd 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -1923,7 +1923,12 @@ final class CParser(AST) : Parser!AST
}
}
if (isalias)
- s = new AST.AliasDeclaration(token.loc, id, dt);
+ {
+ auto ad = new AST.AliasDeclaration(token.loc, id, dt);
+ ad.adFlags |= ad.hidden; // do not print when generating .di files
+ s = ad;
+ }
+
insertTypedefToTypedefTab(id, dt); // remember typedefs
}
else if (id)
@@ -1960,7 +1965,9 @@ final class CParser(AST) : Parser!AST
error("no initializer for function declaration");
if (specifier.scw & SCW.x_Thread_local)
error("functions cannot be `_Thread_local`"); // C11 6.7.1-4
- auto fd = new AST.FuncDeclaration(token.loc, Loc.initial, id, specifiersToSTC(level, specifier), dt, specifier.noreturn);
+ StorageClass stc = specifiersToSTC(level, specifier);
+ stc &= ~STC.gshared; // no gshared functions
+ auto fd = new AST.FuncDeclaration(token.loc, Loc.initial, id, stc, dt, specifier.noreturn);
specifiersToFuncDeclaration(fd, specifier);
s = fd;
}
@@ -2136,7 +2143,9 @@ final class CParser(AST) : Parser!AST
auto body = cparseStatement(ParseStatementFlags.curly); // don't start a new scope; continue with parameter scope
typedefTab.pop(); // end of function scope
- auto fd = new AST.FuncDeclaration(locFunc, prevloc, id, specifiersToSTC(LVL.global, specifier), ft, specifier.noreturn);
+ StorageClass stc = specifiersToSTC(LVL.global, specifier);
+ stc &= ~STC.gshared; // no gshared functions
+ auto fd = new AST.FuncDeclaration(locFunc, prevloc, id, stc, ft, specifier.noreturn);
specifiersToFuncDeclaration(fd, specifier);
if (addFuncName)
@@ -5289,7 +5298,7 @@ final class CParser(AST) : Parser!AST
(*decls)[0] = s;
s = new AST.AlignDeclaration(s.loc, specifier.alignExps, decls);
}
- else if (!specifier.packalign.isDefault())
+ else if (!specifier.packalign.isDefault() && !specifier.packalign.isUnknown())
{
//printf(" applying packalign %d\n", cast(int)specifier.packalign);
// Wrap #pragma pack in an AlignDeclaration
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 230bfec..55844dd 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -42,7 +42,7 @@ import dmd.mtype;
import dmd.nspace;
import dmd.root.array;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.target;
import dmd.typesem;
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 9f661ea..e4d5805 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -3684,7 +3684,7 @@ void fix16997(Scope* sc, UnaExp ue)
* This is to enable comparing things like an immutable
* array with a mutable one.
*/
-extern (C++) bool arrayTypeCompatibleWithoutCasting(Type t1, Type t2)
+extern (D) bool arrayTypeCompatibleWithoutCasting(Type t1, Type t2)
{
t1 = t1.toBasetype();
t2 = t2.toBasetype();
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index 0fbbb11..09a4f4e 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -367,7 +367,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
baseok = Baseok.none;
}
- final void classError(const(char)* fmt, const(char)* arg)
+ extern (D) private void classError(const(char)* fmt, const(char)* arg)
{
.error(loc, fmt, kind, toPrettyChars, arg);
}
@@ -423,7 +423,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
* Determine if 'this' is a base class of cd.
* This is used to detect circular inheritance only.
*/
- final bool isBaseOf2(ClassDeclaration cd) pure nothrow @nogc
+ extern (D) final bool isBaseOf2(ClassDeclaration cd) pure nothrow @nogc
{
if (!cd)
return false;
@@ -538,7 +538,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
* Returns:
* ClassDeclaration if found, null if not
*/
- final ClassDeclaration searchBase(Identifier ident)
+ extern (D) final ClassDeclaration searchBase(Identifier ident)
{
foreach (b; *baseclasses)
{
@@ -716,7 +716,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
* Errors:
* prints error message if more than one match
*/
- final FuncDeclaration findFunc(Identifier ident, TypeFunction tf)
+ extern (D) final FuncDeclaration findFunc(Identifier ident, TypeFunction tf)
{
//printf("ClassDeclaration.findFunc(%s, %s) %s\n", ident.toChars(), tf.toChars(), toChars());
FuncDeclaration fdmatch = null;
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index b65e7e8..d634e7f 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -37,7 +37,7 @@ import dmd.intrange;
import dmd.location;
import dmd.mtype;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.target;
import dmd.tokens;
import dmd.typesem;
@@ -244,6 +244,7 @@ extern (C++) abstract class Declaration : Dsymbol
enum wasRead = 1; // set if AliasDeclaration was read
enum ignoreRead = 2; // ignore any reads of AliasDeclaration
enum nounderscore = 4; // don't prepend _ to mangled name
+ enum hidden = 8; // don't print this in .di files
Symbol* isym; // import version of csym
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 71f2baa..8cd295f 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -705,15 +705,11 @@ public:
bool functionSemantic3();
bool equals(const RootObject * const o) const override final;
- int overrides(FuncDeclaration *fd);
int findVtblIndex(Dsymbols *vtbl, int dim);
- BaseClass *overrideInterface();
bool overloadInsert(Dsymbol *s) override;
bool inUnittest();
MATCH leastAsSpecialized(FuncDeclaration *g, Identifiers *names);
LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc);
- int getLevel(FuncDeclaration *fd, int intypeof); // lexical nesting level difference
- int getLevelAndCheck(const Loc &loc, Scope *sc, FuncDeclaration *fd);
const char *toPrettyChars(bool QualifyTypes = false) override;
const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure'
bool isMain() const;
@@ -726,13 +722,9 @@ public:
bool isOverloadable() const override final;
bool isAbstract() override final;
PURE isPure();
- PURE isPureBypassingInference();
bool isSafe();
- bool isSafeBypassingInference();
bool isTrusted();
-
bool isNogc();
- bool isNogcBypassingInference();
virtual bool isNested() const;
AggregateDeclaration *isThis() override;
@@ -752,8 +744,6 @@ public:
static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);
static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);
- bool checkNRVO();
-
FuncDeclaration *isFuncDeclaration() override final { return this; }
virtual FuncDeclaration *toAliasFunc() { return this; }
@@ -789,8 +779,6 @@ public:
bool addPreInvariant() override;
bool addPostInvariant() override;
- void modifyReturns(Scope *sc, Type *tret);
-
FuncLiteralDeclaration *isFuncLiteralDeclaration() override { return this; }
const char *kind() const override;
const char *toPrettyChars(bool QualifyTypes = false) override;
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index 98bf4dd..f33b5fd 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -99,7 +99,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
ScopeDsymbol.addMember(sc, sds);
}
- addEnumMembers(this, sc, sds);
+ addEnumMembersToSymtab(this, sc, sds);
}
override void setScope(Scope* sc)
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index 3b8d9f6..d74c860 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -128,7 +128,7 @@ extern (C++) final class Import : Dsymbol
* Returns:
* true for errors, false for success
*/
- bool load(Scope* sc)
+ extern (D) bool load(Scope* sc)
{
//printf("Import::load('%s') %p\n", toPrettyChars(), this);
// See if existing module
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index a43be7d..cbd9740 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -44,7 +44,7 @@ import dmd.root.rmem;
import dmd.root.array;
import dmd.root.ctfloat;
import dmd.root.region;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.utf;
import dmd.statement;
import dmd.tokens;
@@ -2975,6 +2975,9 @@ public:
}
}
+ private alias fp_t = extern (D) UnionExp function(const ref Loc loc, Type, Expression, Expression);
+ private alias fp2_t = extern (D) bool function(const ref Loc loc, EXP, Expression, Expression);
+
extern (D) private void interpretCommon(BinExp e, fp_t fp)
{
debug (LOG)
@@ -4965,6 +4968,22 @@ public:
override void visit(CommaExp e)
{
+ /****************************************
+ * Find the first non-comma expression.
+ * Params:
+ * e = Expressions connected by commas
+ * Returns:
+ * left-most non-comma expression
+ */
+ static inout(Expression) firstComma(inout Expression e)
+ {
+ Expression ex = cast()e;
+ while (ex.op == EXP.comma)
+ ex = (cast(CommaExp)ex).e1;
+ return cast(inout)ex;
+
+ }
+
debug (LOG)
{
printf("%s CommaExp::interpret() %s\n", e.loc.toChars(), e.toChars());
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 2026303..548928a 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -45,7 +45,7 @@ import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.port;
import dmd.root.rmem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.semantic2;
import dmd.semantic3;
@@ -1095,7 +1095,7 @@ extern (C++) final class Module : Package
return Package.symtabInsert(s);
}
- void deleteObjFile()
+ extern (D) void deleteObjFile()
{
if (global.params.obj)
File.remove(objfile.toChars());
diff --git a/gcc/d/dmd/doc.h b/gcc/d/dmd/doc.h
index 562427f..ebd3094 100644
--- a/gcc/d/dmd/doc.h
+++ b/gcc/d/dmd/doc.h
@@ -10,8 +10,10 @@
#pragma once
+#include "root/dcompat.h" // for d_size_t
+
class Module;
class ErrorSink;
-void gendocfile(Module *m, const char *ddoctext_ptr, size_t ddoctext_length,
+void gendocfile(Module *m, const char *ddoctext_ptr, d_size_t ddoctext_length,
const char *datetime, ErrorSink *eSink, OutBuffer &outbuf);
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index 981e093..3853512 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -344,7 +344,7 @@ extern (C++) struct Scope
* Returns:
* symbol if found, null if not
*/
- extern (C++) Dsymbol search(const ref Loc loc, Identifier ident, Dsymbol* pscopesym, int flags = IgnoreNone)
+ extern (D) Dsymbol search(const ref Loc loc, Identifier ident, Dsymbol* pscopesym, int flags = IgnoreNone)
{
version (LOGSEARCH)
{
@@ -479,12 +479,6 @@ extern (C++) struct Scope
s = *ps;
}
}
- if (!(flags & (SearchImportsOnly | IgnoreErrors)) &&
- ident == Id.length && sc.scopesym.isArrayScopeSymbol() &&
- sc.enclosing && sc.enclosing.search(loc, ident, null, flags))
- {
- warning(s.loc, "array `length` hides other `length` name in outer scope");
- }
//printMsg("\tfound local", s);
if (pscopesym)
*pscopesym = sc.scopesym;
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index 56aad3e..5171e1f 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -71,7 +71,7 @@ extern (C++) FuncDeclaration search_toString(StructDeclaration sd)
* sc = context
* t = type that TypeInfo is being generated for
*/
-extern (C++) void semanticTypeInfo(Scope* sc, Type t)
+extern (D) void semanticTypeInfo(Scope* sc, Type t)
{
if (sc)
{
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 1f4a466..579a542 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -48,7 +48,7 @@ import dmd.nspace;
import dmd.opover;
import dmd.root.aav;
import dmd.root.rmem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.speller;
import dmd.root.string;
import dmd.statement;
@@ -141,13 +141,14 @@ struct Visibility
Kind kind;
Package pkg;
- extern (D):
-
- this(Visibility.Kind kind) pure nothrow @nogc @safe
+ extern(C++) this(Visibility.Kind kind, Package pkg = null) pure nothrow @nogc @safe
{
this.kind = kind;
+ this.pkg = pkg;
}
+ extern (D):
+
/**
* Checks if `this` is less or more visible than `other`
*
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 65c0795..8309e4a 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -62,7 +62,7 @@ import dmd.root.array;
import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rmem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.utf;
import dmd.semantic2;
import dmd.semantic3;
@@ -2260,7 +2260,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
* so we have to do what addMember() does and install the enum members in the right symbol
* table
*/
- addEnumMembers(ed, sc, sc.getScopesym());
+ addEnumMembersToSymtab(ed, sc, sc.getScopesym());
if (sc.flags & SCOPE.Cfile)
{
@@ -3854,12 +3854,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
*/
funcdecl.foverrides.push(fdv);
- /* Should we really require 'override' when implementing
- * an interface function?
- */
- //if (!isOverride())
- // warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv.toPrettyChars());
-
if (fdv.tintro)
ti = fdv.tintro;
else if (!funcdecl.type.equals(fdv.type))
@@ -5830,9 +5824,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
* sc = context of `ed`
* sds = symbol table that `ed` resides in
*/
-void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
+void addEnumMembersToSymtab(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
{
- //printf("addEnumMembers(ed: %p)\n", ed);
+ const bool isCEnum = (sc.flags & SCOPE.Cfile) != 0; // it's an ImportC enum
+ //printf("addEnumMembersToSymtab(ed: %s added: %d Cfile: %d)\n", ed.toChars(), ed.added, isCEnum);
if (ed.added)
return;
ed.added = true;
@@ -5840,7 +5835,6 @@ void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
if (!ed.members)
return;
- const bool isCEnum = (sc.flags & SCOPE.Cfile) != 0; // it's an ImportC enum
const bool isAnon = ed.isAnonymous();
if ((isCEnum || isAnon) && !sds.symtab)
@@ -5853,10 +5847,15 @@ void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
{
if (EnumMember em = s.isEnumMember())
{
+ //printf("adding EnumMember %s to %s %d\n", em.toChars(), ed.toChars(), isCEnum);
em.ed = ed;
if (isCEnum)
{
- //printf("adding EnumMember %s to %p\n", em.toChars(), ed);
+ /* C doesn't add the enum member to the symbol table of the enum tag, it adds
+ * it to the symbol table that the tag is in. This is in contrast to D, where enum
+ * members become members of the enum tag. To accommodate this, we add
+ * the enum members to both symbol tables.
+ */
em.addMember(sc, ed); // add em to ed's symbol table
em.addMember(sc, sds); // add em to symbol table that ed is in
em.parent = ed; // restore it after previous addMember() changed it
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 23d1140..5dca6df 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -70,7 +70,7 @@ import dmd.mtype;
import dmd.opover;
import dmd.root.array;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.semantic2;
import dmd.semantic3;
import dmd.tokens;
@@ -1241,7 +1241,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* match this is at least as specialized as td2
* 0 td2 is more specialized than this
*/
- MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration td2, ArgumentList argumentList)
+ extern (D) MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration td2, ArgumentList argumentList)
{
enum LOG_LEASTAS = 0;
static if (LOG_LEASTAS)
@@ -2258,7 +2258,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
/**************************************************
* Declare template parameter tp with value o, and install it in the scope sc.
*/
- RootObject declareParameter(Scope* sc, TemplateParameter tp, RootObject o)
+ extern (D) RootObject declareParameter(Scope* sc, TemplateParameter tp, RootObject o)
{
//printf("TemplateDeclaration.declareParameter('%s', o = %p)\n", tp.ident.toChars(), o);
Type ta = isType(o);
@@ -2508,7 +2508,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* Returns:
* The last template parameter if it's a `TemplateTupleParameter`
*/
- TemplateTupleParameter isVariadic()
+ extern (D) TemplateTupleParameter isVariadic()
{
size_t dim = parameters.length;
if (dim == 0)
@@ -6203,7 +6203,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
return false;
}
- final size_t toHash()
+ extern (D) final size_t toHash()
{
if (!hash)
{
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index f906ee1..7c76da9 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -1813,7 +1813,7 @@ public:
{
buf.writestring("::");
- import dmd.root.rootobject;
+ import dmd.rootobject;
// Is this even possible?
if (arg.dyncast != DYNCAST.identifier)
{
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 8562e2e..3f85ea0 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -32,7 +32,7 @@ import dmd.init;
import dmd.location;
import dmd.mtype;
import dmd.printast;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.tokens;
import dmd.visitor;
import dmd.arraytypes;
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 7205231..32ded3b 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -56,14 +56,13 @@ import dmd.nspace;
import dmd.objc;
import dmd.opover;
import dmd.optimize;
-import dmd.postordervisitor;
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.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.root.utf;
import dmd.safe;
@@ -114,22 +113,6 @@ enum ModifyFlags
}
/****************************************
- * Find the first non-comma expression.
- * Params:
- * e = Expressions connected by commas
- * Returns:
- * left-most non-comma expression
- */
-inout(Expression) firstComma(inout Expression e)
-{
- Expression ex = cast()e;
- while (ex.op == EXP.comma)
- ex = (cast(CommaExp)ex).e1;
- return cast(inout)ex;
-
-}
-
-/****************************************
* Find the last non-comma expression.
* Params:
* e = Expressions connected by commas
@@ -146,59 +129,6 @@ inout(Expression) lastComma(inout Expression e)
}
-/*****************************************
- * Determine if `this` is available by walking up the enclosing
- * scopes until a function is found.
- *
- * Params:
- * sc = where to start looking for the enclosing function
- * Returns:
- * Found function if it satisfies `isThis()`, otherwise `null`
- */
-FuncDeclaration hasThis(Scope* sc)
-{
- //printf("hasThis()\n");
- Dsymbol p = sc.parent;
- while (p && p.isTemplateMixin())
- p = p.parent;
- FuncDeclaration fdthis = p ? p.isFuncDeclaration() : null;
- //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis.toChars() : "");
-
- // Go upwards until we find the enclosing member function
- FuncDeclaration fd = fdthis;
- while (1)
- {
- if (!fd)
- {
- return null;
- }
- if (!fd.isNested() || fd.isThis() || (fd.hasDualContext() && fd.isMember2()))
- break;
-
- Dsymbol parent = fd.parent;
- while (1)
- {
- if (!parent)
- return null;
- TemplateInstance ti = parent.isTemplateInstance();
- if (ti)
- parent = ti.parent;
- else
- break;
- }
- fd = parent.isFuncDeclaration();
- }
-
- if (!fd.isThis() && !(fd.hasDualContext() && fd.isMember2()))
- {
- return null;
- }
-
- assert(fd.vthis);
- return fd;
-
-}
-
/***********************************
* Determine if a `this` is needed to access `d`.
* Params:
@@ -396,132 +326,12 @@ TemplateDeclaration getFuncTemplateDecl(Dsymbol s) @safe
return null;
}
-/************************************************
- * If we want the value of this expression, but do not want to call
- * the destructor on it.
- */
-Expression valueNoDtor(Expression e)
-{
- auto ex = lastComma(e);
-
- if (auto ce = ex.isCallExp())
- {
- /* The struct value returned from the function is transferred
- * so do not call the destructor on it.
- * Recognize:
- * ((S _ctmp = S.init), _ctmp).this(...)
- * and make sure the destructor is not called on _ctmp
- * BUG: if ex is a CommaExp, we should go down the right side.
- */
- if (auto dve = ce.e1.isDotVarExp())
- {
- if (dve.var.isCtorDeclaration())
- {
- // It's a constructor call
- if (auto comma = dve.e1.isCommaExp())
- {
- if (auto ve = comma.e2.isVarExp())
- {
- VarDeclaration ctmp = ve.var.isVarDeclaration();
- if (ctmp)
- {
- ctmp.storage_class |= STC.nodtor;
- assert(!ce.isLvalue());
- }
- }
- }
- }
- }
- }
- else if (auto ve = ex.isVarExp())
- {
- auto vtmp = ve.var.isVarDeclaration();
- if (vtmp && (vtmp.storage_class & STC.rvalue))
- {
- vtmp.storage_class |= STC.nodtor;
- }
- }
- return e;
-}
-
-/*********************************************
- * If e is an instance of a struct, and that struct has a copy constructor,
- * rewrite e as:
- * (tmp = e),tmp
- * Input:
- * sc = just used to specify the scope of created temporary variable
- * destinationType = the type of the object on which the copy constructor is called;
- * may be null if the struct defines a postblit
- */
-private Expression callCpCtor(Scope* sc, Expression e, Type destinationType)
-{
- if (auto ts = e.type.baseElemOf().isTypeStruct())
- {
- StructDeclaration sd = ts.sym;
- if (sd.postblit || sd.hasCopyCtor)
- {
- /* Create a variable tmp, and replace the argument e with:
- * (tmp = e),tmp
- * and let AssignExp() handle the construction.
- * This is not the most efficient, ideally tmp would be constructed
- * directly onto the stack.
- */
- auto tmp = copyToTemp(STC.rvalue, "__copytmp", e);
- if (sd.hasCopyCtor && destinationType)
- {
- // https://issues.dlang.org/show_bug.cgi?id=22619
- // If the destination type is inout we can preserve it
- // only if inside an inout function; if we are not inside
- // an inout function, then we will preserve the type of
- // the source
- if (destinationType.hasWild && !(sc.func.storage_class & STC.wild))
- tmp.type = e.type;
- else
- tmp.type = destinationType;
- }
- tmp.storage_class |= STC.nodtor;
- tmp.dsymbolSemantic(sc);
- Expression de = new DeclarationExp(e.loc, tmp);
- Expression ve = new VarExp(e.loc, tmp);
- de.type = Type.tvoid;
- ve.type = e.type;
- return Expression.combine(de, ve);
- }
- }
- return e;
-}
-
-/************************************************
- * Handle the postblit call on lvalue, or the move of rvalue.
- *
- * Params:
- * sc = the scope where the expression is encountered
- * e = the expression the needs to be moved or copied (source)
- * t = if the struct defines a copy constructor, the type of the destination
- *
- * Returns:
- * The expression that copy constructs or moves the value.
- */
-extern (D) Expression doCopyOrMove(Scope *sc, Expression e, Type t = null)
-{
- if (auto ce = e.isCondExp())
- {
- ce.e1 = doCopyOrMove(sc, ce.e1);
- ce.e2 = doCopyOrMove(sc, ce.e2);
- }
- else
- {
- e = e.isLvalue() ? callCpCtor(sc, e, t) : valueNoDtor(e);
- }
- return e;
-}
-
/****************************************************************/
/* 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++) struct UnionExp
+extern (D) struct UnionExp
{
// yes, default constructor does nothing
extern (D) this(Expression e)
@@ -531,14 +341,14 @@ extern (C++) struct UnionExp
/* Extract pointer to Expression
*/
- extern (C++) Expression exp() return
+ extern (D) Expression exp() return
{
return cast(Expression)&u;
}
/* Convert to an allocated Expression
*/
- extern (C++) Expression copy()
+ extern (D) Expression copy()
{
Expression e = exp();
//if (e.size > sizeof(u)) printf("%s\n", EXPtoString(e.op).ptr);
@@ -716,7 +526,7 @@ extern (C++) abstract class Expression : ASTNode
/*********************************
* Does *not* do a deep copy.
*/
- final Expression copy()
+ extern (D) final Expression copy()
{
Expression e;
if (!size)
@@ -935,7 +745,7 @@ extern (C++) abstract class Expression : ASTNode
return toLvalue(sc, e);
}
- final Expression implicitCastTo(Scope* sc, Type t)
+ extern (D) final Expression implicitCastTo(Scope* sc, Type t)
{
return .implicitCastTo(this, sc, t);
}
@@ -945,7 +755,7 @@ extern (C++) abstract class Expression : ASTNode
return .implicitConvTo(this, t);
}
- final Expression castTo(Scope* sc, Type t)
+ extern (D) final Expression castTo(Scope* sc, Type t)
{
return .castTo(this, sc, t);
}
@@ -1051,7 +861,7 @@ extern (C++) abstract class Expression : ASTNode
return checkValue();
}
- final bool checkDeprecated(Scope* sc, Dsymbol s)
+ extern (D) final bool checkDeprecated(Scope* sc, Dsymbol s)
{
return s.checkDeprecated(loc, sc);
}
@@ -1395,10 +1205,11 @@ extern (C++) abstract class Expression : ASTNode
return false;
if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
return false;
- /* The original expression (`new S(...)`) will be verified instead. This
- * is to keep errors related to the original code and not the lowering.
+ /* 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)
+ if (f.ident == Id._d_newitemT || f.ident == Id._d_newarrayT)
return false;
if (!f.isNogc())
@@ -1461,26 +1272,6 @@ extern (C++) abstract class Expression : ASTNode
return false;
}
- extern (D) final bool checkRightThis(Scope* sc)
- {
- if (op == EXP.error)
- return true;
- if (op == EXP.variable && type.ty != Terror)
- {
- VarExp ve = cast(VarExp)this;
- if (isNeedThisScope(sc, ve.var))
- {
- //printf("checkRightThis sc.intypeof = %d, ad = %p, func = %p, fdthis = %p\n",
- // sc.intypeof, sc.getStructClassScope(), func, fdthis);
- auto t = ve.var.isThis();
- assert(t);
- error(loc, "accessing non-static variable `%s` requires an instance of `%s`", ve.var.toChars(), t.toChars());
- return true;
- }
- }
- 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)
@@ -1778,12 +1569,6 @@ extern (C++) final class IntegerExp : Expression
return new IntegerExp(loc, value, type);
}
- // Same as create, but doesn't allocate memory.
- static void emplace(UnionExp* pue, const ref Loc loc, dinteger_t value, Type type)
- {
- emplaceExp!(IntegerExp)(pue, loc, value, type);
- }
-
override bool equals(const RootObject o) const
{
if (this == o)
@@ -1851,7 +1636,7 @@ extern (C++) final class IntegerExp : Expression
return value;
}
- void setInteger(dinteger_t value)
+ extern (D) void setInteger(dinteger_t value)
{
this.value = normalize(type.toBasetype().ty, value);
}
@@ -2048,12 +1833,6 @@ extern (C++) final class RealExp : Expression
return new RealExp(loc, value, type);
}
- // Same as create, but doesn't allocate memory.
- static void emplace(UnionExp* pue, const ref Loc loc, real_t value, Type type)
- {
- emplaceExp!(RealExp)(pue, loc, value, type);
- }
-
/********************************
* Test to see if two reals are the same.
* Regard NaN's as equivalent.
@@ -2146,12 +1925,6 @@ extern (C++) final class ComplexExp : Expression
return new ComplexExp(loc, value, type);
}
- // Same as create, but doesn't allocate memory.
- static void emplace(UnionExp* pue, const ref Loc loc, complex_t value, Type type)
- {
- emplaceExp!(ComplexExp)(pue, loc, value, type);
- }
-
override bool equals(const RootObject o) const
{
if (this == o)
@@ -2487,22 +2260,6 @@ extern (C++) final class StringExp : Expression
return new StringExp(loc, string[0 .. len]);
}
- // Same as create, but doesn't allocate memory.
- static void emplace(UnionExp* pue, const ref Loc loc, const(char)* s)
- {
- emplaceExp!(StringExp)(pue, loc, s.toDString());
- }
-
- extern (D) static void emplace(UnionExp* pue, const ref Loc loc, const(void)[] string)
- {
- emplaceExp!(StringExp)(pue, loc, string);
- }
-
- extern (D) static void emplace(UnionExp* pue, const ref Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix)
- {
- emplaceExp!(StringExp)(pue, loc, string, len, sz, postfix);
- }
-
override bool equals(const RootObject o) const
{
//printf("StringExp::equals('%s') %s\n", o.toChars(), toChars());
@@ -2638,7 +2395,7 @@ extern (C++) final class StringExp : Expression
* i = index
* c = code unit to set it to
*/
- void setCodeUnit(size_t i, dchar c)
+ extern (D) void setCodeUnit(size_t i, dchar c)
{
assert(i < len);
final switch (sz)
@@ -2988,12 +2745,6 @@ extern (C++) final class ArrayLiteralExp : Expression
return new ArrayLiteralExp(loc, null, elements);
}
- // Same as create, but doesn't allocate memory.
- static void emplace(UnionExp* pue, const ref Loc loc, Expressions* elements)
- {
- emplaceExp!(ArrayLiteralExp)(pue, loc, null, elements);
- }
-
override ArrayLiteralExp syntaxCopy()
{
return new ArrayLiteralExp(loc,
@@ -3032,12 +2783,12 @@ extern (C++) final class ArrayLiteralExp : Expression
return false;
}
- Expression getElement(size_t i)
+ Expression getElement(size_t i) // use opIndex instead
{
return this[i];
}
- Expression opIndex(size_t i)
+ extern (D) Expression opIndex(size_t i)
{
auto el = (*elements)[i];
return el ? el : basis;
@@ -3273,7 +3024,7 @@ extern (C++) final class StructLiteralExp : Expression
* Gets expression at offset of type.
* Returns NULL if not found.
*/
- Expression getField(Type type, uint offset)
+ extern (D) Expression getField(Type type, uint offset)
{
//printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n",
// /*toChars()*/"", type.toChars(), offset);
@@ -3323,7 +3074,7 @@ extern (C++) final class StructLiteralExp : Expression
* Get index of field.
* Returns -1 if not found.
*/
- int getFieldIndex(Type type, uint offset)
+ extern (D) int getFieldIndex(Type type, uint offset)
{
/* Find which field offset is by looking at the field offsets
*/
@@ -4282,7 +4033,7 @@ extern (C++) abstract class UnaExp : Expression
* Returns:
* ErrorExp
*/
- final Expression incompatibleTypes()
+ extern (D) final Expression incompatibleTypes()
{
if (e1.type.toBasetype() == Type.terror)
return e1;
@@ -4322,9 +4073,6 @@ extern (C++) abstract class UnaExp : Expression
}
}
-alias fp_t = UnionExp function(const ref Loc loc, Type, Expression, Expression);
-alias fp2_t = bool function(const ref Loc loc, EXP, Expression, Expression);
-
/***********************************************************
* Base class for binary operators
*/
@@ -4357,7 +4105,7 @@ extern (C++) abstract class BinExp : Expression
* Returns:
* ErrorExp
*/
- final Expression incompatibleTypes()
+ extern (D) final Expression incompatibleTypes()
{
if (e1.type.toBasetype() == Type.terror)
return e1;
@@ -4567,7 +4315,7 @@ extern (C++) abstract class BinExp : Expression
}
- final Expression reorderSettingAAElem(Scope* sc)
+ extern (D) final Expression reorderSettingAAElem(Scope* sc)
{
BinExp be = this;
@@ -4939,7 +4687,7 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp
return new DotTemplateInstanceExp(loc, e1.syntaxCopy(), ti.name, TemplateInstance.arraySyntaxCopy(ti.tiargs));
}
- bool findTempDecl(Scope* sc)
+ extern (D) bool findTempDecl(Scope* sc)
{
static if (LOGSEMANTIC)
{
@@ -5533,12 +5281,6 @@ extern (C++) final class VectorExp : UnaExp
return new VectorExp(loc, e, t);
}
- // Same as create, but doesn't allocate memory.
- static void emplace(UnionExp* pue, const ref Loc loc, Expression e, Type type)
- {
- emplaceExp!(VectorExp)(pue, loc, e, type);
- }
-
override VectorExp syntaxCopy()
{
return new VectorExp(loc, e1.syntaxCopy(), to.syntaxCopy());
@@ -6847,78 +6589,6 @@ extern (C++) final class CondExp : BinExp
return toLvalue(sc, this);
}
- void hookDtors(Scope* sc)
- {
- extern (C++) final class DtorVisitor : StoppableVisitor
- {
- alias visit = typeof(super).visit;
- public:
- Scope* sc;
- CondExp ce;
- VarDeclaration vcond;
- bool isThen;
-
- extern (D) this(Scope* sc, CondExp ce) @safe
- {
- this.sc = sc;
- this.ce = ce;
- }
-
- override void visit(Expression e)
- {
- //printf("(e = %s)\n", e.toChars());
- }
-
- override void visit(DeclarationExp e)
- {
- auto v = e.declaration.isVarDeclaration();
- if (v && !v.isDataseg())
- {
- if (v._init)
- {
- if (auto ei = v._init.isExpInitializer())
- walkPostorder(ei.exp, this);
- }
-
- if (v.edtor)
- walkPostorder(v.edtor, this);
-
- if (v.needsScopeDtor())
- {
- if (!vcond)
- {
- vcond = copyToTemp(STC.volatile_ | STC.const_, "__cond", ce.econd);
- vcond.dsymbolSemantic(sc);
-
- Expression de = new DeclarationExp(ce.econd.loc, vcond);
- de = de.expressionSemantic(sc);
-
- Expression ve = new VarExp(ce.econd.loc, vcond);
- ce.econd = Expression.combine(de, ve);
- }
-
- //printf("\t++v = %s, v.edtor = %s\n", v.toChars(), v.edtor.toChars());
- Expression ve = new VarExp(vcond.loc, vcond);
- if (isThen)
- v.edtor = new LogicalExp(v.edtor.loc, EXP.andAnd, ve, v.edtor);
- else
- v.edtor = new LogicalExp(v.edtor.loc, EXP.orOr, ve, v.edtor);
- v.edtor = v.edtor.expressionSemantic(sc);
- //printf("\t--v = %s, v.edtor = %s\n", v.toChars(), v.edtor.toChars());
- }
- }
- }
- }
-
- scope DtorVisitor v = new DtorVisitor(sc, this);
- //printf("+%s\n", toChars());
- v.isThen = true;
- walkPostorder(e1, v);
- v.isThen = false;
- walkPostorder(e2, v);
- //printf("-%s\n", toChars());
- }
-
override void accept(Visitor v)
{
v.visit(this);
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 5c656ee..cfd5198 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -39,7 +39,6 @@ class ClassDeclaration;
class OverloadSet;
class StringExp;
class LoweredAssignExp;
-struct UnionExp;
#ifdef IN_GCC
typedef union tree_node Symbol;
#else
@@ -47,11 +46,6 @@ struct Symbol; // back end symbol
#endif
void expandTuples(Expressions *exps, Identifiers *names = nullptr);
-bool isTrivialExp(Expression *e);
-bool hasSideEffect(Expression *e, bool assumeImpureCalls = false);
-
-enum BE : int32_t;
-BE canThrow(Expression *e, FuncDeclaration *func, ErrorSink *eSink);
typedef unsigned char OwnedBy;
enum
@@ -86,7 +80,6 @@ public:
size_t size() const;
static void _init();
- Expression *copy();
virtual Expression *syntaxCopy();
// kludge for template.isExpression()
@@ -103,13 +96,10 @@ public:
virtual bool isLvalue();
virtual Expression *toLvalue(Scope *sc, Expression *e);
virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
- Expression *implicitCastTo(Scope *sc, Type *t);
MATCH implicitConvTo(Type *t);
- Expression *castTo(Scope *sc, Type *t);
virtual Expression *resolveLoc(const Loc &loc, Scope *sc);
virtual bool checkType();
virtual bool checkValue();
- bool checkDeprecated(Scope *sc, Dsymbol *s);
virtual Expression *addDtorHook(Scope *sc);
Expression *addressOf();
Expression *deref();
@@ -248,7 +238,6 @@ public:
dinteger_t value;
static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type);
- static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type);
bool equals(const RootObject * const o) const override;
dinteger_t toInteger() override;
real_t toReal() override;
@@ -258,7 +247,6 @@ public:
Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
dinteger_t getInteger() { return value; }
- void setInteger(dinteger_t value);
template<int v>
static IntegerExp literal();
};
@@ -278,7 +266,6 @@ public:
real_t value;
static RealExp *create(const Loc &loc, real_t value, Type *type);
- static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type);
bool equals(const RootObject * const o) const override;
bool isIdentical(const Expression *e) const override;
dinteger_t toInteger() override;
@@ -296,7 +283,6 @@ public:
complex_t value;
static ComplexExp *create(const Loc &loc, complex_t value, Type *type);
- static void emplace(UnionExp *pue, const Loc &loc, complex_t value, Type *type);
bool equals(const RootObject * const o) const override;
bool isIdentical(const Expression *e) const override;
dinteger_t toInteger() override;
@@ -376,15 +362,13 @@ public:
void *string; // char, wchar, or dchar data
size_t len; // number of chars, wchars, or dchars
unsigned char sz; // 1: char, 2: wchar, 4: dchar
- bool committed; // if type is committed
- bool hexString; // if string is parsed from a hex string literal
+ d_bool committed; // if type is committed
+ d_bool hexString; // if string is parsed from a hex string literal
static StringExp *create(const Loc &loc, const char *s);
static StringExp *create(const Loc &loc, const void *s, d_size_t len);
- static void emplace(UnionExp *pue, const Loc &loc, const char *s);
bool equals(const RootObject * const o) const override;
char32_t getCodeUnit(d_size_t i) const;
- void setCodeUnit(d_size_t i, char32_t c);
StringExp *toStringExp() override;
StringExp *toUTF8(Scope *sc);
Optional<bool> toBool() override;
@@ -427,11 +411,9 @@ public:
Expressions *elements;
static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
- static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
ArrayLiteralExp *syntaxCopy() override;
bool equals(const RootObject * const o) const override;
- Expression *getElement(d_size_t i); // use opIndex instead
- Expression *opIndex(d_size_t i);
+ Expression *getElement(d_size_t i);
Optional<bool> toBool() override;
StringExp *toStringExp() override;
@@ -490,8 +472,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 *getField(Type *type, unsigned offset);
- int getFieldIndex(Type *type, unsigned offset);
Expression *addDtorHook(Scope *sc) override;
Expression *toLvalue(Scope *sc, Expression *e) override;
@@ -702,7 +682,6 @@ public:
Expression *e1;
UnaExp *syntaxCopy() override;
- Expression *incompatibleTypes();
Expression *resolveLoc(const Loc &loc, Scope *sc) override final;
void accept(Visitor *v) override { v->visit(this); }
@@ -718,9 +697,6 @@ public:
Type *att2; // Save alias this type to detect recursion
BinExp *syntaxCopy() override;
- Expression *incompatibleTypes();
-
- Expression *reorderSettingAAElem(Scope *sc);
void accept(Visitor *v) override { v->visit(this); }
};
@@ -806,7 +782,6 @@ public:
TemplateInstance *ti;
DotTemplateInstanceExp *syntaxCopy() override;
- bool findTempDecl(Scope *sc);
bool checkType() override;
bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
@@ -925,7 +900,6 @@ public:
OwnedBy ownedByCtfe;
static VectorExp *create(const Loc &loc, Expression *e, Type *t);
- static void emplace(UnionExp *pue, const Loc &loc, Expression *e, Type *t);
VectorExp *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -1326,7 +1300,6 @@ public:
bool isLvalue() override;
Expression *toLvalue(Scope *sc, Expression *e) override;
Expression *modifiableLvalue(Scope *sc, Expression *e) override;
- void hookDtors(Scope *sc);
void accept(Visitor *v) override { v->visit(this); }
};
@@ -1387,62 +1360,6 @@ public:
/****************************************************************/
-/* 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.
- */
-struct UnionExp
-{
- UnionExp() { } // yes, default constructor does nothing
-
- UnionExp(Expression *e)
- {
- memcpy(this, (void *)e, e->size());
- }
-
- /* Extract pointer to Expression
- */
- Expression *exp() { return (Expression *)&u; }
-
- /* Convert to an allocated Expression
- */
- Expression *copy();
-
-private:
- // Ensure that the union is suitably aligned.
-#if defined(__GNUC__) || defined(__clang__)
- __attribute__((aligned(8)))
-#elif defined(_MSC_VER)
- __declspec(align(8))
-#elif defined(__DMC__)
- #pragma pack(8)
-#endif
- union
- {
- char exp [sizeof(Expression)];
- char integerexp[sizeof(IntegerExp)];
- char errorexp [sizeof(ErrorExp)];
- char realexp [sizeof(RealExp)];
- char complexexp[sizeof(ComplexExp)];
- char symoffexp [sizeof(SymOffExp)];
- char stringexp [sizeof(StringExp)];
- char arrayliteralexp [sizeof(ArrayLiteralExp)];
- char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
- char structliteralexp [sizeof(StructLiteralExp)];
- char nullexp [sizeof(NullExp)];
- char dotvarexp [sizeof(DotVarExp)];
- char addrexp [sizeof(AddrExp)];
- char indexexp [sizeof(IndexExp)];
- char sliceexp [sizeof(SliceExp)];
- char vectorexp [sizeof(VectorExp)];
- } u;
-#if defined(__DMC__)
- #pragma pack()
-#endif
-};
-
-/****************************************************************/
-
class ObjcClassReferenceExp final : public Expression
{
public:
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 0bdcda9..ac8e571 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -63,11 +63,12 @@ import dmd.opover;
import dmd.optimize;
import dmd.parse;
import dmd.printast;
+import dmd.postordervisitor;
import dmd.root.array;
import dmd.root.ctfloat;
import dmd.root.filename;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.root.utf;
import dmd.semantic2;
@@ -140,6 +141,58 @@ bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps)
return false;
}
+/*****************************************
+ * Determine if `this` is available by walking up the enclosing
+ * scopes until a function is found.
+ *
+ * Params:
+ * sc = where to start looking for the enclosing function
+ * Returns:
+ * Found function if it satisfies `isThis()`, otherwise `null`
+ */
+FuncDeclaration hasThis(Scope* sc)
+{
+ //printf("hasThis()\n");
+ Dsymbol p = sc.parent;
+ while (p && p.isTemplateMixin())
+ p = p.parent;
+ FuncDeclaration fdthis = p ? p.isFuncDeclaration() : null;
+ //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis.toChars() : "");
+
+ // Go upwards until we find the enclosing member function
+ FuncDeclaration fd = fdthis;
+ while (1)
+ {
+ if (!fd)
+ {
+ return null;
+ }
+ if (!fd.isNested() || fd.isThis() || (fd.hasDualContext() && fd.isMember2()))
+ break;
+
+ Dsymbol parent = fd.parent;
+ while (1)
+ {
+ if (!parent)
+ return null;
+ TemplateInstance ti = parent.isTemplateInstance();
+ if (ti)
+ parent = ti.parent;
+ else
+ break;
+ }
+ fd = parent.isFuncDeclaration();
+ }
+
+ if (!fd.isThis() && !(fd.hasDualContext() && fd.isMember2()))
+ {
+ return null;
+ }
+
+ assert(fd.vthis);
+ return fd;
+
+}
/***********************************************************
* Resolve `exp` as a compile-time known string.
@@ -355,6 +408,126 @@ extern(D) bool arrayExpressionSemantic(
return err;
}
+/************************************************
+ * Handle the postblit call on lvalue, or the move of rvalue.
+ *
+ * Params:
+ * sc = the scope where the expression is encountered
+ * e = the expression the needs to be moved or copied (source)
+ * t = if the struct defines a copy constructor, the type of the destination
+ *
+ * Returns:
+ * The expression that copy constructs or moves the value.
+ */
+extern (D) Expression doCopyOrMove(Scope *sc, Expression e, Type t = null)
+{
+ if (auto ce = e.isCondExp())
+ {
+ ce.e1 = doCopyOrMove(sc, ce.e1);
+ ce.e2 = doCopyOrMove(sc, ce.e2);
+ }
+ else
+ {
+ e = e.isLvalue() ? callCpCtor(sc, e, t) : valueNoDtor(e);
+ }
+ return e;
+}
+
+/*********************************************
+ * If e is an instance of a struct, and that struct has a copy constructor,
+ * rewrite e as:
+ * (tmp = e),tmp
+ * Input:
+ * sc = just used to specify the scope of created temporary variable
+ * destinationType = the type of the object on which the copy constructor is called;
+ * may be null if the struct defines a postblit
+ */
+private Expression callCpCtor(Scope* sc, Expression e, Type destinationType)
+{
+ if (auto ts = e.type.baseElemOf().isTypeStruct())
+ {
+ StructDeclaration sd = ts.sym;
+ if (sd.postblit || sd.hasCopyCtor)
+ {
+ /* Create a variable tmp, and replace the argument e with:
+ * (tmp = e),tmp
+ * and let AssignExp() handle the construction.
+ * This is not the most efficient, ideally tmp would be constructed
+ * directly onto the stack.
+ */
+ auto tmp = copyToTemp(STC.rvalue, "__copytmp", e);
+ if (sd.hasCopyCtor && destinationType)
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=22619
+ // If the destination type is inout we can preserve it
+ // only if inside an inout function; if we are not inside
+ // an inout function, then we will preserve the type of
+ // the source
+ if (destinationType.hasWild && !(sc.func.storage_class & STC.wild))
+ tmp.type = e.type;
+ else
+ tmp.type = destinationType;
+ }
+ tmp.storage_class |= STC.nodtor;
+ tmp.dsymbolSemantic(sc);
+ Expression de = new DeclarationExp(e.loc, tmp);
+ Expression ve = new VarExp(e.loc, tmp);
+ de.type = Type.tvoid;
+ ve.type = e.type;
+ return Expression.combine(de, ve);
+ }
+ }
+ return e;
+}
+
+/************************************************
+ * If we want the value of this expression, but do not want to call
+ * the destructor on it.
+ */
+Expression valueNoDtor(Expression e)
+{
+ auto ex = lastComma(e);
+
+ if (auto ce = ex.isCallExp())
+ {
+ /* The struct value returned from the function is transferred
+ * so do not call the destructor on it.
+ * Recognize:
+ * ((S _ctmp = S.init), _ctmp).this(...)
+ * and make sure the destructor is not called on _ctmp
+ * BUG: if ex is a CommaExp, we should go down the right side.
+ */
+ if (auto dve = ce.e1.isDotVarExp())
+ {
+ if (dve.var.isCtorDeclaration())
+ {
+ // It's a constructor call
+ if (auto comma = dve.e1.isCommaExp())
+ {
+ if (auto ve = comma.e2.isVarExp())
+ {
+ VarDeclaration ctmp = ve.var.isVarDeclaration();
+ if (ctmp)
+ {
+ ctmp.storage_class |= STC.nodtor;
+ assert(!ce.isLvalue());
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (auto ve = ex.isVarExp())
+ {
+ auto vtmp = ve.var.isVarDeclaration();
+ if (vtmp && (vtmp.storage_class & STC.rvalue))
+ {
+ vtmp.storage_class |= STC.nodtor;
+ }
+ }
+ return e;
+}
+
/*
Checks if `exp` contains a direct access to a `noreturn`
variable. If that is the case, an `assert(0)` expression
@@ -493,6 +666,78 @@ private bool isDotOpDispatch(Expression e)
return false;
}
+private void hookDtors(CondExp ce, Scope* sc)
+{
+ extern (C++) final class DtorVisitor : StoppableVisitor
+ {
+ alias visit = typeof(super).visit;
+ public:
+ Scope* sc;
+ CondExp ce;
+ VarDeclaration vcond;
+ bool isThen;
+
+ extern (D) this(Scope* sc, CondExp ce) @safe
+ {
+ this.sc = sc;
+ this.ce = ce;
+ }
+
+ override void visit(Expression e)
+ {
+ //printf("(e = %s)\n", e.toChars());
+ }
+
+ override void visit(DeclarationExp e)
+ {
+ auto v = e.declaration.isVarDeclaration();
+ if (v && !v.isDataseg())
+ {
+ if (v._init)
+ {
+ if (auto ei = v._init.isExpInitializer())
+ walkPostorder(ei.exp, this);
+ }
+
+ if (v.edtor)
+ walkPostorder(v.edtor, this);
+
+ if (v.needsScopeDtor())
+ {
+ if (!vcond)
+ {
+ vcond = copyToTemp(STC.volatile_ | STC.const_, "__cond", ce.econd);
+ vcond.dsymbolSemantic(sc);
+
+ Expression de = new DeclarationExp(ce.econd.loc, vcond);
+ de = de.expressionSemantic(sc);
+
+ Expression ve = new VarExp(ce.econd.loc, vcond);
+ ce.econd = Expression.combine(de, ve);
+ }
+
+ //printf("\t++v = %s, v.edtor = %s\n", v.toChars(), v.edtor.toChars());
+ Expression ve = new VarExp(vcond.loc, vcond);
+ if (isThen)
+ v.edtor = new LogicalExp(v.edtor.loc, EXP.andAnd, ve, v.edtor);
+ else
+ v.edtor = new LogicalExp(v.edtor.loc, EXP.orOr, ve, v.edtor);
+ v.edtor = v.edtor.expressionSemantic(sc);
+ //printf("\t--v = %s, v.edtor = %s\n", v.toChars(), v.edtor.toChars());
+ }
+ }
+ }
+ }
+
+ scope DtorVisitor v = new DtorVisitor(sc, ce);
+ //printf("+%s\n", toChars());
+ v.isThen = true;
+ walkPostorder(ce.e1, v);
+ v.isThen = false;
+ walkPostorder(ce.e2, v);
+ //printf("-%s\n", toChars());
+}
+
/******************************
* Pull out callable entity with UFCS.
@@ -1516,6 +1761,26 @@ Leprop:
return ErrorExp.get();
}
+private bool checkRightThis(Expression e, Scope* sc)
+{
+ if (e.op == EXP.error)
+ return true;
+ if (e.op == EXP.variable && e.type.ty != Terror)
+ {
+ VarExp ve = cast(VarExp)e;
+ if (isNeedThisScope(sc, ve.var))
+ {
+ //printf("checkRightThis sc.intypeof = %d, ad = %p, func = %p, fdthis = %p\n",
+ // sc.intypeof, sc.getStructClassScope(), func, fdthis);
+ auto t = ve.var.isThis();
+ assert(t);
+ error(e.loc, "accessing non-static variable `%s` requires an instance of `%s`", ve.var.toChars(), t.toChars());
+ return true;
+ }
+ }
+ return false;
+}
+
extern (C++) Expression resolveProperties(Scope* sc, Expression e)
{
//printf("resolveProperties(%s)\n", e.toChars());
@@ -4141,6 +4406,58 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
(*exp.arguments)[i] = arg;
tb = tb.isTypeDArray().next.toBasetype();
}
+
+ if (nargs == 1)
+ {
+ 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;
+ }
+
+ auto hook = global.params.tracegc ? Id._d_newarrayTTrace : Id._d_newarrayT;
+ if (!verifyHookExist(exp.loc, *sc, hook, "new array"))
+ goto LskipNewArrayLowering;
+
+ /* Lower the memory allocation and initialization of `new T[n]`
+ * to `_d_newarrayT!T(n)`.
+ */
+ Expression lowering = new IdentifierExp(exp.loc, Id.empty);
+ lowering = new DotIdExp(exp.loc, lowering, Id.object);
+ auto tiargs = new Objects();
+ /* Remove `inout`, `const`, `immutable` and `shared` to reduce
+ * the number of generated `_d_newarrayT` instances.
+ */
+ const isShared = exp.type.nextOf.isShared();
+ auto t = exp.type.nextOf.unqualify(MODFlags.wild | MODFlags.const_ |
+ MODFlags.immutable_ | MODFlags.shared_);
+ tiargs.push(t);
+ 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((*exp.arguments)[0]);
+ arguments.push(new IntegerExp(exp.loc, isShared, Type.tbool));
+
+ lowering = new CallExp(exp.loc, lowering, arguments);
+ exp.lowering = lowering.expressionSemantic(sc);
+ }
}
else if (tb.isscalar())
{
@@ -4182,6 +4499,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
+ LskipNewArrayLowering:
//printf("NewExp: '%s'\n", toChars());
//printf("NewExp:type '%s'\n", type.toChars());
semanticTypeInfo(sc, exp.type);
@@ -10085,24 +10403,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- version (none)
- {
- if (global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
- e2x.op != EXP.slice && e2x.op != EXP.assign &&
- e2x.op != EXP.arrayLiteral && e2x.op != EXP.string_ &&
- !(e2x.op == EXP.add || e2x.op == EXP.min ||
- e2x.op == EXP.mul || e2x.op == EXP.div ||
- e2x.op == EXP.mod || e2x.op == EXP.xor ||
- e2x.op == EXP.and || e2x.op == EXP.or ||
- e2x.op == EXP.pow ||
- e2x.op == EXP.tilde || e2x.op == EXP.negate))
- {
- const(char)* e1str = exp.e1.toChars();
- const(char)* e2str = e2x.toChars();
- exp.warning("explicit element-wise assignment `%s = (%s)[]` is better than `%s = %s`", e1str, e2str, e1str, e2str);
- }
- }
-
Type t2n = t2.nextOf();
Type t1n = t1.nextOf();
int offset;
@@ -10149,21 +10449,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- version (none)
- {
- if (global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
- t1.ty == Tarray && t2.ty == Tsarray &&
- e2x.op != EXP.slice &&
- t2.implicitConvTo(t1))
- {
- // Disallow ar[] = sa (Converted to ar[] = sa[])
- // Disallow da = sa (Converted to da = sa[])
- const(char)* e1str = exp.e1.toChars();
- const(char)* e2str = e2x.toChars();
- const(char)* atypestr = exp.e1.op == EXP.slice ? "element-wise" : "slice";
- exp.warning("explicit %s assignment `%s = (%s)[]` is better than `%s = %s`", atypestr, e1str, e2str, e1str, e2str);
- }
- }
if (exp.op == EXP.blit)
e2x = e2x.castTo(sc, exp.e1.type);
else
diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d
index 8af2a95..dc4b20b 100644
--- a/gcc/d/dmd/foreachvar.d
+++ b/gcc/d/dmd/foreachvar.d
@@ -35,7 +35,7 @@ import dmd.mtype;
import dmd.postordervisitor;
import dmd.printast;
import dmd.root.array;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.statement;
import dmd.tokens;
import dmd.visitor;
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 81bb028..99848d8 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -48,7 +48,7 @@ import dmd.mtype;
import dmd.objc;
import dmd.root.aav;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.root.stringtable;
import dmd.semantic2;
@@ -689,7 +689,7 @@ extern (C++) class FuncDeclaration : Declaration
* Determine if 'this' overrides fd.
* Return !=0 if it does.
*/
- final int overrides(FuncDeclaration fd)
+ extern (D) final int overrides(FuncDeclaration fd)
{
int result = 0;
if (fd.ident == ident)
@@ -838,7 +838,7 @@ extern (C++) class FuncDeclaration : Declaration
* Returns:
* base class if overriding, null if not
*/
- final BaseClass* overrideInterface()
+ extern (D) final BaseClass* overrideInterface()
{
for (ClassDeclaration cd = toParent2().isClassDeclaration(); cd; cd = cd.baseClass)
{
@@ -1215,7 +1215,7 @@ extern (C++) class FuncDeclaration : Declaration
* -1 increase nesting by 1 (`fd` is nested within `this`)
* LevelError error, `this` cannot call `fd`
*/
- final int getLevel(FuncDeclaration fd, int intypeof)
+ extern (D) final int getLevel(FuncDeclaration fd, int intypeof)
{
//printf("FuncDeclaration::getLevel(fd = '%s')\n", fd.toChars());
Dsymbol fdparent = fd.toParent2();
@@ -1276,8 +1276,8 @@ extern (C++) class FuncDeclaration : Declaration
* -1 increase nesting by 1 (`fd` is nested within 'this')
* LevelError error
*/
- final int getLevelAndCheck(const ref Loc loc, Scope* sc, FuncDeclaration fd,
- Declaration decl)
+ extern (D) final int getLevelAndCheck(const ref Loc loc, Scope* sc, FuncDeclaration fd,
+ Declaration decl)
{
int level = getLevel(fd, sc.intypeof);
if (level != LevelError)
@@ -1490,7 +1490,7 @@ extern (C++) class FuncDeclaration : Declaration
return purity;
}
- final PURE isPureBypassingInference()
+ extern (D) final PURE isPureBypassingInference()
{
if (purityInprocess)
return PURE.fwdref;
@@ -1544,7 +1544,7 @@ extern (C++) class FuncDeclaration : Declaration
return type.toTypeFunction().trust == TRUST.safe;
}
- final bool isSafeBypassingInference()
+ extern (D) final bool isSafeBypassingInference()
{
return !(safetyInprocess) && isSafe();
}
@@ -1612,7 +1612,7 @@ extern (C++) class FuncDeclaration : Declaration
return type.toTypeFunction().isnogc;
}
- final bool isNogcBypassingInference()
+ extern (D) final bool isNogcBypassingInference()
{
return !nogcInprocess && isNogc();
}
@@ -2935,7 +2935,7 @@ extern (C++) class FuncDeclaration : Declaration
* Returns:
* `false` if the result cannot be returned by hidden reference.
*/
- final bool checkNRVO()
+ extern (D) final bool checkNRVO()
{
if (!isNRVO() || returns is null)
return false;
@@ -3939,7 +3939,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration
* If B to A conversion is convariant that requires offseet adjusting,
* all return statements should be adjusted to return expressions typed A.
*/
- void modifyReturns(Scope* sc, Type tret)
+ extern (D) void modifyReturns(Scope* sc, Type tret)
{
import dmd.statement_rewrite_walker;
@@ -4620,15 +4620,7 @@ bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)
case default_:
if (!sc.func)
return false;
- if (sc.func.isSafeBypassingInference())
- {
- if (!gag)
- {
- version (none) // disable obsolete warning
- warning(loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
- }
- }
- else if (!sc.func.safetyViolation)
+ if (!sc.func.isSafeBypassingInference() && !sc.func.safetyViolation)
{
import dmd.func : AttributeViolation;
sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1, arg2);
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 4048286..5c21be1 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -272,9 +272,9 @@ struct CompileEnv
DString time;
DString vendor;
DString timestamp;
- bool previewIn;
- bool ddocOutput;
- bool shortenedMethods;
+ d_bool previewIn;
+ d_bool ddocOutput;
+ d_bool shortenedMethods;
};
struct Global
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index 056e486..d935bd3 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -45,7 +45,7 @@ import dmd.parse;
import dmd.root.complex;
import dmd.root.ctfloat;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.statement;
import dmd.staticassert;
@@ -58,6 +58,7 @@ struct HdrGenState
bool hdrgen; /// true if generating header file
bool ddoc; /// true if generating Ddoc file
bool fullDump; /// true if generating a full AST dump file
+ bool importcHdr; /// true if generating a .di file from an ImportC file
bool fullQual; /// fully qualify types when printing
int tpltMember;
@@ -85,6 +86,7 @@ extern (C++) void genhdrfile(Module m, ref OutBuffer buf)
buf.writenl();
HdrGenState hgs;
hgs.hdrgen = true;
+ hgs.importcHdr = (m.filetype == FileType.c);
toCBuffer(m, buf, hgs);
}
@@ -1521,6 +1523,28 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
buf.level--;
buf.writeByte('}');
buf.writenl();
+
+ if (!hgs.importcHdr)
+ return;
+
+ /* C enums get their members inserted into the symbol table of the enum declaration.
+ * This is accomplished in addEnumMembersToSymtab().
+ * But when generating D code from ImportC code, D rulez are followed.
+ * Accomplish this by generating an alias declaration for each member
+ */
+ foreach (em; *d.members)
+ {
+ if (!em)
+ continue;
+ buf.writestring("alias ");
+ buf.writestring(em.ident.toString);
+ buf.writestring(" = ");
+ buf.writestring(d.ident.toString);
+ buf.writeByte('.');
+ buf.writestring(em.ident.toString);
+ buf.writeByte(';');
+ buf.writenl();
+ }
}
void visitNspace(Nspace d)
@@ -1541,6 +1565,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
void visitStructDeclaration(StructDeclaration d)
{
+ //printf("visitStructDeclaration() %s\n", d.ident.toChars());
buf.writestring(d.kind());
buf.writeByte(' ');
if (!d.isAnonymous())
@@ -1595,6 +1620,8 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
{
if (d.storage_class & STC.local)
return;
+ if (d.adFlags & d.hidden)
+ return;
buf.writestring("alias ");
if (d.aliassym)
{
@@ -1663,7 +1690,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
//printf("FuncDeclaration::toCBuffer() '%s'\n", f.toChars());
if (stcToBuffer(buf, f.storage_class))
buf.writeByte(' ');
- auto tf = cast(TypeFunction)f.type;
+ auto tf = f.type.isTypeFunction();
typeToBuffer(tf, f.ident, buf, &hgs);
if (hgs.hdrgen)
@@ -4038,6 +4065,7 @@ private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs)
void visitIdentifier(TypeIdentifier t)
{
+ //printf("visitTypeIdentifier() %s\n", t.ident.toChars());
buf.writestring(t.ident.toString());
visitTypeQualifiedHelper(t);
}
@@ -4064,11 +4092,14 @@ private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs)
void visitEnum(TypeEnum t)
{
+ //printf("visitEnum: %s\n", t.sym.toChars());
buf.writestring(hgs.fullQual ? t.sym.toPrettyChars() : t.sym.toChars());
}
void visitStruct(TypeStruct t)
{
+ //printf("visitTypeStruct() %s\n", t.sym.toChars());
+
// https://issues.dlang.org/show_bug.cgi?id=13776
// Don't use ti.toAlias() to avoid forward reference error
// while printing messages.
@@ -4095,6 +4126,11 @@ private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs)
{
if (t.mod & MODFlags.const_)
buf.writestring("const ");
+ if (hgs.importcHdr && t.id)
+ {
+ buf.writestring(t.id.toChars());
+ return;
+ }
buf.writestring(Token.toChars(t.tok));
buf.writeByte(' ');
if (t.id)
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index b506e6f..5fcda91 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -321,6 +321,8 @@ immutable Msgtable[] msgtable =
{ "_d_newclassTTrace" },
{ "_d_newitemT" },
{ "_d_newitemTTrace" },
+ { "_d_newarrayT" },
+ { "_d_newarrayTTrace" },
{ "_d_assert_fail" },
{ "dup" },
{ "_aaApply" },
diff --git a/gcc/d/dmd/identifier.d b/gcc/d/dmd/identifier.d
index 3173445..c2b2fba 100644
--- a/gcc/d/dmd/identifier.d
+++ b/gcc/d/dmd/identifier.d
@@ -17,7 +17,7 @@ import core.stdc.string;
import dmd.id;
import dmd.location;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.root.stringtable;
import dmd.root.utf;
diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h
index ff25ba2..31ee61a 100644
--- a/gcc/d/dmd/import.h
+++ b/gcc/d/dmd/import.h
@@ -41,7 +41,6 @@ public:
const char *kind() const override;
Visibility visible() override;
Import *syntaxCopy(Dsymbol *s) override; // copy only syntax trees
- void load(Scope *sc);
void importAll(Scope *sc) override;
Dsymbol *toAlias() override;
void addMember(Scope *sc, ScopeDsymbol *sds) override;
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index ecca552..ebcd011 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -25,7 +25,7 @@ import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.tokens;
import dmd.visitor;
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 4ab5848..67d0527 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -79,7 +79,6 @@ public:
d_bool isCarray; // C array semantics
bool isAssociativeArray() const;
- Expression *toAssocArrayLiteral();
void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index f1999fd..11ab816 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -35,7 +35,7 @@ import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.target;
import dmd.visitor;
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
index ef2bd0a..9fe48b8 100644
--- a/gcc/d/dmd/location.d
+++ b/gcc/d/dmd/location.d
@@ -64,7 +64,7 @@ nothrow:
this.messageStyle = messageStyle;
}
- extern (D) this(const(char)* filename, uint linnum, uint charnum) @safe
+ extern (C++) this(const(char)* filename, uint linnum, uint charnum) @safe
{
this._linnum = linnum;
this._charnum = charnum;
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index ce51266..6e8153d 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -127,7 +127,6 @@ public:
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;
- void deleteObjFile();
static void runDeferredSemantic();
static void runDeferredSemantic2();
static void runDeferredSemantic3();
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 01f94a7..6af140f 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -46,7 +46,7 @@ import dmd.opover;
import dmd.root.ctfloat;
import dmd.common.outbuffer;
import dmd.root.rmem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.stringtable;
import dmd.target;
import dmd.tokens;
@@ -1393,7 +1393,7 @@ extern (C++) abstract class Type : ASTNode
* For our new type 'this', which is type-constructed from t,
* fill in the cto, ito, sto, scto, wto shortcuts.
*/
- final void fixTo(Type t)
+ extern (D) final void fixTo(Type t)
{
// If fixing this: immutable(T*) by t: immutable(T)*,
// cache t to this.xto won't break transitivity.
@@ -1528,7 +1528,7 @@ extern (C++) abstract class Type : ASTNode
/***************************
* Look for bugs in constructing types.
*/
- final void check()
+ extern (D) final void check()
{
if (mcache)
with (mcache)
@@ -1722,7 +1722,7 @@ extern (C++) abstract class Type : ASTNode
* Apply STCxxxx bits to existing type.
* Use *before* semantic analysis is run.
*/
- final Type addSTC(StorageClass stc)
+ extern (D) final Type addSTC(StorageClass stc)
{
Type t = this;
if (t.isImmutable())
@@ -2555,7 +2555,7 @@ extern (C++) abstract class Type : ASTNode
* Return the mask that an integral type will
* fit into.
*/
- final uinteger_t sizemask()
+ extern (D) final uinteger_t sizemask()
{
uinteger_t m;
switch (toBasetype().ty)
@@ -5227,7 +5227,7 @@ extern (C++) abstract class TypeQualified : Type
// us a `TypeQualified`
abstract override TypeQualified syntaxCopy();
- final void syntaxCopyHelper(TypeQualified t)
+ extern (D) final void syntaxCopyHelper(TypeQualified t)
{
//printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t.toChars(), toChars());
idents.setDim(t.idents.length);
@@ -5265,17 +5265,17 @@ extern (C++) abstract class TypeQualified : Type
}
}
- final void addIdent(Identifier ident)
+ extern (D) final void addIdent(Identifier ident)
{
idents.push(ident);
}
- final void addInst(TemplateInstance inst)
+ extern (D) final void addInst(TemplateInstance inst)
{
idents.push(inst);
}
- final void addIndex(RootObject e)
+ extern (D) final void addIndex(RootObject e)
{
idents.push(e);
}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index aeeee8c..e72d918 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -39,8 +39,6 @@ typedef union tree_node type;
typedef struct TYPE type;
#endif
-void semanticTypeInfo(Scope *sc, Type *t);
-
Type *typeSemantic(Type *t, const Loc &loc, Scope *sc);
Type *merge(Type *type);
@@ -272,9 +270,6 @@ public:
Type *wildConstOf();
Type *sharedWildOf();
Type *sharedWildConstOf();
- void fixTo(Type *t);
- void check();
- Type *addSTC(StorageClass stc);
Type *castMod(MOD mod);
Type *addMod(MOD mod);
virtual Type *addStorageClass(StorageClass stc);
@@ -316,7 +311,6 @@ public:
virtual bool hasInvariant();
virtual Type *nextOf();
Type *baseElemOf();
- uinteger_t sizemask();
virtual bool needsDestruction();
virtual bool needsCopyOrPostblit();
virtual bool needsNested();
@@ -707,10 +701,6 @@ public:
// representing ident.ident!tiargs.ident. ... etc.
Objects idents;
- void syntaxCopyHelper(TypeQualified *t);
- void addIdent(Identifier *ident);
- void addInst(TemplateInstance *inst);
- void addIndex(RootObject *expr);
uinteger_t size(const Loc &loc) override;
void accept(Visitor *v) override { v->visit(this); }
@@ -937,7 +927,5 @@ public:
/**************************************************************/
-bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2);
-
// If the type is a class or struct, returns the symbol for it, else null.
AggregateDeclaration *isAggregate(Type *t);
diff --git a/gcc/d/dmd/mustuse.d b/gcc/d/dmd/mustuse.d
index 1d831bb..6934649 100644
--- a/gcc/d/dmd/mustuse.d
+++ b/gcc/d/dmd/mustuse.d
@@ -18,17 +18,6 @@ import dmd.globals;
import dmd.identifier;
import dmd.location;
-// Used in isIncrementOrDecrement
-private const StringExp plusPlus, minusMinus;
-
-// Loc.initial cannot be used in static initializers, so
-// these need a static constructor.
-shared static this()
-{
- plusPlus = new StringExp(Loc.initial, "++");
- minusMinus = new StringExp(Loc.initial, "--");
-}
-
/**
* Check whether discarding an expression would violate the requirements of
* @mustuse. If so, emit an error.
@@ -173,9 +162,15 @@ private bool isIncrementOrDecrement(Expression e)
{
if (auto argExp = (*tiargs)[0].isExpression())
{
- auto op = argExp.isStringExp();
- if (op && (op.compare(plusPlus) == 0 || op.compare(minusMinus) == 0))
- return true;
+ if (auto op = argExp.isStringExp())
+ {
+ if (op.len == 2 && op.sz == 1)
+ {
+ const s = op.peekString();
+ if (s == "++" || s == "--")
+ return true;
+ }
+ }
}
}
}
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index 5606061..59bf1d5 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -256,7 +256,7 @@ private FuncDeclaration stripHookTraceImpl(FuncDeclaration fd)
{
import dmd.id : Id;
import dmd.dsymbol : Dsymbol;
- import dmd.root.rootobject : RootObject, DYNCAST;
+ import dmd.rootobject : RootObject, DYNCAST;
if (fd.ident != Id._d_HookTraceImpl)
return fd;
diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d
index 8b30681..dc94aec 100644
--- a/gcc/d/dmd/ob.d
+++ b/gcc/d/dmd/ob.d
@@ -16,7 +16,7 @@ import core.stdc.stdlib;
import core.stdc.string;
import dmd.root.array;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.rmem;
import dmd.aggregate;
diff --git a/gcc/d/dmd/objc.h b/gcc/d/dmd/objc.h
index a5cc6f1..40f634e 100644
--- a/gcc/d/dmd/objc.h
+++ b/gcc/d/dmd/objc.h
@@ -30,8 +30,6 @@ struct ObjcSelector
static void _init();
- ObjcSelector(const char *sv, size_t len, size_t pcount);
-
static ObjcSelector *create(FuncDeclaration *fdecl);
};
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 3821f94..9a13d5c 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -25,7 +25,7 @@ import dmd.location;
import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rmem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.tokens;
diff --git a/gcc/d/dmd/root/rootobject.d b/gcc/d/dmd/rootobject.d
index 65c499d..7867ad5 100644
--- a/gcc/d/dmd/root/rootobject.d
+++ b/gcc/d/dmd/rootobject.d
@@ -4,12 +4,12 @@
* Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
* Authors: Walter Bright, https://www.digitalmars.com
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
- * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/rootobject.d, root/_rootobject.d)
- * Documentation: https://dlang.org/phobos/dmd_root_rootobject.html
- * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/rootobject.d
+ * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/rootobject.d, _rootobject.d)
+ * Documentation: https://dlang.org/phobos/dmd_rootobject.html
+ * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/rootobject.d
*/
-module dmd.root.rootobject;
+module dmd.rootobject;
/***********************************************************
*/
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index 3c4ae49..178542e 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -126,6 +126,4 @@ 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/semantic2.d b/gcc/d/dmd/semantic2.d
index 6a379517..036560b 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -55,7 +55,7 @@ import dmd.parse;
import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rmem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.utf;
import dmd.sideeffect;
import dmd.statementsem;
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index e093140..2f1839c 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -58,7 +58,7 @@ import dmd.parse;
import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rmem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.utf;
import dmd.sideeffect;
import dmd.statementsem;
diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d
index de92b29..80c9a46 100644
--- a/gcc/d/dmd/sideeffect.d
+++ b/gcc/d/dmd/sideeffect.d
@@ -32,7 +32,7 @@ import dmd.visitor;
* 1. save evaluation order
* 2. prevent sharing of sub-expression in AST
*/
-extern (C++) bool isTrivialExp(Expression e)
+bool isTrivialExp(Expression e)
{
extern (C++) final class IsTrivialExp : StoppableVisitor
{
@@ -70,7 +70,7 @@ extern (C++) bool isTrivialExp(Expression e)
* assumeImpureCalls = whether function calls should always be assumed to
* be impure (e.g. debug is allowed to violate purity)
*/
-extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false)
+bool hasSideEffect(Expression e, bool assumeImpureCalls = false)
{
extern (C++) final class LambdaHasSideEffect : StoppableVisitor
{
@@ -269,41 +269,6 @@ bool discardValue(Expression e)
break;
}
case EXP.call:
- /* Issue 3882: */
- if (global.params.warnings != DiagnosticReporting.off && !global.gag)
- {
- CallExp ce = cast(CallExp)e;
- if (e.type.ty == Tvoid)
- {
- /* Don't complain about calling void-returning functions with no side-effect,
- * because purity and nothrow are inferred, and because some of the
- * runtime library depends on it. Needs more investigation.
- *
- * One possible solution is to restrict this message to only be called in hierarchies that
- * never call assert (and or not called from inside unittest blocks)
- */
- }
- else if (ce.e1.type)
- {
- Type t = ce.e1.type.toBasetype();
- if (t.ty == Tdelegate)
- t = (cast(TypeDelegate)t).next;
- if (t.ty == Tfunction && (ce.f ? callSideEffectLevel(ce.f) : callSideEffectLevel(ce.e1.type)) > 0)
- {
- const(char)* s;
- if (ce.f)
- s = ce.f.toPrettyChars();
- else if (ce.e1.op == EXP.star)
- {
- // print 'fp' if ce.e1 is (*fp)
- s = (cast(PtrExp)ce.e1).e1.toChars();
- }
- else
- s = ce.e1.toChars();
- warning(e.loc, "calling `%s` without side effects discards return value of type `%s`; prepend a `cast(void)` if intentional", s, e.type.toChars());
- }
- }
- }
return false;
case EXP.andAnd:
case EXP.orOr:
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index da26bc9..b5906c8 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -33,7 +33,7 @@ import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.sapply;
import dmd.staticassert;
import dmd.tokens;
@@ -114,7 +114,7 @@ extern (C++) abstract class Statement : ASTNode
* Returns:
* `true` if statement uses exception handling
*/
- final bool usesEH()
+ extern (D) final bool usesEH()
{
extern (C++) final class UsesEH : StoppableVisitor
{
@@ -153,7 +153,7 @@ extern (C++) abstract class Statement : ASTNode
* Returns:
* `true` if statement 'comes from' somewhere else, like a goto
*/
- final bool comeFrom()
+ extern (D) final bool comeFrom()
{
extern (C++) final class ComeFrom : StoppableVisitor
{
@@ -192,7 +192,7 @@ extern (C++) abstract class Statement : ASTNode
* Returns:
* `true` if statement has executable code.
*/
- final bool hasCode()
+ extern (D) final bool hasCode()
{
extern (C++) final class HasCode : StoppableVisitor
{
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index fe899c6..ef8423f 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -113,14 +113,9 @@ public:
virtual Statement *syntaxCopy();
- void error(const char *format, ...);
- void warning(unsigned flag, const char *format, ...);
- void deprecation(const char *format, ...);
virtual Statement *getRelatedLabeled() { return this; }
virtual bool hasBreak() const;
virtual bool hasContinue() const;
- bool usesEH();
- bool comeFrom();
bool hasCode();
virtual Statement *last();
@@ -712,7 +707,7 @@ class AsmStatement : public Statement
{
public:
Token *tokens;
- bool caseSensitive; // for register names
+ d_bool caseSensitive; // for register names
AsmStatement *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 8622b5c..44f95ec 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -96,12 +96,8 @@ public:
Visibility visible() override;
- MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration* td2, ArgumentList argumentList);
- RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
-
TemplateDeclaration *isTemplateDeclaration() override { return this; }
- TemplateTupleParameter *isVariadic();
bool isDeprecated() const override;
bool isOverloadable() const override;
@@ -298,7 +294,6 @@ public:
const char *toChars() const override;
const char* toPrettyCharsHelper() override final;
Identifier *getIdent() override final;
- hash_t toHash();
bool isDiscardable();
bool needsCodegen();
diff --git a/gcc/d/dmd/templateparamsem.d b/gcc/d/dmd/templateparamsem.d
index 6b8f949..de40c1f 100644
--- a/gcc/d/dmd/templateparamsem.d
+++ b/gcc/d/dmd/templateparamsem.d
@@ -19,7 +19,7 @@ import dmd.globals;
import dmd.location;
import dmd.expression;
import dmd.expressionsem;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.mtype;
import dmd.typesem;
import dmd.visitor;
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index c76d549..317a6e6 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -900,7 +900,7 @@ extern (C++) struct Token
nothrow:
- int isKeyword() pure const @safe @nogc
+ extern (D) int isKeyword() pure const @safe @nogc
{
foreach (kw; keywords)
{
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index b1f633f..560942d 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -469,10 +469,7 @@ struct Token
Identifier *ident;
};
- void free();
-
Token() : next(NULL) {}
- int isKeyword();
const char *toChars() const;
static const char *toChars(TOK value);
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index bdc569c..254900e 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -49,7 +49,7 @@ import dmd.target;
import dmd.tokens;
import dmd.typesem;
import dmd.visitor;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.common.outbuffer;
import dmd.root.string;
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index 376c12f..bf1d38e 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -8,7 +8,7 @@ module dmd.transitivevisitor;
import dmd.astenums;
import dmd.permissivevisitor;
import dmd.tokens;
-import dmd.root.rootobject;
+import dmd.rootobject;
import core.stdc.stdio;
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index c69268a..fe54e29 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -57,7 +57,7 @@ import dmd.root.complex;
import dmd.root.ctfloat;
import dmd.root.rmem;
import dmd.common.outbuffer;
-import dmd.root.rootobject;
+import dmd.rootobject;
import dmd.root.string;
import dmd.root.stringtable;
import dmd.safe;
diff --git a/gcc/d/dmd/visitor.d b/gcc/d/dmd/visitor.d
index 591d3c0..5722e10 100644
--- a/gcc/d/dmd/visitor.d
+++ b/gcc/d/dmd/visitor.d
@@ -17,7 +17,7 @@ import dmd.parsetimevisitor;
import dmd.tokens;
import dmd.transitivevisitor;
import dmd.expression;
-import dmd.root.rootobject;
+import dmd.rootobject;
/**
* Classic Visitor class which implements visit methods for all the AST
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 52243e6..17801a3 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -972,8 +972,7 @@ public:
Declaration *decl = e->e1->isVarExp ()->var;
if (decl->storage_class & (STCout | STCref))
{
- tree t2 = convert_for_assignment (build_expr (e->e2),
- e->e2->type, e->e1->type);
+ tree t2 = convert_for_assignment (e->e2, e->e1->type);
tree t1 = build_expr (e->e1);
/* Want reference to lhs, not indirect ref. */
t1 = TREE_OPERAND (t1, 0);
@@ -993,8 +992,7 @@ public:
if (tb1->ty == TY::Tstruct)
{
tree t1 = build_expr (e->e1);
- tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
- e->e2->type, e->e1->type);
+ tree t2 = convert_for_assignment (e->e2, e->e1->type, true);
StructDeclaration *sd = tb1->isTypeStruct ()->sym;
/* Look for struct = 0. */
@@ -1073,8 +1071,7 @@ public:
|| (e->op == EXP::blit || e->e1->type->size () == 0))
{
tree t1 = build_expr (e->e1);
- tree t2 = convert_for_assignment (build_expr (e->e2),
- e->e2->type, e->e1->type);
+ tree t2 = convert_for_assignment (e->e2, e->e1->type);
this->result_ = build_assign (modifycode, t1, t2);
return;
@@ -1088,8 +1085,7 @@ public:
/* Simple assignment. */
tree t1 = build_expr (e->e1);
- tree t2 = convert_for_assignment (build_expr (e->e2),
- e->e2->type, e->e1->type);
+ tree t2 = convert_for_assignment (e->e2, e->e1->type);
this->result_ = build_assign (modifycode, t1, t2);
}
@@ -1714,6 +1710,12 @@ public:
build the call expression. */
tree exp = d_build_call (tf, callee, object, e->arguments);
+ /* Record whether the call expression has no side effects, so we can check
+ for an unused return value later. */
+ if (TREE_CODE (exp) == CALL_EXPR && CALL_EXPR_FN (exp) != NULL_TREE
+ && call_side_effect_free_p (e->f, e->e1->type))
+ CALL_EXPR_WARN_IF_UNUSED (exp) = 1;
+
if (returnvalue != NULL_TREE)
exp = compound_expr (exp, returnvalue);
@@ -2338,7 +2340,12 @@ public:
new_call = d_save_expr (new_call);
se->type = sd->type;
se->sym = new_call;
- result = compound_expr (build_expr (se), new_call);
+
+ /* Setting `se->sym' would mean that the result of the
+ constructed struct literal expression is `*(new_call)'.
+ Strip off the indirect reference, as we don't mean to
+ compute the value yet. */
+ result = build_address (build_expr (se));
}
else
result = new_call;
@@ -2350,29 +2357,14 @@ public:
else if (tb->ty == TY::Tarray)
{
/* Allocating memory for a new D array. */
- tb = e->newtype->toBasetype ();
- TypeDArray *tarray = tb->isTypeDArray ();
-
gcc_assert (e->arguments && e->arguments->length >= 1);
if (e->arguments->length == 1)
{
- /* Single dimension array allocations. */
- Expression *arg = (*e->arguments)[0];
-
- if (tarray->next->size () == 0)
- {
- /* Array element size is unknown. */
- this->result_ = d_array_value (build_ctype (e->type),
- size_int (0), null_pointer_node);
- return;
- }
-
- libcall_fn libcall = tarray->next->isZeroInit ()
- ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
- result = build_libcall (libcall, tb, 2,
- build_typeinfo (e, e->type),
- build_expr (arg));
+ /* Single dimension array allocations has already been handled by
+ the front-end. */
+ gcc_assert (e->lowering);
+ result = build_expr (e->lowering);
}
else
{
@@ -2408,7 +2400,8 @@ public:
size_int (e->arguments->length),
build_address (var));
- result = build_libcall (libcall, tb, 2, tinfo, dims);
+ result = build_libcall (libcall, e->newtype->toBasetype (), 2,
+ tinfo, dims);
}
if (e->argprefix)
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index 8d6c8f0..e3c1ef9 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -330,7 +330,7 @@ static tree
build_dso_cdtor_fn (bool ctor_p)
{
const char *name = ctor_p ? GDC_PREFIX ("dso_ctor") : GDC_PREFIX ("dso_dtor");
- tree condition = ctor_p ? boolean_true_node : boolean_false_node;
+ tree condition = ctor_p ? d_bool_true_node : d_bool_false_node;
/* Declaration of dso_ctor/dso_dtor is:
@@ -453,7 +453,7 @@ register_moduleinfo (Module *decl, tree minfo)
d_finish_decl (dso_slot_node);
dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"),
- boolean_type_node);
+ d_bool_type);
d_finish_decl (dso_initialized_node);
/* Declare dso_ctor() and dso_dtor(). */
diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def
index 4d1ba09..f7887e1 100644
--- a/gcc/d/runtime.def
+++ b/gcc/d/runtime.def
@@ -70,13 +70,8 @@ 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 an array. The `i' variant is for when the
- initializer is nonzero, and the `m' variant is when initializing a
- multi-dimensional array. */
-DEF_D_RUNTIME (NEWARRAYT, "_d_newarrayT", RT(ARRAY_VOID),
- P2(CONST_TYPEINFO, SIZE_T), 0)
-DEF_D_RUNTIME (NEWARRAYIT, "_d_newarrayiT", RT(ARRAY_VOID),
- P2(CONST_TYPEINFO, SIZE_T), 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),
diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index db6f71b..f87e094 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -215,6 +215,38 @@ add_stmt (tree t)
if (!TREE_SIDE_EFFECTS (t))
return;
+ /* If a call expression has no side effects, and there's no explicit
+ `cast(void)', then issue a warning about the unused return value. */
+ if (TREE_CODE (t) == INDIRECT_REF)
+ {
+ t = TREE_OPERAND (t, 0);
+
+ if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
+ warning (OPT_Wunused_value, "value computed is not used");
+ }
+
+ if (TREE_CODE (t) == CALL_EXPR && CALL_EXPR_FN (t) != NULL_TREE
+ && CALL_EXPR_WARN_IF_UNUSED (t))
+ {
+ tree callee = CALL_EXPR_FN (t);
+
+ /* It's a call to a function or function pointer. */
+ if (TREE_CODE (callee) == ADDR_EXPR
+ && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (callee, 0)))
+ callee = TREE_OPERAND (callee, 0);
+
+ /* It's a call to a delegate object. */
+ if (TREE_CODE (callee) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (callee, 0))) == RECORD_TYPE
+ && TYPE_DELEGATE (TREE_TYPE (TREE_OPERAND (callee, 0))))
+ callee = TREE_OPERAND (callee, 0);
+
+ warning (OPT_Wunused_value,
+ "calling %qE without side effects discards return value "
+ "of type %qT; prepend a %<cast(void)%> if intentional",
+ callee, TREE_TYPE (t));
+ }
+
if (TREE_CODE (t) == COMPOUND_EXPR)
{
/* Push out each comma expressions as separate statements. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index bf941e6..fa74028 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3755,6 +3755,63 @@ my_memcpy (void *dest, const void *src, size_t len)
__attribute__((nonnull));
@end smallexample
+@cindex @code{null_terminated_string_arg} function attribute
+@item null_terminated_string_arg
+@itemx null_terminated_string_arg (@var{N})
+The @code{null_terminated_string_arg} attribute may be applied to a
+function that takes a @code{char *} or @code{const char *} at
+referenced argument @var{N}.
+
+It indicates that the passed argument must be a C-style null-terminated
+string. Specifically, the presence of the attribute implies that, if
+the pointer is non-null, the function may scan through the referenced
+buffer looking for the first zero byte.
+
+In particular, when the analyzer is enabled (via @option{-fanalyzer}),
+if the pointer is non-null, it will simulate scanning for the first
+zero byte in the referenced buffer, and potentially emit
+@option{-Wanalyzer-use-of-uninitialized-value}
+or @option{-Wanalyzer-out-of-bounds} on improperly terminated buffers.
+
+For example, given the following:
+
+@smallexample
+char *example_1 (const char *p)
+ __attribute__((null_terminated_string_arg (1)));
+@end smallexample
+
+the analyzer will check that any non-null pointers passed to the function
+are validly terminated.
+
+If the parameter must be non-null, it is appropriate to use both this
+attribute and the attribute @code{nonnull}, such as in:
+
+@smallexample
+extern char *example_2 (const char *p)
+ __attribute__((null_terminated_string_arg (1),
+ nonnull (1)));
+@end smallexample
+
+See the @code{nonnull} attribute for more information and
+caveats.
+
+If the pointer argument is also referred to by an @code{access} attribute on the
+function with @var{access-mode} either @code{read_only} or @code{read_write}
+and the latter attribute has the optional @var{size-index} argument
+referring to a size argument, this expressses the maximum size of the access.
+For example, given:
+
+@smallexample
+extern char *example_fn (const char *p, size_t n)
+ __attribute__((null_terminated_string_arg (1),
+ access (read_only, 1, 2),
+ nonnull (1)));
+@end smallexample
+
+the analyzer will require the first parameter to be non-null, and either
+be validly null-terminated, or validly readable up to the size specified by
+the second parameter.
+
@cindex @code{noplt} function attribute
@item noplt
The @code{noplt} attribute is the counterpart to option @option{-fno-plt}.
@@ -16749,6 +16806,11 @@ __float128 __builtin_nanq (void);
__float128 __builtin_nansq (void);
@end smallexample
+Returns the value that is currently set in the @samp{tp} register.
+@smallexample
+ void * __builtin_thread_pointer (void)
+@end smallexample
+
@node MIPS DSP Built-in Functions
@subsection MIPS DSP Built-in Functions
@@ -20143,12 +20205,16 @@ int __builtin_bcdadd_ov (vector unsigned char, vector unsigned char, const int);
vector __int128 __builtin_bcdsub (vector __int128, vector __int128, const int);
vector unsigned char __builtin_bcdsub (vector unsigned char, vector unsigned char,
const int);
+int __builtin_bcdsub_le (vector __int128, vector __int128, const int);
+int __builtin_bcdsub_le (vector unsigned char, vector unsigned char, const int);
int __builtin_bcdsub_lt (vector __int128, vector __int128, const int);
int __builtin_bcdsub_lt (vector unsigned char, vector unsigned char, const int);
int __builtin_bcdsub_eq (vector __int128, vector __int128, const int);
int __builtin_bcdsub_eq (vector unsigned char, vector unsigned char, const int);
int __builtin_bcdsub_gt (vector __int128, vector __int128, const int);
int __builtin_bcdsub_gt (vector unsigned char, vector unsigned char, const int);
+int __builtin_bcdsub_ge (vector __int128, vector __int128, const int);
+int __builtin_bcdsub_ge (vector unsigned char, vector unsigned char, const int);
int __builtin_bcdsub_ov (vector __int128, vector __int128, const int);
int __builtin_bcdsub_ov (vector unsigned char, vector unsigned char, const int);
@end smallexample
@@ -22662,6 +22728,9 @@ Intel Knights Mill CPU.
@item lujiazui
ZHAOXIN lujiazui CPU.
+@item yongfeng
+ZHAOXIN yongfeng CPU.
+
@item amdfam10h
AMD Family 10h CPU.
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 4035e80..959a041 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1856,6 +1856,12 @@ particularly useful if you intend to use several versions of GCC in
parallel. The default is @samp{yes} for @samp{libada}, and @samp{no} for
the remaining libraries.
+@item --with-darwin-extra-rpath
+This is provided to allow distributions to add a single additional
+runpath on Darwin / macOS systems. This allows for cases where the
+installed GCC library directories are then symlinked to a common
+directory outside of the GCC installation.
+
@item @anchor{WithAixSoname}--with-aix-soname=@samp{aix}, @samp{svr4} or @samp{both}
Traditional AIX shared library versioning (versioned @code{Shared Object}
files as members of unversioned @code{Archive Library} files named
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 17aaa8c..6e776a0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -926,7 +926,7 @@ Objective-C and Objective-C++ Dialects}.
-iframework
-image_base -init -install_name -keep_private_externs
-multi_module -multiply_defined -multiply_defined_unused
--noall_load -no_dead_strip_inits_and_terms
+-noall_load -no_dead_strip_inits_and_terms -nodefaultrpaths
-nofixprebinding -nomultidefs -noprebind -noseglinkedit
-pagezero_size -prebind -prebind_all_twolevel_modules
-private_bundle -read_only_relocs -sectalign
@@ -1042,7 +1042,7 @@ Objective-C and Objective-C++ Dialects}.
-mcond-move-float -mno-cond-move-float
-memcpy -mno-memcpy -mstrict-align -mno-strict-align
-mmax-inline-memcpy-size=@var{n}
--mexplicit-relocs -mno-explicit-relocs
+-mexplicit-relocs=@var{style} -mexplicit-relocs -mno-explicit-relocs
-mdirect-extern-access -mno-direct-extern-access
-mcmodel=@var{code-model}}
@@ -8138,6 +8138,16 @@ always leads to a call to another @code{cold} function such as wrappers of
C++ @code{throw} or fatal error reporting functions leading to @code{abort}.
@end table
+@opindex Wno-alloc-size
+@opindex Walloc-size
+@item -Walloc-size
+Warn about calls to allocation functions decorated with attribute
+@code{alloc_size} that specify insufficient size for the target type of
+the pointer the result is assigned to, including those to the built-in
+forms of the functions @code{aligned_alloc}, @code{alloca},
+@code{calloc},
+@code{malloc}, and @code{realloc}.
+
@opindex Wno-alloc-zero
@opindex Walloc-zero
@item -Walloc-zero
@@ -24484,6 +24494,14 @@ an executable when linking, using the Darwin @file{libtool} command.
This causes GCC's output file to have the @samp{ALL} subtype, instead of
one controlled by the @option{-mcpu} or @option{-march} option.
+@opindex nodefaultrpaths
+@item -nodefaultrpaths
+Do not add default run paths for the compiler library directories to
+executables, modules or dynamic libraries. On macOS 10.5 and later,
+the embedded runpath is added by default unless the user adds
+@option{-nodefaultrpaths} to the link line. Run paths are needed
+(and therefore enforced) to build on macOS version 10.11 or later.
+
@item -allowable_client @var{client_name}
@itemx -client_name
@itemx -compatibility_version
@@ -26302,26 +26320,39 @@ The text segment and data segment must be within 2GB addressing space.
@item extreme
This mode does not limit the size of the code segment and data segment.
-The @option{-mcmodel=extreme} option is incompatible with @option{-fplt} and
-@option{-mno-explicit-relocs}.
+The @option{-mcmodel=extreme} option is incompatible with @option{-fplt},
+and it requires @option{-mexplicit-relocs=always}.
@end table
The default code model is @code{normal}.
-@opindex mexplicit-relocs
-@opindex mno-explicit-relocs
-@item -mexplicit-relocs
-@itemx -mno-explicit-relocs
-Use or do not use assembler relocation operators when dealing with symbolic
+@item -mexplicit-relocs=@var{style}
+Set when to use assembler relocation operators when dealing with symbolic
addresses. The alternative is to use assembler macros instead, which may
-limit instruction scheduling but allow linker relaxation. The default
+limit instruction scheduling but allow linker relaxation.
+with @option{-mexplicit-relocs=none} the assembler macros are always used,
+with @option{-mexplicit-relocs=always} the assembler relocation operators
+are always used, with @option{-mexplicit-relocs=auto} the compiler will
+use the relocation operators where the linker relaxation is impossible to
+improve the code quality, and macros elsewhere. The default
value for the option is determined during GCC build-time by detecting
corresponding assembler support:
-@code{-mno-explicit-relocs} if the assembler supports relaxation or it
-does not support relocation operators at all,
-@code{-mexplicit-relocs} otherwise. This option is mostly useful for
+@option{-mexplicit-relocs=none} if the assembler does not support
+relocation operators at all,
+@option{-mexplicit-relocs=always} if the assembler supports relocation
+operators but does not support relaxation,
+@option{-mexplicit-relocs=auto} if the assembler supports both relocation
+operators and relaxation. This option is mostly useful for
debugging, or interoperation with assemblers different from the build-time
one.
+@opindex mexplicit-relocs
+@item -mexplicit-relocs
+An alias of @option{-mexplicit-relocs=always} for backward compatibility.
+
+@opindex mno-explicit-relocs
+@item -mno-explicit-relocs
+An alias of @option{-mexplicit-relocs=none} for backward compatibility.
+
@opindex mdirect-extern-access
@item -mdirect-extern-access
@itemx -mno-direct-extern-access
@@ -33292,6 +33323,12 @@ ZHAOXIN lujiazui CPU with x86-64, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, AVX, POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, CX16,
ABM, BMI, BMI2, F16C, FXSR, RDSEED instruction set support.
+@item yongfeng
+ZHAOXIN yongfeng CPU with x86-64, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
+SSE4.2, AVX, POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, CX16,
+ABM, BMI, BMI2, F16C, FXSR, RDSEED, AVX2, FMA, SHA, LZCNT
+instruction set support.
+
@item geode
AMD Geode embedded processor with MMX and 3DNow!@: instruction set support.
@end table
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index daa318e..fab2513 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -7341,8 +7341,10 @@ store the result in operand 0, otherwise store operand 2 in operand 0.
The operation only works for the operands are vectors.
@smallexample
-for (i = 0; i < ops[4] + ops[5]; i++)
- op0[i] = op1[i] ? @var{op} op2[i] : op3[i];
+for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++)
+ op0[i] = (i < ops[4] + ops[5] && op1[i]
+ ? @var{op} op2[i]
+ : op3[i]);
@end smallexample
where, for example, @var{op} is @code{~} for @samp{cond_len_one_cmpl@var{mode}}.
@@ -7403,8 +7405,10 @@ store the result in operand 0, otherwise store operand 4 in operand 0.
The operation only works for the operands are vectors.
@smallexample
-for (i = 0; i < ops[5] + ops[6]; i++)
- op0[i] = op1[i] ? op2[i] @var{op} op3[i] : op4[i];
+for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++)
+ op0[i] = (i < ops[5] + ops[6] && op1[i]
+ ? op2[i] @var{op} op3[i]
+ : op4[i]);
@end smallexample
where, for example, @var{op} is @code{+} for @samp{cond_len_add@var{mode}}.
@@ -7436,8 +7440,10 @@ takes 3 operands rather than two. For example, the vector form of
@samp{cond_len_fma@var{mode}} is equivalent to:
@smallexample
-for (i = 0; i < ops[6] + ops[7]; i++)
- op0[i] = op1[i] ? fma (op2[i], op3[i], op4[i]) : op5[i];
+for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++)
+ op0[i] = (i < ops[6] + ops[7] && op1[i]
+ ? fma (op2[i], op3[i], op4[i])
+ : op5[i]);
@end smallexample
@cindex @code{neg@var{mode}cc} instruction pattern
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 0ea73bf..1e0cec6 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -14311,7 +14311,9 @@ reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
argument pointer and soft frame pointer rtx's.
Use DW_OP_fbreg offset DW_OP_stack_value in this case. */
if ((rtl == arg_pointer_rtx || rtl == frame_pointer_rtx)
- && eliminate_regs (rtl, VOIDmode, NULL_RTX) != rtl)
+ && (ira_use_lra_p
+ ? lra_eliminate_regs (rtl, VOIDmode, NULL_RTX)
+ : eliminate_regs (rtl, VOIDmode, NULL_RTX)) != rtl)
{
dw_loc_descr_ref result = NULL;
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 763bd82..ed4dbb1 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -988,18 +988,47 @@ alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
return align;
}
-/* Return the widest QI vector, if QI_MODE is true, or integer mode
- that is narrower than SIZE bytes. */
+/* Return true if we know how to implement OP using vectors of bytes. */
+static bool
+can_use_qi_vectors (by_pieces_operation op)
+{
+ return (op == COMPARE_BY_PIECES
+ || op == SET_BY_PIECES
+ || op == CLEAR_BY_PIECES);
+}
+/* Return true if optabs exists for the mode and certain by pieces
+ operations. */
+static bool
+by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
+{
+ if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
+ return false;
+
+ if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
+ && VECTOR_MODE_P (mode)
+ && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing)
+ return false;
+
+ if (op == COMPARE_BY_PIECES
+ && !can_compare_p (EQ, mode, ccp_jump))
+ return false;
+
+ return true;
+}
+
+/* Return the widest mode that can be used to perform part of an
+ operation OP on SIZE bytes. Try to use QI vector modes where
+ possible. */
static fixed_size_mode
-widest_fixed_size_mode_for_size (unsigned int size, bool qi_vector)
+widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
{
fixed_size_mode result = NARROWEST_INT_MODE;
gcc_checking_assert (size > 1);
/* Use QI vector only if size is wider than a WORD. */
- if (qi_vector && size > UNITS_PER_WORD)
+ if (can_use_qi_vectors (op) && size > UNITS_PER_WORD)
{
machine_mode mode;
fixed_size_mode candidate;
@@ -1009,8 +1038,7 @@ widest_fixed_size_mode_for_size (unsigned int size, bool qi_vector)
{
if (GET_MODE_SIZE (candidate) >= size)
break;
- if (optab_handler (vec_duplicate_optab, candidate)
- != CODE_FOR_nothing)
+ if (by_pieces_mode_supported_p (candidate, op))
result = candidate;
}
@@ -1019,9 +1047,14 @@ widest_fixed_size_mode_for_size (unsigned int size, bool qi_vector)
}
opt_scalar_int_mode tmode;
+ scalar_int_mode mode;
FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
- if (GET_MODE_SIZE (tmode.require ()) < size)
- result = tmode.require ();
+ {
+ mode = tmode.require ();
+ if (GET_MODE_SIZE (mode) < size
+ && by_pieces_mode_supported_p (mode, op))
+ result = mode;
+ }
return result;
}
@@ -1061,8 +1094,7 @@ by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
{
/* NB: Round up L and ALIGN to the widest integer mode for
MAX_SIZE. */
- mode = widest_fixed_size_mode_for_size (max_size,
- op == SET_BY_PIECES);
+ 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));
@@ -1076,8 +1108,7 @@ 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 == SET_BY_PIECES);
+ mode = widest_fixed_size_mode_for_size (max_size, op);
enum insn_code icode;
unsigned int modesize = GET_MODE_SIZE (mode);
@@ -1317,8 +1348,8 @@ class op_by_pieces_d
bool m_push;
/* True if targetm.overlap_op_by_pieces_p () returns true. */
bool m_overlap_op_by_pieces;
- /* True if QI vector mode can be used. */
- bool m_qi_vector_mode;
+ /* The type of operation that we're performing. */
+ by_pieces_operation m_op;
/* Virtual functions, overriden by derived classes for the specific
operation. */
@@ -1331,7 +1362,7 @@ class op_by_pieces_d
public:
op_by_pieces_d (unsigned int, rtx, bool, rtx, bool, by_pieces_constfn,
void *, unsigned HOST_WIDE_INT, unsigned int, bool,
- bool = false);
+ by_pieces_operation);
void run ();
};
@@ -1349,11 +1380,11 @@ op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
void *from_cfn_data,
unsigned HOST_WIDE_INT len,
unsigned int align, bool push,
- bool qi_vector_mode)
+ by_pieces_operation op)
: m_to (to, to_load, NULL, NULL),
m_from (from, from_load, from_cfn, from_cfn_data),
m_len (len), m_max_size (max_pieces + 1),
- m_push (push), m_qi_vector_mode (qi_vector_mode)
+ m_push (push), m_op (op)
{
int toi = m_to.get_addr_inc ();
int fromi = m_from.get_addr_inc ();
@@ -1375,8 +1406,7 @@ op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
{
/* Find the mode of the largest comparison. */
fixed_size_mode mode
- = widest_fixed_size_mode_for_size (m_max_size,
- m_qi_vector_mode);
+ = widest_fixed_size_mode_for_size (m_max_size, m_op);
m_from.decide_autoinc (mode, m_reverse, len);
m_to.decide_autoinc (mode, m_reverse, len);
@@ -1401,7 +1431,7 @@ op_by_pieces_d::get_usable_mode (fixed_size_mode mode, unsigned int len)
if (len >= size && prepare_mode (mode, m_align))
break;
/* widest_fixed_size_mode_for_size checks SIZE > 1. */
- mode = widest_fixed_size_mode_for_size (size, m_qi_vector_mode);
+ mode = widest_fixed_size_mode_for_size (size, m_op);
}
while (1);
return mode;
@@ -1414,7 +1444,7 @@ fixed_size_mode
op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
{
/* Use QI vector only for > size of WORD. */
- if (m_qi_vector_mode && size > UNITS_PER_WORD)
+ if (can_use_qi_vectors (m_op) && size > UNITS_PER_WORD)
{
machine_mode mode;
fixed_size_mode candidate;
@@ -1427,8 +1457,7 @@ op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
break;
if (GET_MODE_SIZE (candidate) >= size
- && (optab_handler (vec_duplicate_optab, candidate)
- != CODE_FOR_nothing))
+ && by_pieces_mode_supported_p (candidate, m_op))
return candidate;
}
}
@@ -1451,7 +1480,7 @@ op_by_pieces_d::run ()
/* widest_fixed_size_mode_for_size checks M_MAX_SIZE > 1. */
fixed_size_mode mode
- = widest_fixed_size_mode_for_size (m_max_size, m_qi_vector_mode);
+ = widest_fixed_size_mode_for_size (m_max_size, m_op);
mode = get_usable_mode (mode, length);
by_pieces_prev to_prev = { nullptr, mode };
@@ -1516,8 +1545,7 @@ op_by_pieces_d::run ()
else
{
/* widest_fixed_size_mode_for_size checks SIZE > 1. */
- mode = widest_fixed_size_mode_for_size (size,
- m_qi_vector_mode);
+ mode = widest_fixed_size_mode_for_size (size, m_op);
mode = get_usable_mode (mode, length);
}
}
@@ -1543,7 +1571,7 @@ class move_by_pieces_d : public op_by_pieces_d
move_by_pieces_d (rtx to, rtx from, unsigned HOST_WIDE_INT len,
unsigned int align)
: op_by_pieces_d (MOVE_MAX_PIECES, to, false, from, true, NULL,
- NULL, len, align, PUSHG_P (to))
+ NULL, len, align, PUSHG_P (to), MOVE_BY_PIECES)
{
}
rtx finish_retmode (memop_ret);
@@ -1632,15 +1660,16 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
class store_by_pieces_d : public op_by_pieces_d
{
insn_gen_fn m_gen_fun;
+
void generate (rtx, rtx, machine_mode) final override;
bool prepare_mode (machine_mode, unsigned int) final override;
public:
store_by_pieces_d (rtx to, by_pieces_constfn cfn, void *cfn_data,
unsigned HOST_WIDE_INT len, unsigned int align,
- bool qi_vector_mode)
+ by_pieces_operation op)
: op_by_pieces_d (STORE_MAX_PIECES, to, false, NULL_RTX, true, cfn,
- cfn_data, len, align, false, qi_vector_mode)
+ cfn_data, len, align, false, op)
{
}
rtx finish_retmode (memop_ret);
@@ -1729,8 +1758,8 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
max_size = STORE_MAX_PIECES + 1;
while (max_size > 1 && l > 0)
{
- fixed_size_mode mode
- = widest_fixed_size_mode_for_size (max_size, memsetp);
+ auto op = memsetp ? SET_BY_PIECES : STORE_BY_PIECES;
+ auto mode = widest_fixed_size_mode_for_size (max_size, op);
icode = optab_handler (mov_optab, mode);
if (icode != CODE_FOR_nothing
@@ -1793,7 +1822,7 @@ store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
optimize_insn_for_speed_p ()));
store_by_pieces_d data (to, constfun, constfundata, len, align,
- memsetp);
+ memsetp ? SET_BY_PIECES : STORE_BY_PIECES);
data.run ();
if (retmode != RETURN_BEGIN)
@@ -1814,7 +1843,7 @@ clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
/* Use builtin_memset_read_str to support vector mode broadcast. */
char c = 0;
store_by_pieces_d data (to, builtin_memset_read_str, &c, len, align,
- true);
+ CLEAR_BY_PIECES);
data.run ();
}
@@ -1832,12 +1861,13 @@ class compare_by_pieces_d : public op_by_pieces_d
void generate (rtx, rtx, machine_mode) final override;
bool prepare_mode (machine_mode, unsigned int) final override;
void finish_mode (machine_mode) final override;
+
public:
compare_by_pieces_d (rtx op0, rtx op1, by_pieces_constfn op1_cfn,
void *op1_cfn_data, HOST_WIDE_INT len, int align,
rtx_code_label *fail_label)
: op_by_pieces_d (COMPARE_MAX_PIECES, op0, true, op1, true, op1_cfn,
- op1_cfn_data, len, align, false)
+ op1_cfn_data, len, align, false, COMPARE_BY_PIECES)
{
m_fail_label = fail_label;
}
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 680d6e8..6eacbeb 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,67 @@
+2023-10-30 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/104555
+ * resolve.cc (resolve_select_type): If the selector expression
+ has no class component references and the expression is a
+ derived type, copy the typespec of the symbol to that of the
+ expression.
+
+2023-10-27 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/104649
+ * decl.cc (gfc_match_formal_arglist): Handle conflicting declarations
+ of a MODULE PROCEDURE when one of the declarations is an alternate
+ return.
+
+2023-10-27 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/104625
+ * expr.cc (gfc_check_vardef_context): Check that the target
+ does have a vector index before emitting the specific error.
+ * match.cc (copy_ts_from_selector_to_associate): Ensure that
+ class valued operator expressions set the selector rank and
+ use the rank to provide the associate variable with an
+ appropriate array spec.
+ * resolve.cc (resolve_operator): Reduce stacked parentheses to
+ a single pair.
+ (fixup_array_ref): Extract selector symbol from parentheses.
+
+2023-10-26 Paul-Antoine Arras <pa@codesourcery.com>
+ Tobias Burnus <tobias@codesourcery.com>
+
+ * interface.cc (gfc_compare_types): Return true if one type is C_PTR
+ and the other is a compatible INTEGER(8).
+ * misc.cc (gfc_typename): Handle the case where an INTEGER(8) actually
+ holds a TYPE(C_PTR).
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * openmp.cc (omp_mask2): Split 'OMP_CLAUSE_HOST_SELF' into
+ 'OMP_CLAUSE_SELF', 'OMP_CLAUSE_HOST'.
+ (gfc_match_omp_clauses, OACC_UPDATE_CLAUSES): Adjust.
+
+2023-10-25 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * gfortran.h (typedef struct gfc_omp_clauses): Add self_expr field.
+ * openmp.cc (enum omp_mask2): Add OMP_CLAUSE_SELF.
+ (gfc_match_omp_clauses): Add handling for OMP_CLAUSE_SELF.
+ (OACC_PARALLEL_CLAUSES): Add OMP_CLAUSE_SELF.
+ (OACC_KERNELS_CLAUSES): Likewise.
+ (OACC_SERIAL_CLAUSES): Likewise.
+ (resolve_omp_clauses): Add handling for omp_clauses->self_expr.
+ * trans-openmp.cc (gfc_trans_omp_clauses): Add handling of
+ clauses->self_expr and building of OMP_CLAUSE_SELF tree clause.
+ (gfc_split_omp_clauses): Add handling of self_expr field copy.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * dump-parse-tree.cc (show_omp_clauses): Group handling of 'if'
+ clause without and with modifier.
+ * frontend-passes.cc (gfc_code_walker): Likewise.
+ * gfortran.h (gfc_omp_clauses): Likewise.
+ * openmp.cc (gfc_free_omp_clauses): Likewise.
+
2023-10-18 Tobias Burnus <tobias@codesourcery.com>
* intrinsic.texi (signal): Add 'intrinsic :: signal, sleep' to
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index bdd3be3..4893c58 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -6796,12 +6796,25 @@ ok:
|| (p->next == NULL && q->next != NULL))
arg_count_mismatch = true;
else if ((p->sym == NULL && q->sym == NULL)
- || strcmp (p->sym->name, q->sym->name) == 0)
+ || (p->sym && q->sym
+ && strcmp (p->sym->name, q->sym->name) == 0))
continue;
else
- gfc_error_now ("Mismatch in MODULE PROCEDURE formal "
- "argument names (%s/%s) at %C",
- p->sym->name, q->sym->name);
+ {
+ if (q->sym == NULL)
+ gfc_error_now ("MODULE PROCEDURE formal argument %qs "
+ "conflicts with alternate return at %C",
+ p->sym->name);
+ else if (p->sym == NULL)
+ gfc_error_now ("MODULE PROCEDURE formal argument is "
+ "alternate return and conflicts with "
+ "%qs in the separate declaration at %C",
+ q->sym->name);
+ else
+ gfc_error_now ("Mismatch in MODULE PROCEDURE formal "
+ "argument names (%s/%s) at %C",
+ p->sym->name, q->sym->name);
+ }
}
if (arg_count_mismatch)
diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc
index 68122e3..cc4846e 100644
--- a/gcc/fortran/dump-parse-tree.cc
+++ b/gcc/fortran/dump-parse-tree.cc
@@ -1593,6 +1593,27 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
show_expr (omp_clauses->if_expr);
fputc (')', dumpfile);
}
+ for (i = 0; i < OMP_IF_LAST; i++)
+ if (omp_clauses->if_exprs[i])
+ {
+ static const char *ifs[] = {
+ "CANCEL",
+ "PARALLEL",
+ "SIMD",
+ "TASK",
+ "TASKLOOP",
+ "TARGET",
+ "TARGET DATA",
+ "TARGET UPDATE",
+ "TARGET ENTER DATA",
+ "TARGET EXIT DATA"
+ };
+ fputs (" IF(", dumpfile);
+ fputs (ifs[i], dumpfile);
+ fputs (": ", dumpfile);
+ show_expr (omp_clauses->if_exprs[i]);
+ fputc (')', dumpfile);
+ }
if (omp_clauses->final_expr)
{
fputs (" FINAL(", dumpfile);
@@ -1999,27 +2020,6 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
show_expr (omp_clauses->detach);
fputc (')', dumpfile);
}
- for (i = 0; i < OMP_IF_LAST; i++)
- if (omp_clauses->if_exprs[i])
- {
- static const char *ifs[] = {
- "CANCEL",
- "PARALLEL",
- "SIMD",
- "TASK",
- "TASKLOOP",
- "TARGET",
- "TARGET DATA",
- "TARGET UPDATE",
- "TARGET ENTER DATA",
- "TARGET EXIT DATA"
- };
- fputs (" IF(", dumpfile);
- fputs (ifs[i], dumpfile);
- fputs (": ", dumpfile);
- show_expr (omp_clauses->if_exprs[i]);
- fputc (')', dumpfile);
- }
if (omp_clauses->destroy)
fputs (" DESTROY", dumpfile);
if (omp_clauses->depend_source)
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index 663fe63..c668bae 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -6474,7 +6474,8 @@ gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj,
{
if (context)
{
- if (assoc->target->expr_type == EXPR_VARIABLE)
+ if (assoc->target->expr_type == EXPR_VARIABLE
+ && gfc_has_vector_index (assoc->target))
gfc_error ("%qs at %L associated to vector-indexed target"
" cannot be used in a variable definition"
" context (%s)",
diff --git a/gcc/fortran/frontend-passes.cc b/gcc/fortran/frontend-passes.cc
index 536884b..0378e0d 100644
--- a/gcc/fortran/frontend-passes.cc
+++ b/gcc/fortran/frontend-passes.cc
@@ -5652,6 +5652,8 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
size_t idx;
WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
+ for (idx = 0; idx < OMP_IF_LAST; idx++)
+ WALK_SUBEXPR (co->ext.omp_clauses->if_exprs[idx]);
WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
@@ -5667,8 +5669,6 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
WALK_SUBEXPR (co->ext.omp_clauses->num_tasks);
WALK_SUBEXPR (co->ext.omp_clauses->priority);
WALK_SUBEXPR (co->ext.omp_clauses->detach);
- for (idx = 0; idx < OMP_IF_LAST; idx++)
- WALK_SUBEXPR (co->ext.omp_clauses->if_exprs[idx]);
for (idx = 0; idx < ARRAY_SIZE (list_types); idx++)
for (n = co->ext.omp_clauses->lists[list_types[idx]];
n; n = n->next)
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 88f33b0..ceb2873 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1545,6 +1545,8 @@ typedef struct gfc_omp_clauses
{
gfc_omp_namelist *lists[OMP_LIST_NUM];
struct gfc_expr *if_expr;
+ struct gfc_expr *if_exprs[OMP_IF_LAST];
+ struct gfc_expr *self_expr;
struct gfc_expr *final_expr;
struct gfc_expr *num_threads;
struct gfc_expr *chunk_size;
@@ -1561,7 +1563,6 @@ typedef struct gfc_omp_clauses
struct gfc_expr *priority;
struct gfc_expr *detach;
struct gfc_expr *depobj;
- struct gfc_expr *if_exprs[OMP_IF_LAST];
struct gfc_expr *dist_chunk_size;
struct gfc_expr *message;
struct gfc_omp_assumptions *assume;
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index c01df04..8c4571e 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -736,10 +736,18 @@ gfc_compare_types (gfc_typespec *ts1, gfc_typespec *ts2)
better way of doing this. When ISO C binding is cleared up,
this can probably be removed. See PR 57048. */
- if (((ts1->type == BT_INTEGER && ts2->type == BT_DERIVED)
- || (ts1->type == BT_DERIVED && ts2->type == BT_INTEGER))
- && ts1->u.derived && ts2->u.derived
- && ts1->u.derived == ts2->u.derived)
+ if ((ts1->type == BT_INTEGER
+ && ts2->type == BT_DERIVED
+ && ts1->f90_type == BT_VOID
+ && ts2->u.derived->from_intmod == INTMOD_ISO_C_BINDING
+ && ts1->u.derived
+ && strcmp (ts1->u.derived->name, ts2->u.derived->name) == 0)
+ || (ts2->type == BT_INTEGER
+ && ts1->type == BT_DERIVED
+ && ts2->f90_type == BT_VOID
+ && ts1->u.derived->from_intmod == INTMOD_ISO_C_BINDING
+ && ts2->u.derived
+ && strcmp (ts1->u.derived->name, ts2->u.derived->name) == 0))
return true;
/* The _data component is not always present, therefore check for its
diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 148a86b..f848e52 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -6348,12 +6348,13 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
else if (selector->ts.type == BT_CLASS
&& CLASS_DATA (selector)
&& CLASS_DATA (selector)->as
- && ref && ref->type == REF_ARRAY)
+ && ((ref && ref->type == REF_ARRAY)
+ || selector->expr_type == EXPR_OP))
{
/* Ensure that the array reference type is set. We cannot use
gfc_resolve_expr at this point, so the usable parts of
resolve.cc(resolve_array_ref) are employed to do it. */
- if (ref->u.ar.type == AR_UNKNOWN)
+ if (ref && ref->u.ar.type == AR_UNKNOWN)
{
ref->u.ar.type = AR_ELEMENT;
for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
@@ -6367,7 +6368,7 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
}
}
- if (ref->u.ar.type == AR_FULL)
+ if (!ref || ref->u.ar.type == AR_FULL)
selector->rank = CLASS_DATA (selector)->as->rank;
else if (ref->u.ar.type == AR_SECTION)
selector->rank = ref->u.ar.dimen;
@@ -6379,12 +6380,15 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
if (rank)
{
- for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
- if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT
- || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
- && ref->u.ar.end[i] == NULL
- && ref->u.ar.stride[i] == NULL))
- rank--;
+ if (ref)
+ {
+ for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
+ if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT
+ || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
+ && ref->u.ar.end[i] == NULL
+ && ref->u.ar.stride[i] == NULL))
+ rank--;
+ }
if (rank)
{
diff --git a/gcc/fortran/misc.cc b/gcc/fortran/misc.cc
index bae6d29..edffba0 100644
--- a/gcc/fortran/misc.cc
+++ b/gcc/fortran/misc.cc
@@ -138,7 +138,12 @@ gfc_typename (gfc_typespec *ts, bool for_hash)
switch (ts->type)
{
case BT_INTEGER:
- sprintf (buffer, "INTEGER(%d)", ts->kind);
+ if (ts->f90_type == BT_VOID
+ && ts->u.derived
+ && ts->u.derived->from_intmod == INTMOD_ISO_C_BINDING)
+ sprintf (buffer, "TYPE(%s)", ts->u.derived->name);
+ else
+ sprintf (buffer, "INTEGER(%d)", ts->kind);
break;
case BT_REAL:
sprintf (buffer, "REAL(%d)", ts->kind);
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 1cc65d7..2e2e23d 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -161,6 +161,8 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
return;
gfc_free_expr (c->if_expr);
+ for (i = 0; i < OMP_IF_LAST; i++)
+ gfc_free_expr (c->if_exprs[i]);
gfc_free_expr (c->final_expr);
gfc_free_expr (c->num_threads);
gfc_free_expr (c->chunk_size);
@@ -176,8 +178,6 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
gfc_free_expr (c->num_tasks);
gfc_free_expr (c->priority);
gfc_free_expr (c->detach);
- for (i = 0; i < OMP_IF_LAST; i++)
- gfc_free_expr (c->if_exprs[i]);
gfc_free_expr (c->async_expr);
gfc_free_expr (c->gang_num_expr);
gfc_free_expr (c->gang_static_expr);
@@ -1080,7 +1080,8 @@ enum omp_mask2
OMP_CLAUSE_INDEPENDENT,
OMP_CLAUSE_USE_DEVICE,
OMP_CLAUSE_DEVICE_RESIDENT,
- OMP_CLAUSE_HOST_SELF,
+ OMP_CLAUSE_SELF,
+ OMP_CLAUSE_HOST,
OMP_CLAUSE_WAIT,
OMP_CLAUSE_DELETE,
OMP_CLAUSE_AUTO,
@@ -1876,8 +1877,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
that should work. */
bool allow_derived = (openacc
&& ((mask & OMP_CLAUSE_ATTACH)
- || (mask & OMP_CLAUSE_DETACH)
- || (mask & OMP_CLAUSE_HOST_SELF)));
+ || (mask & OMP_CLAUSE_DETACH)));
gcc_checking_assert (OMP_MASK1_LAST <= 64 && OMP_MASK2_LAST <= 64);
*cp = NULL;
@@ -2549,7 +2549,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
&& gfc_match ("device ( ") == MATCH_YES
&& gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
OMP_MAP_FORCE_TO, true,
- allow_derived))
+ /* allow_derived = */ true))
continue;
if ((mask & OMP_CLAUSE_DEVICEPTR)
&& gfc_match ("deviceptr ( ") == MATCH_YES
@@ -2724,11 +2724,11 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
c->assume->holds = el;
continue;
}
- if ((mask & OMP_CLAUSE_HOST_SELF)
+ if ((mask & OMP_CLAUSE_HOST)
&& gfc_match ("host ( ") == MATCH_YES
&& gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
OMP_MAP_FORCE_FROM, true,
- allow_derived))
+ /* allow_derived = */ true))
continue;
break;
case 'i':
@@ -3519,11 +3519,33 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
else
gfc_current_locus = old_loc;
}
- if ((mask & OMP_CLAUSE_HOST_SELF)
+ if ((mask & OMP_CLAUSE_SELF)
+ && !(mask & OMP_CLAUSE_HOST) /* OpenACC compute construct */
+ && (m = gfc_match_dupl_check (!c->self_expr, "self"))
+ != MATCH_NO)
+ {
+ if (m == MATCH_ERROR)
+ goto error;
+ m = gfc_match (" ( %e )", &c->self_expr);
+ if (m == MATCH_ERROR)
+ {
+ gfc_current_locus = old_loc;
+ break;
+ }
+ else if (m == MATCH_NO)
+ {
+ c->self_expr = gfc_get_logical_expr (gfc_default_logical_kind,
+ NULL, true);
+ needs_space = true;
+ }
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_SELF)
+ && (mask & OMP_CLAUSE_HOST) /* OpenACC 'update' directive */
&& gfc_match ("self ( ") == MATCH_YES
&& gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
OMP_MAP_FORCE_FROM, true,
- allow_derived))
+ /* allow_derived = */ true))
continue;
if ((mask & OMP_CLAUSE_SEQ)
&& (m = gfc_match_dupl_check (!c->seq, "seq")) != MATCH_NO)
@@ -3791,19 +3813,22 @@ error:
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
| OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
- | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
+ | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH \
+ | OMP_CLAUSE_SELF)
#define OACC_KERNELS_CLAUSES \
(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
| OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
| OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
- | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
+ | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH \
+ | OMP_CLAUSE_SELF)
#define OACC_SERIAL_CLAUSES \
(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION \
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
| OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
- | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
+ | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH \
+ | OMP_CLAUSE_SELF)
#define OACC_DATA_CLAUSES \
(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
@@ -3829,9 +3854,10 @@ error:
| OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
| OMP_CLAUSE_PRESENT \
| OMP_CLAUSE_LINK)
-#define OACC_UPDATE_CLAUSES \
- (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
- | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
+#define OACC_UPDATE_CLAUSES \
+ (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST \
+ | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT \
+ | OMP_CLAUSE_SELF)
#define OACC_ENTER_DATA_CLAUSES \
(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
@@ -7540,6 +7566,15 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
}
}
+ if (omp_clauses->self_expr)
+ {
+ gfc_expr *expr = omp_clauses->self_expr;
+ if (!gfc_resolve_expr (expr)
+ || expr->ts.type != BT_LOGICAL || expr->rank != 0)
+ gfc_error ("SELF clause at %L requires a scalar LOGICAL expression",
+ &expr->where);
+ }
+
if (omp_clauses->final_expr)
{
gfc_expr *expr = omp_clauses->final_expr;
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 861f69a..81a1465 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -4138,6 +4138,16 @@ resolve_operator (gfc_expr *e)
bool dual_locus_error;
bool t = true;
+ /* Reduce stacked parentheses to single pair */
+ while (e->expr_type == EXPR_OP
+ && e->value.op.op == INTRINSIC_PARENTHESES
+ && e->value.op.op1->expr_type == EXPR_OP
+ && e->value.op.op1->value.op.op == INTRINSIC_PARENTHESES)
+ {
+ gfc_expr *tmp = gfc_copy_expr (e->value.op.op1);
+ gfc_replace_expr (e, tmp);
+ }
+
/* Resolve all subnodes-- give them types. */
switch (e->value.op.op)
@@ -9451,8 +9461,25 @@ fixup_array_ref (gfc_expr **expr1, gfc_expr *expr2,
{
gfc_ref *nref = (*expr1)->ref;
gfc_symbol *sym1 = (*expr1)->symtree->n.sym;
- gfc_symbol *sym2 = expr2 ? expr2->symtree->n.sym : NULL;
+ gfc_symbol *sym2;
+ gfc_expr *selector = gfc_copy_expr (expr2);
+
(*expr1)->rank = rank;
+ if (selector)
+ {
+ gfc_resolve_expr (selector);
+ if (selector->expr_type == EXPR_OP
+ && selector->value.op.op == INTRINSIC_PARENTHESES)
+ sym2 = selector->value.op.op1->symtree->n.sym;
+ else if (selector->expr_type == EXPR_VARIABLE
+ || selector->expr_type == EXPR_FUNCTION)
+ sym2 = selector->symtree->n.sym;
+ else
+ gcc_unreachable ();
+ }
+ else
+ sym2 = NULL;
+
if (sym1->ts.type == BT_CLASS)
{
if ((*expr1)->ts.type != BT_CLASS)
@@ -9551,6 +9578,12 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
{
if (code->expr1->symtree->n.sym->attr.untyped)
code->expr1->symtree->n.sym->ts = code->expr2->ts;
+ /* Sometimes the selector expression is given the typespec of the
+ '_data' field, which is logical enough but inappropriate here. */
+ if (code->expr2->ts.type == BT_DERIVED
+ && code->expr2->symtree
+ && code->expr2->symtree->n.sym->ts.type == BT_CLASS)
+ code->expr2->ts = code->expr2->symtree->n.sym->ts;
selector_type = CLASS_DATA (code->expr2)
? CLASS_DATA (code->expr2)->ts.u.derived : code->expr2->ts.u.derived;
}
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 7930f2f..82bbc41 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -3966,6 +3966,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
OMP_CLAUSE_IF_EXPR (c) = if_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
+
for (ifc = 0; ifc < OMP_IF_LAST; ifc++)
if (clauses->if_exprs[ifc])
{
@@ -4017,6 +4018,21 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
+ if (clauses->self_expr)
+ {
+ tree self_var;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, clauses->self_expr);
+ gfc_add_block_to_block (block, &se.pre);
+ self_var = gfc_evaluate_now (se.expr, block);
+ gfc_add_block_to_block (block, &se.post);
+
+ c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SELF);
+ OMP_CLAUSE_SELF_EXPR (c) = self_var;
+ omp_clauses = gfc_trans_add_clause (c, omp_clauses);
+ }
+
if (clauses->final_expr)
{
tree final_var;
@@ -6615,6 +6631,8 @@ gfc_split_omp_clauses (gfc_code *code,
/* And this is copied to all. */
clausesa[GFC_OMP_SPLIT_TARGET].if_expr
= code->ext.omp_clauses->if_expr;
+ clausesa[GFC_OMP_SPLIT_TARGET].self_expr
+ = code->ext.omp_clauses->self_expr;
clausesa[GFC_OMP_SPLIT_TARGET].nowait
= code->ext.omp_clauses->nowait;
}
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index bfe4439..e6f33e3 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -101,7 +101,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
Records are not nested, but there is a record hierarchy. Tag
numbers reflect this hierarchy. Tags are unique across note and
data files. Some record types have a varying amount of data. The
- LENGTH is the number of 4bytes that follow and is usually used to
+ LENGTH is the number of bytes that follow and is usually used to
determine how much data. The tag value is split into 4 8-bit
fields, one for each of four possible levels. The most significant
is allocated first. Unused levels are zero. Active levels are
diff --git a/gcc/genautomata.cc b/gcc/genautomata.cc
index 72f0168..9dda25e 100644
--- a/gcc/genautomata.cc
+++ b/gcc/genautomata.cc
@@ -9503,9 +9503,9 @@ write_automata (void)
fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
output_get_cpu_unit_code_func ();
output_cpu_unit_reservation_p ();
- output_insn_has_dfa_reservation_p ();
fprintf (output_file, "\n#endif /* #if %s */\n\n",
CPU_UNITS_QUERY_MACRO_NAME);
+ output_insn_has_dfa_reservation_p ();
output_dfa_clean_insn_cache_func ();
output_dfa_start_func ();
output_dfa_finish_func ();
diff --git a/gcc/genemit.cc b/gcc/genemit.cc
index 1ce0564..471fd46 100644
--- a/gcc/genemit.cc
+++ b/gcc/genemit.cc
@@ -49,29 +49,29 @@ struct clobber_ent
struct clobber_ent *next;
};
-static void output_peephole2_scratches (rtx);
+static void output_peephole2_scratches (rtx, FILE*);
/* True for <X>_optab if that optab isn't allowed to fail. */
static bool nofail_optabs[NUM_OPTABS];
static void
-print_code (RTX_CODE code)
+print_code (RTX_CODE code, FILE *file)
{
const char *p1;
for (p1 = GET_RTX_NAME (code); *p1; p1++)
- putchar (TOUPPER (*p1));
+ fprintf (file, "%c", TOUPPER (*p1));
}
static void
-gen_rtx_scratch (rtx x, enum rtx_code subroutine_type)
+gen_rtx_scratch (rtx x, enum rtx_code subroutine_type, FILE *file)
{
if (subroutine_type == DEFINE_PEEPHOLE2)
{
- printf ("operand%d", XINT (x, 0));
+ fprintf (file, "operand%d", XINT (x, 0));
}
else
{
- printf ("gen_rtx_SCRATCH (%smode)", GET_MODE_NAME (GET_MODE (x)));
+ fprintf (file, "gen_rtx_SCRATCH (%smode)", GET_MODE_NAME (GET_MODE (x)));
}
}
@@ -79,7 +79,8 @@ gen_rtx_scratch (rtx x, enum rtx_code subroutine_type)
substituting any operand references appearing within. */
static void
-gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
+gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info,
+ FILE *file)
{
RTX_CODE code;
int i;
@@ -89,7 +90,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
if (x == 0)
{
- printf ("NULL_RTX");
+ fprintf (file, "NULL_RTX");
return;
}
@@ -103,67 +104,67 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
{
if (used[XINT (x, 0)])
{
- printf ("copy_rtx (operand%d)", XINT (x, 0));
+ fprintf (file, "copy_rtx (operand%d)", XINT (x, 0));
return;
}
used[XINT (x, 0)] = 1;
}
- printf ("operand%d", XINT (x, 0));
+ fprintf (file, "operand%d", XINT (x, 0));
return;
case MATCH_OP_DUP:
- printf ("gen_rtx_fmt_");
+ fprintf (file, "gen_rtx_fmt_");
for (i = 0; i < XVECLEN (x, 1); i++)
- printf ("e");
- printf (" (GET_CODE (operand%d), ", XINT (x, 0));
+ fprintf (file, "e");
+ fprintf (file, " (GET_CODE (operand%d), ", XINT (x, 0));
if (GET_MODE (x) == VOIDmode)
- printf ("GET_MODE (operand%d)", XINT (x, 0));
+ fprintf (file, "GET_MODE (operand%d)", XINT (x, 0));
else
- printf ("%smode", GET_MODE_NAME (GET_MODE (x)));
+ fprintf (file, "%smode", GET_MODE_NAME (GET_MODE (x)));
for (i = 0; i < XVECLEN (x, 1); i++)
{
- printf (",\n\t\t");
- gen_exp (XVECEXP (x, 1, i), subroutine_type, used, info);
+ fprintf (file, ",\n\t\t");
+ gen_exp (XVECEXP (x, 1, i), subroutine_type, used, info, file);
}
- printf (")");
+ fprintf (file, ")");
return;
case MATCH_OPERATOR:
- printf ("gen_rtx_fmt_");
+ fprintf (file, "gen_rtx_fmt_");
for (i = 0; i < XVECLEN (x, 2); i++)
- printf ("e");
- printf (" (GET_CODE (operand%d)", XINT (x, 0));
- printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
+ fprintf (file, "e");
+ fprintf (file, " (GET_CODE (operand%d)", XINT (x, 0));
+ fprintf (file, ", %smode", GET_MODE_NAME (GET_MODE (x)));
for (i = 0; i < XVECLEN (x, 2); i++)
{
- printf (",\n\t\t");
- gen_exp (XVECEXP (x, 2, i), subroutine_type, used, info);
+ fprintf (file, ",\n\t\t");
+ gen_exp (XVECEXP (x, 2, i), subroutine_type, used, info, file);
}
- printf (")");
+ fprintf (file, ")");
return;
case MATCH_PARALLEL:
case MATCH_PAR_DUP:
- printf ("operand%d", XINT (x, 0));
+ fprintf (file, "operand%d", XINT (x, 0));
return;
case MATCH_SCRATCH:
- gen_rtx_scratch (x, subroutine_type);
+ gen_rtx_scratch (x, subroutine_type, file);
return;
case PC:
- printf ("pc_rtx");
+ fprintf (file, "pc_rtx");
return;
case RETURN:
- printf ("ret_rtx");
+ fprintf (file, "ret_rtx");
return;
case SIMPLE_RETURN:
- printf ("simple_return_rtx");
+ fprintf (file, "simple_return_rtx");
return;
case CLOBBER:
if (REG_P (XEXP (x, 0)))
{
- printf ("gen_hard_reg_clobber (%smode, %i)",
+ fprintf (file, "gen_hard_reg_clobber (%smode, %i)",
GET_MODE_NAME (GET_MODE (XEXP (x, 0))),
REGNO (XEXP (x, 0)));
return;
@@ -172,22 +173,22 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
case CONST_INT:
if (INTVAL (x) == 0)
- printf ("const0_rtx");
+ fprintf (file, "const0_rtx");
else if (INTVAL (x) == 1)
- printf ("const1_rtx");
+ fprintf (file, "const1_rtx");
else if (INTVAL (x) == -1)
- printf ("constm1_rtx");
+ fprintf (file, "constm1_rtx");
else if (-MAX_SAVED_CONST_INT <= INTVAL (x)
&& INTVAL (x) <= MAX_SAVED_CONST_INT)
- printf ("const_int_rtx[MAX_SAVED_CONST_INT + (%d)]",
+ fprintf (file, "const_int_rtx[MAX_SAVED_CONST_INT + (%d)]",
(int) INTVAL (x));
else if (INTVAL (x) == STORE_FLAG_VALUE)
- printf ("const_true_rtx");
+ fprintf (file, "const_true_rtx");
else
{
- printf ("GEN_INT (");
- printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
- printf (")");
+ fprintf (file, "GEN_INT (");
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
+ fprintf (file, ")");
}
return;
@@ -195,7 +196,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
/* Handle `const_double_zero' rtx. */
if (CONST_DOUBLE_REAL_VALUE (x)->cl == rvc_zero)
{
- printf ("CONST_DOUBLE_ATOF (\"0\", %smode)",
+ fprintf (file, "CONST_DOUBLE_ATOF (\"0\", %smode)",
GET_MODE_NAME (GET_MODE (x)));
return;
}
@@ -210,12 +211,12 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
break;
}
- printf ("gen_rtx_");
- print_code (code);
- printf (" (");
+ fprintf (file, "gen_rtx_");
+ print_code (code, file);
+ fprintf (file, " (");
if (!always_void_p (code))
{
- printf ("%smode", GET_MODE_NAME (GET_MODE (x)));
+ fprintf (file, "%smode", GET_MODE_NAME (GET_MODE (x)));
sep = ",\n\t";
}
@@ -225,41 +226,41 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
{
if (fmt[i] == '0')
break;
- fputs (sep, stdout);
+ fputs (sep, file);
switch (fmt[i])
{
case 'e': case 'u':
- gen_exp (XEXP (x, i), subroutine_type, used, info);
+ gen_exp (XEXP (x, i), subroutine_type, used, info, file);
break;
case 'i':
- printf ("%u", XINT (x, i));
+ fprintf (file, "%u", XINT (x, i));
break;
case 'r':
- printf ("%u", REGNO (x));
+ fprintf (file, "%u", REGNO (x));
break;
case 'p':
/* We don't have a way of parsing polynomial offsets yet,
and hopefully never will. */
- printf ("%d", SUBREG_BYTE (x).to_constant ());
+ fprintf (file, "%d", SUBREG_BYTE (x).to_constant ());
break;
case 's':
- printf ("\"%s\"", XSTR (x, i));
+ fprintf (file, "\"%s\"", XSTR (x, i));
break;
case 'E':
{
int j;
- printf ("gen_rtvec (%d", XVECLEN (x, i));
+ fprintf (file, "gen_rtvec (%d", XVECLEN (x, i));
for (j = 0; j < XVECLEN (x, i); j++)
{
- printf (",\n\t\t");
- gen_exp (XVECEXP (x, i, j), subroutine_type, used, info);
+ fprintf (file, ",\n\t\t");
+ gen_exp (XVECEXP (x, i, j), subroutine_type, used, info, file);
}
- printf (")");
+ fprintf (file, ")");
break;
}
@@ -268,14 +269,14 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
}
sep = ",\n\t";
}
- printf (")");
+ fprintf (file, ")");
}
/* Output code to emit the instruction patterns in VEC, with each element
becoming a separate instruction. USED is as for gen_exp. */
static void
-gen_emit_seq (rtvec vec, char *used, md_rtx_info *info)
+gen_emit_seq (rtvec vec, char *used, md_rtx_info *info, FILE *file)
{
for (int i = 0, len = GET_NUM_ELEM (vec); i < len; ++i)
{
@@ -283,17 +284,17 @@ gen_emit_seq (rtvec vec, char *used, md_rtx_info *info)
rtx next = RTVEC_ELT (vec, i);
if (const char *name = get_emit_function (next))
{
- printf (" %s (", name);
- gen_exp (next, DEFINE_EXPAND, used, info);
- printf (");\n");
+ fprintf (file, " %s (", name);
+ gen_exp (next, DEFINE_EXPAND, used, info, file);
+ fprintf (file, ");\n");
if (!last_p && needs_barrier_p (next))
- printf (" emit_barrier ();");
+ fprintf (file, " emit_barrier ();");
}
else
{
- printf (" emit (");
- gen_exp (next, DEFINE_EXPAND, used, info);
- printf (", %s);\n", last_p ? "false" : "true");
+ fprintf (file, " emit (");
+ gen_exp (next, DEFINE_EXPAND, used, info, file);
+ fprintf (file, ", %s);\n", last_p ? "false" : "true");
}
}
}
@@ -303,27 +304,27 @@ gen_emit_seq (rtvec vec, char *used, md_rtx_info *info)
for use in error messages. */
static void
-emit_c_code (const char *code, bool can_fail_p, const char *name)
+emit_c_code (const char *code, bool can_fail_p, const char *name, FILE *file)
{
if (can_fail_p)
- printf ("#define FAIL return (end_sequence (), _val)\n");
+ fprintf (file, "#define FAIL return (end_sequence (), _val)\n");
else
- printf ("#define FAIL _Pragma (\"GCC error \\\"%s cannot FAIL\\\"\")"
+ fprintf (file, "#define FAIL _Pragma (\"GCC error \\\"%s cannot FAIL\\\"\")"
" (void)0\n", name);
- printf ("#define DONE return (_val = get_insns (), "
+ fprintf (file, "#define DONE return (_val = get_insns (), "
"end_sequence (), _val)\n");
- rtx_reader_ptr->print_md_ptr_loc (code);
- printf ("%s\n", code);
+ rtx_reader_ptr->print_md_ptr_loc (code, file);
+ fprintf (file, "%s\n", code);
- printf ("#undef DONE\n");
- printf ("#undef FAIL\n");
+ fprintf (file, "#undef DONE\n");
+ fprintf (file, "#undef FAIL\n");
}
/* Generate the `gen_...' function for a DEFINE_INSN. */
static void
-gen_insn (md_rtx_info *info)
+gen_insn (md_rtx_info *info, FILE *file)
{
struct pattern_stats stats;
int i;
@@ -409,7 +410,7 @@ gen_insn (md_rtx_info *info)
if (XSTR (insn, 0)[0] == 0 || XSTR (insn, 0)[0] == '*')
return;
- printf ("/* %s:%d */\n", info->loc.filename, info->loc.lineno);
+ fprintf (file, "/* %s:%d */\n", info->loc.filename, info->loc.lineno);
/* Find out how many operands this function has. */
get_pattern_stats (&stats, XVEC (insn, 1));
@@ -417,17 +418,17 @@ gen_insn (md_rtx_info *info)
fatal_at (info->loc, "match_dup operand number has no match_operand");
/* Output the function name and argument declarations. */
- printf ("rtx\ngen_%s (", XSTR (insn, 0));
+ fprintf (file, "rtx\ngen_%s (", XSTR (insn, 0));
if (stats.num_generator_args)
for (i = 0; i < stats.num_generator_args; i++)
if (i)
- printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
+ fprintf (file, ",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
else
- printf ("rtx operand%d ATTRIBUTE_UNUSED", i);
+ fprintf (file, "rtx operand%d ATTRIBUTE_UNUSED", i);
else
- printf ("void");
- printf (")\n");
- printf ("{\n");
+ fprintf (file, "void");
+ fprintf (file, ")\n");
+ fprintf (file, "{\n");
/* Output code to construct and return the rtl for the instruction body. */
@@ -436,16 +437,16 @@ gen_insn (md_rtx_info *info)
char *used = (XVECLEN (insn, 1) == 1
? NULL
: XCNEWVEC (char, stats.num_generator_args));
- printf (" return ");
- gen_exp (pattern, DEFINE_INSN, used, info);
- printf (";\n}\n\n");
+ fprintf (file, " return ");
+ gen_exp (pattern, DEFINE_INSN, used, info, file);
+ fprintf (file, ";\n}\n\n");
XDELETEVEC (used);
}
/* Generate the `gen_...' function for a DEFINE_EXPAND. */
static void
-gen_expand (md_rtx_info *info)
+gen_expand (md_rtx_info *info, FILE *file)
{
struct pattern_stats stats;
int i;
@@ -466,17 +467,17 @@ gen_expand (md_rtx_info *info)
"numbers above all other operands", XSTR (expand, 0));
/* Output the function name and argument declarations. */
- printf ("rtx\ngen_%s (", XSTR (expand, 0));
+ fprintf (file, "rtx\ngen_%s (", XSTR (expand, 0));
if (stats.num_generator_args)
for (i = 0; i < stats.num_generator_args; i++)
if (i)
- printf (",\n\trtx operand%d", i);
+ fprintf (file, ",\n\trtx operand%d", i);
else
- printf ("rtx operand%d", i);
+ fprintf (file, "rtx operand%d", i);
else
- printf ("void");
- printf (")\n");
- printf ("{\n");
+ fprintf (file, "void");
+ fprintf (file, ")\n");
+ fprintf (file, "{\n");
/* If we don't have any C code to write, only one insn is being written,
and no MATCH_DUPs are present, we can just return the desired insn
@@ -485,18 +486,18 @@ gen_expand (md_rtx_info *info)
&& stats.max_opno >= stats.max_dup_opno
&& XVECLEN (expand, 1) == 1)
{
- printf (" return ");
- gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL, info);
- printf (";\n}\n\n");
+ fprintf (file, " return ");
+ gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL, info, file);
+ fprintf (file, ";\n}\n\n");
return;
}
/* For each operand referred to only with MATCH_DUPs,
make a local variable. */
for (i = stats.num_generator_args; i <= stats.max_dup_opno; i++)
- printf (" rtx operand%d;\n", i);
- printf (" rtx_insn *_val = 0;\n");
- printf (" start_sequence ();\n");
+ fprintf (file, " rtx operand%d;\n", i);
+ fprintf (file, " rtx_insn *_val = 0;\n");
+ fprintf (file, " start_sequence ();\n");
/* The fourth operand of DEFINE_EXPAND is some code to be executed
before the actual construction.
@@ -506,13 +507,13 @@ gen_expand (md_rtx_info *info)
So copy the operand values there before executing it. */
if (XSTR (expand, 3) && *XSTR (expand, 3))
{
- printf (" {\n");
+ fprintf (file, " {\n");
if (stats.num_operand_vars > 0)
- printf (" rtx operands[%d];\n", stats.num_operand_vars);
+ fprintf (file, " rtx operands[%d];\n", stats.num_operand_vars);
/* Output code to copy the arguments into `operands'. */
for (i = 0; i < stats.num_generator_args; i++)
- printf (" operands[%d] = operand%d;\n", i, i);
+ fprintf (file, " operands[%d] = operand%d;\n", i, i);
/* Output the special code to be executed before the sequence
is generated. */
@@ -524,7 +525,7 @@ gen_expand (md_rtx_info *info)
if (nofail_optabs[p.op])
can_fail_p = false;
}
- emit_c_code (XSTR (expand, 3), can_fail_p, XSTR (expand, 0));
+ emit_c_code (XSTR (expand, 3), can_fail_p, XSTR (expand, 0), file);
/* Output code to copy the arguments back out of `operands'
(unless we aren't going to use them at all). */
@@ -532,29 +533,29 @@ gen_expand (md_rtx_info *info)
{
for (i = 0; i <= MAX (stats.max_opno, stats.max_dup_opno); i++)
{
- printf (" operand%d = operands[%d];\n", i, i);
- printf (" (void) operand%d;\n", i);
+ fprintf (file, " operand%d = operands[%d];\n", i, i);
+ fprintf (file, " (void) operand%d;\n", i);
}
}
- printf (" }\n");
+ fprintf (file, " }\n");
}
used = XCNEWVEC (char, stats.num_operand_vars);
- gen_emit_seq (XVEC (expand, 1), used, info);
+ gen_emit_seq (XVEC (expand, 1), used, info, file);
XDELETEVEC (used);
/* Call `get_insns' to extract the list of all the
insns emitted within this gen_... function. */
- printf (" _val = get_insns ();\n");
- printf (" end_sequence ();\n");
- printf (" return _val;\n}\n\n");
+ fprintf (file, " _val = get_insns ();\n");
+ fprintf (file, " end_sequence ();\n");
+ fprintf (file, " return _val;\n}\n\n");
}
/* Like gen_expand, but generates insns resulting from splitting SPLIT. */
static void
-gen_split (md_rtx_info *info)
+gen_split (md_rtx_info *info, FILE *file)
{
struct pattern_stats stats;
int i;
@@ -580,62 +581,62 @@ gen_split (md_rtx_info *info)
/* Output the prototype, function name and argument declarations. */
if (GET_CODE (split) == DEFINE_PEEPHOLE2)
{
- printf ("extern rtx_insn *gen_%s_%d (rtx_insn *, rtx *);\n",
+ fprintf (file, "extern rtx_insn *gen_%s_%d (rtx_insn *, rtx *);\n",
name, info->index);
- printf ("rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED,"
+ fprintf (file, "rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED,"
" rtx *operands%s)\n",
name, info->index, unused);
}
else
{
- printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
+ fprintf (file, "extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
info->index);
- printf ("rtx_insn *\ngen_split_%d "
+ fprintf (file, "rtx_insn *\ngen_split_%d "
"(rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
info->index, unused);
}
- printf ("{\n");
+ fprintf (file, "{\n");
/* Declare all local variables. */
for (i = 0; i < stats.num_operand_vars; i++)
- printf (" rtx operand%d;\n", i);
- printf (" rtx_insn *_val = NULL;\n");
+ fprintf (file, " rtx operand%d;\n", i);
+ fprintf (file, " rtx_insn *_val = NULL;\n");
if (GET_CODE (split) == DEFINE_PEEPHOLE2)
- output_peephole2_scratches (split);
+ output_peephole2_scratches (split, file);
const char *fn = info->loc.filename;
for (const char *p = fn; *p; p++)
if (*p == '/')
fn = p + 1;
- printf (" if (dump_file)\n");
- printf (" fprintf (dump_file, \"Splitting with gen_%s_%d (%s:%d)\\n\");\n",
+ fprintf (file, " if (dump_file)\n");
+ fprintf (file, " fprintf (dump_file, \"Splitting with gen_%s_%d (%s:%d)\\n\");\n",
name, info->index, fn, info->loc.lineno);
- printf (" start_sequence ();\n");
+ fprintf (file, " start_sequence ();\n");
/* The fourth operand of DEFINE_SPLIT is some code to be executed
before the actual construction. */
if (XSTR (split, 3))
- emit_c_code (XSTR (split, 3), true, name);
+ emit_c_code (XSTR (split, 3), true, name, file);
/* Output code to copy the arguments back out of `operands' */
for (i = 0; i < stats.num_operand_vars; i++)
{
- printf (" operand%d = operands[%d];\n", i, i);
- printf (" (void) operand%d;\n", i);
+ fprintf (file, " operand%d = operands[%d];\n", i, i);
+ fprintf (file, " (void) operand%d;\n", i);
}
- gen_emit_seq (XVEC (split, 2), used, info);
+ gen_emit_seq (XVEC (split, 2), used, info, file);
/* Call `get_insns' to make a list of all the
insns emitted within this gen_... function. */
- printf (" _val = get_insns ();\n");
- printf (" end_sequence ();\n");
- printf (" return _val;\n}\n\n");
+ fprintf (file, " _val = get_insns ();\n");
+ fprintf (file, " end_sequence ();\n");
+ fprintf (file, " return _val;\n}\n\n");
free (used);
}
@@ -645,37 +646,37 @@ gen_split (md_rtx_info *info)
the end of the vector. */
static void
-output_add_clobbers (md_rtx_info *info)
+output_add_clobbers (md_rtx_info *info, FILE *file)
{
struct clobber_pat *clobber;
struct clobber_ent *ent;
int i;
- printf ("\n\nvoid\nadd_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number)\n");
- printf ("{\n");
- printf (" switch (insn_code_number)\n");
- printf (" {\n");
+ fprintf (file, "\n\nvoid\nadd_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number)\n");
+ fprintf (file, "{\n");
+ fprintf (file, " switch (insn_code_number)\n");
+ fprintf (file, " {\n");
for (clobber = clobber_list; clobber; clobber = clobber->next)
{
for (ent = clobber->insns; ent; ent = ent->next)
- printf (" case %d:\n", ent->code_number);
+ fprintf (file, " case %d:\n", ent->code_number);
for (i = clobber->first_clobber; i < XVECLEN (clobber->pattern, 1); i++)
{
- printf (" XVECEXP (pattern, 0, %d) = ", i);
+ fprintf (file, " XVECEXP (pattern, 0, %d) = ", i);
gen_exp (XVECEXP (clobber->pattern, 1, i),
- GET_CODE (clobber->pattern), NULL, info);
- printf (";\n");
+ GET_CODE (clobber->pattern), NULL, info, file);
+ fprintf (file, ";\n");
}
- printf (" break;\n\n");
+ fprintf (file, " break;\n\n");
}
- printf (" default:\n");
- printf (" gcc_unreachable ();\n");
- printf (" }\n");
- printf ("}\n");
+ fprintf (file, " default:\n");
+ fprintf (file, " gcc_unreachable ();\n");
+ fprintf (file, " }\n");
+ fprintf (file, "}\n");
}
/* Write a function, `added_clobbers_hard_reg_p' that is given an insn_code
@@ -684,17 +685,17 @@ output_add_clobbers (md_rtx_info *info)
SCRATCH. */
static void
-output_added_clobbers_hard_reg_p (void)
+output_added_clobbers_hard_reg_p (FILE *file)
{
struct clobber_pat *clobber;
struct clobber_ent *ent;
int clobber_p;
bool used;
- printf ("\n\nbool\nadded_clobbers_hard_reg_p (int insn_code_number)\n");
- printf ("{\n");
- printf (" switch (insn_code_number)\n");
- printf (" {\n");
+ fprintf (file, "\n\nbool\nadded_clobbers_hard_reg_p (int insn_code_number)\n");
+ fprintf (file, "{\n");
+ fprintf (file, " switch (insn_code_number)\n");
+ fprintf (file, " {\n");
for (clobber_p = 0; clobber_p <= 1; clobber_p++)
{
@@ -703,25 +704,25 @@ output_added_clobbers_hard_reg_p (void)
if (clobber->has_hard_reg == clobber_p)
for (ent = clobber->insns; ent; ent = ent->next)
{
- printf (" case %d:\n", ent->code_number);
+ fprintf (file, " case %d:\n", ent->code_number);
used = true;
}
if (used)
- printf (" return %s;\n\n", clobber_p ? "true" : "false");
+ fprintf (file, " return %s;\n\n", clobber_p ? "true" : "false");
}
- printf (" default:\n");
- printf (" gcc_unreachable ();\n");
- printf (" }\n");
- printf ("}\n");
+ fprintf (file, " default:\n");
+ fprintf (file, " gcc_unreachable ();\n");
+ fprintf (file, " }\n");
+ fprintf (file, "}\n");
}
/* Generate code to invoke find_free_register () as needed for the
scratch registers used by the peephole2 pattern in SPLIT. */
static void
-output_peephole2_scratches (rtx split)
+output_peephole2_scratches (rtx split, FILE *file)
{
int i;
int insn_nr = 0;
@@ -746,12 +747,12 @@ output_peephole2_scratches (rtx split)
if (first)
{
- printf (" HARD_REG_SET _regs_allocated;\n");
- printf (" CLEAR_HARD_REG_SET (_regs_allocated);\n");
+ fprintf (file, " HARD_REG_SET _regs_allocated;\n");
+ fprintf (file, " CLEAR_HARD_REG_SET (_regs_allocated);\n");
first = false;
}
- printf (" if ((operands[%d] = peep2_find_free_register (%d, %d, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\
+ fprintf (file, " if ((operands[%d] = peep2_find_free_register (%d, %d, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\
return NULL;\n",
XINT (elt, 0),
insn_nr, last_insn_nr,
@@ -767,50 +768,50 @@ output_peephole2_scratches (rtx split)
/* Print "arg<N>" parameter declarations for each argument N of ONAME. */
static void
-print_overload_arguments (overloaded_name *oname)
+print_overload_arguments (overloaded_name *oname, FILE *file)
{
for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- printf ("%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
+ fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
}
/* Print code to test whether INSTANCE should be chosen, given that
argument N of the overload is available as "arg<N>". */
static void
-print_overload_test (overloaded_instance *instance)
+print_overload_test (overloaded_instance *instance, FILE *file)
{
for (unsigned int i = 0; i < instance->arg_values.length (); ++i)
- printf ("%sarg%d == %s", i == 0 ? " if (" : "\n && ",
+ fprintf (file, "%sarg%d == %s", i == 0 ? " if (" : "\n && ",
i, instance->arg_values[i]);
- printf (")\n");
+ fprintf (file, ")\n");
}
/* Emit a maybe_code_for_* function for ONAME. */
static void
-handle_overloaded_code_for (overloaded_name *oname)
+handle_overloaded_code_for (overloaded_name *oname, FILE *file)
{
/* Print the function prototype. */
- printf ("\ninsn_code\nmaybe_code_for_%s (", oname->name);
- print_overload_arguments (oname);
- printf (")\n{\n");
+ fprintf (file, "\ninsn_code\nmaybe_code_for_%s (", oname->name);
+ print_overload_arguments (oname, file);
+ fprintf (file, ")\n{\n");
/* Use a sequence of "if" statements for each instance. */
for (overloaded_instance *instance = oname->first_instance;
instance; instance = instance->next)
{
- print_overload_test (instance);
- printf (" return CODE_FOR_%s;\n", instance->name);
+ print_overload_test (instance, file);
+ fprintf (file, " return CODE_FOR_%s;\n", instance->name);
}
/* Return null if no match was found. */
- printf (" return CODE_FOR_nothing;\n}\n");
+ fprintf (file, " return CODE_FOR_nothing;\n}\n");
}
/* Emit a maybe_gen_* function for ONAME. */
static void
-handle_overloaded_gen (overloaded_name *oname)
+handle_overloaded_gen (overloaded_name *oname, FILE *file)
{
unsigned HOST_WIDE_INT seen = 0;
/* All patterns must have the same number of operands. */
@@ -827,25 +828,25 @@ handle_overloaded_gen (overloaded_name *oname)
seen |= mask;
/* Print the function prototype. */
- printf ("\nrtx\nmaybe_gen_%s (", oname->name);
- print_overload_arguments (oname);
+ fprintf (file, "\nrtx\nmaybe_gen_%s (", oname->name);
+ print_overload_arguments (oname, file);
for (int i = 0; i < stats.num_generator_args; ++i)
- printf (", rtx x%d", i);
- printf (")\n{\n");
+ fprintf (file, ", rtx x%d", i);
+ fprintf (file, ")\n{\n");
/* Use maybe_code_for_*, instead of duplicating the selection
logic here. */
- printf (" insn_code code = maybe_code_for_%s (", oname->name);
+ fprintf (file, " insn_code code = maybe_code_for_%s (", oname->name);
for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- printf ("%sarg%d", i == 0 ? "" : ", ", i);
- printf (");\n"
+ fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
+ fprintf (file, ");\n"
" if (code != CODE_FOR_nothing)\n"
" {\n"
" gcc_assert (insn_data[code].n_generator_args == %d);\n"
" return GEN_FCN (code) (", stats.num_generator_args);
for (int i = 0; i < stats.num_generator_args; ++i)
- printf ("%sx%d", i == 0 ? "" : ", ", i);
- printf (");\n"
+ fprintf (file, "%sx%d", i == 0 ? "" : ", ", i);
+ fprintf (file, ");\n"
" }\n"
" else\n"
" return NULL_RTX;\n"
@@ -853,12 +854,68 @@ handle_overloaded_gen (overloaded_name *oname)
}
}
+void
+print_header (FILE *file)
+{
+ fprintf (file, "/* Generated automatically by the program `genemit'\n\
+from the machine description file `md'. */\n\n");
+
+ fprintf (file, "#define IN_TARGET_CODE 1\n");
+ fprintf (file, "#include \"config.h\"\n");
+ fprintf (file, "#include \"system.h\"\n");
+ fprintf (file, "#include \"coretypes.h\"\n");
+ fprintf (file, "#include \"backend.h\"\n");
+ fprintf (file, "#include \"predict.h\"\n");
+ fprintf (file, "#include \"tree.h\"\n");
+ fprintf (file, "#include \"rtl.h\"\n");
+ fprintf (file, "#include \"alias.h\"\n");
+ fprintf (file, "#include \"varasm.h\"\n");
+ fprintf (file, "#include \"stor-layout.h\"\n");
+ fprintf (file, "#include \"calls.h\"\n");
+ fprintf (file, "#include \"memmodel.h\"\n");
+ fprintf (file, "#include \"tm_p.h\"\n");
+ fprintf (file, "#include \"flags.h\"\n");
+ fprintf (file, "#include \"insn-config.h\"\n");
+ fprintf (file, "#include \"expmed.h\"\n");
+ fprintf (file, "#include \"dojump.h\"\n");
+ fprintf (file, "#include \"explow.h\"\n");
+ fprintf (file, "#include \"emit-rtl.h\"\n");
+ fprintf (file, "#include \"stmt.h\"\n");
+ fprintf (file, "#include \"expr.h\"\n");
+ fprintf (file, "#include \"insn-codes.h\"\n");
+ fprintf (file, "#include \"optabs.h\"\n");
+ fprintf (file, "#include \"dfp.h\"\n");
+ fprintf (file, "#include \"output.h\"\n");
+ fprintf (file, "#include \"recog.h\"\n");
+ fprintf (file, "#include \"df.h\"\n");
+ fprintf (file, "#include \"resource.h\"\n");
+ fprintf (file, "#include \"reload.h\"\n");
+ fprintf (file, "#include \"diagnostic-core.h\"\n");
+ fprintf (file, "#include \"regs.h\"\n");
+ fprintf (file, "#include \"tm-constrs.h\"\n");
+ fprintf (file, "#include \"ggc.h\"\n");
+ fprintf (file, "#include \"target.h\"\n\n");
+}
+
+auto_vec<const char *, 10> output_files;
+
+static bool
+handle_arg (const char *arg)
+{
+ if (arg[1] == 'O')
+ {
+ output_files.safe_push (&arg[2]);
+ return true;
+ }
+ return false;
+}
+
int
main (int argc, const char **argv)
{
progname = "genemit";
- if (!init_rtx_reader_args (argc, argv))
+ if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
return (FATAL_EXIT_CODE);
#define DEF_INTERNAL_OPTAB_FN(NAME, FLAGS, OPTAB, TYPE) \
@@ -868,86 +925,87 @@ main (int argc, const char **argv)
/* Assign sequential codes to all entries in the machine description
in parallel with the tables in insn-output.cc. */
- printf ("/* Generated automatically by the program `genemit'\n\
-from the machine description file `md'. */\n\n");
+ int npatterns = count_patterns ();
+ md_rtx_info info;
+
+ bool to_stdout = false;
+ int npatterns_per_file = npatterns;
+ if (!output_files.is_empty ())
+ npatterns_per_file = npatterns / output_files.length () + 1;
+ else
+ to_stdout = true;
- printf ("#define IN_TARGET_CODE 1\n");
- printf ("#include \"config.h\"\n");
- printf ("#include \"system.h\"\n");
- printf ("#include \"coretypes.h\"\n");
- printf ("#include \"backend.h\"\n");
- printf ("#include \"predict.h\"\n");
- printf ("#include \"tree.h\"\n");
- printf ("#include \"rtl.h\"\n");
- printf ("#include \"alias.h\"\n");
- printf ("#include \"varasm.h\"\n");
- printf ("#include \"stor-layout.h\"\n");
- printf ("#include \"calls.h\"\n");
- printf ("#include \"memmodel.h\"\n");
- printf ("#include \"tm_p.h\"\n");
- printf ("#include \"flags.h\"\n");
- printf ("#include \"insn-config.h\"\n");
- printf ("#include \"expmed.h\"\n");
- printf ("#include \"dojump.h\"\n");
- printf ("#include \"explow.h\"\n");
- printf ("#include \"emit-rtl.h\"\n");
- printf ("#include \"stmt.h\"\n");
- printf ("#include \"expr.h\"\n");
- printf ("#include \"insn-codes.h\"\n");
- printf ("#include \"optabs.h\"\n");
- printf ("#include \"dfp.h\"\n");
- printf ("#include \"output.h\"\n");
- printf ("#include \"recog.h\"\n");
- printf ("#include \"df.h\"\n");
- printf ("#include \"resource.h\"\n");
- printf ("#include \"reload.h\"\n");
- printf ("#include \"diagnostic-core.h\"\n");
- printf ("#include \"regs.h\"\n");
- printf ("#include \"tm-constrs.h\"\n");
- printf ("#include \"ggc.h\"\n");
- printf ("#include \"target.h\"\n\n");
+ gcc_assert (npatterns_per_file > 1);
- /* Read the machine description. */
+ /* Reverse so we can pop the first-added element. */
+ output_files.reverse ();
- md_rtx_info info;
+ int count = 0;
+ FILE *file = NULL;
+
+ /* Read the machine description. */
while (read_md_rtx (&info))
- switch (GET_CODE (info.def))
- {
- case DEFINE_INSN:
- gen_insn (&info);
- break;
+ {
+ if (count == 0 || count == npatterns_per_file)
+ {
+ bool is_last = !to_stdout && output_files.is_empty ();
+ if (file && !is_last)
+ if (fclose (file) != 0)
+ return FATAL_EXIT_CODE;
- case DEFINE_EXPAND:
- printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
- gen_expand (&info);
- break;
+ if (!output_files.is_empty ())
+ {
+ const char *const filename = output_files.pop ();
+ file = fopen (filename, "w");
+ }
+ else if (to_stdout)
+ file = stdout;
+ else
+ break;
- case DEFINE_SPLIT:
- printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
- gen_split (&info);
- break;
+ print_header (file);
+ count = 0;
+ }
- case DEFINE_PEEPHOLE2:
- printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
- gen_split (&info);
- break;
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ gen_insn (&info, file);
+ break;
- default:
- break;
- }
+ case DEFINE_EXPAND:
+ fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+ gen_expand (&info, file);
+ break;
+
+ case DEFINE_SPLIT:
+ fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+ gen_split (&info, file);
+ break;
+
+ case DEFINE_PEEPHOLE2:
+ fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+ gen_split (&info, file);
+ break;
+
+ default:
+ break;
+ }
+
+ count++;
+ }
/* Write out the routines to add CLOBBERs to a pattern and say whether they
clobber a hard reg. */
- output_add_clobbers (&info);
- output_added_clobbers_hard_reg_p ();
+ output_add_clobbers (&info, file);
+ output_added_clobbers_hard_reg_p (file);
for (overloaded_name *oname = rtx_reader_ptr->get_overloads ();
oname; oname = oname->next)
{
- handle_overloaded_code_for (oname);
- handle_overloaded_gen (oname);
+ handle_overloaded_code_for (oname, file);
+ handle_overloaded_gen (oname, file);
}
- fflush (stdout);
- return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+ return (fclose (file) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
diff --git a/gcc/gensupport.cc b/gcc/gensupport.cc
index dd920d6..688808c 100644
--- a/gcc/gensupport.cc
+++ b/gcc/gensupport.cc
@@ -3131,6 +3131,61 @@ init_rtx_reader_args (int argc, const char **argv)
return init_rtx_reader_args_cb (argc, argv, 0);
}
+/* Count the number of patterns in all queues and return the count. */
+int
+count_patterns ()
+{
+ int count = 0, truth = 1;
+ rtx def;
+ class queue_elem *cur = define_attr_queue;
+ while (cur)
+ {
+ def = cur->data;
+
+ truth = maybe_eval_c_test (get_c_test (def));
+ if (truth || !insn_elision)
+ count++;
+ cur = cur->next;
+ }
+
+ cur = define_pred_queue;
+ while (cur)
+ {
+ def = cur->data;
+
+ truth = maybe_eval_c_test (get_c_test (def));
+ if (truth || !insn_elision)
+ count++;
+ cur = cur->next;
+ }
+
+ cur = define_insn_queue;
+ truth = 1;
+ while (cur)
+ {
+ def = cur->data;
+
+ truth = maybe_eval_c_test (get_c_test (def));
+ if (truth || !insn_elision)
+ count++;
+ cur = cur->next;
+ }
+
+ cur = other_queue;
+ truth = 1;
+ while (cur)
+ {
+ def = cur->data;
+
+ truth = maybe_eval_c_test (get_c_test (def));
+ if (truth || !insn_elision)
+ count++;
+ cur = cur->next;
+ }
+
+ return count;
+}
+
/* Try to read a single rtx from the file. Return true on success,
describing it in *INFO. */
diff --git a/gcc/gensupport.h b/gcc/gensupport.h
index 7925e22..7396118 100644
--- a/gcc/gensupport.h
+++ b/gcc/gensupport.h
@@ -130,6 +130,7 @@ extern rtx add_implicit_parallel (rtvec);
extern rtx_reader *init_rtx_reader_args_cb (int, const char **,
bool (*)(const char *));
extern rtx_reader *init_rtx_reader_args (int, const char **);
+extern int count_patterns ();
extern bool read_md_rtx (md_rtx_info *);
extern unsigned int get_num_insn_codes ();
diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index a299b98..bded288 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -580,11 +580,21 @@ pass_harden_compares::execute (function *fun)
if (throwing_compare_p)
{
add_stmt_to_eh_lp (asgnck, lookup_stmt_eh_lp (asgn));
- make_eh_edges (asgnck);
+ edge eh = make_eh_edge (asgnck);
+ /* This compare looks like it could raise an exception,
+ but it's dominated by the original compare, that
+ would raise an exception first, so the EH edge from
+ this one is never really taken. */
+ eh->probability = profile_probability::never ();
+ if (eh->dest->count.initialized_p ())
+ eh->dest->count += eh->count ();
+ else
+ eh->dest->count = eh->count ();
edge ckeh;
basic_block nbb = split_edge (non_eh_succ_edge
(gimple_bb (asgnck), &ckeh));
+ gcc_checking_assert (eh == ckeh);
gsi_split = gsi_start_bb (nbb);
if (dump_file)
diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 441df5a..9a45a42 100644
--- a/gcc/gimple-harden-control-flow.cc
+++ b/gcc/gimple-harden-control-flow.cc
@@ -1,5 +1,5 @@
/* Control flow redundancy hardening.
- Copyright (C) 2022 Free Software Foundation, Inc.
+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <oliva@adacore.com>.
This file is part of GCC.
@@ -460,6 +460,10 @@ class rt_bb_visited
at the end of a block's predecessors or successors list. */
tree ckfail, ckpart, ckinv, ckblk;
+ /* If we need to deal with abnormal edges, we insert SSA_NAMEs for
+ boolean true and false. */
+ tree vfalse, vtrue;
+
/* Convert a block index N to a block vindex, the index used to
identify it in the VISITED array. Check that it's in range:
neither ENTRY nor EXIT, but maybe one-past-the-end, to compute
@@ -596,7 +600,8 @@ public:
/* Prepare to add control flow redundancy testing to CFUN. */
rt_bb_visited (int checkpoints)
: nblocks (n_basic_blocks_for_fn (cfun)),
- vword_type (NULL), ckseq (NULL), rtcfg (NULL)
+ vword_type (NULL), ckseq (NULL), rtcfg (NULL),
+ vfalse (NULL), vtrue (NULL)
{
/* If we've already added a declaration for the builtin checker,
extract vword_type and vword_bits from its declaration. */
@@ -703,7 +708,74 @@ public:
/* Insert SEQ on E. */
void insert_exit_check_on_edge (gimple_seq seq, edge e)
{
- gsi_insert_seq_on_edge_immediate (e, seq);
+ if (!(e->flags & EDGE_ABNORMAL))
+ {
+ gsi_insert_seq_on_edge_immediate (e, seq);
+ return;
+ }
+
+ /* Initialize SSA boolean constants for use in abnormal PHIs. */
+ if (!vfalse)
+ {
+ vfalse = make_ssa_name (boolean_type_node);
+ vtrue = make_ssa_name (boolean_type_node);
+
+ gimple_seq vft_seq = NULL;
+ gassign *vfalse_init = gimple_build_assign (vfalse, boolean_false_node);
+ gimple_seq_add_stmt (&vft_seq, vfalse_init);
+ gassign *vtrue_init = gimple_build_assign (vtrue, boolean_true_node);
+ gimple_seq_add_stmt (&vft_seq, vtrue_init);
+
+ gsi_insert_seq_on_edge_immediate (single_succ_edge
+ (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
+ vft_seq);
+ }
+
+ /* We can't insert on abnormal edges, but we can arrange for SEQ
+ to execute conditionally at dest. Add a PHI boolean with TRUE
+ from E and FALSE from other preds, split the whole block, add a
+ test for the PHI to run a new block with SEQ or skip straight
+ to the original block. If there are multiple incoming abnormal
+ edges, we'll do this multiple times. ??? Unless there are
+ multiple abnormal edges with different postcheck status, we
+ could split the block and redirect other edges, rearranging the
+ PHI nodes. Optimizers already know how to do this, so we can
+ keep things simple here. */
+ basic_block bb = e->dest;
+ basic_block bb_postcheck = split_block_after_labels (bb)->dest;
+
+ basic_block bb_check = create_empty_bb (e->dest);
+ bb_check->count = e->count ();
+ if (dom_info_available_p (CDI_DOMINATORS))
+ set_immediate_dominator (CDI_DOMINATORS, bb_check, bb);
+ if (current_loops)
+ add_bb_to_loop (bb_check, current_loops->tree_root);
+
+ gimple_stmt_iterator chkpt = gsi_after_labels (bb_check);
+ gsi_insert_seq_before_without_update (&chkpt, seq, GSI_SAME_STMT);
+ edge edge_postcheck = make_edge (bb_check, bb_postcheck, EDGE_FALLTHRU);
+ edge_postcheck->probability = profile_probability::always ();
+
+ tree cond_var = make_ssa_name (boolean_type_node);
+ gcond *cond = gimple_build_cond (NE_EXPR, cond_var, boolean_false_node,
+ NULL, NULL);
+ gimple_stmt_iterator condpt = gsi_after_labels (bb);
+ gsi_insert_before (&condpt, cond, GSI_SAME_STMT);
+ edge edge_nocheck = single_succ_edge (bb);
+ edge_nocheck->flags &= ~EDGE_FALLTHRU;
+ edge_nocheck->flags |= EDGE_FALSE_VALUE;
+ edge edge_check = make_edge (bb, bb_check, EDGE_TRUE_VALUE);
+ edge_check->probability = e->count ().probability_in (bb->count);
+ edge_nocheck->probability = edge_check->probability.invert ();
+
+ gphi *cond_phi = create_phi_node (cond_var, bb);
+ for (int i = 0, ei = EDGE_COUNT (bb->preds); i < ei; i++)
+ {
+ edge pred = EDGE_PRED (bb, i);
+ bool check_edge = pred == e;
+ tree val = check_edge ? vtrue : vfalse;
+ add_phi_arg (cond_phi, val, pred, UNKNOWN_LOCATION);
+ }
}
/* Add checking code to CHK_EDGES and CHKCALL_BLOCKS, and
@@ -1287,7 +1359,7 @@ pass_harden_control_flow_redundancy::execute (function *fun)
add_stmt_to_eh_lp (stmt, lp_eh_cleanup);
/* Finally, wire the EH cleanup block into the CFG. */
- edge neeh = make_eh_edges (stmt);
+ edge neeh = make_eh_edge (stmt);
neeh->probability = profile_probability::never ();
gcc_checking_assert (neeh->dest == bb_eh_cleanup);
if (neeh->dest->count.initialized_p ())
diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h
index bec3ff4..9892c142 100644
--- a/gcc/gimple-match.h
+++ b/gcc/gimple-match.h
@@ -92,6 +92,10 @@ public:
code_helper, tree, tree, tree, tree, tree);
gimple_match_op (const gimple_match_cond &,
code_helper, tree, tree, tree, tree, tree, tree);
+ gimple_match_op (const gimple_match_cond &,
+ code_helper, tree, tree, tree, tree, tree, tree, tree);
+ gimple_match_op (const gimple_match_cond &,
+ code_helper, tree, tree, tree, tree, tree, tree, tree, tree);
void set_op (code_helper, tree, unsigned int);
void set_op (code_helper, tree, tree);
@@ -100,6 +104,8 @@ public:
void set_op (code_helper, tree, tree, tree, tree, bool);
void set_op (code_helper, tree, tree, tree, tree, tree);
void set_op (code_helper, tree, tree, tree, tree, tree, tree);
+ void set_op (code_helper, tree, tree, tree, tree, tree, tree, tree);
+ void set_op (code_helper, tree, tree, tree, tree, tree, tree, tree, tree);
void set_value (tree);
tree op_or_null (unsigned int) const;
@@ -212,6 +218,39 @@ gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
ops[4] = op4;
}
+inline
+gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
+ code_helper code_in, tree type_in,
+ tree op0, tree op1, tree op2, tree op3,
+ tree op4, tree op5)
+ : cond (cond_in), code (code_in), type (type_in), reverse (false),
+ num_ops (6)
+{
+ ops[0] = op0;
+ ops[1] = op1;
+ ops[2] = op2;
+ ops[3] = op3;
+ ops[4] = op4;
+ ops[5] = op5;
+}
+
+inline
+gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
+ code_helper code_in, tree type_in,
+ tree op0, tree op1, tree op2, tree op3,
+ tree op4, tree op5, tree op6)
+ : cond (cond_in), code (code_in), type (type_in), reverse (false),
+ num_ops (7)
+{
+ ops[0] = op0;
+ ops[1] = op1;
+ ops[2] = op2;
+ ops[3] = op3;
+ ops[4] = op4;
+ ops[5] = op5;
+ ops[6] = op6;
+}
+
/* Change the operation performed to CODE_IN, the type of the result to
TYPE_IN, and the number of operands to NUM_OPS_IN. The caller needs
to set the operands itself. */
@@ -299,6 +338,39 @@ gimple_match_op::set_op (code_helper code_in, tree type_in,
ops[4] = op4;
}
+inline void
+gimple_match_op::set_op (code_helper code_in, tree type_in,
+ tree op0, tree op1, tree op2, tree op3, tree op4,
+ tree op5)
+{
+ code = code_in;
+ type = type_in;
+ num_ops = 6;
+ ops[0] = op0;
+ ops[1] = op1;
+ ops[2] = op2;
+ ops[3] = op3;
+ ops[4] = op4;
+ ops[5] = op5;
+}
+
+inline void
+gimple_match_op::set_op (code_helper code_in, tree type_in,
+ tree op0, tree op1, tree op2, tree op3, tree op4,
+ tree op5, tree op6)
+{
+ code = code_in;
+ type = type_in;
+ num_ops = 7;
+ ops[0] = op0;
+ ops[1] = op1;
+ ops[2] = op2;
+ ops[3] = op3;
+ ops[4] = op4;
+ ops[5] = op5;
+ ops[6] = op6;
+}
+
/* Set the "operation" to be the single value VALUE, such as a constant
or SSA_NAME. */
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 22ff107..77f07af 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -12121,6 +12121,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
}
/* Fall through. */
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_FINAL:
OMP_CLAUSE_OPERAND (c, 0)
= gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
@@ -13342,6 +13343,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d24054e..aff74bd 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-967a215d6419c3db58f8f59a0c252c458abce395
+e997b0201512110e9c20b1fdfd40014830031047
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index d276bd8..c9177b7 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -201,22 +201,35 @@ Expression::report_error(const char* msg)
this->set_is_error();
}
+// A convenience function for handling a type in do_is_untyped. If
+// TYPE is not abstract, return false. Otherwise set *PTYPE to TYPE
+// and return true.
+
+bool
+Expression::is_untyped_type(Type* type, Type** ptype)
+{
+ if (!type->is_abstract())
+ return false;
+ *ptype = type;
+ return true;
+}
+
// Set types of variables and constants. This is implemented by the
// child class.
void
-Expression::determine_type(const Type_context* context)
+Expression::determine_type(Gogo* gogo, const Type_context* context)
{
- this->do_determine_type(context);
+ this->do_determine_type(gogo, context);
}
// Set types when there is no context.
void
-Expression::determine_type_no_context()
+Expression::determine_type_no_context(Gogo* gogo)
{
Type_context context;
- this->do_determine_type(&context);
+ this->do_determine_type(gogo, &context);
}
// Return true if two expressions refer to the same variable or struct
@@ -292,8 +305,8 @@ Expression::convert_for_assignment(Gogo* gogo, Type* lhs_type,
{
// Type to interface conversions have been made explicit early.
go_assert(rhs_type->interface_type() != NULL);
- return Expression::convert_interface_to_interface(lhs_type, rhs, false,
- location);
+ return Expression::convert_interface_to_interface(gogo, lhs_type, rhs,
+ false, location);
}
else if (!are_identical && rhs_type->interface_type() != NULL)
return Expression::convert_interface_to_type(gogo, lhs_type, rhs, location);
@@ -512,7 +525,8 @@ Expression::get_interface_type_descriptor(Expression* rhs)
// interface type.
Expression*
-Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
+Expression::convert_interface_to_interface(Gogo* gogo, Type *lhs_type,
+ Expression* rhs,
bool for_type_guard,
Location location)
{
@@ -545,7 +559,7 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
if (for_type_guard)
{
// A type assertion fails when converting a nil interface.
- first_field = Runtime::make_call(Runtime::ASSERTITAB, location, 2,
+ first_field = Runtime::make_call(gogo, Runtime::ASSERTITAB, location, 2,
lhs_type_expr, rhs_type_expr);
}
else if (lhs_is_empty)
@@ -558,7 +572,7 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
{
// A conversion to a non-empty interface may fail, but unlike a
// type assertion converting nil will always succeed.
- first_field = Runtime::make_call(Runtime::REQUIREITAB, location, 2,
+ first_field = Runtime::make_call(gogo, Runtime::REQUIREITAB, location, 2,
lhs_type_expr, rhs_type_expr);
}
@@ -597,7 +611,7 @@ Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rh
Expression* cond;
if (gogo->need_eqtype()) {
- cond = Runtime::make_call(Runtime::EQTYPE, location,
+ cond = Runtime::make_call(gogo, Runtime::EQTYPE, location,
2, lhs_type_expr,
rhs_descriptor);
} else {
@@ -606,7 +620,7 @@ Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rh
}
rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
- Expression* panic = Runtime::make_call(Runtime::PANICDOTTYPE, location,
+ Expression* panic = Runtime::make_call(gogo, Runtime::PANICDOTTYPE, location,
3, lhs_type_expr->copy(),
rhs_descriptor,
rhs_inter_expr);
@@ -706,7 +720,8 @@ Expression::backend_numeric_constant_expression(Translate_context* context,
// functions, which will panic.
void
-Expression::check_bounds(Expression* val, Operator op, Expression* bound,
+Expression::check_bounds(Gogo* gogo, Expression* val, Operator op,
+ Expression* bound,
Runtime::Function code,
Runtime::Function code_u,
Runtime::Function code_extend,
@@ -800,7 +815,7 @@ Expression::check_bounds(Expression* val, Operator op, Expression* bound,
}
Expression* ignore = Expression::make_boolean(true, loc);
- Expression* crash = Runtime::make_call(c, loc, 2,
+ Expression* crash = Runtime::make_call(gogo, c, loc, 2,
val->copy(), bound->copy());
Expression* cond = Expression::make_conditional(check, ignore, crash, loc);
inserter->insert(Statement::make_statement(cond, true));
@@ -827,7 +842,11 @@ class Error_expression : public Expression
{ return true; }
bool
- do_numeric_constant_value(Numeric_constant* nc) const
+ do_is_untyped(Type**) const
+ { return false; }
+
+ bool
+ do_numeric_constant_value(Numeric_constant* nc)
{
nc->set_unsigned_long(NULL, 0);
return true;
@@ -842,7 +861,7 @@ class Error_expression : public Expression
{ return Type::make_error_type(); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -897,7 +916,7 @@ Type_expression : public Expression
{ return this->type_; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
void
@@ -998,10 +1017,10 @@ Var_expression::do_type()
// Determine the type of a reference to a variable.
void
-Var_expression::do_determine_type(const Type_context*)
+Var_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
if (this->variable_->is_variable())
- this->variable_->var_value()->determine_type();
+ this->variable_->var_value()->determine_type(gogo);
}
// Something takes the address of this variable. This means that we
@@ -1303,9 +1322,10 @@ Set_and_use_temporary_expression::do_type()
void
Set_and_use_temporary_expression::do_determine_type(
+ Gogo* gogo,
const Type_context* context)
{
- this->expr_->determine_type(context);
+ this->expr_->determine_type(gogo, context);
}
// Take the address.
@@ -1378,7 +1398,7 @@ class Sink_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
@@ -1410,7 +1430,7 @@ Sink_expression::do_type()
// Determine the type of a sink expression.
void
-Sink_expression::do_determine_type(const Type_context* context)
+Sink_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (context->type != NULL)
this->type_ = context->type;
@@ -1805,7 +1825,7 @@ class Func_code_reference_expression : public Expression
{ return Type::make_pointer_type(Type::make_void_type()); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -1965,11 +1985,14 @@ class Boolean_expression : public Expression
{ return true; }
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_zero_value() const
{ return this->val_ == false; }
bool
- do_boolean_constant_value(bool* val) const
+ do_boolean_constant_value(bool* val)
{
*val = this->val_;
return true;
@@ -1983,7 +2006,7 @@ class Boolean_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
@@ -2022,6 +2045,15 @@ Boolean_expression::do_traverse(Traverse* traverse)
return TRAVERSE_CONTINUE;
}
+bool
+Boolean_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->type_ != NULL)
+ return Expression::is_untyped_type(this->type_, ptype);
+ *ptype = Type::make_boolean_type();
+ return true;
+}
+
// Get the type.
Type*
@@ -2035,7 +2067,7 @@ Boolean_expression::do_type()
// Set the type from the context.
void
-Boolean_expression::do_determine_type(const Type_context* context)
+Boolean_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
@@ -2095,6 +2127,15 @@ String_expression::do_traverse(Traverse* traverse)
return TRAVERSE_CONTINUE;
}
+bool
+String_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->type_ != NULL)
+ return Expression::is_untyped_type(this->type_, ptype);
+ *ptype = Type::make_string_type();
+ return true;
+}
+
// Get the type.
Type*
@@ -2108,7 +2149,7 @@ String_expression::do_type()
// Set the type from the context.
void
-String_expression::do_determine_type(const Type_context* context)
+String_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
@@ -2278,7 +2319,7 @@ class String_info_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
@@ -2390,7 +2431,7 @@ class String_value_expression : public Expression
{ return Type::make_string_type(); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
@@ -2485,6 +2526,9 @@ class Integer_expression : public Expression
{ return true; }
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_zero_value() const
{ return mpz_sgn(this->val_) == 0; }
@@ -2493,13 +2537,13 @@ class Integer_expression : public Expression
{ return true; }
bool
- do_numeric_constant_value(Numeric_constant* nc) const;
+ do_numeric_constant_value(Numeric_constant* nc);
Type*
do_type();
void
- do_determine_type(const Type_context* context);
+ do_determine_type(Gogo*, const Type_context* context);
void
do_check_types(Gogo*);
@@ -2558,7 +2602,7 @@ Integer_expression::do_traverse(Traverse* traverse)
// this as a character when appropriate.
bool
-Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const
+Integer_expression::do_numeric_constant_value(Numeric_constant* nc)
{
if (this->is_character_constant_)
nc->set_rune(this->type_, this->val_);
@@ -2567,6 +2611,18 @@ Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const
return true;
}
+bool
+Integer_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->type_ != NULL)
+ return Expression::is_untyped_type(this->type_, ptype);
+ if (this->is_character_constant_)
+ *ptype = Type::make_abstract_character_type();
+ else
+ *ptype = Type::make_abstract_integer_type();
+ return true;
+}
+
// Return the current type. If we haven't set the type yet, we return
// an abstract integer type.
@@ -2587,7 +2643,7 @@ Integer_expression::do_type()
// abstract type to a real type.
void
-Integer_expression::do_determine_type(const Type_context* context)
+Integer_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
@@ -2913,6 +2969,9 @@ class Float_expression : public Expression
{ return true; }
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_zero_value() const
{
return mpfr_zero_p(this->val_) != 0
@@ -2924,7 +2983,7 @@ class Float_expression : public Expression
{ return true; }
bool
- do_numeric_constant_value(Numeric_constant* nc) const
+ do_numeric_constant_value(Numeric_constant* nc)
{
nc->set_float(this->type_, this->val_);
return true;
@@ -2934,7 +2993,7 @@ class Float_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -2978,6 +3037,15 @@ Float_expression::do_traverse(Traverse* traverse)
return TRAVERSE_CONTINUE;
}
+bool
+Float_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->type_ != NULL)
+ return Expression::is_untyped_type(this->type_, ptype);
+ *ptype = Type::make_abstract_float_type();
+ return true;
+}
+
// Return the current type. If we haven't set the type yet, we return
// an abstract float type.
@@ -2993,7 +3061,7 @@ Float_expression::do_type()
// abstract type to a real type.
void
-Float_expression::do_determine_type(const Type_context* context)
+Float_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
@@ -3135,6 +3203,9 @@ class Complex_expression : public Expression
{ return true; }
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_zero_value() const
{
return mpfr_zero_p(mpc_realref(this->val_)) != 0
@@ -3148,7 +3219,7 @@ class Complex_expression : public Expression
{ return true; }
bool
- do_numeric_constant_value(Numeric_constant* nc) const
+ do_numeric_constant_value(Numeric_constant* nc)
{
nc->set_complex(this->type_, this->val_);
return true;
@@ -3158,7 +3229,7 @@ class Complex_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -3204,6 +3275,15 @@ Complex_expression::do_traverse(Traverse* traverse)
return TRAVERSE_CONTINUE;
}
+bool
+Complex_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->type_ != NULL)
+ return Expression::is_untyped_type(this->type_, ptype);
+ *ptype = Type::make_abstract_complex_type();
+ return true;
+}
+
// Return the current type. If we haven't set the type yet, we return
// an abstract complex type.
@@ -3219,7 +3299,7 @@ Complex_expression::do_type()
// abstract type to a real type.
void
-Complex_expression::do_determine_type(const Type_context* context)
+Complex_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
@@ -3400,7 +3480,7 @@ Const_expression::do_lower(Gogo* gogo, Named_object*,
// Return a numeric constant value.
bool
-Const_expression::do_numeric_constant_value(Numeric_constant* nc) const
+Const_expression::do_numeric_constant_value(Numeric_constant* nc)
{
if (this->seen_)
return false;
@@ -3428,7 +3508,7 @@ Const_expression::do_numeric_constant_value(Numeric_constant* nc) const
}
bool
-Const_expression::do_string_constant_value(std::string* val) const
+Const_expression::do_string_constant_value(std::string* val)
{
if (this->seen_)
return false;
@@ -3443,7 +3523,7 @@ Const_expression::do_string_constant_value(std::string* val) const
}
bool
-Const_expression::do_boolean_constant_value(bool* val) const
+Const_expression::do_boolean_constant_value(bool* val)
{
if (this->seen_)
return false;
@@ -3457,6 +3537,21 @@ Const_expression::do_boolean_constant_value(bool* val) const
return ok;
}
+// Whether this is untyped.
+
+bool
+Const_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->type_ != NULL)
+ return Expression::is_untyped_type(this->type_, ptype);
+
+ Named_constant* nc = this->constant_->const_value();
+ if (nc->type() != NULL)
+ return Expression::is_untyped_type(nc->type(), ptype);
+
+ return nc->expr()->is_untyped(ptype);
+}
+
// Return the type of the const reference.
Type*
@@ -3507,7 +3602,7 @@ Const_expression::do_type()
// Set the type of the const reference.
void
-Const_expression::do_determine_type(const Type_context* context)
+Const_expression::do_determine_type(Gogo*, const Type_context* context)
{
Type* ctype = this->constant_->const_value()->type();
Type* cetype = (ctype != NULL
@@ -3707,6 +3802,13 @@ class Nil_expression : public Expression
{ return true; }
bool
+ do_untyped_type(Type** ptype) const
+ {
+ *ptype = Type::make_nil_type();
+ return true;
+ }
+
+ bool
do_is_zero_value() const
{ return true; }
@@ -3719,7 +3821,7 @@ class Nil_expression : public Expression
{ return Type::make_nil_type(); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -3816,7 +3918,7 @@ Type_conversion_expression::do_traverse(Traverse* traverse)
// from slice to pointer-to-array, as they can panic.
Expression*
-Type_conversion_expression::do_lower(Gogo*, Named_object*,
+Type_conversion_expression::do_lower(Gogo* gogo, Named_object*,
Statement_inserter* inserter, int)
{
Type* type = this->type_;
@@ -3937,7 +4039,7 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
location);
vallen = Expression::make_temporary_reference(vallen_temp, location);
- Expression* panic = Runtime::make_call(Runtime::PANIC_SLICE_CONVERT,
+ Expression* panic = Runtime::make_call(gogo, Runtime::PANIC_SLICE_CONVERT,
location, 2, arrlen, vallen);
Expression* nil = Expression::make_nil(location);
@@ -4078,7 +4180,7 @@ Type_conversion_expression::do_is_static_initializer() const
bool
Type_conversion_expression::do_numeric_constant_value(
- Numeric_constant* nc) const
+ Numeric_constant* nc)
{
if (!this->type_->is_numeric_type())
return false;
@@ -4090,7 +4192,7 @@ Type_conversion_expression::do_numeric_constant_value(
// Return the constant string value if there is one.
bool
-Type_conversion_expression::do_string_constant_value(std::string* val) const
+Type_conversion_expression::do_string_constant_value(std::string* val)
{
if (this->type_->is_string_type() && this->expr_->type()->is_string_type())
return this->expr_->string_constant_value(val);
@@ -4127,7 +4229,7 @@ Type_conversion_expression::do_string_constant_value(std::string* val) const
// Return the constant boolean value if there is one.
bool
-Type_conversion_expression::do_boolean_constant_value(bool* val) const
+Type_conversion_expression::do_boolean_constant_value(bool* val)
{
if (!this->type_->is_boolean_type())
return false;
@@ -4137,10 +4239,10 @@ Type_conversion_expression::do_boolean_constant_value(bool* val) const
// Determine the resulting type of the conversion.
void
-Type_conversion_expression::do_determine_type(const Type_context*)
+Type_conversion_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
Type_context subcontext(this->type_, false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
// Check that types are convertible.
@@ -4258,7 +4360,7 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
else
buf = Expression::make_nil(loc);
Expression* i2s_expr =
- Runtime::make_call(Runtime::INTSTRING, loc, 2, buf, this->expr_);
+ Runtime::make_call(gogo, Runtime::INTSTRING, loc, 2, buf, this->expr_);
return Expression::make_cast(type, i2s_expr, loc)->get_backend(context);
}
else if (type->is_string_type() && expr_type->is_slice_type())
@@ -4296,14 +4398,14 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
Expression* str = Expression::make_string_value(ptr, len, loc);
return str->get_backend(context);
}
- return Runtime::make_call(Runtime::SLICEBYTETOSTRING, loc, 3, buf,
- ptr, len)->get_backend(context);
+ return Runtime::make_call(gogo, Runtime::SLICEBYTETOSTRING, loc, 3,
+ buf, ptr, len)->get_backend(context);
}
else
{
go_assert(e->integer_type()->is_rune());
- return Runtime::make_call(Runtime::SLICERUNETOSTRING, loc, 2, buf,
- this->expr_)->get_backend(context);
+ return Runtime::make_call(gogo, Runtime::SLICERUNETOSTRING, loc, 2,
+ buf, this->expr_)->get_backend(context);
}
}
else if (type->is_slice_type() && expr_type->is_string_type())
@@ -4332,7 +4434,8 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
}
else
buf = Expression::make_nil(loc);
- Expression* s2a = Runtime::make_call(code, loc, 2, buf, this->expr_);
+ Expression* s2a = Runtime::make_call(gogo, code, loc, 2, buf,
+ this->expr_);
return Expression::make_unsafe_cast(type, s2a, loc)->get_backend(context);
}
else if (type->is_numeric_type())
@@ -4773,6 +4876,14 @@ Unary_expression::do_is_constant() const
return this->expr_->is_constant();
}
+bool
+Unary_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND)
+ return false;
+ return this->expr_->is_untyped(ptype);
+}
+
// Return whether a unary expression can be used as a constant
// initializer.
@@ -5030,7 +5141,7 @@ Unary_expression::eval_constant(Operator op, const Numeric_constant* unc,
// Return the integral constant value of a unary expression, if it has one.
bool
-Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const
+Unary_expression::do_numeric_constant_value(Numeric_constant* nc)
{
Numeric_constant unc;
if (!this->expr_->numeric_constant_value(&unc))
@@ -5043,7 +5154,7 @@ Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const
// Return the boolean constant value of a unary expression, if it has one.
bool
-Unary_expression::do_boolean_constant_value(bool* val) const
+Unary_expression::do_boolean_constant_value(bool* val)
{
if (this->op_ == OPERATOR_NOT
&& this->expr_->boolean_constant_value(val))
@@ -5087,7 +5198,7 @@ Unary_expression::do_type()
// Determine abstract types for a unary expression.
void
-Unary_expression::do_determine_type(const Type_context* context)
+Unary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
switch (this->op_)
{
@@ -5095,7 +5206,7 @@ Unary_expression::do_determine_type(const Type_context* context)
case OPERATOR_MINUS:
case OPERATOR_NOT:
case OPERATOR_XOR:
- this->expr_->determine_type(context);
+ this->expr_->determine_type(gogo, context);
break;
case OPERATOR_AND:
@@ -5105,7 +5216,7 @@ Unary_expression::do_determine_type(const Type_context* context)
? NULL
: context->type->points_to());
Type_context subcontext(subtype, false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
break;
@@ -5116,7 +5227,7 @@ Unary_expression::do_determine_type(const Type_context* context)
? NULL
: Type::make_pointer_type(context->type));
Type_context subcontext(subtype, false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
break;
@@ -5372,7 +5483,7 @@ Unary_expression::do_get_backend(Translate_context* context)
Bexpression* compare =
gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr,
nil, loc);
- Expression* crash = Runtime::make_call(Runtime::PANIC_MEM,
+ Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM,
loc, 0);
Bexpression* bcrash = crash->get_backend(context);
Bfunction* bfn = context->function()->func_value()->get_decl();
@@ -5522,6 +5633,81 @@ Binary_expression::do_traverse(Traverse* traverse)
return Expression::traverse(&this->right_, traverse);
}
+// Return whether a binary expression is untyped.
+
+bool
+Binary_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->type_ != NULL)
+ return Expression::is_untyped_type(this->type_, ptype);
+
+ switch (this->op_)
+ {
+ case OPERATOR_EQEQ:
+ case OPERATOR_NOTEQ:
+ case OPERATOR_LT:
+ case OPERATOR_LE:
+ case OPERATOR_GT:
+ case OPERATOR_GE:
+ // Comparisons are untyped by default.
+ *ptype = Type::make_boolean_type();
+ return true;
+
+ case OPERATOR_LSHIFT:
+ case OPERATOR_RSHIFT:
+ // A shift operation is untyped if the left hand expression is
+ // untyped. The right hand expression is irrelevant.
+ return this->left_->is_untyped(ptype);
+
+ default:
+ break;
+ }
+
+ Type* tleft;
+ Type* tright;
+ if (!this->left_->is_untyped(&tleft)
+ || !this->right_->is_untyped(&tright))
+ return false;
+
+ // If both sides are numeric, pick a type based on the kind.
+ enum kind { INT, RUNE, FLOAT, COMPLEX };
+ enum kind kleft, kright;
+
+ if (tleft->integer_type() != NULL)
+ kleft = tleft->integer_type()->is_rune() ? RUNE : INT;
+ else if (tleft->float_type() != NULL)
+ kleft = FLOAT;
+ else if (tleft->complex_type() != NULL)
+ kleft = COMPLEX;
+ else
+ {
+ // Not numeric. If the types are different, we will report an
+ // error later.
+ *ptype = tleft;
+ return true;
+ }
+
+ if (tright->integer_type() != NULL)
+ kright = tright->integer_type()->is_rune() ? RUNE : INT;
+ else if (tright->float_type() != NULL)
+ kright = FLOAT;
+ else if (tright->complex_type() != NULL)
+ kright = COMPLEX;
+ else
+ {
+ // Types are different. We will report an error later.
+ *ptype = tleft;
+ return true;
+ }
+
+ if (kleft > kright)
+ *ptype = tleft;
+ else
+ *ptype = tright;
+
+ return true;
+}
+
// Return whether this expression may be used as a static initializer.
bool
@@ -6443,7 +6629,8 @@ Binary_expression::lower_interface_value_comparison(Gogo*,
// Lower a struct or array comparison to a call to memcmp.
Expression*
-Binary_expression::lower_compare_to_memcmp(Gogo*, Statement_inserter* inserter)
+Binary_expression::lower_compare_to_memcmp(Gogo* gogo,
+ Statement_inserter* inserter)
{
Location loc = this->location();
@@ -6452,7 +6639,8 @@ Binary_expression::lower_compare_to_memcmp(Gogo*, Statement_inserter* inserter)
Expression* len = Expression::make_type_info(this->left_->type(),
TYPE_INFO_SIZE);
- Expression* call = Runtime::make_call(Runtime::MEMCMP, loc, 3, a1, a2, len);
+ Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP, loc, 3,
+ a1, a2, len);
Type* int32_type = Type::lookup_integer_type("int32");
Expression* zero = Expression::make_integer_ul(0, int32_type, loc);
return Expression::make_binary(this->op_, call, zero, loc);
@@ -6545,7 +6733,7 @@ Binary_expression::operand_address(Statement_inserter* inserter,
// Return the numeric constant value, if it has one.
bool
-Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
+Binary_expression::do_numeric_constant_value(Numeric_constant* nc)
{
Numeric_constant left_nc;
if (!this->left_->numeric_constant_value(&left_nc))
@@ -6561,7 +6749,7 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
// Return the boolean constant value, if it has one.
bool
-Binary_expression::do_boolean_constant_value(bool* val) const
+Binary_expression::do_boolean_constant_value(bool* val)
{
bool is_comparison = false;
switch (this->op_)
@@ -6705,7 +6893,7 @@ Binary_expression::do_type()
// Set type for a binary expression.
void
-Binary_expression::do_determine_type(const Type_context* context)
+Binary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
Type* tleft = this->left_->type();
Type* tright = this->right_->type();
@@ -6782,7 +6970,7 @@ Binary_expression::do_determine_type(const Type_context* context)
subcontext.type = subcontext.type->make_non_abstract_type();
}
- this->left_->determine_type(&subcontext);
+ this->left_->determine_type(gogo, &subcontext);
if (is_shift_op)
{
@@ -6802,7 +6990,7 @@ Binary_expression::do_determine_type(const Type_context* context)
subcontext.may_be_abstract = false;
}
- this->right_->determine_type(&subcontext);
+ this->right_->determine_type(gogo, &subcontext);
if (is_comparison)
{
@@ -7154,7 +7342,7 @@ Binary_expression::do_get_backend(Translate_context* context)
Bexpression* compare =
gogo->backend()->binary_expression(OPERATOR_LT, right, zero_expr,
loc);
- Expression* crash = Runtime::make_call(Runtime::PANIC_SHIFT,
+ Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_SHIFT,
loc, 0);
Bexpression* bcrash = crash->get_backend(context);
Bfunction* bfn = context->function()->func_value()->get_decl();
@@ -7175,7 +7363,7 @@ Binary_expression::do_get_backend(Translate_context* context)
gogo->backend()->binary_expression(OPERATOR_EQEQ,
right, zero_expr, loc);
- Expression* crash = Runtime::make_call(Runtime::PANIC_DIVIDE,
+ Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_DIVIDE,
loc, 0);
Bexpression* bcrash = crash->get_backend(context);
@@ -7478,6 +7666,7 @@ Expression::comparison(Translate_context* context, Type* result_type,
Operator op, Expression* left, Expression* right,
Location location)
{
+ Gogo* gogo = context->gogo();
Type* left_type = left->type();
Type* right_type = right->type();
@@ -7510,7 +7699,8 @@ Expression::comparison(Translate_context* context, Type* result_type,
Expression* ptreq = Expression::make_binary(OPERATOR_EQEQ, lptr, rptr,
location);
Expression* btrue = Expression::make_boolean(true, location);
- Expression* call = Runtime::make_call(Runtime::MEMCMP, location, 3,
+ Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP,
+ location, 3,
lptr->copy(), rptr->copy(),
rlen->copy());
Type* int32_type = Type::lookup_integer_type("int32");
@@ -7525,7 +7715,7 @@ Expression::comparison(Translate_context* context, Type* result_type,
}
else
{
- left = Runtime::make_call(Runtime::CMPSTRING, location, 2,
+ left = Runtime::make_call(gogo, Runtime::CMPSTRING, location, 2,
left, right);
right = zexpr;
}
@@ -7559,9 +7749,10 @@ Expression::comparison(Translate_context* context, Type* result_type,
Expression* descriptor =
Expression::make_type_descriptor(right_type, location);
left =
- Runtime::make_call((left_type->interface_type()->is_empty()
- ? Runtime::EFACEVALEQ
- : Runtime::IFACEVALEQ),
+ Runtime::make_call(gogo,
+ (left_type->interface_type()->is_empty()
+ ? Runtime::EFACEVALEQ
+ : Runtime::IFACEVALEQ),
location, 3, left, descriptor,
pointer_arg);
go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
@@ -7589,7 +7780,8 @@ Expression::comparison(Translate_context* context, Type* result_type,
compare_function = Runtime::IFACEEFACEEQ;
}
- left = Runtime::make_call(compare_function, location, 2, left, right);
+ left = Runtime::make_call(gogo, compare_function, location, 2,
+ left, right);
go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
right = Expression::make_boolean(true, location);
}
@@ -7620,7 +7812,6 @@ Expression::comparison(Translate_context* context, Type* result_type,
Bexpression* left_bexpr = left->get_backend(context);
Bexpression* right_bexpr = right->get_backend(context);
- Gogo* gogo = context->gogo();
Bexpression* ret = gogo->backend()->binary_expression(op, left_bexpr,
right_bexpr, location);
if (result_type != NULL)
@@ -7645,6 +7836,21 @@ String_concat_expression::do_is_constant() const
}
bool
+String_concat_expression::do_is_untyped(Type** ptype) const
+{
+ for (Expression_list::iterator pe = this->exprs_->begin();
+ pe != this->exprs_->end();
+ ++pe)
+ {
+ if (!(*pe)->is_untyped(ptype))
+ return false;
+ }
+
+ *ptype = Type::make_string_type();
+ return true;
+}
+
+bool
String_concat_expression::do_is_zero_value() const
{
for (Expression_list::const_iterator pe = this->exprs_->begin();
@@ -7689,7 +7895,8 @@ String_concat_expression::do_type()
}
void
-String_concat_expression::do_determine_type(const Type_context* context)
+String_concat_expression::do_determine_type(Gogo* gogo,
+ const Type_context* context)
{
Type_context subcontext(*context);
for (Expression_list::iterator pe = this->exprs_->begin();
@@ -7708,7 +7915,7 @@ String_concat_expression::do_determine_type(const Type_context* context)
for (Expression_list::iterator pe = this->exprs_->begin();
pe != this->exprs_->end();
++pe)
- (*pe)->determine_type(&subcontext);
+ (*pe)->determine_type(gogo, &subcontext);
}
void
@@ -7742,7 +7949,7 @@ String_concat_expression::do_check_types(Gogo*)
}
Expression*
-String_concat_expression::do_flatten(Gogo*, Named_object*,
+String_concat_expression::do_flatten(Gogo* gogo, Named_object*,
Statement_inserter* inserter)
{
if (this->is_error_expression())
@@ -7812,8 +8019,8 @@ String_concat_expression::do_flatten(Gogo*, Named_object*,
Expression* ref = Expression::make_temporary_reference(ts, loc);
ref = Expression::make_unary(OPERATOR_AND, ref, loc);
Expression* call =
- Runtime::make_call(Runtime::CONCATSTRINGS, loc, 3, buf,
- ref, len->copy());
+ Runtime::make_call(gogo, Runtime::CONCATSTRINGS, loc, 3,
+ buf, ref, len->copy());
return Expression::make_cast(type, call, loc);
}
@@ -7862,7 +8069,7 @@ Bound_method_expression::do_type()
// Determine the types of a method expression.
void
-Bound_method_expression::do_determine_type(const Type_context*)
+Bound_method_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
Named_object* fn = this->method_->named_object();
Function_type* fntype;
@@ -7873,11 +8080,11 @@ Bound_method_expression::do_determine_type(const Type_context*)
else
fntype = NULL;
if (fntype == NULL || !fntype->is_method())
- this->expr_->determine_type_no_context();
+ this->expr_->determine_type_no_context(gogo);
else
{
Type_context subcontext(fntype->receiver()->type(), false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
}
@@ -8178,7 +8385,7 @@ Bound_method_expression::do_flatten(Gogo* gogo, Named_object*,
if (nil_check != NULL)
{
- Expression* crash = Runtime::make_call(Runtime::PANIC_MEM, loc, 0);
+ Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
// Fix the type of the conditional expression by pretending to
// evaluate to RET either way through the conditional.
crash = Expression::make_compound(crash, ret, loc);
@@ -8219,6 +8426,287 @@ Expression::make_bound_method(Expression* expr, const Method* method,
return new Bound_method_expression(expr, method, function, location);
}
+// A general selector. This is a Parser_expression for LEFT.NAME. It
+// is lowered after we know the type of the left hand side.
+
+class Selector_expression : public Parser_expression
+{
+ public:
+ Selector_expression(Expression* left, const std::string& name,
+ Location location)
+ : Parser_expression(EXPRESSION_SELECTOR, location),
+ left_(left), name_(name)
+ { }
+
+ protected:
+ int
+ do_traverse(Traverse* traverse)
+ { return Expression::traverse(&this->left_, traverse); }
+
+ Expression*
+ do_lower(Gogo*, Named_object*, Statement_inserter*, int);
+
+ Expression*
+ do_copy()
+ {
+ return new Selector_expression(this->left_->copy(), this->name_,
+ this->location());
+ }
+
+ void
+ do_dump_expression(Ast_dump_context* ast_dump_context) const;
+
+ private:
+ Expression*
+ lower_method_expression(Gogo*);
+
+ // The expression on the left hand side.
+ Expression* left_;
+ // The name on the right hand side.
+ std::string name_;
+};
+
+// Lower a selector expression once we know the real type of the left
+// hand side.
+
+Expression*
+Selector_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*,
+ int)
+{
+ Expression* left = this->left_;
+ if (left->is_type_expression())
+ return this->lower_method_expression(gogo);
+ return Type::bind_field_or_method(gogo, left->type(), left, this->name_,
+ this->location());
+}
+
+// Lower a method expression T.M or (*T).M. We turn this into a
+// function literal.
+
+Expression*
+Selector_expression::lower_method_expression(Gogo* gogo)
+{
+ Location location = this->location();
+ Type* left_type = this->left_->type();
+ Type* type = left_type;
+ const std::string& name(this->name_);
+
+ bool is_pointer;
+ if (type->points_to() == NULL)
+ is_pointer = false;
+ else
+ {
+ is_pointer = true;
+ type = type->points_to();
+ }
+
+ Named_type* nt = type->named_type();
+ Struct_type* st = type->struct_type();
+ bool is_ambiguous;
+ Method* method = NULL;
+ if (nt != NULL)
+ method = nt->method_function(name, &is_ambiguous);
+ else if (st != NULL)
+ method = st->method_function(name, &is_ambiguous);
+ const Typed_identifier* imethod = NULL;
+ if (method == NULL && !is_pointer)
+ {
+ Interface_type* it = type->interface_type();
+ if (it != NULL)
+ imethod = it->find_method(name);
+ }
+
+ if ((method == NULL && imethod == NULL)
+ || (left_type->named_type() != NULL && left_type->points_to() != NULL))
+ {
+ if (nt != NULL)
+ {
+ if (!is_ambiguous)
+ go_error_at(location, "type %<%s%s%> has no method %<%s%>",
+ is_pointer ? "*" : "",
+ nt->message_name().c_str(),
+ Gogo::message_name(name).c_str());
+ else
+ go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
+ Gogo::message_name(name).c_str(),
+ is_pointer ? "*" : "",
+ nt->message_name().c_str());
+ }
+ else
+ {
+ if (!is_ambiguous)
+ go_error_at(location, "type has no method %<%s%>",
+ Gogo::message_name(name).c_str());
+ else
+ go_error_at(location, "method %<%s%> is ambiguous",
+ Gogo::message_name(name).c_str());
+ }
+ return Expression::make_error(location);
+ }
+
+ if (method != NULL && !is_pointer && !method->is_value_method())
+ {
+ go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
+ nt->message_name().c_str(),
+ Gogo::message_name(name).c_str());
+ return Expression::make_error(location);
+ }
+
+ // Build a new function type in which the receiver becomes the first
+ // argument.
+ Function_type* method_type;
+ if (method != NULL)
+ {
+ method_type = method->type();
+ go_assert(method_type->is_method());
+ }
+ else
+ {
+ method_type = imethod->type()->function_type();
+ go_assert(method_type != NULL && !method_type->is_method());
+ }
+
+ const char* const receiver_name = "$this";
+ Typed_identifier_list* parameters = new Typed_identifier_list();
+ parameters->push_back(Typed_identifier(receiver_name, this->left_->type(),
+ location));
+
+ const Typed_identifier_list* method_parameters = method_type->parameters();
+ if (method_parameters != NULL)
+ {
+ int i = 0;
+ for (Typed_identifier_list::const_iterator p = method_parameters->begin();
+ p != method_parameters->end();
+ ++p, ++i)
+ {
+ if (!p->name().empty() && !Gogo::is_sink_name(p->name()))
+ parameters->push_back(*p);
+ else
+ {
+ char buf[20];
+ snprintf(buf, sizeof buf, "$param%d", i);
+ parameters->push_back(Typed_identifier(buf, p->type(),
+ p->location()));
+ }
+ }
+ }
+
+ const Typed_identifier_list* method_results = method_type->results();
+ Typed_identifier_list* results;
+ if (method_results == NULL)
+ results = NULL;
+ else
+ {
+ results = new Typed_identifier_list();
+ for (Typed_identifier_list::const_iterator p = method_results->begin();
+ p != method_results->end();
+ ++p)
+ results->push_back(*p);
+ }
+
+ Function_type* fntype = Type::make_function_type(NULL, parameters, results,
+ location);
+ if (method_type->is_varargs())
+ fntype->set_is_varargs();
+
+ // We generate methods which always takes a pointer to the receiver
+ // as their first argument. If this is for a pointer type, we can
+ // simply reuse the existing function. We use an internal hack to
+ // get the right type.
+ // FIXME: This optimization is disabled because it doesn't yet work
+ // with function descriptors when the method expression is not
+ // directly called.
+ if (method != NULL && is_pointer && false)
+ {
+ Named_object* mno = (method->needs_stub_method()
+ ? method->stub_object()
+ : method->named_object());
+ Expression* f = Expression::make_func_reference(mno, NULL, location);
+ f = Expression::make_cast(fntype, f, location);
+ Type_conversion_expression* tce =
+ static_cast<Type_conversion_expression*>(f);
+ tce->set_may_convert_function_types();
+ return f;
+ }
+
+ Named_object* no = gogo->start_function(gogo->thunk_name(), fntype, false,
+ location);
+
+ Named_object* vno = gogo->lookup(receiver_name, NULL);
+ go_assert(vno != NULL);
+ Expression* ve = Expression::make_var_reference(vno, location);
+ Expression* bm;
+ if (method != NULL)
+ bm = Type::bind_field_or_method(gogo, type, ve, name, location);
+ else
+ bm = Expression::make_interface_field_reference(ve, name, location);
+
+ // Even though we found the method above, if it has an error type we
+ // may see an error here.
+ if (bm->is_error_expression())
+ {
+ gogo->finish_function(location);
+ return bm;
+ }
+
+ Expression_list* args;
+ if (parameters->size() <= 1)
+ args = NULL;
+ else
+ {
+ args = new Expression_list();
+ Typed_identifier_list::const_iterator p = parameters->begin();
+ ++p;
+ for (; p != parameters->end(); ++p)
+ {
+ vno = gogo->lookup(p->name(), NULL);
+ go_assert(vno != NULL);
+ args->push_back(Expression::make_var_reference(vno, location));
+ }
+ }
+
+ gogo->start_block(location);
+
+ Call_expression* call = Expression::make_call(bm, args,
+ method_type->is_varargs(),
+ location);
+
+ Statement* s = Statement::make_return_from_call(call, location);
+ gogo->add_statement(s);
+
+ Block* b = gogo->finish_block(location);
+
+ gogo->add_block(b, location);
+
+ // Lower the call in case there are multiple results.
+ gogo->lower_block(no, b);
+ gogo->flatten_block(no, b);
+
+ gogo->finish_function(location);
+
+ return Expression::make_func_reference(no, NULL, location);
+}
+
+// Dump the ast for a selector expression.
+
+void
+Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
+ const
+{
+ ast_dump_context->dump_expression(this->left_);
+ ast_dump_context->ostream() << ".";
+ ast_dump_context->ostream() << this->name_;
+}
+
+// Make a selector expression.
+
+Expression*
+Expression::make_selector(Expression* left, const std::string& name,
+ Location location)
+{
+ return new Selector_expression(left, name, location);
+}
+
// Class Builtin_call_expression. This is used for a call to a
// builtin function.
@@ -8310,7 +8798,7 @@ Builtin_call_expression::do_set_recover_arg(Expression* arg)
// specific expressions. We also convert to a constant if we can.
Expression*
-Builtin_call_expression::do_lower(Gogo*, Named_object* function,
+Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
Statement_inserter* inserter, int)
{
if (this->is_error_expression())
@@ -8388,7 +8876,7 @@ Builtin_call_expression::do_lower(Gogo*, Named_object* function,
break;
case BUILTIN_MAKE:
- return this->lower_make(inserter);
+ return this->lower_make(gogo, inserter);
case BUILTIN_RECOVER:
if (function != NULL)
@@ -8531,7 +9019,7 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
Expression::make_slice_info(arg2, SLICE_INFO_VALUE_POINTER, loc);
Expression* ls =
Expression::make_slice_info(arg2, SLICE_INFO_LENGTH, loc);
- ret = Runtime::make_call(Runtime::TYPEDSLICECOPY, loc,
+ ret = Runtime::make_call(gogo, Runtime::TYPEDSLICECOPY, loc,
5, td, pd, ld, ps, ls);
}
else
@@ -8587,7 +9075,9 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
: Expression::make_slice_info(arg2,
SLICE_INFO_VALUE_POINTER,
loc));
- Expression* call = Runtime::make_call(Runtime::BUILTIN_MEMMOVE, loc, 3,
+ Expression* call = Runtime::make_call(gogo,
+ Runtime::BUILTIN_MEMMOVE,
+ loc, 3,
p1, p2, sz);
// n is the return value of copy
@@ -8717,7 +9207,7 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
}
}
- return Runtime::make_call(code, loc, 3, e1, e2, e3);
+ return Runtime::make_call(gogo, code, loc, 3, e1, e2, e3);
}
case BUILTIN_ADD:
@@ -8781,7 +9271,7 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
: Runtime::UNSAFESLICE64);
Expression* td =
Expression::make_type_descriptor(ptr->type()->points_to(), loc);
- Expression* check = Runtime::make_call(code, loc, 3,
+ Expression* check = Runtime::make_call(gogo, code, loc, 3,
td, ptr, len);
if (ptr_temp == NULL)
@@ -8840,7 +9330,7 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
// Lower a make expression.
Expression*
-Builtin_call_expression::lower_make(Statement_inserter* inserter)
+Builtin_call_expression::lower_make(Gogo* gogo, Statement_inserter* inserter)
{
Location loc = this->location();
@@ -8899,7 +9389,7 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
else
{
len_arg = *parg;
- len_arg->determine_type(&int_context);
+ len_arg->determine_type(gogo, &int_context);
if (len_arg->type()->integer_type() == NULL)
{
go_error_at(len_arg->location(), "non-integer len argument in make");
@@ -8919,7 +9409,7 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
if (is_slice && parg != args->end())
{
cap_arg = *parg;
- cap_arg->determine_type(&int_context);
+ cap_arg->determine_type(gogo, &int_context);
if (cap_arg->type()->integer_type() == NULL)
{
go_error_at(cap_arg->location(), "non-integer cap argument in make");
@@ -8982,8 +9472,8 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
Runtime::Function code = Runtime::MAKESLICE;
if (!len_small || !cap_small)
code = Runtime::MAKESLICE64;
- Expression* mem = Runtime::make_call(code, loc, 3, type_arg, len_arg,
- cap_arg);
+ Expression* mem = Runtime::make_call(gogo, code, loc, 3,
+ type_arg, len_arg, cap_arg);
mem = Expression::make_unsafe_cast(Type::make_pointer_type(et), mem,
loc);
Type* int_type = Type::lookup_integer_type("int");
@@ -8995,7 +9485,7 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
{
Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
if (!len_small)
- call = Runtime::make_call(Runtime::MAKEMAP64, loc, 3, type_arg,
+ call = Runtime::make_call(gogo, Runtime::MAKEMAP64, loc, 3, type_arg,
len_arg,
Expression::make_nil(loc));
else
@@ -9003,9 +9493,9 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
if (len_arg->numeric_constant_value(&nclen)
&& nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
&& vlen <= Map_type::bucket_size)
- call = Runtime::make_call(Runtime::MAKEMAP_SMALL, loc, 0);
+ call = Runtime::make_call(gogo, Runtime::MAKEMAP_SMALL, loc, 0);
else
- call = Runtime::make_call(Runtime::MAKEMAP, loc, 3, type_arg,
+ call = Runtime::make_call(gogo, Runtime::MAKEMAP, loc, 3, type_arg,
len_arg,
Expression::make_nil(loc));
}
@@ -9016,7 +9506,7 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
Runtime::Function code = Runtime::MAKECHAN;
if (!len_small)
code = Runtime::MAKECHAN64;
- call = Runtime::make_call(code, loc, 2, type_arg, len_arg);
+ call = Runtime::make_call(gogo, code, loc, 2, type_arg, len_arg);
}
else
go_unreachable();
@@ -9126,7 +9616,8 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
loc);
len2 = Expression::make_temporary_reference(l2tmp, loc);
Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc);
- Expression* check = Runtime::make_call(Runtime::CHECK_MAKE_SLICE,
+ Expression* check = Runtime::make_call(gogo,
+ Runtime::CHECK_MAKE_SLICE,
loc, 3, elem, len2, cap2);
gogo->lower_expression(function, inserter, &check);
gogo->flatten_expression(function, inserter, &check);
@@ -9222,7 +9713,7 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
Expression* a3 = Expression::make_temporary_reference(l1tmp, loc);
Expression* a4 = Expression::make_temporary_reference(c1tmp, loc);
Expression* a5 = Expression::make_temporary_reference(ntmp, loc);
- Expression* call = Runtime::make_call(Runtime::GROWSLICE, loc, 5,
+ Expression* call = Runtime::make_call(gogo, Runtime::GROWSLICE, loc, 5,
a1, a2, a3, a4, a5);
call = Expression::make_unsafe_cast(slice_type, call, loc);
@@ -9292,13 +9783,14 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
a2 = Expression::make_binary(OPERATOR_MULT, a2, ref, loc);
if (element_type->has_pointer())
- call = Runtime::make_call(Runtime::MEMCLRHASPTR, loc, 2, a1, a2);
+ call = Runtime::make_call(gogo, Runtime::MEMCLRHASPTR, loc, 2,
+ a1, a2);
else
{
Type* int32_type = Type::lookup_integer_type("int32");
zero = Expression::make_integer_ul(0, int32_type, loc);
- call = Runtime::make_call(Runtime::BUILTIN_MEMSET, loc, 3, a1,
- zero, a2);
+ call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMSET, loc, 3,
+ a1, zero, a2);
}
if (element_type->has_pointer())
@@ -9358,7 +9850,7 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
a3 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
a3 = Expression::make_binary(OPERATOR_MULT, a3, ref, loc);
- call = Runtime::make_call(Runtime::BUILTIN_MEMMOVE, loc, 3,
+ call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMMOVE, loc, 3,
a1, a2, a3);
}
}
@@ -9669,10 +10161,51 @@ Builtin_call_expression::do_is_constant() const
return false;
}
+// Return whether a builtin call is untyped. Most builtin functions
+// have a known type, but complex, real, and imag can be untyped.
+
+bool
+Builtin_call_expression::do_is_untyped(Type** ptype) const
+{
+ if (this->is_error_expression())
+ return false;
+
+ switch (this->code_)
+ {
+ default:
+ return false;
+
+ case BUILTIN_COMPLEX:
+ {
+ const Expression_list* args = this->args();
+ if (args == NULL || args->size() != 2)
+ return false;
+ Type* dummy;
+ if (!args->front()->is_untyped(&dummy)
+ || !args->back()->is_untyped(&dummy))
+ return false;
+ *ptype = Type::make_abstract_complex_type();
+ return true;
+ }
+
+ case BUILTIN_REAL:
+ case BUILTIN_IMAG:
+ {
+ Expression* arg = this->one_arg();
+ if (arg == NULL)
+ return false;
+ if (!arg->is_untyped(ptype))
+ return false;
+ *ptype = Type::make_abstract_float_type();
+ return true;
+ }
+ }
+}
+
// Return a numeric constant if possible.
bool
-Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
+Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc)
{
if (this->code_ == BUILTIN_LEN
|| this->code_ == BUILTIN_CAP)
@@ -9709,7 +10242,8 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
// We may be replacing this expression with a constant
// during lowering, so verify the type to report any errors.
// It's OK to verify an array type more than once.
- arg_type->verify();
+ // FIXME: Remove this reference to go_get_gogo.
+ arg_type->verify(go_get_gogo());
if (!arg_type->is_error())
{
Expression* e = arg_type->array_type()->length();
@@ -10048,12 +10582,13 @@ Builtin_call_expression::do_type()
// Determine the type.
void
-Builtin_call_expression::do_determine_type(const Type_context* context)
+Builtin_call_expression::do_determine_type(Gogo* gogo,
+ const Type_context* context)
{
if (!this->determining_types())
return;
- this->fn()->determine_type_no_context();
+ this->fn()->determine_type_no_context(gogo);
const Expression_list* args = this->args();
@@ -10113,16 +10648,16 @@ Builtin_call_expression::do_determine_type(const Type_context* context)
if (args != NULL && args->size() == 2)
{
if (this->code_ == BUILTIN_SLICE)
- args->front()->determine_type_no_context();
+ args->front()->determine_type_no_context(gogo);
else
{
Type* pointer = Type::make_pointer_type(Type::make_void_type());
Type_context subcontext(pointer, false);
- args->front()->determine_type(&subcontext);
+ args->front()->determine_type(gogo, &subcontext);
}
Type* int_type = Type::lookup_integer_type("int");
Type_context subcontext(int_type, false);
- args->back()->determine_type(&subcontext);
+ args->back()->determine_type(gogo, &subcontext);
return;
}
is_print = false;
@@ -10183,7 +10718,7 @@ Builtin_call_expression::do_determine_type(const Type_context* context)
}
}
- (*pa)->determine_type(&subcontext);
+ (*pa)->determine_type(gogo, &subcontext);
if (trailing_arg_types != NULL)
{
@@ -10759,7 +11294,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
{
const bool is_ln = this->code_ == BUILTIN_PRINTLN;
- Expression* print_stmts = Runtime::make_call(Runtime::PRINTLOCK,
+ Expression* print_stmts = Runtime::make_call(gogo, Runtime::PRINTLOCK,
location, 0);
const Expression_list* call_args = this->args();
@@ -10772,7 +11307,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
if (is_ln && p != call_args->begin())
{
Expression* print_space =
- Runtime::make_call(Runtime::PRINTSP, location, 0);
+ Runtime::make_call(gogo, Runtime::PRINTSP, location, 0);
print_stmts =
Expression::make_compound(print_stmts, print_space,
@@ -10840,7 +11375,8 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
return context->backend()->error_expression();
}
- Expression* call = Runtime::make_call(code, location, 1, arg);
+ Expression* call = Runtime::make_call(gogo, code, location, 1,
+ arg);
print_stmts = Expression::make_compound(print_stmts, call,
location);
}
@@ -10849,12 +11385,12 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
if (is_ln)
{
Expression* print_nl =
- Runtime::make_call(Runtime::PRINTNL, location, 0);
+ Runtime::make_call(gogo, Runtime::PRINTNL, location, 0);
print_stmts = Expression::make_compound(print_stmts, print_nl,
location);
}
- Expression* unlock = Runtime::make_call(Runtime::PRINTUNLOCK,
+ Expression* unlock = Runtime::make_call(gogo, Runtime::PRINTUNLOCK,
location, 0);
print_stmts = Expression::make_compound(print_stmts, unlock, location);
@@ -10871,7 +11407,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
arg = Expression::convert_for_assignment(gogo, empty, arg, location);
Expression* panic =
- Runtime::make_call(Runtime::GOPANIC, location, 1, arg);
+ Runtime::make_call(gogo, Runtime::GOPANIC, location, 1, arg);
return panic->get_backend(context);
}
@@ -10891,7 +11427,8 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
// We need to handle a deferred call to recover specially,
// because it changes whether it can recover a panic or not.
// See test7 in test/recover1.go.
- Expression* recover = Runtime::make_call((this->is_deferred()
+ Expression* recover = Runtime::make_call(gogo,
+ (this->is_deferred()
? Runtime::DEFERREDRECOVER
: Runtime::GORECOVER),
location, 0);
@@ -10905,7 +11442,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
const Expression_list* args = this->args();
go_assert(args != NULL && args->size() == 1);
Expression* arg = args->front();
- Expression* close = Runtime::make_call(Runtime::CLOSE, location,
+ Expression* close = Runtime::make_call(gogo, Runtime::CLOSE, location,
1, arg);
return close->get_backend(context);
}
@@ -10974,37 +11511,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
void
Builtin_call_expression::do_export(Export_function_body* efb) const
{
- Numeric_constant nc;
- if (this->numeric_constant_value(&nc))
- {
- if (nc.is_int())
- {
- mpz_t val;
- nc.get_int(&val);
- Integer_expression::export_integer(efb, val);
- mpz_clear(val);
- }
- else if (nc.is_float())
- {
- mpfr_t fval;
- nc.get_float(&fval);
- Float_expression::export_float(efb, fval);
- mpfr_clear(fval);
- }
- else if (nc.is_complex())
- {
- mpc_t cval;
- nc.get_complex(&cval);
- Complex_expression::export_complex(efb, cval);
- mpc_clear(cval);
- }
- else
- go_unreachable();
-
- // A trailing space lets us reliably identify the end of the number.
- efb->write_c_string(" ");
- }
- else if (this->code_ == BUILTIN_ADD || this->code_ == BUILTIN_SLICE)
+ if (this->code_ == BUILTIN_ADD || this->code_ == BUILTIN_SLICE)
{
char buf[50];
snprintf(buf, sizeof buf, "<p%d>%s", efb->unsafe_package_index(),
@@ -11683,7 +12190,7 @@ Call_expression::intrinsify(Gogo* gogo,
{
Expression* arg = Expression::make_integer_ul(0, uint32_type, loc);
Expression* call =
- Runtime::make_call(Runtime::BUILTIN_RETURN_ADDRESS, loc,
+ Runtime::make_call(gogo, Runtime::BUILTIN_RETURN_ADDRESS, loc,
1, arg);
// The builtin functions return void*, but the Go functions return uintptr.
return Expression::make_cast(uintptr_type, call, loc);
@@ -11693,7 +12200,7 @@ Call_expression::intrinsify(Gogo* gogo,
{
Expression* call =
- Runtime::make_call(Runtime::BUILTIN_DWARF_CFA, loc, 0);
+ Runtime::make_call(gogo, Runtime::BUILTIN_DWARF_CFA, loc, 0);
// The builtin functions return void*, but the Go functions return uintptr.
return Expression::make_cast(uintptr_type, call, loc);
}
@@ -11719,7 +12226,7 @@ Call_expression::intrinsify(Gogo* gogo,
else
go_unreachable();
Expression* arg = this->args_->front();
- Expression* call = Runtime::make_call(code, loc, 1, arg);
+ Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
if (name == "ReverseBytes")
return Expression::make_cast(uint_type, call, loc);
return call;
@@ -11734,7 +12241,8 @@ Call_expression::intrinsify(Gogo* gogo,
unsigned long mask = (name == "TrailingZeros8" ? 0x100 : 0x10000);
Expression* c = Expression::make_integer_ul(mask, uint32_type, loc);
arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
- Expression* call = Runtime::make_call(Runtime::BUILTIN_CTZ, loc, 1, arg);
+ Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
+ loc, 1, arg);
return Expression::make_cast(int_type, call, loc);
}
else if ((name == "TrailingZeros32"
@@ -11752,7 +12260,8 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
- Expression* call = Runtime::make_call(Runtime::BUILTIN_CTZ, loc, 1, arg->copy());
+ Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
+ loc, 1, arg->copy());
call = Expression::make_cast(int_type, call, loc);
return Expression::make_conditional(cmp, c32, call, loc);
}
@@ -11771,7 +12280,8 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
- Expression* call = Runtime::make_call(Runtime::BUILTIN_CTZLL, loc, 1, arg->copy());
+ Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZLL,
+ loc, 1, arg->copy());
call = Expression::make_cast(int_type, call, loc);
return Expression::make_conditional(cmp, c64, call, loc);
}
@@ -11791,7 +12301,8 @@ Call_expression::intrinsify(Gogo* gogo,
((name == "LeadingZeros8" || name == "Len8") ? 0xffffff : 0xffff);
c = Expression::make_integer_ul(mask, uint32_type, loc);
arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
- Expression* call = Runtime::make_call(Runtime::BUILTIN_CLZ, loc, 1, arg);
+ Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
+ loc, 1, arg);
call = Expression::make_cast(int_type, call, loc);
// len = width - clz
if (name == "Len8")
@@ -11821,7 +12332,8 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
- Expression* call = Runtime::make_call(Runtime::BUILTIN_CLZ, loc, 1, arg->copy());
+ Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
+ loc, 1, arg->copy());
call = Expression::make_cast(int_type, call, loc);
Expression* cond = Expression::make_conditional(cmp, c32, call, loc);
// len = 32 - clz
@@ -11844,7 +12356,8 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
- Expression* call = Runtime::make_call(Runtime::BUILTIN_CLZLL, loc, 1, arg->copy());
+ Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZLL,
+ loc, 1, arg->copy());
call = Expression::make_cast(int_type, call, loc);
Expression* cond = Expression::make_conditional(cmp, c64, call, loc);
// len = 64 - clz
@@ -11865,7 +12378,7 @@ Call_expression::intrinsify(Gogo* gogo,
else
code = Runtime::BUILTIN_POPCOUNT;
Expression* arg = this->args_->front();
- Expression* call = Runtime::make_call(code, loc, 1, arg);
+ Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
return Expression::make_cast(int_type, call, loc);
}
}
@@ -12069,7 +12582,7 @@ Call_expression::intrinsify(Gogo* gogo,
go_unreachable();
Expression* a1 = this->args_->front();
Expression* a2 = Expression::make_integer_ul(memorder, int32_type, loc);
- Expression* call = Runtime::make_call(code, loc, 2, a1, a2);
+ Expression* call = Runtime::make_call(gogo, code, loc, 2, a1, a2);
return Expression::make_unsafe_cast(res_type, call, loc);
}
@@ -12110,7 +12623,7 @@ Call_expression::intrinsify(Gogo* gogo,
else
go_unreachable();
Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
- return Runtime::make_call(code, loc, 3, a1, a2, a3);
+ return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
}
if ((name == "Xchg" || name == "Xchg64" || name == "Xchguintptr"
@@ -12154,7 +12667,7 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* a1 = this->args_->at(0);
Expression* a2 = this->args_->at(1);
Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
- Expression* call = Runtime::make_call(code, loc, 3, a1, a2, a3);
+ Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
return Expression::make_cast(res_type, call, loc);
}
@@ -12208,7 +12721,7 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* a4 = Expression::make_boolean(false, loc);
Expression* a5 = Expression::make_integer_ul(memorder, int32_type, loc);
Expression* a6 = Expression::make_integer_ul(__ATOMIC_RELAXED, int32_type, loc);
- return Runtime::make_call(code, loc, 6, a1, a2, a3, a4, a5, a6);
+ return Runtime::make_call(gogo, code, loc, 6, a1, a2, a3, a4, a5, a6);
}
if ((name == "Xadd" || name == "Xadd64" || name == "Xaddint64"
@@ -12252,7 +12765,7 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* a1 = this->args_->at(0);
Expression* a2 = this->args_->at(1);
Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
- Expression* call = Runtime::make_call(code, loc, 3, a1, a2, a3);
+ Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
return Expression::make_cast(res_type, call, loc);
}
@@ -12269,7 +12782,7 @@ Call_expression::intrinsify(Gogo* gogo,
Expression* a1 = this->args_->at(0);
Expression* a2 = this->args_->at(1);
Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
- return Runtime::make_call(code, loc, 3, a1, a2, a3);
+ return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
}
}
else if (package == "internal/abi"
@@ -12513,12 +13026,12 @@ Call_expression::do_type()
// parameter types to set the types of the arguments.
void
-Call_expression::do_determine_type(const Type_context* context)
+Call_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
if (!this->determining_types())
return;
- this->fn_->determine_type_no_context();
+ this->fn_->determine_type_no_context(gogo);
Function_type* fntype = this->get_function_type();
const Typed_identifier_list* parameters = NULL;
if (fntype != NULL)
@@ -12545,7 +13058,7 @@ Call_expression::do_determine_type(const Type_context* context)
if (rtype->points_to() == NULL)
rtype = Type::make_pointer_type(rtype);
Type_context subcontext(rtype, false);
- (*pa)->determine_type(&subcontext);
+ (*pa)->determine_type(gogo, &subcontext);
continue;
}
}
@@ -12553,11 +13066,11 @@ Call_expression::do_determine_type(const Type_context* context)
if (parameters != NULL && pt != parameters->end())
{
Type_context subcontext(pt->type(), false);
- (*pa)->determine_type(&subcontext);
+ (*pa)->determine_type(gogo, &subcontext);
++pt;
}
else
- (*pa)->determine_type_no_context();
+ (*pa)->determine_type_no_context(gogo);
}
}
@@ -13110,9 +13623,9 @@ Call_result_expression::do_check_types(Gogo*)
// needs to pass down to the caller.
void
-Call_result_expression::do_determine_type(const Type_context*)
+Call_result_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->call_->determine_type_no_context();
+ this->call_->determine_type_no_context(gogo);
}
// Return the backend representation. We just refer to the temporary set by the
@@ -13358,16 +13871,16 @@ Array_index_expression::do_type()
// Set the type of an array index.
void
-Array_index_expression::do_determine_type(const Type_context*)
+Array_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->array_->determine_type_no_context();
+ this->array_->determine_type_no_context(gogo);
Type_context index_context(Type::lookup_integer_type("int"), false);
- this->start_->determine_type(&index_context);
+ this->start_->determine_type(gogo, &index_context);
if (this->end_ != NULL)
- this->end_->determine_type(&index_context);
+ this->end_->determine_type(gogo, &index_context);
if (this->cap_ != NULL)
- this->cap_->determine_type(&index_context);
+ this->cap_->determine_type(gogo, &index_context);
}
// Check types of an array index.
@@ -13619,14 +14132,14 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
if (cap != NULL)
{
if (array_type->is_slice_type())
- Expression::check_bounds(cap, OPERATOR_LE, scap,
+ Expression::check_bounds(gogo, cap, OPERATOR_LE, scap,
Runtime::PANIC_SLICE3_ACAP,
Runtime::PANIC_SLICE3_ACAP_U,
Runtime::PANIC_EXTEND_SLICE3_ACAP,
Runtime::PANIC_EXTEND_SLICE3_ACAP_U,
inserter, loc);
else
- Expression::check_bounds(cap, OPERATOR_LE, len,
+ Expression::check_bounds(gogo, cap, OPERATOR_LE, len,
Runtime::PANIC_SLICE3_ALEN,
Runtime::PANIC_SLICE3_ALEN_U,
Runtime::PANIC_EXTEND_SLICE3_ALEN,
@@ -13636,7 +14149,7 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
Expression* start_bound = cap;
if (end != NULL && !end->is_nil_expression())
{
- Expression::check_bounds(end, OPERATOR_LE, cap,
+ Expression::check_bounds(gogo, end, OPERATOR_LE, cap,
Runtime::PANIC_SLICE3_B,
Runtime::PANIC_SLICE3_B_U,
Runtime::PANIC_EXTEND_SLICE3_B,
@@ -13645,7 +14158,7 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
start_bound = end;
}
- Expression::check_bounds(start, OPERATOR_LE, start_bound,
+ Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
Runtime::PANIC_SLICE3_C,
Runtime::PANIC_SLICE3_C_U,
Runtime::PANIC_EXTEND_SLICE3_C,
@@ -13655,21 +14168,21 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
else if (end != NULL && !end->is_nil_expression())
{
if (array_type->is_slice_type())
- Expression::check_bounds(end, OPERATOR_LE, scap,
+ Expression::check_bounds(gogo, end, OPERATOR_LE, scap,
Runtime::PANIC_SLICE_ACAP,
Runtime::PANIC_SLICE_ACAP_U,
Runtime::PANIC_EXTEND_SLICE_ACAP,
Runtime::PANIC_EXTEND_SLICE_ACAP_U,
inserter, loc);
else
- Expression::check_bounds(end, OPERATOR_LE, len,
+ Expression::check_bounds(gogo, end, OPERATOR_LE, len,
Runtime::PANIC_SLICE_ALEN,
Runtime::PANIC_SLICE_ALEN_U,
Runtime::PANIC_EXTEND_SLICE_ALEN,
Runtime::PANIC_EXTEND_SLICE_ALEN_U,
inserter, loc);
- Expression::check_bounds(start, OPERATOR_LE, end,
+ Expression::check_bounds(gogo, start, OPERATOR_LE, end,
Runtime::PANIC_SLICE_B,
Runtime::PANIC_SLICE_B_U,
Runtime::PANIC_EXTEND_SLICE_B,
@@ -13683,7 +14196,7 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
start_bound = scap;
else
start_bound = len;
- Expression::check_bounds(start, OPERATOR_LE, start_bound,
+ Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
Runtime::PANIC_SLICE_B,
Runtime::PANIC_SLICE_B_U,
Runtime::PANIC_EXTEND_SLICE_B,
@@ -13691,7 +14204,7 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
inserter, loc);
}
else
- Expression::check_bounds(start, OPERATOR_LT, len,
+ Expression::check_bounds(gogo, start, OPERATOR_LT, len,
Runtime::PANIC_INDEX,
Runtime::PANIC_INDEX_U,
Runtime::PANIC_EXTEND_INDEX,
@@ -13924,7 +14437,7 @@ String_index_expression::do_traverse(Traverse* traverse)
}
Expression*
-String_index_expression::do_flatten(Gogo*, Named_object*,
+String_index_expression::do_flatten(Gogo* gogo, Named_object*,
Statement_inserter* inserter)
{
if (this->is_flattened_)
@@ -13986,13 +14499,13 @@ String_index_expression::do_flatten(Gogo*, Named_object*,
if (end != NULL && !end->is_nil_expression())
{
- Expression::check_bounds(end, OPERATOR_LE, len,
+ Expression::check_bounds(gogo, end, OPERATOR_LE, len,
Runtime::PANIC_SLICE_ALEN,
Runtime::PANIC_SLICE_ALEN_U,
Runtime::PANIC_EXTEND_SLICE_ALEN,
Runtime::PANIC_EXTEND_SLICE_ALEN_U,
inserter, loc);
- Expression::check_bounds(start, OPERATOR_LE, end,
+ Expression::check_bounds(gogo, start, OPERATOR_LE, end,
Runtime::PANIC_SLICE_B,
Runtime::PANIC_SLICE_B_U,
Runtime::PANIC_EXTEND_SLICE_B,
@@ -14000,14 +14513,14 @@ String_index_expression::do_flatten(Gogo*, Named_object*,
inserter, loc);
}
else if (end != NULL)
- Expression::check_bounds(start, OPERATOR_LE, len,
+ Expression::check_bounds(gogo, start, OPERATOR_LE, len,
Runtime::PANIC_SLICE_B,
Runtime::PANIC_SLICE_B_U,
Runtime::PANIC_EXTEND_SLICE_B,
Runtime::PANIC_EXTEND_SLICE_B_U,
inserter, loc);
else
- Expression::check_bounds(start, OPERATOR_LT, len,
+ Expression::check_bounds(gogo, start, OPERATOR_LT, len,
Runtime::PANIC_INDEX,
Runtime::PANIC_INDEX_U,
Runtime::PANIC_EXTEND_INDEX,
@@ -14031,14 +14544,14 @@ String_index_expression::do_type()
// Determine the type of a string index.
void
-String_index_expression::do_determine_type(const Type_context*)
+String_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->string_->determine_type_no_context();
+ this->string_->determine_type_no_context(gogo);
Type_context index_context(Type::lookup_integer_type("int"), false);
- this->start_->determine_type(&index_context);
+ this->start_->determine_type(gogo, &index_context);
if (this->end_ != NULL)
- this->end_->determine_type(&index_context);
+ this->end_->determine_type(gogo, &index_context);
}
// Check types of a string index.
@@ -14331,13 +14844,13 @@ Map_index_expression::do_type()
// Fix the type of a map index.
void
-Map_index_expression::do_determine_type(const Type_context*)
+Map_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->map_->determine_type_no_context();
+ this->map_->determine_type_no_context(gogo);
Map_type* mt = this->get_map_type();
Type* key_type = mt == NULL ? NULL : mt->key_type();
Type_context subcontext(key_type, false);
- this->index_->determine_type(&subcontext);
+ this->index_->determine_type(gogo, &subcontext);
}
// Check types of a map index.
@@ -14463,11 +14976,11 @@ Map_index_expression::get_value_pointer(Gogo* gogo)
code = Runtime::MAPACCESS1;
break;
}
- map_index = Runtime::make_call(code, loc, 3,
+ map_index = Runtime::make_call(gogo, code, loc, 3,
type_expr, map_ref, key);
}
else
- map_index = Runtime::make_call(Runtime::MAPACCESS1_FAT, loc, 4,
+ map_index = Runtime::make_call(gogo, Runtime::MAPACCESS1_FAT, loc, 4,
type_expr, map_ref, index_ptr, zero);
Type* val_type = type->val_type();
@@ -14601,7 +15114,7 @@ Field_reference_expression::do_lower(Gogo* gogo, Named_object* function,
e = Expression::make_var_reference(no, loc);
e = Expression::make_unary(OPERATOR_AND, e, loc);
- Expression* call = Runtime::make_call(Runtime::FIELDTRACK, loc, 1, e);
+ Expression* call = Runtime::make_call(gogo, Runtime::FIELDTRACK, loc, 1, e);
gogo->lower_expression(function, inserter, &call);
inserter->insert(Statement::make_statement(call, false));
@@ -14770,9 +15283,10 @@ Interface_field_reference_expression::do_type()
// Determine types.
void
-Interface_field_reference_expression::do_determine_type(const Type_context*)
+Interface_field_reference_expression::do_determine_type(Gogo* gogo,
+ const Type_context*)
{
- this->expr_->determine_type_no_context();
+ this->expr_->determine_type_no_context(gogo);
}
// Check the types for an interface field reference.
@@ -14999,7 +15513,7 @@ Interface_field_reference_expression::do_get_backend(Translate_context* context)
Expression::make_nil(loc), loc);
Bexpression* bnil_check = nil_check->get_backend(context);
- Expression* crash = Runtime::make_call(Runtime::PANIC_MEM, loc, 0);
+ Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
Bexpression* bcrash = crash->get_backend(context);
Bfunction* bfn = context->function()->func_value()->get_decl();
@@ -15032,287 +15546,6 @@ Expression::make_interface_field_reference(Expression* expr,
return new Interface_field_reference_expression(expr, field, location);
}
-// A general selector. This is a Parser_expression for LEFT.NAME. It
-// is lowered after we know the type of the left hand side.
-
-class Selector_expression : public Parser_expression
-{
- public:
- Selector_expression(Expression* left, const std::string& name,
- Location location)
- : Parser_expression(EXPRESSION_SELECTOR, location),
- left_(left), name_(name)
- { }
-
- protected:
- int
- do_traverse(Traverse* traverse)
- { return Expression::traverse(&this->left_, traverse); }
-
- Expression*
- do_lower(Gogo*, Named_object*, Statement_inserter*, int);
-
- Expression*
- do_copy()
- {
- return new Selector_expression(this->left_->copy(), this->name_,
- this->location());
- }
-
- void
- do_dump_expression(Ast_dump_context* ast_dump_context) const;
-
- private:
- Expression*
- lower_method_expression(Gogo*);
-
- // The expression on the left hand side.
- Expression* left_;
- // The name on the right hand side.
- std::string name_;
-};
-
-// Lower a selector expression once we know the real type of the left
-// hand side.
-
-Expression*
-Selector_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*,
- int)
-{
- Expression* left = this->left_;
- if (left->is_type_expression())
- return this->lower_method_expression(gogo);
- return Type::bind_field_or_method(gogo, left->type(), left, this->name_,
- this->location());
-}
-
-// Lower a method expression T.M or (*T).M. We turn this into a
-// function literal.
-
-Expression*
-Selector_expression::lower_method_expression(Gogo* gogo)
-{
- Location location = this->location();
- Type* left_type = this->left_->type();
- Type* type = left_type;
- const std::string& name(this->name_);
-
- bool is_pointer;
- if (type->points_to() == NULL)
- is_pointer = false;
- else
- {
- is_pointer = true;
- type = type->points_to();
- }
-
- Named_type* nt = type->named_type();
- Struct_type* st = type->struct_type();
- bool is_ambiguous;
- Method* method = NULL;
- if (nt != NULL)
- method = nt->method_function(name, &is_ambiguous);
- else if (st != NULL)
- method = st->method_function(name, &is_ambiguous);
- const Typed_identifier* imethod = NULL;
- if (method == NULL && !is_pointer)
- {
- Interface_type* it = type->interface_type();
- if (it != NULL)
- imethod = it->find_method(name);
- }
-
- if ((method == NULL && imethod == NULL)
- || (left_type->named_type() != NULL && left_type->points_to() != NULL))
- {
- if (nt != NULL)
- {
- if (!is_ambiguous)
- go_error_at(location, "type %<%s%s%> has no method %<%s%>",
- is_pointer ? "*" : "",
- nt->message_name().c_str(),
- Gogo::message_name(name).c_str());
- else
- go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
- Gogo::message_name(name).c_str(),
- is_pointer ? "*" : "",
- nt->message_name().c_str());
- }
- else
- {
- if (!is_ambiguous)
- go_error_at(location, "type has no method %<%s%>",
- Gogo::message_name(name).c_str());
- else
- go_error_at(location, "method %<%s%> is ambiguous",
- Gogo::message_name(name).c_str());
- }
- return Expression::make_error(location);
- }
-
- if (method != NULL && !is_pointer && !method->is_value_method())
- {
- go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
- nt->message_name().c_str(),
- Gogo::message_name(name).c_str());
- return Expression::make_error(location);
- }
-
- // Build a new function type in which the receiver becomes the first
- // argument.
- Function_type* method_type;
- if (method != NULL)
- {
- method_type = method->type();
- go_assert(method_type->is_method());
- }
- else
- {
- method_type = imethod->type()->function_type();
- go_assert(method_type != NULL && !method_type->is_method());
- }
-
- const char* const receiver_name = "$this";
- Typed_identifier_list* parameters = new Typed_identifier_list();
- parameters->push_back(Typed_identifier(receiver_name, this->left_->type(),
- location));
-
- const Typed_identifier_list* method_parameters = method_type->parameters();
- if (method_parameters != NULL)
- {
- int i = 0;
- for (Typed_identifier_list::const_iterator p = method_parameters->begin();
- p != method_parameters->end();
- ++p, ++i)
- {
- if (!p->name().empty() && !Gogo::is_sink_name(p->name()))
- parameters->push_back(*p);
- else
- {
- char buf[20];
- snprintf(buf, sizeof buf, "$param%d", i);
- parameters->push_back(Typed_identifier(buf, p->type(),
- p->location()));
- }
- }
- }
-
- const Typed_identifier_list* method_results = method_type->results();
- Typed_identifier_list* results;
- if (method_results == NULL)
- results = NULL;
- else
- {
- results = new Typed_identifier_list();
- for (Typed_identifier_list::const_iterator p = method_results->begin();
- p != method_results->end();
- ++p)
- results->push_back(*p);
- }
-
- Function_type* fntype = Type::make_function_type(NULL, parameters, results,
- location);
- if (method_type->is_varargs())
- fntype->set_is_varargs();
-
- // We generate methods which always takes a pointer to the receiver
- // as their first argument. If this is for a pointer type, we can
- // simply reuse the existing function. We use an internal hack to
- // get the right type.
- // FIXME: This optimization is disabled because it doesn't yet work
- // with function descriptors when the method expression is not
- // directly called.
- if (method != NULL && is_pointer && false)
- {
- Named_object* mno = (method->needs_stub_method()
- ? method->stub_object()
- : method->named_object());
- Expression* f = Expression::make_func_reference(mno, NULL, location);
- f = Expression::make_cast(fntype, f, location);
- Type_conversion_expression* tce =
- static_cast<Type_conversion_expression*>(f);
- tce->set_may_convert_function_types();
- return f;
- }
-
- Named_object* no = gogo->start_function(gogo->thunk_name(), fntype, false,
- location);
-
- Named_object* vno = gogo->lookup(receiver_name, NULL);
- go_assert(vno != NULL);
- Expression* ve = Expression::make_var_reference(vno, location);
- Expression* bm;
- if (method != NULL)
- bm = Type::bind_field_or_method(gogo, type, ve, name, location);
- else
- bm = Expression::make_interface_field_reference(ve, name, location);
-
- // Even though we found the method above, if it has an error type we
- // may see an error here.
- if (bm->is_error_expression())
- {
- gogo->finish_function(location);
- return bm;
- }
-
- Expression_list* args;
- if (parameters->size() <= 1)
- args = NULL;
- else
- {
- args = new Expression_list();
- Typed_identifier_list::const_iterator p = parameters->begin();
- ++p;
- for (; p != parameters->end(); ++p)
- {
- vno = gogo->lookup(p->name(), NULL);
- go_assert(vno != NULL);
- args->push_back(Expression::make_var_reference(vno, location));
- }
- }
-
- gogo->start_block(location);
-
- Call_expression* call = Expression::make_call(bm, args,
- method_type->is_varargs(),
- location);
-
- Statement* s = Statement::make_return_from_call(call, location);
- gogo->add_statement(s);
-
- Block* b = gogo->finish_block(location);
-
- gogo->add_block(b, location);
-
- // Lower the call in case there are multiple results.
- gogo->lower_block(no, b);
- gogo->flatten_block(no, b);
-
- gogo->finish_function(location);
-
- return Expression::make_func_reference(no, NULL, location);
-}
-
-// Dump the ast for a selector expression.
-
-void
-Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
- const
-{
- ast_dump_context->dump_expression(this->left_);
- ast_dump_context->ostream() << ".";
- ast_dump_context->ostream() << this->name_;
-}
-
-// Make a selector expression.
-
-Expression*
-Expression::make_selector(Expression* left, const std::string& name,
- Location location)
-{
- return new Selector_expression(left, name, location);
-}
-
// Class Allocation_expression.
int
@@ -15541,7 +15774,8 @@ Struct_construction_expression::do_is_static_initializer() const
// Final type determination.
void
-Struct_construction_expression::do_determine_type(const Type_context*)
+Struct_construction_expression::do_determine_type(Gogo* gogo,
+ const Type_context*)
{
if (this->vals() == NULL)
return;
@@ -15556,13 +15790,13 @@ Struct_construction_expression::do_determine_type(const Type_context*)
if (*pv != NULL)
{
Type_context subcontext(pf->type(), false);
- (*pv)->determine_type(&subcontext);
+ (*pv)->determine_type(gogo, &subcontext);
}
}
// Extra values are an error we will report elsewhere; we still want
// to determine the type to avoid knockon errors.
for (; pv != this->vals()->end(); ++pv)
- (*pv)->determine_type_no_context();
+ (*pv)->determine_type_no_context(gogo);
}
// Check types.
@@ -15827,7 +16061,8 @@ Array_construction_expression::do_is_static_initializer() const
// Final type determination.
void
-Array_construction_expression::do_determine_type(const Type_context*)
+Array_construction_expression::do_determine_type(Gogo* gogo,
+ const Type_context*)
{
if (this->is_error_expression())
{
@@ -15850,7 +16085,7 @@ Array_construction_expression::do_determine_type(const Type_context*)
++pv)
{
if (*pv != NULL)
- (*pv)->determine_type(&subcontext);
+ (*pv)->determine_type(gogo, &subcontext);
}
}
@@ -16378,7 +16613,7 @@ Map_construction_expression::do_flatten(Gogo* gogo, Named_object*,
// Final type determination.
void
-Map_construction_expression::do_determine_type(const Type_context*)
+Map_construction_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
if (this->vals_ == NULL)
return;
@@ -16390,9 +16625,9 @@ Map_construction_expression::do_determine_type(const Type_context*)
pv != this->vals_->end();
++pv)
{
- (*pv)->determine_type(&key_context);
+ (*pv)->determine_type(gogo, &key_context);
++pv;
- (*pv)->determine_type(&val_context);
+ (*pv)->determine_type(gogo, &val_context);
}
}
@@ -16518,8 +16753,8 @@ Map_construction_expression::do_get_backend(Translate_context* context)
Expression::make_struct_field_offset(this->element_type_, valfield);
Expression* map_ctor =
- Runtime::make_call(Runtime::CONSTRUCT_MAP, loc, 5, descriptor, count,
- entry_size, val_offset, ventries);
+ Runtime::make_call(context->gogo(), Runtime::CONSTRUCT_MAP, loc, 5,
+ descriptor, count, entry_size, val_offset, ventries);
return map_ctor->get_backend(context);
}
@@ -17596,13 +17831,16 @@ Type_guard_expression::do_get_backend(Translate_context* context)
{
Expression* conversion;
if (this->type_->interface_type() != NULL)
- conversion =
- Expression::convert_interface_to_interface(this->type_, this->expr_,
- true, this->location());
+ conversion = Expression::convert_interface_to_interface(context->gogo(),
+ this->type_,
+ this->expr_,
+ true,
+ this->location());
else
- conversion =
- Expression::convert_for_assignment(context->gogo(), this->type_,
- this->expr_, this->location());
+ conversion = Expression::convert_for_assignment(context->gogo(),
+ this->type_,
+ this->expr_,
+ this->location());
Gogo* gogo = context->gogo();
Btype* bt = this->type_->get_backend(gogo);
@@ -17702,7 +17940,7 @@ Heap_expression::do_get_backend(Translate_context* context)
erhs = Expression::make_backend(btempref, etype, loc);
erhs = Expression::unpack_direct_iface(erhs, loc);
erhs = Expression::make_unsafe_cast(uintptr_type, erhs, loc);
- call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2,
+ call = Runtime::make_call(gogo, Runtime::GCWRITEBARRIER, loc, 2,
elhs, erhs);
}
else
@@ -17711,7 +17949,7 @@ Heap_expression::do_get_backend(Translate_context* context)
Bexpression* addr =
gogo->backend()->address_expression(btempref, loc);
erhs = Expression::make_backend(addr, etype_ptr, loc);
- call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
+ call = Runtime::make_call(gogo, Runtime::TYPEDMEMMOVE, loc, 3,
td, elhs, erhs);
}
Statement* cs = Statement::make_statement(call, false);
@@ -17840,12 +18078,13 @@ Receive_expression::do_get_backend(Translate_context* context)
return context->backend()->error_expression();
}
+ Gogo* gogo = context->gogo();
Expression* recv_ref =
Expression::make_temporary_reference(this->temp_receiver_, loc);
Expression* recv_addr =
Expression::make_temporary_reference(this->temp_receiver_, loc);
recv_addr = Expression::make_unary(OPERATOR_AND, recv_addr, loc);
- Expression* recv = Runtime::make_call(Runtime::CHANRECV1, loc, 2,
+ Expression* recv = Runtime::make_call(gogo, Runtime::CHANRECV1, loc, 2,
this->channel_, recv_addr);
return Expression::make_compound(recv, recv_ref, loc)->get_backend(context);
}
@@ -17910,7 +18149,7 @@ class Type_descriptor_expression : public Expression
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -17978,7 +18217,7 @@ class GC_symbol_expression : public Expression
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -18037,7 +18276,7 @@ class Ptrmask_symbol_expression : public Expression
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -18124,7 +18363,7 @@ class Type_info_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -18311,11 +18550,11 @@ Slice_value_expression::do_traverse(Traverse* traverse)
// Determine type of a slice value.
void
-Slice_value_expression::do_determine_type(const Type_context*)
+Slice_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->valmem_->determine_type_no_context();
- this->len_->determine_type_no_context();
- this->cap_->determine_type_no_context();
+ this->valmem_->determine_type_no_context(gogo);
+ this->len_->determine_type_no_context(gogo);
+ this->cap_->determine_type_no_context(gogo);
}
Expression*
@@ -18421,7 +18660,7 @@ class Interface_info_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -18591,7 +18830,7 @@ class Interface_value_expression : public Expression
{ return this->type_; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
@@ -18686,7 +18925,7 @@ class Interface_mtable_expression : public Expression
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
@@ -18932,7 +19171,7 @@ class Struct_field_offset_expression : public Expression
{ return Type::lookup_integer_type("uintptr"); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -19017,7 +19256,7 @@ class Label_addr_expression : public Expression
{ return Type::make_pointer_type(Type::make_void_type()); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -19080,11 +19319,12 @@ Conditional_expression::do_type()
// Determine type for a conditional expression.
void
-Conditional_expression::do_determine_type(const Type_context* context)
+Conditional_expression::do_determine_type(Gogo* gogo,
+ const Type_context* context)
{
- this->cond_->determine_type_no_context();
- this->then_->determine_type(context);
- this->else_->determine_type(context);
+ this->cond_->determine_type_no_context(gogo);
+ this->then_->determine_type(gogo, context);
+ this->else_->determine_type(gogo, context);
}
// Get the backend representation of a conditional expression.
@@ -19150,10 +19390,10 @@ Compound_expression::do_type()
// Determine type for a compound expression.
void
-Compound_expression::do_determine_type(const Type_context* context)
+Compound_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
- this->init_->determine_type_no_context();
- this->expr_->determine_type(context);
+ this->init_->determine_type_no_context(gogo);
+ this->expr_->determine_type(gogo, context);
}
// Get the backend representation of a compound expression.
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index bdb7ccd..d5df724 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -566,6 +566,15 @@ class Expression
is_constant() const
{ return this->do_is_constant(); }
+ // Return whether this expression is untyped. This isn't quite the
+ // same as is_constant with an abstract type, as 1<<val is untyped
+ // even if val is a variable. If this returns true, it sets *PTYPE
+ // to an abstract type, which is the type the expression will have
+ // if there is no context.
+ bool
+ is_untyped(Type** ptype) const
+ { return this->do_is_untyped(ptype); }
+
// Return whether this is the zero value of its type.
bool
is_zero_value() const
@@ -589,19 +598,19 @@ class Expression
// If this is not a numeric constant, return false. If it is one,
// return true, and set VAL to hold the value.
bool
- numeric_constant_value(Numeric_constant* val) const
+ numeric_constant_value(Numeric_constant* val)
{ return this->do_numeric_constant_value(val); }
// If this is not a constant expression with string type, return
// false. If it is one, return true, and set VAL to the value.
bool
- string_constant_value(std::string* val) const
+ string_constant_value(std::string* val)
{ return this->do_string_constant_value(val); }
// If this is not a constant expression with boolean type, return
// false. If it is one, return true, and set VAL to the value.
bool
- boolean_constant_value(bool* val) const
+ boolean_constant_value(bool* val)
{ return this->do_boolean_constant_value(val); }
// If this is a const reference expression, return the named
@@ -1002,7 +1011,7 @@ class Expression
// floating point, or complex type. TYPE_CONTEXT describes the
// expected type.
void
- determine_type(const Type_context*);
+ determine_type(Gogo*, const Type_context*);
// Check types in an expression.
void
@@ -1011,7 +1020,7 @@ class Expression
// Determine the type when there is no context.
void
- determine_type_no_context();
+ determine_type_no_context(Gogo*);
// Return the current type of the expression. This may be changed
// by determine_type. This should not be called before the lowering
@@ -1081,7 +1090,7 @@ class Expression
// interface type. If FOR_TYPE_GUARD is true this is for a type
// assertion.
static Expression*
- convert_interface_to_interface(Type* lhs_type,
+ convert_interface_to_interface(Gogo*, Type* lhs_type,
Expression* rhs, bool for_type_guard,
Location);
@@ -1116,9 +1125,9 @@ class Expression
// Insert bounds checks for an index expression.
static void
- check_bounds(Expression* val, Operator, Expression* bound, Runtime::Function,
+ check_bounds(Gogo*, Expression* val, Operator, Expression* bound,
Runtime::Function, Runtime::Function, Runtime::Function,
- Statement_inserter*, Location);
+ Runtime::Function, Statement_inserter*, Location);
// Return an expression for constructing a direct interface type from a
// pointer.
@@ -1169,6 +1178,11 @@ class Expression
do_is_constant() const
{ return false; }
+ // Return whether this expression is untyped.
+ virtual bool
+ do_is_untyped(Type**) const
+ { return false; }
+
// Return whether this is the zero value of its type.
virtual bool
do_is_zero_value() const
@@ -1183,19 +1197,19 @@ class Expression
// Return whether this is a constant expression of numeric type, and
// set the Numeric_constant to the value.
virtual bool
- do_numeric_constant_value(Numeric_constant*) const
+ do_numeric_constant_value(Numeric_constant*)
{ return false; }
// Return whether this is a constant expression of string type, and
// set VAL to the value.
virtual bool
- do_string_constant_value(std::string*) const
+ do_string_constant_value(std::string*)
{ return false; }
// Return whether this is a constant expression of boolean type, and
// set VAL to the value.
virtual bool
- do_boolean_constant_value(bool*) const
+ do_boolean_constant_value(bool*)
{ return false; }
// Called by the parser if the value is being discarded.
@@ -1208,7 +1222,7 @@ class Expression
// Child class implements determining type information.
virtual void
- do_determine_type(const Type_context*) = 0;
+ do_determine_type(Gogo*, const Type_context*) = 0;
// Child class implements type checking if needed.
virtual void
@@ -1274,6 +1288,12 @@ class Expression
void
report_error(const char*);
+ // A convenience function for handling a type in do_is_untyped. If
+ // TYPE is not abstract, return false. Otherwise set *PTYPE to TYPE
+ // and return true.
+ static bool
+ is_untyped_type(Type* type, Type** ptype);
+
// Write a name to export data.
static void
export_name(Export_function_body* efb, const Named_object*);
@@ -1456,7 +1476,7 @@ class Parser_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
void
@@ -1502,6 +1522,9 @@ class Const_expression : public Expression
{ return true; }
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_zero_value() const;
bool
@@ -1509,20 +1532,20 @@ class Const_expression : public Expression
{ return true; }
bool
- do_numeric_constant_value(Numeric_constant* nc) const;
+ do_numeric_constant_value(Numeric_constant* nc);
bool
- do_string_constant_value(std::string* val) const;
+ do_string_constant_value(std::string* val);
bool
- do_boolean_constant_value(bool* val) const;
+ do_boolean_constant_value(bool* val);
Type*
do_type();
// The type of a const is set by the declaration, not the use.
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -1581,7 +1604,7 @@ class Var_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
@@ -1649,8 +1672,8 @@ class Enclosed_var_expression : public Expression
{ return this->reference_->type(); }
void
- do_determine_type(const Type_context* context)
- { return this->reference_->determine_type(context); }
+ do_determine_type(Gogo* gogo, const Type_context* context)
+ { return this->reference_->determine_type(gogo, context); }
Expression*
do_copy()
@@ -1707,7 +1730,7 @@ class Temporary_reference_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -1772,7 +1795,7 @@ class Set_and_use_temporary_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
@@ -1831,6 +1854,9 @@ class String_expression : public Expression
{ return true; }
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_zero_value() const
{ return this->val_ == ""; }
@@ -1839,7 +1865,7 @@ class String_expression : public Expression
{ return true; }
bool
- do_string_constant_value(std::string* val) const
+ do_string_constant_value(std::string* val)
{
*val = this->val_;
return true;
@@ -1849,7 +1875,7 @@ class String_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
@@ -1941,20 +1967,20 @@ class Type_conversion_expression : public Expression
do_is_static_initializer() const;
bool
- do_numeric_constant_value(Numeric_constant*) const;
+ do_numeric_constant_value(Numeric_constant*);
bool
- do_string_constant_value(std::string*) const;
+ do_string_constant_value(std::string*);
bool
- do_boolean_constant_value(bool*) const;
+ do_boolean_constant_value(bool*);
Type*
do_type()
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -2021,8 +2047,8 @@ class Unsafe_type_conversion_expression : public Expression
{ return this->type_; }
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
Expression*
do_copy();
@@ -2137,19 +2163,22 @@ class Unary_expression : public Expression
do_is_constant() const;
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_static_initializer() const;
bool
- do_numeric_constant_value(Numeric_constant*) const;
+ do_numeric_constant_value(Numeric_constant*);
bool
- do_boolean_constant_value(bool*) const;
+ do_boolean_constant_value(bool*);
Type*
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -2294,13 +2323,16 @@ class Binary_expression : public Expression
{ return this->left_->is_constant() && this->right_->is_constant(); }
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_static_initializer() const;
bool
- do_numeric_constant_value(Numeric_constant*) const;
+ do_numeric_constant_value(Numeric_constant*);
bool
- do_boolean_constant_value(bool*) const;
+ do_boolean_constant_value(bool*);
bool
do_discarding_value();
@@ -2309,7 +2341,7 @@ class Binary_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -2416,6 +2448,9 @@ class String_concat_expression : public Expression
do_is_constant() const;
bool
+ do_is_untyped(Type**) const;
+
+ bool
do_is_zero_value() const;
bool
@@ -2425,7 +2460,7 @@ class String_concat_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -2599,7 +2634,7 @@ class Call_expression : public Expression
do_type();
virtual void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
virtual void
do_check_types(Gogo*);
@@ -2768,7 +2803,10 @@ class Builtin_call_expression : public Call_expression
do_is_constant() const;
bool
- do_numeric_constant_value(Numeric_constant*) const;
+ do_is_untyped(Type**) const;
+
+ bool
+ do_numeric_constant_value(Numeric_constant*);
bool
do_discarding_value();
@@ -2777,7 +2815,7 @@ class Builtin_call_expression : public Call_expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -2815,7 +2853,7 @@ class Builtin_call_expression : public Call_expression
complex_type(Type*);
Expression*
- lower_make(Statement_inserter*);
+ lower_make(Gogo*, Statement_inserter*);
bool
check_int_value(Expression*, bool is_length, bool* small);
@@ -2874,7 +2912,7 @@ class Call_result_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -2955,10 +2993,10 @@ class Func_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo* gogo, const Type_context*)
{
if (this->closure_ != NULL)
- this->closure_->determine_type_no_context();
+ this->closure_->determine_type_no_context(gogo);
}
Expression*
@@ -3015,7 +3053,7 @@ class Func_descriptor_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
@@ -3207,7 +3245,7 @@ class Array_index_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -3312,7 +3350,7 @@ class String_index_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -3408,7 +3446,7 @@ class Map_index_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -3511,7 +3549,7 @@ class Bound_method_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -3601,8 +3639,8 @@ class Field_reference_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
void
do_check_types(Gogo*);
@@ -3697,7 +3735,7 @@ class Interface_field_reference_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -3759,7 +3797,7 @@ class Allocation_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
void
@@ -3925,7 +3963,7 @@ class Struct_construction_expression : public Expression,
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -3992,7 +4030,7 @@ protected:
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -4124,7 +4162,7 @@ class Map_construction_expression : public Expression
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
@@ -4187,8 +4225,8 @@ class Type_guard_expression : public Expression
{ return this->type_; }
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
void
do_check_types(Gogo*);
@@ -4238,8 +4276,8 @@ class Heap_expression : public Expression
Type*
do_type();
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
Expression*
do_copy()
@@ -4301,8 +4339,8 @@ class Receive_expression : public Expression
do_flatten(Gogo*, Named_object*, Statement_inserter*);
void
- do_determine_type(const Type_context*)
- { this->channel_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->channel_->determine_type_no_context(gogo); }
void
do_check_types(Gogo*);
@@ -4364,7 +4402,7 @@ class Slice_value_expression : public Expression
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy();
@@ -4417,8 +4455,8 @@ class Slice_info_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*)
- { this->slice_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->slice_->determine_type_no_context(gogo); }
Expression*
do_copy()
@@ -4475,7 +4513,7 @@ class Conditional_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
@@ -4524,7 +4562,7 @@ class Compound_expression : public Expression
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
@@ -4571,7 +4609,7 @@ class Backend_expression : public Expression
{ return this->type_; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index fa3cd6e..3c021b9 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -898,7 +898,8 @@ Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
Expression* root_addr = Expression::make_unary(OPERATOR_AND, root_list_ctor,
builtin_loc);
root_addr->unary_expression()->set_is_gc_root();
- Expression* register_roots = Runtime::make_call(Runtime::REGISTER_GC_ROOTS,
+ Expression* register_roots = Runtime::make_call(this,
+ Runtime::REGISTER_GC_ROOTS,
builtin_loc, 1, root_addr);
Translate_context context(this, NULL, NULL, NULL);
@@ -1039,7 +1040,7 @@ Gogo::register_type_descriptors(std::vector<Bstatement*>& init_stmts,
Type* array_ptr_type = Type::make_pointer_type(list_array_type);
Expression* expr = Expression::make_backend(bexpr, array_ptr_type,
builtin_loc);
- expr = Runtime::make_call(Runtime::REGISTER_TYPE_DESCRIPTORS,
+ expr = Runtime::make_call(this, Runtime::REGISTER_TYPE_DESCRIPTORS,
builtin_loc, 2, len_expr->copy(), expr);
Bexpression* bcall = expr->get_backend(&context);
init_stmts.push_back(this->backend()->expression_statement(init_bfn,
@@ -2865,12 +2866,16 @@ Gogo::add_type_to_verify(Type* type)
class Verify_types : public Traverse
{
public:
- Verify_types()
- : Traverse(traverse_types)
+ Verify_types(Gogo* gogo)
+ : Traverse(traverse_types),
+ gogo_(gogo)
{ }
int
type(Type*);
+
+ private:
+ Gogo* gogo_;
};
// Verify that a type is correct.
@@ -2878,7 +2883,7 @@ class Verify_types : public Traverse
int
Verify_types::type(Type* t)
{
- if (!t->verify())
+ if (!t->verify(this->gogo_))
return TRAVERSE_SKIP_COMPONENTS;
return TRAVERSE_CONTINUE;
}
@@ -2888,13 +2893,13 @@ Verify_types::type(Type* t)
void
Gogo::verify_types()
{
- Verify_types traverse;
+ Verify_types traverse(this);
this->traverse(&traverse);
for (std::vector<Type*>::iterator p = this->verify_types_.begin();
p != this->verify_types_.end();
++p)
- (*p)->verify();
+ (*p)->verify(this);
this->verify_types_.clear();
}
@@ -3224,9 +3229,10 @@ Gogo::add_conversions_in_block(Block *b)
class Remove_deadcode : public Traverse
{
public:
- Remove_deadcode()
+ Remove_deadcode(Gogo* gogo)
: Traverse(traverse_statements
- | traverse_expressions)
+ | traverse_expressions),
+ gogo_(gogo)
{ }
int
@@ -3234,6 +3240,9 @@ class Remove_deadcode : public Traverse
int
expression(Expression**);
+
+ private:
+ Gogo* gogo_;
};
// Remove deadcode in a statement.
@@ -3283,7 +3292,7 @@ Remove_deadcode::expression(Expression** pexpr)
{
*pexpr = Expression::make_boolean(bval, be->location());
Type_context context(NULL, false);
- (*pexpr)->determine_type(&context);
+ (*pexpr)->determine_type(this->gogo_, &context);
}
return TRAVERSE_CONTINUE;
}
@@ -3293,7 +3302,7 @@ Remove_deadcode::expression(Expression** pexpr)
void
Gogo::remove_deadcode()
{
- Remove_deadcode remove_deadcode;
+ Remove_deadcode remove_deadcode(this);
this->traverse(&remove_deadcode);
}
@@ -3622,11 +3631,11 @@ Gogo::determine_types()
++p)
{
if ((*p)->is_function())
- (*p)->func_value()->determine_types();
+ (*p)->func_value()->determine_types(this);
else if ((*p)->is_variable())
- (*p)->var_value()->determine_type();
+ (*p)->var_value()->determine_type(this);
else if ((*p)->is_const())
- (*p)->const_value()->determine_type();
+ (*p)->const_value()->determine_type(this);
// See if a variable requires us to build an initialization
// function. We know that we will see all global variables
@@ -3662,7 +3671,7 @@ Gogo::determine_types()
for (Packages::const_iterator p = this->packages_.begin();
p != this->packages_.end();
++p)
- p->second->determine_types();
+ p->second->determine_types(this);
}
// Traversal class used for type checking.
@@ -4809,7 +4818,7 @@ Build_recover_thunks::function(Named_object* orig_no)
call->set_varargs_are_lowered();
Statement* s = Statement::make_return_from_call(call, location);
- s->determine_types();
+ s->determine_types(this->gogo_);
gogo->add_statement(s);
Block* b = gogo->finish_block(location);
@@ -4920,7 +4929,8 @@ Build_recover_thunks::can_recover_arg(Location location)
}
Expression* zexpr = Expression::make_integer_ul(0, NULL, location);
- Expression* call = Runtime::make_call(Runtime::BUILTIN_RETURN_ADDRESS,
+ Expression* call = Runtime::make_call(this->gogo_,
+ Runtime::BUILTIN_RETURN_ADDRESS,
location, 1, zexpr);
call = Expression::make_unsafe_cast(uintptr_type, call, location);
@@ -5070,7 +5080,7 @@ Expression*
Gogo::allocate_memory(Type* type, Location location)
{
Expression* td = Expression::make_type_descriptor(type, location);
- return Runtime::make_call(Runtime::NEW, location, 1, td);
+ return Runtime::make_call(this, Runtime::NEW, location, 1, td);
}
// Traversal class used to check for return statements.
@@ -5882,10 +5892,10 @@ Function::traverse(Traverse* traverse)
// Work out types for unspecified variables and constants.
void
-Function::determine_types()
+Function::determine_types(Gogo* gogo)
{
if (this->block_ != NULL)
- this->block_->determine_types();
+ this->block_->determine_types(gogo);
}
// Return the function descriptor, the value you get when you refer to
@@ -6770,7 +6780,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
// libgo/runtime/go-unwind.c.
std::vector<Bstatement*> stmts;
- Expression* call = Runtime::make_call(Runtime::CHECKDEFER, end_loc, 1,
+ Expression* call = Runtime::make_call(gogo, Runtime::CHECKDEFER, end_loc, 1,
this->defer_stack(end_loc));
Translate_context context(gogo, named_function, NULL, NULL);
Bexpression* defer = call->get_backend(&context);
@@ -6783,11 +6793,11 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
go_assert(*except == NULL);
*except = gogo->backend()->statement_list(stmts);
- call = Runtime::make_call(Runtime::CHECKDEFER, end_loc, 1,
+ call = Runtime::make_call(gogo, Runtime::CHECKDEFER, end_loc, 1,
this->defer_stack(end_loc));
defer = call->get_backend(&context);
- call = Runtime::make_call(Runtime::DEFERRETURN, end_loc, 1,
+ call = Runtime::make_call(gogo, Runtime::DEFERRETURN, end_loc, 1,
this->defer_stack(end_loc));
Bexpression* undefer = call->get_backend(&context);
Bstatement* function_defer =
@@ -6961,7 +6971,7 @@ Block::traverse(Traverse* traverse)
// Work out types for unspecified variables and constants.
void
-Block::determine_types()
+Block::determine_types(Gogo* gogo)
{
for (Bindings::const_definitions_iterator pb =
this->bindings_->begin_definitions();
@@ -6969,15 +6979,15 @@ Block::determine_types()
++pb)
{
if ((*pb)->is_variable())
- (*pb)->var_value()->determine_type();
+ (*pb)->var_value()->determine_type(gogo);
else if ((*pb)->is_const())
- (*pb)->const_value()->determine_type();
+ (*pb)->const_value()->determine_type(gogo);
}
for (std::vector<Statement*>::const_iterator ps = this->statements_.begin();
ps != this->statements_.end();
++ps)
- (*ps)->determine_types();
+ (*ps)->determine_types(gogo);
}
// Return true if the statements in this block may fall through.
@@ -7456,7 +7466,7 @@ Function_declaration::import_function_body(Gogo* gogo, Named_object* no)
return;
gogo->lower_block(no, outer);
- outer->determine_types();
+ outer->determine_types(gogo);
gogo->add_imported_inline_function(no);
}
@@ -7826,14 +7836,14 @@ Variable::type() const
// Set the type if necessary.
void
-Variable::determine_type()
+Variable::determine_type(Gogo* gogo)
{
if (this->determined_type_)
return;
this->determined_type_ = true;
if (this->preinit_ != NULL)
- this->preinit_->determine_types();
+ this->preinit_->determine_types(gogo);
// A variable in a type switch with a nil case will have the wrong
// type here. It will have an initializer which is a type guard.
@@ -7854,14 +7864,14 @@ Variable::determine_type()
else if (this->type_from_init_tuple_)
{
Expression *init = this->init_;
- init->determine_type_no_context();
+ init->determine_type_no_context(gogo);
this->type_ = this->type_from_tuple(init, true);
this->init_ = NULL;
}
else if (this->type_from_range_index_ || this->type_from_range_value_)
{
Expression* init = this->init_;
- init->determine_type_no_context();
+ init->determine_type_no_context(gogo);
this->type_ = this->type_from_range(init, this->type_from_range_index_,
true);
this->init_ = NULL;
@@ -7869,14 +7879,14 @@ Variable::determine_type()
else if (this->type_from_chan_element_)
{
Expression* init = this->init_;
- init->determine_type_no_context();
+ init->determine_type_no_context(gogo);
this->type_ = this->type_from_chan_element(init, true);
this->init_ = NULL;
}
else
{
Type_context context(this->type_, false);
- this->init_->determine_type(&context);
+ this->init_->determine_type(gogo, &context);
if (this->type_ == NULL)
{
Type* type = this->init_->type();
@@ -8204,18 +8214,18 @@ Named_constant::traverse_expression(Traverse* traverse)
// Determine the type of the constant.
void
-Named_constant::determine_type()
+Named_constant::determine_type(Gogo* gogo)
{
if (this->type_ != NULL)
{
Type_context context(this->type_, false);
- this->expr_->determine_type(&context);
+ this->expr_->determine_type(gogo, &context);
}
else
{
// A constant may have an abstract type.
Type_context context(NULL, true);
- this->expr_->determine_type(&context);
+ this->expr_->determine_type(gogo, &context);
this->type_ = this->expr_->type();
go_assert(this->type_ != NULL);
}
@@ -9566,7 +9576,7 @@ Package::add_alias(const std::string& alias, Location location)
// type. Constants may have abstract types.
void
-Package::determine_types()
+Package::determine_types(Gogo* gogo)
{
Bindings* bindings = this->bindings_;
for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
@@ -9574,7 +9584,7 @@ Package::determine_types()
++p)
{
if ((*p)->is_const())
- (*p)->const_value()->determine_type();
+ (*p)->const_value()->determine_type(gogo);
}
}
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 4fd45bf..f254a61 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -1429,7 +1429,7 @@ class Block
// Set final types for unspecified variables and constants.
void
- determine_types();
+ determine_types(Gogo*);
// Return true if execution of this block may fall through to the
// next block.
@@ -1760,7 +1760,7 @@ class Function
// Determine types in the function.
void
- determine_types();
+ determine_types(Gogo*);
// Return an expression for the function descriptor, given the named
// object for this function. This may only be called for functions
@@ -2365,7 +2365,7 @@ class Variable
// Determine the type of the variable if necessary.
void
- determine_type();
+ determine_type(Gogo*);
// Get the backend representation of the variable.
Bvariable*
@@ -2620,7 +2620,7 @@ class Named_constant
// Determine the type of the constant if necessary.
void
- determine_type();
+ determine_type(Gogo*);
// Indicate that we found and reported an error for this constant.
void
@@ -3687,7 +3687,7 @@ class Package
// Determine types of constants.
void
- determine_types();
+ determine_types(Gogo*);
private:
// The package path for type reflection data.
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index c93d82b..d741058 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -4932,7 +4932,7 @@ Parse::type_switch_body(Label* label, const Type_switch& type_switch,
}
Type_switch_statement* statement =
- Statement::make_type_switch_statement(var_name, init, location);
+ Statement::make_type_switch_statement(init, location);
this->push_break_statement(statement, label);
Type_case_clauses* case_clauses = new Type_case_clauses();
diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc
index 3cc5ded..274aa4a 100644
--- a/gcc/go/gofrontend/runtime.cc
+++ b/gcc/go/gofrontend/runtime.cc
@@ -317,7 +317,7 @@ Runtime::convert_types(Gogo* gogo)
Type* t = runtime_function_types[i];
if (t != NULL && t->named_type() != NULL)
{
- bool r = t->verify();
+ bool r = t->verify(gogo);
go_assert(r);
t->named_type()->convert(gogo);
}
@@ -414,7 +414,7 @@ Runtime::runtime_declaration(Function code)
// Make a call to a runtime function.
Call_expression*
-Runtime::make_call(Runtime::Function code, Location loc,
+Runtime::make_call(Gogo*, Runtime::Function code, Location loc,
int param_count, ...)
{
go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);
diff --git a/gcc/go/gofrontend/runtime.h b/gcc/go/gofrontend/runtime.h
index e92510b..bea2dbe 100644
--- a/gcc/go/gofrontend/runtime.h
+++ b/gcc/go/gofrontend/runtime.h
@@ -32,7 +32,7 @@ class Runtime
// Make a call to a runtime function.
static Call_expression*
- make_call(Function, Location, int, ...);
+ make_call(Gogo*, Function, Location, int, ...);
// Convert all the types used by runtime functions to the backend
// representation.
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index af8c7d1..5d652a1 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -64,16 +64,6 @@ Statement::traverse_contents(Traverse* traverse)
return this->do_traverse(traverse);
}
-// Traverse assignments.
-
-bool
-Statement::traverse_assignments(Traverse_assignments* tassign)
-{
- if (this->classification_ == STATEMENT_ERROR)
- return false;
- return this->do_traverse_assignments(tassign);
-}
-
// Traverse an expression in a statement. This is a helper function
// for child classes.
@@ -117,9 +107,9 @@ Statement::traverse_type(Traverse* traverse, Type* type)
// the child class.
void
-Statement::determine_types()
+Statement::determine_types(Gogo* gogo)
{
- this->do_determine_types();
+ this->do_determine_types(gogo);
}
// Read a statement from export data.
@@ -288,17 +278,6 @@ Variable_declaration_statement::do_traverse(Traverse*)
return TRAVERSE_CONTINUE;
}
-// Traverse the assignments in a variable declaration. Note that this
-// traversal is different from the usual traversal.
-
-bool
-Variable_declaration_statement::do_traverse_assignments(
- Traverse_assignments* tassign)
-{
- tassign->initialize_variable(this->var_);
- return true;
-}
-
// Lower the variable's initialization expression.
Statement*
@@ -510,21 +489,10 @@ Temporary_statement::do_traverse(Traverse* traverse)
return this->traverse_expression(traverse, &this->init_);
}
-// Traverse assignments.
-
-bool
-Temporary_statement::do_traverse_assignments(Traverse_assignments* tassign)
-{
- if (this->init_ == NULL)
- return false;
- tassign->value(&this->init_, true, true);
- return true;
-}
-
// Determine types.
void
-Temporary_statement::do_determine_types()
+Temporary_statement::do_determine_types(Gogo* gogo)
{
if (this->type_ != NULL && this->type_->is_abstract())
this->type_ = this->type_->make_non_abstract_type();
@@ -532,11 +500,11 @@ Temporary_statement::do_determine_types()
if (this->init_ != NULL)
{
if (this->type_ == NULL)
- this->init_->determine_type_no_context();
+ this->init_->determine_type_no_context(gogo);
else
{
Type_context context(this->type_, false);
- this->init_->determine_type(&context);
+ this->init_->determine_type(gogo, &context);
}
}
@@ -889,13 +857,6 @@ Assignment_statement::do_traverse(Traverse* traverse)
return this->traverse_expression(traverse, &this->rhs_);
}
-bool
-Assignment_statement::do_traverse_assignments(Traverse_assignments* tassign)
-{
- tassign->assignment(&this->lhs_, &this->rhs_);
- return true;
-}
-
// Lower an assignment to a map index expression to a runtime function
// call. Mark some slice assignments as not requiring a write barrier.
@@ -1000,7 +961,7 @@ Assignment_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
code = Runtime::MAPASSIGN;
break;
}
- Expression* call = Runtime::make_call(code, loc, 3,
+ Expression* call = Runtime::make_call(gogo, code, loc, 3,
a1, a2, a3);
Type* ptrval_type = Type::make_pointer_type(mt->val_type());
call = Expression::make_cast(ptrval_type, call, loc);
@@ -1046,14 +1007,14 @@ Assignment_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
// Set types for the assignment.
void
-Assignment_statement::do_determine_types()
+Assignment_statement::do_determine_types(Gogo* gogo)
{
- this->lhs_->determine_type_no_context();
+ this->lhs_->determine_type_no_context(gogo);
Type* rhs_context_type = this->lhs_->type();
if (rhs_context_type->is_sink_type())
rhs_context_type = NULL;
Type_context context(rhs_context_type, false);
- this->rhs_->determine_type(&context);
+ this->rhs_->determine_type(gogo, &context);
}
// Check types for an assignment.
@@ -1212,10 +1173,6 @@ class Assignment_operation_statement : public Statement
int
do_traverse(Traverse*);
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -1365,10 +1322,6 @@ class Tuple_assignment_statement : public Statement
int
do_traverse(Traverse* traverse);
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -1511,10 +1464,6 @@ public:
int
do_traverse(Traverse* traverse);
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -1648,10 +1597,11 @@ Tuple_map_assignment_statement::do_lower(Gogo* gogo, Named_object*,
code = Runtime::MAPACCESS2;
break;
}
- call = Runtime::make_call(code, loc, 3, a1, a2, a3);
+ call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
}
else
- call = Runtime::make_call(Runtime::MAPACCESS2_FAT, loc, 4, a1, a2, a3, a4);
+ call = Runtime::make_call(gogo, Runtime::MAPACCESS2_FAT, loc, 4,
+ a1, a2, a3, a4);
ref = Expression::make_temporary_reference(val_ptr_temp, loc);
ref->set_is_lvalue();
Expression* res = Expression::make_call_result(call, 0);
@@ -1719,10 +1669,6 @@ class Tuple_receive_assignment_statement : public Statement
int
do_traverse(Traverse* traverse);
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -1756,7 +1702,7 @@ Tuple_receive_assignment_statement::do_traverse(Traverse* traverse)
// Lower to a function call.
Statement*
-Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*,
+Tuple_receive_assignment_statement::do_lower(Gogo* gogo, Named_object*,
Block* enclosing,
Statement_inserter*)
{
@@ -1799,7 +1745,7 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*,
Temporary_reference_expression* ref =
Expression::make_temporary_reference(val_temp, loc);
Expression* p2 = Expression::make_unary(OPERATOR_AND, ref, loc);
- Expression* call = Runtime::make_call(Runtime::CHANRECV2,
+ Expression* call = Runtime::make_call(gogo, Runtime::CHANRECV2,
loc, 2, this->channel_, p2);
ref = Expression::make_temporary_reference(closed_temp, loc);
ref->set_is_lvalue();
@@ -1862,10 +1808,6 @@ class Tuple_type_guard_assignment_statement : public Statement
int
do_traverse(Traverse*);
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -1878,10 +1820,10 @@ class Tuple_type_guard_assignment_statement : public Statement
private:
Call_expression*
- lower_to_type(Runtime::Function);
+ lower_to_type(Gogo*, Runtime::Function);
void
- lower_to_object_type(Block*, Runtime::Function);
+ lower_to_object_type(Gogo*, Block*, Runtime::Function);
// The variable which recieves the converted value.
Expression* val_;
@@ -1908,7 +1850,7 @@ Tuple_type_guard_assignment_statement::do_traverse(Traverse* traverse)
// Lower to a function call.
Statement*
-Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
+Tuple_type_guard_assignment_statement::do_lower(Gogo* gogo, Named_object*,
Block* enclosing,
Statement_inserter*)
{
@@ -1935,22 +1877,25 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
if (this->type_->interface_type() != NULL)
{
if (this->type_->interface_type()->is_empty())
- call = Runtime::make_call((expr_is_empty
+ call = Runtime::make_call(gogo,
+ (expr_is_empty
? Runtime::IFACEE2E2
: Runtime::IFACEI2E2),
loc, 1, this->expr_);
else
- call = this->lower_to_type(expr_is_empty
- ? Runtime::IFACEE2I2
- : Runtime::IFACEI2I2);
+ call = this->lower_to_type(gogo,
+ (expr_is_empty
+ ? Runtime::IFACEE2I2
+ : Runtime::IFACEI2I2));
}
else if (this->type_->points_to() != NULL)
- call = this->lower_to_type(expr_is_empty
- ? Runtime::IFACEE2T2P
- : Runtime::IFACEI2T2P);
+ call = this->lower_to_type(gogo,
+ (expr_is_empty
+ ? Runtime::IFACEE2T2P
+ : Runtime::IFACEI2T2P));
else
{
- this->lower_to_object_type(b,
+ this->lower_to_object_type(gogo, b,
(expr_is_empty
? Runtime::IFACEE2T2
: Runtime::IFACEI2T2));
@@ -1977,10 +1922,11 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
// Lower a conversion to a non-empty interface type or a pointer type.
Call_expression*
-Tuple_type_guard_assignment_statement::lower_to_type(Runtime::Function code)
+Tuple_type_guard_assignment_statement::lower_to_type(Gogo* gogo,
+ Runtime::Function code)
{
Location loc = this->location();
- return Runtime::make_call(code, loc, 2,
+ return Runtime::make_call(gogo, code, loc, 2,
Expression::make_type_descriptor(this->type_, loc),
this->expr_);
}
@@ -1989,6 +1935,7 @@ Tuple_type_guard_assignment_statement::lower_to_type(Runtime::Function code)
void
Tuple_type_guard_assignment_statement::lower_to_object_type(
+ Gogo* gogo,
Block* b,
Runtime::Function code)
{
@@ -2014,7 +1961,8 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(
Expression* p1 = Expression::make_type_descriptor(this->type_, loc);
Expression* ref = Expression::make_temporary_reference(val_temp, loc);
Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc);
- Expression* call = Runtime::make_call(code, loc, 3, p1, this->expr_, p3);
+ Expression* call = Runtime::make_call(gogo, code, loc, 3,
+ p1, this->expr_, p3);
Statement* s;
if (ok_temp == NULL)
s = Statement::make_statement(call, true);
@@ -2080,9 +2028,9 @@ Expression_statement::Expression_statement(Expression* expr, bool is_ignored)
// Determine types.
void
-Expression_statement::do_determine_types()
+Expression_statement::do_determine_types(Gogo* gogo)
{
- this->expr_->determine_type_no_context();
+ this->expr_->determine_type_no_context(gogo);
}
// Check the types of an expression statement. The only check we do
@@ -2277,10 +2225,6 @@ class Inc_dec_statement : public Statement
do_traverse(Traverse* traverse)
{ return this->traverse_expression(traverse, &this->expr_); }
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -2412,24 +2356,12 @@ Thunk_statement::do_traverse(Traverse* traverse)
return this->traverse_expression(traverse, &this->call_);
}
-// We implement traverse_assignment for a thunk statement because it
-// effectively copies the function call.
-
-bool
-Thunk_statement::do_traverse_assignments(Traverse_assignments* tassign)
-{
- Expression* fn = this->call_->call_expression()->fn();
- Expression* fn2 = fn;
- tassign->value(&fn2, true, false);
- return true;
-}
-
// Determine types in a thunk statement.
void
-Thunk_statement::do_determine_types()
+Thunk_statement::do_determine_types(Gogo* gogo)
{
- this->call_->determine_type_no_context();
+ this->call_->determine_type_no_context(gogo);
}
// Check types in a thunk statement.
@@ -2640,7 +2572,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
Expression* nil = Expression::make_nil(location);
Expression* isnil = Expression::make_binary(OPERATOR_EQEQ, fn, nil,
location);
- Expression* crash = Runtime::make_call(Runtime::PANIC_GO_NIL,
+ Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_GO_NIL,
location, 0);
crash = Expression::make_conditional(isnil, crash,
Expression::make_nil(location),
@@ -2679,7 +2611,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
// We already ran the determine_types pass, so we need to run it now
// for the new statement.
- s->determine_types();
+ s->determine_types(gogo);
// Sanity check.
gogo->check_types_in_block(block);
@@ -2824,7 +2756,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
{
retaddr_label = gogo->add_label_reference("retaddr", location, false);
Expression* arg = Expression::make_label_addr(retaddr_label, location);
- Expression* call = Runtime::make_call(Runtime::SETDEFERRETADDR,
+ Expression* call = Runtime::make_call(gogo, Runtime::SETDEFERRETADDR,
location, 1, arg);
// This is a hack to prevent the middle-end from deleting the
@@ -2833,11 +2765,11 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
gogo->add_statement(Statement::make_goto_statement(retaddr_label,
location));
Block* then_block = gogo->finish_block(location);
- then_block->determine_types();
+ then_block->determine_types(gogo);
Statement* s = Statement::make_if_statement(call, then_block, NULL,
location);
- s->determine_types();
+ s->determine_types(gogo);
gogo->add_statement(s);
function->func_value()->set_calls_defer_retaddr();
@@ -2977,7 +2909,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
// We already ran the determine_types pass, so we need to run it
// just for the call statement now. The other types are known.
- call_statement->determine_types();
+ call_statement->determine_types(gogo);
gogo->add_conversions_in_block(b);
@@ -3048,7 +2980,8 @@ Go_statement::do_get_backend(Translate_context* context)
if (!this->get_fn_and_arg(&fn, &arg))
return context->backend()->error_statement();
- Expression* call = Runtime::make_call(Runtime::GO, this->location(), 2,
+ Gogo* gogo = context->gogo();
+ Expression* call = Runtime::make_call(gogo, Runtime::GO, this->location(), 2,
fn, arg);
Bexpression* bcall = call->get_backend(context);
Bfunction* bfunction = context->function()->func_value()->get_decl();
@@ -3084,6 +3017,7 @@ Defer_statement::do_get_backend(Translate_context* context)
if (!this->get_fn_and_arg(&fn, &arg))
return context->backend()->error_statement();
+ Gogo* gogo = context->gogo();
Location loc = this->location();
Expression* ds = context->function()->func_value()->defer_stack(loc);
@@ -3097,11 +3031,11 @@ Defer_statement::do_get_backend(Translate_context* context)
Expression* defer = Expression::make_allocation(defer_type, loc);
defer->allocation_expression()->set_allocate_on_stack();
defer->allocation_expression()->set_no_zero();
- call = Runtime::make_call(Runtime::DEFERPROCSTACK, loc, 4,
+ call = Runtime::make_call(gogo, Runtime::DEFERPROCSTACK, loc, 4,
defer, ds, fn, arg);
}
else
- call = Runtime::make_call(Runtime::DEFERPROC, loc, 3,
+ call = Runtime::make_call(gogo, Runtime::DEFERPROC, loc, 3,
ds, fn, arg);
Bexpression* bcall = call->get_backend(context);
Bfunction* bfunction = context->function()->func_value()->get_decl();
@@ -3148,23 +3082,6 @@ Statement::make_defer_statement(Call_expression* call,
// Class Return_statement.
-// Traverse assignments. We treat each return value as a top level
-// RHS in an expression.
-
-bool
-Return_statement::do_traverse_assignments(Traverse_assignments* tassign)
-{
- Expression_list* vals = this->vals_;
- if (vals != NULL)
- {
- for (Expression_list::iterator p = vals->begin();
- p != vals->end();
- ++p)
- tassign->value(&*p, true, true);
- }
- return true;
-}
-
// Lower a return statement. If we are returning a function call
// which returns multiple values which match the current function,
// split up the call's results. If the return statement lists
@@ -3173,8 +3090,8 @@ Return_statement::do_traverse_assignments(Traverse_assignments* tassign)
// return. This lets panic/recover work correctly.
Statement*
-Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
- Statement_inserter*)
+Return_statement::do_lower(Gogo* gogo, Named_object* function,
+ Block* enclosing, Statement_inserter*)
{
if (this->is_lowered_)
return this;
@@ -3253,7 +3170,7 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
Type *rvtype = rv->result_var_value()->type();
Type_context type_context(rvtype, false);
- e->determine_type(&type_context);
+ e->determine_type(gogo, &type_context);
std::string reason;
if (Type::are_assignable(rvtype, e->type(), &reason))
@@ -3764,13 +3681,13 @@ If_statement::do_traverse(Traverse* traverse)
}
void
-If_statement::do_determine_types()
+If_statement::do_determine_types(Gogo* gogo)
{
Type_context context(Type::lookup_bool_type(), false);
- this->cond_->determine_type(&context);
- this->then_block_->determine_types();
+ this->cond_->determine_type(gogo, &context);
+ this->then_block_->determine_types(gogo);
if (this->else_block_ != NULL)
- this->else_block_->determine_types();
+ this->else_block_->determine_types(gogo);
}
// Check types.
@@ -4082,7 +3999,7 @@ Case_clauses::Case_clause::lower(Block* b, Temporary_statement* val_temp,
// Determine types.
void
-Case_clauses::Case_clause::determine_types(Type* type)
+Case_clauses::Case_clause::determine_types(Gogo* gogo, Type* type)
{
if (this->cases_ != NULL)
{
@@ -4090,10 +4007,10 @@ Case_clauses::Case_clause::determine_types(Type* type)
for (Expression_list::iterator p = this->cases_->begin();
p != this->cases_->end();
++p)
- (*p)->determine_type(&case_context);
+ (*p)->determine_type(gogo, &case_context);
}
if (this->statements_ != NULL)
- this->statements_->determine_types();
+ this->statements_->determine_types(gogo);
}
// Check types. Returns false if there was an error.
@@ -4319,12 +4236,12 @@ Case_clauses::lower(Block* b, Temporary_statement* val_temp,
// Determine types.
void
-Case_clauses::determine_types(Type* type)
+Case_clauses::determine_types(Gogo* gogo, Type* type)
{
for (Clauses::iterator p = this->clauses_.begin();
p != this->clauses_.end();
++p)
- p->determine_types(type);
+ p->determine_types(gogo, type);
}
// Check types. Returns false if there was an error.
@@ -4425,7 +4342,7 @@ class Constant_switch_statement : public Statement
do_traverse(Traverse*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
@@ -4458,10 +4375,10 @@ Constant_switch_statement::do_traverse(Traverse* traverse)
// Determine types.
void
-Constant_switch_statement::do_determine_types()
+Constant_switch_statement::do_determine_types(Gogo* gogo)
{
- this->val_->determine_type_no_context();
- this->clauses_->determine_types(this->val_->type());
+ this->val_->determine_type_no_context(gogo);
+ this->clauses_->determine_types(gogo, this->val_->type());
}
// Check types.
@@ -4724,12 +4641,12 @@ Type_case_clauses::Type_case_clause::lower(Gogo* gogo,
Expression::make_type_descriptor(type, loc),
loc);
else
- cond = Runtime::make_call(Runtime::EQTYPE, loc, 2,
+ cond = Runtime::make_call(gogo, Runtime::EQTYPE, loc, 2,
Expression::make_type_descriptor(type, loc),
ref);
}
else
- cond = Runtime::make_call(Runtime::IFACET2IP, loc, 2,
+ cond = Runtime::make_call(gogo, Runtime::IFACET2IP, loc, 2,
Expression::make_type_descriptor(type, loc),
ref);
@@ -5046,8 +4963,6 @@ Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "switch ";
- if (!this->name_.empty())
- ast_dump_context->ostream() << this->name_ << " = ";
ast_dump_context->dump_expression(this->expr_);
ast_dump_context->ostream() << " .(type)";
if (ast_dump_context->dump_subblocks())
@@ -5062,10 +4977,9 @@ Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
// Make a type switch statement.
Type_switch_statement*
-Statement::make_type_switch_statement(const std::string& name, Expression* expr,
- Location location)
+Statement::make_type_switch_statement(Expression* expr, Location location)
{
- return new Type_switch_statement(name, expr, location);
+ return new Type_switch_statement(expr, location);
}
// Class Send_statement.
@@ -5083,14 +4997,14 @@ Send_statement::do_traverse(Traverse* traverse)
// Determine types.
void
-Send_statement::do_determine_types()
+Send_statement::do_determine_types(Gogo* gogo)
{
- this->channel_->determine_type_no_context();
+ this->channel_->determine_type_no_context(gogo);
Type* type = this->channel_->type();
Type_context context;
if (type->channel_type() != NULL)
context.type = type->channel_type()->element_type();
- this->val_->determine_type(&context);
+ this->val_->determine_type(gogo, &context);
}
// Check types.
@@ -5171,6 +5085,7 @@ Send_statement::do_add_conversions()
Bstatement*
Send_statement::do_get_backend(Translate_context* context)
{
+ Gogo* gogo = context->gogo();
Location loc = this->location();
Channel_type* channel_type = this->channel_->type()->channel_type();
@@ -5242,7 +5157,7 @@ Send_statement::do_get_backend(Translate_context* context)
btemp = temp->get_backend(context);
}
- Expression* call = Runtime::make_call(Runtime::CHANSEND, loc, 2,
+ Expression* call = Runtime::make_call(gogo, Runtime::CHANSEND, loc, 2,
this->channel_, val);
context->gogo()->lower_expression(context->function(), NULL, &call);
@@ -5492,11 +5407,11 @@ Select_clauses::Select_clause::set_case(Block* b,
// Determine types.
void
-Select_clauses::Select_clause::determine_types()
+Select_clauses::Select_clause::determine_types(Gogo* gogo)
{
go_assert(this->is_lowered_);
if (this->statements_ != NULL)
- this->statements_->determine_types();
+ this->statements_->determine_types(gogo);
}
// Check types.
@@ -5676,12 +5591,12 @@ Select_clauses::lower(Gogo* gogo, Named_object* function, Block* b,
// Determine types.
void
-Select_clauses::determine_types()
+Select_clauses::determine_types(Gogo* gogo)
{
for (Clauses::iterator p = this->clauses_.begin();
p != this->clauses_.end();
++p)
- p->determine_types();
+ p->determine_types(gogo);
}
// Check types.
@@ -5755,7 +5670,9 @@ Select_clauses::get_backend(Translate_context* context,
if (count == 0)
return context->backend()->expression_statement(bfunction, bindex);
- Expression* crash = Runtime::make_call(Runtime::UNREACHABLE, location, 0);
+ Gogo* gogo = context->gogo();
+ Expression* crash = Runtime::make_call(gogo, Runtime::UNREACHABLE,
+ location, 0);
Bexpression* bcrash = crash->get_backend(context);
clauses[count] = context->backend()->expression_statement(bfunction, bcrash);
@@ -5821,7 +5738,7 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
// Zero-case select. Just block the execution.
if (ncases == 0)
{
- Expression* call = Runtime::make_call(Runtime::BLOCK, loc, 0);
+ Expression* call = Runtime::make_call(gogo, Runtime::BLOCK, loc, 0);
Statement *s = Statement::make_statement(call, false);
b->add_statement(s);
this->is_lowered_ = true;
@@ -5830,12 +5747,12 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
// One-case select. It is mostly just to run the case.
if (ncases == 1)
- return this->lower_one_case(b);
+ return this->lower_one_case(gogo, b);
// Two-case select with one default case. It is a non-blocking
// send/receive.
if (ncases == 2 && has_default)
- return this->lower_two_case(b);
+ return this->lower_two_case(gogo, b);
// We don't allocate an entry in scases for the default case.
if (has_default)
@@ -5898,7 +5815,7 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
loc);
Expression* block_expr = Expression::make_boolean(!has_default, loc);
- Call_expression* call = Runtime::make_call(Runtime::SELECTGO, loc, 5,
+ Call_expression* call = Runtime::make_call(gogo, Runtime::SELECTGO, loc, 5,
scases_ref, order_ref,
send_count_expr, recv_count_expr,
block_expr);
@@ -5922,7 +5839,7 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
// Lower a one-case select statement.
Statement*
-Select_statement::lower_one_case(Block* b)
+Select_statement::lower_one_case(Gogo* gogo, Block* b)
{
Select_clauses::Select_clause& scase = this->clauses_->at(0);
Location loc = this->location();
@@ -5938,7 +5855,7 @@ Select_statement::lower_one_case(Block* b)
Expression* nil = Expression::make_nil(loc);
Expression* cond = Expression::make_binary(OPERATOR_EQEQ, chanref, nil, loc);
Block* bnil = new Block(b, loc);
- Expression* call = Runtime::make_call(Runtime::BLOCK, loc, 0);
+ Expression* call = Runtime::make_call(gogo, Runtime::BLOCK, loc, 0);
Statement* s = Statement::make_statement(call, false);
bnil->add_statement(s);
Statement* ifs = Statement::make_if_statement(cond, bnil, NULL, loc);
@@ -6030,7 +5947,7 @@ Select_statement::lower_one_case(Block* b)
// Lower a two-case select statement with one default case.
Statement*
-Select_statement::lower_two_case(Block* b)
+Select_statement::lower_two_case(Gogo* gogo, Block* b)
{
Select_clauses::Select_clause& chancase =
(this->clauses_->at(0).is_default()
@@ -6063,7 +5980,8 @@ Select_statement::lower_two_case(Block* b)
Expression* ref = Expression::make_temporary_reference(ts, loc);
Expression* addr = Expression::make_unary(OPERATOR_AND, ref, loc);
- cond = Runtime::make_call(Runtime::SELECTNBSEND, loc, 2, chanref, addr);
+ cond = Runtime::make_call(gogo, Runtime::SELECTNBSEND, loc, 2,
+ chanref, addr);
bchan = chancase.statements();
}
else
@@ -6075,8 +5993,8 @@ Select_statement::lower_two_case(Block* b)
Expression* addr = Expression::make_unary(OPERATOR_AND, ref, loc);
// selected, ok = selectnbrecv(&lhs, chan)
- Call_expression* call = Runtime::make_call(Runtime::SELECTNBRECV, loc, 2,
- addr, chanref);
+ Call_expression* call = Runtime::make_call(gogo, Runtime::SELECTNBRECV,
+ loc, 2, addr, chanref);
Temporary_statement* selected_temp =
Statement::make_temporary(Type::make_boolean_type(),
@@ -6484,7 +6402,8 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
// calls.
if (range_type->map_type() != NULL)
{
- Statement* clear = this->lower_map_range_clear(range_type,
+ Statement* clear = this->lower_map_range_clear(gogo,
+ range_type,
enclosing,
orig_range_expr,
range_object,
@@ -6951,7 +6870,7 @@ For_range_statement::lower_range_string(Gogo* gogo,
ref = this->make_range_ref(range_object, range_temp, loc);
index_ref = Expression::make_temporary_reference(index_temp, loc);
- call = Runtime::make_call(Runtime::DECODERUNE, loc, 2, ref, index_ref);
+ call = Runtime::make_call(gogo, Runtime::DECODERUNE, loc, 2, ref, index_ref);
value_ref = Expression::make_temporary_reference(value_temp, loc);
value_ref->set_is_lvalue();
@@ -7030,7 +6949,7 @@ For_range_statement::lower_range_map(Gogo* gogo,
Expression* p2 = this->make_range_ref(range_object, range_temp, loc);
Expression* ref = Expression::make_temporary_reference(hiter, loc);
Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc);
- Expression* call = Runtime::make_call(Runtime::MAPITERINIT, loc, 3,
+ Expression* call = Runtime::make_call(gogo, Runtime::MAPITERINIT, loc, 3,
p1, p2, p3);
init->add_statement(Statement::make_statement(call, true));
@@ -7080,7 +6999,7 @@ For_range_statement::lower_range_map(Gogo* gogo,
ref = Expression::make_temporary_reference(hiter, loc);
p1 = Expression::make_unary(OPERATOR_AND, ref, loc);
- call = Runtime::make_call(Runtime::MAPITERNEXT, loc, 1, p1);
+ call = Runtime::make_call(gogo, Runtime::MAPITERNEXT, loc, 1, p1);
post->add_statement(Statement::make_statement(call, true));
*ppost = post;
@@ -7164,7 +7083,8 @@ For_range_statement::lower_range_channel(Gogo*,
// containing the call. Return NULL otherwise.
Statement*
-For_range_statement::lower_map_range_clear(Type* map_type,
+For_range_statement::lower_map_range_clear(Gogo* gogo,
+ Type* map_type,
Block* enclosing,
Expression* orig_range_expr,
Named_object* range_object,
@@ -7204,7 +7124,7 @@ For_range_statement::lower_map_range_clear(Type* map_type,
// Everything matches. Rewrite to mapclear(TYPE, MAP).
Expression* e1 = Expression::make_type_descriptor(map_type, loc);
Expression* e2 = this->make_range_ref(range_object, range_temp, loc);
- call = Runtime::make_call(Runtime::MAPCLEAR, loc, 2, e1, e2);
+ call = Runtime::make_call(gogo, Runtime::MAPCLEAR, loc, 2, e1, e2);
return Statement::make_statement(call, true);
}
@@ -7293,12 +7213,13 @@ For_range_statement::lower_array_range_clear(Gogo* gogo,
Expression* sz_arg = Expression::make_temporary_reference(ts2, loc);
Expression* call;
if (elem_type->has_pointer())
- call = Runtime::make_call(Runtime::MEMCLRHASPTR, loc, 2, ptr_arg, sz_arg);
+ call = Runtime::make_call(gogo, Runtime::MEMCLRHASPTR, loc, 2,
+ ptr_arg, sz_arg);
else
{
Type* int32_type = Type::lookup_integer_type("int32");
Expression* zero32 = Expression::make_integer_ul(0, int32_type, loc);
- call = Runtime::make_call(Runtime::BUILTIN_MEMSET, loc, 3, ptr_arg,
+ call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMSET, loc, 3, ptr_arg,
zero32, sz_arg);
}
Statement* cs3 = Statement::make_statement(call, true);
diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h
index 3d1ee33..9a920ba 100644
--- a/gcc/go/gofrontend/statements.h
+++ b/gcc/go/gofrontend/statements.h
@@ -55,42 +55,6 @@ class Bstatement;
class Bvariable;
class Ast_dump_context;
-// This class is used to traverse assignments made by a statement
-// which makes assignments.
-
-class Traverse_assignments
-{
- public:
- Traverse_assignments()
- { }
-
- virtual ~Traverse_assignments()
- { }
-
- // This is called for a variable initialization.
- virtual void
- initialize_variable(Named_object*) = 0;
-
- // This is called for each assignment made by the statement. PLHS
- // points to the left hand side, and PRHS points to the right hand
- // side. PRHS may be NULL if there is no associated expression, as
- // in the bool set by a non-blocking receive.
- virtual void
- assignment(Expression** plhs, Expression** prhs) = 0;
-
- // This is called for each expression which is not passed to the
- // assignment function. This is used for some of the statements
- // which assign two values, for which there is no expression which
- // describes the value. For ++ and -- the value is passed to both
- // the assignment method and the rhs method. IS_STORED is true if
- // this value is being stored directly. It is false if the value is
- // computed but not stored. IS_LOCAL is true if the value is being
- // stored in a local variable or this is being called by a return
- // statement.
- virtual void
- value(Expression**, bool is_stored, bool is_local) = 0;
-};
-
// A single statement.
class Statement
@@ -253,7 +217,7 @@ class Statement
// Make a type switch statement.
static Type_switch_statement*
- make_type_switch_statement(const std::string&, Expression*, Location);
+ make_type_switch_statement(Expression*, Location);
// Make a send statement.
static Send_statement*
@@ -292,13 +256,6 @@ class Statement
int
traverse_contents(Traverse*);
- // If this statement assigns some values, it calls a function for
- // each value to which this statement assigns a value, and returns
- // true. If this statement does not assign any values, it returns
- // false.
- bool
- traverse_assignments(Traverse_assignments* tassign);
-
// Lower a statement. This is called immediately after parsing to
// simplify statements for further processing. It returns the same
// Statement or a new one. FUNCTION is the function containing this
@@ -321,7 +278,7 @@ class Statement
// Set type information for unnamed constants.
void
- determine_types();
+ determine_types(Gogo*);
// Check types in a statement. This simply checks that any
// expressions used by the statement have the right type.
@@ -486,12 +443,6 @@ class Statement
virtual int
do_traverse(Traverse*) = 0;
- // Implemented by child class: traverse assignments. Any statement
- // which includes an assignment should implement this.
- virtual bool
- do_traverse_assignments(Traverse_assignments*)
- { return false; }
-
// Implemented by the child class: lower this statement to a simpler
// one.
virtual Statement*
@@ -508,7 +459,7 @@ class Statement
// constants. Any statement which includes an expression needs to
// implement this.
virtual void
- do_determine_types()
+ do_determine_types(Gogo*)
{ }
// Implemented by child class: check types of expressions used in a
@@ -633,14 +584,11 @@ class Assignment_statement : public Statement
int
do_traverse(Traverse* traverse);
- bool
- do_traverse_assignments(Traverse_assignments*);
-
virtual Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
@@ -753,11 +701,8 @@ class Temporary_statement : public Statement
int
do_traverse(Traverse*);
- bool
- do_traverse_assignments(Traverse_assignments*);
-
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
@@ -820,9 +765,6 @@ class Variable_declaration_statement : public Statement
int
do_traverse(Traverse*);
- bool
- do_traverse_assignments(Traverse_assignments*);
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -869,9 +811,6 @@ class Return_statement : public Statement
do_traverse(Traverse* traverse)
{ return this->traverse_expression_list(traverse, this->vals_); }
- bool
- do_traverse_assignments(Traverse_assignments*);
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -916,7 +855,7 @@ class Expression_statement : public Statement
{ return this->traverse_expression(traverse, &this->expr_); }
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
@@ -983,8 +922,8 @@ class Block_statement : public Statement
{ return this->block_->traverse(traverse); }
void
- do_determine_types()
- { this->block_->determine_types(); }
+ do_determine_types(Gogo* gogo)
+ { this->block_->determine_types(gogo); }
int
do_inlining_cost()
@@ -1033,7 +972,7 @@ class Send_statement : public Statement
do_traverse(Traverse* traverse);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
@@ -1106,7 +1045,7 @@ class Select_clauses
// Determine types.
void
- determine_types();
+ determine_types(Gogo*);
// Check types.
void
@@ -1157,7 +1096,7 @@ class Select_clauses
// Determine types.
void
- determine_types();
+ determine_types(Gogo*);
// Check types.
void
@@ -1326,8 +1265,8 @@ class Select_statement : public Statement
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
void
- do_determine_types()
- { this->clauses_->determine_types(); }
+ do_determine_types(Gogo* gogo)
+ { this->clauses_->determine_types(gogo); }
void
do_check_types(Gogo*)
@@ -1345,11 +1284,11 @@ class Select_statement : public Statement
private:
// Lower a one-case select statement.
Statement*
- lower_one_case(Block*);
+ lower_one_case(Gogo*, Block*);
// Lower a two-case select statement with one defualt case.
Statement*
- lower_two_case(Block*);
+ lower_two_case(Gogo*, Block*);
// The select clauses.
Select_clauses* clauses_;
@@ -1383,11 +1322,8 @@ class Thunk_statement : public Statement
int
do_traverse(Traverse* traverse);
- bool
- do_traverse_assignments(Traverse_assignments*);
-
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
@@ -1655,7 +1591,7 @@ class If_statement : public Statement
do_traverse(Traverse*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
@@ -1719,10 +1655,6 @@ class For_statement : public Statement
int
do_traverse(Traverse*);
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -1783,10 +1715,6 @@ class For_range_statement : public Statement
int
do_traverse(Traverse*);
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
@@ -1832,7 +1760,7 @@ class For_range_statement : public Statement
Block**);
Statement*
- lower_map_range_clear(Type*, Block*, Expression*, Named_object*,
+ lower_map_range_clear(Gogo*, Type*, Block*, Expression*, Named_object*,
Temporary_statement*, Location);
Statement*
@@ -1894,7 +1822,7 @@ class Case_clauses
// Determine types of expressions. The Type parameter is the type
// of the switch value.
void
- determine_types(Type*);
+ determine_types(Gogo*, Type*);
// Check types. The Type parameter is the type of the switch value.
bool
@@ -1968,7 +1896,7 @@ class Case_clauses
// Determine types.
void
- determine_types(Type*);
+ determine_types(Gogo*, Type*);
// Check types.
bool
@@ -2191,10 +2119,9 @@ class Type_case_clauses
class Type_switch_statement : public Statement
{
public:
- Type_switch_statement(const std::string& name, Expression* expr,
- Location location)
+ Type_switch_statement(Expression* expr, Location location)
: Statement(STATEMENT_TYPE_SWITCH, location),
- name_(name), expr_(expr), clauses_(NULL), break_label_(NULL)
+ expr_(expr), clauses_(NULL), break_label_(NULL)
{ }
// Add the clauses.
@@ -2227,10 +2154,7 @@ class Type_switch_statement : public Statement
do_may_fall_through() const;
private:
- // The name of the variable declared in the type switch guard. Empty if there
- // is no variable declared.
- std::string name_;
- // The expression we are switching on if there is no variable.
+ // The expression we are switching on.
Expression* expr_;
// The type case clauses.
Type_case_clauses* clauses_;
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 7f471ea..e6b1250 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -1555,7 +1555,7 @@ Type::convert_builtin_named_types(Gogo* gogo)
p != Type::named_builtin_types.end();
++p)
{
- bool r = (*p)->verify();
+ bool r = (*p)->verify(gogo);
go_assert(r);
(*p)->convert(gogo);
}
@@ -5950,7 +5950,7 @@ Struct_type::do_traverse(Traverse* traverse)
// Verify that the struct type is complete and valid.
bool
-Struct_type::do_verify()
+Struct_type::do_verify(Gogo*)
{
Struct_field_list* fields = this->fields_;
if (fields == NULL)
@@ -7337,13 +7337,13 @@ Array_type::do_traverse(Traverse* traverse)
// Check that the length is valid.
bool
-Array_type::verify_length()
+Array_type::verify_length(Gogo* gogo)
{
if (this->length_ == NULL)
return true;
Type_context context(Type::lookup_integer_type("int"), false);
- this->length_->determine_type(&context);
+ this->length_->determine_type(gogo, &context);
if (this->length_->is_error_expression()
|| this->length_->type()->is_error())
@@ -7421,14 +7421,14 @@ Array_type::verify_length()
// Verify the type.
bool
-Array_type::do_verify()
+Array_type::do_verify(Gogo* gogo)
{
if (this->element_type()->is_error_type())
{
this->set_is_error();
return false;
}
- if (!this->verify_length())
+ if (!this->verify_length(gogo))
{
this->length_ = Expression::make_error(this->length_->location());
this->set_is_error();
@@ -8225,7 +8225,7 @@ Map_type::do_traverse(Traverse* traverse)
// Check that the map type is OK.
bool
-Map_type::do_verify()
+Map_type::do_verify(Gogo*)
{
// The runtime support uses "map[void]void".
if (!this->key_type_->is_comparable() && !this->key_type_->is_void_type())
@@ -8768,7 +8768,7 @@ Type::make_map_type(Type* key_type, Type* val_type, Location location)
// Verify.
bool
-Channel_type::do_verify()
+Channel_type::do_verify(Gogo*)
{
// We have no location for this error, but this is not something the
// ordinary user will see.
@@ -10833,7 +10833,7 @@ Find_alias::type(Type* type)
// Verify that a named type does not refer to itself.
bool
-Named_type::do_verify()
+Named_type::do_verify(Gogo*)
{
if (this->is_verified_)
return true;
@@ -11016,7 +11016,7 @@ Named_type::convert(Gogo* gogo)
// If we are called to turn unsafe.Sizeof into a constant, we may
// not have verified the type yet. We have to make sure it is
// verified, since that sets the list of dependencies.
- this->verify();
+ this->verify(gogo);
// Convert all the dependencies. If they refer indirectly back to
// this type, they will pick up the intermediate representation we just
@@ -12791,7 +12791,7 @@ Forward_declaration_type::do_traverse(Traverse* traverse)
// Verify the type.
bool
-Forward_declaration_type::do_verify()
+Forward_declaration_type::do_verify(Gogo*)
{
if (!this->is_defined() && !this->is_nil_constant_as_type())
{
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 057fa01..15f29f7 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -584,8 +584,8 @@ class Type
// returns false if the type is invalid and we should not continue
// traversing it.
bool
- verify()
- { return this->do_verify(); }
+ verify(Gogo* gogo)
+ { return this->do_verify(gogo); }
// Bit flags to pass to are_identical and friends.
@@ -1101,7 +1101,7 @@ class Type
// Verify the type.
virtual bool
- do_verify()
+ do_verify(Gogo*)
{ return true; }
virtual bool
@@ -2297,8 +2297,8 @@ class Pointer_type : public Type
do_traverse(Traverse*);
bool
- do_verify()
- { return this->to_type_->verify(); }
+ do_verify(Gogo* gogo)
+ { return this->to_type_->verify(gogo); }
// If this is a pointer to a type that can't be in the heap, then
// the garbage collector does not have to look at this, so pretend
@@ -2675,7 +2675,7 @@ class Struct_type : public Type
do_traverse(Traverse*);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const;
@@ -2855,7 +2855,7 @@ class Array_type : public Type
do_traverse(Traverse* traverse);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const;
@@ -2901,7 +2901,7 @@ class Array_type : public Type
private:
bool
- verify_length();
+ verify_length(Gogo*);
Expression*
array_type_descriptor(Gogo*, Named_type*);
@@ -3003,7 +3003,7 @@ class Map_type : public Type
do_traverse(Traverse*);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const
@@ -3123,7 +3123,7 @@ class Channel_type : public Type
{ return Type::traverse(this->element_type_, traverse); }
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const
@@ -3604,7 +3604,7 @@ class Named_type : public Type
{ return Type::traverse(this->type_, traverse); }
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const;
@@ -3762,7 +3762,7 @@ class Forward_declaration_type : public Type
do_traverse(Traverse* traverse);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const
diff --git a/gcc/go/gofrontend/wb.cc b/gcc/go/gofrontend/wb.cc
index e039c66..0621014 100644
--- a/gcc/go/gofrontend/wb.cc
+++ b/gcc/go/gofrontend/wb.cc
@@ -923,7 +923,8 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing,
{
// These types are all represented by a single pointer.
rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc);
- call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs);
+ call = Runtime::make_call(this, Runtime::GCWRITEBARRIER, loc, 2,
+ lhs, rhs);
}
break;
@@ -953,7 +954,8 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing,
assign = Statement::make_assignment(lhs, rhs, loc);
lhs = Expression::make_unary(OPERATOR_AND, lhs, loc);
rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc);
- call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs);
+ call = Runtime::make_call(this, Runtime::GCWRITEBARRIER, loc, 2,
+ lhs, rhs);
}
break;
@@ -990,7 +992,8 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing,
assign = Statement::make_assignment(lhs, rhs, loc);
lhs = Expression::make_unary(OPERATOR_AND, lhs, loc);
rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc);
- call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs);
+ call = Runtime::make_call(this, Runtime::GCWRITEBARRIER, loc, 2,
+ lhs, rhs);
}
break;
@@ -1033,7 +1036,8 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing,
assign = Statement::make_assignment(lhs, rhs, loc);
lhs = Expression::make_unary(OPERATOR_AND, lhs, loc);
rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc);
- call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs);
+ call = Runtime::make_call(this, Runtime::GCWRITEBARRIER, loc, 2,
+ lhs, rhs);
break;
}
// fallthrough
@@ -1043,14 +1047,15 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing,
{
rhs = Expression::unpack_direct_iface(rhs, loc);
rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc);
- call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs);
+ call = Runtime::make_call(this, Runtime::GCWRITEBARRIER, loc, 2,
+ lhs, rhs);
}
else
{
// TODO: split assignments for small struct/array?
rhs = Expression::make_unary(OPERATOR_AND, rhs, loc);
rhs->unary_expression()->set_does_not_escape();
- call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
+ call = Runtime::make_call(this, Runtime::TYPEDMEMMOVE, loc, 3,
Expression::make_type_descriptor(type, loc),
lhs, rhs);
}
diff --git a/gcc/input.cc b/gcc/input.cc
index fd09fcc..6256d81 100644
--- a/gcc/input.cc
+++ b/gcc/input.cc
@@ -1530,9 +1530,9 @@ dump_location_info (FILE *stream)
map->start_location,
(map->start_location
+ MACRO_MAP_NUM_MACRO_TOKENS (map)));
- inform (MACRO_MAP_EXPANSION_POINT_LOCATION (map),
+ inform (map->get_expansion_point_location (),
"expansion point is location %i",
- MACRO_MAP_EXPANSION_POINT_LOCATION (map));
+ map->get_expansion_point_location ());
fprintf (stream, " map->start_location: %u\n",
map->start_location);
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index 61d5a9e..e7451b9 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -3208,7 +3208,7 @@ expand_VEC_CONVERT (internal_fn, gcall *)
gcc_unreachable ();
}
-/* Expand IFN_RAWMEMCHAR internal function. */
+/* Expand IFN_RAWMEMCHR internal function. */
void
expand_RAWMEMCHR (internal_fn, gcall *stmt)
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index e056030..788157e 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1271,6 +1271,8 @@ ipa_argagg_value_list::dump (FILE *f)
print_generic_expr (f, av.value);
if (av.by_ref)
fprintf (f, "(by_ref)");
+ if (av.killed)
+ fprintf (f, "(killed)");
comma = true;
}
fprintf (f, "\n");
@@ -1437,6 +1439,8 @@ ipa_argagg_value_list::push_adjusted_values (unsigned src_index,
new_av.unit_offset = av->unit_offset - unit_delta;
new_av.index = dest_index;
new_av.by_ref = av->by_ref;
+ gcc_assert (!av->killed);
+ new_av.killed = false;
/* Quick check that the offsets we push are indeed increasing. */
gcc_assert (first
@@ -1473,6 +1477,7 @@ push_agg_values_from_plats (ipcp_param_lattices *plats, int dest_index,
iav.unit_offset = aglat->offset / BITS_PER_UNIT - unit_delta;
iav.index = dest_index;
iav.by_ref = plats->aggs_by_ref;
+ iav.killed = false;
gcc_assert (first
|| iav.unit_offset > prev_unit_offset);
@@ -2139,6 +2144,7 @@ ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node,
iav.unit_offset = item.offset / BITS_PER_UNIT;
iav.index = dst_index;
iav.by_ref = agg_jfunc->by_ref;
+ iav.killed = 0;
gcc_assert (first
|| iav.unit_offset > prev_unit_offset);
@@ -3981,6 +3987,7 @@ estimate_local_effects (struct cgraph_node *node)
avals.m_known_aggs[j].unit_offset = unit_offset;
avals.m_known_aggs[j].index = index;
avals.m_known_aggs[j].by_ref = plats->aggs_by_ref;
+ avals.m_known_aggs[j].killed = false;
perform_estimation_of_a_value (node, &avals,
removable_params_cost, 0, val);
@@ -5857,6 +5864,7 @@ push_agg_values_for_index_from_edge (struct cgraph_edge *cs, int index,
iav.unit_offset = agg_jf.offset / BITS_PER_UNIT;
iav.index = index;
iav.by_ref = jfunc->agg.by_ref;
+ iav.killed = false;
gcc_assert (first
|| iav.unit_offset > prev_unit_offset);
diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index 836d091..bbdfd44 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -218,6 +218,7 @@ sem_item::target_supports_symbol_aliases_p (void)
#if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
return false;
#else
+ gcc_checking_assert (TARGET_SUPPORTS_ALIASES);
return true;
#endif
}
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index fe55621..cbe788a 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -4065,21 +4065,74 @@ remap_kills (vec <modref_access_node> &kills, const vec <int> &map)
i++;
}
+/* Return true if the V can overlap with KILL. */
+
+static bool
+ipcp_argagg_and_kill_overlap_p (const ipa_argagg_value &v,
+ const modref_access_node &kill)
+{
+ if (kill.parm_index == v.index)
+ {
+ gcc_assert (kill.parm_offset_known);
+ gcc_assert (known_eq (kill.max_size, kill.size));
+ poly_int64 repl_size;
+ bool ok = poly_int_tree_p (TYPE_SIZE (TREE_TYPE (v.value)),
+ &repl_size);
+ gcc_assert (ok);
+ poly_int64 repl_offset (v.unit_offset);
+ repl_offset <<= LOG2_BITS_PER_UNIT;
+ poly_int64 combined_offset
+ = (kill.parm_offset << LOG2_BITS_PER_UNIT) + kill.offset;
+ if (ranges_maybe_overlap_p (repl_offset, repl_size,
+ combined_offset, kill.size))
+ return true;
+ }
+ return false;
+}
+
/* If signature changed, update the summary. */
static void
update_signature (struct cgraph_node *node)
{
- clone_info *info = clone_info::get (node);
- if (!info || !info->param_adjustments)
- return;
-
modref_summary *r = optimization_summaries
? optimization_summaries->get (node) : NULL;
modref_summary_lto *r_lto = summaries_lto
? summaries_lto->get (node) : NULL;
if (!r && !r_lto)
return;
+
+ /* Propagating constants in killed memory can lead to eliminated stores in
+ both callees (because they are considered redundant) and callers, leading
+ to missing them altogether. */
+ ipcp_transformation *ipcp_ts = ipcp_get_transformation_summary (node);
+ if (ipcp_ts)
+ {
+ for (auto &v : ipcp_ts->m_agg_values)
+ {
+ if (!v.by_ref)
+ continue;
+ if (r)
+ for (const modref_access_node &kill : r->kills)
+ if (ipcp_argagg_and_kill_overlap_p (v, kill))
+ {
+ v.killed = true;
+ break;
+ }
+ if (!v.killed && r_lto)
+ for (const modref_access_node &kill : r_lto->kills)
+ if (ipcp_argagg_and_kill_overlap_p (v, kill))
+ {
+ v.killed = true;
+ break;
+ }
+ }
+ }
+
+ clone_info *info = clone_info::get (node);
+ if (!info || !info->param_adjustments)
+ return;
+
if (dump_file)
{
fprintf (dump_file, "Updating summary for %s from:\n",
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 9442cdd..827bdb6 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -5299,6 +5299,7 @@ write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, av.by_ref, 1);
+ bp_pack_value (&bp, av.killed, 1);
streamer_write_bitpack (&bp);
}
@@ -5331,6 +5332,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
bitpack_d bp = streamer_read_bitpack (ib);
av->by_ref = bp_unpack_value (&bp, 1);
+ av->killed = bp_unpack_value (&bp, 1);
}
}
@@ -5616,7 +5618,9 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
/* If IPA-CP discovered a constant in parameter PARM at OFFSET of a given SIZE
- whether passed by reference or not is given by BY_REF - return that
- constant. Otherwise return NULL_TREE. */
+ constant. Otherwise return NULL_TREE. The is supposed to be used only
+ after clone materialization and transformation is done (because it asserts
+ that killed constants have been pruned). */
tree
ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
@@ -5634,7 +5638,11 @@ ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
ipa_argagg_value_list avl (ts);
unsigned unit_offset = bit_offset / BITS_PER_UNIT;
- tree v = avl.get_value (index, unit_offset, by_ref);
+ const ipa_argagg_value *av = avl.get_elt (index, unit_offset);
+ if (!av || av->by_ref != by_ref)
+ return NULL_TREE;
+ gcc_assert (!av->killed);
+ tree v = av->value;
if (!v
|| maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), bit_size))
return NULL_TREE;
@@ -5884,6 +5892,11 @@ ipcp_transform_function (struct cgraph_node *node)
free_ipa_bb_info (bi);
fbi.bb_infos.release ();
+ ts->remove_argaggs_if ([](const ipa_argagg_value &v)
+ {
+ return v.killed;
+ });
+
vec_free (descriptors);
if (cfg_changed)
delete_unreachable_blocks_update_callgraph (node, false);
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index a7f34a8..fcd0e5c 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -213,6 +213,10 @@ struct GTY(()) ipa_argagg_value
unsigned index : IPA_PROP_ARG_INDEX_LIMIT_BITS;
/* Whether the value was passed by reference. */
unsigned by_ref : 1;
+ /* Set if the value should not be used after materialization in
+ value_numbering. It is kept around just so that clone materialization can
+ distinguish a combined IPA-CP and IPA-SRA from a deleted argument. */
+ unsigned killed : 1;
};
/* A view into a sorted list of aggregate values in a particular context, be it
@@ -947,6 +951,39 @@ struct GTY(()) ipcp_transformation
void maybe_create_parm_idx_map (tree fndecl);
+ /* Remove all elements in m_agg_values on which PREDICATE returns true. */
+
+ template<typename pred_function>
+ void remove_argaggs_if (pred_function &&predicate)
+ {
+ unsigned ts_len = vec_safe_length (m_agg_values);
+ if (ts_len == 0)
+ return;
+
+ bool removed_item = false;
+ unsigned dst_index = 0;
+
+ for (unsigned i = 0; i < ts_len; i++)
+ {
+ ipa_argagg_value *v = &(*m_agg_values)[i];
+ if (!predicate (*v))
+ {
+ if (removed_item)
+ (*m_agg_values)[dst_index] = *v;
+ dst_index++;
+ }
+ else
+ removed_item = true;
+ }
+ if (dst_index == 0)
+ {
+ ggc_free (m_agg_values);
+ m_agg_values = NULL;
+ }
+ else if (removed_item)
+ m_agg_values->truncate (dst_index);
+ }
+
/* Known aggregate values. */
vec<ipa_argagg_value, va_gc> *m_agg_values;
/* Value range information. */
diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
index 495d7e6..6ffad33 100644
--- a/gcc/ipa-sra.cc
+++ b/gcc/ipa-sra.cc
@@ -4104,35 +4104,10 @@ mark_callers_calls_comdat_local (struct cgraph_node *node, void *)
static void
zap_useless_ipcp_results (const isra_func_summary *ifs, ipcp_transformation *ts)
{
- unsigned ts_len = vec_safe_length (ts->m_agg_values);
-
- if (ts_len == 0)
- return;
-
- bool removed_item = false;
- unsigned dst_index = 0;
-
- for (unsigned i = 0; i < ts_len; i++)
- {
- ipa_argagg_value *v = &(*ts->m_agg_values)[i];
- const isra_param_desc *desc = &(*ifs->m_parameters)[v->index];
-
- if (!desc->locally_unused)
- {
- if (removed_item)
- (*ts->m_agg_values)[dst_index] = *v;
- dst_index++;
- }
- else
- removed_item = true;
- }
- if (dst_index == 0)
- {
- ggc_free (ts->m_agg_values);
- ts->m_agg_values = NULL;
- }
- else if (removed_item)
- ts->m_agg_values->truncate (dst_index);
+ ts->remove_argaggs_if ([ifs](const ipa_argagg_value &v)
+ {
+ return (*ifs->m_parameters)[v.index].locally_unused;
+ });
bool useful_vr = false;
unsigned count = vec_safe_length (ts->m_vr);
diff --git a/gcc/ipa-visibility.cc b/gcc/ipa-visibility.cc
index 8ec82bb..8ce5611 100644
--- a/gcc/ipa-visibility.cc
+++ b/gcc/ipa-visibility.cc
@@ -622,41 +622,43 @@ function_and_variable_visibility (bool whole_program)
/* All aliases should be processed at this point. */
gcc_checking_assert (!alias_pairs || !alias_pairs->length ());
-#ifdef ASM_OUTPUT_DEF
- FOR_EACH_DEFINED_FUNCTION (node)
+ if (TARGET_SUPPORTS_ALIASES)
{
- if (node->get_availability () != AVAIL_INTERPOSABLE
- || DECL_EXTERNAL (node->decl)
- || node->has_aliases_p ()
- || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
- continue;
-
- cgraph_node *alias = 0;
- cgraph_edge *next_edge;
- for (cgraph_edge *e = node->callees; e; e = next_edge)
+ FOR_EACH_DEFINED_FUNCTION (node)
{
- next_edge = e->next_callee;
- /* Recursive function calls usually can't be interposed. */
-
- if (!e->recursive_p ())
+ if (node->get_availability () != AVAIL_INTERPOSABLE
+ || DECL_EXTERNAL (node->decl)
+ || node->has_aliases_p ()
+ || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
continue;
- if (!alias)
+ cgraph_node *alias = 0;
+ cgraph_edge *next_edge;
+ for (cgraph_edge *e = node->callees; e; e = next_edge)
{
- alias = dyn_cast<cgraph_node *> (node->noninterposable_alias ());
- gcc_assert (alias && alias != node);
- }
+ next_edge = e->next_callee;
+ /* Recursive function calls usually can't be interposed. */
- e->redirect_callee (alias);
- if (gimple_has_body_p (e->caller->decl))
- {
- push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
- cgraph_edge::redirect_call_stmt_to_callee (e);
- pop_cfun ();
+ if (!e->recursive_p ())
+ continue;
+
+ if (!alias)
+ {
+ alias
+ = dyn_cast<cgraph_node *> (node->noninterposable_alias ());
+ gcc_assert (alias && alias != node);
+ }
+
+ e->redirect_callee (alias);
+ if (gimple_has_body_p (e->caller->decl))
+ {
+ push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
+ cgraph_edge::redirect_call_stmt_to_callee (e);
+ pop_cfun ();
+ }
}
}
}
-#endif
FOR_EACH_FUNCTION (node)
{
diff --git a/gcc/ira-costs.cc b/gcc/ira-costs.cc
index d9e700e..50f8077 100644
--- a/gcc/ira-costs.cc
+++ b/gcc/ira-costs.cc
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
+#include "regset.h"
#include "ira.h"
#include "ira-int.h"
#include "addresses.h"
@@ -1757,6 +1758,150 @@ process_bb_node_for_costs (ira_loop_tree_node_t loop_tree_node)
process_bb_for_costs (bb);
}
+/* Check that reg REGNO can be changed by TO in INSN. Return true in case the
+ result insn would be valid one. */
+static bool
+equiv_can_be_consumed_p (int regno, rtx to, rtx_insn *insn)
+{
+ validate_replace_src_group (regno_reg_rtx[regno], to, insn);
+ bool res = verify_changes (0);
+ cancel_changes (0);
+ return res;
+}
+
+/* Return true if X contains a pseudo with equivalence. In this case also
+ return the pseudo through parameter REG. If the pseudo is a part of subreg,
+ return the subreg through parameter SUBREG. */
+
+static bool
+get_equiv_regno (rtx x, int &regno, rtx &subreg)
+{
+ subreg = NULL_RTX;
+ if (GET_CODE (x) == SUBREG)
+ {
+ subreg = x;
+ x = SUBREG_REG (x);
+ }
+ if (REG_P (x)
+ && (ira_reg_equiv[REGNO (x)].memory != NULL
+ || ira_reg_equiv[REGNO (x)].invariant != NULL
+ || ira_reg_equiv[REGNO (x)].constant != NULL))
+ {
+ regno = REGNO (x);
+ return true;
+ }
+ RTX_CODE code = GET_CODE (x);
+ const char *fmt = GET_RTX_FORMAT (code);
+
+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ if (fmt[i] == 'e')
+ {
+ if (get_equiv_regno (XEXP (x, i), regno, subreg))
+ return true;
+ }
+ else if (fmt[i] == 'E')
+ {
+ for (int j = 0; j < XVECLEN (x, i); j++)
+ if (get_equiv_regno (XVECEXP (x, i, j), regno, subreg))
+ return true;
+ }
+ return false;
+}
+
+/* A pass through the current function insns. Calculate costs of using
+ equivalences for pseudos and store them in regno_equiv_gains. */
+
+static void
+calculate_equiv_gains (void)
+{
+ basic_block bb;
+ int regno, freq, cost;
+ rtx subreg;
+ rtx_insn *insn;
+ machine_mode mode;
+ enum reg_class rclass;
+ bitmap_head equiv_pseudos;
+
+ ira_assert (allocno_p);
+ bitmap_initialize (&equiv_pseudos, &reg_obstack);
+ for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--)
+ if (ira_reg_equiv[regno].init_insns != NULL
+ && (ira_reg_equiv[regno].memory != NULL
+ || ira_reg_equiv[regno].invariant != NULL
+ || (ira_reg_equiv[regno].constant != NULL
+ /* Ignore complicated constants which probably will be placed
+ in memory: */
+ && GET_CODE (ira_reg_equiv[regno].constant) != CONST_DOUBLE
+ && GET_CODE (ira_reg_equiv[regno].constant) != CONST_VECTOR
+ && GET_CODE (ira_reg_equiv[regno].constant) != LABEL_REF)))
+ {
+ rtx_insn_list *x;
+ for (x = ira_reg_equiv[regno].init_insns; x != NULL; x = x->next ())
+ {
+ insn = x->insn ();
+ rtx set = single_set (insn);
+
+ if (set == NULL_RTX || SET_DEST (set) != regno_reg_rtx[regno])
+ break;
+ bb = BLOCK_FOR_INSN (insn);
+ ira_curr_regno_allocno_map
+ = ira_bb_nodes[bb->index].parent->regno_allocno_map;
+ mode = PSEUDO_REGNO_MODE (regno);
+ rclass = pref[COST_INDEX (regno)];
+ ira_init_register_move_cost_if_necessary (mode);
+ if (ira_reg_equiv[regno].memory != NULL)
+ cost = ira_memory_move_cost[mode][rclass][1];
+ else
+ cost = ira_register_move_cost[mode][rclass][rclass];
+ freq = REG_FREQ_FROM_BB (bb);
+ regno_equiv_gains[regno] += cost * freq;
+ }
+ if (x != NULL)
+ /* We found complicated equiv or reverse equiv mem=reg. Ignore
+ them. */
+ regno_equiv_gains[regno] = 0;
+ else
+ bitmap_set_bit (&equiv_pseudos, regno);
+ }
+
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ freq = REG_FREQ_FROM_BB (bb);
+ ira_curr_regno_allocno_map
+ = ira_bb_nodes[bb->index].parent->regno_allocno_map;
+ FOR_BB_INSNS (bb, insn)
+ {
+ if (!NONDEBUG_INSN_P (insn)
+ || !get_equiv_regno (PATTERN (insn), regno, subreg)
+ || !bitmap_bit_p (&equiv_pseudos, regno))
+ continue;
+ rtx subst = ira_reg_equiv[regno].memory;
+
+ if (subst == NULL)
+ subst = ira_reg_equiv[regno].constant;
+ if (subst == NULL)
+ subst = ira_reg_equiv[regno].invariant;
+ ira_assert (subst != NULL);
+ mode = PSEUDO_REGNO_MODE (regno);
+ ira_init_register_move_cost_if_necessary (mode);
+ bool consumed_p = equiv_can_be_consumed_p (regno, subst, insn);
+
+ rclass = pref[COST_INDEX (regno)];
+ if (MEM_P (subst)
+ /* If it is a change of constant into double for example, the
+ result constant probably will be placed in memory. */
+ || (subreg != NULL_RTX && !INTEGRAL_MODE_P (GET_MODE (subreg))))
+ cost = ira_memory_move_cost[mode][rclass][1] + (consumed_p ? 0 : 1);
+ else if (consumed_p)
+ continue;
+ else
+ cost = ira_register_move_cost[mode][rclass][rclass];
+ regno_equiv_gains[regno] -= cost * freq;
+ }
+ }
+ bitmap_clear (&equiv_pseudos);
+}
+
/* Find costs of register classes and memory for allocnos or pseudos
and their best costs. Set up preferred, alternative and allocno
classes for pseudos. */
@@ -1855,6 +2000,12 @@ find_costs_and_classes (FILE *dump_file)
if (pass == 0)
pref = pref_buffer;
+ if (ira_use_lra_p && allocno_p && pass == 1)
+ /* It is a pass through all insns. So do it once and only for RA (not
+ for insn scheduler) when we already found preferable pseudo register
+ classes on the previous pass. */
+ calculate_equiv_gains ();
+
/* Now for each allocno look at how desirable each class is and
find which class is preferred. */
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
@@ -1947,6 +2098,17 @@ find_costs_and_classes (FILE *dump_file)
}
if (i >= first_moveable_pseudo && i < last_moveable_pseudo)
i_mem_cost = 0;
+ else if (ira_use_lra_p)
+ {
+ if (equiv_savings > 0)
+ {
+ i_mem_cost = 0;
+ if (ira_dump_file != NULL && internal_flag_ira_verbose > 5)
+ fprintf (ira_dump_file,
+ " Use MEM for r%d as the equiv savings is %d\n",
+ i, equiv_savings);
+ }
+ }
else if (equiv_savings < 0)
i_mem_cost = -equiv_savings;
else if (equiv_savings > 0)
@@ -2395,7 +2557,10 @@ ira_costs (void)
total_allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size
* ira_allocnos_num);
initiate_regno_cost_classes ();
- calculate_elim_costs_all_insns ();
+ if (!ira_use_lra_p)
+ /* 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);
setup_allocno_class_and_costs ();
finish_regno_cost_classes ();
@@ -2520,13 +2685,14 @@ ira_tune_allocno_costs (void)
}
}
-/* Add COST to the estimated gain for eliminating REGNO with its
- equivalence. If COST is zero, record that no such elimination is
- possible. */
+/* A hook from the reload pass. Add COST to the estimated gain for eliminating
+ REGNO with its equivalence. If COST is zero, record that no such
+ elimination is possible. */
void
ira_adjust_equiv_reg_cost (unsigned regno, int cost)
{
+ ira_assert (!ira_use_lra_p);
if (cost == 0)
regno_equiv_gains[regno] = 0;
else
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index df2e3b8..e7aa7e2 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,12 @@
+2023-10-25 Vibhav Pant <vibhavp@gmail.com>
+
+ * jit-recording.cc (recording::global::write_to_dump): Fix
+ dump of string literal initializers.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Make-lang.in: Handle Darwin rpaths.
+
2023-10-02 David Malcolm <dmalcolm@redhat.com>
* dummy-frontend.cc (jit_langhook_init): Update for change to
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 326c8c28..9b5b800 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -4966,7 +4966,7 @@ recording::global::write_to_dump (dump &d)
else if (m_rvalue_init)
{
d.write (" = ");
- d.write (m_rvalue_init->get_debug_string ());
+ d.write ("%s", m_rvalue_init->get_debug_string ());
d.write (";\n");
}
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index d10a2a3..0607c8b 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -2609,12 +2609,15 @@ process_alt_operands (int only_alternative)
winreg = true;
if (REG_P (op))
{
+ tree decl;
if (hard_regno[nop] >= 0
&& in_hard_reg_set_p (this_alternative_set,
mode, hard_regno[nop])
- && !TEST_HARD_REG_BIT
- (this_alternative_exclude_start_hard_regs,
- hard_regno[nop]))
+ && ((REG_ATTRS (op) && (decl = REG_EXPR (op)) != NULL
+ && VAR_P (decl) && DECL_HARD_REGISTER (decl))
+ || !(TEST_HARD_REG_BIT
+ (this_alternative_exclude_start_hard_regs,
+ hard_regno[nop]))))
win = true;
else if (hard_regno[nop] < 0
&& in_class_p (op, this_alternative, NULL))
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog
index d690ec9..5ecb9c4 100644
--- a/gcc/m2/ChangeLog
+++ b/gcc/m2/ChangeLog
@@ -1,3 +1,49 @@
+2023-10-27 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/111530
+ * gm2-libs-ch/cgetopt.c (cgetopt_cgetopt_long): Re-format.
+ (cgetopt_cgetopt_long_only): Re-format.
+ (cgetopt_SetOption): Re-format and assign flag to NULL
+ if name is also NULL.
+ * gm2-libs/GetOpt.def (AddLongOption): Add index parameter
+ and change flag to be a VAR parameter rather than a pointer.
+ (GetOptLong): Re-format.
+ (GetOpt): Correct comment.
+ * gm2-libs/GetOpt.mod: Re-write to rely on cgetopt rather
+ than implement long option creation in GetOpt.
+ * gm2-libs/cgetopt.def (SetOption): has_arg type is INTEGER.
+
+2023-10-25 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/111955
+ * gm2-gcc/m2builtins.cc (gm2_isnan_node): New tree.
+ (DoBuiltinIsnan): New function.
+ (m2builtins_BuiltInIsnan): New function.
+ (m2builtins_init): Initialize gm2_isnan_node.
+ (list_of_builtins): Add define for __builtin_isnan.
+ * gm2-libs-ch/wrapc.c (wrapc_isnan): New function.
+ (wrapc_isnanf): New function.
+ (wrapc_isnanl): New function.
+ * gm2-libs/Builtins.def (isnanf): New procedure function.
+ (isnan): New procedure function.
+ (isnanl): New procedure function.
+ * gm2-libs/Builtins.mod:
+ * gm2-libs/wrapc.def (isnan): New function.
+ (isnanf): New function.
+ (isnanl): New function.
+
+2023-10-24 Gaius Mulley <gaiusmod2@gmail.com>
+
+ * gm2-libs/M2Dependent.mod (InitDependencyList): New
+ procedure.
+ (CreateModule): Call InitDependencyList to initialize
+ all fields of DependencyList.
+
+2023-10-24 Gaius Mulley <gaiusmod2@gmail.com>
+
+ * gm2-libs/M2Dependent.mod (CreateModule): Initialize all
+ dependency fields for DependencyList.
+
2023-10-17 Gaius Mulley <gaiusmod2@gmail.com>
PR modula2/111756
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod
index c2ed90f..d82a38c 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -76,7 +76,7 @@ FROM M2Base IMPORT MixTypes, InitBase, Char, Integer, LongReal,
Cardinal, LongInt, LongCard, ZType, RType ;
FROM M2System IMPORT Address ;
-FROM m2decl IMPORT ConstantStringExceedsZType ;
+FROM m2expr IMPORT OverflowZType ;
FROM m2tree IMPORT Tree ;
FROM m2linemap IMPORT BuiltinsLocation ;
FROM StrLib IMPORT StrEqual ;
@@ -6588,12 +6588,12 @@ BEGIN
loc := TokenToLocation (tok) ;
CASE char (s, -1) OF
- 'H': overflow := ConstantStringExceedsZType (loc, string (s), 16, issueError) |
- 'B': overflow := ConstantStringExceedsZType (loc, string (s), 8, issueError) |
- 'A': overflow := ConstantStringExceedsZType (loc, string (s), 2, issueError)
+ 'H': overflow := OverflowZType (loc, string (s), 16, issueError) |
+ 'B': overflow := OverflowZType (loc, string (s), 8, issueError) |
+ 'A': overflow := OverflowZType (loc, string (s), 2, issueError)
ELSE
- overflow := ConstantStringExceedsZType (loc, string (s), 10, issueError)
+ overflow := OverflowZType (loc, string (s), 10, issueError)
END ;
s := KillString (s) ;
RETURN ZType
diff --git a/gcc/m2/gm2-gcc/m2builtins.cc b/gcc/m2/gm2-gcc/m2builtins.cc
index 8774ee7..bcf9a02 100644
--- a/gcc/m2/gm2-gcc/m2builtins.cc
+++ b/gcc/m2/gm2-gcc/m2builtins.cc
@@ -145,6 +145,8 @@ static struct builtin_function_entry list_of_builtins[] = {
BUILT_IN_NORMAL, "memcpy", NULL, NULL, bf_default_lib },
{ "__builtin_isfinite", BT_FN_INT_DOUBLE, BUILT_IN_ISFINITE, BUILT_IN_NORMAL,
"isfinite", NULL, NULL, bf_gcc },
+ { "__builtin_isnan", BT_FN_INT_DOUBLE, BUILT_IN_ISNAN, BUILT_IN_NORMAL,
+ "isnan", NULL, NULL, bf_gcc },
{ "__builtin_sinf", BT_FN_FLOAT_FLOAT, BUILT_IN_SINF, BUILT_IN_NORMAL,
"sinf", NULL, NULL, bf_c99_c90res },
{ "__builtin_sin", BT_FN_DOUBLE_DOUBLE, BUILT_IN_SIN, BUILT_IN_NORMAL, "sin",
@@ -408,6 +410,7 @@ static GTY (()) tree gm2_alloca_node;
static GTY (()) tree gm2_memcpy_node;
static GTY (()) tree gm2_memset_node;
static GTY (()) tree gm2_isfinite_node;
+static GTY (()) tree gm2_isnan_node;
static GTY (()) tree gm2_huge_valf_node;
static GTY (()) tree gm2_huge_val_node;
static GTY (()) tree gm2_huge_vall_node;
@@ -421,6 +424,7 @@ static tree DoBuiltinAlloca (location_t location, tree n);
static tree DoBuiltinMemCopy (location_t location, tree dest, tree src,
tree n);
static tree DoBuiltinIsfinite (location_t location, tree value);
+static tree DoBuiltinIsnan (location_t location, tree value);
static void create_function_prototype (location_t location,
struct builtin_function_entry *fe);
static tree doradix (location_t location, tree type);
@@ -830,6 +834,15 @@ m2builtins_BuiltInIsfinite (location_t location, tree expression)
return DoBuiltinIsfinite (location, expression);
}
+/* BuiltInIsnan - return integer 1 if the real expression is
+ nan otherwise return integer 0. */
+
+tree
+m2builtins_BuiltInIsnan (location_t location, tree expression)
+{
+ return DoBuiltinIsnan (location, expression);
+}
+
/* do_target_support_exists returns true if the builting function
is supported by the target. */
@@ -969,6 +982,17 @@ DoBuiltinIsfinite (location_t location, tree value)
return call;
}
+static tree
+DoBuiltinIsnan (location_t location, tree value)
+{
+ tree functype = TREE_TYPE (gm2_isnan_node);
+ tree funcptr
+ = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_isnan_node);
+ tree call = m2treelib_DoCall1 (location, ptr_type_node, funcptr, value);
+
+ return call;
+}
+
tree
m2builtins_BuiltInHugeVal (location_t location)
{
@@ -1404,6 +1428,7 @@ m2builtins_init (location_t location)
gm2_huge_val_node = find_builtin_tree ("__builtin_huge_val");
gm2_huge_vall_node = find_builtin_tree ("__builtin_huge_vall");
gm2_isfinite_node = find_builtin_tree ("__builtin_isfinite");
+ gm2_isnan_node = find_builtin_tree ("__builtin_isnan");
m2block_popGlobalScope ();
}
diff --git a/gcc/m2/gm2-gcc/m2decl.cc b/gcc/m2/gm2-gcc/m2decl.cc
index 535e3a6..24fff75 100644
--- a/gcc/m2/gm2-gcc/m2decl.cc
+++ b/gcc/m2/gm2-gcc/m2decl.cc
@@ -284,17 +284,6 @@ m2decl_DeclareModuleCtor (tree decl)
return decl;
}
-/* ConstantStringExceedsZType return TRUE if str cannot be represented in the ZTYPE. */
-
-bool
-m2decl_ConstantStringExceedsZType (location_t location,
- const char *str, unsigned int base,
- bool issueError)
-{
- widest_int wval;
- return m2expr_StrToWideInt (location, str, base, wval, issueError);
-}
-
/* BuildConstLiteralNumber - returns a GCC TREE built from the
string, str. It assumes that, str, represents a legal number in
Modula-2. It always returns a positive value. */
@@ -305,12 +294,22 @@ m2decl_BuildConstLiteralNumber (location_t location, const char *str,
{
widest_int wval;
tree value;
- bool overflow = m2expr_StrToWideInt (location, str, base, wval, issueError);
- value = wide_int_to_tree (m2type_GetM2ZType (), wval);
-
- if (issueError && (overflow || m2expr_TreeOverflow (value)))
+ bool overflow = m2expr_OverflowZType (location, str, base, issueError);
+ if (overflow)
+ value = m2expr_GetIntegerZero (location);
+ else
+ {
+ overflow = m2expr_StrToWideInt (location, str, base, wval, issueError);
+ if (overflow)
+ value = m2expr_GetIntegerZero (location);
+ else
+ {
+ value = wide_int_to_tree (m2type_GetM2ZType (), wval);
+ overflow = m2expr_TreeOverflow (value);
+ }
+ }
+ if (issueError && overflow)
error_at (location, "constant %qs is too large", str);
-
return m2block_RememberConstant (value);
}
diff --git a/gcc/m2/gm2-gcc/m2decl.def b/gcc/m2/gm2-gcc/m2decl.def
index 2fe4434..4bfeb15 100644
--- a/gcc/m2/gm2-gcc/m2decl.def
+++ b/gcc/m2/gm2-gcc/m2decl.def
@@ -161,15 +161,6 @@ PROCEDURE RememberVariables (l: Tree) ;
(*
- ConstantStringExceedsZType - return TRUE if str exceeds the ZTYPE range.
-*)
-
-PROCEDURE ConstantStringExceedsZType (location: location_t;
- str: ADDRESS; base: CARDINAL;
- issueError: BOOLEAN) : BOOLEAN ;
-
-
-(*
BuildConstLiteralNumber - returns a GCC TREE built from the string, str.
It assumes that, str, represents a legal
number in Modula-2. It always returns a
diff --git a/gcc/m2/gm2-gcc/m2decl.h b/gcc/m2/gm2-gcc/m2decl.h
index 3756976..31e6bc7 100644
--- a/gcc/m2/gm2-gcc/m2decl.h
+++ b/gcc/m2/gm2-gcc/m2decl.h
@@ -51,9 +51,6 @@ EXTERN tree m2decl_BuildConstLiteralNumber (location_t location,
const char *str,
unsigned int base,
bool issueError);
-EXTERN bool m2decl_ConstantStringExceedsZType (location_t location,
- const char *str, unsigned int base,
- bool issueError);
EXTERN void m2decl_RememberVariables (tree l);
EXTERN tree m2decl_BuildEndFunctionDeclaration (
diff --git a/gcc/m2/gm2-gcc/m2expr.cc b/gcc/m2/gm2-gcc/m2expr.cc
index bb56a57..a19aed5 100644
--- a/gcc/m2/gm2-gcc/m2expr.cc
+++ b/gcc/m2/gm2-gcc/m2expr.cc
@@ -40,6 +40,7 @@ along with GNU Modula-2; see the file COPYING3. If not see
#include "m2treelib.h"
#include "m2type.h"
#include "m2linemap.h"
+#include "math.h"
static void m2expr_checkRealOverflow (location_t location, enum tree_code code,
tree result);
@@ -3873,13 +3874,54 @@ m2expr_BuildBinaryForeachWordDo (location_t location, tree type, tree op1,
}
-/* StrToWideInt return true if an overflow occurs when attempting to convert
- str to an unsigned ZTYPE the value is contained in the widest_int result.
- The value result is undefined if true is returned. */
+/* OverflowZType returns true if the ZTYPE str will exceed the
+ internal representation. This routine is much faster (at
+ least 2 orders of magnitude faster) than the char at a time overflow
+ detection used in ToWideInt and so it should be
+ used to filter out erroneously large constants before calling ToWideInt
+ allowing a quick fail. */
bool
-m2expr_StrToWideInt (location_t location, const char *str, unsigned int base,
- widest_int &result, bool issueError)
+m2expr_OverflowZType (location_t location, const char *str, unsigned int base,
+ bool issueError)
+{
+ int length = strlen (str);
+ bool overflow = false;
+
+ switch (base)
+ {
+ case 2:
+ overflow = ((length -1) > WIDE_INT_MAX_PRECISION);
+ break;
+ case 8:
+ overflow = (((length -1) * 3) > WIDE_INT_MAX_PRECISION);
+ break;
+ case 10:
+ {
+ int str_log10 = length;
+ int bits_str = (int) (((float) (str_log10)) / log10f (2.0)) + 1;
+ overflow = (bits_str > WIDE_INT_MAX_PRECISION);
+ }
+ break;
+ case 16:
+ overflow = (((length -1) * 4) > WIDE_INT_MAX_PRECISION);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (issueError && overflow)
+ error_at (location,
+ "constant literal %qs exceeds internal ZTYPE range", str);
+ return overflow;
+}
+
+
+/* ToWideInt converts a ZTYPE str value into result. */
+
+static
+bool
+ToWideInt (location_t location, const char *str, unsigned int base,
+ widest_int &result, bool issueError)
{
tree type = m2type_GetM2ZType ();
unsigned int i = 0;
@@ -3990,6 +4032,20 @@ m2expr_StrToWideInt (location_t location, const char *str, unsigned int base,
}
+/* StrToWideInt return true if an overflow occurs when attempting to convert
+ str to an unsigned ZTYPE the value is contained in the widest_int result.
+ The value result is undefined if true is returned. */
+
+bool
+m2expr_StrToWideInt (location_t location, const char *str, unsigned int base,
+ widest_int &result, bool issueError)
+{
+ if (m2expr_OverflowZType (location, str, base, issueError))
+ return true;
+ return ToWideInt (location, str, base, result, issueError);
+}
+
+
/* GetSizeOfInBits return the number of bits used to contain, type. */
tree
diff --git a/gcc/m2/gm2-gcc/m2expr.def b/gcc/m2/gm2-gcc/m2expr.def
index e1ae799..e941d73 100644
--- a/gcc/m2/gm2-gcc/m2expr.def
+++ b/gcc/m2/gm2-gcc/m2expr.def
@@ -729,4 +729,13 @@ PROCEDURE BuildAddAddress (location: location_t; op1, op2: Tree) : Tree ;
PROCEDURE calcNbits (location: location_t; min, max: Tree) : Tree ;
+(*
+ OverflowZType - return TRUE if str exceeds the ZTYPE range.
+*)
+
+PROCEDURE OverflowZType (location: location_t;
+ str: ADDRESS; base: CARDINAL;
+ issueError: BOOLEAN) : BOOLEAN ;
+
+
END m2expr.
diff --git a/gcc/m2/gm2-gcc/m2expr.h b/gcc/m2/gm2-gcc/m2expr.h
index bf5e0b8..0eef3be 100644
--- a/gcc/m2/gm2-gcc/m2expr.h
+++ b/gcc/m2/gm2-gcc/m2expr.h
@@ -241,6 +241,8 @@ EXTERN tree m2expr_BuildRDiv (location_t location, tree op1, tree op2,
bool needconvert);
EXTERN int m2expr_GetCstInteger (tree cst);
EXTERN tree m2expr_calcNbits (location_t location, tree min, tree max);
+EXTERN bool m2expr_OverflowZType (location_t location, const char *str,
+ unsigned int base, bool issueError);
EXTERN void m2expr_init (location_t location);
#undef EXTERN
diff --git a/gcc/m2/gm2-libs-ch/cgetopt.c b/gcc/m2/gm2-libs-ch/cgetopt.c
index 017fe91..36aadbd 100644
--- a/gcc/m2/gm2-libs-ch/cgetopt.c
+++ b/gcc/m2/gm2-libs-ch/cgetopt.c
@@ -59,7 +59,7 @@ cgetopt_getopt (int argc, char *argv[], char *optstring)
int
cgetopt_cgetopt_long (int argc, char *argv[], char *optstring, const struct option *longopts,
- int *longindex)
+ int *longindex)
{
int r = getopt_long (argc, argv, optstring, longopts, longindex);
@@ -74,7 +74,7 @@ cgetopt_cgetopt_long (int argc, char *argv[], char *optstring, const struct opti
int
cgetopt_cgetopt_long_only (int argc, char *argv[], char *optstring,
- const struct option *longopts, int *longindex)
+ const struct option *longopts, int *longindex)
{
int r = getopt_long_only (argc, argv, optstring, longopts, longindex);
@@ -121,8 +121,8 @@ cgetopt_KillOptions (cgetopt_Options *o)
void
cgetopt_SetOption (cgetopt_Options *o, unsigned int index,
- char *name, bool has_arg,
- int *flag, int val)
+ char *name, int has_arg,
+ int *flag, int val)
{
if (index > o->high)
{
@@ -131,6 +131,8 @@ cgetopt_SetOption (cgetopt_Options *o, unsigned int index,
}
o->cinfo[index].name = name;
o->cinfo[index].has_arg = has_arg;
+ if (name == NULL)
+ flag = NULL;
o->cinfo[index].flag = flag;
o->cinfo[index].val = val;
}
diff --git a/gcc/m2/gm2-libs-ch/wrapc.c b/gcc/m2/gm2-libs-ch/wrapc.c
index 51cbbf7..fdb51cd 100644
--- a/gcc/m2/gm2-libs-ch/wrapc.c
+++ b/gcc/m2/gm2-libs-ch/wrapc.c
@@ -225,6 +225,33 @@ wrapc_isfinitef (float x)
return (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE);
}
+/* isnan - provide non builtin alternative to the gcc builtin isnan.
+ Returns 1 if x is a NaN otherwise return 0. */
+
+int
+wrapc_isnan (double x)
+{
+ return isnan (x);
+}
+
+/* isnanf - provide non builtin alternative to the gcc builtin isnanf.
+ Returns 1 if x is a NaN otherwise return 0. */
+
+int
+wrapc_isnanf (float x)
+{
+ return isnan (x);
+}
+
+/* isnanl - provide non builtin alternative to the gcc builtin isnanl.
+ Returns 1 if x is a NaN otherwise return 0. */
+
+int
+wrapc_isnanl (long double x)
+{
+ return isnan (x);
+}
+
/* init - init/finish functions for the module */
void
diff --git a/gcc/m2/gm2-libs/Builtins.def b/gcc/m2/gm2-libs/Builtins.def
index 651ade58..8660976 100644
--- a/gcc/m2/gm2-libs/Builtins.def
+++ b/gcc/m2/gm2-libs/Builtins.def
@@ -30,6 +30,10 @@ FROM SYSTEM IMPORT ADDRESS ;
(* floating point intrinsic procedure functions *)
+PROCEDURE __BUILTIN__ isnanf (x: SHORTREAL) : INTEGER ;
+PROCEDURE __BUILTIN__ isnan (x: REAL) : INTEGER ;
+PROCEDURE __BUILTIN__ isnanl (x: LONGREAL) : INTEGER ;
+
PROCEDURE __BUILTIN__ isfinitef (x: SHORTREAL) : INTEGER ;
PROCEDURE __BUILTIN__ isfinite (x: REAL) : INTEGER ;
PROCEDURE __BUILTIN__ isfinitel (x: LONGREAL) : INTEGER ;
diff --git a/gcc/m2/gm2-libs/Builtins.mod b/gcc/m2/gm2-libs/Builtins.mod
index 707f0e3..4efe47f 100644
--- a/gcc/m2/gm2-libs/Builtins.mod
+++ b/gcc/m2/gm2-libs/Builtins.mod
@@ -58,6 +58,22 @@ BEGIN
RETURN cbuiltin.memcpy (dest, src, nbytes)
END memcpy ;
+
+PROCEDURE __ATTRIBUTE__ __BUILTIN__ ((__builtin_isnan)) isnanf (x: SHORTREAL) : INTEGER ;
+BEGIN
+ RETURN wrapc.isnanf (x)
+END isnanf ;
+
+PROCEDURE __ATTRIBUTE__ __BUILTIN__ ((__builtin_isnan)) isnan (x: REAL) : INTEGER ;
+BEGIN
+ RETURN wrapc.isnan (x)
+END isnan ;
+
+PROCEDURE __ATTRIBUTE__ __BUILTIN__ ((__builtin_isnan)) isnanl (x: LONGREAL) : INTEGER ;
+BEGIN
+ RETURN wrapc.isnanl (x)
+END isnanl ;
+
PROCEDURE __ATTRIBUTE__ __BUILTIN__ ((__builtin_isfinite)) isfinitef (x: SHORTREAL) : INTEGER ;
BEGIN
RETURN wrapc.isfinitef (x)
diff --git a/gcc/m2/gm2-libs/GetOpt.def b/gcc/m2/gm2-libs/GetOpt.def
index 2da5512..bd021e4 100644
--- a/gcc/m2/gm2-libs/GetOpt.def
+++ b/gcc/m2/gm2-libs/GetOpt.def
@@ -40,7 +40,7 @@ TYPE
(*
GetOpt - call C getopt and fill in the parameters:
- optarg, optind, opterr and optop.
+ optarg, optind, opterr and optopt.
*)
PROCEDURE GetOpt (argc: INTEGER; argv: ADDRESS; optstring: String;
@@ -83,13 +83,12 @@ PROCEDURE InitLongOptions () : LongOptions ;
val is the value to return, or to load into the variable
pointed to by flag.
- The last element of the array has to be filled with zeros.
+ The last element of the array must be filled with zeros.
*)
-PROCEDURE AddLongOption (lo: LongOptions;
+PROCEDURE AddLongOption (lo: LongOptions; index: CARDINAL;
name: String; has_arg: INTEGER;
- flag: PtrToInteger;
- val: INTEGER) : LongOptions ;
+ VAR flag: INTEGER; val: INTEGER) : LongOptions ;
(*
@@ -106,8 +105,8 @@ PROCEDURE KillLongOptions (lo: LongOptions) : LongOptions ;
then optstring should be an empty string, not NIL.
*)
-PROCEDURE GetOptLong (argc: INTEGER; argv: ADDRESS; optstring: String;
- longopts: LongOptions;
+PROCEDURE GetOptLong (argc: INTEGER; argv: ADDRESS;
+ optstring: String; longopts: LongOptions;
VAR longindex: INTEGER) : INTEGER ;
diff --git a/gcc/m2/gm2-libs/GetOpt.mod b/gcc/m2/gm2-libs/GetOpt.mod
index e7eaae6..e3dcb94 100644
--- a/gcc/m2/gm2-libs/GetOpt.mod
+++ b/gcc/m2/gm2-libs/GetOpt.mod
@@ -34,19 +34,8 @@ IMPORT cgetopt ;
TYPE
- Crecord = RECORD (* see man 3 getopt. *)
- name : ADDRESS ;
- has_arg: INTEGER ;
- flag : PtrToInteger ;
- val : INTEGER ;
- END ;
-
- ptrToCrecord = POINTER TO Crecord ;
-
LongOptions = POINTER TO RECORD
- cptr: ptrToCrecord ;
- len : CARDINAL ;
- size: CARDINAL ;
+ cptr: cgetopt.Options
END ;
@@ -79,9 +68,7 @@ VAR
BEGIN
NEW (lo) ;
WITH lo^ DO
- cptr := NIL ;
- len := 0 ;
- size := 0
+ cptr := cgetopt.InitOptions ()
END ;
RETURN lo
END InitLongOptions ;
@@ -110,69 +97,25 @@ END InitLongOptions ;
val is the value to return, or to load into the variable pointed to by flag.
- The last element of the array has to be filled with zeros.
+ The last element of the array must be filled with zeros.
*)
-PROCEDURE AddLongOption (lo: LongOptions;
+PROCEDURE AddLongOption (lo: LongOptions; index: CARDINAL;
name: String; has_arg: INTEGER;
- flag: PtrToInteger; val: INTEGER) : LongOptions ;
-VAR
- old,
- entry: ptrToCrecord ;
+ VAR flag: INTEGER; val: INTEGER) : LongOptions ;
BEGIN
- IF lo^.cptr = NIL
- THEN
- NEW (lo^.cptr) ;
- lo^.len := 1 ;
- lo^.size := SIZE (Crecord) ;
- entry := lo^.cptr
- ELSE
- old := lo^.cptr ;
- INC (lo^.len) ;
- lo^.size := lo^.len * SIZE (Crecord) ;
- REALLOCATE (lo^.cptr, lo^.size) ;
- IF lo^.cptr = NIL
- THEN
- entry := NIL
- ELSIF old = lo^.cptr
- THEN
- entry := lo^.cptr ;
- INC (entry, SIZE (Crecord) * lo^.len-1)
- ELSE
- MemCopy (old, lo^.len-1, lo^.cptr) ;
- entry := lo^.cptr ;
- INC (entry, SIZE (Crecord) * lo^.len-1)
- END
- END ;
- fillIn (entry, name, has_arg, flag, val) ;
+ cgetopt.SetOption (lo^.cptr, index, name, has_arg, flag, val) ;
RETURN lo
END AddLongOption ;
(*
- fillIn - fills in
-*)
-
-PROCEDURE fillIn (entry: ptrToCrecord;
- name: String; has_arg: INTEGER; flag: PtrToInteger; val: INTEGER) ;
-BEGIN
- IF entry # NIL
- THEN
- entry^.name := name ;
- entry^.has_arg := has_arg ;
- entry^.flag := flag ;
- entry^.val := val
- END
-END fillIn ;
-
-
-(*
KillLongOptions - returns NIL and also frees up memory associated with, lo.
*)
PROCEDURE KillLongOptions (lo: LongOptions) : LongOptions ;
BEGIN
- DEALLOCATE (lo^.cptr, lo^.size) ;
+ lo^.cptr := cgetopt.KillOptions (lo^.cptr) ;
DISPOSE (lo) ;
RETURN NIL
END KillLongOptions ;
@@ -186,11 +129,9 @@ END KillLongOptions ;
PROCEDURE GetOptLong (argc: INTEGER; argv: ADDRESS; optstring: String;
longopts: LongOptions; VAR longindex: INTEGER) : INTEGER ;
-VAR
- r: INTEGER ;
BEGIN
- r := cgetopt.getopt_long (argc, argv, string (optstring), longopts^.cptr, longindex) ;
- RETURN r
+ RETURN cgetopt.getopt_long (argc, argv, string (optstring),
+ cgetopt.GetLongOptionArray (longopts^.cptr), longindex)
END GetOptLong ;
@@ -201,12 +142,9 @@ END GetOptLong ;
PROCEDURE GetOptLongOnly (argc: INTEGER; argv: ADDRESS; optstring: String;
longopts: LongOptions; VAR longindex: INTEGER) : INTEGER ;
-VAR
- r: INTEGER ;
BEGIN
- r := cgetopt.getopt_long_only (argc, argv, string (optstring),
- longopts^.cptr, longindex) ;
- RETURN r
+ RETURN cgetopt.getopt_long_only (argc, argv, string (optstring),
+ cgetopt.GetLongOptionArray (longopts^.cptr), longindex)
END GetOptLongOnly ;
diff --git a/gcc/m2/gm2-libs/M2Dependent.mod b/gcc/m2/gm2-libs/M2Dependent.mod
index 47bbf13..19bdab1 100644
--- a/gcc/m2/gm2-libs/M2Dependent.mod
+++ b/gcc/m2/gm2-libs/M2Dependent.mod
@@ -75,6 +75,21 @@ VAR
(*
+ InitDependencyList - initialize all fields of DependencyList.
+*)
+
+PROCEDURE InitDependencyList (VAR depList: DependencyList;
+ proc: PROC; state: DependencyState) ;
+BEGIN
+ depList.proc := proc ;
+ depList.forced := FALSE ;
+ depList.forc := FALSE ;
+ depList.appl := FALSE ;
+ depList.state := state
+END InitDependencyList ;
+
+
+(*
CreateModule - creates a new module entry and returns the
ModuleChain.
*)
@@ -90,8 +105,7 @@ BEGIN
mptr^.libname := libname ;
mptr^.init := init ;
mptr^.fini := fini ;
- mptr^.dependency.proc := dependencies ;
- mptr^.dependency.state := unregistered ;
+ InitDependencyList (mptr^.dependency, dependencies, unregistered) ;
mptr^.prev := NIL ;
mptr^.next := NIL ;
IF HexTrace
diff --git a/gcc/m2/gm2-libs/cgetopt.def b/gcc/m2/gm2-libs/cgetopt.def
index 79da9ad..e2162d5 100644
--- a/gcc/m2/gm2-libs/cgetopt.def
+++ b/gcc/m2/gm2-libs/cgetopt.def
@@ -28,7 +28,6 @@ DEFINITION MODULE cgetopt ;
FROM SYSTEM IMPORT ADDRESS ;
-
TYPE
Options = ADDRESS ;
@@ -92,7 +91,7 @@ PROCEDURE KillOptions (o: Options) : Options ;
*)
PROCEDURE SetOption (o: Options; index: CARDINAL;
- name: ADDRESS; has_arg: BOOLEAN;
+ name: ADDRESS; has_arg: INTEGER;
VAR flag: INTEGER; val: INTEGER) ;
diff --git a/gcc/m2/gm2-libs/wrapc.def b/gcc/m2/gm2-libs/wrapc.def
index 90c14d1..238d52d 100644
--- a/gcc/m2/gm2-libs/wrapc.def
+++ b/gcc/m2/gm2-libs/wrapc.def
@@ -28,11 +28,6 @@ DEFINITION MODULE wrapc ;
FROM SYSTEM IMPORT ADDRESS ;
-EXPORT QUALIFIED strtime, filesize, fileinode,
- getrand, getusername, filemtime,
- getnameuidgid, signbit, signbitf, signbitl,
- isfinite, isfinitel, isfinitef ;
-
(*
strtime - returns the C string for the equivalent C asctime
@@ -121,4 +116,28 @@ PROCEDURE isfinitef (x: SHORTREAL) : INTEGER ;
PROCEDURE isfinitel (x: LONGREAL) : INTEGER ;
+(*
+ isnan - provide non builtin alternative to the gcc builtin isnan.
+ Returns 1 if x is a NaN otherwise return 0.
+*)
+
+PROCEDURE isnan (x: REAL) : INTEGER ;
+
+
+(*
+ isnanf - provide non builtin alternative to the gcc builtin isnanf.
+ Returns 1 if x is a NaN otherwise return 0.
+*)
+
+PROCEDURE isnanf (x: SHORTREAL) : INTEGER ;
+
+
+(*
+ isnanl - provide non builtin alternative to the gcc builtin isnanl.
+ Returns 1 if x is a NaN otherwise return 0.
+*)
+
+PROCEDURE isnanl (x: LONGREAL) : INTEGER ;
+
+
END wrapc.
diff --git a/gcc/match.pd b/gcc/match.pd
index a56838f..424bbd0 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -103,12 +103,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
IFN_COND_FMIN IFN_COND_FMAX
IFN_COND_AND IFN_COND_IOR IFN_COND_XOR
IFN_COND_SHL IFN_COND_SHR)
+(define_operator_list COND_LEN_BINARY
+ IFN_COND_LEN_ADD IFN_COND_LEN_SUB
+ IFN_COND_LEN_MUL IFN_COND_LEN_DIV
+ IFN_COND_LEN_MOD IFN_COND_LEN_RDIV
+ IFN_COND_LEN_MIN IFN_COND_LEN_MAX
+ IFN_COND_LEN_FMIN IFN_COND_LEN_FMAX
+ IFN_COND_LEN_AND IFN_COND_LEN_IOR IFN_COND_LEN_XOR
+ IFN_COND_LEN_SHL IFN_COND_LEN_SHR)
/* Same for ternary operations. */
(define_operator_list UNCOND_TERNARY
IFN_FMA IFN_FMS IFN_FNMA IFN_FNMS)
(define_operator_list COND_TERNARY
IFN_COND_FMA IFN_COND_FMS IFN_COND_FNMA IFN_COND_FNMS)
+(define_operator_list COND_LEN_TERNARY
+ IFN_COND_LEN_FMA IFN_COND_LEN_FMS IFN_COND_LEN_FNMA IFN_COND_LEN_FNMS)
/* __atomic_fetch_or_*, __atomic_fetch_xor_*, __atomic_xor_fetch_* */
(define_operator_list ATOMIC_FETCH_OR_XOR_N
@@ -2707,6 +2717,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (TREE_INT_CST_LOW (@1) & 1)
{ constant_boolean_node (cmp == NE_EXPR, type); })))
+/*
+ U & N <= U -> true
+ U & N > U -> false
+ U needs to be non-negative.
+
+ U | N < U -> false
+ U | N >= U -> true
+ U and N needs to be non-negative
+
+ U | N < U -> true
+ U | N >= U -> false
+ U needs to be non-negative and N needs to be a negative constant.
+ */
+(for cmp (lt ge le gt )
+ bitop (bit_ior bit_ior bit_and bit_and)
+ (simplify
+ (cmp:c (bitop:c tree_expr_nonnegative_p@0 @1) @0)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ (if (bitop == BIT_AND_EXPR || tree_expr_nonnegative_p (@1))
+ { constant_boolean_node (cmp == GE_EXPR || cmp == LE_EXPR, type); }
+ /* The sign is opposite now so the comparison is swapped around. */
+ (if (TREE_CODE (@1) == INTEGER_CST && wi::neg_p (wi::to_wide (@1)))
+ { constant_boolean_node (cmp == LT_EXPR, type); })))))
+
/* Arguments on which one can call get_nonzero_bits to get the bits
possibly set. */
(match with_possible_nonzero_bits
@@ -4121,6 +4155,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
(op (mult (convert:type @0) @2) @1))))
+/* ?: Value replacement. */
+/* a == 0 ? b : b + a -> b + a */
+(for op (plus bit_ior bit_xor)
+ (simplify
+ (cond (eq @0 integer_zerop) @1 (op:c@2 @1 @0))
+ @2))
+/* a == 0 ? b : b - a -> b - a */
+/* a == 0 ? b : b ptr+ a -> b ptr+ a */
+/* a == 0 ? b : b shift/rotate a -> b shift/rotate a */
+(for op (lrotate rrotate lshift rshift minus pointer_plus)
+ (simplify
+ (cond (eq @0 integer_zerop) @1 (op@2 @1 @0))
+ @2))
+
+/* a == 1 ? b : b / a -> b / a */
+(for op (trunc_div ceil_div floor_div round_div exact_div)
+ (simplify
+ (cond (eq @0 integer_onep) @1 (op@2 @1 @0))
+ @2))
+
+/* a == 1 ? b : a * b -> a * b */
+(for op (mult)
+ (simplify
+ (cond (eq @0 integer_onep) @1 (op:c@2 @1 @0))
+ @2))
+
+/* a == -1 ? b : a & b -> a & b */
+(for op (bit_and)
+ (simplify
+ (cond (eq @0 integer_all_onesp) @1 (op:c@2 @1 @0))
+ @2))
+
/* Simplifications of shift and rotates. */
(for rotate (lrotate rrotate)
@@ -5611,6 +5677,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (wi::eq_p (wi::bit_not (wi::to_wide (@1)), wi::to_wide (@2)))
@3))
+/* X != C1 ? abs(X) : C2 simplifies to abs(x) when abs(C1) == C2. */
+(for op (abs absu)
+ (simplify
+ (cond (ne @0 INTEGER_CST@1) (op@3 @0) INTEGER_CST@2)
+ (if (wi::abs (wi::to_wide (@1)) == wi::to_wide (@2))
+ (if (op != ABSU_EXPR && wi::only_sign_bit_p (wi::to_wide (@1)))
+ (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+ (convert (absu:utype @0)))
+ @3))))
+
/* (X + 1) > Y ? -X : 1 simplifies to X >= Y ? -X : 1 when
X is unsigned, as when X + 1 overflows, X is -1, so -X == 1. */
(simplify
@@ -5650,9 +5726,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cnd (logical_inverted_value truth_valued_p@0) @1 @2)
(cnd @0 @2 @1)))
-/* abs/negative simplifications moved from fold_cond_expr_with_comparison,
- Need to handle (A - B) case as fold_cond_expr_with_comparison does.
- Need to handle UN* comparisons.
+/* abs/negative simplifications moved from fold_cond_expr_with_comparison.
None of these transformations work for modes with signed
zeros. If A is +/-0, the first two transformations will
@@ -5717,6 +5791,48 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(convert (negate (absu:utype @0))))
(negate (abs @0)))))
)
+
+ /* (A - B) == 0 ? (A - B) : (B - A) same as (B - A) */
+ (for cmp (eq uneq)
+ (simplify
+ (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus@3 @2 @1))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @3))
+ (simplify
+ (cnd (cmp (minus@0 @1 @2) integer_zerop) integer_zerop (minus@3 @2 @1))
+ @3)
+ )
+ /* (A - B) != 0 ? (A - B) : (B - A) same as (A - B) */
+ (for cmp (ne ltgt)
+ (simplify
+ (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus @2 @1))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @0))
+ (simplify
+ (cnd (cmp (minus@0 @1 @2) integer_zerop) @0 integer_zerop)
+ @0)
+ )
+ /* (A - B) >=/> 0 ? (A - B) : (B - A) same as abs (A - B) */
+ (for cmp (ge gt)
+ (simplify
+ (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus @2 @1))
+ (if (!HONOR_SIGNED_ZEROS (type)
+ && !TYPE_UNSIGNED (type))
+ (abs @0))))
+ /* (A - B) <=/< 0 ? (A - B) : (B - A) same as -abs (A - B) */
+ (for cmp (le lt)
+ (simplify
+ (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus @2 @1))
+ (if (!HONOR_SIGNED_ZEROS (type)
+ && !TYPE_UNSIGNED (type))
+ (if (ANY_INTEGRAL_TYPE_P (type)
+ && !TYPE_OVERFLOW_WRAPS (type))
+ (with {
+ tree utype = unsigned_type_for (type);
+ }
+ (convert (negate (absu:utype @0))))
+ (negate (abs @0)))))
+ )
)
/* -(type)!A -> (type)A - 1. */
@@ -8560,7 +8676,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* popcount(X&Y) + popcount(X|Y) is popcount(x) + popcount(Y). */
(simplify
(plus:c (POPCOUNT:s (bit_and:s @0 @1)) (POPCOUNT:s (bit_ior:cs @0 @1)))
- (plus (POPCOUNT @0) (POPCOUNT @1)))
+ (plus (POPCOUNT:type @0) (POPCOUNT:type @1)))
/* popcount(X) + popcount(Y) - popcount(X&Y) is popcount(X|Y). */
/* popcount(X) + popcount(Y) - popcount(X|Y) is popcount(X&Y). */
@@ -8940,6 +9056,35 @@ and,
&& element_precision (type) == element_precision (op_type))
(view_convert (cond_op @2 @3 @4 @5 (view_convert:op_type @1)))))))
+/* Detect cases in which a VEC_COND_EXPR effectively replaces the
+ "else" value of an IFN_COND_LEN_*. */
+(for cond_len_op (COND_LEN_BINARY)
+ (simplify
+ (vec_cond @0 (view_convert? (cond_len_op @0 @1 @2 @3 @4 @5)) @6)
+ (with { tree op_type = TREE_TYPE (@3); }
+ (if (element_precision (type) == element_precision (op_type))
+ (view_convert (cond_len_op @0 @1 @2 (view_convert:op_type @6) @4 @5)))))
+ (simplify
+ (vec_cond @0 @1 (view_convert? (cond_len_op @2 @3 @4 @5 @6 @7)))
+ (with { tree op_type = TREE_TYPE (@5); }
+ (if (inverse_conditions_p (@0, @2)
+ && element_precision (type) == element_precision (op_type))
+ (view_convert (cond_len_op @2 @3 @4 (view_convert:op_type @1) @6 @7))))))
+
+/* Same for ternary operations. */
+(for cond_len_op (COND_LEN_TERNARY)
+ (simplify
+ (vec_cond @0 (view_convert? (cond_len_op @0 @1 @2 @3 @4 @5 @6)) @7)
+ (with { tree op_type = TREE_TYPE (@4); }
+ (if (element_precision (type) == element_precision (op_type))
+ (view_convert (cond_len_op @0 @1 @2 @3 (view_convert:op_type @7) @5 @6)))))
+ (simplify
+ (vec_cond @0 @1 (view_convert? (cond_len_op @2 @3 @4 @5 @6 @7 @8)))
+ (with { tree op_type = TREE_TYPE (@6); }
+ (if (inverse_conditions_p (@0, @2)
+ && element_precision (type) == element_precision (op_type))
+ (view_convert (cond_len_op @2 @3 @4 @5 (view_convert:op_type @1) @7 @8))))))
+
/* Detect simplication for a conditional reduction where
a = mask1 ? b : 0
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 155efd1..1f8f400 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,10 @@
+2023-10-23 Andrew Pinski <pinskia@gmail.com>
+
+ * objc-gnu-runtime-abi-01.cc (build_objc_method_call): Allow
+ for error_operand after call to build_c_cast.
+ * objc-next-runtime-abi-01.cc (build_objc_method_call): Likewise.
+ * objc-next-runtime-abi-02.cc (build_v2_build_objc_method_call): Likewise.
+
2023-08-31 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* objc-act.cc: Change spelling to macOS.
diff --git a/gcc/objc/objc-gnu-runtime-abi-01.cc b/gcc/objc/objc-gnu-runtime-abi-01.cc
index fbf8307..6f45283 100644
--- a/gcc/objc/objc-gnu-runtime-abi-01.cc
+++ b/gcc/objc/objc-gnu-runtime-abi-01.cc
@@ -700,6 +700,9 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
lookup_object = build_c_cast (loc, rcv_p, lookup_object);
+ if (error_operand_p (lookup_object))
+ return error_mark_node;
+
/* Use SAVE_EXPR to avoid evaluating the receiver twice. */
lookup_object = save_expr (lookup_object);
diff --git a/gcc/objc/objc-next-runtime-abi-01.cc b/gcc/objc/objc-next-runtime-abi-01.cc
index 70ab5262..9e28976 100644
--- a/gcc/objc/objc-next-runtime-abi-01.cc
+++ b/gcc/objc/objc-next-runtime-abi-01.cc
@@ -846,6 +846,9 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
lookup_object = build_c_cast (loc, rcv_p, lookup_object);
+ if (error_operand_p (lookup_object))
+ return error_mark_node;
+
/* Use SAVE_EXPR to avoid evaluating the receiver twice. */
lookup_object = save_expr (lookup_object);
diff --git a/gcc/objc/objc-next-runtime-abi-02.cc b/gcc/objc/objc-next-runtime-abi-02.cc
index 6548c00..723b47c 100644
--- a/gcc/objc/objc-next-runtime-abi-02.cc
+++ b/gcc/objc/objc-next-runtime-abi-02.cc
@@ -1729,6 +1729,9 @@ build_v2_build_objc_method_call (int super, tree method_prototype,
lookup_object = build_c_cast (loc, rcv_p, lookup_object);
+ if (error_operand_p (lookup_object))
+ return error_mark_node;
+
/* Use SAVE_EXPR to avoid evaluating the receiver twice. */
lookup_object = save_expr (lookup_object);
diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog
index d4df075..019292d 100644
--- a/gcc/objcp/ChangeLog
+++ b/gcc/objcp/ChangeLog
@@ -1,3 +1,9 @@
+2023-10-22 Patrick Palka <ppalka@redhat.com>
+
+ PR objc++/111920
+ * objcp-lang.cc (objcp_tsubst_expr) <case CLASS_REFERENCE_EXPR>:
+ Use tsubst instead of tsubst_expr for type operands.
+
2023-10-20 Patrick Palka <ppalka@redhat.com>
* objcp-lang.cc (objcp_tsubst_copy_and_build): Rename to ...
diff --git a/gcc/objcp/objcp-lang.cc b/gcc/objcp/objcp-lang.cc
index 5b04cd6..ee39aec 100644
--- a/gcc/objcp/objcp-lang.cc
+++ b/gcc/objcp/objcp-lang.cc
@@ -66,8 +66,14 @@ objcp_tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
RECURSE (TREE_OPERAND (t, 2)), NULL);
case CLASS_REFERENCE_EXPR:
- return objc_get_class_reference
- (RECURSE (TREE_OPERAND (t, 0)));
+ {
+ tree ident = TREE_OPERAND (t, 0);
+ if (TYPE_P (ident))
+ ident = tsubst (ident, args, complain, in_decl);
+ else
+ ident = RECURSE (ident);
+ return objc_get_class_reference (ident);
+ }
default:
break;
diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index 6172839..5c6a7f2 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -10332,6 +10332,57 @@ expand_omp_target (struct omp_region *region)
}
}
+ if ((c = omp_find_clause (clauses, OMP_CLAUSE_SELF)) != NULL_TREE)
+ {
+ gcc_assert ((is_gimple_omp_oacc (entry_stmt) && offloaded)
+ || (gimple_omp_target_kind (entry_stmt)
+ == GF_OMP_TARGET_KIND_OACC_DATA_KERNELS));
+
+ edge e;
+ if (offloaded)
+ e = split_block_after_labels (new_bb);
+ else
+ {
+ gsi = gsi_last_nondebug_bb (new_bb);
+ gsi_prev (&gsi);
+ e = split_block (new_bb, gsi_stmt (gsi));
+ }
+ basic_block cond_bb = e->src;
+ new_bb = e->dest;
+ remove_edge (e);
+
+ basic_block then_bb = create_empty_bb (cond_bb);
+ basic_block else_bb = create_empty_bb (then_bb);
+ set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
+ set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
+
+ tree self_cond = gimple_boolify (OMP_CLAUSE_SELF_EXPR (c));
+ stmt = gimple_build_cond_empty (self_cond);
+ gsi = gsi_last_bb (cond_bb);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+
+ tree tmp_var = create_tmp_var (TREE_TYPE (goacc_flags));
+ stmt = gimple_build_assign (tmp_var, BIT_IOR_EXPR, goacc_flags,
+ build_int_cst (integer_type_node,
+ GOACC_FLAG_LOCAL_DEVICE));
+ gsi = gsi_start_bb (then_bb);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+
+ gsi = gsi_start_bb (else_bb);
+ stmt = gimple_build_assign (tmp_var, goacc_flags);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+
+ make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
+ make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
+ add_bb_to_loop (then_bb, cond_bb->loop_father);
+ add_bb_to_loop (else_bb, cond_bb->loop_father);
+ make_edge (then_bb, new_bb, EDGE_FALLTHRU);
+ make_edge (else_bb, new_bb, EDGE_FALLTHRU);
+
+ goacc_flags = tmp_var;
+ gsi = gsi_last_nondebug_bb (new_bb);
+ }
+
if (need_device_adjustment)
{
tree uns = fold_convert (unsigned_type_node, device);
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 91ef74f..161bcfe 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -1493,6 +1493,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
@@ -1920,6 +1921,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_DEFAULT:
case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
diff --git a/gcc/omp-oacc-kernels-decompose.cc b/gcc/omp-oacc-kernels-decompose.cc
index ffc0a8f..dfbb349 100644
--- a/gcc/omp-oacc-kernels-decompose.cc
+++ b/gcc/omp-oacc-kernels-decompose.cc
@@ -1519,17 +1519,18 @@ omp_oacc_kernels_decompose_1 (gimple *kernels_stmt)
break;
}
}
- else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
{
- /* If there is an 'if' clause, it must be duplicated to the
- enclosing data region. Temporarily remove the if clause's
- chain to avoid copying it. */
+ /* If there is an 'if' or 'self' clause, it must be duplicated to the
+ enclosing data region. Temporarily remove its chain to avoid
+ copying it. */
tree saved_chain = OMP_CLAUSE_CHAIN (c);
OMP_CLAUSE_CHAIN (c) = NULL;
- tree new_if_clause = unshare_expr (c);
+ tree new_clause = unshare_expr (c);
OMP_CLAUSE_CHAIN (c) = saved_chain;
- OMP_CLAUSE_CHAIN (new_if_clause) = data_clauses;
- data_clauses = new_if_clause;
+ OMP_CLAUSE_CHAIN (new_clause) = data_clauses;
+ data_clauses = new_clause;
}
}
/* Restore the original order of the clauses. */
diff --git a/gcc/omp-simd-clone.cc b/gcc/omp-simd-clone.cc
index f611fdb..57b0793 100644
--- a/gcc/omp-simd-clone.cc
+++ b/gcc/omp-simd-clone.cc
@@ -701,10 +701,9 @@ simd_clone_create (struct cgraph_node *old_node, bool force_local)
}
/* Adjust the return type of the given function to its appropriate
- vector counterpart. Returns a simd array to be used throughout the
- function as a return value. */
+ vector counterpart. */
-static tree
+static void
simd_clone_adjust_return_type (struct cgraph_node *node)
{
tree fndecl = node->decl;
@@ -714,7 +713,7 @@ simd_clone_adjust_return_type (struct cgraph_node *node)
/* Adjust the function return type. */
if (orig_rettype == void_type_node)
- return NULL_TREE;
+ return;
t = TREE_TYPE (TREE_TYPE (fndecl));
if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
veclen = node->simdclone->vecsize_int;
@@ -737,24 +736,6 @@ simd_clone_adjust_return_type (struct cgraph_node *node)
veclen));
}
TREE_TYPE (TREE_TYPE (fndecl)) = t;
- if (!node->definition)
- return NULL_TREE;
-
- t = DECL_RESULT (fndecl);
- /* Adjust the DECL_RESULT. */
- gcc_assert (TREE_TYPE (t) != void_type_node);
- TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (fndecl));
- relayout_decl (t);
-
- tree atype = build_array_type_nelts (orig_rettype,
- node->simdclone->simdlen);
- if (maybe_ne (veclen, node->simdclone->simdlen))
- return build1 (VIEW_CONVERT_EXPR, atype, t);
-
- /* Set up a SIMD array to use as the return value. */
- tree retval = create_tmp_var_raw (atype, "retval");
- gimple_add_tmp_var (retval);
- return retval;
}
/* Each vector argument has a corresponding array to be used locally
@@ -788,7 +769,7 @@ create_tmp_simd_array (const char *prefix, tree type, poly_uint64 simdlen)
declarations will be remapped. New arguments which are not to be remapped
are marked with USER_FLAG. */
-static ipa_param_body_adjustments *
+static void
simd_clone_adjust_argument_types (struct cgraph_node *node)
{
auto_vec<tree> args;
@@ -798,15 +779,11 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
else
simd_clone_vector_of_formal_parm_types (&args, node->decl);
struct cgraph_simd_clone *sc = node->simdclone;
- vec<ipa_adjusted_param, va_gc> *new_params = NULL;
- vec_safe_reserve (new_params, sc->nargs);
- unsigned i, j, k;
+ unsigned i, k;
poly_uint64 veclen;
for (i = 0; i < sc->nargs; ++i)
{
- ipa_adjusted_param adj;
- memset (&adj, 0, sizeof (adj));
tree parm = NULL_TREE;
tree parm_type = NULL_TREE;
if (i < args.length())
@@ -815,17 +792,12 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
parm_type = node->definition ? TREE_TYPE (parm) : parm;
}
- adj.base_index = i;
- adj.prev_clone_index = i;
-
sc->args[i].orig_arg = node->definition ? parm : NULL_TREE;
sc->args[i].orig_type = parm_type;
switch (sc->args[i].arg_type)
{
default:
- /* No adjustment necessary for scalar arguments. */
- adj.op = IPA_PARAM_OP_COPY;
break;
case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP:
case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
@@ -834,7 +806,6 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
= create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)),
TREE_TYPE (parm_type),
sc->simdlen);
- adj.op = IPA_PARAM_OP_COPY;
break;
case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
@@ -851,28 +822,12 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
GET_MODE_BITSIZE (SCALAR_TYPE_MODE (parm_type)));
if (multiple_p (veclen, sc->simdlen))
veclen = sc->simdlen;
- adj.op = IPA_PARAM_OP_NEW;
- adj.param_prefix_index = IPA_PARAM_PREFIX_SIMD;
+ tree vtype;
if (POINTER_TYPE_P (parm_type))
- adj.type = build_vector_type (pointer_sized_int_node, veclen);
+ vtype = build_vector_type (pointer_sized_int_node, veclen);
else
- adj.type = build_vector_type (parm_type, veclen);
- sc->args[i].vector_type = adj.type;
- k = vector_unroll_factor (sc->simdlen, veclen);
- for (j = 1; j < k; j++)
- {
- vec_safe_push (new_params, adj);
- if (j == 1)
- {
- memset (&adj, 0, sizeof (adj));
- adj.op = IPA_PARAM_OP_NEW;
- adj.user_flag = 1;
- adj.param_prefix_index = IPA_PARAM_PREFIX_SIMD;
- adj.base_index = i;
- adj.prev_clone_index = i;
- adj.type = sc->args[i].vector_type;
- }
- }
+ vtype = build_vector_type (parm_type, veclen);
+ sc->args[i].vector_type = vtype;
if (node->definition)
sc->args[i].simd_array
@@ -880,20 +835,12 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
? IDENTIFIER_POINTER (DECL_NAME (parm))
: NULL, parm_type, sc->simdlen);
}
- vec_safe_push (new_params, adj);
}
if (sc->inbranch)
{
tree base_type = simd_clone_compute_base_data_type (sc->origin, sc);
- ipa_adjusted_param adj;
- memset (&adj, 0, sizeof (adj));
- adj.op = IPA_PARAM_OP_NEW;
- adj.user_flag = 1;
- adj.param_prefix_index = IPA_PARAM_PREFIX_MASK;
-
- adj.base_index = i;
- adj.prev_clone_index = i;
+ tree mask_type;
if (INTEGRAL_TYPE_P (base_type) || POINTER_TYPE_P (base_type))
veclen = sc->vecsize_int;
else
@@ -906,17 +853,14 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
if (multiple_p (veclen, sc->simdlen))
veclen = sc->simdlen;
if (sc->mask_mode != VOIDmode)
- adj.type
+ mask_type
= lang_hooks.types.type_for_mode (sc->mask_mode, 1);
else if (POINTER_TYPE_P (base_type))
- adj.type = build_vector_type (pointer_sized_int_node, veclen);
+ mask_type = build_vector_type (pointer_sized_int_node, veclen);
else
- adj.type = build_vector_type (base_type, veclen);
- vec_safe_push (new_params, adj);
+ mask_type = build_vector_type (base_type, veclen);
k = vector_unroll_factor (sc->simdlen, veclen);
- for (j = 1; j < k; j++)
- vec_safe_push (new_params, adj);
/* We have previously allocated one extra entry for the mask. Use
it and fill it. */
@@ -932,24 +876,16 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
= create_tmp_simd_array ("mask", base_type, sc->simdlen);
else if (k > 1)
sc->args[i].simd_array
- = create_tmp_simd_array ("mask", adj.type, k);
+ = create_tmp_simd_array ("mask", mask_type, k);
else
sc->args[i].simd_array = NULL_TREE;
}
sc->args[i].orig_type = base_type;
sc->args[i].arg_type = SIMD_CLONE_ARG_TYPE_MASK;
- sc->args[i].vector_type = adj.type;
+ sc->args[i].vector_type = mask_type;
}
- if (node->definition)
- {
- ipa_param_body_adjustments *adjustments
- = new ipa_param_body_adjustments (new_params, node->decl);
-
- adjustments->modify_formal_parameters ();
- return adjustments;
- }
- else
+ if (!node->definition)
{
tree new_arg_types = NULL_TREE, new_reversed;
bool last_parm_void = false;
@@ -957,15 +893,20 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
last_parm_void = true;
gcc_assert (TYPE_ARG_TYPES (TREE_TYPE (node->decl)));
- j = vec_safe_length (new_params);
- for (i = 0; i < j; i++)
+ for (i = 0; i < sc->nargs; i++)
{
- struct ipa_adjusted_param *adj = &(*new_params)[i];
tree ptype;
- if (adj->op == IPA_PARAM_OP_COPY)
- ptype = args[adj->base_index];
- else
- ptype = adj->type;
+ switch (sc->args[i].arg_type)
+ {
+ default:
+ ptype = sc->args[i].orig_type;
+ break;
+ case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
+ case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
+ case SIMD_CLONE_ARG_TYPE_VECTOR:
+ ptype = sc->args[i].vector_type;
+ break;
+ }
new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
}
new_reversed = nreverse (new_arg_types);
@@ -977,7 +918,6 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
new_reversed = void_list_node;
}
TYPE_ARG_TYPES (TREE_TYPE (node->decl)) = new_reversed;
- return NULL;
}
}
@@ -996,7 +936,8 @@ simd_clone_init_simd_arrays (struct cgraph_node *node,
arg;
arg = DECL_CHAIN (arg), i++, j++)
{
- if ((*adjustments->m_adj_params)[j].op == IPA_PARAM_OP_COPY
+ ipa_adjusted_param adj = (*adjustments->m_adj_params)[j];
+ if (adj.op == IPA_PARAM_OP_COPY
|| POINTER_TYPE_P (TREE_TYPE (arg)))
continue;
@@ -1004,7 +945,7 @@ simd_clone_init_simd_arrays (struct cgraph_node *node,
tree array = node->simdclone->args[i].simd_array;
if (node->simdclone->mask_mode != VOIDmode
- && node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK)
+ && adj.param_prefix_index == IPA_PARAM_PREFIX_MASK)
{
if (array == NULL_TREE)
continue;
@@ -1024,8 +965,9 @@ simd_clone_init_simd_arrays (struct cgraph_node *node,
}
continue;
}
- if (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)),
- node->simdclone->simdlen))
+ if (!VECTOR_TYPE_P (TREE_TYPE (arg))
+ || known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)),
+ node->simdclone->simdlen))
{
tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
tree ptr = build_fold_addr_expr (array);
@@ -1423,13 +1365,120 @@ simd_clone_adjust (struct cgraph_node *node)
{
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+ tree orig_rettype = TREE_TYPE (TREE_TYPE (node->decl));
TREE_TYPE (node->decl) = build_distinct_type_copy (TREE_TYPE (node->decl));
+ simd_clone_adjust_return_type (node);
+ simd_clone_adjust_argument_types (node);
targetm.simd_clone.adjust (node);
+ tree retval = NULL_TREE;
+ if (orig_rettype != void_type_node)
+ {
+ poly_uint64 veclen;
+ if (INTEGRAL_TYPE_P (orig_rettype) || POINTER_TYPE_P (orig_rettype))
+ veclen = node->simdclone->vecsize_int;
+ else
+ veclen = node->simdclone->vecsize_float;
+ if (known_eq (veclen, 0U))
+ veclen = node->simdclone->simdlen;
+ else
+ veclen = exact_div (veclen,
+ GET_MODE_BITSIZE (SCALAR_TYPE_MODE (orig_rettype)));
+ if (multiple_p (veclen, node->simdclone->simdlen))
+ veclen = node->simdclone->simdlen;
+
+ retval = DECL_RESULT (node->decl);
+ /* Adjust the DECL_RESULT. */
+ TREE_TYPE (retval) = TREE_TYPE (TREE_TYPE (node->decl));
+ relayout_decl (retval);
+
+ tree atype = build_array_type_nelts (orig_rettype,
+ node->simdclone->simdlen);
+ if (maybe_ne (veclen, node->simdclone->simdlen))
+ retval = build1 (VIEW_CONVERT_EXPR, atype, retval);
+ else
+ {
+ /* Set up a SIMD array to use as the return value. */
+ retval = create_tmp_var_raw (atype, "retval");
+ gimple_add_tmp_var (retval);
+ }
+ }
- tree retval = simd_clone_adjust_return_type (node);
+ struct cgraph_simd_clone *sc = node->simdclone;
+ vec<ipa_adjusted_param, va_gc> *new_params = NULL;
+ vec_safe_reserve (new_params, sc->nargs);
+ unsigned i, j, k;
+ for (i = 0; i < sc->nargs; ++i)
+ {
+ ipa_adjusted_param adj;
+ memset (&adj, 0, sizeof (adj));
+ poly_uint64 veclen;
+ tree elem_type;
+
+ adj.base_index = i;
+ adj.prev_clone_index = i;
+ switch (sc->args[i].arg_type)
+ {
+ default:
+ /* No adjustment necessary for scalar arguments. */
+ adj.op = IPA_PARAM_OP_COPY;
+ break;
+ case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
+ adj.op = IPA_PARAM_OP_COPY;
+ break;
+ case SIMD_CLONE_ARG_TYPE_MASK:
+ case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
+ case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
+ case SIMD_CLONE_ARG_TYPE_VECTOR:
+ if (sc->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK
+ && sc->mask_mode != VOIDmode)
+ elem_type = boolean_type_node;
+ else
+ elem_type = TREE_TYPE (sc->args[i].vector_type);
+ if (INTEGRAL_TYPE_P (elem_type) || POINTER_TYPE_P (elem_type))
+ veclen = sc->vecsize_int;
+ else
+ veclen = sc->vecsize_float;
+ if (known_eq (veclen, 0U))
+ veclen = sc->simdlen;
+ else
+ veclen
+ = exact_div (veclen,
+ GET_MODE_BITSIZE (SCALAR_TYPE_MODE (elem_type)));
+ if (multiple_p (veclen, sc->simdlen))
+ veclen = sc->simdlen;
+ if (sc->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK)
+ {
+ adj.user_flag = 1;
+ adj.param_prefix_index = IPA_PARAM_PREFIX_MASK;
+ }
+ else
+ adj.param_prefix_index = IPA_PARAM_PREFIX_SIMD;
+ adj.op = IPA_PARAM_OP_NEW;
+ adj.type = sc->args[i].vector_type;
+ k = vector_unroll_factor (sc->simdlen, veclen);
+ for (j = 1; j < k; j++)
+ {
+ vec_safe_push (new_params, adj);
+ if (j == 1)
+ {
+ memset (&adj, 0, sizeof (adj));
+ adj.op = IPA_PARAM_OP_NEW;
+ adj.user_flag = 1;
+ if (sc->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK)
+ adj.param_prefix_index = IPA_PARAM_PREFIX_MASK;
+ else
+ adj.param_prefix_index = IPA_PARAM_PREFIX_SIMD;
+ adj.base_index = i;
+ adj.prev_clone_index = i;
+ adj.type = sc->args[i].vector_type;
+ }
+ }
+ }
+ vec_safe_push (new_params, adj);
+ }
ipa_param_body_adjustments *adjustments
- = simd_clone_adjust_argument_types (node);
- gcc_assert (adjustments);
+ = new ipa_param_body_adjustments (new_params, node->decl);
+ adjustments->modify_formal_parameters ();
push_gimplify_context ();
@@ -2050,9 +2099,9 @@ expand_simd_clones (struct cgraph_node *node)
{
TREE_TYPE (n->decl)
= build_distinct_type_copy (TREE_TYPE (n->decl));
- targetm.simd_clone.adjust (n);
simd_clone_adjust_return_type (n);
simd_clone_adjust_argument_types (n);
+ targetm.simd_clone.adjust (n);
}
if (dump_file)
fprintf (dump_file, "\nGenerated %s clone %s\n",
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 573dcf8..f54cf83 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -50,7 +50,7 @@ static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
const char *const debug_type_names[] =
{
- "none", "stabs", "dwarf-2", "xcoff", "vms", "ctf", "btf"
+ "none", "dwarf-2", "vms", "ctf", "btf"
};
/* Bitmasks of fundamental debug info formats indexed by enum
@@ -65,7 +65,7 @@ static uint32_t debug_type_masks[] =
/* Names of the set of debug formats requested by user. Updated and accessed
via debug_set_names. */
-static char df_set_names[sizeof "none stabs dwarf-2 xcoff vms ctf btf"];
+static char df_set_names[sizeof "none dwarf-2 vms ctf btf"];
/* Get enum debug_info_type of the specified debug format, for error messages.
Can be used only for individual debug format types. */
@@ -3679,9 +3679,9 @@ char *
get_option_url (diagnostic_context *, int option_index)
{
if (option_index)
- return concat (/* DOCUMENTATION_ROOT_URL should be supplied via -D by
- the Makefile (see --with-documentation-root-url), and
- should have a trailing slash. */
+ return concat (/* DOCUMENTATION_ROOT_URL should be supplied via
+ #include "config.h" (see --with-documentation-root-url),
+ and should have a trailing slash. */
DOCUMENTATION_ROOT_URL,
/* get_option_html_page will return something like
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 75446cc..80780cf 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -1664,7 +1664,8 @@ pretty_printer::pretty_printer (int maximum_length)
need_newline (),
translate_identifiers (true),
show_color (),
- url_format (URL_FORMAT_NONE)
+ url_format (URL_FORMAT_NONE),
+ m_skipping_null_url (false)
{
pp_line_cutoff (this) = maximum_length;
/* By default, we emit prefixes once per message. */
@@ -1687,7 +1688,8 @@ pretty_printer::pretty_printer (const pretty_printer &other)
need_newline (other.need_newline),
translate_identifiers (other.translate_identifiers),
show_color (other.show_color),
- url_format (other.url_format)
+ url_format (other.url_format),
+ m_skipping_null_url (false)
{
pp_line_cutoff (this) = maximum_length;
/* By default, we emit prefixes once per message. */
@@ -2211,6 +2213,13 @@ identifier_to_locale (const char *ident)
void
pp_begin_url (pretty_printer *pp, const char *url)
{
+ if (!url)
+ {
+ /* Handle null URL by skipping all output here,
+ and in the next pp_end_url. */
+ pp->m_skipping_null_url = true;
+ return;
+ }
switch (pp->url_format)
{
case URL_FORMAT_NONE:
@@ -2254,6 +2263,13 @@ get_end_url_string (pretty_printer *pp)
void
pp_end_url (pretty_printer *pp)
{
+ if (pp->m_skipping_null_url)
+ {
+ /* We gracefully handle pp_begin_url (NULL) by omitting output for
+ both begin and end. Here we handle the latter. */
+ pp->m_skipping_null_url = false;
+ return;
+ }
if (pp->url_format != URL_FORMAT_NONE)
pp_string (pp, get_end_url_string (pp));
}
@@ -2588,6 +2604,42 @@ test_urls ()
}
}
+/* Verify that we gracefully reject null URLs. */
+
+void
+test_null_urls ()
+{
+ {
+ pretty_printer pp;
+ pp.url_format = URL_FORMAT_NONE;
+ pp_begin_url (&pp, nullptr);
+ pp_string (&pp, "This isn't a link");
+ pp_end_url (&pp);
+ ASSERT_STREQ ("This isn't a link",
+ pp_formatted_text (&pp));
+ }
+
+ {
+ pretty_printer pp;
+ pp.url_format = URL_FORMAT_ST;
+ pp_begin_url (&pp, nullptr);
+ pp_string (&pp, "This isn't a link");
+ pp_end_url (&pp);
+ ASSERT_STREQ ("This isn't a link",
+ pp_formatted_text (&pp));
+ }
+
+ {
+ pretty_printer pp;
+ pp.url_format = URL_FORMAT_BEL;
+ pp_begin_url (&pp, nullptr);
+ pp_string (&pp, "This isn't a link");
+ pp_end_url (&pp);
+ ASSERT_STREQ ("This isn't a link",
+ pp_formatted_text (&pp));
+ }
+}
+
/* Test multibyte awareness. */
static void test_utf8 ()
{
@@ -2637,6 +2689,7 @@ pretty_print_cc_tests ()
test_pp_format ();
test_prefixes_and_wrapping ();
test_urls ();
+ test_null_urls ();
test_utf8 ();
}
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index 02658c8..8759f0d 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -295,6 +295,10 @@ public:
/* Whether URLs should be emitted, and which terminator to use. */
diagnostic_url_format url_format;
+
+ /* If true, then we've had a pp_begin_url (nullptr), and so the
+ next pp_end_url should be a no-op. */
+ bool m_skipping_null_url;
};
inline const char *
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 0951bd3..75816942 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -62,35 +62,14 @@ range_operator::fold_range (frange &r, tree type,
return true;
}
- REAL_VALUE_TYPE lb, ub;
- bool maybe_nan;
- rv_fold (lb, ub, maybe_nan, type,
+ rv_fold (r, type,
op1.lower_bound (), op1.upper_bound (),
op2.lower_bound (), op2.upper_bound (), trio.op1_op2 ());
- // Handle possible NANs by saturating to the appropriate INF if only
- // one end is a NAN. If both ends are a NAN, just return a NAN.
- bool lb_nan = real_isnan (&lb);
- bool ub_nan = real_isnan (&ub);
- if (lb_nan && ub_nan)
- {
- r.set_nan (type);
- return true;
- }
- if (lb_nan)
- lb = dconstninf;
- else if (ub_nan)
- ub = dconstinf;
-
- r.set (type, lb, ub);
-
- if (lb_nan || ub_nan || maybe_nan
- || op1.maybe_isnan ()
- || op2.maybe_isnan ())
- // Keep the default NAN (with a varying sign) set by the setter.
- ;
- else
- r.clear_nan ();
+ if (r.known_isnan ())
+ return true;
+ if (op1.maybe_isnan () || op2.maybe_isnan ())
+ r.update_nan ();
// If the result has overflowed and flag_trapping_math, folding this
// operation could elide an overflow or division by zero exception.
@@ -122,19 +101,13 @@ range_operator::fold_range (frange &r, tree type,
// MAYBE_NAN is set to TRUE if, in addition to any result in LB or
// UB, the final range has the possibility of a NAN.
void
-range_operator::rv_fold (REAL_VALUE_TYPE &lb,
- REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
- tree type ATTRIBUTE_UNUSED,
- const REAL_VALUE_TYPE &lh_lb ATTRIBUTE_UNUSED,
- const REAL_VALUE_TYPE &lh_ub ATTRIBUTE_UNUSED,
- const REAL_VALUE_TYPE &rh_lb ATTRIBUTE_UNUSED,
- const REAL_VALUE_TYPE &rh_ub ATTRIBUTE_UNUSED,
- relation_kind) const
+range_operator::rv_fold (frange &r, tree type,
+ const REAL_VALUE_TYPE &,
+ const REAL_VALUE_TYPE &,
+ const REAL_VALUE_TYPE &,
+ const REAL_VALUE_TYPE &, relation_kind) const
{
- lb = dconstninf;
- ub = dconstinf;
- maybe_nan = true;
+ r.set (type, dconstninf, dconstinf, nan_state (true));
}
bool
@@ -2471,14 +2444,16 @@ operator_plus::op2_range (frange &r, tree type,
}
void
-operator_plus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan, tree type,
+operator_plus::rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
const REAL_VALUE_TYPE &rh_ub,
relation_kind) const
{
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
+
frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
@@ -2488,8 +2463,21 @@ operator_plus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
// [+INF] + [-INF] = NAN
else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
maybe_nan = true;
- else
- maybe_nan = false;
+
+ // Handle possible NANs by saturating to the appropriate INF if only
+ // one end is a NAN. If both ends are a NAN, just return a NAN.
+ bool lb_nan = real_isnan (&lb);
+ bool ub_nan = real_isnan (&ub);
+ if (lb_nan && ub_nan)
+ {
+ r.set_nan (type);
+ return;
+ }
+ if (lb_nan)
+ lb = dconstninf;
+ else if (ub_nan)
+ ub = dconstinf;
+ r.set (type, lb, ub, nan_state (maybe_nan));
}
@@ -2519,14 +2507,16 @@ operator_minus::op2_range (frange &r, tree type,
}
void
-operator_minus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan, tree type,
+operator_minus::rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
const REAL_VALUE_TYPE &rh_ub,
relation_kind) const
{
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
+
frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
@@ -2536,8 +2526,21 @@ operator_minus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
// [-INF] - [-INF] = NAN
else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
maybe_nan = true;
- else
- maybe_nan = false;
+
+ // Handle possible NANs by saturating to the appropriate INF if only
+ // one end is a NAN. If both ends are a NAN, just return a NAN.
+ bool lb_nan = real_isnan (&lb);
+ bool ub_nan = real_isnan (&ub);
+ if (lb_nan && ub_nan)
+ {
+ r.set_nan (type);
+ return;
+ }
+ if (lb_nan)
+ lb = dconstninf;
+ else if (ub_nan)
+ ub = dconstinf;
+ r.set (type, lb, ub, nan_state (maybe_nan));
}
@@ -2612,8 +2615,7 @@ operator_mult::op2_range (frange &r, tree type,
}
void
-operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan, tree type,
+operator_mult::rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
@@ -2626,8 +2628,8 @@ operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
&& real_equal (&lh_ub, &rh_ub)
&& real_isneg (&lh_lb) == real_isneg (&rh_lb)
&& real_isneg (&lh_ub) == real_isneg (&rh_ub));
-
- maybe_nan = false;
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
// x * x never produces a new NAN and we only multiply the same
// values, so the 0 * INF problematic cases never appear there.
if (!is_square)
@@ -2636,9 +2638,7 @@ operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
|| (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
{
- real_nan (&lb, "", 0, TYPE_MODE (type));
- ub = lb;
- maybe_nan = true;
+ r.set_nan (type);
return;
}
@@ -2660,12 +2660,20 @@ operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
// is INF.
if (singleton_inf_p (lh_lb, lh_ub)
|| singleton_inf_p (rh_lb, rh_ub))
- return inf_range (lb, ub, signbit_known);
+ {
+ inf_range (lb, ub, signbit_known);
+ r.set (type, lb, ub, nan_state (true));
+ return;
+ }
// If one of the multiplicands must be zero, the resulting
// range is +-0 and NAN.
if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
- return zero_range (lb, ub, signbit_known);
+ {
+ zero_range (lb, ub, signbit_known);
+ r.set (type, lb, ub, nan_state (true));
+ return;
+ }
// Otherwise one of the multiplicands could be
// [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
@@ -2673,7 +2681,9 @@ operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
// is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
// so if the signs are always the same or always different,
// result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
- return zero_to_inf_range (lb, ub, signbit_known);
+ zero_to_inf_range (lb, ub, signbit_known);
+ r.set (type, lb, ub, nan_state (true));
+ return;
}
}
@@ -2713,6 +2723,10 @@ operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
find_range (lb, ub, cp);
+
+ gcc_checking_assert (!real_isnan (&lb));
+ gcc_checking_assert (!real_isnan (&ub));
+ r.set (type, lb, ub, nan_state (maybe_nan));
}
@@ -2785,8 +2799,7 @@ public:
return float_binary_op_range_finish (ret, r, type, wlhs, true);
}
private:
- void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
- tree type,
+ void rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
@@ -2797,12 +2810,12 @@ private:
if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
|| (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
{
- real_nan (&lb, "", 0, TYPE_MODE (type));
- ub = lb;
- maybe_nan = true;
+ r.set_nan (type);
return;
}
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
// If +-0.0 is in both ranges, it is a maybe NAN.
if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
maybe_nan = true;
@@ -2810,8 +2823,6 @@ private:
else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
&& (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
maybe_nan = true;
- else
- maybe_nan = false;
int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
@@ -2820,14 +2831,22 @@ private:
// If divisor must be +-INF, the range is just +-0
// (including if the dividend is zero).
if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
- return zero_range (lb, ub, signbit_known);
+ {
+ zero_range (lb, ub, signbit_known);
+ r.set (type, lb, ub, nan_state (maybe_nan));
+ return;
+ }
// If divisor must be zero, the range is just +-INF
// (including if the dividend is +-INF).
// If dividend must be +-INF, the range is just +-INF
// (including if the dividend is zero).
if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
- return inf_range (lb, ub, signbit_known);
+ {
+ inf_range (lb, ub, signbit_known);
+ r.set (type, lb, ub, nan_state (maybe_nan));
+ return;
+ }
// Otherwise if both operands may be zero, divisor could be
// nextafter(0.0, +-1.0) and dividend +-0.0
@@ -2843,7 +2862,11 @@ private:
// [+0.0, +INF], if they are always different we have
// [-INF, -0.0]. If they vary, VARYING.
if (maybe_nan)
- return zero_to_inf_range (lb, ub, signbit_known);
+ {
+ zero_to_inf_range (lb, ub, signbit_known);
+ r.set (type, lb, ub, nan_state (maybe_nan));
+ return;
+ }
REAL_VALUE_TYPE cp[8];
// Do a cross-division. At this point none of the divisions should
@@ -2869,6 +2892,10 @@ private:
if (signbit_known >= 0)
real_inf (&ub, false);
}
+
+ gcc_checking_assert (!real_isnan (&lb));
+ gcc_checking_assert (!real_isnan (&ub));
+ r.set (type, lb, ub, nan_state (maybe_nan));
}
} fop_div;
diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h
index f7ff47b..45e11df 100644
--- a/gcc/range-op-mixed.h
+++ b/gcc/range-op-mixed.h
@@ -414,8 +414,7 @@ private:
void wi_fold (irange &r, tree type, const wide_int &lh_lb,
const wide_int &lh_ub, const wide_int &rh_lb,
const wide_int &rh_ub) const final override;
- void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan, tree type,
+ void rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
relation_kind) const final override;
@@ -483,8 +482,7 @@ private:
void wi_fold (irange &r, tree type, const wide_int &lh_lb,
const wide_int &lh_ub, const wide_int &rh_lb,
const wide_int &rh_ub) const final override;
- void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan, tree type,
+ void rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
relation_kind) const final override;
@@ -553,8 +551,7 @@ public:
bool wi_op_overflows (wide_int &res, tree type, const wide_int &w0,
const wide_int &w1) const final override;
- void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan, tree type,
+ void rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
relation_kind kind) const final override;
diff --git a/gcc/range-op.h b/gcc/range-op.h
index 21d401c..282ce38 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -185,9 +185,7 @@ protected:
virtual void update_bitmask (irange &, const irange &, const irange &) const;
// Perform an float operation between 2 ranges and return it.
- virtual void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
- tree type,
+ virtual void rv_fold (frange &r, tree type,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
diff --git a/gcc/read-md.cc b/gcc/read-md.cc
index fd38818..46ab906 100644
--- a/gcc/read-md.cc
+++ b/gcc/read-md.cc
@@ -132,9 +132,9 @@ md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
/* Special fprint_md_ptr_loc for writing to STDOUT. */
void
-md_reader::print_md_ptr_loc (const void *ptr)
+md_reader::print_md_ptr_loc (const void *ptr, FILE *file)
{
- fprint_md_ptr_loc (stdout, ptr);
+ fprint_md_ptr_loc (file, ptr);
}
/* Return a condition that satisfies both COND1 and COND2. Either string
diff --git a/gcc/read-md.h b/gcc/read-md.h
index b309c9c..2adcb58 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -194,7 +194,7 @@ class md_reader
const struct ptr_loc *get_md_ptr_loc (const void *ptr);
void copy_md_ptr_loc (const void *new_ptr, const void *old_ptr);
void fprint_md_ptr_loc (FILE *outf, const void *ptr);
- void print_md_ptr_loc (const void *ptr);
+ void print_md_ptr_loc (const void *ptr, FILE * = stdout);
struct enum_type *lookup_enum_type (const char *name);
void traverse_enum_types (htab_trav callback, void *info);
diff --git a/gcc/recog.cc b/gcc/recog.cc
index 92f1512..3bd2d73 100644
--- a/gcc/recog.cc
+++ b/gcc/recog.cc
@@ -1339,13 +1339,26 @@ insn_propagation::apply_to_pattern_1 (rtx *loc)
&& apply_to_pattern_1 (&COND_EXEC_CODE (body)));
case PARALLEL:
- {
- int last = XVECLEN (body, 0) - 1;
- for (int i = 0; i < last; ++i)
- if (!apply_to_pattern_1 (&XVECEXP (body, 0, i)))
- return false;
- return apply_to_pattern_1 (&XVECEXP (body, 0, last));
- }
+ for (int i = 0; i < XVECLEN (body, 0); ++i)
+ {
+ rtx *subloc = &XVECEXP (body, 0, i);
+ if (GET_CODE (*subloc) == SET)
+ {
+ if (!apply_to_lvalue_1 (SET_DEST (*subloc)))
+ return false;
+ /* ASM_OPERANDS are shared between SETs in the same PARALLEL.
+ Only process them on the first iteration. */
+ if ((i == 0 || GET_CODE (SET_SRC (*subloc)) != ASM_OPERANDS)
+ && !apply_to_rvalue_1 (&SET_SRC (*subloc)))
+ return false;
+ }
+ else
+ {
+ if (!apply_to_pattern_1 (subloc))
+ return false;
+ }
+ }
+ return true;
case ASM_OPERANDS:
for (int i = 0, len = ASM_OPERANDS_INPUT_LENGTH (body); i < len; ++i)
@@ -3080,13 +3093,6 @@ constrain_operands (int strict, alternative_mask alternatives)
earlyclobber[opno] = 0;
- /* A unary operator may be accepted by the predicate, but it
- is irrelevant for matching constraints. */
- /* For special_memory_operand, there could be a memory operand inside,
- and it would cause a mismatch for constraint_satisfied_p. */
- if (UNARY_P (op) && op == extract_mem_from_operand (op))
- op = XEXP (op, 0);
-
if (GET_CODE (op) == SUBREG)
{
if (REG_P (SUBREG_REG (op))
@@ -3152,14 +3158,6 @@ constrain_operands (int strict, alternative_mask alternatives)
{
rtx op1 = recog_data.operand[match];
rtx op2 = recog_data.operand[opno];
-
- /* A unary operator may be accepted by the predicate,
- but it is irrelevant for matching constraints. */
- if (UNARY_P (op1))
- op1 = XEXP (op1, 0);
- if (UNARY_P (op2))
- op2 = XEXP (op2, 0);
-
val = operands_match_p (op1, op2);
}
diff --git a/gcc/reload.cc b/gcc/reload.cc
index 2e57ebb..07256b6 100644
--- a/gcc/reload.cc
+++ b/gcc/reload.cc
@@ -3077,12 +3077,6 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
enum constraint_num cn;
enum reg_class cl;
- /* If the predicate accepts a unary operator, it means that
- we need to reload the operand, but do not do this for
- match_operator and friends. */
- if (UNARY_P (operand) && *p != 0)
- operand = XEXP (operand, 0);
-
/* If the operand is a SUBREG, extract
the REG or MEM (or maybe even a constant) within.
(Constants can occur as a result of reg_equiv_constant.) */
diff --git a/gcc/rtl-ssa.h b/gcc/rtl-ssa.h
index 7355c6c..3a3c8b5 100644
--- a/gcc/rtl-ssa.h
+++ b/gcc/rtl-ssa.h
@@ -49,6 +49,7 @@
#include "obstack-utils.h"
#include "mux-utils.h"
#include "rtlanal.h"
+#include "cfgbuild.h"
// Provides the global crtl->ssa.
#include "memmodel.h"
diff --git a/gcc/rtl-ssa/access-utils.h b/gcc/rtl-ssa/access-utils.h
index 84d386b..f078625b 100644
--- a/gcc/rtl-ssa/access-utils.h
+++ b/gcc/rtl-ssa/access-utils.h
@@ -33,6 +33,20 @@ accesses_include_hard_registers (const access_array &accesses)
return accesses.size () && HARD_REGISTER_NUM_P (accesses.front ()->regno ());
}
+// Return true if ACCESSES includes a reference to a non-fixed hard register.
+inline bool
+accesses_include_nonfixed_hard_registers (access_array accesses)
+{
+ for (access_info *access : accesses)
+ {
+ if (!HARD_REGISTER_NUM_P (access->regno ()))
+ break;
+ if (!fixed_regs[access->regno ()])
+ return true;
+ }
+ return false;
+}
+
// Return true if sorted array ACCESSES includes an access to memory.
inline bool
accesses_include_memory (const access_array &accesses)
@@ -127,24 +141,6 @@ set_with_nondebug_insn_uses (access_info *access)
return nullptr;
}
-// Return true if SET is the only set of SET->resource () and if it
-// dominates all uses (excluding uses of SET->resource () at points
-// where SET->resource () is always undefined).
-inline bool
-is_single_dominating_def (const set_info *set)
-{
- return set->is_first_def () && set->is_last_def ();
-}
-
-// SET is known to be available on entry to BB. Return true if it is
-// also available on exit from BB. (The value might or might not be live.)
-inline bool
-remains_available_on_exit (const set_info *set, bb_info *bb)
-{
- return (set->is_last_def ()
- || *set->next_def ()->insn () > *bb->end_insn ());
-}
-
// ACCESS is known to be associated with an instruction rather than
// a phi node. Return which instruction that is.
inline insn_info *
@@ -264,6 +260,22 @@ last_def (def_mux mux)
return mux.last_def ();
}
+// If INSN's definitions contain a single set, return that set, otherwise
+// return null.
+inline set_info *
+single_set_info (insn_info *insn)
+{
+ set_info *set = nullptr;
+ for (auto def : insn->defs ())
+ if (auto this_set = dyn_cast<set_info *> (def))
+ {
+ if (set)
+ return nullptr;
+ set = this_set;
+ }
+ return set;
+}
+
int lookup_use (splay_tree<use_info *> &, insn_info *);
int lookup_def (def_splay_tree &, insn_info *);
int lookup_clobber (clobber_tree &, insn_info *);
@@ -313,6 +325,15 @@ next_call_clobbers_ignoring (insn_call_clobbers_tree &tree, insn_info *insn,
return tree->insn ();
}
+// Search forwards from immediately after INSN for the first instruction
+// recorded in TREE. Return null if no such instruction exists.
+inline insn_info *
+next_call_clobbers (insn_call_clobbers_tree &tree, insn_info *insn)
+{
+ auto ignore = [](const insn_info *) { return false; };
+ return next_call_clobbers_ignoring (tree, insn, ignore);
+}
+
// If ACCESS is a set, return the first use of ACCESS by a nondebug insn I
// for which IGNORE (I) is false. Return null if ACCESS is not a set or if
// no such use exists.
@@ -548,6 +569,10 @@ insert_access (obstack_watermark &watermark,
return T (insert_access_base (watermark, access1, accesses2));
}
+// Return a copy of USES that drops any use of DEF.
+use_array remove_uses_of_def (obstack_watermark &, use_array uses,
+ def_info *def);
+
// The underlying non-template implementation of remove_note_accesses.
access_array remove_note_accesses_base (obstack_watermark &, access_array);
@@ -563,4 +588,11 @@ remove_note_accesses (obstack_watermark &watermark, T accesses)
return T (remove_note_accesses_base (watermark, accesses));
}
+// Return true if ACCESSES1 and ACCESSES2 have at least one resource in common.
+bool accesses_reference_same_resource (access_array accesses1,
+ access_array accesses2);
+
+// Return true if INSN clobbers the value of any resources in ACCESSES.
+bool insn_clobbers_resources (insn_info *insn, access_array accesses);
+
}
diff --git a/gcc/rtl-ssa/accesses.cc b/gcc/rtl-ssa/accesses.cc
index 774ab9d..510545a 100644
--- a/gcc/rtl-ssa/accesses.cc
+++ b/gcc/rtl-ssa/accesses.cc
@@ -1303,6 +1303,58 @@ function_info::insert_temp_clobber (obstack_watermark &watermark,
return insert_access (watermark, clobber, old_defs);
}
+// See the comment above the declaration.
+bool
+function_info::remains_available_at_insn (const set_info *set,
+ insn_info *insn)
+{
+ auto *ebb = set->ebb ();
+ gcc_checking_assert (ebb == insn->ebb ());
+
+ def_info *next_def = set->next_def ();
+ if (next_def && *next_def->insn () < *insn)
+ return false;
+
+ if (HARD_REGISTER_NUM_P (set->regno ())
+ && TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ()))
+ for (ebb_call_clobbers_info *call_group : ebb->call_clobbers ())
+ {
+ if (!call_group->clobbers (set->resource ()))
+ continue;
+
+ insn_info *call_insn = next_call_clobbers (*call_group, insn);
+ if (call_insn && *call_insn < *insn)
+ return false;
+ }
+
+ return true;
+}
+
+// See the comment above the declaration.
+bool
+function_info::remains_available_on_exit (const set_info *set, bb_info *bb)
+{
+ if (HARD_REGISTER_NUM_P (set->regno ())
+ && TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ()))
+ {
+ insn_info *search_insn = (set->bb () == bb
+ ? set->insn ()
+ : bb->head_insn ());
+ for (ebb_call_clobbers_info *call_group : bb->ebb ()->call_clobbers ())
+ {
+ if (!call_group->clobbers (set->resource ()))
+ continue;
+
+ insn_info *insn = next_call_clobbers (*call_group, search_insn);
+ if (insn && insn->bb () == bb)
+ return false;
+ }
+ }
+
+ return (set->is_last_def ()
+ || *set->next_def ()->insn () > *bb->end_insn ());
+}
+
// A subroutine of make_uses_available. Try to make USE's definition
// available at the head of BB. WILL_BE_DEBUG_USE is true if the
// definition will be used only in debug instructions.
@@ -1329,14 +1381,20 @@ function_info::make_use_available (use_info *use, bb_info *bb,
if (is_single_dominating_def (def))
return use;
- // FIXME: Deliberately limited for fwprop compatibility testing.
+ if (def->ebb () == bb->ebb ())
+ {
+ if (remains_available_at_insn (def, bb->head_insn ()))
+ return use;
+ return nullptr;
+ }
+
basic_block cfg_bb = bb->cfg_bb ();
bb_info *use_bb = use->bb ();
if (single_pred_p (cfg_bb)
&& single_pred (cfg_bb) == use_bb->cfg_bb ()
&& remains_available_on_exit (def, use_bb))
{
- if (def->ebb () == bb->ebb () || will_be_debug_use)
+ if (will_be_debug_use)
return use;
resource_info resource = use->resource ();
@@ -1512,6 +1570,19 @@ rtl_ssa::insert_access_base (obstack_watermark &watermark,
}
// See the comment above the declaration.
+use_array
+rtl_ssa::remove_uses_of_def (obstack_watermark &watermark, use_array uses,
+ def_info *def)
+{
+ access_array_builder uses_builder (watermark);
+ uses_builder.reserve (uses.size ());
+ for (use_info *use : uses)
+ if (use->def () != def)
+ uses_builder.quick_push (use);
+ return use_array (uses_builder.finish ());
+}
+
+// See the comment above the declaration.
access_array
rtl_ssa::remove_note_accesses_base (obstack_watermark &watermark,
access_array accesses)
@@ -1529,6 +1600,56 @@ rtl_ssa::remove_note_accesses_base (obstack_watermark &watermark,
return accesses;
}
+// See the comment above the declaration.
+bool
+rtl_ssa::accesses_reference_same_resource (access_array accesses1,
+ access_array accesses2)
+{
+ auto i1 = accesses1.begin ();
+ auto end1 = accesses1.end ();
+ auto i2 = accesses2.begin ();
+ auto end2 = accesses2.end ();
+
+ while (i1 != end1 && i2 != end2)
+ {
+ access_info *access1 = *i1;
+ access_info *access2 = *i2;
+
+ unsigned int regno1 = access1->regno ();
+ unsigned int regno2 = access2->regno ();
+ if (regno1 == regno2)
+ return true;
+
+ if (regno1 < regno2)
+ ++i1;
+ else
+ ++i2;
+ }
+ return false;
+}
+
+// See the comment above the declaration.
+bool
+rtl_ssa::insn_clobbers_resources (insn_info *insn, access_array accesses)
+{
+ if (accesses_reference_same_resource (insn->defs (), accesses))
+ return true;
+
+ if (insn->is_call () && accesses_include_hard_registers (accesses))
+ {
+ function_abi abi = insn_callee_abi (insn->rtl ());
+ for (const access_info *access : accesses)
+ {
+ if (!HARD_REGISTER_NUM_P (access->regno ()))
+ break;
+ if (abi.clobbers_reg_p (access->mode (), access->regno ()))
+ return true;
+ }
+ }
+
+ return false;
+}
+
// Print RESOURCE to PP.
void
rtl_ssa::pp_resource (pretty_printer *pp, resource_info resource)
diff --git a/gcc/rtl-ssa/blocks.cc b/gcc/rtl-ssa/blocks.cc
index d46cbf1..0ce798e 100644
--- a/gcc/rtl-ssa/blocks.cc
+++ b/gcc/rtl-ssa/blocks.cc
@@ -47,7 +47,8 @@ function_info::build_info::build_info (unsigned int num_regs,
potential_phi_regs (num_regs),
bb_phis (num_bb_indices),
bb_mem_live_out (num_bb_indices),
- bb_to_rpo (num_bb_indices)
+ bb_to_rpo (num_bb_indices),
+ exit_block_dominator (nullptr)
{
last_access.safe_grow_cleared (num_regs + 1);
@@ -103,21 +104,8 @@ function_info::bb_walker::bb_walker (function_info *function, build_info &bi)
: dom_walker (CDI_DOMINATORS, ALL_BLOCKS, bi.bb_to_rpo.address ()),
m_function (function),
m_bi (bi),
- m_exit_block_dominator (nullptr)
+ m_exit_block_dominator (bi.exit_block_dominator)
{
- // ??? There is no dominance information associated with the exit block,
- // so work out its immediate dominator using predecessor blocks. We then
- // walk the exit block just before popping its immediate dominator.
- edge e;
- edge_iterator ei;
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (m_function->m_fn)->preds)
- if (m_exit_block_dominator)
- m_exit_block_dominator
- = nearest_common_dominator (CDI_DOMINATORS,
- m_exit_block_dominator, e->src);
- else
- m_exit_block_dominator = e->src;
-
// If the exit block is unreachable, process it last.
if (!m_exit_block_dominator)
m_exit_block_dominator = ENTRY_BLOCK_PTR_FOR_FN (m_function->m_fn);
@@ -525,6 +513,11 @@ function_info::create_phi (ebb_info *ebb, resource_info resource,
phi_info *
function_info::create_degenerate_phi (ebb_info *ebb, set_info *def)
{
+ // Allow the function to be called twice in succession for the same def.
+ def_lookup dl = find_def (def->resource (), ebb->phi_insn ());
+ if (set_info *set = dl.matching_set ())
+ return as_a<phi_info *> (set);
+
access_info *input = def;
phi_info *phi = create_phi (ebb, def->resource (), &input, 1);
if (def->is_reg ())
@@ -619,6 +612,19 @@ function_info::place_phis (build_info &bi)
bitmap_initialize (&frontiers[i], &bitmap_default_obstack);
compute_dominance_frontiers (frontiers.address ());
+ // The normal dominance information doesn't calculate dominators for
+ // the exit block, so we don't get dominance frontiers for them either.
+ // Calculate them by hand.
+ for (edge e : EXIT_BLOCK_PTR_FOR_FN (m_fn)->preds)
+ {
+ basic_block bb = e->src;
+ while (bb != bi.exit_block_dominator)
+ {
+ bitmap_set_bit (&frontiers[bb->index], EXIT_BLOCK);
+ bb = get_immediate_dominator (CDI_DOMINATORS, bb);
+ }
+ }
+
// In extreme cases, the number of live-in registers can be much
// greater than the number of phi nodes needed in a block (see PR98863).
// Try to reduce the number of operations involving live-in sets by using
@@ -861,11 +867,14 @@ function_info::add_artificial_accesses (build_info &bi, df_ref_flags flags)
start_insn_accesses ();
+ HARD_REG_SET added_regs = {};
FOR_EACH_ARTIFICIAL_USE (ref, cfg_bb->index)
if ((DF_REF_FLAGS (ref) & DF_REF_AT_TOP) == flags)
{
unsigned int regno = DF_REF_REGNO (ref);
machine_mode mode = GET_MODE (DF_REF_REAL_REG (ref));
+ if (HARD_REGISTER_NUM_P (regno))
+ SET_HARD_REG_BIT (added_regs, regno);
// A definition must be available.
gcc_checking_assert (bitmap_bit_p (&lr_info->in, regno)
@@ -874,10 +883,20 @@ function_info::add_artificial_accesses (build_info &bi, df_ref_flags flags)
m_temp_uses.safe_push (create_reg_use (bi, insn, { mode, regno }));
}
- // Track the return value of memory by adding an artificial use of
- // memory at the end of the exit block.
- if (flags == 0 && cfg_bb->index == EXIT_BLOCK)
+ // Ensure that global registers and memory are live at the end of any
+ // block that has no successors, such as the exit block and non-local gotos.
+ // Global registers have to be singled out because they are not part of
+ // the DF artifical use list (they are instead treated as used within
+ // every block).
+ if (flags == 0 && EDGE_COUNT (cfg_bb->succs) == 0)
{
+ for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
+ if (global_regs[i] && !TEST_HARD_REG_BIT (added_regs, i))
+ {
+ auto mode = reg_raw_mode[i];
+ m_temp_uses.safe_push (create_reg_use (bi, insn, { mode, i }));
+ }
+
auto *use = allocate<use_info> (insn, memory, bi.current_mem_value ());
add_use (use);
m_temp_uses.safe_push (use);
@@ -1246,6 +1265,16 @@ function_info::process_all_blocks ()
build_info bi (m_num_regs, num_bb_indices);
+ // ??? There is no dominance information associated with the exit block,
+ // so work out its immediate dominator using predecessor blocks.
+ for (edge e : EXIT_BLOCK_PTR_FOR_FN (m_fn)->preds)
+ if (bi.exit_block_dominator)
+ bi.exit_block_dominator
+ = nearest_common_dominator (CDI_DOMINATORS,
+ bi.exit_block_dominator, e->src);
+ else
+ bi.exit_block_dominator = e->src;
+
calculate_potential_phi_regs (bi);
create_ebbs (bi);
place_phis (bi);
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index 73ab3cc..aab532b 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -34,6 +34,7 @@
#include "emit-rtl.h"
#include "cfghooks.h"
#include "cfgrtl.h"
+#include "sreal.h"
using namespace rtl_ssa;
@@ -171,18 +172,33 @@ rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
{
unsigned int old_cost = 0;
unsigned int new_cost = 0;
+ sreal weighted_old_cost = 0;
+ sreal weighted_new_cost = 0;
+ auto entry_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
for (insn_change *change : changes)
{
old_cost += change->old_cost ();
+ basic_block cfg_bb = change->bb ()->cfg_bb ();
+ bool for_speed = optimize_bb_for_speed_p (cfg_bb);
+ if (for_speed)
+ weighted_old_cost += (cfg_bb->count.to_sreal_scale (entry_count)
+ * change->old_cost ());
if (!change->is_deletion ())
{
- basic_block cfg_bb = change->bb ()->cfg_bb ();
- change->new_cost = insn_cost (change->rtl (),
- optimize_bb_for_speed_p (cfg_bb));
+ change->new_cost = insn_cost (change->rtl (), for_speed);
new_cost += change->new_cost;
+ if (for_speed)
+ weighted_new_cost += (cfg_bb->count.to_sreal_scale (entry_count)
+ * change->new_cost);
}
}
- bool ok_p = (strict_p ? new_cost < old_cost : new_cost <= old_cost);
+ bool ok_p;
+ if (weighted_new_cost != weighted_old_cost)
+ ok_p = weighted_new_cost < weighted_old_cost;
+ else if (strict_p)
+ ok_p = new_cost < old_cost;
+ else
+ ok_p = new_cost <= old_cost;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "original cost");
@@ -192,6 +208,8 @@ rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
fprintf (dump_file, " %c %d", sep, change->old_cost ());
sep = '+';
}
+ if (weighted_old_cost != 0)
+ fprintf (dump_file, " (weighted: %f)", weighted_old_cost.to_double ());
fprintf (dump_file, ", replacement cost");
sep = '=';
for (const insn_change *change : changes)
@@ -200,6 +218,8 @@ rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
fprintf (dump_file, " %c %d", sep, change->new_cost);
sep = '+';
}
+ if (weighted_new_cost != 0)
+ fprintf (dump_file, " (weighted: %f)", weighted_new_cost.to_double ());
fprintf (dump_file, "; %s\n",
ok_p ? "keeping replacement" : "rejecting replacement");
}
@@ -209,6 +229,35 @@ rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
return true;
}
+// SET has been deleted. Clean up all remaining uses. Such uses are
+// either dead phis or now-redundant live-out uses.
+void
+function_info::process_uses_of_deleted_def (set_info *set)
+{
+ if (!set->has_any_uses ())
+ return;
+
+ auto *use = *set->all_uses ().begin ();
+ do
+ {
+ auto *next_use = use->next_use ();
+ if (use->is_in_phi ())
+ {
+ // This call will not recurse.
+ process_uses_of_deleted_def (use->phi ());
+ delete_phi (use->phi ());
+ }
+ else
+ {
+ gcc_assert (use->is_live_out_use ());
+ remove_use (use);
+ }
+ use = next_use;
+ }
+ while (use);
+ gcc_assert (!set->has_any_uses ());
+}
+
// Update the REG_NOTES of INSN, whose pattern has just been changed.
static void
update_notes (rtx_insn *insn)
@@ -429,8 +478,18 @@ function_info::finalize_new_accesses (insn_change &change, insn_info *pos)
// Also keep any explicitly-recorded call clobbers, which are deliberately
// excluded from the vec_rtx_properties. Calls shouldn't move, so we can
// keep the definitions in their current position.
+ //
+ // If the change describes a set of memory, but the pattern doesn't
+ // reference memory, keep the set anyway. This can happen if the
+ // old pattern was a parallel that contained a memory clobber, and if
+ // the new pattern was recognized without that clobber. Keeping the
+ // set avoids a linear-complexity update to the set's users.
+ //
+ // ??? We could queue an update so that these bogus clobbers are
+ // removed later.
for (def_info *def : change.new_defs)
- if (def->m_has_been_superceded && def->is_call_clobber ())
+ if (def->m_has_been_superceded
+ && (def->is_call_clobber () || def->is_mem ()))
{
def->m_has_been_superceded = false;
def->set_insn (insn);
@@ -535,7 +594,7 @@ function_info::finalize_new_accesses (insn_change &change, insn_info *pos)
}
}
- // Install the new list of definitions in CHANGE.
+ // Install the new list of uses in CHANGE.
sort_accesses (m_temp_uses);
change.new_uses = use_array (temp_access_array (m_temp_uses));
m_temp_uses.truncate (0);
@@ -586,8 +645,6 @@ function_info::apply_changes_to_insn (insn_change &change)
insn->set_accesses (builder.finish ().begin (), num_defs, num_uses);
}
-
- add_reg_unused_notes (insn);
}
// Add a temporary placeholder instruction after AFTER.
@@ -687,7 +744,8 @@ function_info::change_insns (array_slice<insn_change *> changes)
}
// Remove all definitions that are no longer needed. After the above,
- // such definitions should no longer have any registered users.
+ // the only uses of such definitions should be dead phis and now-redundant
+ // live-out uses.
//
// In particular, this means that consumers must handle debug
// instructions before removing a set.
@@ -696,7 +754,8 @@ function_info::change_insns (array_slice<insn_change *> changes)
if (def->m_has_been_superceded)
{
auto *set = dyn_cast<set_info *> (def);
- gcc_assert (!set || !set->has_any_uses ());
+ if (set && set->has_any_uses ())
+ process_uses_of_deleted_def (set);
remove_def (def);
}
@@ -733,9 +792,14 @@ function_info::change_insns (array_slice<insn_change *> changes)
}
}
- // Finally apply the changes to the underlying insn_infos.
+ // Apply the changes to the underlying insn_infos.
for (insn_change *change : changes)
apply_changes_to_insn (*change);
+
+ // Now that the insns and accesses are up to date, add any REG_UNUSED notes.
+ for (insn_change *change : changes)
+ if (!change->is_deletion ())
+ add_reg_unused_notes (change->insn ());
}
// See the comment above the declaration.
@@ -983,7 +1047,10 @@ function_info::perform_pending_updates ()
for (insn_info *insn : m_queued_insn_updates)
{
rtx_insn *rtl = insn->rtl ();
- if (JUMP_P (rtl))
+ if (NOTE_P (rtl))
+ // The insn was later optimized away, typically to a NOTE_INSN_DELETED.
+ ;
+ else if (JUMP_P (rtl))
{
if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
{
diff --git a/gcc/rtl-ssa/functions.cc b/gcc/rtl-ssa/functions.cc
index c35d25d..8a8108b 100644
--- a/gcc/rtl-ssa/functions.cc
+++ b/gcc/rtl-ssa/functions.cc
@@ -32,7 +32,7 @@
using namespace rtl_ssa;
function_info::function_info (function *fn)
- : m_fn (fn)
+ : m_fn (fn), m_clobbered_by_calls ()
{
// Force the alignment to be obstack_alignment. Everything else is normal.
obstack_specify_allocation (&m_obstack, OBSTACK_CHUNK_SIZE,
diff --git a/gcc/rtl-ssa/functions.h b/gcc/rtl-ssa/functions.h
index 73690a0..ecb40fd 100644
--- a/gcc/rtl-ssa/functions.h
+++ b/gcc/rtl-ssa/functions.h
@@ -102,6 +102,11 @@ public:
// definitions by things like phi nodes.
iterator_range<def_iterator> reg_defs (unsigned int regno) const;
+ // Return true if SET is the only set of SET->resource () and if it
+ // dominates all uses (excluding uses of SET->resource () at points
+ // where SET->resource () is always undefined).
+ bool is_single_dominating_def (const set_info *set) const;
+
// Check if all uses of register REGNO are either unconditionally undefined
// or use the same single dominating definition. Return the definition
// if so, otherwise return null.
@@ -116,6 +121,15 @@ public:
// scope until the change has been aborted or successfully completed.
obstack_watermark new_change_attempt () { return &m_temp_obstack; }
+ // SET and INSN belong to the same EBB, with SET occuring before INSN.
+ // Return true if SET is still available at INSN.
+ bool remains_available_at_insn (const set_info *set, insn_info *insn);
+
+ // SET either occurs in BB or is known to be available on entry to BB.
+ // Return true if it is also available on exit from BB. (The value
+ // might or might not be live.)
+ bool remains_available_on_exit (const set_info *set, bb_info *bb);
+
// Make a best attempt to check whether the values used by USES are
// available on entry to BB, without solving a full dataflow problem.
// If all the values are already live on entry to BB or can be made
@@ -263,6 +277,7 @@ private:
bb_info *create_bb_info (basic_block);
void append_bb (bb_info *);
+ void process_uses_of_deleted_def (set_info *);
insn_info *add_placeholder_after (insn_info *);
void possibly_queue_changes (insn_change &);
void finalize_new_accesses (insn_change &, insn_info *);
@@ -356,6 +371,10 @@ private:
// on it. As with M_QUEUED_INSN_UPDATES, these updates are queued until
// a convenient point.
auto_bitmap m_need_to_purge_dead_edges;
+
+ // The set of hard registers that are fully or partially clobbered
+ // by at least one insn_call_clobbers_note.
+ HARD_REG_SET m_clobbered_by_calls;
};
void pp_function (pretty_printer *, const function_info *);
diff --git a/gcc/rtl-ssa/insns.cc b/gcc/rtl-ssa/insns.cc
index f970375..5fde3f2 100644
--- a/gcc/rtl-ssa/insns.cc
+++ b/gcc/rtl-ssa/insns.cc
@@ -568,6 +568,8 @@ function_info::record_call_clobbers (build_info &bi, insn_info *insn,
insn->add_note (insn_clobbers);
ecc->insert_max_node (insn_clobbers);
+
+ m_clobbered_by_calls |= abi.full_and_partial_reg_clobbers ();
}
else
for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
diff --git a/gcc/rtl-ssa/internals.h b/gcc/rtl-ssa/internals.h
index 6ed9577..e65ba9f 100644
--- a/gcc/rtl-ssa/internals.h
+++ b/gcc/rtl-ssa/internals.h
@@ -135,6 +135,10 @@ public:
// The top of this stack records the start of the current block's
// section in DEF_STACK.
auto_vec<unsigned int> old_def_stack_limit;
+
+ // The block that dominates the exit block, or null if the exit block
+ // is unreachable.
+ basic_block exit_block_dominator;
};
}
diff --git a/gcc/rtl-ssa/member-fns.inl b/gcc/rtl-ssa/member-fns.inl
index c127fab..ce2db04 100644
--- a/gcc/rtl-ssa/member-fns.inl
+++ b/gcc/rtl-ssa/member-fns.inl
@@ -215,7 +215,7 @@ set_info::last_nondebug_insn_use () const
inline use_info *
set_info::first_any_insn_use () const
{
- if (m_first_use->is_in_any_insn ())
+ if (m_first_use && m_first_use->is_in_any_insn ())
return m_first_use;
return nullptr;
}
@@ -916,6 +916,15 @@ function_info::reg_defs (unsigned int regno) const
return { m_defs[regno + 1], nullptr };
}
+inline bool
+function_info::is_single_dominating_def (const set_info *set) const
+{
+ return (set->is_first_def ()
+ && set->is_last_def ()
+ && (!HARD_REGISTER_NUM_P (set->regno ())
+ || !TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ())));
+}
+
inline set_info *
function_info::single_dominating_def (unsigned int regno) const
{
diff --git a/gcc/rtl-ssa/movement.cc b/gcc/rtl-ssa/movement.cc
new file mode 100644
index 0000000..fcf5f8b
--- /dev/null
+++ b/gcc/rtl-ssa/movement.cc
@@ -0,0 +1,40 @@
+// RTL SSA routines for moving instructions
+// 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/>.
+
+#define INCLUDE_ALGORITHM
+#define INCLUDE_FUNCTIONAL
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "rtl.h"
+#include "df.h"
+#include "rtl-ssa.h"
+#include "rtl-ssa/internals.h"
+#include "rtl-ssa/internals.inl"
+
+using namespace rtl_ssa;
+
+// See the comment above the declaration.
+bool
+rtl_ssa::can_move_insn_p (insn_info *insn)
+{
+ return (!control_flow_insn_p (insn->rtl ())
+ && !may_trap_p (PATTERN (insn->rtl ())));
+}
diff --git a/gcc/rtl-ssa/movement.h b/gcc/rtl-ssa/movement.h
index d9945f4..ec076db 100644
--- a/gcc/rtl-ssa/movement.h
+++ b/gcc/rtl-ssa/movement.h
@@ -19,6 +19,10 @@
namespace rtl_ssa {
+// Return true if INSN can in principle be moved around, and if RTL-SSA
+// has enough information to do that.
+bool can_move_insn_p (insn_info *);
+
// Restrict movement range RANGE so that the instruction is placed later
// than INSN. (The movement range is the range of instructions after which
// an instruction can be placed.)
@@ -61,7 +65,8 @@ move_earlier_than (insn_range_info range, insn_info *insn)
inline bool
can_insert_after (insn_info *insn)
{
- return insn->is_bb_head () || (insn->is_real () && !insn->is_jump ());
+ return (insn->is_bb_head ()
+ || (insn->is_real () && !control_flow_insn_p (insn->rtl ())));
}
// Try to restrict move range MOVE_RANGE so that it is possible to
diff --git a/gcc/stringpool.cc b/gcc/stringpool.cc
index 8658e6a..3848967 100644
--- a/gcc/stringpool.cc
+++ b/gcc/stringpool.cc
@@ -29,8 +29,10 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "cpplib.h"
struct ht *ident_hash;
+struct ht *ident_hash_extra;
static hashnode alloc_node (cpp_hash_table *);
static int mark_ident (struct cpp_reader *, hashnode, const void *);
@@ -49,11 +51,21 @@ init_stringpool (void)
(We can't make this idempotent since identifiers contain state) */
if (ident_hash)
ht_destroy (ident_hash);
+ if (ident_hash_extra)
+ ht_destroy (ident_hash_extra);
/* Create with 16K (2^14) entries. */
ident_hash = ht_create (14);
ident_hash->alloc_node = alloc_node;
ident_hash->alloc_subobject = stringpool_ggc_alloc;
+
+ /* Create with 64 (2^6) entries. */
+ ident_hash_extra = ht_create (6);
+ ident_hash_extra->alloc_node = [] (cpp_hash_table *)
+ {
+ return HT_NODE (ggc_cleared_alloc<cpp_hashnode_extra> ());
+ };
+ ident_hash_extra->alloc_subobject = stringpool_ggc_alloc;
}
/* Allocate a hash node. */
@@ -166,6 +178,12 @@ void
ggc_mark_stringpool (void)
{
ht_forall (ident_hash, mark_ident, NULL);
+ ht_forall (ident_hash_extra,
+ [] (cpp_reader *, hashnode h, const void *)
+ {
+ gt_ggc_m_18cpp_hashnode_extra (h);
+ return 1;
+ }, nullptr);
}
/* Purge the identifier hash of identifiers which are no longer
@@ -175,6 +193,11 @@ void
ggc_purge_stringpool (void)
{
ht_purge (ident_hash, maybe_delete_ident, NULL);
+ ht_purge (ident_hash_extra,
+ [] (cpp_reader *, hashnode h, const void *) -> int
+ {
+ return !ggc_marked_p (h);
+ }, nullptr);
}
/* Pointer-walking routine for strings (not very interesting, since
@@ -251,7 +274,19 @@ struct GTY(()) string_pool_data {
unsigned int nelements;
};
+struct GTY (()) string_pool_data_extra
+{
+ ht_identifier_ptr *
+ GTY((length ("%h.nslots"),
+ nested_ptr (cpp_hashnode_extra, "%h ? HT_NODE (%h) : nullptr",
+ "(cpp_hashnode_extra *)%h")))
+ entries;
+ unsigned int nslots;
+ unsigned int nelements;
+};
+
static GTY(()) struct string_pool_data * spd;
+static GTY(()) struct string_pool_data_extra *spd2;
/* Save the stringpool data in SPD. */
@@ -264,6 +299,13 @@ gt_pch_save_stringpool (void)
spd->entries = ggc_vec_alloc<ht_identifier_ptr> (spd->nslots);
memcpy (spd->entries, ident_hash->entries,
spd->nslots * sizeof (spd->entries[0]));
+
+ spd2 = ggc_alloc<string_pool_data_extra> ();
+ spd2->nslots = ident_hash_extra->nslots;
+ spd2->nelements = ident_hash_extra->nelements;
+ spd2->entries = ggc_vec_alloc<ht_identifier_ptr> (spd2->nslots);
+ memcpy (spd2->entries, ident_hash_extra->entries,
+ spd2->nslots * sizeof (spd2->entries[0]));
}
/* Return the stringpool to its state before gt_pch_save_stringpool
@@ -281,7 +323,10 @@ void
gt_pch_restore_stringpool (void)
{
ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
+ ht_load (ident_hash_extra, spd2->entries, spd2->nslots, spd2->nelements,
+ false);
spd = NULL;
+ spd2 = NULL;
}
#include "gt-stringpool.h"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 413c9b7..1560603 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,958 @@
+2023-10-31 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.dg/vect/vect-gather-6.c: New test.
+
+2023-10-31 Cupertino Miranda <cupertino.miranda@oracle.com>
+
+ * gcc.target/bpf/core-attr-5.c: New test.
+ * gcc.target/bpf/core-attr-6.c: New test.
+ * gcc.target/bpf/core-builtin-1.c: Corrected
+ * gcc.target/bpf/core-builtin-enumvalue-opt.c: Corrected regular
+ expression.
+ * gcc.target/bpf/core-builtin-enumvalue.c: Corrected regular
+ expression.
+ * gcc.target/bpf/core-builtin-exprlist-1.c: New test.
+ * gcc.target/bpf/core-builtin-exprlist-2.c: New test.
+ * gcc.target/bpf/core-builtin-exprlist-3.c: New test.
+ * gcc.target/bpf/core-builtin-exprlist-4.c: New test.
+ * gcc.target/bpf/core-builtin-fieldinfo-offset-1.c: Extra tests
+
+2023-10-31 Neal Frager <neal.frager@amd.com>
+
+ * gcc.target/microblaze/isa/bshift.c: Bump to mcpu=v10.0.
+ * gcc.target/microblaze/isa/div.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp1.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp2.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp3.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp4.c: Ditto.
+ * gcc.target/microblaze/isa/fcvt.c: Ditto.
+ * gcc.target/microblaze/isa/float.c: Ditto.
+ * gcc.target/microblaze/isa/fsqrt.c: Ditto.
+ * gcc.target/microblaze/isa/mul-bshift-pcmp.c: Ditto.
+ * gcc.target/microblaze/isa/mul-bshift.c: Ditto.
+ * gcc.target/microblaze/isa/mul.c: Ditto.
+ * gcc.target/microblaze/isa/mulh-bshift-pcmp.c: Ditto.
+ * gcc.target/microblaze/isa/mulh.c: Ditto.
+ * gcc.target/microblaze/isa/nofcmp.c: Ditto.
+ * gcc.target/microblaze/isa/nofloat.c: Ditto.
+ * gcc.target/microblaze/isa/pcmp.c: Ditto.
+ * gcc.target/microblaze/isa/vanilla.c: Ditto.
+ * gcc.target/microblaze/microblaze.exp: Ditto.
+
+2023-10-31 Patrick O'Neill <patrick@rivosinc.com>
+
+ * gcc.target/riscv/amo-table-a-6-amo-add-1.c: Add A extension to
+ dg-options for dg-do compile.
+ * gcc.target/riscv/amo-table-a-6-amo-add-2.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-amo-add-3.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-amo-add-4.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-amo-add-5.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-compare-exchange-1.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-compare-exchange-2.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-compare-exchange-3.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-compare-exchange-4.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-compare-exchange-5.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-compare-exchange-6.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-compare-exchange-7.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-subword-amo-add-1.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-subword-amo-add-2.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-subword-amo-add-3.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-subword-amo-add-4.c: Ditto.
+ * gcc.target/riscv/amo-table-a-6-subword-amo-add-5.c: Ditto.
+ * gcc.target/riscv/inline-atomics-2.c: Ditto.
+ * gcc.target/riscv/inline-atomics-3.c: Require A extension for dg-do
+ run.
+ * gcc.target/riscv/inline-atomics-4.c: Ditto.
+ * gcc.target/riscv/inline-atomics-5.c: Ditto.
+ * gcc.target/riscv/inline-atomics-6.c: Ditto.
+ * gcc.target/riscv/inline-atomics-7.c: Ditto.
+ * gcc.target/riscv/inline-atomics-8.c: Ditto.
+ * lib/target-supports.exp: Add testing infrastructure to require the A
+ extension or add it to an existing -march.
+
+2023-10-31 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * gcc.target/riscv/xtheadfmemidx-index-update.c: New test.
+ * gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c: New test.
+ * gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c: New test.
+ * gcc.target/riscv/xtheadfmemidx-index.c: New test.
+ * gcc.target/riscv/xtheadfmemidx-uindex-update.c: New test.
+ * gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c: New test.
+ * gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c: New test.
+ * gcc.target/riscv/xtheadfmemidx-uindex.c: New test.
+
+2023-10-31 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * gcc.target/riscv/xtheadmemidx-helpers.h: New test.
+ * gcc.target/riscv/xtheadmemidx-index-update.c: New test.
+ * gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c: New test.
+ * gcc.target/riscv/xtheadmemidx-index-xtheadbb.c: New test.
+ * gcc.target/riscv/xtheadmemidx-index.c: New test.
+ * gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c: New test.
+ * gcc.target/riscv/xtheadmemidx-modify.c: New test.
+ * gcc.target/riscv/xtheadmemidx-uindex-update.c: New test.
+ * gcc.target/riscv/xtheadmemidx-uindex-xtheadbb-update.c: New test.
+ * gcc.target/riscv/xtheadmemidx-uindex-xtheadbb.c: New test.
+ * gcc.target/riscv/xtheadmemidx-uindex.c: New test.
+
+2023-10-31 Carl Love <cel@us.ibm.com>
+
+ * gcc.target/powerpc/bcd-3.c (do_sub_ge, do_suble): Add functions
+ to test builtins __builtin_bcdsub_ge and __builtin_bcdsub_le.
+
+2023-10-31 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/111971
+ * gcc.target/powerpc/pr111971.c: New test.
+
+2023-10-31 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Remove
+ -ffast-math.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/binop/fmax-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/fmin-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c: New test.
+ * gcc.target/riscv/rvv/autovec/reduc/reduc-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c: New test.
+
+2023-10-31 Alexandre Oliva <oliva@adacore.com>
+
+ PR tree-optimization/111943
+ * gcc.dg/harden-cfr-pr111943.c: New.
+
+2023-10-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/112305
+ * gcc.dg/torture/pr112305.c: New testcase.
+
+2023-10-31 Lehua Ding <lehua.ding@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c: Add vmerge assert.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv64gcv.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-10.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-11.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-5.c: New test.
+
+2023-10-31 Lehua Ding <lehua.ding@rivai.ai>
+
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-1.c:
+ Add vfncvt.f.f.w assert.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-2.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c:
+ Ditto.
+ * gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c:
+ Ditto.
+
+2023-10-31 liuhongt <hongtao.liu@intel.com>
+
+ * g++.target/i386/part-vect-vcondhf.C: Adjust testcase.
+ * gcc.target/i386/pr112276.c: New test.
+
+2023-10-31 Andrew Pinski <pinskia@gmail.com>
+
+ * gcc.dg/tree-ssa/phi-opt-value-4.c: New test.
+
+2023-10-31 Andrew Pinski <pinskia@gmail.com>
+
+ * gcc.dg/tree-ssa/cond-1.c: New test.
+ * gcc.dg/tree-ssa/phi-opt-value-1.c: New test.
+ * gcc.dg/tree-ssa/phi-opt-value-1a.c: New test.
+ * gcc.dg/tree-ssa/phi-opt-value-2.c: New test.
+
+2023-10-31 Neal Frager <neal.frager@amd.com>
+
+ * gcc.target/microblaze/isa/bshift.c: Bump to mcpu=v10.0.
+ * gcc.target/microblaze/isa/div.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp1.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp2.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp3.c: Ditto.
+ * gcc.target/microblaze/isa/fcmp4.c: Ditto.
+ * gcc.target/microblaze/isa/fcvt.c: Ditto.
+ * gcc.target/microblaze/isa/float.c: Ditto.
+ * gcc.target/microblaze/isa/fsqrt.c: Ditto.
+ * gcc.target/microblaze/isa/mul-bshift-pcmp.c: Ditto.
+ * gcc.target/microblaze/isa/mul-bshift.c: Ditto.
+ * gcc.target/microblaze/isa/mul.c: Ditto.
+ * gcc.target/microblaze/isa/mulh-bshift-pcmp.c: Ditto.
+ * gcc.target/microblaze/isa/mulh.c: Ditto.
+ * gcc.target/microblaze/isa/nofcmp.c: Ditto.
+ * gcc.target/microblaze/isa/nofloat.c: Ditto.
+ * gcc.target/microblaze/isa/pcmp.c: Ditto.
+ * gcc.target/microblaze/isa/vanilla.c: Ditto.
+ * gcc.target/microblaze/microblaze.exp: Ditto.
+
+2023-10-30 Mayshao <mayshao-oc@zhaoxin.com>
+
+ * g++.target/i386/mv32.C: Handle new -march.
+ * gcc.target/i386/funcspec-56.inc: Ditto.
+
+2023-10-30 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/111157
+ * gcc.dg/lto/pr111157_0.c: New test.
+ * gcc.dg/lto/pr111157_1.c: Second file of the same new test.
+
+2023-10-30 Patrick O'Neill <patrick@rivosinc.com>
+
+ * gcc.target/riscv/rv32i_zcmp.c: Accept any register in the
+ range of 1-9 for cm.push and cm.popret insns.
+
+2023-10-30 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR middle-end/101955
+ * gcc.target/arc/pr101955.c: New test case.
+
+2023-10-30 Roger Sayle <roger@nextmovesoftware.com>
+
+ * gcc.target/arc/lsl16-1.c: New test case.
+ * gcc.target/arc/lsr16-1.c: Likewise.
+ * gcc.target/arc/swap-1.c: Likewise.
+ * gcc.target/arc/swap-2.c: Likewise.
+
+2023-10-30 Richard Ball <richard.ball@arm.com>
+
+ * gcc.target/arm/arm-switchstatement.c: Alter the tests to
+ change adr instruction to ldr.
+
+2023-10-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gcc.target/i386/pr105554.c: Require ifunc.
+
+2023-10-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gcc.dg/Wtrampolines.c: Skip on darwin20 and later.
+
+2023-10-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR target/112287
+ * gcc.target/i386/pr111698.c: Pass -march=sandybridge.
+
+2023-10-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gcc.dg/pie-2.c: Skip test on darwin.
+
+2023-10-30 Richard Biener <rguenther@suse.de>
+
+ PR testsuite/111462
+ * gcc.dg/tree-ssa/ssa-sink-18.c: XFAIL also powerpc64le.
+
+2023-10-30 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/104555
+ * gfortran.dg/pr104555.f90: New test.
+
+2023-10-30 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr104610-2.c: New test.
+
+2023-10-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/110712
+ * gdc.dg/pr110712.d: New test.
+
+2023-10-29 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.target/i386/large-data.c: Skip for Darwin.
+
+2023-10-29 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.target/i386/apx-interrupt-1.c: Skip for Darwin.
+ * gcc.target/i386/apx-push2pop2-1.c: Likewise.
+ * gcc.target/i386/apx-push2pop2_force_drap-1.c: Likewise.
+
+2023-10-29 Martin Uecker <uecker@tugraz.at>
+
+ PR tree-optimization/109334
+ * gcc.dg/builtin-dynamic-object-size-0.c
+ (test_parmsz_simple3): Supported again.
+ (test_parmsz_external4): New test.
+ * gcc.dg/builtin-dynamic-object-size-20.c: New test.
+ * gcc.dg/pr104970.c: New test.
+
+2023-10-28 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/112270
+ * gdc.dg/pr112270.d: New test.
+
+2023-10-28 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.dg/Wunused_value.d: New test.
+
+2023-10-27 Patrick O'Neill <patrick@rivosinc.com>
+
+ * gcc.target/riscv/stack_save_restore_2.c: Accept any number
+ after __riscv_save_ and __riscv_restore_.
+
+2023-10-27 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/104649
+ * gfortran.dg/pr104649.f90: New test.
+
+2023-10-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/111929
+ * g++.dg/template/non-dependent28a.C: New test.
+
+2023-10-27 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/template/new14.C: New test.
+
+2023-10-27 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/warn/Wparentheses-13.C: Strengthen by expecting that
+ we issue the -Wparentheses warnings ahead of time.
+ * g++.dg/warn/Wparentheses-23.C: Likewise.
+ * g++.dg/warn/Wparentheses-32.C: Remove xfails.
+
+2023-10-27 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/111530
+ * gm2/pimlib/run/pass/testgetopt.mod: New test.
+
+2023-10-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.dg/tree-prof/peel-2.c: Add
+ -fno-tree-loop-distribute-patterns.
+ * gcc.dg/tree-ssa/ldist-rawmemchr-1.c: Add riscv.
+ * gcc.dg/tree-ssa/ldist-rawmemchr-2.c: Ditto.
+ * gcc.target/riscv/rvv/rvv.exp: Add builtin directory.
+ * gcc.target/riscv/rvv/autovec/builtin/rawmemchr-1.c: New test.
+
+2023-10-27 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c: Remove
+ Float16.
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c: Ditto.
+ * lib/target-supports.exp: Add zvfh handling.
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-2.c: New test.
+
+2023-10-27 Paul-Antoine Arras <pa@codesourcery.com>
+
+ * gfortran.dg/c_ptr_tests_20.f90: Moved to...
+ * gfortran.dg/gomp/c_ptr_tests_20.f90: ...here.
+ * gfortran.dg/c_ptr_tests_21.f90: Moved to...
+ * gfortran.dg/gomp/c_ptr_tests_21.f90: ...here.
+
+2023-10-27 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR target/110551
+ * gcc.target/i386/pr110551.c: New test case.
+
+2023-10-27 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/87299
+ * c-c++-common/pragma-target-1.c: New test.
+ * c-c++-common/pragma-target-2.c: New test.
+ * g++.target/i386/pr87299-1.C: New test.
+ * g++.target/i386/pr87299-2.C: New test.
+ * gcc.target/i386/pr87299-1.c: New test.
+ * gcc.target/i386/pr87299-2.c: New test.
+ * gcc.target/s390/target-attribute/tattr-2b.c: New test.
+ * gcc.target/aarch64/pragma_cpp_predefs_1b.c: New test.
+ * gcc.target/arm/pragma_arch_attribute_1b.c: New test.
+ * gcc.target/nios2/custom-fp-2b.c: New test.
+ * gcc.target/powerpc/float128-3b.c: New test.
+
+2023-10-27 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/104625
+ * gfortran.dg/pr104625.f90: New test.
+ * gfortran.dg/associate_55.f90: Change error check.
+
+2023-10-27 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/101590
+ PR tree-optimization/94884
+ * gcc.dg/tree-ssa/bitcmp-1.c: New test.
+ * gcc.dg/tree-ssa/bitcmp-2.c: New test.
+ * gcc.dg/tree-ssa/bitcmp-3.c: New test.
+ * gcc.dg/tree-ssa/bitcmp-4.c: New test.
+ * gcc.dg/tree-ssa/bitcmp-5.c: New test.
+ * gcc.dg/tree-ssa/bitcmp-6.c: New test.
+
+2023-10-27 liuhongt <hongtao.liu@intel.com>
+
+ * g++.target/i386/part-vect-vcondhf.C: New test.
+ * gcc.target/i386/part-vect-vec_cmphf.c: New test.
+
+2023-10-26 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/111318
+ PR target/111888
+ * gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c: Adapt test.
+ * gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/partial/select_vl-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/pr111318.c: New test.
+ * gcc.target/riscv/rvv/autovec/pr111888.c: New test.
+
+2023-10-26 David Malcolm <dmalcolm@redhat.com>
+
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-access-read_write.c:
+ New test.
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-access-without-size.c:
+ New test.
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-multiple.c:
+ New test.
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-2.c:
+ New test.
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-sized.c:
+ New test.
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull.c:
+ New test.
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-nullable-sized.c:
+ New test.
+ * c-c++-common/analyzer/attr-null_terminated_string_arg-nullable.c:
+ New test.
+ * c-c++-common/attr-null_terminated_string_arg.c: New test.
+
+2023-10-26 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.target/aarch64/aarch64.exp: Use aarch64-with-arch-dg-options
+ to normaize the options to the tests in aarch64.exp.
+
+2023-10-26 Iain Sandoe <iain@sandoe.co.uk>
+
+ * lib/target-libpath.exp: Skip DYLD_LIBRARY_PATH for all
+ current OS versions > 10.
+
+2023-10-26 Andrew Pinski <pinskia@gmail.com>
+
+ PR tree-optimization/111957
+ * gcc.dg/tree-ssa/phi-opt-40.c: New test.
+
+2023-10-26 Paul-Antoine Arras <pa@codesourcery.com>
+
+ * gfortran.dg/c_ptr_tests_20.f90: Add "fopenmp" effective target.
+ * gfortran.dg/c_ptr_tests_21.f90: Add "fopenmp" effective target.
+
+2023-10-26 Patrick O'Neill <patrick@rivosinc.com>
+
+ * g++.target/riscv/rvv/rvv.exp: Add -mabi argument to CFLAGS.
+
+2023-10-26 Richard Sandiford <richard.sandiford@arm.com>
+
+ * lib/target-supports-dg.exp (check-flags): Move default argument
+ handling further up. Fix a couple of issues in the lappends.
+ Avoid frobbing the compiler flags if the return value is already
+ known to be 1.
+ * lib/dg-pch.exp (dg-flags-pch): Process the dg-skip-if and
+ dg-require-effective-target directives to see whether the
+ assembly test should be skipped.
+ * gcc.dg/pch/valid-1.c: Remove dg-require-effective-target.
+ * gcc.dg/pch/valid-1b.c: Likewise.
+
+2023-10-26 Richard Ball <richard.ball@arm.com>
+
+ * gcc.target/arm/arm-switchstatement.c: New test.
+
+2023-10-26 Paul-Antoine Arras <pa@codesourcery.com>
+ Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/c_ptr_tests_20.f90: New test, checking that INTEGER(8)
+ and TYPE(C_PTR) are recognised as compatible.
+ * gfortran.dg/c_ptr_tests_21.f90: New test, exercising the error
+ detection for C_FUNPTR.
+
+2023-10-26 Roger Sayle <roger@nextmovesoftware.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR rtl-optimization/91865
+ * gcc.target/msp430/pr91865.c: New test case.
+
+2023-10-26 Jiahao Xu <xujiahao@loongson.cn>
+
+ * gcc.target/loongarch/vector/lasx/lasx-vcond-1.c: New test.
+ * gcc.target/loongarch/vector/lasx/lasx-vcond-2.c: New test.
+ * gcc.target/loongarch/vector/lsx/lsx-vcond-1.c: New test.
+ * gcc.target/loongarch/vector/lsx/lsx-vcond-2.c: New test.
+
+2023-10-26 Stefan Schulze Frielinghaus <stefansf@linux.ibm.com>
+
+ * gcc.misc-tests/godump-1.c: Move _BitInt tests into godump-2.c.
+ * gcc.misc-tests/godump-2.c: New test.
+
+2023-10-26 Alexandre Oliva <oliva@adacore.com>
+
+ PR tree-optimization/111520
+ * g++.dg/torture/harden-comp-pr111520.cc: New.
+
+2023-10-25 Wilco Dijkstra <wilco.dijkstra@arm.com>
+
+ * gcc.target/aarch64/imm_choice_comparison.c: Change tests.
+ * gcc.target/aarch64/moveor_imm.c: Add new test.
+ * gcc.target/aarch64/pr106583.c: Change tests.
+
+2023-10-25 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/111698
+ * gcc.target/i386/pr111698.c: New test.
+
+2023-10-25 chenxiaolong <chenxiaolong@loongson.cn>
+
+ * gcc.target/loongarch/builtin_thread_pointer.c: New test.
+
+2023-10-25 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/99804
+ * g++.dg/template/enum9.C: New test.
+
+2023-10-25 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/111955
+ * gm2/pimlib/run/pass/testnan.mod: New test.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/self-clause-2.c: Verify
+ '--param=openacc-kernels=decompose'.
+ * gfortran.dg/goacc/kernels-tree.f95: Adjust.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/if-clause-2.c: Enhance.
+ * c-c++-common/goacc/self-clause-1.c: Likewise.
+ * c-c++-common/goacc/self-clause-2.c: Likewise.
+ * gfortran.dg/goacc/if.f95: Likewise.
+ * gfortran.dg/goacc/kernels-tree.f95: Likewise.
+ * gfortran.dg/goacc/parallel-tree.f95: Likewise.
+ * gfortran.dg/goacc/self.f95: Likewise.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/if-clause-1.c: Enable for C++
+ * c-c++-common/goacc/self-clause-1.c: Likewise.
+
+2023-10-25 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * c-c++-common/goacc/self-clause-1.c: New test.
+ * c-c++-common/goacc/self-clause-2.c: New test.
+ * gfortran.dg/goacc/self.f95: New test.
+
+2023-10-25 Marek Polacek <polacek@redhat.com>
+
+ PR c++/111895
+ * g++.dg/cpp0x/scoped_enum12.C: New test.
+
+2023-10-24 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/111929
+ * g++.dg/template/non-dependent28.C: New test.
+
+2023-10-24 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/111919
+ * g++.dg/template/non-dependent27.C: New test.
+
+2023-10-24 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/arm/mve/mve_vadcq_vsbcq_fpscr_overwrite.c: Fix.
+
+2023-10-24 Andrew Pinski <pinskia@gmail.com>
+
+ PR tree-optimization/101541
+ * gcc.dg/tree-ssa/phi-opt-39.c: New test.
+
+2023-10-24 Andrew Pinski <pinskia@gmail.com>
+
+ PR tree-optimization/111913
+ * gcc.c-torture/compile/fold-popcount-1.c: New test.
+ * gcc.dg/fold-popcount-8a.c: New test.
+
+2023-10-24 xuli <xuli1@eswincomputing.com>
+
+ PR target/111935
+ * gcc.target/riscv/rvv/base/pr111935.c: New test.
+
+2023-10-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/111947
+ * gcc.target/riscv/rvv/vsetvl/pr111947.c: New test.
+
+2023-10-23 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/36887
+ * c-c++-common/cpp/diagnostic-poison.c: New test.
+ * g++.dg/pch/pr36887.C: New test.
+ * g++.dg/pch/pr36887.Hs: New test.
+
+2023-10-23 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/slp-mask-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/slp-mask-run-1.c: New test.
+
+2023-10-23 Robin Dapp <rdapp@ventanamicro.com>
+
+ * gcc.target/riscv/rvv/autovec/unop/popcount-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/unop/popcount-2.c: New test.
+ * gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c: New test.
+ * gcc.target/riscv/rvv/autovec/unop/popcount.c: New test.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/111916
+ * gcc.dg/torture/pr111916.c: New testcase.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/111915
+ * gcc.dg/vect/pr111915.c: New testcase.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR ipa/111914
+ * gcc.dg/pr111914.c: New testcase.
+
+2023-10-23 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/111860
+ * gcc.dg/vect/pr111860-2.c: New test.
+ * gcc.dg/vect/pr111860-3.c: New test.
+
+2023-10-23 Andrew Pinski <apinski@marvell.com>
+
+ * gcc.dg/tree-ssa/phi-opt-38.c: New test.
+
+2023-10-23 Andrew Pinski <pinskia@gmail.com>
+
+ PR c/111903
+ * gcc.target/i386/float16-8.c: New test.
+
+2023-10-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/111917
+ * gcc.dg/torture/pr111917.c: New testcase.
+
+2023-10-23 Juzhe-Zhong <juzhe.zhong@rivai.ai>
+
+ PR target/111927
+ * gcc.target/riscv/rvv/vsetvl/pr111927.c: New test.
+
+2023-10-23 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/autovec/unop/cvt-0.c: Remove the vsetvl
+ asm check from func body.
+ * gcc.target/riscv/rvv/autovec/unop/cvt-1.c: Ditto.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/explicit-relocs-auto-single-load-store.c:
+ New test.
+ * gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c:
+ New test.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c: New
+ test.
+ * gcc.target/loongarch/explicit-relocs-auto-tls-le-ie.c: New
+ test.
+
+2023-10-23 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/explicit-relocs-auto-lto.c: New test.
+
+2023-10-23 Florian Weimer <fweimer@redhat.com>
+
+ * gcc.c-torture/execute/builtins/pr93262-chk.c (main_test):
+ Remove unnecessary return statement.
+
+2023-10-23 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/base/binop_vv_constraint-1.c: Remove the
+ vsetvl asm check from func body.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-1.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-10.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-11.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-12.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-129.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-13.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-130.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-131.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-133.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-134.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-135.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-14.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-15.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-153.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-154.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-155.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-158.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-16.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-17.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-171.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-172.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-173.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-174.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-18.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-19.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-2.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-20.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-21.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-22.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-23.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-24.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-25.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-26.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-27.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-28.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-29.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-3.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-30.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-31.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-32.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-33.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-34.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-35.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-36.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-37.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-38.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-39.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-4.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-40.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-41.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-42.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-43.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-44.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-5.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-6.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-7.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-8.c: Ditto.
+ * gcc.target/riscv/rvv/base/binop_vx_constraint-9.c: Ditto.
+ * gcc.target/riscv/rvv/base/shift_vx_constraint-1.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vv_constraint-1.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vv_constraint-2.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vv_constraint-3.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vv_constraint-4.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vv_constraint-5.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vv_constraint-6.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vx_constraint-1.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vx_constraint-8.c: Ditto.
+ * gcc.target/riscv/rvv/base/ternop_vx_constraint-9.c: Ditto.
+ * gcc.target/riscv/rvv/base/unop_v_constraint-1.c: Ditto.
+ * gcc.target/riscv/rvv/base/unop_v_constraint-2.c: Ditto.
+
+2023-10-23 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/autovec/unop/bswap16-0.c: Remove the
+ vsetvl check.
+ * gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-floor-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-floor-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-floor-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-floor-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-irint-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-iround-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lceil-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lceil-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lfloor-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lfloor-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-llrint-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-llround-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lrint-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lrint-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lround-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-lround-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-nearbyint-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-nearbyint-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-nearbyint-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-nearbyint-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-rint-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-rint-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-rint-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-rint-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-round-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-round-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-round-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-round-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-roundeven-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-roundeven-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-roundeven-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-roundeven-3.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-trunc-0.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-trunc-1.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-trunc-2.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/unop/math-trunc-3.c: Ditto.
+
+2023-10-23 Haochen Jiang <haochen.jiang@intel.com>
+
+ PR target/111753
+ * gcc.target/i386/pr111753.c: New test.
+
+2023-10-23 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr111820-1.c: New test.
+ * gcc.target/i386/pr111820-2.c: New test.
+ * gcc.target/i386/pr111820-3.c: New test.
+ * gcc.target/i386/pr103144-mul-1.c: Adjust testcase.
+ * gcc.target/i386/pr103144-mul-2.c: Adjust testcase.
+
+2023-10-22 Andrew Pinski <pinskia@gmail.com>
+
+ PR target/110986
+ * gcc.target/aarch64/cond_op-1.c: New test.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gfortran.dg/coarray/caf.exp: Correctly set
+ libatomic flags.
+ * gfortran.dg/dg.exp: Likewise.
+ * lib/asan-dg.exp: Set correct -B flags.
+ * lib/atomic-dg.exp: Likewise.
+ * lib/target-libpath.exp: Handle ENABLE_DARWIN_AT_RPATH.
+
+2023-10-22 Tsukasa OI <research_trasio@irq.a4lg.com>
+
+ * gcc.target/riscv/arch-26.c: New test.
+
2023-10-21 Florian Weimer <fweimer@redhat.com>
* gcc.c-torture/compile/20000403-1.c: Compile with -std=gnu89.
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-read_write.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-read_write.c
new file mode 100644
index 0000000..dc5da22
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-read_write.c
@@ -0,0 +1,15 @@
+/* { dg-additional-options "-Wno-stringop-overflow" } */
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+char *example_fn (char *p, __SIZE_TYPE__ n)
+ __attribute__((null_terminated_string_arg (1)))
+ __attribute__((access (read_write, 1, 2)));
+
+char *
+test_unterminated_str (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str, 4); /* { dg-warning "stack-based buffer over-read" } */
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-without-size.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-without-size.c
new file mode 100644
index 0000000..83ec24a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-access-without-size.c
@@ -0,0 +1,54 @@
+/* { dg-additional-options "-Wno-stringop-overread" } */
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+char *example_fn (const char *p, __SIZE_TYPE__ n) /* { dg-message "argument 1 of '\[^\n\r\]*' must be a pointer to a null-terminated string" } */
+ __attribute__((null_terminated_string_arg (1)))
+ __attribute__((access (read_only, 1))); // but doesn't identify an argument for a size limit
+
+char *
+test_passthrough (const char* str, __SIZE_TYPE__ n)
+{
+ return example_fn (str, n);
+}
+
+char *
+test_NULL_str_a (void)
+{
+ return example_fn (NULL, 0); /* { dg-bogus "use of NULL where non-null expected" } */
+}
+
+char *
+test_NULL_str_b (void)
+{
+ return example_fn (NULL, 4); /* { dg-bogus "use of NULL where non-null expected" } */
+}
+
+char *
+test_unterminated_str (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str, 4); /* { dg-warning "stack-based buffer over-read" } */
+}
+
+char *
+test_uninitialized_str_a (void)
+{
+ char str[16];
+ return example_fn (str, 1); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_b (void)
+{
+ char str[16];
+ return example_fn (str, 16); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_c (void)
+{
+ char str[16];
+ return example_fn (str, 17); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-multiple.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-multiple.c
new file mode 100644
index 0000000..a5418b4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-multiple.c
@@ -0,0 +1,52 @@
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+/* Example with multiple params with attribute null_terminated_string_arg. */
+
+char *example_fn (const char *p, const char *q)
+ __attribute__((null_terminated_string_arg (1)))
+ __attribute__((null_terminated_string_arg (2)));
+// but can be NULL
+
+char *
+test_passthrough (const char *a, const char *b)
+{
+ return example_fn (a, b);
+}
+
+char *
+test_NULL_str (void)
+{
+ return example_fn (NULL, NULL); /* { dg-bogus "use of NULL where non-null expected" } */
+}
+
+char *
+test_unterminated_str_1 (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str, NULL); /* { dg-warning "stack-based buffer over-read" } */
+ /* { dg-message "while looking for null terminator for argument 1" "note" { target *-*-* } .-1 } */
+}
+
+char *
+test_unterminated_str_2 (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (NULL, str); /* { dg-warning "stack-based buffer over-read" } */
+ /* { dg-message "while looking for null terminator for argument 2" "note" { target *-*-* } .-1 } */
+}
+
+char *
+test_uninitialized_str_1 (void)
+{
+ char str[16];
+ return example_fn (str, NULL); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_2 (void)
+{
+ char str[16];
+ return example_fn (NULL, str); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-2.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-2.c
new file mode 100644
index 0000000..2614633
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-2.c
@@ -0,0 +1,33 @@
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+extern char *example_fn (const char *p) /* { dg-message "argument 1 of '\[^\n\r\]*' must be a pointer to a null-terminated string" } */
+ __attribute__((null_terminated_string_arg (1), nonnull (1)));
+
+char *
+test_passthrough (const char* str)
+{
+ return example_fn (str);
+}
+
+char *
+test_NULL_str (void)
+{
+ return example_fn (NULL); /* { dg-warning "use of NULL where non-null expected" } */
+}
+
+char *
+test_unterminated_str (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str); /* { dg-warning "stack-based buffer over-read" } */
+ /* { dg-message "while looking for null terminator for argument 1" "note" { target *-*-* } .-1 } */
+}
+
+char *
+test_uninitialized_str (void)
+{
+ char str[16];
+ return example_fn (str); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-sized.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-sized.c
new file mode 100644
index 0000000..c539f29
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull-sized.c
@@ -0,0 +1,69 @@
+/* { dg-additional-options "-Wno-stringop-overread" } */
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+char *example_fn (const char *p, __SIZE_TYPE__ n) /* { dg-message "argument 1 of '\[^\n\r\]*' must be a pointer to a null-terminated string" } */
+ __attribute__((null_terminated_string_arg (1)))
+ __attribute__((access (read_only, 1, 2)))
+ __attribute__((nonnull));
+
+char *
+test_passthrough (const char* str, __SIZE_TYPE__ n)
+{
+ return example_fn (str, n);
+}
+
+char *
+test_NULL_str_a (void)
+{
+ return example_fn (NULL, 0); /* { dg-warning "use of NULL where non-null expected" } */
+}
+
+char *
+test_NULL_str_b (void)
+{
+ return example_fn (NULL, 4); /* { dg-warning "use of NULL where non-null expected" } */
+}
+
+char *
+test_unterminated_str (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str, 4); /* { dg-warning "stack-based buffer over-read" } */
+}
+
+char *
+test_unterminated_str_truncated (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str, 3); /* { dg-bogus "stack-based buffer over-read" } */
+}
+
+char *
+test_uninitialized_str_a (void)
+{
+ char str[16];
+ return example_fn (str, 1); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_b (void)
+{
+ char str[16];
+ return example_fn (str, 16); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_c (void)
+{
+ char str[16];
+ return example_fn (str, 17); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_truncated (void)
+{
+ char str[16];
+ return example_fn (str, 0); /* { dg-bogus "use of uninitialized value" } */
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull.c
new file mode 100644
index 0000000..6f805d5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nonnull.c
@@ -0,0 +1,34 @@
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+char *example_fn (const char *p) /* { dg-message "argument 1 of '\[^\n\r\]*' must be a pointer to a null-terminated string" } */
+ __attribute__((null_terminated_string_arg (1)))
+ __attribute__((nonnull));
+
+char *
+test_passthrough (const char* str)
+{
+ return example_fn (str);
+}
+
+char *
+test_NULL_str (void)
+{
+ return example_fn (NULL); /* { dg-warning "use of NULL where non-null expected" } */
+}
+
+char *
+test_unterminated_str (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str); /* { dg-warning "stack-based buffer over-read" } */
+ /* { dg-message "while looking for null terminator for argument 1" "note" { target *-*-* } .-1 } */
+}
+
+char *
+test_uninitialized_str (void)
+{
+ char str[16];
+ return example_fn (str); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable-sized.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable-sized.c
new file mode 100644
index 0000000..28df4b5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable-sized.c
@@ -0,0 +1,69 @@
+/* { dg-additional-options "-Wno-stringop-overread" } */
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+char *example_fn (const char *p, __SIZE_TYPE__ n) /* { dg-message "argument 1 of '\[^\n\r\]*' must be a pointer to a null-terminated string" } */
+ __attribute__((null_terminated_string_arg (1)))
+ __attribute__((access (read_only, 1, 2)));
+// can be NULL
+
+char *
+test_passthrough (const char* str, __SIZE_TYPE__ n)
+{
+ return example_fn (str, n);
+}
+
+char *
+test_NULL_str_a (void)
+{
+ return example_fn (NULL, 0); /* { dg-bogus "use of NULL where non-null expected" } */
+}
+
+char *
+test_NULL_str_b (void)
+{
+ return example_fn (NULL, 4); /* { dg-bogus "use of NULL where non-null expected" } */
+}
+
+char *
+test_unterminated_str (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str, 4); /* { dg-warning "stack-based buffer over-read" } */
+}
+
+char *
+test_unterminated_str_truncated (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str, 3); /* { dg-bogus "stack-based buffer over-read" } */
+}
+
+char *
+test_uninitialized_str_a (void)
+{
+ char str[16];
+ return example_fn (str, 1); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_b (void)
+{
+ char str[16];
+ return example_fn (str, 16); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_c (void)
+{
+ char str[16];
+ return example_fn (str, 17); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
+
+char *
+test_uninitialized_str_truncated (void)
+{
+ char str[16];
+ return example_fn (str, 0); /* { dg-bogus "use of uninitialized value" } */
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable.c b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable.c
new file mode 100644
index 0000000..8bbe0b6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-null_terminated_string_arg-nullable.c
@@ -0,0 +1,34 @@
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+/* { dg-additional-options "-fpermissive" { target c++ } } */
+
+char *example_fn (const char *p) /* { dg-message "argument 1 of '\[^\n\r\]*' must be a pointer to a null-terminated string" } */
+ __attribute__((null_terminated_string_arg (1)));
+// but can be NULL
+
+char *
+test_passthrough (const char* str)
+{
+ return example_fn (str);
+}
+
+char *
+test_NULL_str (void)
+{
+ return example_fn (NULL); /* { dg-bogus "use of NULL where non-null expected" } */
+}
+
+char *
+test_unterminated_str (void)
+{
+ char str[3] = "abc"; /* { dg-warning "initializer-string for '\[^\n\]*' is too long" "" { target c++ } } */
+ return example_fn (str); /* { dg-warning "stack-based buffer over-read" } */
+ /* { dg-message "while looking for null terminator for argument 1" "note" { target *-*-* } .-1 } */
+}
+
+char *
+test_uninitialized_str (void)
+{
+ char str[16];
+ return example_fn (str); /* { dg-warning "use of uninitialized value 'str\\\[0\\\]'" } */
+}
diff --git a/gcc/testsuite/c-c++-common/attr-null_terminated_string_arg.c b/gcc/testsuite/c-c++-common/attr-null_terminated_string_arg.c
new file mode 100644
index 0000000..f2f1d48
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-null_terminated_string_arg.c
@@ -0,0 +1,16 @@
+extern int not_a_function __attribute__((null_terminated_string_arg(1))); /* { dg-warning "'null_terminated_string_arg' attribute only applies to function types" } */
+
+extern void no_arg (void) __attribute__((null_terminated_string_arg)); /* { dg-error "wrong number of arguments specified for 'null_terminated_string_arg' attribute" } */
+
+extern void arg_idx_not_an_int (int) __attribute__((null_terminated_string_arg ("foo"))); /* { dg-warning "'null_terminated_string_arg' attribute argument has type" } */
+
+extern void arg_not_a_pointer (int) __attribute__((null_terminated_string_arg (1))); /* { dg-warning "'null_terminated_string_arg' attribute argument value '1' refers to parameter type 'int'" } */
+
+extern void arg_not_a_char_pointer (int) __attribute__((null_terminated_string_arg (1))); /* { dg-warning "'null_terminated_string_arg' attribute argument value '1' refers to parameter type 'int'" } */
+
+extern void arg_idx_too_low (const char *) __attribute__((null_terminated_string_arg (0))); /* { dg-warning "'null_terminated_string_arg' attribute argument value '0' does not refer to a function parameter" } */
+
+extern void arg_idx_too_high (const char *) __attribute__((null_terminated_string_arg (2))); /* { dg-warning "'null_terminated_string_arg' attribute argument value '2' exceeds the number of function parameters 1" } */
+
+extern void valid_non_const (char *) __attribute__((null_terminated_string_arg (1)));
+extern void valid_const (const char *) __attribute__((null_terminated_string_arg (1)));
diff --git a/gcc/testsuite/c-c++-common/cpp/diagnostic-poison.c b/gcc/testsuite/c-c++-common/cpp/diagnostic-poison.c
new file mode 100644
index 0000000..294f77e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/diagnostic-poison.c
@@ -0,0 +1,13 @@
+/* PR preprocessor/36887 */
+/* { dg-do preprocess } */
+
+#ifdef LEVEL2
+/* Test that we get the include traced location as well. */
+#pragma GCC poison p1 /* { dg-note "poisoned here" } */
+#else
+#define LEVEL2
+#include "diagnostic-poison.c"
+int p1; /* { dg-error "attempt to use poisoned" } */
+_Pragma("GCC poison p2") /* { dg-note "poisoned here" } */
+int p2; /* { dg-error "attempt to use poisoned" } */
+#endif
diff --git a/gcc/testsuite/c-c++-common/goacc/if-clause-1.c b/gcc/testsuite/c-c++-common/goacc/if-clause-1.c
index 85abf165..d78520b 100644
--- a/gcc/testsuite/c-c++-common/goacc/if-clause-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/if-clause-1.c
@@ -1,4 +1,4 @@
-/* { dg-skip-if "not yet" { c++ } } */
+/* See also 'self-clause-1.c'. */
void
f (void)
@@ -6,5 +6,7 @@ f (void)
struct { int i; } *p;
#pragma acc data copyout(p) if(1) if(1) /* { dg-error "too many 'if' clauses" } */
;
-#pragma acc update device(p) if(*p) /* { dg-error "used struct type value where scalar is required" } */
+#pragma acc update device(p) if(*p)
+ /* { dg-error {used struct type value where scalar is required} {} { target c } .-1 }
+ { dg-error {could not convert '\* p' from 'f\(\)::<unnamed struct>' to 'bool'} {} { target c++ } .-2 } */
}
diff --git a/gcc/testsuite/c-c++-common/goacc/if-clause-2.c b/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
index a480725..7147552 100644
--- a/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
@@ -1,3 +1,5 @@
+/* See also 'self-clause-2.c'. */
+
/* { dg-additional-options "-fdump-tree-gimple" } */
/* { dg-additional-options "--param=openacc-kernels=decompose" }
{ dg-additional-options "-fdump-tree-omp_oacc_kernels_decompose" } */
diff --git a/gcc/testsuite/c-c++-common/goacc/self-clause-1.c b/gcc/testsuite/c-c++-common/goacc/self-clause-1.c
new file mode 100644
index 0000000..28de3dc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/self-clause-1.c
@@ -0,0 +1,34 @@
+/* See also 'if-clause-1.c'. */
+
+void
+f (int b)
+{
+ struct { int i; } *p;
+
+#pragma acc parallel self(0) self(b) /* { dg-error "too many 'self' clauses" } */
+ ;
+#pragma acc parallel self self(b) /* { dg-error "too many 'self' clauses" } */
+ ;
+#pragma acc parallel self(*p)
+ /* { dg-error {used struct type value where scalar is required} {} { target c } .-1 }
+ { dg-error {could not convert '\* p' from 'f\(int\)::<unnamed struct>' to 'bool'} {} { target c++ } .-2 } */
+ ;
+
+#pragma acc kernels self(0) self(b) /* { dg-error "too many 'self' clauses" } */
+ ;
+#pragma acc kernels self self(b) /* { dg-error "too many 'self' clauses" } */
+ ;
+#pragma acc kernels self(*p)
+ /* { dg-error {used struct type value where scalar is required} {} { target c } .-1 }
+ { dg-error {could not convert '\* p' from 'f\(int\)::<unnamed struct>' to 'bool'} {} { target c++ } .-2 } */
+ ;
+
+#pragma acc serial self(0) self(b) /* { dg-error "too many 'self' clauses" } */
+ ;
+#pragma acc serial self self(b) /* { dg-error "too many 'self' clauses" } */
+ ;
+#pragma acc serial self(*p)
+ /* { dg-error {used struct type value where scalar is required} {} { target c } .-1 }
+ { dg-error {could not convert '\* p' from 'f\(int\)::<unnamed struct>' to 'bool'} {} { target c++ } .-2 } */
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/self-clause-2.c b/gcc/testsuite/c-c++-common/goacc/self-clause-2.c
new file mode 100644
index 0000000..3ac29a0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/self-clause-2.c
@@ -0,0 +1,43 @@
+/* See also 'if-clause-2.c'. */
+
+/* { dg-additional-options "-fdump-tree-gimple" } */
+/* { dg-additional-options "--param=openacc-kernels=decompose" }
+ { dg-additional-options "-fdump-tree-omp_oacc_kernels_decompose" } */
+
+void
+f (short c)
+{
+#pragma acc parallel self(c) copy(c)
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel map\(tofrom:c \[len: [0-9]+\]\) self\(_[0-9]+\)$} 1 "gimple" } } */
+ ++c;
+
+#pragma acc kernels self(c) copy(c)
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_kernels map\(tofrom:c \[len: [0-9]+\]\) self\(_[0-9]+\)$} 1 "gimple" } } */
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels map\(tofrom:c \[len: [0-9]+\]\) self\(_[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single async\(-1\) num_gangs\(1\) map\(force_present:c \[len: [0-9]+\]\) self\(_[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } } */
+ ++c;
+
+#pragma acc serial self(c) copy(c)
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_serial map\(tofrom:c \[len: [0-9]+\]\) self\(_[0-9]+\)$} 1 "gimple" } } */
+ ++c;
+}
+
+/* The same, but with implicit 'true' condition-argument. */
+
+void
+g (short d)
+{
+#pragma acc parallel self copy(d)
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel map\(tofrom:d \[len: [0-9]+\]\) self\(1\)$} 1 "gimple" } } */
+ ++d;
+
+#pragma acc kernels self copy(d)
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_kernels map\(tofrom:d \[len: [0-9]+\]\) self\(1\)$} 1 "gimple" } } */
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels map\(tofrom:d \[len: [0-9]+\]\) self\(1\)$} 1 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single async\(-1\) num_gangs\(1\) map\(force_present:d \[len: [0-9]+\]\) self\(1+\)$} 1 "omp_oacc_kernels_decompose" } } */
+ ++d;
+
+#pragma acc serial self copy(d)
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_serial map\(tofrom:d \[len: [0-9]+\]\) self\(1\)$} 1 "gimple" } } */
+ ++d;
+}
diff --git a/gcc/testsuite/c-c++-common/pragma-target-1.c b/gcc/testsuite/c-c++-common/pragma-target-1.c
new file mode 100644
index 0000000..2584c22
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pragma-target-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-mno-avx -O3" } */
+
+void f (double *x)
+{
+ for (int i = 0; i != 8; ++i)
+ x[i] *= 2;
+}
+
+#pragma GCC target("avx")
+
+void g (double *x)
+{
+ for (int i = 0; i != 8; ++i)
+ x[i] *= 2;
+}
+
+/* Make sure the target pragma affected only g() and not also f(). */
+/* { dg-final { scan-assembler-times vzeroupper 1 } } */
diff --git a/gcc/testsuite/c-c++-common/pragma-target-2.c b/gcc/testsuite/c-c++-common/pragma-target-2.c
new file mode 100644
index 0000000..e7bf305
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pragma-target-2.c
@@ -0,0 +1,27 @@
+/* { dg-do preprocess { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-mno-avx" } */
+
+#ifdef __AVX__
+#error "__AVX__ should not be defined #1"
+#endif
+
+#pragma GCC target("avx")
+#ifndef __AVX__
+#error "__AVX__ should be defined #1"
+#endif
+
+#pragma GCC reset_options
+#ifdef __AVX__
+#error "__AVX__ should not be defined #2"
+#endif
+
+#pragma GCC push_options
+#pragma GCC target("avx")
+#ifndef __AVX__
+#error "__AVX__ should be defined #2"
+#endif
+
+#pragma GCC pop_options
+#ifdef __AVX__
+#error "__AVX__ should not be defined #3"
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp0x/scoped_enum12.C b/gcc/testsuite/g++.dg/cpp0x/scoped_enum12.C
new file mode 100644
index 0000000..1d10431
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/scoped_enum12.C
@@ -0,0 +1,8 @@
+// PR c++/111895
+// { dg-do compile { target c++11 } }
+
+enum class o_field : unsigned char { no, yes, different_from_s };
+struct fields {
+ o_field o : 2;
+};
+bool func(fields f) { return static_cast<bool>(f.o); }
diff --git a/gcc/testsuite/g++.dg/pch/pr36887.C b/gcc/testsuite/g++.dg/pch/pr36887.C
new file mode 100644
index 0000000..620ccc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr36887.C
@@ -0,0 +1,3 @@
+#include "pr36887.H"
+int p1; /* { dg-error "attempt to use poisoned" } */
+/* { dg-note "poisoned here" "" { target *-*-* } 1 } */
diff --git a/gcc/testsuite/g++.dg/pch/pr36887.Hs b/gcc/testsuite/g++.dg/pch/pr36887.Hs
new file mode 100644
index 0000000..e5f4caf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr36887.Hs
@@ -0,0 +1 @@
+#pragma GCC poison p1
diff --git a/gcc/testsuite/g++.dg/template/enum9.C b/gcc/testsuite/g++.dg/template/enum9.C
new file mode 100644
index 0000000..c992cd5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/enum9.C
@@ -0,0 +1,12 @@
+// PR c++/99804
+
+struct S {
+ enum E { A, B } e : 1;
+ void f(E);
+ template<class> void g() { f(e); }
+};
+
+int main() {
+ S s;
+ s.g<int>();
+}
diff --git a/gcc/testsuite/g++.dg/template/new14.C b/gcc/testsuite/g++.dg/template/new14.C
new file mode 100644
index 0000000..8c0efe4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/new14.C
@@ -0,0 +1,20 @@
+// Verify we check new-expressions ahead of time.
+
+struct A { };
+struct B { B(int); };
+struct C { void* operator new(__SIZE_TYPE__, int); };
+
+template<class T>
+void f() {
+ new A(1); // { dg-error "no match" "" { xfail *-*-* } }
+ new B(1, 2); // { dg-error "no match" }
+ new B; // { dg-error "no match" }
+ new C; // { dg-error "no match" }
+}
+
+
+template<class T>
+void g() {
+ new int[__SIZE_MAX__]; // { dg-error "exceeds maximum" }
+ new int[__SIZE_MAX__ / sizeof(int)]; // { dg-error "exceeds maximum" }
+}
diff --git a/gcc/testsuite/g++.dg/template/non-dependent27.C b/gcc/testsuite/g++.dg/template/non-dependent27.C
new file mode 100644
index 0000000..c06bca7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent27.C
@@ -0,0 +1,8 @@
+// PR c++/111919
+
+int i[42];
+
+template<class T>
+void f() {
+ i[42 / (int)sizeof(T)] |= 42;
+}
diff --git a/gcc/testsuite/g++.dg/template/non-dependent28.C b/gcc/testsuite/g++.dg/template/non-dependent28.C
new file mode 100644
index 0000000..f7f31d9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent28.C
@@ -0,0 +1,6 @@
+// PR c++/111929
+
+template<class>
+void f(char x) {
+ new int[x + 42];
+}
diff --git a/gcc/testsuite/g++.dg/template/non-dependent28a.C b/gcc/testsuite/g++.dg/template/non-dependent28a.C
new file mode 100644
index 0000000..d32520c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent28a.C
@@ -0,0 +1,8 @@
+// PR c++/111929
+
+struct A { operator int(); };
+
+template<class>
+void f() {
+ new int[A()];
+}
diff --git a/gcc/testsuite/g++.dg/torture/harden-comp-pr111520.cc b/gcc/testsuite/g++.dg/torture/harden-comp-pr111520.cc
new file mode 100644
index 0000000..b4381b4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/harden-comp-pr111520.cc
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fharden-compares -fsignaling-nans -fnon-call-exceptions" } */
+
+struct S
+{
+ S (bool);
+ ~S ();
+};
+
+float f;
+
+void
+foo ()
+{
+ S a = 0;
+ S b = f;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-13.C b/gcc/testsuite/g++.dg/warn/Wparentheses-13.C
index 22a139f..d643894 100644
--- a/gcc/testsuite/g++.dg/warn/Wparentheses-13.C
+++ b/gcc/testsuite/g++.dg/warn/Wparentheses-13.C
@@ -65,5 +65,3 @@ bar (T)
d = (a = a);
foo (27);
}
-
-template void bar<int> (int); // { dg-message "required" }
diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-23.C b/gcc/testsuite/g++.dg/warn/Wparentheses-23.C
index f1749c2..bd7195e 100644
--- a/gcc/testsuite/g++.dg/warn/Wparentheses-23.C
+++ b/gcc/testsuite/g++.dg/warn/Wparentheses-23.C
@@ -114,8 +114,5 @@ bar4 (T)
return (a = a);
}
-template void bar<int> (int); // { dg-message "required" }
-template bool bar1<int> (int); // { dg-message "required" }
template bool bar2<int> (int);
-template bool bar3<int> (int); // { dg-message "required" }
template bool bar4<int> (int);
diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-32.C b/gcc/testsuite/g++.dg/warn/Wparentheses-32.C
index 719a9d9..b03515a 100644
--- a/gcc/testsuite/g++.dg/warn/Wparentheses-32.C
+++ b/gcc/testsuite/g++.dg/warn/Wparentheses-32.C
@@ -21,8 +21,8 @@ void f() {
if (z1 = z2) { } // { dg-warning "parentheses" }
bool b;
- b = m = n; // { dg-warning "parentheses" "" { xfail *-*-* } }
- b = x1 = x2; // { dg-warning "parentheses" "" { xfail *-*-* } }
- b = y1 = y2; // { dg-warning "parentheses" "" { xfail *-*-* } }
- b = z1 = z2; // { dg-warning "parentheses" "" { xfail *-*-* } }
+ b = m = n; // { dg-warning "parentheses" }
+ b = x1 = x2; // { dg-warning "parentheses" }
+ b = y1 = y2; // { dg-warning "parentheses" }
+ b = z1 = z2; // { dg-warning "parentheses" }
}
diff --git a/gcc/testsuite/g++.target/i386/mv32.C b/gcc/testsuite/g++.target/i386/mv32.C
index 8f74352..6c99321 100644
--- a/gcc/testsuite/g++.target/i386/mv32.C
+++ b/gcc/testsuite/g++.target/i386/mv32.C
@@ -17,6 +17,9 @@ int __attribute__ ((target("arch=lujiazui"))) foo () {
return 1;
}
+int __attribute__ ((target("arch=yongfeng"))) foo () {
+ return 2;
+}
int main ()
{
@@ -24,6 +27,8 @@ int main ()
if (__builtin_cpu_is ("lujiazui"))
assert (val == 1);
+ else if (__builtin_cpu_is ("yongfeng"))
+ assert (val == 2);
else
assert (val == 0);
diff --git a/gcc/testsuite/g++.target/i386/part-vect-vcondhf.C b/gcc/testsuite/g++.target/i386/part-vect-vcondhf.C
new file mode 100644
index 0000000..e623e6c
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/part-vect-vcondhf.C
@@ -0,0 +1,44 @@
+/* PR target/103861 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512fp16 -mavx512vl" } */
+/* { dg-final { scan-assembler-times "vpcmpeqw" 6 } } */
+/* { dg-final { scan-assembler-times "vpcmpgtw" 2 } } */
+/* { dg-final { scan-assembler-times "vcmpph" 8 } } */
+/* { dg-final { scan-assembler-times "vpblendvb" 8 } } */
+typedef unsigned short __attribute__((__vector_size__ (4))) __v2hu;
+typedef short __attribute__((__vector_size__ (4))) __v2hi;
+
+typedef unsigned short __attribute__((__vector_size__ (8))) __v4hu;
+typedef short __attribute__((__vector_size__ (8))) __v4hi;
+
+typedef _Float16 __attribute__((__vector_size__ (4))) __v2hf;
+typedef _Float16 __attribute__((__vector_size__ (8))) __v4hf;
+
+
+__v2hu au, bu;
+__v2hi as, bs;
+__v2hf af, bf;
+
+__v4hu cu, du;
+__v4hi cs, ds;
+__v4hf cf, df;
+
+__v2hf auf (__v2hu a, __v2hu b) { return (a > b) ? af : bf; }
+__v2hf asf (__v2hi a, __v2hi b) { return (a > b) ? af : bf; }
+__v2hu afu (__v2hf a, __v2hf b) { return (a > b) ? au : bu; }
+__v2hi afs (__v2hf a, __v2hf b) { return (a > b) ? as : bs; }
+
+__v4hf cuf (__v4hu c, __v4hu d) { return (c > d) ? cf : df; }
+__v4hf csf (__v4hi c, __v4hi d) { return (c > d) ? cf : df; }
+__v4hu cfu (__v4hf c, __v4hf d) { return (c > d) ? cu : du; }
+__v4hi cfs (__v4hf c, __v4hf d) { return (c > d) ? cs : ds; }
+
+__v2hf auf_ne (__v2hu a, __v2hu b) { return (a != b) ? af : bf; }
+__v2hf asf_ne (__v2hi a, __v2hi b) { return (a != b) ? af : bf; }
+__v2hu afu_ne (__v2hf a, __v2hf b) { return (a != b) ? au : bu; }
+__v2hi afs_ne (__v2hf a, __v2hf b) { return (a != b) ? as : bs; }
+
+__v4hf cuf_ne (__v4hu c, __v4hu d) { return (c != d) ? cf : df; }
+__v4hf csf_ne (__v4hi c, __v4hi d) { return (c != d) ? cf : df; }
+__v4hu cfu_ne (__v4hf c, __v4hf d) { return (c != d) ? cu : du; }
+__v4hi cfs_ne (__v4hf c, __v4hf d) { return (c != d) ? cs : ds; }
diff --git a/gcc/testsuite/g++.target/i386/pr87299-1.C b/gcc/testsuite/g++.target/i386/pr87299-1.C
new file mode 100644
index 0000000..38d4c3b
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr87299-1.C
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
diff --git a/gcc/testsuite/g++.target/i386/pr87299-2.C b/gcc/testsuite/g++.target/i386/pr87299-2.C
new file mode 100644
index 0000000..263dfb7
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr87299-2.C
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-save-temps -mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
diff --git a/gcc/testsuite/g++.target/riscv/rvv/rvv.exp b/gcc/testsuite/g++.target/riscv/rvv/rvv.exp
index c30d6e9..5b01e4e 100644
--- a/gcc/testsuite/g++.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/g++.target/riscv/rvv/rvv.exp
@@ -28,15 +28,17 @@ if ![istarget riscv*-*-*] then {
load_lib g++-dg.exp
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 "-march=$gcc_march -O3"
+set CFLAGS "-march=$gcc_march -mabi=$gcc_mabi -O3"
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/base/*.C]] \
"" $CFLAGS
diff --git a/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c b/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c
new file mode 100644
index 0000000..d3d3a29
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/111913 */
+
+int f(unsigned int x, unsigned int y)
+{
+ return __builtin_popcount (x&y) + __builtin_popcount (y|x--);
+}
+
+int f2(unsigned int x, unsigned int y)
+{
+ int t = __builtin_popcount (x&y);
+ int t1 = __builtin_popcount (x|y);
+ return t + t1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/pr93262-chk.c b/gcc/testsuite/gcc.c-torture/execute/builtins/pr93262-chk.c
index 66d86b4..e558686 100644
--- a/gcc/testsuite/gcc.c-torture/execute/builtins/pr93262-chk.c
+++ b/gcc/testsuite/gcc.c-torture/execute/builtins/pr93262-chk.c
@@ -51,5 +51,4 @@ main_test (void)
}
if (chk_calls != 2)
abort ();
- return 0;
}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-1.c b/gcc/testsuite/gcc.dg/Walloc-size-1.c
new file mode 100644
index 0000000..cae5e07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-1.c
@@ -0,0 +1,34 @@
+/* Tests the warnings for insufficient allocation size.
+ { dg-do compile }
+ { dg-options "-Walloc-size" }
+ * */
+
+struct b { int x[10]; };
+
+void fo0(void)
+{
+ struct b *p = __builtin_malloc(sizeof *p);
+}
+
+void fo1(void)
+{
+ struct b *p = __builtin_malloc(sizeof p); /* { dg-warning "allocation of insufficient size" } */
+}
+
+void fo2(void)
+{
+ struct b *p = __builtin_alloca(sizeof p); /* { dg-warning "allocation of insufficient size" } */
+}
+
+void fo3(void)
+{
+ struct b *p = __builtin_calloc(1, sizeof p); /* { dg-warning "allocation of insufficient size" } */
+}
+
+void g(struct b* p);
+
+void fo4(void)
+{
+ g(__builtin_malloc(4)); /* { dg-warning "allocation of insufficient size" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-2.c b/gcc/testsuite/gcc.dg/Walloc-size-2.c
new file mode 100644
index 0000000..de641a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-2.c
@@ -0,0 +1,18 @@
+/* Test that VLA types do not crash with -Walloc-size
+ { dg-do compile }
+ { dg-options "-Walloc-size" }
+ * */
+
+struct foo { int x[10]; };
+
+void fo0(int n)
+{
+ struct foo (*p)[n] = __builtin_malloc(sizeof *p);
+}
+
+void fo1(int n)
+{
+ struct bar { int x[n]; };
+ struct bar *p = __builtin_malloc(sizeof *p);
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wtrampolines.c b/gcc/testsuite/gcc.dg/Wtrampolines.c
index 8ff09eb..fc7dfe1 100644
--- a/gcc/testsuite/gcc.dg/Wtrampolines.c
+++ b/gcc/testsuite/gcc.dg/Wtrampolines.c
@@ -5,6 +5,9 @@
/* { dg-require-effective-target trampolines } */
/* { dg-options "-O2 -Wtrampolines" } */
+/* macOS 11 and above use heap-based trampolines, which do not emit a warning. */
+/* { dg-skip-if "" { *-*-darwin2* } } */
+
/* This used to fail on various versions of Solaris 2 because the
trampoline couldn't be made executable. */
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
index 6da0420..07e3da6 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
@@ -455,7 +455,6 @@ test_parmsz_simple2 (size_t sz, char obj[])
return __builtin_dynamic_object_size (obj, 0);
}
-/* Implicitly constructed access attributes not supported yet. */
size_t
__attribute__ ((noinline))
test_parmsz_simple3 (size_t sz, char obj[sz])
@@ -527,6 +526,13 @@ test_parmsz_internal3 (size_t sz1, size_t sz2, double obj[sz1][sz2])
return __builtin_dynamic_object_size (obj, 0);
}
+size_t
+__attribute__ ((noinline))
+test_parmsz_internal4 (size_t sz1, size_t sz2, double obj[sz1 + 1][4])
+{
+ return __builtin_dynamic_object_size (obj, 0);
+}
+
/* Loops. */
size_t
@@ -721,8 +727,8 @@ main (int argc, char **argv)
if (test_parmsz_simple2 (__builtin_strlen (argv[0]) + 1, argv[0])
!= __builtin_strlen (argv[0]) + 1)
FAIL ();
- /* Only explicitly added access attributes are supported for now. */
- if (test_parmsz_simple3 (__builtin_strlen (argv[0]) + 1, argv[0]) != -1)
+ if (test_parmsz_simple3 (__builtin_strlen (argv[0]) + 1, argv[0])
+ != __builtin_strlen (argv[0]) + 1)
FAIL ();
int arr[42];
if (test_parmsz_scaled (arr, 42) != sizeof (arr))
@@ -759,6 +765,8 @@ main (int argc, char **argv)
FAIL ();
if (test_parmsz_internal3 (4, 4, obj) != -1)
FAIL ();
+ if (test_parmsz_internal4 (3, 4, obj) != -1)
+ FAIL ();
if (test_loop (arr, 42, 0, 32, 1) != 10 * sizeof (int))
FAIL ();
if (test_loop (arr, 42, 32, -1, -1) != 0)
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c
new file mode 100644
index 0000000..2c8e07d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c
@@ -0,0 +1,49 @@
+/* PR 109334
+ * { dg-do run }
+ * { dg-options "-O1" } */
+
+
+[[gnu::noinline,gnu::noipa]]
+int f(int n, int buf[n])
+ [[gnu::access(read_only, 2, 1)]]
+{
+ return __builtin_dynamic_object_size(buf, 0);
+}
+
+[[gnu::noinline,gnu::noipa]]
+int g(int n, int buf[])
+ [[gnu::access(read_only, 2, 1)]]
+{
+ return __builtin_dynamic_object_size(buf, 0);
+}
+
+[[gnu::noinline,gnu::noipa]]
+int h(int n, int buf[n])
+{
+ return __builtin_dynamic_object_size(buf, 0);
+}
+
+int dummy(int x) { return x + 1; }
+
+[[gnu::noinline,gnu::noipa]]
+int i(int n, int buf[dummy(n)])
+{
+ return __builtin_dynamic_object_size(buf, 0);
+}
+
+int main()
+{
+ int n = 10;
+ int buf[n];
+ if (n * sizeof(int) != f(n, buf))
+ __builtin_abort();
+ if (n * sizeof(int) != g(n, buf))
+ __builtin_abort();
+ if (n * sizeof(int) != h(n, buf))
+ __builtin_abort();
+
+ (void)i(n, buf);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/fold-popcount-8a.c b/gcc/testsuite/gcc.dg/fold-popcount-8a.c
new file mode 100644
index 0000000..3001522
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-popcount-8a.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo1(unsigned int x, unsigned int y)
+{
+ int t = __builtin_popcount (x&y);
+ int t1 = __builtin_popcount (x|y);
+ return t + t1;
+}
+
+int foo2(unsigned int x, unsigned int y)
+{
+ int t1 = __builtin_popcount (x|y);
+ int t = __builtin_popcount (x&y);
+ return t + t1;
+}
+
+int foo3(unsigned int y, unsigned int x)
+{
+ int t = __builtin_popcount (x&y);
+ int t1 = __builtin_popcount (x|y);
+ return t + t1;
+}
+
+int foo4(unsigned int y, unsigned int x)
+{
+ int t1 = __builtin_popcount (x|y);
+ int t = __builtin_popcount (x&y);
+ return t + t1;
+}
+
+/* { dg-final { scan-tree-dump-not " & " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\| " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/harden-cfr-pr111943.c b/gcc/testsuite/gcc.dg/harden-cfr-pr111943.c
new file mode 100644
index 0000000..5a5a213
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/harden-cfr-pr111943.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fharden-control-flow-redundancy --param=max-jump-thread-duplication-stmts=0 -Ofast -fdump-tree-hardcfr -fdump-tree-optimized" } */
+/* { dg-require-effective-target indirect_jumps } */
+/* { dg-require-effective-target label_values } */
+
+/* Based on gcc.c-torture/compile/20050510-1.c. */
+
+extern void dont_remove (void);
+
+void bar (int k)
+{
+ void *label = (k) ? &&x : &&y;
+
+ if (k >= 0)
+ goto *label;
+
+x:
+ if (k <= 0)
+ dont_remove ();
+ /* else goto y; */
+
+y:
+ return;
+}
+
+/* Check before calling dont_remove(), in the 'else goto y' edge, and in the
+ abnormal edge to y. */
+/* { dg-final { scan-tree-dump-times "hardcfr_check" 3 "hardcfr" } } */
+/* { dg-final { scan-tree-dump-times "hardcfr_check" 3 "optimized" } } */
+/* Check that hardcfr introduces an abnormal PHI node (this could be avoided,
+ but it's not worth the effort), and that it gets optimized out. */
+/* { dg-final { scan-tree-dump-times {\(ab\) = PHI .*\(ab\)} 1 "hardcfr" } } */
+/* { dg-final { scan-tree-dump-not {\(ab\) = PHI .*\(ab\)} "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/lto/pr111157_0.c b/gcc/testsuite/gcc.dg/lto/pr111157_0.c
new file mode 100644
index 0000000..8bb4c65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr111157_0.c
@@ -0,0 +1,24 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O2 -flto=auto } } } */
+/* { dg-extra-ld-options { -flto-partition=1to1 } } */
+
+extern __attribute__((noinline))
+void foo (int *p);
+
+
+void __attribute__((noinline))
+bar (void)
+{
+ int istat;
+
+ istat = 1234;
+ foo (&istat);
+ if (istat != 1234)
+ __builtin_abort ();
+}
+
+int main (int argc, char **argv)
+{
+ bar ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/pr111157_1.c b/gcc/testsuite/gcc.dg/lto/pr111157_1.c
new file mode 100644
index 0000000..f9ba5af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr111157_1.c
@@ -0,0 +1,10 @@
+volatile int v = 0;
+
+void __attribute__((noinline))
+foo (int *p)
+{
+ *p = 1234;
+ if (v)
+ *p = 0;
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/valid-1.c b/gcc/testsuite/gcc.dg/pch/valid-1.c
index 6e9abda..b950d0d 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-1.c
+++ b/gcc/testsuite/gcc.dg/pch/valid-1.c
@@ -1,4 +1,3 @@
-/* { dg-require-effective-target pch_supported_debug } */
/* { dg-options "-I. -Winvalid-pch -g" } */
#include "valid-1.h"/* { dg-warning "created with .none. debug info, but used with" } */
diff --git a/gcc/testsuite/gcc.dg/pch/valid-1b.c b/gcc/testsuite/gcc.dg/pch/valid-1b.c
index 3113d0f..a270996 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-1b.c
+++ b/gcc/testsuite/gcc.dg/pch/valid-1b.c
@@ -1,4 +1,3 @@
-/* { dg-require-effective-target pch_supported_debug } */
/* { dg-options "-I. -Winvalid-pch -g0" } */
#include "valid-1b.h"
diff --git a/gcc/testsuite/gcc.dg/pie-2.c b/gcc/testsuite/gcc.dg/pie-2.c
index 1838745..0a1cc27 100644
--- a/gcc/testsuite/gcc.dg/pie-2.c
+++ b/gcc/testsuite/gcc.dg/pie-2.c
@@ -2,6 +2,7 @@
/* { dg-options "-fPIE" } */
/* { dg-require-effective-target pie } */
/* { dg-skip-if "__PIC__ is always 1 for MIPS" { mips*-*-* } } */
+/* { dg-skip-if "__PIE__ is often not defined on darwin" { *-*-darwin* } } */
#if __PIC__ != 2
# error __PIC__ is not 2!
diff --git a/gcc/testsuite/gcc.dg/pr104970.c b/gcc/testsuite/gcc.dg/pr104970.c
new file mode 100644
index 0000000..ce81654
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104970.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+__inline void
+memset2(void *__dest, int __ch, long __len) {
+ long __trans_tmp_1 = __builtin_dynamic_object_size(__dest, 0);
+ __builtin___memset_chk(__dest, __ch, __len, __trans_tmp_1);
+}
+
+void
+mleye(int l, double E[][l]) { memset2(E, 0, sizeof(double)); }
+
+
diff --git a/gcc/testsuite/gcc.dg/pr111914.c b/gcc/testsuite/gcc.dg/pr111914.c
new file mode 100644
index 0000000..05804bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr111914.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+__attribute__((always_inline))
+static inline void f(int n, int (*a())[n])
+{
+ /* Unused 'a'. */
+}
+
+void g(void)
+{
+ int (*a())[1];
+ f(1, a);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr111916.c b/gcc/testsuite/gcc.dg/torture/pr111916.c
new file mode 100644
index 0000000..2873045
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr111916.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+#pragma pack(1)
+struct A {
+ int b : 4;
+ int c : 11;
+ int d : 2;
+ int e : 5;
+} f;
+int main()
+{
+ struct A g = {1, 1, 1, 1};
+ while (!g.b)
+ f = g;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr111917.c b/gcc/testsuite/gcc.dg/torture/pr111917.c
new file mode 100644
index 0000000..532e302
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr111917.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-funswitch-loops" } */
+
+long t;
+long a() {
+ long b = t, c = t;
+ for (; b < 31; b++)
+ c <<= 1;
+ return c;
+}
+long t1;
+static
+int d() {
+ if (!t1)
+ return 0;
+e:
+f:
+ for (; a();)
+ ;
+ goto f;
+ return 0;
+}
+int main() { d(); }
diff --git a/gcc/testsuite/gcc.dg/torture/pr112305.c b/gcc/testsuite/gcc.dg/torture/pr112305.c
new file mode 100644
index 0000000..9d363aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr112305.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+int a;
+void b()
+{
+ long c = 3;
+ unsigned int d = 50253292;
+ int e = 2147483648;
+ for (; a < 5; a++)
+ do {
+ e += 4;
+ d -= c;
+ } while (e < 20);
+ if (d != -1560359471u)
+ __builtin_abort ();
+}
+int main() { b(); }
diff --git a/gcc/testsuite/gcc.dg/tree-prof/peel-2.c b/gcc/testsuite/gcc.dg/tree-prof/peel-2.c
index ac417fb..216e655 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/peel-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/peel-2.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -fdump-tree-cunroll-details -fno-unroll-loops -fpeel-loops -fdump-tree-ch2-details-blocks" } */
+/* { dg-options "-O3 -fdump-tree-cunroll-details -fno-unroll-loops -fpeel-loops -fdump-tree-ch2-details-blocks -fno-tree-loop-distribute-patterns" } */
int a[100];
int n = 1000000;
int zeroc;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-1.c
new file mode 100644
index 0000000..f3d515b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/101590 */
+
+int f_and_le(unsigned len) {
+ const unsigned N = 4;
+ unsigned newlen = len & -N;
+ return newlen <= len; // return 1
+}
+int f_or_ge(unsigned len) {
+ const unsigned N = 4;
+ unsigned newlen = len | -N;
+ return newlen >= len; // return 1
+}
+
+/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " & " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\\| " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-2.c
new file mode 100644
index 0000000..d0031d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/101590 */
+
+int f_and_gt(unsigned len) {
+ const unsigned N = 4;
+ unsigned newlen = len & -N;
+ return newlen > len; // return 0
+}
+int f_or_lt(unsigned len) {
+ const unsigned N = 4;
+ unsigned newlen = len | -N;
+ return newlen < len; // return 0
+}
+
+/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " & " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\\| " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-3.c b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-3.c
new file mode 100644
index 0000000..5cfab7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/94884 */
+
+#define bool _Bool
+bool decide() __attribute((const));
+
+inline unsigned getXOrY(unsigned x, unsigned y)
+{
+ return decide() ? y : x;
+}
+
+bool f(unsigned x, unsigned y)
+{
+ return (x | y) >= getXOrY(x, y);
+}
+
+
+/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\\| " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1;" 1 "optimized" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-4.c b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-4.c
new file mode 100644
index 0000000..701014b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-4.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/101590 */
+
+int f_and_le(int len) {
+ const int N = 4;
+ int newlen = len & -N;
+ return newlen <= len;
+}
+int f_or_ge(int len) {
+ const int N = 4;
+ int newlen = len | -N;
+ return newlen >= len;
+}
+
+int f_and_gt(int len) {
+ const int N = 4;
+ int newlen = len & -N;
+ return newlen > len;
+}
+int f_or_lt(int len) {
+ const int N = 4;
+ int newlen = len | -N;
+ return newlen < len;
+}
+
+/* These cannot be optimized since we don't know if the sign
+ can change or not. */
+/* { dg-final { scan-tree-dump-times " > " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " < " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " <= " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " >= " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " & " 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\\| " 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "return 1;" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "return 0;" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-5.c b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-5.c
new file mode 100644
index 0000000..a6be142
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-5.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/101590 */
+
+/* These are the signed integer versions
+ of `(a & b) CMP a` and `(a | b) CMP a`
+ which can be optimized to 1. */
+
+
+/* For `&`, the non-negativeness of b is not taken into account. */
+int f_and_le(int len) {
+ len &= 0xfffff;
+ const int N = 4;
+ int newlen = len & -N;
+ return newlen <= len; // return 1
+}
+int f_and_le_(int len, int N) {
+ len &= 0xfffff;
+ int newlen = len & -N;
+ return newlen <= len; // return 1
+}
+
+
+/* For `|`, to get a known value, b either needs to be non-negative
+ or a constant. For the negative constant case, we swap around the comparison. */
+int f_or_ge_(int len, int N) {
+ len &= 0xfffff;
+ N &= 0xffff;
+ int newlen = len | N;
+ return newlen >= len; // return 1
+}
+int f_or_lt(int len) {
+ len &= 0xfffff;
+ const int N = 4;
+ int newlen = len | -N;
+ return newlen < len; // return 1
+}
+
+/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " & " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\\| " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1;" 4 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-6.c b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-6.c
new file mode 100644
index 0000000..a86a19f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitcmp-6.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/101590 */
+
+/* These are the signed integer versions
+ of `(a & b) CMP a` and `(a | b) CMP a`
+ which can be optimized to 0. */
+
+/* For `&`, the non-negativeness of b is not taken into account. */
+int f_and_gt(int len) {
+ len &= 0xfffff;
+ const int N = 4;
+ int newlen = len & -N;
+ return newlen > len; // return 0
+}
+int f_and_gt_(int len, int N) {
+ len &= 0xfffff;
+ int newlen = len & -N;
+ return newlen > len; // return 0
+}
+
+/* For `|`, to get a known value, b either needs to be non-negative
+ or a constant. For the negative constant case, we swap around the comparison. */
+int f_or_lt_(int len, int N) {
+ len &= 0xfffff;
+ N &= 0xffff;
+ int newlen = len | N;
+ return newlen < len; // return 0
+}
+int f_or_ge(int len) {
+ len &= 0xfffff;
+ const int N = 4;
+ int newlen = len | -N;
+ return newlen >= len; // return 0
+}
+
+/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " & " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\\| " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0;" 4 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
new file mode 100644
index 0000000..478a818
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized-raw" } */
+
+int sub(int a, int b, int c, int d) {
+ int e = (a == 0);
+ int f = !e;
+ c = b;
+ d = b - a ;
+ return ((-e & c) | (-f & d));
+}
+
+/* In the end we end up with `(a == 0) ? (b - a) : b`
+ which then can be optimized to just `(b - a)`. */
+
+/* { dg-final { scan-tree-dump-not "cond_expr," "optimized" } } */
+/* { dg-final { scan-tree-dump-not "eq_expr," "optimized" } } */
+/* { dg-final { scan-tree-dump-times "minus_expr," 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-1.c
index bf6335f..adf53b1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-1.c
@@ -1,9 +1,9 @@
-/* { dg-do run { target s390x-*-* } } */
+/* { dg-do run { target { { s390x-*-* } || { riscv_v } } } } */
/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-details" } */
/* { dg-additional-options "-march=z13 -mzarch" { target s390x-*-* } } */
-/* { dg-final { scan-tree-dump-times "generated rawmemchrQI" 2 "ldist" { target s390x-*-* } } } */
-/* { dg-final { scan-tree-dump-times "generated rawmemchrHI" 2 "ldist" { target s390x-*-* } } } */
-/* { dg-final { scan-tree-dump-times "generated rawmemchrSI" 2 "ldist" { target s390x-*-* } } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrQI" 2 "ldist" { target { { s390x-*-* } || { riscv_v } } } } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrHI" 2 "ldist" { target { { s390x-*-* } || { riscv_v } } } } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrSI" 2 "ldist" { target { { s390x-*-* } || { riscv_v } } } } } */
/* Rawmemchr pattern: reduction stmt and no store */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-2.c
index 83f5a35..6c8a485 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-rawmemchr-2.c
@@ -1,9 +1,9 @@
-/* { dg-do run { target s390x-*-* } } */
+/* { dg-do run { target { { s390x-*-* } || { riscv_v } } } } */
/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-details" } */
/* { dg-additional-options "-march=z13 -mzarch" { target s390x-*-* } } */
-/* { dg-final { scan-tree-dump-times "generated rawmemchrQI" 2 "ldist" { target s390x-*-* } } } */
-/* { dg-final { scan-tree-dump-times "generated rawmemchrHI" 2 "ldist" { target s390x-*-* } } } */
-/* { dg-final { scan-tree-dump-times "generated rawmemchrSI" 2 "ldist" { target s390x-*-* } } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrQI" 2 "ldist" { target { { s390x-*-* } || { riscv_v } } } } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrHI" 2 "ldist" { target { { s390x-*-* } || { riscv_v } } } } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrSI" 2 "ldist" { target { { s390x-*-* } || { riscv_v } } } } } */
/* Rawmemchr pattern: reduction stmt and store */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c
new file mode 100644
index 0000000..0f0e317
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c
@@ -0,0 +1,45 @@
+/* { dg-options "-O2 -fno-signed-zeros -fdump-tree-phiopt" } */
+int minus1(int a, int b)
+{
+ int c = a - b;
+ if (c == 0) c = b - a;
+ return c;
+}
+int minus2(int a, int b)
+{
+ int c = a - b;
+ if (c != 0) c = b - a;
+ return c;
+}
+int minus3(int a, int b)
+{
+ int c = a - b;
+ if (c == 0) c = 0;
+ else c = b - a;
+ return c;
+}
+int minus4(int a, int b)
+{
+ int c;
+ if (a == b) c = 0;
+ else
+ c = b - a;
+ return c;
+}
+int abs0(int a, int b)
+{
+ int c = a - b;
+ if (c <= 0) c = b - a;
+ return c;
+}
+int negabs(int a, int b)
+{
+ int c = a - b;
+ if (c >= 0) c = b - a;
+ return c;
+}
+
+/* The above should be optimized at phiopt1 except for negabs which has to wait
+ until phiopt2 as -abs is not acceptable in early phiopt. */
+/* { dg-final { scan-tree-dump-times "if" 1 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-39.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-39.c
new file mode 100644
index 0000000..6b6006a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-39.c
@@ -0,0 +1,43 @@
+/* { dg-options "-O2 -fdump-tree-phiopt" } */
+
+unsigned f0(int A)
+{
+// A == 0? A : -A same as -A
+ if (A == 0) return A;
+ return -A;
+}
+
+unsigned f1(int A)
+{
+// A != 0? A : -A same as A
+ if (A != 0) return A;
+ return -A;
+}
+unsigned f2(int A)
+{
+// A >= 0? A : -A same as abs (A)
+ if (A >= 0) return A;
+ return -A;
+}
+unsigned f3(int A)
+{
+// A > 0? A : -A same as abs (A)
+ if (A > 0) return A;
+ return -A;
+}
+unsigned f4(int A)
+{
+// A <= 0? A : -A same as -abs (A)
+ if (A <= 0) return A;
+ return -A;
+}
+unsigned f5(int A)
+{
+// A < 0? A : -A same as -abs (A)
+ if (A < 0) return A;
+ return -A;
+}
+
+/* f4 and f5 are not allowed to be optimized in early phi-opt. */
+/* { dg-final { scan-tree-dump-times "if" 2 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-40.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-40.c
new file mode 100644
index 0000000..a9011ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-40.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiopt" } */
+/* PR tree-optimization/111957 */
+
+int f(int a)
+{
+ if (a)
+ return a > 0 ? a : -a;
+ return 0;
+}
+
+int f1(int x)
+{
+ int intmin = (-1u >> 1);
+ intmin = -intmin - 1;
+ if (x != intmin)
+ return x > 0 ? x : -x;
+ return intmin;
+}
+
+/* { dg-final { scan-tree-dump-times "if " 1 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if " "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "ABS_EXPR <" 2 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "ABS_EXPR <" 1 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "ABSU_EXPR <" 1 "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
new file mode 100644
index 0000000..a90de89
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* Phi-OPT should be able to optimize this without sinking being invoked. */
+/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
+
+char *f(char *a, __SIZE_TYPE__ b) {
+ char *d = a + b;
+ if (b == 0) return a;
+ return d;
+}
+int sub(int a, int b, int c) {
+ int d = a - b;
+ if (b == 0) return a;
+ return d;
+}
+
+/* { dg-final { scan-tree-dump-not "goto" "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
new file mode 100644
index 0000000..b884f94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+[[gnu::const]]
+int constcall(int);
+
+int f(int a, int b)
+{
+ int c = b+a;
+ int t = constcall(c);
+ int d;
+ if (a == 0) d= b; else d= c;
+ return constcall(d) + t;
+}
+
+/* There should be no if statement and 2 calls to call1. */
+/* { dg-final { scan-tree-dump-not "if " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "constcall " 1 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
new file mode 100644
index 0000000..809ccfe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* Phi-OPT should be able to optimize this without sinking being invoked. */
+/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
+
+int f(int a, int b, int c) {
+ int d = a + b;
+ if (c > 5) return c;
+ if (a == 0) return b;
+ return d;
+}
+
+unsigned rot(unsigned x, int n) {
+ const int bits = __CHAR_BIT__ * __SIZEOF_INT__;
+ int t = ((x << n) | (x >> (bits - n)));
+ return (n == 0) ? x : t;
+}
+
+/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "goto" 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
new file mode 100644
index 0000000..380082c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-fre3 -fdump-tree-phiopt1 -fdump-tree-optimized" } */
+
+[[gnu::const]]
+int constcall(int);
+
+int fdiv(int a, int b)
+{
+ int c = b/a;
+ int t = constcall(c);
+ int d;
+ if (a == 1) d = b; else d = c;
+ return constcall(d) + t;
+}
+int fmult(int a, int b)
+{
+ int c = b*a;
+ int t = constcall(c);
+ int d;
+ if (a == 1) d = b; else d = c;
+ return constcall(d) + t;
+}
+int fand(int a, int b)
+{
+ int c = b&a;
+ int t = constcall(c);
+ int d;
+ if (a == -1) d = b; else d = c;
+ return constcall(d) + t;
+}
+
+/* Should be able to optimize away the if statements in phiopt1. */
+/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */
+/* fre3 should be optimize each function to just `return constcall(a OP b) * 2;`. */
+/* { dg-final { scan-tree-dump-times "constcall " 3 "fre3" } } */
+/* { dg-final { scan-tree-dump-times "constcall " 3 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c
index 13b9ba4..1372100 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-sink-stats" } */
+/* { dg-options "-O2 -fdump-tree-sink2-stats" } */
/* { dg-require-effective-target int32plus } */
#include <stdint.h>
@@ -213,6 +213,6 @@ compute_on_bytes (uint8_t *in_data, int in_len, uint8_t *out_data, int out_len)
expected, so this case is restricted to lp64 only so far. This different
ivopts choice affects riscv64 as well, probably because it also lacks
base+index addressing modes, so the ip[len] address computation can't be
- made from the IV computation above. */
+ made from the IV computation above. powerpc64le similarly is affected. */
- /* { dg-final { scan-tree-dump-times "Sunk statements: 5" 1 "sink2" { target lp64 xfail { riscv64-*-* } } } } */
+ /* { dg-final { scan-tree-dump-times "Sunk statements: 5" 1 "sink2" { target lp64 xfail { riscv64-*-* powerpc64le-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
index 928a507..5278e4a 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
@@ -39,7 +39,7 @@ void foo2 (int16_t *__restrict a,
}
}
-/* { dg-final { scan-assembler {e32,m4} } } */
+/* { dg-final { scan-assembler {e16,m2} } } */
/* { dg-final { scan-assembler-not {csrr} } } */
/* { dg-final { scan-tree-dump-times "Maximum lmul = 8" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "Maximum lmul = 4" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-2.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-2.c
index a50265f..1db2e07 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-2.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-2.c
@@ -10,7 +10,7 @@ foo (int32_t *__restrict a, int16_t *__restrict b, int n)
a[i] = a[i] + b[i];
}
-/* { dg-final { scan-assembler {e32,m8} } } */
+/* { dg-final { scan-assembler {e16,m4} } } */
/* { dg-final { scan-assembler-not {csrr} } } */
/* { dg-final { scan-tree-dump-times "Maximum lmul = 8" 1 "vect" } } */
/* { dg-final { scan-tree-dump-not "Maximum lmul = 4" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr111860-2.c b/gcc/testsuite/gcc.dg/vect/pr111860-2.c
new file mode 100644
index 0000000..07f64ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr111860-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-sink -ftree-vectorize" } */
+int buffer_ctrl_ctx_0, buffer_ctrl_p1, buffer_ctrl_cmd;
+
+int
+buffer_ctrl (long ret, int i)
+{
+ switch (buffer_ctrl_cmd)
+ {
+ case 1:
+ buffer_ctrl_ctx_0 = 0;
+ for (; i; i++)
+ if (buffer_ctrl_p1)
+ ret++;
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr111860-3.c b/gcc/testsuite/gcc.dg/vect/pr111860-3.c
new file mode 100644
index 0000000..07f64ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr111860-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-sink -ftree-vectorize" } */
+int buffer_ctrl_ctx_0, buffer_ctrl_p1, buffer_ctrl_cmd;
+
+int
+buffer_ctrl (long ret, int i)
+{
+ switch (buffer_ctrl_cmd)
+ {
+ case 1:
+ buffer_ctrl_ctx_0 = 0;
+ for (; i; i++)
+ if (buffer_ctrl_p1)
+ ret++;
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr111915.c b/gcc/testsuite/gcc.dg/vect/pr111915.c
new file mode 100644
index 0000000..8614bac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr111915.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-vrp -fno-tree-dominator-opts -fno-tree-ccp" } */
+
+void
+foo (int * __restrict a, int * __restrict b, int * __restrict w)
+{
+ for (int i = 0; i < 16; ++i)
+ {
+ *a += w[2*i+0];
+ *b += w[2*i&1];
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-gather-6.c b/gcc/testsuite/gcc.dg/vect/vect-gather-6.c
new file mode 100644
index 0000000..ff55f32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-gather-6.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+void
+f (int *restrict y, int *restrict x, int *restrict indices, int *restrict cond, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ if (cond[i * 2])
+ y[i * 2] = x[indices[i * 2]] + 1;
+ if (cond[i * 2 + 1])
+ y[i * 2 + 1] = x[indices[i * 2 + 1]] + 2;
+ }
+}
+
+/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" vect { target vect_gather_load_ifn } } } */
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c b/gcc/testsuite/gcc.misc-tests/godump-1.c
index f359a65..b661d04 100644
--- a/gcc/testsuite/gcc.misc-tests/godump-1.c
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -234,18 +234,6 @@ const char cc_v1;
cc_t cc_v2;
/* { dg-final { scan-file godump-1.out "(?n)^var _cc_v2 _cc_t$" } } */
-_BitInt(32) b32_v;
-/* { dg-final { scan-file godump-1.out "(?n)^var _b32_v int32$" } } */
-
-_BitInt(64) b64_v;
-/* { dg-final { scan-file godump-1.out "(?n)^var _b64_v int64$" } } */
-
-unsigned _BitInt(32) b32u_v;
-/* { dg-final { scan-file godump-1.out "(?n)^var _b32u_v uint32$" } } */
-
-_BitInt(33) b33_v;
-/* { dg-final { scan-file godump-1.out "(?n)^// var _b33_v INVALID-bitint-33$" } } */
-
/*** pointer and array types ***/
typedef void *vp_t;
/* { dg-final { scan-file godump-1.out "(?n)^type _vp_t \\*byte$" } } */
diff --git a/gcc/testsuite/gcc.misc-tests/godump-2.c b/gcc/testsuite/gcc.misc-tests/godump-2.c
new file mode 100644
index 0000000..ed093c9
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/godump-2.c
@@ -0,0 +1,18 @@
+/* { dg-options "-c -fdump-go-spec=godump-2.out" } */
+/* { dg-do compile { target bitint } } */
+/* { dg-skip-if "not supported for target" { ! "alpha*-*-* s390*-*-* i?86-*-* x86_64-*-*" } } */
+/* { dg-skip-if "not supported for target" { ! lp64 } } */
+
+_BitInt(32) b32_v;
+/* { dg-final { scan-file godump-2.out "(?n)^var _b32_v int32$" } } */
+
+_BitInt(64) b64_v;
+/* { dg-final { scan-file godump-2.out "(?n)^var _b64_v int64$" } } */
+
+unsigned _BitInt(32) b32u_v;
+/* { dg-final { scan-file godump-2.out "(?n)^var _b32u_v uint32$" } } */
+
+_BitInt(33) b33_v;
+/* { dg-final { scan-file godump-2.out "(?n)^// var _b33_v INVALID-bitint-33$" } } */
+
+/* { dg-final { remove-build-file "godump-2.out" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/aarch64.exp b/gcc/testsuite/gcc.target/aarch64/aarch64.exp
index bd306e3..7612ea7 100644
--- a/gcc/testsuite/gcc.target/aarch64/aarch64.exp
+++ b/gcc/testsuite/gcc.target/aarch64/aarch64.exp
@@ -37,9 +37,10 @@ if ![info exists DEFAULT_CFLAGS] then {
# Initialize `dg'.
dg-init
-# Main loop.
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
- "" $DEFAULT_CFLAGS
-
+aarch64-with-arch-dg-options "" {
+ # Main loop.
+ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+ "" $DEFAULT_CFLAGS
+}
# All done.
dg-finish
diff --git a/gcc/testsuite/gcc.target/aarch64/cond_op-1.c b/gcc/testsuite/gcc.target/aarch64/cond_op-1.c
new file mode 100644
index 0000000..e6c7821
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cond_op-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* PR target/110986 */
+
+
+long long full(unsigned a, unsigned b)
+{
+ return a ? ~b : b;
+}
+unsigned fuu(unsigned a, unsigned b)
+{
+ return a ? ~b : b;
+}
+long long fllll(unsigned long long a, unsigned long long b)
+{
+ return a ? ~b : b;
+}
+
+/* { dg-final { scan-assembler-times "csinv\tw\[0-9\]*" 2 } } */
+/* { dg-final { scan-assembler-times "csinv\tx\[0-9\]*" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison.c b/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison.c
index ebc44d6..d52d592 100644
--- a/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison.c
+++ b/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison.c
@@ -1,32 +1,69 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Go from four moves to two. */
+/*
+** foo:
+** ...
+** mov w[0-9]+, 2576980377
+** movk x[0-9]+, 0x9999, lsl 32
+** ...
+*/
+
int
foo (long long x)
{
- return x <= 0x1999999999999998;
+ return x <= 0x0000999999999998;
}
+/*
+** GT:
+** ...
+** mov w[0-9]+, -16777217
+** ...
+*/
+
int
GT (unsigned int x)
{
return x > 0xfefffffe;
}
+/*
+** LE:
+** ...
+** mov w[0-9]+, -16777217
+** ...
+*/
+
int
LE (unsigned int x)
{
return x <= 0xfefffffe;
}
+/*
+** GE:
+** ...
+** mov w[0-9]+, 4278190079
+** ...
+*/
+
int
GE (long long x)
{
return x >= 0xff000000;
}
+/*
+** LT:
+** ...
+** mov w[0-9]+, -16777217
+** ...
+*/
+
int
LT (int x)
{
@@ -35,6 +72,13 @@ LT (int x)
/* Optimize the immediate in conditionals. */
+/*
+** check:
+** ...
+** mov w[0-9]+, -16777217
+** ...
+*/
+
int
check (int x, int y)
{
@@ -44,11 +88,15 @@ check (int x, int y)
return x;
}
+/*
+** tern:
+** ...
+** mov w[0-9]+, -16777217
+** ...
+*/
+
int
tern (int x)
{
return x >= 0xff000000 ? 5 : -3;
}
-
-/* baz produces one movk instruction. */
-/* { dg-final { scan-assembler-times "movk" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/moveor_imm.c b/gcc/testsuite/gcc.target/aarch64/moveor_imm.c
new file mode 100644
index 0000000..887b182
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/moveor_imm.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** f1:
+** ...
+** mov x0, -6148914691236517206
+** eor x0, x0, -9223372036854775807
+** ...
+*/
+
+long f1 (void)
+{
+ return 0x2aaaaaaaaaaaaaab;
+}
+
+/*
+** f2:
+** ...
+** mov x0, -1085102592571150096
+** eor x0, x0, -2305843009213693951
+** ...
+*/
+
+long f2 (void)
+{
+ return 0x10f0f0f0f0f0f0f1;
+}
+
+/*
+** f3:
+** ...
+** mov x0, -3689348814741910324
+** eor x0, x0, -4611686018427387903
+** ...
+*/
+
+long f3 (void)
+{
+ return 0xccccccccccccccd;
+}
+
+/*
+** f4:
+** ...
+** mov x0, -7378697629483820647
+** eor x0, x0, -9223372036854775807
+** ...
+*/
+
+long f4 (void)
+{
+ return 0x1999999999999998;
+}
+
+/*
+** f5:
+** ...
+** mov x0, 3689348814741910323
+** eor x0, x0, 864691128656461824
+** ...
+*/
+
+long f5 (void)
+{
+ return 0x3f3333333f333333;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr106583.c b/gcc/testsuite/gcc.target/aarch64/pr106583.c
index 0f93158..5708f03 100644
--- a/gcc/testsuite/gcc.target/aarch64/pr106583.c
+++ b/gcc/testsuite/gcc.target/aarch64/pr106583.c
@@ -1,41 +1,101 @@
-/* { dg-do assemble } */
-/* { dg-options "-O2 --save-temps" } */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** f1:
+** ...
+** mov x0, -72340172838076674
+** movk x0, 0xfeff, lsl 0
+** movk x0, 0x75fe, lsl 48
+** ...
+*/
long f1 (void)
{
- return 0x7efefefefefefeff;
+ return 0x75fefefefefefeff;
}
+/*
+** f2:
+** ...
+** mov x0, -6148914691236517206
+** movk x0, 0x5678, lsl 32
+** movk x0, 0x1234, lsl 48
+** ...
+*/
+
long f2 (void)
{
return 0x12345678aaaaaaaa;
}
+/*
+** f3:
+** ...
+** mov x0, -3689348814741910324
+** movk x0, 0x5678, lsl 0
+** movk x0, 0x1234, lsl 48
+** ...
+*/
+
long f3 (void)
{
return 0x1234cccccccc5678;
}
+/*
+** f4:
+** ...
+** mov x0, 8608480567731124087
+** movk x0, 0x5678, lsl 16
+** movk x0, 0x1234, lsl 32
+** ...
+*/
+
long f4 (void)
{
return 0x7777123456787777;
}
+/*
+** f5:
+** ...
+** mov x0, 6148914691236517205
+** movk x0, 0x5678, lsl 0
+** movk x0, 0x1234, lsl 16
+** ...
+*/
+
long f5 (void)
{
return 0x5555555512345678;
}
+/*
+** f6:
+** ...
+** mov x0, -4919131752989213765
+** movk x0, 0x5678, lsl 16
+** movk x0, 0x1234, lsl 48
+** ...
+*/
+
long f6 (void)
{
return 0x1234bbbb5678bbbb;
}
+/*
+** f7:
+** ...
+** mov x0, 4919131752989213764
+** movk x0, 0x5678, lsl 0
+** movk x0, 0x1234, lsl 32
+** ...
+*/
+
long f7 (void)
{
return 0x4444123444445678;
}
-
-
-/* { dg-final { scan-assembler-times {\tmovk\t} 14 } } */
-/* { dg-final { scan-assembler-times {\tmov\t} 7 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1b.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1b.c
new file mode 100644
index 0000000..65bfab8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1b.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8-a+crypto -save-temps" } */
+#include "pragma_cpp_predefs_1.c"
diff --git a/gcc/testsuite/gcc.target/arc/lsl16-1.c b/gcc/testsuite/gcc.target/arc/lsl16-1.c
new file mode 100644
index 0000000..cbd0dae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lsl16-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+int foo(int x)
+{
+ return x << 16;
+}
+
+/* { dg-final { scan-assembler "lsl16\\s+r0,r0" } } */
+
diff --git a/gcc/testsuite/gcc.target/arc/lsr16-1.c b/gcc/testsuite/gcc.target/arc/lsr16-1.c
new file mode 100644
index 0000000..8ce5f13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lsr16-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+unsigned int foo(unsigned int x)
+{
+ return x >> 16;
+}
+
+/* { dg-final { scan-assembler "lsr16\\s+r0,r0" } } */
+
diff --git a/gcc/testsuite/gcc.target/arc/pr101955.c b/gcc/testsuite/gcc.target/arc/pr101955.c
new file mode 100644
index 0000000..3c66885
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/pr101955.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+int f(int a)
+{
+ return (a << 31) >> 31;
+}
+
+/* { dg-final { scan-assembler "bmsk_s\\s+r0,r0,0" } } */
+/* { dg-final { scan-assembler "neg_s\\s+r0,r0" } } */
diff --git a/gcc/testsuite/gcc.target/arc/swap-1.c b/gcc/testsuite/gcc.target/arc/swap-1.c
new file mode 100644
index 0000000..71afc75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/swap-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+int foo(int x)
+{
+ return ((unsigned int)x >> 16) | (x << 16);
+}
+
+/* { dg-final { scan-assembler "swap\\s+r0,r0" } } */
diff --git a/gcc/testsuite/gcc.target/arc/swap-2.c b/gcc/testsuite/gcc.target/arc/swap-2.c
new file mode 100644
index 0000000..bf12392
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/swap-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+int foo(int x)
+{
+ return x >> 16;
+}
+
+/* { dg-final { scan-assembler "swap\\s+r0,r0" } } */
+/* { dg-final { scan-assembler "sexh_s\\s+r0,r0" } } */
+
diff --git a/gcc/testsuite/gcc.target/arm/arm-switchstatement.c b/gcc/testsuite/gcc.target/arm/arm-switchstatement.c
new file mode 100644
index 0000000..803731c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/arm-switchstatement.c
@@ -0,0 +1,155 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 --param case-values-threshold=1 -fno-reorder-blocks -fno-tree-dce" } */
+/* { dg-require-effective-target arm_nothumb } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#define NOP "nop;"
+#define NOP2 NOP NOP
+#define NOP4 NOP2 NOP2
+#define NOP8 NOP4 NOP4
+#define NOP16 NOP8 NOP8
+#define NOP32 NOP16 NOP16
+#define NOP64 NOP32 NOP32
+#define NOP128 NOP64 NOP64
+#define NOP256 NOP128 NOP128
+#define NOP512 NOP256 NOP256
+#define NOP1024 NOP512 NOP512
+#define NOP2048 NOP1024 NOP1024
+#define NOP4096 NOP2048 NOP2048
+#define NOP8192 NOP4096 NOP4096
+#define NOP16384 NOP8192 NOP8192
+#define NOP32768 NOP16384 NOP16384
+#define NOP65536 NOP32768 NOP32768
+#define NOP131072 NOP65536 NOP65536
+
+enum z
+{
+ a = 1,
+ b,
+ c,
+ d,
+ e,
+ f = 7,
+};
+
+inline void QIFunction (const char* flag)
+{
+ asm volatile (NOP32);
+ return;
+}
+
+inline void HIFunction (const char* flag)
+{
+ asm volatile (NOP512);
+ return;
+}
+
+inline void SIFunction (const char* flag)
+{
+ asm volatile (NOP131072);
+ return;
+}
+
+/*
+**QImode_test:
+** ...
+** ldr (r[0-9]+), .L[0-9]+
+** ...
+** ldrb (r[0-9]+), \[\1, r[0-9]+\]
+** add pc, pc, \2, lsl #2
+** ...
+*/
+__attribute__ ((noinline)) __attribute__ ((noclone)) const char* QImode_test(enum z x)
+{
+ switch (x)
+ {
+ case d:
+ QIFunction("QItest");
+ return "InlineASM";
+ case f:
+ return "TEST";
+ default:
+ return "Default";
+ }
+}
+
+/* { dg-final { scan-assembler ".byte" } } */
+
+/*
+**HImode_test:
+** ...
+** ldr (r[0-9]+), .L[0-9]+
+** ...
+** add r[0-9]+, r[0-9]+, r[0-9]+
+** ldrh (r[0-9]+), \[r[0-9]+, r[0-9]+]
+** add pc, pc, \2, lsl #2
+** ...
+*/
+__attribute__ ((noinline)) __attribute__ ((noclone)) const char* HImode_test(enum z x)
+{
+ switch (x)
+ {
+ case d:
+ HIFunction("HItest");
+ return "InlineASM";
+ case f:
+ return "TEST";
+ default:
+ return "Default";
+ }
+}
+
+/* { dg-final { scan-assembler ".2byte" } } */
+
+/*
+**SImode_test:
+** ...
+** ldr (r[0-9]+), .L[0-9]+
+** ...
+** ldr pc, \[\1, r[0-9]+, lsl #2\]
+** ...
+*/
+__attribute__ ((noinline)) __attribute__ ((noclone)) const char* SImode_test(enum z x)
+{
+ switch (x)
+ {
+ case d:
+ SIFunction("SItest");
+ return "InlineASM";
+ case f:
+ return "TEST";
+ default:
+ return "Default";
+ }
+}
+
+/* { dg-final { scan-assembler ".word" } } */
+
+/*
+**backwards_branch_test:
+** ...
+** ldr (r[0-9]+), .L[0-9]+
+** ...
+** add r[0-9]+, r[0-9]+, r[0-9]+
+** ldrsh (r[0-9]+), \[r[0-9]+, r[0-9]+]
+** add pc, pc, \2, lsl #2
+** ...
+*/
+__attribute__ ((noinline)) __attribute__ ((noclone)) const char* backwards_branch_test(enum z x, int flag)
+{
+ if (flag == 5)
+ {
+ backwards:
+ asm volatile (NOP512);
+ return "ASM";
+ }
+ switch (x)
+ {
+ case d:
+ goto backwards;
+ case f:
+ return "TEST";
+ default:
+ return "Default";
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/mve_vadcq_vsbcq_fpscr_overwrite.c b/gcc/testsuite/gcc.target/arm/mve/mve_vadcq_vsbcq_fpscr_overwrite.c
index a8c6cce..931c9d2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/mve_vadcq_vsbcq_fpscr_overwrite.c
+++ b/gcc/testsuite/gcc.target/arm/mve/mve_vadcq_vsbcq_fpscr_overwrite.c
@@ -7,7 +7,7 @@
volatile int32x4_t c1;
volatile uint32x4_t c2;
-int *carry;
+int carry;
int
main ()
@@ -21,45 +21,45 @@ main ()
uint32x4_t inactive2 = vcreateq_u32 (0, 0);
mve_pred16_t p = 0xFFFF;
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c1 = vadcq (a1, b1, carry);
+ c1 = vadcq (a1, b1, &carry);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c2 = vadcq (a2, b2, carry);
+ c2 = vadcq (a2, b2, &carry);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c1 = vsbcq (a1, b1, carry);
+ c1 = vsbcq (a1, b1, &carry);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c2 = vsbcq (a2, b2, carry);
+ c2 = vsbcq (a2, b2, &carry);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c1 = vadcq_m (inactive1, a1, b1, carry, p);
+ c1 = vadcq_m (inactive1, a1, b1, &carry, p);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c2 = vadcq_m (inactive2, a2, b2, carry, p);
+ c2 = vadcq_m (inactive2, a2, b2, &carry, p);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c1 = vsbcq_m (inactive1, a1, b1, carry, p);
+ c1 = vsbcq_m (inactive1, a1, b1, &carry, p);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
- (*carry) = 0xFFFFFFFF;
+ carry = 0xFFFFFFFF;
__builtin_arm_set_fpscr_nzcvqc (0);
- c2 = vsbcq_m (inactive2, a2, b2, carry, p);
+ c2 = vsbcq_m (inactive2, a2, b2, &carry, p);
if (__builtin_arm_get_fpscr_nzcvqc () & !0x20000000)
__builtin_abort ();
diff --git a/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_1b.c b/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_1b.c
new file mode 100644
index 0000000..652d084
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_1b.c
@@ -0,0 +1,6 @@
+/* Test for #pragma target macros. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
+/* { dg-additional-options "-save-temps" } */
+/* { dg-add-options arm_arch_v8a } */
+#include "pragma_arch_attribute.c"
diff --git a/gcc/testsuite/gcc.target/bpf/core-attr-5.c b/gcc/testsuite/gcc.target/bpf/core-attr-5.c
new file mode 100644
index 0000000..c0dc15f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-attr-5.c
@@ -0,0 +1,62 @@
+/* Test for BPF CO-RE __attribute__((preserve_access_index)) with accesses on
+ LHS and both LHS and RHS of assignment. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -dA -gbtf -mco-re" } */
+
+struct U {
+ int c;
+ struct V {
+ int d;
+ int e[4];
+ int f;
+ int *g;
+ } v;
+} __attribute__((preserve_access_index));
+
+struct T {
+ int a;
+ int b;
+ struct U u;
+ struct U *ptr_u;
+ struct U *array_u;
+} __attribute__((preserve_access_index));
+
+
+extern void mset(void *);
+void
+func (struct T *t, int i)
+{
+ /* This next expression is silently generating incomplete CO-RE relocations
+ * because of a front-end optimization to the array access with i. It is
+ * converting the access to pointer arithmetics, which completely removes the
+ * reference to the type of array_u. With current folding it is not possible
+ * to generate correct/complete CO-RE relocations for such cases. The XFAIL
+ * is exactly for this reason. Once we do XPASS this test there is a slight
+ * chance we are doing the proper code generation. */
+
+ /* 0:4 sizeof(struct U) 0:1:1:3 */
+ t->array_u[i].v.e[3] = 0xc1;
+
+ /* This was commented since in this case it is detectable as not a field
+ * expression. */
+ /* 0:4 sizeof(struct U) 0:1:1:2 */
+ //__builtin_preserve_access_index (t->array_u[i].v.e[2]) = 0xa1;
+
+ /* 0:3 0:1:1:1 */
+ t->ptr_u->v.e[1] = 0xb1;
+
+ /* 0:3 0:1:2 */
+ mset (&(t->ptr_u->v.f));
+
+ mset (&t->a);
+}
+
+/* { dg-final { scan-assembler-times "ascii \"0:4.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:1:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:1:1.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 2 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:0.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "bpfcr_type \\(struct T \\*\\)" 4 } } */
+/* { dg-final { scan-assembler-times "bpfcr_type \\(struct U \\*\\)" 4 { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.target/bpf/core-attr-6.c b/gcc/testsuite/gcc.target/bpf/core-attr-6.c
new file mode 100644
index 0000000..858ae62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-attr-6.c
@@ -0,0 +1,46 @@
+/* Test for BPF CO-RE __attribute__((preserve_access_index)) with accesses on
+ LHS and both LHS and RHS of assignment. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -dA -gbtf -mco-re" } */
+
+struct U {
+ int c;
+ struct V {
+ int d;
+ int e[4];
+ int f;
+ int *g;
+ } v;
+} u;
+
+struct T {
+ int a;
+ int b;
+ struct U u;
+ struct U *ptr_u;
+ struct U *array_u;
+} __attribute__((preserve_access_index));
+
+extern void mset(void *);
+
+void
+func (struct T *t, int i)
+{
+ /* 0:3 0:1:1:1 */
+ t->ptr_u->v.e[1] = 0xb1;
+
+ /* 0:3 0:1:2 */
+ mset (&(t->ptr_u->v.f));
+
+ /* 0:0 */
+ mset (&t->a);
+}
+
+/* { dg-final { scan-assembler-times "ascii \"0:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 2 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:1:1.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:0.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "bpfcr_type \\(struct T \\*\\)" 3 } } */
+/* { dg-final { scan-assembler-times "bpfcr_type \\(struct U \\*\\)" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-1.c b/gcc/testsuite/gcc.target/bpf/core-builtin-1.c
index e994dc6..3f15980 100644
--- a/gcc/testsuite/gcc.target/bpf/core-builtin-1.c
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-1.c
@@ -21,7 +21,7 @@ unsigned long ula[8];
#define _(x) (__builtin_preserve_access_index (x))
-void
+unsigned long
func (void)
{
/* 1 */
@@ -35,6 +35,8 @@ func (void)
/* 6 */
unsigned long ul = _(ula[6]);
+
+ return b + c + uc + ul;
}
char
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c
index 363ad0c..c87e1a3 100644
--- a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c
@@ -26,8 +26,8 @@ unsigned long foo(void *data)
return 0;
}
-/* { dg-final { scan-assembler-times "\t.4byte\t0x8\t; bpfcr_type \\(named_ue64\\)" 2 } } */
-/* { dg-final { scan-assembler-times "\t.4byte\t0x9\t; bpfcr_type \\(named_se64\\)" 2} } */
+/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type \\(named_ue64\\)" 2 } } */
+/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type \\(named_se64\\)" 2} } */
/* { dg-final { scan-assembler-times "\t.4byte\t0xa\t; bpfcr_kind" 2 } } BPF_ENUMVAL_EXISTS */
/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_kind" 2 } } BPF_ENUMVAL_VALUE */
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
index 3e3334d..2f16903 100644
--- a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
@@ -40,10 +40,10 @@ int foo(void *data)
return 0;
}
-/* { dg-final { scan-assembler-times "\t.4byte\t0x8\t; bpfcr_type \\(named_ue64\\)" 5 } } */
-/* { dg-final { scan-assembler-times "\t.4byte\t0x9\t; bpfcr_type \\(named_se64\\)" 5} } */
-/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_type \\(named_ue\\)" 5 } } */
-/* { dg-final { scan-assembler-times "\t.4byte\t0xc\t; bpfcr_type \\(named_se\\)" 5} } */
+/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type \\(named_ue64\\)" 5 } } */
+/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type \\(named_se64\\)" 5} } */
+/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type \\(named_ue\\)" 5 } } */
+/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type \\(named_se\\)" 5} } */
/* { dg-final { scan-assembler-times "\t.4byte\t0xa\t; bpfcr_kind" 12 } } BPF_ENUMVAL_EXISTS */
/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_kind" 8 } } BPF_ENUMVAL_VALUE */
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-1.c b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-1.c
new file mode 100644
index 0000000..b8bdeea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-1.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -dA -gbtf -mco-re" } */
+
+struct S {
+ int a;
+ int b;
+ char c;
+};
+
+union U {
+ unsigned int u;
+ int i;
+ unsigned char uc[4];
+ signed char ic[4];
+};
+
+struct S my_s;
+union U my_u;
+
+unsigned long ula[8];
+
+#define _(x) (__builtin_preserve_access_index (x))
+
+unsigned long
+func (void)
+{
+ int b;
+ char c;
+ unsigned char uc;
+ unsigned long ul;
+ int ic;
+
+ __builtin_preserve_access_index (({
+ /* 1 */
+ b = my_s.b;
+
+ /* 2 */
+ ic = my_s.c;
+
+ /* 2:3 */
+ uc = my_u.uc[3];
+
+ /* 6 */
+ ul = ula[6];
+ }));
+
+ return b + ic + uc + ul;
+}
+
+char
+s_ptr (struct S *ps)
+{
+ /* 0:2 */
+ char x;
+ __builtin_preserve_access_index (({ x = ps->c; }));
+ return x;
+}
+
+unsigned char
+u_ptr (union U *pu)
+{
+ /* 0:2:3 */
+ unsigned char x;
+ __builtin_preserve_access_index (({ x = pu->uc[3]; }));
+ return x;
+}
+
+/* { dg-final { scan-assembler-times "ascii \"1.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"2:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"6.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:2:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+
+/* { dg-final { scan-assembler-times "bpfcr_type" 6 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x6c\[\t \]+\[^\n\]*core_relo_len" 1 } } */
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-2.c b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-2.c
new file mode 100644
index 0000000..3a22b99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-2.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -dA -gbtf -mco-re" } */
+
+struct T {
+ int a;
+ int b;
+ struct U {
+ int c;
+ struct V {
+ int d;
+ int e[4];
+ int f;
+ } v;
+ } u;
+};
+
+void func (struct T * foo)
+{
+ /* Access string: "0:2:1:1:3" */
+ int *x;
+ int *y;
+ __builtin_preserve_access_index (({
+ x = &(foo->u.v.e[3]);
+ struct U *tmp = &(foo->u);
+ y = &(tmp->v.f);
+ }));
+
+ *x = 17;
+ *y = 16;
+}
+
+/* { dg-final { scan-assembler-times "ascii \"0:2:1:1:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "bpfcr_type" 3 } } */
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-3.c b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-3.c
new file mode 100644
index 0000000..bccf2b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-3.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -dA -gbtf -mco-re" } */
+
+struct T {
+ int a;
+ int b;
+ struct U {
+ int c;
+ struct V {
+ int d;
+ int e[4];
+ int f;
+ } v;
+ } u;
+};
+
+void func (struct T * foo)
+{
+ /* Access string: "0:2:1:1:3" */
+ int *x;
+ int *y;
+ struct U *tmp;
+ __builtin_preserve_access_index (({
+ x = &(foo->u.v.e[3]);
+ tmp = &(foo->u);
+ }));
+ y = __builtin_preserve_access_index(tmp ? 0 : &(tmp->v.f));
+
+ *x = 17;
+ if (y != 0)
+ *y = 16;
+}
+
+/* { dg-final { scan-assembler-times "ascii \"0:2:1:1:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "bpfcr_type" 3 } } */
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-4.c b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-4.c
new file mode 100644
index 0000000..8ef239c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-exprlist-4.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -dA -gbtf -mco-re" } */
+
+struct T {
+ int a;
+ int b;
+ struct U {
+ int c;
+ struct V {
+ int d;
+ int e[4];
+ int f;
+ } *v;
+ } u;
+};
+
+void func (struct T * foo)
+{
+ /* Access string: "0:2:1:1:3" */
+ int *x;
+ int *y;
+ __builtin_preserve_access_index (({
+ x = &((foo->u.v)->e[3]);
+ }));
+
+ *x = 17;
+}
+
+/* { dg-final { scan-assembler-times "ascii \"0:2:1.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "bpfcr_type" 2 } } */
diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-offset-1.c b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-offset-1.c
index 590eea0..a4af9a5 100644
--- a/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-offset-1.c
+++ b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-offset-1.c
@@ -20,6 +20,7 @@ enum {
FIELD_BYTE_OFFSET = 0,
};
+extern struct T *bar();
unsigned int foo (struct T *t)
{
@@ -34,23 +35,26 @@ unsigned int foo (struct T *t)
unsigned c = __builtin_preserve_field_info (t->c, FIELD_BYTE_OFFSET);
unsigned d = __builtin_preserve_field_info (t->d, FIELD_BYTE_OFFSET);
- return s0a1 + s0a4 + s0x + s1a1 + s1a4 + s1x + c + d;
+ unsigned e1 = __builtin_preserve_field_info (bar()->d, FIELD_BYTE_OFFSET);
+ unsigned e2 = __builtin_preserve_field_info (bar()->s[1].a4, FIELD_BYTE_OFFSET);
+
+ return s0a1 + s0a4 + s0x + s1a1 + s1a4 + s1x + c + d + e1 + e2;
}
/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],4" 2 } } */
/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],8" 1 } } */
-/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],12" 2 } } */
+/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],12" 3 } } */
/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],16" 1 } } */
/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],20" 1 } } */
-/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],21" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],21" 2 } } */
/* { dg-final { scan-assembler-times "ascii \"0:1:0:0.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
/* { dg-final { scan-assembler-times "ascii \"0:1:0:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
/* { dg-final { scan-assembler-times "ascii \"0:1:0:4.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
/* { dg-final { scan-assembler-times "ascii \"0:1:1:0.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
-/* { dg-final { scan-assembler-times "ascii \"0:1:1:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:1:1:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 2 } } */
/* { dg-final { scan-assembler-times "ascii \"0:1:1:4.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
/* { dg-final { scan-assembler-times "ascii \"0:2.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
-/* { dg-final { scan-assembler-times "ascii \"0:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"0:3.0\"\[\t \]+\[^\n\]*btf_aux_string" 2 } } */
-/* { dg-final { scan-assembler-times "0\[\t \]+\[^\n\]*bpfcr_kind" 8 } } */
+/* { dg-final { scan-assembler-times "0\[\t \]+\[^\n\]*bpfcr_kind" 10 } } */
diff --git a/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c b/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c
index dc1fc3f..5f732d3 100644
--- a/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c
+++ b/gcc/testsuite/gcc.target/i386/apx-interrupt-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-mapxf -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));
extern int bar (int);
diff --git a/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c b/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c
index c7968d6..089941d 100644
--- a/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c
+++ b/gcc/testsuite/gcc.target/i386/apx-push2pop2-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O2 -mapxf" } */
+/* { dg-skip-if "does not emit .cfi_xxx" "*-*-darwin*" } */
extern int bar (int);
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 3878799..656ca91 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,6 @@
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O2 -mapxf -mforce-drap" } */
+/* { dg-skip-if "does not emit .cfi_xxx" "*-*-darwin*" } */
#include "apx-push2pop2-1.c"
diff --git a/gcc/testsuite/gcc.target/i386/float16-8.c b/gcc/testsuite/gcc.target/i386/float16-8.c
new file mode 100644
index 0000000..003f82e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/float16-8.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mno-sse" } */
+/* PR c/111903 */
+
+int i;
+_Float16 f;
+int bar(...);
+void
+foo (void)
+{
+ i /= bar ((_Complex _Float16) f); /* { dg-error "" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
index eae6b13..210da1d 100644
--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc
+++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
@@ -218,7 +218,8 @@ extern void test_arch_graniterapids_d (void) __attribute__((__target__("arch=gra
extern void test_arch_arrowlake (void) __attribute__((__target__("arch=arrowlake")));
extern void test_arch_arrowlake_s (void) __attribute__((__target__("arch=arrowlake-s")));
extern void test_arch_pantherlake (void) __attribute__((__target__("arch=pantherlake")));
-extern void test_arch_lujiazui (void) __attribute__((__target__("arch=lujiazui")));
+extern void test_arch_lujiazui (void) __attribute__((__target__("arch=lujiazui")));
+extern void test_arch_yongfeng (void) __attribute__((__target__("arch=yongfeng")));
extern void test_arch_k8 (void) __attribute__((__target__("arch=k8")));
extern void test_arch_k8_sse3 (void) __attribute__((__target__("arch=k8-sse3")));
extern void test_arch_opteron (void) __attribute__((__target__("arch=opteron")));
@@ -241,7 +242,8 @@ extern void test_tune_core2 (void) __attribute__((__target__("tune=core2")));
extern void test_tune_corei7 (void) __attribute__((__target__("tune=corei7")));
extern void test_tune_corei7_avx (void) __attribute__((__target__("tune=corei7-avx")));
extern void test_tune_core_avx2 (void) __attribute__((__target__("tune=core-avx2")));
-extern void test_tune_lujiazui (void) __attribute__((__target__("tune=lujiazui")));
+extern void test_tune_lujiazui (void) __attribute__((__target__("tune=lujiazui")));
+extern void test_tune_yongfeng (void) __attribute__((__target__("tune=yongfeng")));
extern void test_tune_k8 (void) __attribute__((__target__("tune=k8")));
extern void test_tune_k8_sse3 (void) __attribute__((__target__("tune=k8-sse3")));
extern void test_tune_opteron (void) __attribute__((__target__("tune=opteron")));
diff --git a/gcc/testsuite/gcc.target/i386/large-data.c b/gcc/testsuite/gcc.target/i386/large-data.c
index bdd4acd..164b38b 100644
--- a/gcc/testsuite/gcc.target/i386/large-data.c
+++ b/gcc/testsuite/gcc.target/i386/large-data.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-require-effective-target lp64 } */
/* { dg-options "-O2 -mcmodel=large -mlarge-data-threshold=4" } */
+/* { dg-skip-if "PR90698" "*-*-darwin*" } */
/* { dg-final { scan-assembler {\.lbss} } } */
/* { dg-final { scan-assembler {\.bss} } } */
/* { dg-final { scan-assembler {\.ldata} } } */
diff --git a/gcc/testsuite/gcc.target/i386/part-vect-vec_cmphf.c b/gcc/testsuite/gcc.target/i386/part-vect-vec_cmphf.c
new file mode 100644
index 0000000..ee86593
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/part-vect-vec_cmphf.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512fp16 -mavx512vl" } */
+/* { dg-final { scan-assembler-times "vcmpph" 10 } } */
+
+typedef _Float16 __attribute__((__vector_size__ (4))) v2hf;
+typedef _Float16 __attribute__((__vector_size__ (8))) v4hf;
+
+
+#define VCMPMN(type, op, name) \
+type \
+__attribute__ ((noinline, noclone)) \
+vec_cmp_##type##type##name (type a, type b) \
+{ \
+ return a op b; \
+}
+
+VCMPMN (v4hf, <, lt)
+VCMPMN (v2hf, <, lt)
+VCMPMN (v4hf, <=, le)
+VCMPMN (v2hf, <=, le)
+VCMPMN (v4hf, >, gt)
+VCMPMN (v2hf, >, gt)
+VCMPMN (v4hf, >=, ge)
+VCMPMN (v2hf, >=, ge)
+VCMPMN (v4hf, ==, eq)
+VCMPMN (v2hf, ==, eq)
diff --git a/gcc/testsuite/gcc.target/i386/pr103144-mul-1.c b/gcc/testsuite/gcc.target/i386/pr103144-mul-1.c
index 640c34f..913d773 100644
--- a/gcc/testsuite/gcc.target/i386/pr103144-mul-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr103144-mul-1.c
@@ -11,7 +11,7 @@ foo_mul (int* a, int b)
for (int i = 0; i != N; i++)
{
a[i] = b;
- b *= 3;
+ b *= 4;
}
}
@@ -23,7 +23,7 @@ foo_mul_const (int* a)
for (int i = 0; i != N; i++)
{
a[i] = b;
- b *= 3;
+ b *= 4;
}
}
@@ -34,7 +34,7 @@ foo_mul_peel (int* a, int b)
for (int i = 0; i != 39; i++)
{
a[i] = b;
- b *= 3;
+ b *= 4;
}
}
@@ -46,6 +46,6 @@ foo_mul_peel_const (int* a)
for (int i = 0; i != 39; i++)
{
a[i] = b;
- b *= 3;
+ b *= 4;
}
}
diff --git a/gcc/testsuite/gcc.target/i386/pr103144-mul-2.c b/gcc/testsuite/gcc.target/i386/pr103144-mul-2.c
index 39fdea3..b2ff186 100644
--- a/gcc/testsuite/gcc.target/i386/pr103144-mul-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr103144-mul-2.c
@@ -16,12 +16,12 @@ avx2_test (void)
__builtin_memset (epi32_exp, 0, N * sizeof (int));
int b = 8;
- v8si init = __extension__(v8si) { b, b * 3, b * 9, b * 27, b * 81, b * 243, b * 729, b * 2187 };
+ v8si init = __extension__(v8si) { b, b * 4, b * 16, b * 64, b * 256, b * 1024, b * 4096, b * 16384 };
for (int i = 0; i != N / 8; i++)
{
memcpy (epi32_exp + i * 8, &init, 32);
- init *= 6561;
+ init *= 65536;
}
foo_mul (epi32_dst, b);
@@ -32,11 +32,11 @@ avx2_test (void)
if (__builtin_memcmp (epi32_dst, epi32_exp, 39 * 4) != 0)
__builtin_abort ();
- init = __extension__(v8si) { 1, 3, 9, 27, 81, 243, 729, 2187 };
+ init = __extension__(v8si) { 1, 4, 16, 64, 256, 1024, 4096, 16384 };
for (int i = 0; i != N / 8; i++)
{
memcpy (epi32_exp + i * 8, &init, 32);
- init *= 6561;
+ init *= 65536;
}
foo_mul_const (epi32_dst);
diff --git a/gcc/testsuite/gcc.target/i386/pr104610-2.c b/gcc/testsuite/gcc.target/i386/pr104610-2.c
new file mode 100644
index 0000000..999ef92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr104610-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512f -O2 -mtune=generic" } */
+/* { dg-final { scan-assembler-times {(?n)vpcmpeq.*zmm} 2 } } */
+/* { dg-final { scan-assembler-times {(?n)kortest.*k[0-7]} 2 } } */
+
+int compare (const char* s1, const char* s2)
+{
+ return __builtin_memcmp (s1, s2, 64) == 0;
+}
+
+int compare1 (const char* s1, const char* s2)
+{
+ return __builtin_memcmp (s1, s2, 64) != 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr105554.c b/gcc/testsuite/gcc.target/i386/pr105554.c
index 08e90bb..e9ef494 100644
--- a/gcc/testsuite/gcc.target/i386/pr105554.c
+++ b/gcc/testsuite/gcc.target/i386/pr105554.c
@@ -1,5 +1,6 @@
/* PR target/105554 */
/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
/* { dg-options "-O2 -Wno-psabi -mno-sse3" } */
typedef long long v4di __attribute__((__vector_size__(32)));
diff --git a/gcc/testsuite/gcc.target/i386/pr110551-2.c b/gcc/testsuite/gcc.target/i386/pr110551-2.c
new file mode 100644
index 0000000..4936adf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr110551-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -march=haswell" } */
+
+typedef unsigned long long uint64_t;
+
+uint64_t mulx64(uint64_t x)
+{
+ __uint128_t r = (__uint128_t)x * 0x9E3779B97F4A7C15ull;
+ return (uint64_t)r ^ (uint64_t)( r >> 64 );
+}
+
+/* { dg-final { scan-assembler-not "movq" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr110551.c b/gcc/testsuite/gcc.target/i386/pr110551.c
new file mode 100644
index 0000000..142b808
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr110551.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+typedef unsigned long long uint64_t;
+
+uint64_t mulx64(uint64_t x)
+{
+ __uint128_t r = (__uint128_t)x * 0x9E3779B97F4A7C15ull;
+ return (uint64_t)r ^ (uint64_t)( r >> 64 );
+}
+
+/* { dg-final { scan-assembler-not "movq" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr111698.c b/gcc/testsuite/gcc.target/i386/pr111698.c
new file mode 100644
index 0000000..0370007
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr111698.c
@@ -0,0 +1,19 @@
+/* PR target/111698 */
+/* { dg-options "-O2 -masm=att -march=sandybridge" } */
+/* { dg-final { scan-assembler-not "testl" } } */
+
+int m;
+
+_Bool foo (void)
+{
+ return m & 0x0a0000;
+}
+
+/* { dg-final { scan-assembler-times "testb" 1 } } */
+
+_Bool bar (void)
+{
+ return m & 0xa0a000;
+}
+
+/* { dg-final { scan-assembler-times "testw" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr111753.c b/gcc/testsuite/gcc.target/i386/pr111753.c
new file mode 100644
index 0000000..16ceca6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr111753.c
@@ -0,0 +1,69 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512bw -fno-tree-ter -Wno-div-by-zero" } */
+
+typedef int __attribute__((__vector_size__ (8))) v64u8;
+typedef char __attribute__((__vector_size__ (16))) v128u8;
+typedef int __attribute__((__vector_size__ (16))) v128u32;
+typedef int __attribute__((__vector_size__ (32))) v256u8;
+typedef int __attribute__((__vector_size__ (64))) v512u8;
+typedef short __attribute__((__vector_size__ (4))) v32s16;
+typedef short __attribute__((__vector_size__ (16))) v128s16;
+typedef short __attribute__((__vector_size__ (32))) v256s16;
+typedef _Float16 __attribute__((__vector_size__ (16))) f16;
+typedef _Float32 f32;
+typedef double __attribute__((__vector_size__ (64))) v512f64;
+typedef _Decimal32 d32;
+typedef _Decimal64 __attribute__((__vector_size__ (32))) v256d64;
+typedef _Decimal64 __attribute__((__vector_size__ (64))) v512d64;
+d32 foo0_d32_0, foo0_ret;
+v256d64 foo0_v256d64_0;
+v128s16 foo0_v128s16_0;
+int foo0_v256d128_0;
+
+extern void bar(int);
+
+void
+foo (v64u8, v128u8 v128u8_0, v128u8 v128s8_0,
+ v256u8 v256u8_0, int v256s8_0, v512u8 v512u8_0, int v512s8_0,
+ v256s16 v256s16_0,
+ v512u8 v512s16_0,
+ v128u32 v128u64_0,
+ v128u32 v128s64_0,
+ int, int, __int128 v128u128_0, __int128 v128s128_0, v128u32 v128f64_0)
+{
+ v512d64 v512d64_0;
+ v256u8 v256f32_0, v256d64_1 = foo0_v256d64_0 == foo0_d32_0;
+ f32 f32_0;
+ f16 v128f16_0;
+ f32_0 /= 0;
+ v128u8 v128u8_1 = v128u8_0 != 0;
+ int v256d32_1;
+ v256f32_0 /= 0;
+ v32s16 v32s16_1 = __builtin_shufflevector ((v128s16) { }, v256s16_0, 5, 10);
+ v512f64 v512f64_1 = __builtin_convertvector (v512d64_0, v512f64);
+ v512u8 v512d128_1 = v512s16_0;
+ v128s16 v128s16_2 =
+ __builtin_shufflevector ((v32s16) { }, v32s16_1, 0, 3, 2, 1,
+ 0, 0, 0, 3), v128s16_3 = foo0_v128s16_0 > 0;
+ v128f16_0 /= 0;
+ __int128 v128s128_1 = 0 == v128s128_0;
+ v512u8 v512u8_r = v512u8_0 + v512s8_0 + (v512u8) v512f64_1 + v512s16_0;
+ v256u8 v256u8_r = ((union {
+ v512u8 a;
+ v256u8 b;}) v512u8_r).b +
+ v256u8_0 + v256s8_0 + v256f32_0 + v256d32_1 +
+ (v256u8) v256d64_1 + foo0_v256d128_0;
+ v128u8 v128u8_r = ((union {
+ v256u8 a;
+ v128u8 b;}) v256u8_r).b +
+ v128u8_0 + v128u8_1 + v128s8_0 + (v128u8) v128s16_2 +
+ (v128u8) v128s16_3 + (v128u8) v128u64_0 + (v128u8) v128s64_0 +
+ (v128u8) v128u128_0 + (v128u8) v128s128_1 +
+ (v128u8) v128f16_0 + (v128u8) v128f64_0;
+ bar (f32_0 + (int) foo0_d32_0);
+ foo0_ret = ((union {
+ v64u8 a;
+ int b;}) ((union {
+ v128u8 a;
+ v64u8 b;}) v128u8_r).b).b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr111820-1.c b/gcc/testsuite/gcc.target/i386/pr111820-1.c
new file mode 100644
index 0000000..50e960c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr111820-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx2 -fno-tree-vrp -Wno-aggressive-loop-optimizations -fdump-tree-vect-details" } */
+/* { dg-final { scan-tree-dump "Avoid compile time hog on vect_peel_nonlinear_iv_init for nonlinear induction vec_step_op_mul when iteration count is too big" "vect" } } */
+
+int r;
+int r_0;
+
+void f1 (void)
+{
+ int n = 0;
+ while (-- n)
+ {
+ r_0 += r;
+ r *= 3;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr111820-2.c b/gcc/testsuite/gcc.target/i386/pr111820-2.c
new file mode 100644
index 0000000..dbeceb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr111820-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx2 -fno-tree-vrp -fdump-tree-vect-details -Wno-aggressive-loop-optimizations" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+int r;
+int r_0;
+
+void f (void)
+{
+ int n = 0;
+ while (-- n)
+ {
+ r_0 += r ;
+ r *= 2;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr111820-3.c b/gcc/testsuite/gcc.target/i386/pr111820-3.c
new file mode 100644
index 0000000..b778f51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr111820-3.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx2 -fno-tree-vrp -fdump-tree-vect-details -Wno-aggressive-loop-optimizations" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+int r;
+int r_0;
+
+void f (void)
+{
+ int n = 14;
+ while (-- n)
+ {
+ r_0 += r ;
+ r *= 3;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr112276.c b/gcc/testsuite/gcc.target/i386/pr112276.c
new file mode 100644
index 0000000..5365313
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112276.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse4.1" } */
+/* { dg-require-effective-target sse4 } */
+
+#include "sse4_1-check.h"
+
+typedef unsigned short __attribute__((__vector_size__ (8))) U4;
+typedef unsigned short __attribute__((__vector_size__ (4))) U2;
+
+U4
+__attribute__((noipa))
+foo4 (U4 a, U4 b)
+{
+ return a > b;
+}
+
+U2
+__attribute__((noipa))
+foo2 (U2 a, U2 b)
+{
+ return a > b;
+}
+
+static void
+sse4_1_test ()
+{
+ U4 a = __extension__(U4) {1, 1, 1, 1};
+ U4 b = foo4 (a, a);
+ if (b[0] || b[1] || b[2] || b[3]) __builtin_abort();
+
+ U2 c = __extension__(U2) {1, 1};
+ U2 d = foo2 (c, c);
+ if (d[0] || d[1]) __builtin_abort();
+
+ return;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr87299-1.c b/gcc/testsuite/gcc.target/i386/pr87299-1.c
new file mode 100644
index 0000000..38d4c3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr87299-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
diff --git a/gcc/testsuite/gcc.target/i386/pr87299-2.c b/gcc/testsuite/gcc.target/i386/pr87299-2.c
new file mode 100644
index 0000000..263dfb7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr87299-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-save-temps -mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
diff --git a/gcc/testsuite/gcc.target/loongarch/builtin_thread_pointer.c b/gcc/testsuite/gcc.target/loongarch/builtin_thread_pointer.c
new file mode 100644
index 0000000..541e3b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/builtin_thread_pointer.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "or\t\\\$r4,\\\$r2,\\\$r0" } } */
+
+void *
+get_tp ()
+{
+ return __builtin_thread_pointer ();
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-lto.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-lto.c
new file mode 100644
index 0000000..f53b546
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-lto.c
@@ -0,0 +1,26 @@
+/* { dg-do link } */
+/* { dg-require-effective-target lto } */
+/* { dg-require-linker-plugin "" } */
+/* { dg-options "-fpic -shared -O2 --save-temps -mexplicit-relocs=auto -flto -fuse-linker-plugin -flto-partition=one" } */
+
+int pcrel __attribute__ ((visibility ("hidden")));
+int got __attribute__ ((visibility ("default")));
+
+int
+*addr_pcrel (void)
+{
+ return &pcrel;
+}
+
+int
+*addr_got (void)
+{
+ return &got;
+}
+
+/* With linker plugin we should use la.local (it can be relaxed to pcaddi),
+ but not la.global (we are pretty sure the linker cannot relax la.global
+ got). */
+/* { dg-final { scan-lto-assembler "la.local.*pcrel" } } */
+/* { dg-final { scan-lto-assembler "pcalau12i.*%got_pc_hi20\\\(got\\\)" } } */
+/* { dg-final { scan-lto-assembler "ld.*%got_pc_lo12\\\(got\\\)" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c
new file mode 100644
index 0000000..fb03403
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mexplicit-relocs=auto -fno-section-anchors" } */
+
+#include "explicit-relocs-auto-single-load-store.c"
+
+/* { dg-final { scan-assembler-not "la.local" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c
new file mode 100644
index 0000000..0d53644
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mexplicit-relocs=auto" } */
+
+long a;
+int b;
+unsigned int c;
+
+long load_a() { return a; }
+long load_b() { return b; }
+long load_c() { return c; }
+void store_a(long x) { a = x; }
+void store_b(int x) { b = x; }
+
+/* { dg-final { scan-assembler-not "la.local" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c
new file mode 100644
index 0000000..957ff98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto" } */
+
+__thread int a __attribute__((visibility("hidden")));
+extern __thread int b __attribute__((visibility("default")));
+
+int test() { return a + b; }
+
+/* { dg-final { scan-assembler-not "la.tls" { target tls_native } } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-le-ie.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-le-ie.c
new file mode 100644
index 0000000..78898cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-le-ie.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mexplicit-relocs=auto" } */
+
+#include "explicit-relocs-auto-tls-ld-gd.c"
+
+/* { dg-final { scan-assembler-not "la.tls" { target tls_native } } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-1.c
new file mode 100644
index 0000000..ee9cb1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-1.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-unroll-loops -fno-vect-cost-model -mlasx" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_VCOND_VAR(DATA_TYPE, CMP_TYPE, COND, SUFFIX) \
+ void __attribute__ ((noinline, noclone)) \
+ vcond_var_##CMP_TYPE##_##SUFFIX (DATA_TYPE *__restrict__ r, \
+ DATA_TYPE *__restrict__ x, \
+ DATA_TYPE *__restrict__ y, \
+ CMP_TYPE *__restrict__ a, \
+ CMP_TYPE *__restrict__ b, \
+ int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ { \
+ DATA_TYPE xval = x[i], yval = y[i]; \
+ CMP_TYPE aval = a[i], bval = b[i]; \
+ r[i] = aval COND bval ? xval : yval; \
+ } \
+ }
+
+#define TEST_COND_VAR_SIGNED_ALL(T, COND, SUFFIX) \
+ T (int8_t, int8_t, COND, SUFFIX) \
+ T (int16_t, int16_t, COND, SUFFIX) \
+ T (int32_t, int32_t, COND, SUFFIX) \
+ T (int64_t, int64_t, COND, SUFFIX) \
+ T (float, int32_t, COND, SUFFIX##_float) \
+ T (double, int64_t, COND, SUFFIX##_double)
+
+#define TEST_COND_VAR_UNSIGNED_ALL(T, COND, SUFFIX) \
+ T (uint8_t, uint8_t, COND, SUFFIX) \
+ T (uint16_t, uint16_t, COND, SUFFIX) \
+ T (uint32_t, uint32_t, COND, SUFFIX) \
+ T (uint64_t, uint64_t, COND, SUFFIX) \
+ T (float, uint32_t, COND, SUFFIX##_float) \
+ T (double, uint64_t, COND, SUFFIX##_double)
+
+#define TEST_COND_VAR_ALL(T, COND, SUFFIX) \
+ TEST_COND_VAR_SIGNED_ALL (T, COND, SUFFIX) \
+ TEST_COND_VAR_UNSIGNED_ALL (T, COND, SUFFIX)
+
+#define TEST_VAR_ALL(T) \
+ TEST_COND_VAR_ALL (T, >, _gt) \
+ TEST_COND_VAR_ALL (T, <, _lt) \
+ TEST_COND_VAR_ALL (T, >=, _ge) \
+ TEST_COND_VAR_ALL (T, <=, _le) \
+ TEST_COND_VAR_ALL (T, ==, _eq) \
+ TEST_COND_VAR_ALL (T, !=, _ne)
+
+TEST_VAR_ALL (DEF_VCOND_VAR)
+
+/* { dg-final { scan-assembler-times {\txvslt\.b} 4 } } */
+/* { dg-final { scan-assembler-times {\txvslt\.h} 4 } } */
+/* { dg-final { scan-assembler-times {\txvslt\.w} 4 } } */
+/* { dg-final { scan-assembler-times {\txvslt\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\txvsle\.b} 4 } } */
+/* { dg-final { scan-assembler-times {\txvsle\.h} 4 } } */
+/* { dg-final { scan-assembler-times {\txvsle\.w} 4 } } */
+/* { dg-final { scan-assembler-times {\txvsle\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\txvseq\.b} 4 } } */
+/* { dg-final { scan-assembler-times {\txvseq\.h} 4 } } */
+/* { dg-final { scan-assembler-times {\txvseq\.w} 4 } } */
+/* { dg-final { scan-assembler-times {\txvseq\.d} 4 } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-2.c
new file mode 100644
index 0000000..5f40ed4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-2.c
@@ -0,0 +1,87 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -mlasx" } */
+
+#include <stdint-gcc.h>
+
+#define eq(A, B) ((A) == (B))
+#define ne(A, B) ((A) != (B))
+#define olt(A, B) ((A) < (B))
+#define ole(A, B) ((A) <= (B))
+#define oge(A, B) ((A) >= (B))
+#define ogt(A, B) ((A) > (B))
+#define ordered(A, B) (!__builtin_isunordered (A, B))
+#define unordered(A, B) (__builtin_isunordered (A, B))
+#define ueq(A, B) (!__builtin_islessgreater (A, B))
+#define ult(A, B) (__builtin_isless (A, B))
+#define ule(A, B) (__builtin_islessequal (A, B))
+#define uge(A, B) (__builtin_isgreaterequal (A, B))
+#define ugt(A, B) (__builtin_isgreater (A, B))
+#define nueq(A, B) (__builtin_islessgreater (A, B))
+#define nult(A, B) (!__builtin_isless (A, B))
+#define nule(A, B) (!__builtin_islessequal (A, B))
+#define nuge(A, B) (!__builtin_isgreaterequal (A, B))
+#define nugt(A, B) (!__builtin_isgreater (A, B))
+
+#define TEST_LOOP(TYPE1, TYPE2, CMP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE1##_##TYPE2##_##CMP##_var (TYPE1 *restrict dest, \
+ TYPE1 *restrict src, \
+ TYPE1 fallback, \
+ TYPE2 *restrict a, \
+ TYPE2 *restrict b, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ {\
+ TYPE2 aval = a[i]; \
+ TYPE2 bval = b[i]; \
+ TYPE1 srcval = src[i]; \
+ dest[i] = CMP (aval, bval) ? srcval : fallback; \
+ }\
+ }
+
+#define TEST_CMP(CMP) \
+ TEST_LOOP (int32_t, float, CMP) \
+ TEST_LOOP (uint32_t, float, CMP) \
+ TEST_LOOP (float, float, CMP) \
+ TEST_LOOP (int64_t, double, CMP) \
+ TEST_LOOP (uint64_t, double, CMP) \
+ TEST_LOOP (double, double, CMP)
+
+TEST_CMP (eq)
+TEST_CMP (ne)
+TEST_CMP (olt)
+TEST_CMP (ole)
+TEST_CMP (oge)
+TEST_CMP (ogt)
+TEST_CMP (ordered)
+TEST_CMP (unordered)
+TEST_CMP (ueq)
+TEST_CMP (ult)
+TEST_CMP (ule)
+TEST_CMP (uge)
+TEST_CMP (ugt)
+TEST_CMP (nueq)
+TEST_CMP (nult)
+TEST_CMP (nule)
+TEST_CMP (nuge)
+TEST_CMP (nugt)
+
+/* { dg-final { scan-assembler-times {\txvfcmp\.ceq\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.ceq\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cne\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cne\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.slt\.s} 4 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.slt\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.sle\.s} 4 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.sle\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cor\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cor\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cun\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cun\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cueq\.s} 4 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cueq\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cule\.s} 8 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cule\.d} 8 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cult\.s} 8 } } */
+/* { dg-final { scan-assembler-times {\txvfcmp\.cult\.d} 8 } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-1.c
new file mode 100644
index 0000000..138adcc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-1.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-unroll-loops -fno-vect-cost-model -mlsx" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_VCOND_VAR(DATA_TYPE, CMP_TYPE, COND, SUFFIX) \
+ void __attribute__ ((noinline, noclone)) \
+ vcond_var_##CMP_TYPE##_##SUFFIX (DATA_TYPE *__restrict__ r, \
+ DATA_TYPE *__restrict__ x, \
+ DATA_TYPE *__restrict__ y, \
+ CMP_TYPE *__restrict__ a, \
+ CMP_TYPE *__restrict__ b, \
+ int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ { \
+ DATA_TYPE xval = x[i], yval = y[i]; \
+ CMP_TYPE aval = a[i], bval = b[i]; \
+ r[i] = aval COND bval ? xval : yval; \
+ } \
+ }
+
+#define TEST_COND_VAR_SIGNED_ALL(T, COND, SUFFIX) \
+ T (int8_t, int8_t, COND, SUFFIX) \
+ T (int16_t, int16_t, COND, SUFFIX) \
+ T (int32_t, int32_t, COND, SUFFIX) \
+ T (int64_t, int64_t, COND, SUFFIX) \
+ T (float, int32_t, COND, SUFFIX##_float) \
+ T (double, int64_t, COND, SUFFIX##_double)
+
+#define TEST_COND_VAR_UNSIGNED_ALL(T, COND, SUFFIX) \
+ T (uint8_t, uint8_t, COND, SUFFIX) \
+ T (uint16_t, uint16_t, COND, SUFFIX) \
+ T (uint32_t, uint32_t, COND, SUFFIX) \
+ T (uint64_t, uint64_t, COND, SUFFIX) \
+ T (float, uint32_t, COND, SUFFIX##_float) \
+ T (double, uint64_t, COND, SUFFIX##_double)
+
+#define TEST_COND_VAR_ALL(T, COND, SUFFIX) \
+ TEST_COND_VAR_SIGNED_ALL (T, COND, SUFFIX) \
+ TEST_COND_VAR_UNSIGNED_ALL (T, COND, SUFFIX)
+
+#define TEST_VAR_ALL(T) \
+ TEST_COND_VAR_ALL (T, >, _gt) \
+ TEST_COND_VAR_ALL (T, <, _lt) \
+ TEST_COND_VAR_ALL (T, >=, _ge) \
+ TEST_COND_VAR_ALL (T, <=, _le) \
+ TEST_COND_VAR_ALL (T, ==, _eq) \
+ TEST_COND_VAR_ALL (T, !=, _ne)
+
+TEST_VAR_ALL (DEF_VCOND_VAR)
+
+/* { dg-final { scan-assembler-times {\tvslt\.b} 4 } } */
+/* { dg-final { scan-assembler-times {\tvslt\.h} 4 } } */
+/* { dg-final { scan-assembler-times {\tvslt\.w} 4 } } */
+/* { dg-final { scan-assembler-times {\tvslt\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\tvsle\.b} 4 } } */
+/* { dg-final { scan-assembler-times {\tvsle\.h} 4 } } */
+/* { dg-final { scan-assembler-times {\tvsle\.w} 4 } } */
+/* { dg-final { scan-assembler-times {\tvsle\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\tvseq\.b} 4 } } */
+/* { dg-final { scan-assembler-times {\tvseq\.h} 4 } } */
+/* { dg-final { scan-assembler-times {\tvseq\.w} 4 } } */
+/* { dg-final { scan-assembler-times {\tvseq\.d} 4 } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-2.c
new file mode 100644
index 0000000..e8fe31f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vcond-2.c
@@ -0,0 +1,87 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -mlsx" } */
+
+#include <stdint-gcc.h>
+
+#define eq(A, B) ((A) == (B))
+#define ne(A, B) ((A) != (B))
+#define olt(A, B) ((A) < (B))
+#define ole(A, B) ((A) <= (B))
+#define oge(A, B) ((A) >= (B))
+#define ogt(A, B) ((A) > (B))
+#define ordered(A, B) (!__builtin_isunordered (A, B))
+#define unordered(A, B) (__builtin_isunordered (A, B))
+#define ueq(A, B) (!__builtin_islessgreater (A, B))
+#define ult(A, B) (__builtin_isless (A, B))
+#define ule(A, B) (__builtin_islessequal (A, B))
+#define uge(A, B) (__builtin_isgreaterequal (A, B))
+#define ugt(A, B) (__builtin_isgreater (A, B))
+#define nueq(A, B) (__builtin_islessgreater (A, B))
+#define nult(A, B) (!__builtin_isless (A, B))
+#define nule(A, B) (!__builtin_islessequal (A, B))
+#define nuge(A, B) (!__builtin_isgreaterequal (A, B))
+#define nugt(A, B) (!__builtin_isgreater (A, B))
+
+#define TEST_LOOP(TYPE1, TYPE2, CMP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE1##_##TYPE2##_##CMP##_var (TYPE1 *restrict dest, \
+ TYPE1 *restrict src, \
+ TYPE1 fallback, \
+ TYPE2 *restrict a, \
+ TYPE2 *restrict b, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ {\
+ TYPE2 aval = a[i]; \
+ TYPE2 bval = b[i]; \
+ TYPE1 srcval = src[i]; \
+ dest[i] = CMP (aval, bval) ? srcval : fallback; \
+ }\
+ }
+
+#define TEST_CMP(CMP) \
+ TEST_LOOP (int32_t, float, CMP) \
+ TEST_LOOP (uint32_t, float, CMP) \
+ TEST_LOOP (float, float, CMP) \
+ TEST_LOOP (int64_t, double, CMP) \
+ TEST_LOOP (uint64_t, double, CMP) \
+ TEST_LOOP (double, double, CMP)
+
+TEST_CMP (eq)
+TEST_CMP (ne)
+TEST_CMP (olt)
+TEST_CMP (ole)
+TEST_CMP (oge)
+TEST_CMP (ogt)
+TEST_CMP (ordered)
+TEST_CMP (unordered)
+TEST_CMP (ueq)
+TEST_CMP (ult)
+TEST_CMP (ule)
+TEST_CMP (uge)
+TEST_CMP (ugt)
+TEST_CMP (nueq)
+TEST_CMP (nult)
+TEST_CMP (nule)
+TEST_CMP (nuge)
+TEST_CMP (nugt)
+
+/* { dg-final { scan-assembler-times {\tvfcmp\.ceq\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.ceq\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cne\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cne\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.slt\.s} 4 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.slt\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.sle\.s} 4 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.sle\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cor\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cor\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cun\.s} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cun\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cueq\.s} 4 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cueq\.d} 4 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cule\.s} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cule\.d} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cult\.s} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfcmp\.cult\.d} 8 } } */
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/bshift.c b/gcc/testsuite/gcc.target/microblaze/isa/bshift.c
index 64cf1e2..664586b 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/bshift.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/bshift.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mxl-barrel-shift" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mxl-barrel-shift" } */
volatile int m1, m2, m3;
volatile unsigned int u1, u2, u3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/div.c b/gcc/testsuite/gcc.target/microblaze/isa/div.c
index 25ee42c..783e7c0 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/div.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/div.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mno-xl-soft-div" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mno-xl-soft-div" } */
volatile int m1, m2, m3;
volatile long l1, l2;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/fcmp1.c b/gcc/testsuite/gcc.target/microblaze/isa/fcmp1.c
index 4041a24..b6202e1 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/fcmp1.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/fcmp1.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mhard-float" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mhard-float" } */
volatile float f1, f2, f3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/fcmp2.c b/gcc/testsuite/gcc.target/microblaze/isa/fcmp2.c
index 3902b83..4386c6e 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/fcmp2.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/fcmp2.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mhard-float" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mhard-float" } */
volatile float f1, f2, f3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/fcmp3.c b/gcc/testsuite/gcc.target/microblaze/isa/fcmp3.c
index 8555974..b414e48 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/fcmp3.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/fcmp3.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mhard-float" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mhard-float" } */
volatile float f1, f2, f3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/fcmp4.c b/gcc/testsuite/gcc.target/microblaze/isa/fcmp4.c
index 79cc5f9..ff13701 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/fcmp4.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/fcmp4.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mhard-float" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mhard-float" } */
void float_func(float f1, float f2, float f3)
{
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/fcvt.c b/gcc/testsuite/gcc.target/microblaze/isa/fcvt.c
index ee057c1..90fd45b 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/fcvt.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/fcvt.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mhard-float -mxl-float-convert" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mhard-float -mxl-float-convert" } */
int float_func (float f)
{
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/float.c b/gcc/testsuite/gcc.target/microblaze/isa/float.c
index f5ef318..212435d 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/float.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/float.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mhard-float" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mhard-float" } */
volatile float f1, f2, f3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/fsqrt.c b/gcc/testsuite/gcc.target/microblaze/isa/fsqrt.c
index 4c2466e..834767d 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/fsqrt.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/fsqrt.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mhard-float -mxl-float-sqrt" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mhard-float -mxl-float-sqrt" } */
#include <math.h>
float sqrt_func (float f)
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift-pcmp.c b/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift-pcmp.c
index ce18631..2720ad3 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift-pcmp.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift-pcmp.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mxl-barrel-shift -mno-xl-soft-mul -mxl-pattern-compare" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mxl-barrel-shift -mno-xl-soft-mul -mxl-pattern-compare" } */
volatile int m1, m2, m3;
volatile unsigned int u1, u2, u3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift.c b/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift.c
index 76d174e..59a17c7 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/mul-bshift.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mxl-barrel-shift -mno-xl-soft-mul" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mxl-barrel-shift -mno-xl-soft-mul" } */
volatile int m1, m2, m3;
volatile unsigned int u1, u2, u3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/mul.c b/gcc/testsuite/gcc.target/microblaze/isa/mul.c
index d2a6bec..e4e330a 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/mul.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/mul.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mno-xl-soft-mul" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mno-xl-soft-mul" } */
volatile int m1, m2, m3;
volatile long l1, l2;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/mulh-bshift-pcmp.c b/gcc/testsuite/gcc.target/microblaze/isa/mulh-bshift-pcmp.c
index a15983a..0f96203 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/mulh-bshift-pcmp.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/mulh-bshift-pcmp.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mxl-barrel-shift -mno-xl-soft-mul -mxl-pattern-compare -mxl-multiply-high" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mxl-barrel-shift -mno-xl-soft-mul -mxl-pattern-compare -mxl-multiply-high" } */
volatile int m1, m2, m3;
volatile unsigned int u1, u2, u3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/mulh.c b/gcc/testsuite/gcc.target/microblaze/isa/mulh.c
index 6e0cc3ac..da28e8c 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/mulh.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/mulh.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mno-xl-soft-mul -mxl-multiply-high" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mno-xl-soft-mul -mxl-multiply-high" } */
volatile int m1, m2, m3;
volatile unsigned int u1, u2, u3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/nofcmp.c b/gcc/testsuite/gcc.target/microblaze/isa/nofcmp.c
index ebfb170..86910fc 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/nofcmp.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/nofcmp.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a " } */
+/* { dg-options "-O3 -mcpu=v10.0" } */
volatile float f1, f2, f3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/nofloat.c b/gcc/testsuite/gcc.target/microblaze/isa/nofloat.c
index 647da3c..b1f0268 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/nofloat.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/nofloat.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -msoft-float" } */
+/* { dg-options "-O3 -mcpu=v10.0 -msoft-float" } */
volatile float f1, f2, f3;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/pcmp.c b/gcc/testsuite/gcc.target/microblaze/isa/pcmp.c
index aea7957..d9e5793 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/pcmp.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/pcmp.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mxl-pattern-compare" } */
+/* { dg-options "-O3 -mcpu=v10.0 -mxl-pattern-compare" } */
volatile int m1, m2, m3;
volatile long l1, l2;
diff --git a/gcc/testsuite/gcc.target/microblaze/isa/vanilla.c b/gcc/testsuite/gcc.target/microblaze/isa/vanilla.c
index 1d6ba80..35824b6 100644
--- a/gcc/testsuite/gcc.target/microblaze/isa/vanilla.c
+++ b/gcc/testsuite/gcc.target/microblaze/isa/vanilla.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -mcpu=v6.00.a -mcpu=v6.00.a" } */
+/* { dg-options "-O3 -mcpu=v10.0" } */
volatile int m1, m2, m3;
volatile long l1, l2;
diff --git a/gcc/testsuite/gcc.target/microblaze/microblaze.exp b/gcc/testsuite/gcc.target/microblaze/microblaze.exp
index 1c7b0e2..33979ae 100644
--- a/gcc/testsuite/gcc.target/microblaze/microblaze.exp
+++ b/gcc/testsuite/gcc.target/microblaze/microblaze.exp
@@ -49,7 +49,7 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/isa/*.\[cSi\]]] \
${default_c_flags} ""
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/others/*.\[cSi\]]] \
- "" "-mcpu=v6.00.a"
+ "" "-mcpu=v10.0"
# All done.
diff --git a/gcc/testsuite/gcc.target/msp430/pr91865.c b/gcc/testsuite/gcc.target/msp430/pr91865.c
new file mode 100644
index 0000000..8cc21c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/pr91865.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlarge" } */
+
+const int table[2] = {1, 2};
+int foo (char i) { return table[i]; }
+
+/* { dg-final { scan-assembler-not "AND" } } */
+/* { dg-final { scan-assembler-not "RRAM" } } */
diff --git a/gcc/testsuite/gcc.target/nios2/custom-fp-2b.c b/gcc/testsuite/gcc.target/nios2/custom-fp-2b.c
new file mode 100644
index 0000000..ce35c63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nios2/custom-fp-2b.c
@@ -0,0 +1,26 @@
+/* Test specification of custom instructions via pragmas. */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -ffinite-math-only -save-temps" } */
+
+/* -O1 in the options is significant. Without it FP operations may not be
+ optimized to custom instructions. */
+
+#include <stdio.h>
+#include <math.h>
+
+#pragma GCC target ("custom-fmaxs=246")
+#pragma GCC target ("custom-fmins=247")
+#pragma GCC target ("custom-fsqrts=251")
+
+void
+custom_fp (float operand_a, float operand_b, float *result)
+{
+ result[0] = fmaxf (operand_a, operand_b);
+ result[1] = fminf (operand_a, operand_b);
+ result[2] = sqrtf (operand_a);
+}
+
+/* { dg-final { scan-assembler "custom\\t246, .* # fmaxs .*" } } */
+/* { dg-final { scan-assembler "custom\\t247, .* # fmins .*" } } */
+/* { dg-final { scan-assembler "custom\\t251, .* # fsqrts .*" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-3.c b/gcc/testsuite/gcc.target/powerpc/bcd-3.c
index 7948a0c..9891f4f 100644
--- a/gcc/testsuite/gcc.target/powerpc/bcd-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bcd-3.c
@@ -3,7 +3,7 @@
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
/* { dg-final { scan-assembler-times "bcdadd\[.\] " 4 } } */
-/* { dg-final { scan-assembler-times "bcdsub\[.\] " 4 } } */
+/* { dg-final { scan-assembler-times "bcdsub\[.\] " 6 } } */
/* { dg-final { scan-assembler-not "bl __builtin" } } */
/* { dg-final { scan-assembler-not "mtvsr" } } */
/* { dg-final { scan-assembler-not "mfvsr" } } */
@@ -94,6 +94,26 @@ do_sub_gt (vector_128_t a, vector_128_t b, int *p)
}
vector_128_t
+do_sub_ge (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdsub (a, b, 0);
+ if (__builtin_bcdsub_ge (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_sub_le (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdsub (a, b, 0);
+ if (__builtin_bcdsub_le (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
do_sub_ov (vector_128_t a, vector_128_t b, int *p)
{
vector_128_t ret = __builtin_bcdsub (a, b, 0);
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-3b.c b/gcc/testsuite/gcc.target/powerpc/float128-3b.c
new file mode 100644
index 0000000..6b409c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-3b.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mvsx -mno-float128 -save-temps" } */
+#include "float128-3.c"
diff --git a/gcc/testsuite/gcc.target/powerpc/pr111971.c b/gcc/testsuite/gcc.target/powerpc/pr111971.c
new file mode 100644
index 0000000..7f058bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr111971.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+void
+foo (unsigned long long *a)
+{
+ register long long d asm ("r0") = 0x24;
+ long long n;
+ asm ("mr %0, %1" : "=r"(n) : "r"(d));
+ *a++ = n;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-1.c
index 071a339..8ab1a02 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-1.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match Table A.6's recommended mapping. */
/* { dg-options "-O3" } */
+/* { dg-add-options riscv_a } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-2.c
index d6b2d91..a5a841a 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-2.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match Table A.6's recommended mapping. */
/* { dg-options "-O3" } */
+/* { dg-add-options riscv_a } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-3.c
index 68a69ed..f523821 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-3.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match Table A.6's recommended mapping. */
/* { dg-options "-O3" } */
+/* { dg-add-options riscv_a } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-4.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-4.c
index b5cac4c..f1561b5 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-4.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-4.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match Table A.6's recommended mapping. */
/* { dg-options "-O3" } */
+/* { dg-add-options riscv_a } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-5.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-5.c
index 268e58c..81f876e 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-5.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-amo-add-5.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match Table A.6's recommended mapping. */
/* { dg-options "-O3" } */
+/* { dg-add-options riscv_a } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-1.c
index 8349e7a..dc445f0 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-2.c
index bf30b29..7e8ab7b 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-3.c
index 41444ec..4cb6c42 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-3.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-4.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-4.c
index dc2d7bd..da81c34 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-4.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-4.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-5.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-5.c
index 5324621..bb16ccc 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-5.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-5.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-6.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-6.c
index 1376ac2..0f3f0b4 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-6.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-6.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* Mixed mappings need to be unioned. */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-7.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-7.c
index 98083cb..d51de56 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-7.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-compare-exchange-7.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-1.c
index d7d887d..ca8aa71 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-2.c
index 897bad2..e64759a 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-3.c
index 79efca2..9d3f692 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-3.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-4.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-4.c
index 772ac1b..ba32ed5 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-4.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-4.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-5.c b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-5.c
index b0bec66..f9be8c5 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-5.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-a-6-subword-amo-add-5.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match Table A.6's recommended mapping. */
+/* { dg-add-options riscv_a } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-1.c
index a88d08e..65a4351 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-1.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-2.c
index ebd240f..03da6b0 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-2.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-3.c
index ee00d22..695306e 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-3.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-4.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-4.c
index ff08811..e7e5ac7 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-4.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-4.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-5.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-5.c
index b129df4..457d0b1 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-5.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-amo-add-5.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-1.c
index 9d5b8c2..dd6b5c2 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-2.c
index 57d6746..b0bafa3 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-2.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-3.c
index d004410..78cb8aa 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-3.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-4.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-4.c
index 6a53473..0656b84 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-4.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-4.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-5.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-5.c
index 8072909..33d486c 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-5.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-5.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-6.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-6.c
index 731f7f8..f8331bf 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-6.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-6.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-7.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-7.c
index 3806d55..b5c42e1 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-7.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-compare-exchange-7.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that compare exchange mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-1.c
index 81f2f9f..ec008d2 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-1.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that fence mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-2.c
index 8e86889..acef911 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-2.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that fence mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-3.c
index 5eb1aa7..6931ba0 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-3.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that fence mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-4.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-4.c
index 3df959a..b5a0429 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-4.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-4.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that fence mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-5.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-5.c
index 731f9a3..860fb97 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-5.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-fence-5.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that fence mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-1.c
index b911a6e..6319779 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-1.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that load mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-2.c
index 056506f..2c24f10 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-2.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that load mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-3.c
index 35a301f..7d2166d 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-load-3.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that load mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-1.c
index f0bda4b..29a7702 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-1.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that store mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-2.c
index 45f7305..fb82360 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-2.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that store mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-3.c
index 762468b..88d8432 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-store-3.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* Verify that store mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d -O3" } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-1.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-1.c
index e9ae506..3ba69eb 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-1.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-2.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-2.c
index f47922f..4f38ed3 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-2.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-2.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-3.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-3.c
index 296387a..e5bcb12 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-3.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-3.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-4.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-4.c
index f919ede..316183c 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-4.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-4.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-5.c b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-5.c
index 2027a93..fc1aa8d 100644
--- a/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-5.c
+++ b/gcc/testsuite/gcc.target/riscv/amo-table-ztso-subword-amo-add-5.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* Verify that subword atomic op mappings match the Ztso suggested mapping. */
-/* { dg-options "-march=rv64id_ztso -mabi=lp64d" } */
+/* { dg-add-options riscv_ztso } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c
index 01b4390..76c9982 100644
--- a/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c
+++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c
@@ -1,9 +1,10 @@
/* { dg-do compile } */
/* Verify that subword atomics do not generate calls. */
/* { dg-options "-minline-atomics" } */
+/* { dg-add-options riscv_a } */
/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */
/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */
/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */
/* { dg-final { scan-assembler-not "\tcall\t__sync_bool_compare_and_swap_1" } } */
-#include "inline-atomics-1.c" \ No newline at end of file
+#include "inline-atomics-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c
index 709f373..7bab0dd 100644
--- a/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c
+++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c
@@ -2,7 +2,7 @@
/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */
/* Test __atomic routines for existence and proper execution on 1 byte
values with each valid memory model. */
-/* { dg-do run } */
+/* { dg-do run { target { riscv_a } } } */
/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */
/* Test the execution of the __atomic_*OP builtin routines for a char. */
diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c
index eecfaae..4806613 100644
--- a/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c
+++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c
@@ -2,7 +2,7 @@
/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-2.c */
/* Test __atomic routines for existence and proper execution on 2 byte
values with each valid memory model. */
-/* { dg-do run } */
+/* { dg-do run { target { riscv_a } } } */
/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */
/* Test the execution of the __atomic_*OP builtin routines for a short. */
diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c
index 5209389..b677418 100644
--- a/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c
+++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c
@@ -1,7 +1,7 @@
/* Test __atomic routines for existence and proper execution on 1 byte
values with each valid memory model. */
/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-1.c */
-/* { dg-do run } */
+/* { dg-do run { target { riscv_a } } } */
/* { dg-options "-minline-atomics" } */
/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */
diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c
index 8fee8c4..fcf2a13 100644
--- a/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c
+++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c
@@ -1,7 +1,7 @@
/* Test __atomic routines for existence and proper execution on 2 byte
values with each valid memory model. */
/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-2.c */
-/* { dg-do run } */
+/* { dg-do run { target { riscv_a } } } */
/* { dg-options "-minline-atomics" } */
/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */
diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c
index 24c344c..72dc422 100644
--- a/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c
+++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c
@@ -1,7 +1,7 @@
/* Test __atomic routines for existence and proper execution on 1 byte
values with each valid memory model. */
/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-1.c */
-/* { dg-do run } */
+/* { dg-do run { target { riscv_a } } } */
/* { dg-options "-minline-atomics" } */
/* Test the execution of the __atomic_exchange_n builtin for a char. */
diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c
index edc212d..f583e71 100644
--- a/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c
+++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c
@@ -1,7 +1,7 @@
/* Test __atomic routines for existence and proper execution on 2 byte
values with each valid memory model. */
/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-2.c */
-/* { dg-do run } */
+/* { dg-do run { target { riscv_a } } } */
/* { dg-options "-minline-atomics" } */
/* Test the execution of the __atomic_X builtin for a short. */
diff --git a/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c b/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c
index ea562b7..1e1a8be 100644
--- a/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c
+++ b/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c
@@ -26,9 +26,9 @@ f2 (void);
/*
**test1:
** ...
-** cm.push {ra, s0-s4}, -80
+** cm.push {ra, s0-s[1-9]}, -80
** ...
-** cm.popret {ra, s0-s4}, 80
+** cm.popret {ra, s0-s[1-9]}, 80
** ...
*/
int
@@ -50,9 +50,9 @@ test1 ()
/*
**test2_step1_0_size:
** ...
-** cm.push {ra, s0-s1}, -64
+** cm.push {ra, s0-s[1-9]}, -64
** ...
-** cm.popret {ra, s0-s1}, 64
+** cm.popret {ra, s0-s[1-9]}, 64
** ...
*/
int
@@ -70,9 +70,9 @@ test2_step1_0_size ()
/*
**test3:
** ...
-** cm.push {ra, s0-s4}, -80
+** cm.push {ra, s0-s[1-9]}, -80
** ...
-** cm.popret {ra, s0-s4}, 80
+** cm.popret {ra, s0-s[1-9]}, 80
** ...
*/
float
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
new file mode 100644
index 0000000..d635499
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f, float) \
+ T (FN, , double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
new file mode 100644
index 0000000..31661ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
@@ -0,0 +1,47 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+#include "fmax-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ test_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
new file mode 100644
index 0000000..c137955
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
@@ -0,0 +1,23 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f16, _Float16) \
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
new file mode 100644
index 0000000..4a248c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
@@ -0,0 +1,48 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+#include "fmax_zvfh-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ kest_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
new file mode 100644
index 0000000..0d2b53e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
new file mode 100644
index 0000000..19641373
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
new file mode 100644
index 0000000..39643a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
new file mode 100644
index 0000000..05bfce4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/builtin/rawmemchr-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/builtin/rawmemchr-1.c
new file mode 100644
index 0000000..ba83cb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/builtin/rawmemchr-1.c
@@ -0,0 +1,99 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=gnu99 -O2 -ftree-loop-distribution -fdump-tree-ldist-details" } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrQI" 2 "ldist" } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrHI" 2 "ldist" } } */
+/* { dg-final { scan-tree-dump-times "generated rawmemchrSI" 2 "ldist" } } */
+
+#include <string.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define rawmemchrT(T, pattern) \
+__attribute__((noinline,noclone)) \
+T* rawmemchr_##T (T *s) \
+{ \
+ while (*s != pattern) \
+ ++s; \
+ return s; \
+}
+
+rawmemchrT(int8_t, (int8_t)0xde)
+rawmemchrT(uint8_t, 0xde)
+rawmemchrT(int16_t, (int16_t)0xdead)
+rawmemchrT(uint16_t, 0xdead)
+rawmemchrT(int32_t, (int32_t)0xdeadbeef)
+rawmemchrT(uint32_t, 0xdeadbeef)
+
+#define runT(T, pattern) \
+void run_##T () \
+{ \
+ T *buf = malloc (4096 * 2 * sizeof(T)); \
+ assert (buf != NULL); \
+ memset (buf, 0xa, 4096 * 2 * sizeof(T)); \
+ /* ensure q is 4096-byte aligned */ \
+ T *q = (T*)((unsigned char *)buf \
+ + (4096 - ((uintptr_t)buf & 4095))); \
+ T *p; \
+ /* unaligned + block boundary + 1st load */ \
+ p = (T *) ((uintptr_t)q - 8); \
+ p[2] = pattern; \
+ assert ((rawmemchr_##T (&p[0]) == &p[2])); \
+ p[2] = (T) 0xaaaaaaaa; \
+ /* unaligned + block boundary + 2nd load */ \
+ p = (T *) ((uintptr_t)q - 8); \
+ p[6] = pattern; \
+ assert ((rawmemchr_##T (&p[0]) == &p[6])); \
+ p[6] = (T) 0xaaaaaaaa; \
+ /* unaligned + 1st load */ \
+ q[5] = pattern; \
+ assert ((rawmemchr_##T (&q[2]) == &q[5])); \
+ q[5] = (T) 0xaaaaaaaa; \
+ /* unaligned + 2nd load */ \
+ q[14] = pattern; \
+ assert ((rawmemchr_##T (&q[2]) == &q[14])); \
+ q[14] = (T) 0xaaaaaaaa; \
+ /* unaligned + 3rd load */ \
+ q[19] = pattern; \
+ assert ((rawmemchr_##T (&q[2]) == &q[19])); \
+ q[19] = (T) 0xaaaaaaaa; \
+ /* unaligned + 4th load */ \
+ q[25] = pattern; \
+ assert ((rawmemchr_##T (&q[2]) == &q[25])); \
+ q[25] = (T) 0xaaaaaaaa; \
+ /* aligned + 1st load */ \
+ q[5] = pattern; \
+ assert ((rawmemchr_##T (&q[0]) == &q[5])); \
+ q[5] = (T) 0xaaaaaaaa; \
+ /* aligned + 2nd load */ \
+ q[14] = pattern; \
+ assert ((rawmemchr_##T (&q[0]) == &q[14])); \
+ q[14] = (T) 0xaaaaaaaa; \
+ /* aligned + 3rd load */ \
+ q[19] = pattern; \
+ assert ((rawmemchr_##T (&q[0]) == &q[19])); \
+ q[19] = (T) 0xaaaaaaaa; \
+ /* aligned + 4th load */ \
+ q[25] = pattern; \
+ assert ((rawmemchr_##T (&q[0]) == &q[25])); \
+ q[25] = (T) 0xaaaaaaaa; \
+ free (buf); \
+}
+
+runT(int8_t, (int8_t)0xde)
+runT(uint8_t, 0xde)
+runT(int16_t, (int16_t)0xdead)
+runT(uint16_t, 0xdead)
+runT(int32_t, (int32_t)0xdeadbeef)
+runT(uint32_t, 0xdeadbeef)
+
+int main (void)
+{
+ run_uint8_t ();
+ run_int8_t ();
+ run_uint16_t ();
+ run_int16_t ();
+ run_uint32_t ();
+ run_int32_t ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c
index 922be4d..afd73c2 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c
@@ -59,3 +59,4 @@ TEST_ALL
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-10.c
new file mode 100644
index 0000000..f549b9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-10.c
@@ -0,0 +1,63 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(TYPE, NAME, OP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, TYPE *__restrict y, \
+ TYPE *__restrict z, TYPE *__restrict pred, \
+ TYPE *__restrict merged, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] OP z[i] : merged[i]; \
+ }
+
+#define TEST_TYPE(TYPE) \
+ TEST (TYPE, add, +) \
+ TEST (TYPE, sub, -) \
+ TEST (TYPE, mul, *) \
+ TEST (TYPE, div, /)
+
+#define TEST_TYPE2(TYPE) TEST (TYPE, rem, %)
+
+#define TEST_ALL \
+ TEST_TYPE (int8_t) \
+ TEST_TYPE (uint8_t) \
+ TEST_TYPE (int16_t) \
+ TEST_TYPE (uint16_t) \
+ TEST_TYPE (int32_t) \
+ TEST_TYPE (uint32_t) \
+ TEST_TYPE (int64_t) \
+ TEST_TYPE (uint64_t) \
+ TEST_TYPE2 (int8_t) \
+ TEST_TYPE2 (uint8_t) \
+ TEST_TYPE2 (int16_t) \
+ TEST_TYPE2 (uint16_t) \
+ TEST_TYPE2 (int32_t) \
+ TEST_TYPE2 (uint32_t) \
+ TEST_TYPE2 (int64_t) \
+ TEST_TYPE2 (uint64_t) \
+ TEST_TYPE (_Float16) \
+ TEST_TYPE (float) \
+ TEST_TYPE (double)
+
+TEST_ALL
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MOD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_RDIV" 3 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vrem\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vremu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-11.c
new file mode 100644
index 0000000..8b6ae61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-11.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
+
+#include "cond_arith-1.c"
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MOD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 3 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vrem\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vremu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c
index 986a70e..8b6ae61 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c
@@ -28,3 +28,4 @@
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c
index a97d34f..7f7d08a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c
@@ -68,3 +68,4 @@ TEST_ALL
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c
index 30089b7..8b1acea 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c
@@ -22,3 +22,4 @@
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c
index 2f9e883..d659f67 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c
@@ -59,3 +59,4 @@ TEST_ALL
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c
index 13a230c..ef9e365 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c
@@ -28,3 +28,4 @@
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c
index e43f040..48c2a2b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c
@@ -57,3 +57,4 @@ TEST_ALL
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c
index eac77e0..375a7b9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c
@@ -77,3 +77,4 @@ TEST_ALL
/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 22 } } */
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 22 } } */
/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 22 } } */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-10.c
new file mode 100644
index 0000000..8e0d365
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-10.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_arith-10.c"
+
+#define N 99
+
+#undef TEST
+#define TEST(TYPE, NAME, OP) \
+ { \
+ TYPE x[N], y[N], z[N], pred[N], merged[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ z[i] = ((i + 2) % 3) * (i + 1); \
+ pred[i] = i % 3; \
+ merged[i] = i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, pred, merged, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] OP z[i] : merged[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-11.c
new file mode 100644
index 0000000..b2da299
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-11.c
@@ -0,0 +1,4 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_arith_run-10.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-1.c
index bb4873b..07512e5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-1.c
@@ -9,3 +9,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w\tv[0-9]+,v[0-9]+\n} 1 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-2.c
index 4ec20e5..d2d1ea3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv32-2.c
@@ -9,3 +9,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w\tv[0-9]+,v[0-9]+\n} 1 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c
index ec861fe..f793e93 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c
@@ -9,3 +9,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w\tv[0-9]+,v[0-9]+\n} 1 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c
index 455a4b3..79b835a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c
@@ -9,3 +9,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w\tv[0-9]+,v[0-9]+\n} 1 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-1.c
index 9dcbaa9..8cc0170 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-1.c
@@ -15,3 +15,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.x\.f\.w\tv[0-9]+,v[0-9]+\n} 6 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-2.c
index 25d5424..44e9901 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv32-2.c
@@ -15,3 +15,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.x\.f\.w\tv[0-9]+,v[0-9]+\n} 6 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c
index 495f4b5..143e78c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c
@@ -15,3 +15,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.x\.f\.w\tv[0-9]+,v[0-9]+\n} 6 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c
index 520c9df..2d85a48 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c
@@ -15,3 +15,4 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.rtz\.x\.f\.w\tv[0-9]+,v[0-9]+\n} 6 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-1.c
index f5d3bb4..a211192 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-1.c
@@ -12,4 +12,8 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.xu\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.x\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-2.c
index f5d3bb4..a211192 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv32-2.c
@@ -12,4 +12,8 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.xu\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.x\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c
index 5ebed2f..4b35569 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c
@@ -12,4 +12,8 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.xu\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.x\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c
index 097e377..42239ad 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c
@@ -12,4 +12,8 @@
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.xu\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
/* { dg-final { scan-assembler-times {\tvfncvt\.f\.x\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
+
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-1.c
index 8c07e42..84988a7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-1.c
@@ -14,4 +14,4 @@
/* { dg-final { scan-assembler-times {\tvncvt\.x\.x\.w\tv[0-9]+,v[0-9]+\n} 8 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
-
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-2.c
index 74490cd..2b6c72f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv32-2.c
@@ -14,3 +14,4 @@
/* { dg-final { scan-assembler-times {\tvncvt\.x\.x\.w\tv[0-9]+,v[0-9]+\n} 8 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-1.c
index 0035796..e800abe 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-1.c
@@ -14,3 +14,4 @@
/* { dg-final { scan-assembler-times {\tvncvt\.x\.x\.w\tv[0-9]+,v[0-9]+\n} 8 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-2.c
index 3c4ad9c..904e01c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-rv64-2.c
@@ -14,3 +14,4 @@
/* { dg-final { scan-assembler-times {\tvncvt\.x\.x\.w\tv[0-9]+,v[0-9]+\n} 8 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c
index cef531b..7340cc9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c
@@ -10,3 +10,4 @@
/* { dg-final { scan-assembler-times {\tvfsgnjx\.vv} 6 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {\tvfsgnjn\.vv} 6 } } */
/* { dg-final { scan-assembler-not {\tvmerge\.vvm} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv64gcv.c
index cc2aa4d..471b56a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv64gcv.c
@@ -10,3 +10,4 @@
/* { dg-final { scan-assembler-times {\tvfsgnjx\.vv} 6 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {\tvfsgnjn\.vv} 6 } } */
/* { dg-final { scan-assembler-not {\tvmerge\.vvm} } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c
index c9d14f2..6f37680 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c
@@ -30,3 +30,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 18 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c
index 21f9f9f..eba1ab5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c
@@ -29,3 +29,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c
index f71dbaa..c58eae9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c
@@ -30,3 +30,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 18 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c
index ffbe9a4..4ad7f72 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c
@@ -30,3 +30,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 18 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c
index 0b19c54..b4df366 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c
@@ -33,3 +33,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vfmadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c
index bd61c0e..b2ac8e1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c
@@ -33,3 +33,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vfmadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c
index c011a29..6941a7b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c
@@ -33,3 +33,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c
index 98ba3c1..30cee81 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c
@@ -33,3 +33,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c
index 98ba3c1..9b6a03e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c
@@ -1,30 +1,29 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
-#define DEF_LOOP(TYPE, NAME, OP) \
- void __attribute__ ((noipa)) \
- test_##TYPE##_##NAME (TYPE *__restrict r, \
- TYPE *__restrict a, \
- TYPE *__restrict b, TYPE c, \
- TYPE *__restrict pred, int n) \
- { \
- for (int i = 0; i < n; ++i) \
- r[i] = pred[i] == 1 ? a[i] OP b[i] * c : pred[i]; \
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE c, TYPE *__restrict pred, \
+ TYPE *__restrict merged, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] == 1 ? a[i] OP b[i] * c : merged[i]; \
}
-#define TEST_TYPE(T, TYPE) \
- T (TYPE, add, +) \
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, add, +) \
T (TYPE, sub, -)
-#define TEST_ALL(T) \
- TEST_TYPE (T, uint8_t) \
- TEST_TYPE (T, uint16_t) \
- TEST_TYPE (T, uint32_t) \
- TEST_TYPE (T, uint64_t) \
- TEST_TYPE (T, _Float16) \
- TEST_TYPE (T, float) \
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, uint64_t) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
TEST_TYPE (T, double)
TEST_ALL (DEF_LOOP)
@@ -33,3 +32,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* NOTE: 14 vmerge is need for other purpose. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c
index e72eb5e..345f6ef 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c
@@ -33,3 +33,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* NOTE: 14 vmerge is need for other purpose. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c
index 3a69a59..26a2179 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c
@@ -33,3 +33,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c
index 4df9da8..f78fa09 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c
@@ -33,3 +33,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c
index 3b0582d..0fddce1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c
@@ -6,25 +6,25 @@
#define FACTOR 17
#define N 99
-#define TEST_LOOP(TYPE, NAME, OP) \
- { \
- TYPE r[N], a[N], b[N], pred[N]; \
- for (int i = 0; i < N; ++i) \
- { \
- a[i] = (i & 1 ? i : 3 * i); \
- b[i] = (i >> 4) << (i & 15); \
- pred[i] = i % 3 < i % 5; \
- asm volatile ("" ::: "memory"); \
- } \
- test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N); \
- for (int i = 0; i < N; ++i) \
- { \
- TYPE expected \
- = pred[i] ? a[i] OP b[i] * (TYPE) FACTOR : 0; \
- if (r[i] != expected) \
- __builtin_abort (); \
- asm volatile ("" ::: "memory"); \
- } \
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N], merged[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ merged[i] = i * 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, FACTOR, pred, merged, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = pred[i] ? a[i] OP b[i] * (TYPE) FACTOR : merged[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
}
int
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
index fe37794..25c35cf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
index f25562b..17f8623 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -30,3 +31,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
index a23f491..9a29b52 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
index 79e4771..cba6cdf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
index e136f98..3dc1fb8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-1.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
index 291cfca..0cf6756 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-2.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
index 34f011d..df4a5de 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-3.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
index 9986f8d..1b94951 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-4.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
new file mode 100644
index 0000000..c6929a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
new file mode 100644
index 0000000..b8a1841
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE) \
+ T (FN, TYPE, zero, 0) \
+ T (FN, TYPE, one, 1) \
+ T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
new file mode 100644
index 0000000..af06f11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 4; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
new file mode 100644
index 0000000..e6a5a76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 0; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
new file mode 100644
index 0000000..1609d2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-1.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
new file mode 100644
index 0000000..6c33858
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-2.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
new file mode 100644
index 0000000..6df48c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-3.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
new file mode 100644
index 0000000..9bb1beb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-4.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
index f159640..2c8fbfb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-1.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
-
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
index 7c8c79e..fe04554 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
@@ -1,9 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-2.c"
/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
index aee0e35..e76361c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
@@ -1,9 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-3.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
index 223c8a6..9399a40 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
@@ -1,9 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-4.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
index 293e1d9..139f9f7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
index 3310bb7..e9449b8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
index 6bed341..f70c344 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
index 4af0322..fe700a2 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
new file mode 100644
index 0000000..77bc6e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
new file mode 100644
index 0000000..8e330af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-2.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
new file mode 100644
index 0000000..5caeac9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-3.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
new file mode 100644
index 0000000..8281dc6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-4.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
new file mode 100644
index 0000000..b334f4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
new file mode 100644
index 0000000..873f413
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
new file mode 100644
index 0000000..94be087
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
new file mode 100644
index 0000000..8a144e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c
index 2a28941..d3bf00e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c
@@ -27,3 +27,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {vfmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c
index d1826f3..f593d56 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c
@@ -27,3 +27,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {vfmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c
index 5745823..cc23b12 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c
@@ -27,3 +27,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c
index b5ed704..bd7b27a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c
@@ -27,3 +27,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* NOTE: 3 vmerge is need for other purpose. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c
index b5ed704..bd7b27a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c
@@ -27,3 +27,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* NOTE: 3 vmerge is need for other purpose. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c
index c5c8af8..bcb356e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c
@@ -27,3 +27,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 { xfail riscv*-*-* } } } */
/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* NOTE: 3 vmerge is need for other purpose. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c
index 94cec7f..9c9ed43 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c
@@ -27,3 +27,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c
index c8ada38..3e7d1db 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c
@@ -26,3 +26,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c
index bd325ea..e3c306d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c
@@ -27,3 +27,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c
index 118c9a4..57163ef 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c
@@ -27,3 +27,4 @@
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c
new file mode 100644
index 0000000..2e031a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, TYPE *__restrict merged, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] * (TYPE) CONST : merged[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, two, 2.0) \
+ T (TYPE, PRED_TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-5.c
new file mode 100644
index 0000000..c3763b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-5.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmul-5.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], merged[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ merged[i] = i; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, merged, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] * (TYPE) CONST : merged[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-1.c
index 7034786..f902702 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-1.c
@@ -47,3 +47,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vminu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vmaxu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-2.c
index 44cbbe6..70daec9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-2.c
@@ -47,3 +47,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vminu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vmaxu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-3.c
index 220a376..72d498e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-3.c
@@ -47,3 +47,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vminu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vmaxu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-4.c
index 0763d92..a28bf57 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-4.c
@@ -47,3 +47,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vminu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vmaxu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-5.c
index 304c9ee..03fb859 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_min_max-5.c
@@ -47,3 +47,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vminu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vmaxu\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c
index 6bf2538..1c8a4ca 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c
@@ -31,3 +31,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c
index 2edf38f..eb375dd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c
@@ -31,3 +31,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c
index 84f91ee..ab1c9e9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c
@@ -31,3 +31,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c
index a4be0b3..c7dd3df 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c
@@ -31,3 +31,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c
index 06a0a1a..cdaa3e1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c
@@ -27,3 +27,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c
index 3b1c485..aa957dd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c
@@ -25,3 +25,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 1 } } */
/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 1 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c
index d44cf43..1f271c6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c
@@ -27,3 +27,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c
index e68289b..f6dc7ff 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c
@@ -27,3 +27,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c
index 892bc08..df3f390 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c
@@ -27,3 +27,4 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c
index c7bd37e..d6b2f0f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
#include <stdint-gcc.h>
@@ -13,12 +13,13 @@
}
#define TEST_ALL(T) \
- T (_Float16, __builtin_sqrtf16) \
T (float, __builtin_sqrtf) \
T (double, __builtin_sqrt)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {\tvfsqrt\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfsqrt\.v\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c
index c2fb92f..1c5d3f0 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
#include <stdint-gcc.h>
@@ -13,12 +13,13 @@
}
#define TEST_ALL(T) \
- T (_Float16, __builtin_sqrtf16) \
T (float, __builtin_sqrtf) \
T (double, __builtin_sqrt)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {\tvfsqrt\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfsqrt\.v\tv[0-9]+,v[0-9]+,v0\.t} 2 } } */
/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
+
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-1.c
new file mode 100644
index 0000000..c632d63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? OP (a[i]) : a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, __builtin_sqrtf16) \
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tvfsqrt\.v\tv[0-9]+,v[0-9]+,v0\.t} 1 } } */
+/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-2.c
new file mode 100644
index 0000000..8e1bc60
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt-zvfh-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? OP (a[i]) : b[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, __builtin_sqrtf16) \
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tvfsqrt\.v\tv[0-9]+,v[0-9]+,v0\.t} 1 } } */
+
+/* { dg-final { scan-assembler {\tvsetvli\t[a-z0-9]+,[a-z0-9]+,e[0-9]+,m[f0-9]+,t[au],mu} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-1.c
new file mode 100644
index 0000000..c96a1a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-1.c
@@ -0,0 +1,29 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math " } */
+
+#include "cond_sqrt-zvfh-1.c"
+#include <stdio.h>
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : 2); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? OP (a[i]) : a[i])) \
+ __builtin_abort (); \
+ }
+
+int
+main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-2.c
new file mode 100644
index 0000000..3386242
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_sqrt_run-zvfh-2.c
@@ -0,0 +1,29 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_sqrt-zvfh-2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : 2); \
+ b[i] = (i % 9) * (i % 7 + 1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, b, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? OP (a[i]) : b[i])) \
+ __builtin_abort (); \
+ }
+
+int
+main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c
index cb738a8..28a5e02 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c
@@ -41,3 +41,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 4 } } */
/* { dg-final { scan-assembler-times {\tvfabs\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
/* { dg-final { scan-assembler-times {\tvfneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c
index d9fb086..e456e68 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c
@@ -44,3 +44,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 4 } } */
/* { dg-final { scan-assembler-times {\tvfabs\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
/* { dg-final { scan-assembler-times {\tvfneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c
index 1458393..e2a8733 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c
@@ -41,3 +41,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 4 } } */
/* { dg-final { scan-assembler-times {\tvfabs\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
/* { dg-final { scan-assembler-times {\tvfneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c
index e120e8f..37c7ccb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c
@@ -41,3 +41,5 @@ TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 4 } } */
/* { dg-final { scan-assembler-times {\tvfabs\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
/* { dg-final { scan-assembler-times {\tvfneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 3 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c
index 775e65e..2b4857f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c
@@ -34,3 +34,5 @@ TEST_ALL (DEF_LOOP)
/* NOTE: int abs operator is converted to vmslt + vneg.v */
/* { dg-final { scan-assembler-times {\tvneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 12 } } */
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 6 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c
index 6331440..4519a56 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c
@@ -37,3 +37,5 @@ TEST_ALL (DEF_LOOP)
/* NOTE: int abs operator is converted to vmslt + vneg.v */
/* { dg-final { scan-assembler-times {\tvneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 12 } } */
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 6 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c
index 4847aec..0368f1c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c
@@ -34,3 +34,5 @@ TEST_ALL (DEF_LOOP)
/* NOTE: int abs operator is converted to vmslt + vneg.v */
/* { dg-final { scan-assembler-times {\tvneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 12 } } */
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 6 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c
index ae4d118..e3c19e4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c
@@ -34,3 +34,5 @@ TEST_ALL (DEF_LOOP)
/* NOTE: int abs operator is converted to vmslt + vneg.v */
/* { dg-final { scan-assembler-times {\tvneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 12 } } */
/* { dg-final { scan-assembler-times {\tvnot\.v\tv[0-9]+,v[0-9]+,v0\.t} 6 } } */
+/* NOTE: int abs operator cannot combine the vmerge. */
+/* { dg-final { scan-assembler-times {\tvf?merge\.v[vxi]m\t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
index eac7cbc..ca88d42 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
@@ -7,10 +7,11 @@
/*
** foo:
** vsetivli\t[a-x0-9]+,\s*8,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetvli\t[a-x0-9]+,\s*[a-x0-9]+,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
-** add\t[a-x0-9]+,[a-x0-9]+,[a-x0-9]+
+** vsetvli\tzero,\s*[a-x0-9]+,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111318.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111318.c
new file mode 100644
index 0000000..ff36da8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111318.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fno-vect-cost-model" } */
+
+void
+foo (int *__restrict a, int *__restrict b, int *__restrict c, int n)
+{
+ for (int i = 0; i < n; i += 1)
+ c[i] = a[i] + b[i];
+}
+
+/* { dg-final { scan-assembler-times {vsetvli} 1 } } */
+/* { dg-final { scan-assembler-not {vsetivli} } } */
+/* { dg-final { scan-assembler-times {vsetvli\s*[a-x0-9]+,\s*[a-x0-9]+} 1 } } */
+/* { dg-final { scan-assembler-not {vsetvli\s*[a-x0-9]+,\s*zero} } } */
+/* { dg-final { scan-assembler-not {vsetvli\s*zero} } } */
+/* { dg-final { scan-assembler-not {vsetivli\s*zero} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111888.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111888.c
new file mode 100644
index 0000000..2387c20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111888.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fno-vect-cost-model" } */
+
+void
+foo (int *__restrict a, int *__restrict b, int *__restrict c,
+ int *__restrict a2, int *__restrict b2, int *__restrict c2,
+ int *__restrict a3, int *__restrict b3, int *__restrict c3,
+ int *__restrict a4, int *__restrict b4, int *__restrict c4,
+ int *__restrict a5, int *__restrict b5, int *__restrict c5,
+ int *__restrict d, int *__restrict d2, int *__restrict d3,
+ int *__restrict d4, int *__restrict d5, int n, int m)
+{
+ for (int i = 0; i < n; i++)
+ {
+ a[i] = b[i] + c[i];
+ a2[i] = b2[i] + c2[i];
+ a3[i] = b3[i] + c3[i];
+ a4[i] = b4[i] + c4[i];
+ a5[i] = a[i] + a4[i];
+ d[i] = a[i] - a2[i];
+ d2[i] = a2[i] * a[i];
+ d3[i] = a3[i] * a2[i];
+ d4[i] = a2[i] * d2[i];
+ d5[i] = a[i] * a2[i] * a3[i] * a4[i] * d[i];
+ }
+}
+
+/* { dg-final { scan-assembler-times {vsetvli} 1 } } */
+/* { dg-final { scan-assembler-not {vsetivli} } } */
+/* { dg-final { scan-assembler-times {vsetvli\s*[a-x0-9]+,\s*[a-x0-9]+} 1 } } */
+/* { dg-final { scan-assembler-not {vsetvli\s*[a-x0-9]+,\s*zero} } } */
+/* { dg-final { scan-assembler-not {vsetvli\s*zero} } } */
+/* { dg-final { scan-assembler-not {vsetivli\s*zero} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
new file mode 100644
index 0000000..be339bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (float, max, __builtin_fmaxf) \
+ T (double, max, __builtin_fmax) \
+ T (float, min, __builtin_fminf) \
+ T (double, min, __builtin_fmin)
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
new file mode 100644
index 0000000..6dc372f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+
+#include "reduc-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
new file mode 100644
index 0000000..0651e31
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (_Float16, max, __builtin_fmaxf16) \
+ T (_Float16, min, __builtin_fminf16) \
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
new file mode 100644
index 0000000..2b8bcdf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+
+#include "reduc_zvfh-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-1.c
new file mode 100644
index 0000000..ee1baa5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=gnu99 -O3 -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable -fdump-tree-slp-details" } */
+
+void
+__attribute__ ((noipa))
+f (int *restrict x, short *restrict y, int *restrict res)
+{
+ res[0] = x[0] == 1 & y[0] == 2;
+ res[1] = x[1] == 1 & y[1] == 2;
+ res[2] = x[2] == 1 & y[2] == 2;
+ res[3] = x[3] == 1 & y[3] == 2;
+ res[4] = x[4] == 1 & y[4] == 2;
+ res[5] = x[5] == 1 & y[5] == 2;
+ res[6] = x[6] == 1 & y[6] == 2;
+ res[7] = x[7] == 1 & y[7] == 2;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-run-1.c
new file mode 100644
index 0000000..b3469c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-mask-run-1.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=gnu99 -O3 -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable" } */
+
+#include <malloc.h>
+#include <stdio.h>
+
+#include "slp-mask-1.c"
+
+#define SZ 8
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ int *a = malloc (SZ * sizeof (*a));
+ short *b = malloc (SZ * sizeof (*b));
+ int *res = malloc (SZ * sizeof (*res));
+ int *ref = malloc (SZ * sizeof (*ref));
+
+ for (int i = 0; i < SZ; i++)
+ {
+ a[i] = i & 1;
+ b[i] = 2;
+ ref[i] = a[i] == 1 & b[i] == 2;
+ }
+
+ f (a, b, res);
+
+ for (int i = 0; i < SZ; i++)
+ if (res[i] != ref[i])
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c
index 965365d..1336742 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c
@@ -3,7 +3,6 @@
#include "ternop-2.c"
-/* { dg-final { scan-assembler-times {\tvmacc\.vv} 8 } } */
/* { dg-final { scan-assembler-times {\tvfma[c-d][c-d]\.vv} 9 } } */
/* { dg-final { scan-tree-dump-times "COND_LEN_FMA" 9 "optimized" } } */
/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/bswap16-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/bswap16-0.c
index 10d235a..605b356 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/bswap16-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/bswap16-0.c
@@ -8,7 +8,6 @@
/*
** test_uint16_t___builtin_bswap16:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*ma
** vsrl\.vi\s+v[0-9]+,\s*v[0-9],\s*8+
** vsll\.vi\s+v[0-9]+,\s*v[0-9],\s*8+
** vor\.vv\s+v[0-9]+,\s*v[0-9],\s*v[0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-0.c
index 762b140..7d66ed3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-0.c
@@ -7,9 +7,8 @@
/*
** test_int65_to_fp16:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*mf2,\s*ta,\s*ma
** vfncvt\.f\.x\.w\s+v[0-9]+,\s*v[0-9]+
-** vsetvli\s+zero,\s*zero,\s*e16,\s*mf4,\s*ta,\s*ma
+** ...
** vfncvt\.f\.f\.w\s+v[0-9]+,\s*v[0-9]+
** ...
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-1.c
index 3180ba3..af08c51 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/cvt-1.c
@@ -7,9 +7,8 @@
/*
** test_uint65_to_fp16:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*mf2,\s*ta,\s*ma
** vfncvt\.f\.xu\.w\s+v[0-9]+,\s*v[0-9]+
-** vsetvli\s+zero,\s*zero,\s*e16,\s*mf4,\s*ta,\s*ma
+** ...
** vfncvt\.f\.f\.w\s+v[0-9]+,\s*v[0-9]+
** ...
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
index 1c53d9b..5660d98 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
index a6d0ac3..62a089b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
index d196fc6..1f57e08 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
index cd3df49..e74d230 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-0.c
index 33b1693..06af0f1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-1.c
index 5c462c42..b4913ea 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-1.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-2.c
index 6f07add..86a83d8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-2.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-3.c
index a091ffd..a9a5d15 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-floor-3.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
index 2d4a1d1..b834786 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
index b9ec415..40c6519 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-irint-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-irint-0.c
index 3ca2f65..3d0c887 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-irint-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-irint-0.c
@@ -7,7 +7,6 @@
/*
** test_float_int___builtin_irintf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iround-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iround-0.c
index f32515d..14828e2 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iround-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iround-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-0.c
index 3b13a52..5084672 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-1.c
index 5ff5d1d..1a51482 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lceil-1.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-0.c
index ac2d172..10bfadc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-1.c
index 164e97c..b2eede8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lfloor-1.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
index 3480c3e..ba85728 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
@@ -11,7 +11,6 @@
** ...
** fsrmi\s+3
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
index 4b10f96..2bd82ac 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
@@ -11,7 +11,6 @@
** ...
** fsrmi\s+2
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llrint-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llrint-0.c
index 4bf125f..b919109 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llrint-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llrint-0.c
@@ -8,7 +8,6 @@
/*
** test_double_int64_t___builtin_llrint:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llround-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llround-0.c
index 4f8b455..2f3a7c6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llround-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llround-0.c
@@ -11,7 +11,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-0.c
index a60ef30..dae0cfa 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-0.c
@@ -7,7 +7,6 @@
/*
** test_double_long___builtin_lrint:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-1.c
index 57e92ff..426a643 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lrint-1.c
@@ -7,7 +7,6 @@
/*
** test_float_long___builtin_lrintf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-0.c
index 32b7348..242074e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-1.c
index a4d6fcf..3d95e22 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-lround-1.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
** ...
** fsrm\s+[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-0.c
index f67b22a..85d5e0a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-0.c
@@ -7,7 +7,6 @@
/*
** test__Float16___builtin_nearbyintf16:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** frflags\s+[axt][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-1.c
index 9363986..9697aed 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-1.c
@@ -7,7 +7,6 @@
/*
** test_float___builtin_nearbyintf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** frflags\s+[axt][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-2.c
index d31de73..00402dd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-2.c
@@ -7,7 +7,6 @@
/*
** test_double___builtin_nearbyint:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** frflags\s+[axt][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-3.c
index 4fd9950..6a8a276 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-nearbyint-3.c
@@ -7,7 +7,6 @@
/*
** test_float___builtin_nearbyintf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** frflags\s+[axt][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-0.c
index 0d44b98..d57f9de 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-0.c
@@ -7,7 +7,6 @@
/*
** test__Float16___builtin_rintf16:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-1.c
index 2ce122a..4a79673 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-1.c
@@ -7,7 +7,6 @@
/*
** test_float___builtin_rintf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-2.c
index e3b911b..a7d7550 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-2.c
@@ -7,7 +7,6 @@
/*
** test_double___builtin_rint:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-3.c
index 541c42c..33e6287 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-3.c
@@ -7,7 +7,6 @@
/*
** test_float___builtin_rintf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-0.c
index 06de57b..18770df 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-1.c
index ee51bcd..d50c293 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-1.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-2.c
index d78f058..28a928d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-2.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-3.c
index 98d1467..953ed60 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-round-3.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+4
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-0.c
index ab65e37..98d1171 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-0.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+0
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-1.c
index fac85ed..5c021770 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-1.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+0
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-2.c
index 074f1b4..7a14a7d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-2.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+0
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-3.c
index c95e8ec..6092fdc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-roundeven-3.c
@@ -10,7 +10,6 @@
** ...
** fsrmi\s+0
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-0.c
index e304634..ea135cd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-0.c
@@ -7,7 +7,6 @@
/*
** test__Float16___builtin_truncf16:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.rtz\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-1.c
index 8100419..e4ef82d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-1.c
@@ -7,7 +7,6 @@
/*
** test_float___builtin_truncf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.rtz\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-2.c
index 40551f5..7d17a11 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-2.c
@@ -7,7 +7,6 @@
/*
** test_double___builtin_trunc:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.rtz\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-3.c
index bb113fd..66c1946 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-trunc-3.c
@@ -7,7 +7,6 @@
/*
** test_float___builtin_truncf:
** ...
-** vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
** vfabs\.v\s+v[0-9]+,\s*v[0-9]+
** vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
** vfcvt\.rtz\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c
new file mode 100644
index 0000000..9c065be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+void __attribute__ ((noipa))
+popcount_32 (uint32_t *restrict dst, uint32_t *restrict src, int size)
+{
+ for (int i = 0; i < size; ++i)
+ dst[i] = __builtin_popcount (src[i]);
+}
+
+void __attribute__ ((noipa))
+popcount_64 (uint64_t *restrict dst, uint64_t *restrict src, int size)
+{
+ for (int i = 0; i < size; ++i)
+ dst[i] = __builtin_popcountll (src[i]);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c
new file mode 100644
index 0000000..5719d9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-slp-details" } */
+
+int x[8];
+int y[8];
+
+void foo ()
+{
+ x[0] = __builtin_popcount (y[0]);
+ x[1] = __builtin_popcount (y[1]);
+ x[2] = __builtin_popcount (y[2]);
+ x[3] = __builtin_popcount (y[3]);
+ x[4] = __builtin_popcount (y[4]);
+ x[5] = __builtin_popcount (y[5]);
+ x[6] = __builtin_popcount (y[6]);
+ x[7] = __builtin_popcount (y[7]);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c
new file mode 100644
index 0000000..38f1633
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c
@@ -0,0 +1,49 @@
+/* { dg-do run { target { riscv_v } } } */
+
+#include "popcount-1.c"
+
+extern void abort (void) __attribute__ ((noreturn));
+
+unsigned int data[] = {
+ 0x11111100, 6,
+ 0xe0e0f0f0, 14,
+ 0x9900aab3, 13,
+ 0x00040003, 3,
+ 0x000e000c, 5,
+ 0x22227777, 16,
+ 0x12341234, 10,
+ 0x0, 0
+};
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+ unsigned int count = sizeof (data) / sizeof (data[0]) / 2;
+
+ uint32_t in32[count];
+ uint32_t out32[count];
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ in32[i] = data[i * 2];
+ asm volatile ("" ::: "memory");
+ }
+ popcount_32 (out32, in32, count);
+ for (unsigned int i = 0; i < count; ++i)
+ if (out32[i] != data[i * 2 + 1])
+ abort ();
+
+ count /= 2;
+ uint64_t in64[count];
+ uint64_t out64[count];
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ in64[i] = ((uint64_t) data[i * 4] << 32) | data[i * 4 + 2];
+ asm volatile ("" ::: "memory");
+ }
+ popcount_64 (out64, in64, count);
+ for (unsigned int i = 0; i < count; ++i)
+ if (out64[i] != data[i * 4 + 1] + data[i * 4 + 3])
+ 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
new file mode 100644
index 0000000..585a522
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount.c
@@ -0,0 +1,1464 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options { -O2 -fdump-tree-vect-details -fno-vect-cost-model } } */
+
+#include "stdint-gcc.h"
+#include <assert.h>
+
+#define DEF64(TYPEDST, TYPESRC) \
+ void __attribute__ ((noipa)) \
+ popcount64_##TYPEDST##TYPESRC (TYPEDST *restrict dst, TYPESRC *restrict src, \
+ int size) \
+ { \
+ for (int i = 0; i < size; ++i) \
+ dst[i] = __builtin_popcountll (src[i]); \
+ }
+
+#define DEF32(TYPEDST, TYPESRC) \
+ void __attribute__ ((noipa)) \
+ popcount32_##TYPEDST##TYPESRC (TYPEDST *restrict dst, TYPESRC *restrict src, \
+ int size) \
+ { \
+ for (int i = 0; i < size; ++i) \
+ dst[i] = __builtin_popcount (src[i]); \
+ }
+
+#define DEFCTZ64(TYPEDST, TYPESRC) \
+ void __attribute__ ((noipa)) \
+ ctz64_##TYPEDST##TYPESRC (TYPEDST *restrict dst, TYPESRC *restrict src, \
+ int size) \
+ { \
+ for (int i = 0; i < size; ++i) \
+ dst[i] = __builtin_ctzll (src[i]); \
+ }
+
+#define DEFCTZ32(TYPEDST, TYPESRC) \
+ void __attribute__ ((noipa)) \
+ ctz32_##TYPEDST##TYPESRC (TYPEDST *restrict dst, TYPESRC *restrict src, \
+ int size) \
+ { \
+ for (int i = 0; i < size; ++i) \
+ dst[i] = __builtin_ctz (src[i]); \
+ }
+
+#define DEFFFS64(TYPEDST, TYPESRC) \
+ void __attribute__ ((noipa)) \
+ ffs64_##TYPEDST##TYPESRC (TYPEDST *restrict dst, TYPESRC *restrict src, \
+ int size) \
+ { \
+ for (int i = 0; i < size; ++i) \
+ dst[i] = __builtin_ffsll (src[i]); \
+ }
+
+#define DEFFFS32(TYPEDST, TYPESRC) \
+ void __attribute__ ((noipa)) \
+ ffs32_##TYPEDST##TYPESRC (TYPEDST *restrict dst, TYPESRC *restrict src, \
+ int size) \
+ { \
+ for (int i = 0; i < size; ++i) \
+ dst[i] = __builtin_ffs (src[i]); \
+ }
+
+#define DEF_ALL() \
+ DEF64 (uint64_t, uint64_t) \
+ DEF64 (uint64_t, uint32_t) \
+ DEF64 (uint64_t, uint16_t) \
+ DEF64 (uint64_t, uint8_t) \
+ DEF64 (uint64_t, int64_t) \
+ DEF64 (uint64_t, int32_t) \
+ DEF64 (uint64_t, int16_t) \
+ DEF64 (uint64_t, int8_t) \
+ DEF64 (int64_t, uint64_t) \
+ DEF64 (int64_t, uint32_t) \
+ DEF64 (int64_t, uint16_t) \
+ DEF64 (int64_t, uint8_t) \
+ DEF64 (int64_t, int64_t) \
+ DEF64 (int64_t, int32_t) \
+ DEF64 (int64_t, int16_t) \
+ DEF64 (int64_t, int8_t) \
+ DEF64 (uint32_t, uint64_t) \
+ DEF64 (uint32_t, uint32_t) \
+ DEF64 (uint32_t, uint16_t) \
+ DEF64 (uint32_t, uint8_t) \
+ DEF64 (uint32_t, int64_t) \
+ DEF64 (uint32_t, int32_t) \
+ DEF64 (uint32_t, int16_t) \
+ DEF64 (uint32_t, int8_t) \
+ DEF64 (int32_t, uint64_t) \
+ DEF64 (int32_t, uint32_t) \
+ DEF64 (int32_t, uint16_t) \
+ DEF64 (int32_t, uint8_t) \
+ DEF64 (int32_t, int64_t) \
+ DEF64 (int32_t, int32_t) \
+ DEF64 (int32_t, int16_t) \
+ DEF64 (int32_t, int8_t) \
+ DEF64 (uint16_t, uint64_t) \
+ DEF64 (uint16_t, uint32_t) \
+ DEF64 (uint16_t, uint16_t) \
+ DEF64 (uint16_t, uint8_t) \
+ DEF64 (uint16_t, int64_t) \
+ DEF64 (uint16_t, int32_t) \
+ DEF64 (uint16_t, int16_t) \
+ DEF64 (uint16_t, int8_t) \
+ DEF64 (int16_t, uint64_t) \
+ DEF64 (int16_t, uint32_t) \
+ DEF64 (int16_t, uint16_t) \
+ DEF64 (int16_t, uint8_t) \
+ DEF64 (int16_t, int64_t) \
+ DEF64 (int16_t, int32_t) \
+ DEF64 (int16_t, int16_t) \
+ DEF64 (int16_t, int8_t) \
+ DEF64 (uint8_t, uint64_t) \
+ DEF64 (uint8_t, uint32_t) \
+ DEF64 (uint8_t, uint16_t) \
+ DEF64 (uint8_t, uint8_t) \
+ DEF64 (uint8_t, int64_t) \
+ DEF64 (uint8_t, int32_t) \
+ DEF64 (uint8_t, int16_t) \
+ DEF64 (uint8_t, int8_t) \
+ DEF64 (int8_t, uint64_t) \
+ DEF64 (int8_t, uint32_t) \
+ DEF64 (int8_t, uint16_t) \
+ DEF64 (int8_t, uint8_t) \
+ DEF64 (int8_t, int64_t) \
+ DEF64 (int8_t, int32_t) \
+ DEF64 (int8_t, int16_t) \
+ DEF64 (int8_t, int8_t) \
+ DEF32 (uint64_t, uint64_t) \
+ DEF32 (uint64_t, uint32_t) \
+ DEF32 (uint64_t, uint16_t) \
+ DEF32 (uint64_t, uint8_t) \
+ DEF32 (uint64_t, int64_t) \
+ DEF32 (uint64_t, int32_t) \
+ DEF32 (uint64_t, int16_t) \
+ DEF32 (uint64_t, int8_t) \
+ DEF32 (int64_t, uint64_t) \
+ DEF32 (int64_t, uint32_t) \
+ DEF32 (int64_t, uint16_t) \
+ DEF32 (int64_t, uint8_t) \
+ DEF32 (int64_t, int64_t) \
+ DEF32 (int64_t, int32_t) \
+ DEF32 (int64_t, int16_t) \
+ DEF32 (int64_t, int8_t) \
+ DEF32 (uint32_t, uint64_t) \
+ DEF32 (uint32_t, uint32_t) \
+ DEF32 (uint32_t, uint16_t) \
+ DEF32 (uint32_t, uint8_t) \
+ DEF32 (uint32_t, int64_t) \
+ DEF32 (uint32_t, int32_t) \
+ DEF32 (uint32_t, int16_t) \
+ DEF32 (uint32_t, int8_t) \
+ DEF32 (int32_t, uint64_t) \
+ DEF32 (int32_t, uint32_t) \
+ DEF32 (int32_t, uint16_t) \
+ DEF32 (int32_t, uint8_t) \
+ DEF32 (int32_t, int64_t) \
+ DEF32 (int32_t, int32_t) \
+ DEF32 (int32_t, int16_t) \
+ DEF32 (int32_t, int8_t) \
+ DEF32 (uint16_t, uint64_t) \
+ DEF32 (uint16_t, uint32_t) \
+ DEF32 (uint16_t, uint16_t) \
+ DEF32 (uint16_t, uint8_t) \
+ DEF32 (uint16_t, int64_t) \
+ DEF32 (uint16_t, int32_t) \
+ DEF32 (uint16_t, int16_t) \
+ DEF32 (uint16_t, int8_t) \
+ DEF32 (int16_t, uint64_t) \
+ DEF32 (int16_t, uint32_t) \
+ DEF32 (int16_t, uint16_t) \
+ DEF32 (int16_t, uint8_t) \
+ DEF32 (int16_t, int64_t) \
+ DEF32 (int16_t, int32_t) \
+ DEF32 (int16_t, int16_t) \
+ DEF32 (int16_t, int8_t) \
+ DEF32 (uint8_t, uint64_t) \
+ DEF32 (uint8_t, uint32_t) \
+ DEF32 (uint8_t, uint16_t) \
+ DEF32 (uint8_t, uint8_t) \
+ DEF32 (uint8_t, int64_t) \
+ DEF32 (uint8_t, int32_t) \
+ DEF32 (uint8_t, int16_t) \
+ DEF32 (uint8_t, int8_t) \
+ DEF32 (int8_t, uint64_t) \
+ DEF32 (int8_t, uint32_t) \
+ DEF32 (int8_t, uint16_t) \
+ DEF32 (int8_t, uint8_t) \
+ DEF32 (int8_t, int64_t) \
+ DEF32 (int8_t, int32_t) \
+ DEF32 (int8_t, int16_t) \
+ DEF32 (int8_t, int8_t) \
+ DEFCTZ64 (uint64_t, uint64_t) \
+ DEFCTZ64 (uint64_t, uint32_t) \
+ DEFCTZ64 (uint64_t, uint16_t) \
+ DEFCTZ64 (uint64_t, uint8_t) \
+ DEFCTZ64 (uint64_t, int64_t) \
+ DEFCTZ64 (uint64_t, int32_t) \
+ DEFCTZ64 (uint64_t, int16_t) \
+ DEFCTZ64 (uint64_t, int8_t) \
+ DEFCTZ64 (int64_t, uint64_t) \
+ DEFCTZ64 (int64_t, uint32_t) \
+ DEFCTZ64 (int64_t, uint16_t) \
+ DEFCTZ64 (int64_t, uint8_t) \
+ DEFCTZ64 (int64_t, int64_t) \
+ DEFCTZ64 (int64_t, int32_t) \
+ DEFCTZ64 (int64_t, int16_t) \
+ DEFCTZ64 (int64_t, int8_t) \
+ DEFCTZ64 (uint32_t, uint64_t) \
+ DEFCTZ64 (uint32_t, uint32_t) \
+ DEFCTZ64 (uint32_t, uint16_t) \
+ DEFCTZ64 (uint32_t, uint8_t) \
+ DEFCTZ64 (uint32_t, int64_t) \
+ DEFCTZ64 (uint32_t, int32_t) \
+ DEFCTZ64 (uint32_t, int16_t) \
+ DEFCTZ64 (uint32_t, int8_t) \
+ DEFCTZ64 (int32_t, uint64_t) \
+ DEFCTZ64 (int32_t, uint32_t) \
+ DEFCTZ64 (int32_t, uint16_t) \
+ DEFCTZ64 (int32_t, uint8_t) \
+ DEFCTZ64 (int32_t, int64_t) \
+ DEFCTZ64 (int32_t, int32_t) \
+ DEFCTZ64 (int32_t, int16_t) \
+ DEFCTZ64 (int32_t, int8_t) \
+ DEFCTZ64 (uint16_t, uint64_t) \
+ DEFCTZ64 (uint16_t, uint32_t) \
+ DEFCTZ64 (uint16_t, uint16_t) \
+ DEFCTZ64 (uint16_t, uint8_t) \
+ DEFCTZ64 (uint16_t, int64_t) \
+ DEFCTZ64 (uint16_t, int32_t) \
+ DEFCTZ64 (uint16_t, int16_t) \
+ DEFCTZ64 (uint16_t, int8_t) \
+ DEFCTZ64 (int16_t, uint64_t) \
+ DEFCTZ64 (int16_t, uint32_t) \
+ DEFCTZ64 (int16_t, uint16_t) \
+ DEFCTZ64 (int16_t, uint8_t) \
+ DEFCTZ64 (int16_t, int64_t) \
+ DEFCTZ64 (int16_t, int32_t) \
+ DEFCTZ64 (int16_t, int16_t) \
+ DEFCTZ64 (int16_t, int8_t) \
+ DEFCTZ64 (uint8_t, uint64_t) \
+ DEFCTZ64 (uint8_t, uint32_t) \
+ DEFCTZ64 (uint8_t, uint16_t) \
+ DEFCTZ64 (uint8_t, uint8_t) \
+ DEFCTZ64 (uint8_t, int64_t) \
+ DEFCTZ64 (uint8_t, int32_t) \
+ DEFCTZ64 (uint8_t, int16_t) \
+ DEFCTZ64 (uint8_t, int8_t) \
+ DEFCTZ64 (int8_t, uint64_t) \
+ DEFCTZ64 (int8_t, uint32_t) \
+ DEFCTZ64 (int8_t, uint16_t) \
+ DEFCTZ64 (int8_t, uint8_t) \
+ DEFCTZ64 (int8_t, int64_t) \
+ DEFCTZ64 (int8_t, int32_t) \
+ DEFCTZ64 (int8_t, int16_t) \
+ DEFCTZ64 (int8_t, int8_t) \
+ DEFCTZ32 (uint64_t, uint64_t) \
+ DEFCTZ32 (uint64_t, uint32_t) \
+ DEFCTZ32 (uint64_t, uint16_t) \
+ DEFCTZ32 (uint64_t, uint8_t) \
+ DEFCTZ32 (uint64_t, int64_t) \
+ DEFCTZ32 (uint64_t, int32_t) \
+ DEFCTZ32 (uint64_t, int16_t) \
+ DEFCTZ32 (uint64_t, int8_t) \
+ DEFCTZ32 (int64_t, uint64_t) \
+ DEFCTZ32 (int64_t, uint32_t) \
+ DEFCTZ32 (int64_t, uint16_t) \
+ DEFCTZ32 (int64_t, uint8_t) \
+ DEFCTZ32 (int64_t, int64_t) \
+ DEFCTZ32 (int64_t, int32_t) \
+ DEFCTZ32 (int64_t, int16_t) \
+ DEFCTZ32 (int64_t, int8_t) \
+ DEFCTZ32 (uint32_t, uint64_t) \
+ DEFCTZ32 (uint32_t, uint32_t) \
+ DEFCTZ32 (uint32_t, uint16_t) \
+ DEFCTZ32 (uint32_t, uint8_t) \
+ DEFCTZ32 (uint32_t, int64_t) \
+ DEFCTZ32 (uint32_t, int32_t) \
+ DEFCTZ32 (uint32_t, int16_t) \
+ DEFCTZ32 (uint32_t, int8_t) \
+ DEFCTZ32 (int32_t, uint64_t) \
+ DEFCTZ32 (int32_t, uint32_t) \
+ DEFCTZ32 (int32_t, uint16_t) \
+ DEFCTZ32 (int32_t, uint8_t) \
+ DEFCTZ32 (int32_t, int64_t) \
+ DEFCTZ32 (int32_t, int32_t) \
+ DEFCTZ32 (int32_t, int16_t) \
+ DEFCTZ32 (int32_t, int8_t) \
+ DEFCTZ32 (uint16_t, uint64_t) \
+ DEFCTZ32 (uint16_t, uint32_t) \
+ DEFCTZ32 (uint16_t, uint16_t) \
+ DEFCTZ32 (uint16_t, uint8_t) \
+ DEFCTZ32 (uint16_t, int64_t) \
+ DEFCTZ32 (uint16_t, int32_t) \
+ DEFCTZ32 (uint16_t, int16_t) \
+ DEFCTZ32 (uint16_t, int8_t) \
+ DEFCTZ32 (int16_t, uint64_t) \
+ DEFCTZ32 (int16_t, uint32_t) \
+ DEFCTZ32 (int16_t, uint16_t) \
+ DEFCTZ32 (int16_t, uint8_t) \
+ DEFCTZ32 (int16_t, int64_t) \
+ DEFCTZ32 (int16_t, int32_t) \
+ DEFCTZ32 (int16_t, int16_t) \
+ DEFCTZ32 (int16_t, int8_t) \
+ DEFCTZ32 (uint8_t, uint64_t) \
+ DEFCTZ32 (uint8_t, uint32_t) \
+ DEFCTZ32 (uint8_t, uint16_t) \
+ DEFCTZ32 (uint8_t, uint8_t) \
+ DEFCTZ32 (uint8_t, int64_t) \
+ DEFCTZ32 (uint8_t, int32_t) \
+ DEFCTZ32 (uint8_t, int16_t) \
+ DEFCTZ32 (uint8_t, int8_t) \
+ DEFCTZ32 (int8_t, uint64_t) \
+ DEFCTZ32 (int8_t, uint32_t) \
+ DEFCTZ32 (int8_t, uint16_t) \
+ DEFCTZ32 (int8_t, uint8_t) \
+ DEFCTZ32 (int8_t, int64_t) \
+ DEFCTZ32 (int8_t, int32_t) \
+ DEFCTZ32 (int8_t, int16_t) \
+ DEFCTZ32 (int8_t, int8_t) \
+ DEFFFS64 (uint64_t, uint64_t) \
+ DEFFFS64 (uint64_t, uint32_t) \
+ DEFFFS64 (uint64_t, uint16_t) \
+ DEFFFS64 (uint64_t, uint8_t) \
+ DEFFFS64 (uint64_t, int64_t) \
+ DEFFFS64 (uint64_t, int32_t) \
+ DEFFFS64 (uint64_t, int16_t) \
+ DEFFFS64 (uint64_t, int8_t) \
+ DEFFFS64 (int64_t, uint64_t) \
+ DEFFFS64 (int64_t, uint32_t) \
+ DEFFFS64 (int64_t, uint16_t) \
+ DEFFFS64 (int64_t, uint8_t) \
+ DEFFFS64 (int64_t, int64_t) \
+ DEFFFS64 (int64_t, int32_t) \
+ DEFFFS64 (int64_t, int16_t) \
+ DEFFFS64 (int64_t, int8_t) \
+ DEFFFS64 (uint32_t, uint64_t) \
+ DEFFFS64 (uint32_t, uint32_t) \
+ DEFFFS64 (uint32_t, uint16_t) \
+ DEFFFS64 (uint32_t, uint8_t) \
+ DEFFFS64 (uint32_t, int64_t) \
+ DEFFFS64 (uint32_t, int32_t) \
+ DEFFFS64 (uint32_t, int16_t) \
+ DEFFFS64 (uint32_t, int8_t) \
+ DEFFFS64 (int32_t, uint64_t) \
+ DEFFFS64 (int32_t, uint32_t) \
+ DEFFFS64 (int32_t, uint16_t) \
+ DEFFFS64 (int32_t, uint8_t) \
+ DEFFFS64 (int32_t, int64_t) \
+ DEFFFS64 (int32_t, int32_t) \
+ DEFFFS64 (int32_t, int16_t) \
+ DEFFFS64 (int32_t, int8_t) \
+ DEFFFS64 (uint16_t, uint64_t) \
+ DEFFFS64 (uint16_t, uint32_t) \
+ DEFFFS64 (uint16_t, uint16_t) \
+ DEFFFS64 (uint16_t, uint8_t) \
+ DEFFFS64 (uint16_t, int64_t) \
+ DEFFFS64 (uint16_t, int32_t) \
+ DEFFFS64 (uint16_t, int16_t) \
+ DEFFFS64 (uint16_t, int8_t) \
+ DEFFFS64 (int16_t, uint64_t) \
+ DEFFFS64 (int16_t, uint32_t) \
+ DEFFFS64 (int16_t, uint16_t) \
+ DEFFFS64 (int16_t, uint8_t) \
+ DEFFFS64 (int16_t, int64_t) \
+ DEFFFS64 (int16_t, int32_t) \
+ DEFFFS64 (int16_t, int16_t) \
+ DEFFFS64 (int16_t, int8_t) \
+ DEFFFS64 (uint8_t, uint64_t) \
+ DEFFFS64 (uint8_t, uint32_t) \
+ DEFFFS64 (uint8_t, uint16_t) \
+ DEFFFS64 (uint8_t, uint8_t) \
+ DEFFFS64 (uint8_t, int64_t) \
+ DEFFFS64 (uint8_t, int32_t) \
+ DEFFFS64 (uint8_t, int16_t) \
+ DEFFFS64 (uint8_t, int8_t) \
+ DEFFFS64 (int8_t, uint64_t) \
+ DEFFFS64 (int8_t, uint32_t) \
+ DEFFFS64 (int8_t, uint16_t) \
+ DEFFFS64 (int8_t, uint8_t) \
+ DEFFFS64 (int8_t, int64_t) \
+ DEFFFS64 (int8_t, int32_t) \
+ DEFFFS64 (int8_t, int16_t) \
+ DEFFFS64 (int8_t, int8_t) \
+ DEFFFS32 (uint64_t, uint64_t) \
+ DEFFFS32 (uint64_t, uint32_t) \
+ DEFFFS32 (uint64_t, uint16_t) \
+ DEFFFS32 (uint64_t, uint8_t) \
+ DEFFFS32 (uint64_t, int64_t) \
+ DEFFFS32 (uint64_t, int32_t) \
+ DEFFFS32 (uint64_t, int16_t) \
+ DEFFFS32 (uint64_t, int8_t) \
+ DEFFFS32 (int64_t, uint64_t) \
+ DEFFFS32 (int64_t, uint32_t) \
+ DEFFFS32 (int64_t, uint16_t) \
+ DEFFFS32 (int64_t, uint8_t) \
+ DEFFFS32 (int64_t, int64_t) \
+ DEFFFS32 (int64_t, int32_t) \
+ DEFFFS32 (int64_t, int16_t) \
+ DEFFFS32 (int64_t, int8_t) \
+ DEFFFS32 (uint32_t, uint64_t) \
+ DEFFFS32 (uint32_t, uint32_t) \
+ DEFFFS32 (uint32_t, uint16_t) \
+ DEFFFS32 (uint32_t, uint8_t) \
+ DEFFFS32 (uint32_t, int64_t) \
+ DEFFFS32 (uint32_t, int32_t) \
+ DEFFFS32 (uint32_t, int16_t) \
+ DEFFFS32 (uint32_t, int8_t) \
+ DEFFFS32 (int32_t, uint64_t) \
+ DEFFFS32 (int32_t, uint32_t) \
+ DEFFFS32 (int32_t, uint16_t) \
+ DEFFFS32 (int32_t, uint8_t) \
+ DEFFFS32 (int32_t, int64_t) \
+ DEFFFS32 (int32_t, int32_t) \
+ DEFFFS32 (int32_t, int16_t) \
+ DEFFFS32 (int32_t, int8_t) \
+ DEFFFS32 (uint16_t, uint64_t) \
+ DEFFFS32 (uint16_t, uint32_t) \
+ DEFFFS32 (uint16_t, uint16_t) \
+ DEFFFS32 (uint16_t, uint8_t) \
+ DEFFFS32 (uint16_t, int64_t) \
+ DEFFFS32 (uint16_t, int32_t) \
+ DEFFFS32 (uint16_t, int16_t) \
+ DEFFFS32 (uint16_t, int8_t) \
+ DEFFFS32 (int16_t, uint64_t) \
+ DEFFFS32 (int16_t, uint32_t) \
+ DEFFFS32 (int16_t, uint16_t) \
+ DEFFFS32 (int16_t, uint8_t) \
+ DEFFFS32 (int16_t, int64_t) \
+ DEFFFS32 (int16_t, int32_t) \
+ DEFFFS32 (int16_t, int16_t) \
+ DEFFFS32 (int16_t, int8_t) \
+ DEFFFS32 (uint8_t, uint64_t) \
+ DEFFFS32 (uint8_t, uint32_t) \
+ DEFFFS32 (uint8_t, uint16_t) \
+ DEFFFS32 (uint8_t, uint8_t) \
+ DEFFFS32 (uint8_t, int64_t) \
+ DEFFFS32 (uint8_t, int32_t) \
+ DEFFFS32 (uint8_t, int16_t) \
+ DEFFFS32 (uint8_t, int8_t) \
+ DEFFFS32 (int8_t, uint64_t) \
+ DEFFFS32 (int8_t, uint32_t) \
+ DEFFFS32 (int8_t, uint16_t) \
+ DEFFFS32 (int8_t, uint8_t) \
+ DEFFFS32 (int8_t, int64_t) \
+ DEFFFS32 (int8_t, int32_t) \
+ DEFFFS32 (int8_t, int16_t) \
+ DEFFFS32 (int8_t, int8_t)
+
+DEF_ALL ()
+
+#define SZ 512
+
+#define TEST64(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) test64_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * 1234567890; \
+ dst[i] = 0; \
+ } \
+ popcount64_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_popcountll (src[i])); \
+ } \
+ }
+
+#define TEST64N(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) test64n_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * -1234567890; \
+ dst[i] = 0; \
+ } \
+ popcount64_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_popcountll (src[i])); \
+ } \
+ }
+
+#define TEST32(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) test32_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * 1234567; \
+ dst[i] = 0; \
+ } \
+ popcount32_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_popcount (src[i])); \
+ } \
+ }
+
+#define TEST32N(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) test32n_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * -1234567; \
+ dst[i] = 0; \
+ } \
+ popcount32_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_popcount (src[i])); \
+ } \
+ }
+
+#define TESTCTZ64(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testctz64_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * 1234567890; \
+ dst[i] = 0; \
+ } \
+ ctz64_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ if (src[i] != 0) \
+ assert (dst[i] == __builtin_ctzll (src[i])); \
+ } \
+ }
+
+#define TESTCTZ64N(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testctz64n_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * -1234567890; \
+ dst[i] = 0; \
+ } \
+ ctz64_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ if (src[i] != 0) \
+ assert (dst[i] == __builtin_ctzll (src[i])); \
+ } \
+ }
+
+#define TESTCTZ32(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testctz32_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * 1234567; \
+ dst[i] = 0; \
+ } \
+ ctz32_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ if (src[i] != 0) \
+ assert (dst[i] == __builtin_ctz (src[i])); \
+ } \
+ }
+
+#define TESTCTZ32N(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testctz32n_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * -1234567; \
+ dst[i] = 0; \
+ } \
+ ctz32_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ if (src[i] != 0) \
+ assert (dst[i] == __builtin_ctz (src[i])); \
+ } \
+ }
+
+#define TESTFFS64(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testffs64_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * 1234567890; \
+ dst[i] = 0; \
+ } \
+ ffs64_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_ffsll (src[i])); \
+ } \
+ }
+
+#define TESTFFS64N(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testffs64n_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * -1234567890; \
+ dst[i] = 0; \
+ } \
+ ffs64_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_ffsll (src[i])); \
+ } \
+ }
+
+#define TESTFFS32(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testffs32_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * 1234567; \
+ dst[i] = 0; \
+ } \
+ ffs32_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_ffs (src[i])); \
+ } \
+ }
+
+#define TESTFFS32N(TYPEDST, TYPESRC) \
+ void __attribute__ ((optimize ("0"))) testffs32n_##TYPEDST##TYPESRC () \
+ { \
+ TYPESRC src[SZ]; \
+ TYPEDST dst[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ int ia = i + 1; \
+ src[i] = ia * -1234567; \
+ dst[i] = 0; \
+ } \
+ ffs32_##TYPEDST##TYPESRC (dst, src, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ assert (dst[i] == __builtin_ffs (src[i])); \
+ } \
+ }
+
+#define TEST_ALL() \
+ TEST64 (uint64_t, uint64_t) \
+ TEST64 (uint64_t, uint32_t) \
+ TEST64 (uint64_t, uint16_t) \
+ TEST64 (uint64_t, uint8_t) \
+ TEST64 (uint64_t, int64_t) \
+ TEST64 (uint64_t, int32_t) \
+ TEST64 (uint64_t, int16_t) \
+ TEST64 (uint64_t, int8_t) \
+ TEST64N (int64_t, uint64_t) \
+ TEST64N (int64_t, uint32_t) \
+ TEST64N (int64_t, uint16_t) \
+ TEST64N (int64_t, uint8_t) \
+ TEST64N (int64_t, int64_t) \
+ TEST64N (int64_t, int32_t) \
+ TEST64N (int64_t, int16_t) \
+ TEST64N (int64_t, int8_t) \
+ TEST64 (uint32_t, uint64_t) \
+ TEST64 (uint32_t, uint32_t) \
+ TEST64 (uint32_t, uint16_t) \
+ TEST64 (uint32_t, uint8_t) \
+ TEST64 (uint32_t, int64_t) \
+ TEST64 (uint32_t, int32_t) \
+ TEST64 (uint32_t, int16_t) \
+ TEST64 (uint32_t, int8_t) \
+ TEST64N (int32_t, uint64_t) \
+ TEST64N (int32_t, uint32_t) \
+ TEST64N (int32_t, uint16_t) \
+ TEST64N (int32_t, uint8_t) \
+ TEST64N (int32_t, int64_t) \
+ TEST64N (int32_t, int32_t) \
+ TEST64N (int32_t, int16_t) \
+ TEST64N (int32_t, int8_t) \
+ TEST64 (uint16_t, uint64_t) \
+ TEST64 (uint16_t, uint32_t) \
+ TEST64 (uint16_t, uint16_t) \
+ TEST64 (uint16_t, uint8_t) \
+ TEST64 (uint16_t, int64_t) \
+ TEST64 (uint16_t, int32_t) \
+ TEST64 (uint16_t, int16_t) \
+ TEST64 (uint16_t, int8_t) \
+ TEST64N (int16_t, uint64_t) \
+ TEST64N (int16_t, uint32_t) \
+ TEST64N (int16_t, uint16_t) \
+ TEST64N (int16_t, uint8_t) \
+ TEST64N (int16_t, int64_t) \
+ TEST64N (int16_t, int32_t) \
+ TEST64N (int16_t, int16_t) \
+ TEST64N (int16_t, int8_t) \
+ TEST64 (uint8_t, uint64_t) \
+ TEST64 (uint8_t, uint32_t) \
+ TEST64 (uint8_t, uint16_t) \
+ TEST64 (uint8_t, uint8_t) \
+ TEST64 (uint8_t, int64_t) \
+ TEST64 (uint8_t, int32_t) \
+ TEST64 (uint8_t, int16_t) \
+ TEST64 (uint8_t, int8_t) \
+ TEST64N (int8_t, uint64_t) \
+ TEST64N (int8_t, uint32_t) \
+ TEST64N (int8_t, uint16_t) \
+ TEST64N (int8_t, uint8_t) \
+ TEST64N (int8_t, int64_t) \
+ TEST64N (int8_t, int32_t) \
+ TEST64N (int8_t, int16_t) \
+ TEST64N (int8_t, int8_t) \
+ TEST32 (uint64_t, uint64_t) \
+ TEST32 (uint64_t, uint32_t) \
+ TEST32 (uint64_t, uint16_t) \
+ TEST32 (uint64_t, uint8_t) \
+ TEST32 (uint64_t, int64_t) \
+ TEST32 (uint64_t, int32_t) \
+ TEST32 (uint64_t, int16_t) \
+ TEST32 (uint64_t, int8_t) \
+ TEST32N (int64_t, uint64_t) \
+ TEST32N (int64_t, uint32_t) \
+ TEST32N (int64_t, uint16_t) \
+ TEST32N (int64_t, uint8_t) \
+ TEST32N (int64_t, int64_t) \
+ TEST32N (int64_t, int32_t) \
+ TEST32N (int64_t, int16_t) \
+ TEST32N (int64_t, int8_t) \
+ TEST32 (uint32_t, uint64_t) \
+ TEST32 (uint32_t, uint32_t) \
+ TEST32 (uint32_t, uint16_t) \
+ TEST32 (uint32_t, uint8_t) \
+ TEST32 (uint32_t, int64_t) \
+ TEST32 (uint32_t, int32_t) \
+ TEST32 (uint32_t, int16_t) \
+ TEST32 (uint32_t, int8_t) \
+ TEST32N (int32_t, uint64_t) \
+ TEST32N (int32_t, uint32_t) \
+ TEST32N (int32_t, uint16_t) \
+ TEST32N (int32_t, uint8_t) \
+ TEST32N (int32_t, int64_t) \
+ TEST32N (int32_t, int32_t) \
+ TEST32N (int32_t, int16_t) \
+ TEST32N (int32_t, int8_t) \
+ TEST32 (uint16_t, uint64_t) \
+ TEST32 (uint16_t, uint32_t) \
+ TEST32 (uint16_t, uint16_t) \
+ TEST32 (uint16_t, uint8_t) \
+ TEST32 (uint16_t, int64_t) \
+ TEST32 (uint16_t, int32_t) \
+ TEST32 (uint16_t, int16_t) \
+ TEST32 (uint16_t, int8_t) \
+ TEST32N (int16_t, uint64_t) \
+ TEST32N (int16_t, uint32_t) \
+ TEST32N (int16_t, uint16_t) \
+ TEST32N (int16_t, uint8_t) \
+ TEST32N (int16_t, int64_t) \
+ TEST32N (int16_t, int32_t) \
+ TEST32N (int16_t, int16_t) \
+ TEST32N (int16_t, int8_t) \
+ TEST32 (uint8_t, uint64_t) \
+ TEST32 (uint8_t, uint32_t) \
+ TEST32 (uint8_t, uint16_t) \
+ TEST32 (uint8_t, uint8_t) \
+ TEST32 (uint8_t, int64_t) \
+ TEST32 (uint8_t, int32_t) \
+ TEST32 (uint8_t, int16_t) \
+ TEST32 (uint8_t, int8_t) \
+ TEST32N (int8_t, uint64_t) \
+ TEST32N (int8_t, uint32_t) \
+ TEST32N (int8_t, uint16_t) \
+ TEST32N (int8_t, uint8_t) \
+ TEST32N (int8_t, int64_t) \
+ TEST32N (int8_t, int32_t) \
+ TEST32N (int8_t, int16_t) \
+ TEST32N (int8_t, int8_t) \
+ TESTCTZ64 (uint64_t, uint64_t) \
+ TESTCTZ64 (uint64_t, uint32_t) \
+ TESTCTZ64 (uint64_t, uint16_t) \
+ TESTCTZ64 (uint64_t, uint8_t) \
+ TESTCTZ64 (uint64_t, int64_t) \
+ TESTCTZ64 (uint64_t, int32_t) \
+ TESTCTZ64 (uint64_t, int16_t) \
+ TESTCTZ64 (uint64_t, int8_t) \
+ TESTCTZ64N (int64_t, uint64_t) \
+ TESTCTZ64N (int64_t, uint32_t) \
+ TESTCTZ64N (int64_t, uint16_t) \
+ TESTCTZ64N (int64_t, uint8_t) \
+ TESTCTZ64N (int64_t, int64_t) \
+ TESTCTZ64N (int64_t, int32_t) \
+ TESTCTZ64N (int64_t, int16_t) \
+ TESTCTZ64N (int64_t, int8_t) \
+ TESTCTZ64 (uint32_t, uint64_t) \
+ TESTCTZ64 (uint32_t, uint32_t) \
+ TESTCTZ64 (uint32_t, uint16_t) \
+ TESTCTZ64 (uint32_t, uint8_t) \
+ TESTCTZ64 (uint32_t, int64_t) \
+ TESTCTZ64 (uint32_t, int32_t) \
+ TESTCTZ64 (uint32_t, int16_t) \
+ TESTCTZ64 (uint32_t, int8_t) \
+ TESTCTZ64N (int32_t, uint64_t) \
+ TESTCTZ64N (int32_t, uint32_t) \
+ TESTCTZ64N (int32_t, uint16_t) \
+ TESTCTZ64N (int32_t, uint8_t) \
+ TESTCTZ64N (int32_t, int64_t) \
+ TESTCTZ64N (int32_t, int32_t) \
+ TESTCTZ64N (int32_t, int16_t) \
+ TESTCTZ64N (int32_t, int8_t) \
+ TESTCTZ64 (uint16_t, uint64_t) \
+ TESTCTZ64 (uint16_t, uint32_t) \
+ TESTCTZ64 (uint16_t, uint16_t) \
+ TESTCTZ64 (uint16_t, uint8_t) \
+ TESTCTZ64 (uint16_t, int64_t) \
+ TESTCTZ64 (uint16_t, int32_t) \
+ TESTCTZ64 (uint16_t, int16_t) \
+ TESTCTZ64 (uint16_t, int8_t) \
+ TESTCTZ64N (int16_t, uint64_t) \
+ TESTCTZ64N (int16_t, uint32_t) \
+ TESTCTZ64N (int16_t, uint16_t) \
+ TESTCTZ64N (int16_t, uint8_t) \
+ TESTCTZ64N (int16_t, int64_t) \
+ TESTCTZ64N (int16_t, int32_t) \
+ TESTCTZ64N (int16_t, int16_t) \
+ TESTCTZ64N (int16_t, int8_t) \
+ TESTCTZ64 (uint8_t, uint64_t) \
+ TESTCTZ64 (uint8_t, uint32_t) \
+ TESTCTZ64 (uint8_t, uint16_t) \
+ TESTCTZ64 (uint8_t, uint8_t) \
+ TESTCTZ64 (uint8_t, int64_t) \
+ TESTCTZ64 (uint8_t, int32_t) \
+ TESTCTZ64 (uint8_t, int16_t) \
+ TESTCTZ64 (uint8_t, int8_t) \
+ TESTCTZ64N (int8_t, uint64_t) \
+ TESTCTZ64N (int8_t, uint32_t) \
+ TESTCTZ64N (int8_t, uint16_t) \
+ TESTCTZ64N (int8_t, uint8_t) \
+ TESTCTZ64N (int8_t, int64_t) \
+ TESTCTZ64N (int8_t, int32_t) \
+ TESTCTZ64N (int8_t, int16_t) \
+ TESTCTZ64N (int8_t, int8_t) \
+ TESTCTZ32 (uint64_t, uint64_t) \
+ TESTCTZ32 (uint64_t, uint32_t) \
+ TESTCTZ32 (uint64_t, uint16_t) \
+ TESTCTZ32 (uint64_t, uint8_t) \
+ TESTCTZ32 (uint64_t, int64_t) \
+ TESTCTZ32 (uint64_t, int32_t) \
+ TESTCTZ32 (uint64_t, int16_t) \
+ TESTCTZ32 (uint64_t, int8_t) \
+ TESTCTZ32N (int64_t, uint64_t) \
+ TESTCTZ32N (int64_t, uint32_t) \
+ TESTCTZ32N (int64_t, uint16_t) \
+ TESTCTZ32N (int64_t, uint8_t) \
+ TESTCTZ32N (int64_t, int64_t) \
+ TESTCTZ32N (int64_t, int32_t) \
+ TESTCTZ32N (int64_t, int16_t) \
+ TESTCTZ32N (int64_t, int8_t) \
+ TESTCTZ32 (uint32_t, uint64_t) \
+ TESTCTZ32 (uint32_t, uint32_t) \
+ TESTCTZ32 (uint32_t, uint16_t) \
+ TESTCTZ32 (uint32_t, uint8_t) \
+ TESTCTZ32 (uint32_t, int64_t) \
+ TESTCTZ32 (uint32_t, int32_t) \
+ TESTCTZ32 (uint32_t, int16_t) \
+ TESTCTZ32 (uint32_t, int8_t) \
+ TESTCTZ32N (int32_t, uint64_t) \
+ TESTCTZ32N (int32_t, uint32_t) \
+ TESTCTZ32N (int32_t, uint16_t) \
+ TESTCTZ32N (int32_t, uint8_t) \
+ TESTCTZ32N (int32_t, int64_t) \
+ TESTCTZ32N (int32_t, int32_t) \
+ TESTCTZ32N (int32_t, int16_t) \
+ TESTCTZ32N (int32_t, int8_t) \
+ TESTCTZ32 (uint16_t, uint64_t) \
+ TESTCTZ32 (uint16_t, uint32_t) \
+ TESTCTZ32 (uint16_t, uint16_t) \
+ TESTCTZ32 (uint16_t, uint8_t) \
+ TESTCTZ32 (uint16_t, int64_t) \
+ TESTCTZ32 (uint16_t, int32_t) \
+ TESTCTZ32 (uint16_t, int16_t) \
+ TESTCTZ32 (uint16_t, int8_t) \
+ TESTCTZ32N (int16_t, uint64_t) \
+ TESTCTZ32N (int16_t, uint32_t) \
+ TESTCTZ32N (int16_t, uint16_t) \
+ TESTCTZ32N (int16_t, uint8_t) \
+ TESTCTZ32N (int16_t, int64_t) \
+ TESTCTZ32N (int16_t, int32_t) \
+ TESTCTZ32N (int16_t, int16_t) \
+ TESTCTZ32N (int16_t, int8_t) \
+ TESTCTZ32 (uint8_t, uint64_t) \
+ TESTCTZ32 (uint8_t, uint32_t) \
+ TESTCTZ32 (uint8_t, uint16_t) \
+ TESTCTZ32 (uint8_t, uint8_t) \
+ TESTCTZ32 (uint8_t, int64_t) \
+ TESTCTZ32 (uint8_t, int32_t) \
+ TESTCTZ32 (uint8_t, int16_t) \
+ TESTCTZ32 (uint8_t, int8_t) \
+ TESTCTZ32N (int8_t, uint64_t) \
+ TESTCTZ32N (int8_t, uint32_t) \
+ TESTCTZ32N (int8_t, uint16_t) \
+ TESTCTZ32N (int8_t, uint8_t) \
+ TESTCTZ32N (int8_t, int64_t) \
+ TESTCTZ32N (int8_t, int32_t) \
+ TESTCTZ32N (int8_t, int16_t) \
+ TESTCTZ32N (int8_t, int8_t) \
+ TESTFFS64 (uint64_t, uint64_t) \
+ TESTFFS64 (uint64_t, uint32_t) \
+ TESTFFS64 (uint64_t, uint16_t) \
+ TESTFFS64 (uint64_t, uint8_t) \
+ TESTFFS64 (uint64_t, int64_t) \
+ TESTFFS64 (uint64_t, int32_t) \
+ TESTFFS64 (uint64_t, int16_t) \
+ TESTFFS64 (uint64_t, int8_t) \
+ TESTFFS64N (int64_t, uint64_t) \
+ TESTFFS64N (int64_t, uint32_t) \
+ TESTFFS64N (int64_t, uint16_t) \
+ TESTFFS64N (int64_t, uint8_t) \
+ TESTFFS64N (int64_t, int64_t) \
+ TESTFFS64N (int64_t, int32_t) \
+ TESTFFS64N (int64_t, int16_t) \
+ TESTFFS64N (int64_t, int8_t) \
+ TESTFFS64 (uint32_t, uint64_t) \
+ TESTFFS64 (uint32_t, uint32_t) \
+ TESTFFS64 (uint32_t, uint16_t) \
+ TESTFFS64 (uint32_t, uint8_t) \
+ TESTFFS64 (uint32_t, int64_t) \
+ TESTFFS64 (uint32_t, int32_t) \
+ TESTFFS64 (uint32_t, int16_t) \
+ TESTFFS64 (uint32_t, int8_t) \
+ TESTFFS64N (int32_t, uint64_t) \
+ TESTFFS64N (int32_t, uint32_t) \
+ TESTFFS64N (int32_t, uint16_t) \
+ TESTFFS64N (int32_t, uint8_t) \
+ TESTFFS64N (int32_t, int64_t) \
+ TESTFFS64N (int32_t, int32_t) \
+ TESTFFS64N (int32_t, int16_t) \
+ TESTFFS64N (int32_t, int8_t) \
+ TESTFFS64 (uint16_t, uint64_t) \
+ TESTFFS64 (uint16_t, uint32_t) \
+ TESTFFS64 (uint16_t, uint16_t) \
+ TESTFFS64 (uint16_t, uint8_t) \
+ TESTFFS64 (uint16_t, int64_t) \
+ TESTFFS64 (uint16_t, int32_t) \
+ TESTFFS64 (uint16_t, int16_t) \
+ TESTFFS64 (uint16_t, int8_t) \
+ TESTFFS64N (int16_t, uint64_t) \
+ TESTFFS64N (int16_t, uint32_t) \
+ TESTFFS64N (int16_t, uint16_t) \
+ TESTFFS64N (int16_t, uint8_t) \
+ TESTFFS64N (int16_t, int64_t) \
+ TESTFFS64N (int16_t, int32_t) \
+ TESTFFS64N (int16_t, int16_t) \
+ TESTFFS64N (int16_t, int8_t) \
+ TESTFFS64 (uint8_t, uint64_t) \
+ TESTFFS64 (uint8_t, uint32_t) \
+ TESTFFS64 (uint8_t, uint16_t) \
+ TESTFFS64 (uint8_t, uint8_t) \
+ TESTFFS64 (uint8_t, int64_t) \
+ TESTFFS64 (uint8_t, int32_t) \
+ TESTFFS64 (uint8_t, int16_t) \
+ TESTFFS64 (uint8_t, int8_t) \
+ TESTFFS64N (int8_t, uint64_t) \
+ TESTFFS64N (int8_t, uint32_t) \
+ TESTFFS64N (int8_t, uint16_t) \
+ TESTFFS64N (int8_t, uint8_t) \
+ TESTFFS64N (int8_t, int64_t) \
+ TESTFFS64N (int8_t, int32_t) \
+ TESTFFS64N (int8_t, int16_t) \
+ TESTFFS64N (int8_t, int8_t) \
+ TESTFFS32 (uint64_t, uint64_t) \
+ TESTFFS32 (uint64_t, uint32_t) \
+ TESTFFS32 (uint64_t, uint16_t) \
+ TESTFFS32 (uint64_t, uint8_t) \
+ TESTFFS32 (uint64_t, int64_t) \
+ TESTFFS32 (uint64_t, int32_t) \
+ TESTFFS32 (uint64_t, int16_t) \
+ TESTFFS32 (uint64_t, int8_t) \
+ TESTFFS32N (int64_t, uint64_t) \
+ TESTFFS32N (int64_t, uint32_t) \
+ TESTFFS32N (int64_t, uint16_t) \
+ TESTFFS32N (int64_t, uint8_t) \
+ TESTFFS32N (int64_t, int64_t) \
+ TESTFFS32N (int64_t, int32_t) \
+ TESTFFS32N (int64_t, int16_t) \
+ TESTFFS32N (int64_t, int8_t) \
+ TESTFFS32 (uint32_t, uint64_t) \
+ TESTFFS32 (uint32_t, uint32_t) \
+ TESTFFS32 (uint32_t, uint16_t) \
+ TESTFFS32 (uint32_t, uint8_t) \
+ TESTFFS32 (uint32_t, int64_t) \
+ TESTFFS32 (uint32_t, int32_t) \
+ TESTFFS32 (uint32_t, int16_t) \
+ TESTFFS32 (uint32_t, int8_t) \
+ TESTFFS32N (int32_t, uint64_t) \
+ TESTFFS32N (int32_t, uint32_t) \
+ TESTFFS32N (int32_t, uint16_t) \
+ TESTFFS32N (int32_t, uint8_t) \
+ TESTFFS32N (int32_t, int64_t) \
+ TESTFFS32N (int32_t, int32_t) \
+ TESTFFS32N (int32_t, int16_t) \
+ TESTFFS32N (int32_t, int8_t) \
+ TESTFFS32 (uint16_t, uint64_t) \
+ TESTFFS32 (uint16_t, uint32_t) \
+ TESTFFS32 (uint16_t, uint16_t) \
+ TESTFFS32 (uint16_t, uint8_t) \
+ TESTFFS32 (uint16_t, int64_t) \
+ TESTFFS32 (uint16_t, int32_t) \
+ TESTFFS32 (uint16_t, int16_t) \
+ TESTFFS32 (uint16_t, int8_t) \
+ TESTFFS32N (int16_t, uint64_t) \
+ TESTFFS32N (int16_t, uint32_t) \
+ TESTFFS32N (int16_t, uint16_t) \
+ TESTFFS32N (int16_t, uint8_t) \
+ TESTFFS32N (int16_t, int64_t) \
+ TESTFFS32N (int16_t, int32_t) \
+ TESTFFS32N (int16_t, int16_t) \
+ TESTFFS32N (int16_t, int8_t) \
+ TESTFFS32 (uint8_t, uint64_t) \
+ TESTFFS32 (uint8_t, uint32_t) \
+ TESTFFS32 (uint8_t, uint16_t) \
+ TESTFFS32 (uint8_t, uint8_t) \
+ TESTFFS32 (uint8_t, int64_t) \
+ TESTFFS32 (uint8_t, int32_t) \
+ TESTFFS32 (uint8_t, int16_t) \
+ TESTFFS32 (uint8_t, int8_t) \
+ TESTFFS32N (int8_t, uint64_t) \
+ TESTFFS32N (int8_t, uint32_t) \
+ TESTFFS32N (int8_t, uint16_t) \
+ TESTFFS32N (int8_t, uint8_t) \
+ TESTFFS32N (int8_t, int64_t) \
+ TESTFFS32N (int8_t, int32_t) \
+ TESTFFS32N (int8_t, int16_t) \
+ TESTFFS32N (int8_t, int8_t)
+
+TEST_ALL ()
+
+#define RUN64(TYPEDST, TYPESRC) test64_##TYPEDST##TYPESRC ();
+#define RUN64N(TYPEDST, TYPESRC) test64n_##TYPEDST##TYPESRC ();
+#define RUN32(TYPEDST, TYPESRC) test32_##TYPEDST##TYPESRC ();
+#define RUN32N(TYPEDST, TYPESRC) test32n_##TYPEDST##TYPESRC ();
+#define RUNCTZ64(TYPEDST, TYPESRC) testctz64_##TYPEDST##TYPESRC ();
+#define RUNCTZ64N(TYPEDST, TYPESRC) testctz64n_##TYPEDST##TYPESRC ();
+#define RUNCTZ32(TYPEDST, TYPESRC) testctz32_##TYPEDST##TYPESRC ();
+#define RUNCTZ32N(TYPEDST, TYPESRC) testctz32n_##TYPEDST##TYPESRC ();
+#define RUNFFS64(TYPEDST, TYPESRC) testffs64_##TYPEDST##TYPESRC ();
+#define RUNFFS64N(TYPEDST, TYPESRC) testffs64n_##TYPEDST##TYPESRC ();
+#define RUNFFS32(TYPEDST, TYPESRC) testffs32_##TYPEDST##TYPESRC ();
+#define RUNFFS32N(TYPEDST, TYPESRC) testffs32n_##TYPEDST##TYPESRC ();
+
+#define RUN_ALL() \
+ RUN64 (uint64_t, uint64_t) \
+ RUN64 (uint64_t, uint32_t) \
+ RUN64 (uint64_t, uint16_t) \
+ RUN64 (uint64_t, uint8_t) \
+ RUN64 (uint64_t, int64_t) \
+ RUN64 (uint64_t, int32_t) \
+ RUN64 (uint64_t, int16_t) \
+ RUN64 (uint64_t, int8_t) \
+ RUN64N (int64_t, uint64_t) \
+ RUN64N (int64_t, uint32_t) \
+ RUN64N (int64_t, uint16_t) \
+ RUN64N (int64_t, uint8_t) \
+ RUN64N (int64_t, int64_t) \
+ RUN64N (int64_t, int32_t) \
+ RUN64N (int64_t, int16_t) \
+ RUN64N (int64_t, int8_t) \
+ RUN64 (uint32_t, uint64_t) \
+ RUN64 (uint32_t, uint32_t) \
+ RUN64 (uint32_t, uint16_t) \
+ RUN64 (uint32_t, uint8_t) \
+ RUN64 (uint32_t, int64_t) \
+ RUN64 (uint32_t, int32_t) \
+ RUN64 (uint32_t, int16_t) \
+ RUN64 (uint32_t, int8_t) \
+ RUN64N (int32_t, uint64_t) \
+ RUN64N (int32_t, uint32_t) \
+ RUN64N (int32_t, uint16_t) \
+ RUN64N (int32_t, uint8_t) \
+ RUN64N (int32_t, int64_t) \
+ RUN64N (int32_t, int32_t) \
+ RUN64N (int32_t, int16_t) \
+ RUN64N (int32_t, int8_t) \
+ RUN64 (uint16_t, uint64_t) \
+ RUN64 (uint16_t, uint32_t) \
+ RUN64 (uint16_t, uint16_t) \
+ RUN64 (uint16_t, uint8_t) \
+ RUN64 (uint16_t, int64_t) \
+ RUN64 (uint16_t, int32_t) \
+ RUN64 (uint16_t, int16_t) \
+ RUN64 (uint16_t, int8_t) \
+ RUN64N (int16_t, uint64_t) \
+ RUN64N (int16_t, uint32_t) \
+ RUN64N (int16_t, uint16_t) \
+ RUN64N (int16_t, uint8_t) \
+ RUN64N (int16_t, int64_t) \
+ RUN64N (int16_t, int32_t) \
+ RUN64N (int16_t, int16_t) \
+ RUN64N (int16_t, int8_t) \
+ RUN64 (uint8_t, uint64_t) \
+ RUN64 (uint8_t, uint32_t) \
+ RUN64 (uint8_t, uint16_t) \
+ RUN64 (uint8_t, uint8_t) \
+ RUN64 (uint8_t, int64_t) \
+ RUN64 (uint8_t, int32_t) \
+ RUN64 (uint8_t, int16_t) \
+ RUN64 (uint8_t, int8_t) \
+ RUN64N (int8_t, uint64_t) \
+ RUN64N (int8_t, uint32_t) \
+ RUN64N (int8_t, uint16_t) \
+ RUN64N (int8_t, uint8_t) \
+ RUN64N (int8_t, int64_t) \
+ RUN64N (int8_t, int32_t) \
+ RUN64N (int8_t, int16_t) \
+ RUN64N (int8_t, int8_t) \
+ RUN32 (uint64_t, uint64_t) \
+ RUN32 (uint64_t, uint32_t) \
+ RUN32 (uint64_t, uint16_t) \
+ RUN32 (uint64_t, uint8_t) \
+ RUN32 (uint64_t, int64_t) \
+ RUN32 (uint64_t, int32_t) \
+ RUN32 (uint64_t, int16_t) \
+ RUN32 (uint64_t, int8_t) \
+ RUN32N (int64_t, uint64_t) \
+ RUN32N (int64_t, uint32_t) \
+ RUN32N (int64_t, uint16_t) \
+ RUN32N (int64_t, uint8_t) \
+ RUN32N (int64_t, int64_t) \
+ RUN32N (int64_t, int32_t) \
+ RUN32N (int64_t, int16_t) \
+ RUN32N (int64_t, int8_t) \
+ RUN32 (uint32_t, uint64_t) \
+ RUN32 (uint32_t, uint32_t) \
+ RUN32 (uint32_t, uint16_t) \
+ RUN32 (uint32_t, uint8_t) \
+ RUN32 (uint32_t, int64_t) \
+ RUN32 (uint32_t, int32_t) \
+ RUN32 (uint32_t, int16_t) \
+ RUN32 (uint32_t, int8_t) \
+ RUN32N (int32_t, uint64_t) \
+ RUN32N (int32_t, uint32_t) \
+ RUN32N (int32_t, uint16_t) \
+ RUN32N (int32_t, uint8_t) \
+ RUN32N (int32_t, int64_t) \
+ RUN32N (int32_t, int32_t) \
+ RUN32N (int32_t, int16_t) \
+ RUN32N (int32_t, int8_t) \
+ RUN32 (uint16_t, uint64_t) \
+ RUN32 (uint16_t, uint32_t) \
+ RUN32 (uint16_t, uint16_t) \
+ RUN32 (uint16_t, uint8_t) \
+ RUN32 (uint16_t, int64_t) \
+ RUN32 (uint16_t, int32_t) \
+ RUN32 (uint16_t, int16_t) \
+ RUN32 (uint16_t, int8_t) \
+ RUN32N (int16_t, uint64_t) \
+ RUN32N (int16_t, uint32_t) \
+ RUN32N (int16_t, uint16_t) \
+ RUN32N (int16_t, uint8_t) \
+ RUN32N (int16_t, int64_t) \
+ RUN32N (int16_t, int32_t) \
+ RUN32N (int16_t, int16_t) \
+ RUN32N (int16_t, int8_t) \
+ RUN32 (uint8_t, uint64_t) \
+ RUN32 (uint8_t, uint32_t) \
+ RUN32 (uint8_t, uint16_t) \
+ RUN32 (uint8_t, uint8_t) \
+ RUN32 (uint8_t, int64_t) \
+ RUN32 (uint8_t, int32_t) \
+ RUN32 (uint8_t, int16_t) \
+ RUN32 (uint8_t, int8_t) \
+ RUN32N (int8_t, uint64_t) \
+ RUN32N (int8_t, uint32_t) \
+ RUN32N (int8_t, uint16_t) \
+ RUN32N (int8_t, uint8_t) \
+ RUN32N (int8_t, int64_t) \
+ RUN32N (int8_t, int32_t) \
+ RUN32N (int8_t, int16_t) \
+ RUN32N (int8_t, int8_t) \
+ RUNCTZ64 (uint64_t, uint64_t) \
+ RUNCTZ64 (uint64_t, uint32_t) \
+ RUNCTZ64 (uint64_t, uint16_t) \
+ RUNCTZ64 (uint64_t, uint8_t) \
+ RUNCTZ64 (uint64_t, int64_t) \
+ RUNCTZ64 (uint64_t, int32_t) \
+ RUNCTZ64 (uint64_t, int16_t) \
+ RUNCTZ64 (uint64_t, int8_t) \
+ RUNCTZ64N (int64_t, uint64_t) \
+ RUNCTZ64N (int64_t, uint32_t) \
+ RUNCTZ64N (int64_t, uint16_t) \
+ RUNCTZ64N (int64_t, uint8_t) \
+ RUNCTZ64N (int64_t, int64_t) \
+ RUNCTZ64N (int64_t, int32_t) \
+ RUNCTZ64N (int64_t, int16_t) \
+ RUNCTZ64N (int64_t, int8_t) \
+ RUNCTZ64 (uint32_t, uint64_t) \
+ RUNCTZ64 (uint32_t, uint32_t) \
+ RUNCTZ64 (uint32_t, uint16_t) \
+ RUNCTZ64 (uint32_t, uint8_t) \
+ RUNCTZ64 (uint32_t, int64_t) \
+ RUNCTZ64 (uint32_t, int32_t) \
+ RUNCTZ64 (uint32_t, int16_t) \
+ RUNCTZ64 (uint32_t, int8_t) \
+ RUNCTZ64N (int32_t, uint64_t) \
+ RUNCTZ64N (int32_t, uint32_t) \
+ RUNCTZ64N (int32_t, uint16_t) \
+ RUNCTZ64N (int32_t, uint8_t) \
+ RUNCTZ64N (int32_t, int64_t) \
+ RUNCTZ64N (int32_t, int32_t) \
+ RUNCTZ64N (int32_t, int16_t) \
+ RUNCTZ64N (int32_t, int8_t) \
+ RUNCTZ64 (uint16_t, uint64_t) \
+ RUNCTZ64 (uint16_t, uint32_t) \
+ RUNCTZ64 (uint16_t, uint16_t) \
+ RUNCTZ64 (uint16_t, uint8_t) \
+ RUNCTZ64 (uint16_t, int64_t) \
+ RUNCTZ64 (uint16_t, int32_t) \
+ RUNCTZ64 (uint16_t, int16_t) \
+ RUNCTZ64 (uint16_t, int8_t) \
+ RUNCTZ64N (int16_t, uint64_t) \
+ RUNCTZ64N (int16_t, uint32_t) \
+ RUNCTZ64N (int16_t, uint16_t) \
+ RUNCTZ64N (int16_t, uint8_t) \
+ RUNCTZ64N (int16_t, int64_t) \
+ RUNCTZ64N (int16_t, int32_t) \
+ RUNCTZ64N (int16_t, int16_t) \
+ RUNCTZ64N (int16_t, int8_t) \
+ RUNCTZ64 (uint8_t, uint64_t) \
+ RUNCTZ64 (uint8_t, uint32_t) \
+ RUNCTZ64 (uint8_t, uint16_t) \
+ RUNCTZ64 (uint8_t, uint8_t) \
+ RUNCTZ64 (uint8_t, int64_t) \
+ RUNCTZ64 (uint8_t, int32_t) \
+ RUNCTZ64 (uint8_t, int16_t) \
+ RUNCTZ64 (uint8_t, int8_t) \
+ RUNCTZ64N (int8_t, uint64_t) \
+ RUNCTZ64N (int8_t, uint32_t) \
+ RUNCTZ64N (int8_t, uint16_t) \
+ RUNCTZ64N (int8_t, uint8_t) \
+ RUNCTZ64N (int8_t, int64_t) \
+ RUNCTZ64N (int8_t, int32_t) \
+ RUNCTZ64N (int8_t, int16_t) \
+ RUNCTZ64N (int8_t, int8_t) \
+ RUNCTZ32 (uint64_t, uint64_t) \
+ RUNCTZ32 (uint64_t, uint32_t) \
+ RUNCTZ32 (uint64_t, uint16_t) \
+ RUNCTZ32 (uint64_t, uint8_t) \
+ RUNCTZ32 (uint64_t, int64_t) \
+ RUNCTZ32 (uint64_t, int32_t) \
+ RUNCTZ32 (uint64_t, int16_t) \
+ RUNCTZ32 (uint64_t, int8_t) \
+ RUNCTZ32N (int64_t, uint64_t) \
+ RUNCTZ32N (int64_t, uint32_t) \
+ RUNCTZ32N (int64_t, uint16_t) \
+ RUNCTZ32N (int64_t, uint8_t) \
+ RUNCTZ32N (int64_t, int64_t) \
+ RUNCTZ32N (int64_t, int32_t) \
+ RUNCTZ32N (int64_t, int16_t) \
+ RUNCTZ32N (int64_t, int8_t) \
+ RUNCTZ32 (uint32_t, uint64_t) \
+ RUNCTZ32 (uint32_t, uint32_t) \
+ RUNCTZ32 (uint32_t, uint16_t) \
+ RUNCTZ32 (uint32_t, uint8_t) \
+ RUNCTZ32 (uint32_t, int64_t) \
+ RUNCTZ32 (uint32_t, int32_t) \
+ RUNCTZ32 (uint32_t, int16_t) \
+ RUNCTZ32 (uint32_t, int8_t) \
+ RUNCTZ32N (int32_t, uint64_t) \
+ RUNCTZ32N (int32_t, uint32_t) \
+ RUNCTZ32N (int32_t, uint16_t) \
+ RUNCTZ32N (int32_t, uint8_t) \
+ RUNCTZ32N (int32_t, int64_t) \
+ RUNCTZ32N (int32_t, int32_t) \
+ RUNCTZ32N (int32_t, int16_t) \
+ RUNCTZ32N (int32_t, int8_t) \
+ RUNCTZ32 (uint16_t, uint64_t) \
+ RUNCTZ32 (uint16_t, uint32_t) \
+ RUNCTZ32 (uint16_t, uint16_t) \
+ RUNCTZ32 (uint16_t, uint8_t) \
+ RUNCTZ32 (uint16_t, int64_t) \
+ RUNCTZ32 (uint16_t, int32_t) \
+ RUNCTZ32 (uint16_t, int16_t) \
+ RUNCTZ32 (uint16_t, int8_t) \
+ RUNCTZ32N (int16_t, uint64_t) \
+ RUNCTZ32N (int16_t, uint32_t) \
+ RUNCTZ32N (int16_t, uint16_t) \
+ RUNCTZ32N (int16_t, uint8_t) \
+ RUNCTZ32N (int16_t, int64_t) \
+ RUNCTZ32N (int16_t, int32_t) \
+ RUNCTZ32N (int16_t, int16_t) \
+ RUNCTZ32N (int16_t, int8_t) \
+ RUNCTZ32 (uint8_t, uint64_t) \
+ RUNCTZ32 (uint8_t, uint32_t) \
+ RUNCTZ32 (uint8_t, uint16_t) \
+ RUNCTZ32 (uint8_t, uint8_t) \
+ RUNCTZ32 (uint8_t, int64_t) \
+ RUNCTZ32 (uint8_t, int32_t) \
+ RUNCTZ32 (uint8_t, int16_t) \
+ RUNCTZ32 (uint8_t, int8_t) \
+ RUNCTZ32N (int8_t, uint64_t) \
+ RUNCTZ32N (int8_t, uint32_t) \
+ RUNCTZ32N (int8_t, uint16_t) \
+ RUNCTZ32N (int8_t, uint8_t) \
+ RUNCTZ32N (int8_t, int64_t) \
+ RUNCTZ32N (int8_t, int32_t) \
+ RUNCTZ32N (int8_t, int16_t) \
+ RUNCTZ32N (int8_t, int8_t) \
+ RUNFFS64 (uint64_t, uint64_t) \
+ RUNFFS64 (uint64_t, uint32_t) \
+ RUNFFS64 (uint64_t, uint16_t) \
+ RUNFFS64 (uint64_t, uint8_t) \
+ RUNFFS64 (uint64_t, int64_t) \
+ RUNFFS64 (uint64_t, int32_t) \
+ RUNFFS64 (uint64_t, int16_t) \
+ RUNFFS64 (uint64_t, int8_t) \
+ RUNFFS64N (int64_t, uint64_t) \
+ RUNFFS64N (int64_t, uint32_t) \
+ RUNFFS64N (int64_t, uint16_t) \
+ RUNFFS64N (int64_t, uint8_t) \
+ RUNFFS64N (int64_t, int64_t) \
+ RUNFFS64N (int64_t, int32_t) \
+ RUNFFS64N (int64_t, int16_t) \
+ RUNFFS64N (int64_t, int8_t) \
+ RUNFFS64 (uint32_t, uint64_t) \
+ RUNFFS64 (uint32_t, uint32_t) \
+ RUNFFS64 (uint32_t, uint16_t) \
+ RUNFFS64 (uint32_t, uint8_t) \
+ RUNFFS64 (uint32_t, int64_t) \
+ RUNFFS64 (uint32_t, int32_t) \
+ RUNFFS64 (uint32_t, int16_t) \
+ RUNFFS64 (uint32_t, int8_t) \
+ RUNFFS64N (int32_t, uint64_t) \
+ RUNFFS64N (int32_t, uint32_t) \
+ RUNFFS64N (int32_t, uint16_t) \
+ RUNFFS64N (int32_t, uint8_t) \
+ RUNFFS64N (int32_t, int64_t) \
+ RUNFFS64N (int32_t, int32_t) \
+ RUNFFS64N (int32_t, int16_t) \
+ RUNFFS64N (int32_t, int8_t) \
+ RUNFFS64 (uint16_t, uint64_t) \
+ RUNFFS64 (uint16_t, uint32_t) \
+ RUNFFS64 (uint16_t, uint16_t) \
+ RUNFFS64 (uint16_t, uint8_t) \
+ RUNFFS64 (uint16_t, int64_t) \
+ RUNFFS64 (uint16_t, int32_t) \
+ RUNFFS64 (uint16_t, int16_t) \
+ RUNFFS64 (uint16_t, int8_t) \
+ RUNFFS64N (int16_t, uint64_t) \
+ RUNFFS64N (int16_t, uint32_t) \
+ RUNFFS64N (int16_t, uint16_t) \
+ RUNFFS64N (int16_t, uint8_t) \
+ RUNFFS64N (int16_t, int64_t) \
+ RUNFFS64N (int16_t, int32_t) \
+ RUNFFS64N (int16_t, int16_t) \
+ RUNFFS64N (int16_t, int8_t) \
+ RUNFFS64 (uint8_t, uint64_t) \
+ RUNFFS64 (uint8_t, uint32_t) \
+ RUNFFS64 (uint8_t, uint16_t) \
+ RUNFFS64 (uint8_t, uint8_t) \
+ RUNFFS64 (uint8_t, int64_t) \
+ RUNFFS64 (uint8_t, int32_t) \
+ RUNFFS64 (uint8_t, int16_t) \
+ RUNFFS64 (uint8_t, int8_t) \
+ RUNFFS64N (int8_t, uint64_t) \
+ RUNFFS64N (int8_t, uint32_t) \
+ RUNFFS64N (int8_t, uint16_t) \
+ RUNFFS64N (int8_t, uint8_t) \
+ RUNFFS64N (int8_t, int64_t) \
+ RUNFFS64N (int8_t, int32_t) \
+ RUNFFS64N (int8_t, int16_t) \
+ RUNFFS64N (int8_t, int8_t) \
+ RUNFFS32 (uint64_t, uint64_t) \
+ RUNFFS32 (uint64_t, uint32_t) \
+ RUNFFS32 (uint64_t, uint16_t) \
+ RUNFFS32 (uint64_t, uint8_t) \
+ RUNFFS32 (uint64_t, int64_t) \
+ RUNFFS32 (uint64_t, int32_t) \
+ RUNFFS32 (uint64_t, int16_t) \
+ RUNFFS32 (uint64_t, int8_t) \
+ RUNFFS32N (int64_t, uint64_t) \
+ RUNFFS32N (int64_t, uint32_t) \
+ RUNFFS32N (int64_t, uint16_t) \
+ RUNFFS32N (int64_t, uint8_t) \
+ RUNFFS32N (int64_t, int64_t) \
+ RUNFFS32N (int64_t, int32_t) \
+ RUNFFS32N (int64_t, int16_t) \
+ RUNFFS32N (int64_t, int8_t) \
+ RUNFFS32 (uint32_t, uint64_t) \
+ RUNFFS32 (uint32_t, uint32_t) \
+ RUNFFS32 (uint32_t, uint16_t) \
+ RUNFFS32 (uint32_t, uint8_t) \
+ RUNFFS32 (uint32_t, int64_t) \
+ RUNFFS32 (uint32_t, int32_t) \
+ RUNFFS32 (uint32_t, int16_t) \
+ RUNFFS32 (uint32_t, int8_t) \
+ RUNFFS32N (int32_t, uint64_t) \
+ RUNFFS32N (int32_t, uint32_t) \
+ RUNFFS32N (int32_t, uint16_t) \
+ RUNFFS32N (int32_t, uint8_t) \
+ RUNFFS32N (int32_t, int64_t) \
+ RUNFFS32N (int32_t, int32_t) \
+ RUNFFS32N (int32_t, int16_t) \
+ RUNFFS32N (int32_t, int8_t) \
+ RUNFFS32 (uint16_t, uint64_t) \
+ RUNFFS32 (uint16_t, uint32_t) \
+ RUNFFS32 (uint16_t, uint16_t) \
+ RUNFFS32 (uint16_t, uint8_t) \
+ RUNFFS32 (uint16_t, int64_t) \
+ RUNFFS32 (uint16_t, int32_t) \
+ RUNFFS32 (uint16_t, int16_t) \
+ RUNFFS32 (uint16_t, int8_t) \
+ RUNFFS32N (int16_t, uint64_t) \
+ RUNFFS32N (int16_t, uint32_t) \
+ RUNFFS32N (int16_t, uint16_t) \
+ RUNFFS32N (int16_t, uint8_t) \
+ RUNFFS32N (int16_t, int64_t) \
+ RUNFFS32N (int16_t, int32_t) \
+ RUNFFS32N (int16_t, int16_t) \
+ RUNFFS32N (int16_t, int8_t) \
+ RUNFFS32 (uint8_t, uint64_t) \
+ RUNFFS32 (uint8_t, uint32_t) \
+ RUNFFS32 (uint8_t, uint16_t) \
+ RUNFFS32 (uint8_t, uint8_t) \
+ RUNFFS32 (uint8_t, int64_t) \
+ RUNFFS32 (uint8_t, int32_t) \
+ RUNFFS32 (uint8_t, int16_t) \
+ RUNFFS32 (uint8_t, int8_t) \
+ RUNFFS32N (int8_t, uint64_t) \
+ RUNFFS32N (int8_t, uint32_t) \
+ RUNFFS32N (int8_t, uint16_t) \
+ RUNFFS32N (int8_t, uint8_t) \
+ RUNFFS32N (int8_t, int64_t) \
+ RUNFFS32N (int8_t, int32_t) \
+ RUNFFS32N (int8_t, int16_t) \
+ RUNFFS32N (int8_t, int8_t)
+
+int
+main ()
+{
+ RUN_ALL ()
+}
+
+/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 229 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vv_constraint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vv_constraint-1.c
index 3372ec1..4fc7f40 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vv_constraint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vv_constraint-1.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
** vadd\.vv\tv[1-9][0-9]?,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
** vadd\.vv\tv[1-9][0-9]?,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-1.c
index 09e0e21..9a248bf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-1.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vadd\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vadd\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-10.c
index faf5ffb..c40d676 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-10.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vand\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vand\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-11.c
index 54fe941..b9b09a8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-11.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-11.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vand\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vand\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-12.c
index 8a18a1d..634c12a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-12.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-12.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-129.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-129.c
index db5dfe1..b99628b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-129.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-129.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmseq\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmseq\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmseq\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-13.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-13.c
index d844e1b..4d8e641 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-13.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-13.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vor\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vor\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-130.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-130.c
index da6b02d..47c984b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-130.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-130.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmseq\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmseq\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmseq\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-131.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-131.c
index 16d35c8..b6e12b3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-131.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-131.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmseq\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmseq\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmseq\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-133.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-133.c
index 2da8ab7..f6d0d7f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-133.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-133.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmslt\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-134.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-134.c
index a83fee4..ff39b24 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-134.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-134.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmslt\.vi\tv[0-9]+,\s*v[0-9]+,\s*-15
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vi\tv[0-9]+,\s*v[0-9]+,\s*-15
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vi\tv[0-9]+,\s*v[0-9]+,\s*-15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-135.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-135.c
index 7679876..4852601 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-135.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-135.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmslt\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-14.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-14.c
index 6779dfe..4c07a33 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-14.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-14.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-15.c
index 611a86f..82cc944 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-15.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-15.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-153.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-153.c
index a941bcd..a0f6c67 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-153.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-153.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmslt\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -26,9 +26,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -51,9 +51,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmslt\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-154.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-154.c
index ddbde57..8e18d76 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-154.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-154.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*-15
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*-15
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*-15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-155.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-155.c
index d22f3e4..4b5e681 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-155.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-155.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-158.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-158.c
index d22f3e4..4b5e681 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-158.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-158.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
@@ -47,9 +47,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,t[au],m[au]
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmsge\.vi\tv[0-9]+,\s*v[0-9]+,\s*16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-16.c
index 0a7a1e8..651d610 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-16.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-17.c
index eeea351..d19a9fd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-17.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-17.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-171.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-171.c
index 6e8669a..591a99e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-171.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-171.c
@@ -7,10 +7,6 @@
/*
** f1:
** ...
-** vsetivli\t[a-x0-9]+,\s*4,e64,m1,t[au],m[au]
-** ...
-** vsetvli\tzero,\s*[a-x0-9]+,e32,m1,tu,m[au]
-** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -41,10 +37,6 @@ void f1 (void * in, void *out, int64_t x, int n)
/*
** f2:
** ...
-** vsetivli\t[a-x0-9]+,\s*4,e64,m1,t[au],m[au]
-** ...
-** vsetvli\tzero,\s*[a-x0-9]+,e32,m1,tu,m[au]
-** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-172.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-172.c
index 060c853..ae48b08 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-172.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-172.c
@@ -7,8 +7,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,\s*4,e32,m1,tu,m[au]
-** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -39,8 +37,6 @@ void f1 (void * in, void *out, int64_t x, int n)
/*
** f2:
** ...
-** vsetivli\tzero,\s*4,e32,m1,tu,m[au]
-** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-173.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-173.c
index af9c45e..ca68cc5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-173.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-173.c
@@ -7,10 +7,6 @@
/*
** f1:
** ...
-** vsetvli\t[a-x0-9]+,\s*[a-x0-9]+,e64,m1,t[au],m[au]
-** ...
-** vsetvli\tzero,\s*[a-x0-9]+,e32,m1,tu,m[au]
-** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -41,10 +37,6 @@ void f1 (void * in, void *out, int64_t x, int vl)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,\s*[a-x0-9]+,e64,m1,t[au],m[au]
-** ...
-** vsetvli\tzero,\s*[a-x0-9]+,e32,m1,tu,m[au]
-** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-174.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-174.c
index f2e5d40..c566db4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-174.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-174.c
@@ -7,8 +7,6 @@
/*
** f1:
** ...
-** vsetvli\t[a-x0-9]+,\s*zero,e32,m1,tu,m[au]
-** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1down\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -39,8 +37,6 @@ void f1 (void * in, void *out, int64_t x, int vl)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,\s*zero,e32,m1,tu,m[au]
-** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** ...
** vslide1up\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-18.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-18.c
index 328564f..db89600 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-18.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-18.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmul\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmul\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmul\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-19.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-19.c
index f4616b4..16f4315 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-19.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-19.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-2.c
index 2c02c35..9c40181 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-2.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-20.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-20.c
index 4415736..d5c1dcf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-20.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-20.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmax\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmax\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmax\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-21.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-21.c
index c082f40..347c846 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-21.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-21.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-22.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-22.c
index b481362..28a1bc1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-22.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-22.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmin\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmin\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmin\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-23.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-23.c
index fd6fd67..bc41444 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-23.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-23.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-24.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-24.c
index d8ed5b1..eb74df5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-24.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-24.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, uint32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmaxu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, uint32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, uint32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, uint8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vmaxu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, uint8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vmaxu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-25.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-25.c
index 66891ac..ce3f3af 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-25.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-25.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-26.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-26.c
index b70a136..9b578cc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-26.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-26.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, uint32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vminu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, uint32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, uint32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, uint8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vminu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, uint8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vminu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-27.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-27.c
index 6f06829..4946f84 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-27.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-27.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-28.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-28.c
index a239a33..b1ca4cb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-28.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-28.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vdiv\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vdiv\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdiv\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-29.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-29.c
index 9424a46..5f2eede 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-29.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-29.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-3.c
index 1da0cb6..21c1fc5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-3.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-30.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-30.c
index 272c0ea..a9ac723 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-30.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-30.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, uint32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vdivu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, uint32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, uint32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, uint8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vdivu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, uint8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-31.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-31.c
index 9424a46..5f2eede 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-31.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-31.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-32.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-32.c
index 272c0ea..a9ac723 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-32.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, uint32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vdivu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, uint32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, uint32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, uint8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vdivu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, uint8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vdivu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-33.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-33.c
index 6f2bca4..88fcba6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-33.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-33.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-34.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-34.c
index 45015d7..edb35c8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-34.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-34.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, uint32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vremu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, uint32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, uint32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, uint8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vremu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, uint8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-35.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-35.c
index 6f2bca4..88fcba6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-35.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-35.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-36.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-36.c
index 45015d7..edb35c8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-36.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-36.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, uint32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vremu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, uint32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, uint32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, uint8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vremu\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, uint8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vremu\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-37.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-37.c
index 34de445..10322b6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-37.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-37.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vsub\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vsub\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-38.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-38.c
index 1374bec..45452fe 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-38.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-38.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-39.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-39.c
index 21b77b9..ff470b3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-39.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-39.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-4.c
index 297ed23..87a1645 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-4.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-40.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-40.c
index 653f043..c0321ce 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-40.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-40.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-41.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-41.c
index 4ff352b..7b6a1a8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-41.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-41.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vrsub\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vrsub\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-42.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-42.c
index 975ebe7..42f7ba4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-42.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-42.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vrsub\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vrsub\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-43.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-43.c
index 4f3e906..55583298 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-43.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-43.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vrsub\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vrsub\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-44.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-44.c
index d4dc4e0..ab0f13b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-44.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-44.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vrsub\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-5.c
index 29eab66..0600f98 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-5.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vxor\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vxor\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-6.c
index 67fd655..dae7aaa 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-6.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vxor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
** vxor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-7.c
index 71a320a..8b80a7f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-7.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vxor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
** vxor\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*15,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vi\tv[0-9]+,\s*v[0-9]+,\s*15
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-8.c
index 797abbd..9bf9ff5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-8.c
@@ -6,8 +6,6 @@
/*
** f1:
** ...
-** vsetivli\tzero,4,e32,m1,tu,ma
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -29,12 +27,8 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
-** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -56,12 +50,8 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,tu,mu
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
@@ -85,8 +75,6 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
** ...
-** vsetivli\tzero,4,e8,mf8,tu,ma
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
@@ -108,12 +96,8 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,ta,ma
-** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** ...
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -135,12 +119,8 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
** ...
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
-** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e8,mf8,tu,mu
-** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vxor\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-9.c
index ce786e1..e92fe0c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-9.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vand\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out, int32_t x)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out, int8_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
** vand\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out, int8_t x)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vand\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c
new file mode 100644
index 0000000..0b936d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O0 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+inline vuint32m4_t __attribute__((__always_inline__)) transpose_indexes() {
+ static const uint32_t idx_[16] = {0, 4, 8, 12,
+ 1, 5, 9, 13,
+ 2, 6, 10, 14,
+ 3, 7, 11, 15};
+ return __riscv_vle32_v_u32m4(idx_, 16);
+}
+
+void pffft_real_preprocess_4x4(const float *in) {
+ vfloat32m1_t r0=__riscv_vle32_v_f32m1(in,4);
+ vfloat32m4_t tmp = __riscv_vundefined_f32m4();
+ tmp = __riscv_vset_v_f32m1_f32m4(tmp, 0, r0);
+ tmp = __riscv_vset_v_f32m1_f32m4(tmp, 1, r0);
+ tmp = __riscv_vset_v_f32m1_f32m4(tmp, 2, r0);
+ tmp = __riscv_vset_v_f32m1_f32m4(tmp, 3, r0);
+ tmp = __riscv_vrgather_vv_f32m4(tmp, transpose_indexes(), 16);
+ r0 = __riscv_vget_v_f32m4_f32m1(tmp, 0);
+}
+
+/* { dg-final { scan-assembler-times {vl[0-9]+re[0-9]+\.v\s+v[0-9]+,\s*0\([a-z]+[0-9]+\)} 10 } } */
+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*0\([a-z]+[0-9]+\)} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/shift_vx_constraint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/shift_vx_constraint-1.c
index e40e193..250e017 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/shift_vx_constraint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/shift_vx_constraint-1.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vsll\.vi\tv[0-9]+,\s*v[0-9]+,31
@@ -24,10 +24,9 @@ void f1 (void * in, void *out)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-** vsetivli\tzero,4,e32,m1,ta,ma
** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsll\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -48,9 +47,9 @@ void f2 (void * in, void *out)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsll\.vi\tv[0-9]+,\s*v[0-9]+,\s*17
@@ -71,7 +70,7 @@ void f3 (void * in, void *out)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vsll\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
@@ -90,9 +89,9 @@ void f4 (void * in, void *out, size_t x)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsll\.vi\tv[0-9]+,\s*v[0-9]+,\s*5
** vsll\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*5,\s*v0.t
@@ -112,9 +111,9 @@ void f5 (void * in, void *out)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsll\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-1.c
index 838776e..7d0a44e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-1.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -30,7 +30,7 @@ void f1 (void * in, void * in2, void *out)
/*
** f2:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -55,7 +55,7 @@ void f2 (void * in, void * in2, void *out)
/*
** f3:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vlm\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-2.c
index 54506c1..61345f0 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-2.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -30,7 +30,7 @@ void f1 (void * in, void * in2, void *out)
/*
** f2:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -55,7 +55,7 @@ void f2 (void * in, void * in2, void *out)
/*
** f3:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vlm\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-3.c
index 5ff07da..100f12e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-3.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -30,7 +30,7 @@ void f1 (void * in, void * in2, void *out)
/*
** f2:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -55,7 +55,7 @@ void f2 (void * in, void * in2, void *out)
/*
** f3:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vlm\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-4.c
index c280d97..4dd09ae 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-4.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -30,7 +30,7 @@ void f1 (void * in, void * in2, void *out)
/*
** f2:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -55,7 +55,7 @@ void f2 (void * in, void * in2, void *out)
/*
** f3:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vlm\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-5.c
index 1f71aa8..02263b5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-5.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfnma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -30,7 +30,7 @@ void f1 (void * in, void * in2, void *out)
/*
** f2:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfnma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -55,7 +55,7 @@ void f2 (void * in, void * in2, void *out)
/*
** f3:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vlm\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-6.c
index 2d2ed66..db77dff 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vv_constraint-6.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfnma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -30,7 +30,7 @@ void f1 (void * in, void * in2, void *out)
/*
** f2:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfnma[c-d][c-d]\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -55,7 +55,7 @@ void f2 (void * in, void * in2, void *out)
/*
** f3:
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vlm\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-1.c
index 90e1206..99083a4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-1.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vma[c-d][c-d]\.vx\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, int32_t x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vma[c-d][c-d]\.vx\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
@@ -47,9 +47,9 @@ void f2 (void * in, void * in2, void *out, int32_t x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vma[c-d][c-d]\.vx\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-8.c
index 82e1473..6d0cd29 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-8.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfma[c-d][c-d]\.vf\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, float x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vfma[c-d][c-d]\.vf\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
@@ -47,9 +47,9 @@ void f2 (void * in, void * in2, void *out, float x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vfma[c-d][c-d]\.vf\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-9.c
index 1beed49..db86eaa 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/ternop_vx_constraint-9.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vfnma[c-d][c-d]\.vf\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void * in2, void *out, float x)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vfnma[c-d][c-d]\.vf\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
@@ -47,9 +47,9 @@ void f2 (void * in, void * in2, void *out, float x)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vle32.v\tv[0-9]+,0\([a-x0-9]+\)
** vfnma[c-d][c-d]\.vf\tv[0-9]+,\s*[a-x0-9]+,\s*v[0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c
new file mode 100644
index 0000000..174860d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat16mf4x2_t
+test_vundefined_f16mf4x2 ()
+{
+ return __riscv_vundefined_f16mf4x2 ();
+}
+
+vfloat32m1x3_t
+test_vundefined_f32m1x3 ()
+{
+ return __riscv_vundefined_f32m1x3 ();
+}
+
+vfloat64m1x5_t
+test_vundefined_f64m1x5 ()
+{
+ return __riscv_vundefined_f64m1x5 ();
+}
+
+vint8mf4x2_t
+test_vundefined_i8mf4x2 ()
+{
+ return __riscv_vundefined_i8mf4x2 ();
+}
+
+vint16mf4x8_t
+test_vundefined_i16mf4x8 ()
+{
+ return __riscv_vundefined_i16mf4x8 ();
+}
+
+vint32m1x7_t
+test_vundefined_i32m1x7 ()
+{
+ return __riscv_vundefined_i32m1x7 ();
+}
+
+vint64m1x4_t
+test_vundefined_i64m1x4 ()
+{
+ return __riscv_vundefined_i64m1x4 ();
+}
+
+vuint8mf8x2_t
+test_vundefined_u8mf8x2 ()
+{
+ return __riscv_vundefined_u8mf8x2 ();
+}
+
+vuint16mf4x4_t
+test_vundefined_u16mf4x4 ()
+{
+ return __riscv_vundefined_u16mf4x4 ();
+}
+
+vuint32m1x7_t
+test_vundefined_u32m1x7 ()
+{
+ return __riscv_vundefined_u32m1x7 ();
+}
+
+vuint64m4x2_t
+test_vundefined_u64m4x2 ()
+{
+ return __riscv_vundefined_u64m4x2 ();
+}
+
+/* { dg-final { scan-assembler-times {vse[0-9]+\.v\s+v[0-9]+,\s*0\([0-9ax]+\)} 18 } } */
+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 28 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-1.c
index 1266784..64f4407 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-1.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vneg\.v\tv[0-9]+,\s*v[0-9]+
@@ -24,9 +24,9 @@ void f1 (void * in, void *out)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vneg\.v\tv[0-9]+,\s*v[0-9]+
** vneg\.v\tv[1-9][0-9]?,\s*v[0-9]+,\s*v0.t
@@ -46,9 +46,9 @@ void f2 (void * in, void *out)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle32.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vneg\.v\tv[0-9]+,\s*v[0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out)
/*
** f4:
-** vsetivli\tzero,4,e8,mf8,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vneg\.v\tv[0-9]+,\s*v[0-9]+
@@ -88,9 +88,9 @@ void f4 (void * in, void *out)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vneg\.v\tv[0-9]+,\s*v[0-9]+
** vneg\.v\tv[1-9][0-9]?,\s*v[0-9]+,\s*v0.t
@@ -110,9 +110,9 @@ void f5 (void * in, void *out)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e8,mf8,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vneg\.v\tv[0-9]+,\s*v[0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-2.c
index 19f9365..3344d42 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/unop_v_constraint-2.c
@@ -5,7 +5,7 @@
/*
** f1:
-** vsetivli\tzero,4,e32,m1,tu,ma
+** ...
** vle16\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle16\.v\tv[0-9]+,0\([a-x0-9]+\)
** vsext\.vf2\tv[0-9]+,\s*v[0-9]+
@@ -24,12 +24,12 @@ void f1 (void * in, void *out)
/*
** f2:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,ta,ma
+** ...
** vle16\.v\tv[0-9]+,0\([a-x0-9]+\)
** vsext\.vf2\tv[0-9]+,\s*v[0-9]+
-** vsetvli\tzero,zero,e64,m2,ta,ma
+** ...
** vsext\.vf2\tv[1-9][0-9]?,\s*v[0-9]+,\s*v0.t
** vse64\.v\tv[0-9]+,0\([a-x0-9]+\)
** ret
@@ -46,9 +46,9 @@ void f2 (void * in, void *out)
/*
** f3:
-** vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e32,m1,tu,mu
+** ...
** vle16\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle16\.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsext\.vf2\tv[0-9]+,\s*v[0-9]+
@@ -69,7 +69,7 @@ void f3 (void * in, void *out)
/*
** f4:
-** vsetivli\tzero,4,e16,mf4,tu,ma
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vsext\.vf2\tv[0-9]+,\s*v[0-9]+
@@ -88,12 +88,12 @@ void f4 (void * in, void *out)
/*
** f5:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e16,mf4,ta,ma
+** ...
** vle8.v\tv[0-9]+,0\([a-x0-9]+\)
** vsext\.vf2\tv[0-9]+,\s*v[0-9]+
-** vsetvli\tzero,zero,e32,mf2,ta,ma
+** ...
** vsext\.vf2\tv[1-9][0-9]?,\s*v[0-9]+,\s*v0.t
** vse32.v\tv[0-9]+,0\([a-x0-9]+\)
** ret
@@ -110,9 +110,9 @@ void f5 (void * in, void *out)
/*
** f6:
-** vsetvli\t[a-x0-9]+,zero,e8,mf8,ta,ma
+** ...
** vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** vsetivli\tzero,4,e16,mf4,tu,mu
+** ...
** vle8\.v\tv[0-9]+,0\([a-x0-9]+\)
** vle8.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
** vsext\.vf2\tv[0-9]+,\s*v[0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
index 674ba0d..237a20e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
@@ -81,6 +81,8 @@ foreach op $AUTOVEC_TEST_OPTS {
"" "$op"
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/cond/*.\[cS\]]] \
"" "$op"
+ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/builtin/*.\[cS\]]] \
+ "" "$op"
}
# widening operation only test on LMUL < 8
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111927.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111927.c
new file mode 100644
index 0000000..ab599ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111927.c
@@ -0,0 +1,170 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+#define RISCV_MATH_LOOPUNROLL
+#define RISCV_MATH_VECTOR
+typedef float float32_t;
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that controls filter coefficient updates. */
+ } riscv_lms_instance_f32;
+
+
+void riscv_lms_f32(
+ const riscv_lms_instance_f32 * S,
+ const float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize)
+{
+ float32_t *pState = S->pState; /* State pointer */
+ float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
+ float32_t *pStateCurnt; /* Points to the current sample of the state */
+ float32_t *px, *pb; /* Temporary pointers for state and coefficient buffers */
+ float32_t mu = S->mu; /* Adaptive factor */
+ float32_t acc, e; /* Accumulator, error */
+ float32_t w; /* Weight factor */
+ uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
+ uint32_t tapCnt, blkCnt; /* Loop counters */
+
+ /* Initializations of error, difference, Coefficient update */
+ e = 0.0f;
+ w = 0.0f;
+
+ /* S->pState points to state array which contains previous frame (numTaps - 1) samples */
+ /* pStateCurnt points to the location where the new input data should be written */
+ pStateCurnt = &(S->pState[(numTaps - 1U)]);
+
+ /* initialise loop count */
+ blkCnt = blockSize;
+
+ while (blkCnt > 0U)
+ {
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc++;
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize coefficient pointer */
+ pb = pCoeffs;
+
+ /* Set the accumulator to zero */
+ acc = 0.0f;
+ uint32_t vblkCnt = numTaps; /* Loop counter */
+ size_t l;
+ vfloat32m8_t vx, vy;
+ vfloat32m1_t temp00m1;
+ l = __riscv_vsetvl_e32m1(1);
+ temp00m1 = __riscv_vfmv_v_f_f32m1(0, l);
+ for (; (l = __riscv_vsetvl_e32m8(vblkCnt)) > 0; vblkCnt -= l) {
+ vx = __riscv_vle32_v_f32m8(px, l);
+ px += l;
+ vy = __riscv_vle32_v_f32m8(pb, l);
+ pb += l;
+ temp00m1 = __riscv_vfredusum_vs_f32m8_f32m1(__riscv_vfmul_vv_f32m8(vx, vy, l), temp00m1, l);
+ }
+ acc += __riscv_vfmv_f_s_f32m1_f32(temp00m1);
+
+ while (tapCnt > 0U)
+ {
+ /* Perform the multiply-accumulate */
+ acc += (*px++) * (*pb++);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = acc;
+
+ /* Compute and store error */
+ e = (float32_t) *pRef++ - acc;
+ *pErr++ = e;
+
+ /* Calculation of Weighting factor for updating filter coefficients */
+ w = e * mu;
+
+ /* Initialize pState pointer */
+ /* Advance state pointer by 1 for the next sample */
+ px = pState++;
+
+ /* Initialize coefficient pointer */
+ pb = pCoeffs;
+
+ vblkCnt = numTaps;
+ for (; (l = __riscv_vsetvl_e32m8(vblkCnt)) > 0; vblkCnt -= l) {
+ vx = __riscv_vle32_v_f32m8(px, l);
+ px += l;
+ __riscv_vse32_v_f32m8(pb, __riscv_vfadd_vv_f32m8(__riscv_vfmul_vf_f32m8(vx, w, l), __riscv_vle32_v_f32m8(pb, l), l) , l);
+ pb += l;
+ }
+ while (tapCnt > 0U)
+ {
+ /* Perform the multiply-accumulate */
+ *pb += w * (*px++);
+ pb++;
+
+ /* Decrement loop counter */
+ tapCnt--;
+ }
+ /* Decrement loop counter */
+ blkCnt--;
+ }
+
+ /* Processing is complete.
+ Now copy the last numTaps - 1 samples to the start of the state buffer.
+ This prepares the state buffer for the next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* copy data */
+
+ uint32_t vblkCnt = (numTaps - 1U); /* Loop counter */
+ size_t l;
+ for (; (l = __riscv_vsetvl_e32m8(vblkCnt)) > 0; vblkCnt -= l) {
+ __riscv_vse32_v_f32m8(pStateCurnt, __riscv_vle32_v_f32m8(pState, l) , l);
+ pState += l;
+ pStateCurnt += l;
+ }
+
+
+ /* Loop unrolling: Compute 4 taps at a time. */
+ tapCnt = (numTaps - 1U) >> 2U;
+
+ while (tapCnt > 0U)
+ {
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement loop counter */
+ tapCnt--;
+ }
+
+ /* Loop unrolling: Compute remaining taps */
+ tapCnt = (numTaps - 1U) & 0x3U;
+
+
+
+ /* Initialize tapCnt with number of samples */
+ tapCnt = (numTaps - 1U);
+
+
+
+ while (tapCnt > 0U)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement loop counter */
+ tapCnt--;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c
new file mode 100644
index 0000000..cea19b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O2 -Wno-implicit-int" } */
+
+char *a;
+b() {
+ int c[2];
+ int d = 0;
+ for (; d < 16; d += 2)
+ c[d / 2] = a[d | 1];
+ if (c[0])
+ for (;;)
+ ;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c b/gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c
index 4c549cb..5f03892 100644
--- a/gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c
+++ b/gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c
@@ -7,7 +7,7 @@ float getf();
/*
** bar:
-** call t0,__riscv_save_(3|4)
+** call t0,__riscv_save_[0-9]+
** addi sp,sp,-[0-9]+
** ...
** li t0,-[0-9]+
@@ -17,7 +17,7 @@ float getf();
** add sp,sp,t0
** ...
** addi sp,sp,[0-9]+
-** tail __riscv_restore_(3|4)
+** tail __riscv_restore_[0-9]+
*/
int bar()
{
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
new file mode 100644
index 0000000..24bbb63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM_UPD(float, 0)
+#if __riscv_xlen == 64
+LR_REG_IMM_UPD(double, 2)
+#endif
+
+SR_REG_IMM_UPD(float, 1)
+#if __riscv_xlen == 64
+SR_REG_IMM_UPD(double, 3)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 1 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 3 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
new file mode 100644
index 0000000..3b931a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadbb_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM_UPD(float, 0)
+#if __riscv_xlen == 64
+LR_REG_IMM_UPD(double, 2)
+#endif
+
+SR_REG_IMM_UPD(float, 1)
+#if __riscv_xlen == 64
+SR_REG_IMM_UPD(double, 3)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 1 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 3 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
new file mode 100644
index 0000000..4885860
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadbb_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM(float, 0)
+/* { dg-final { scan-assembler-times {\mth\.flrw\t[^\n\r]*0\M} 1 } } */
+#if __riscv_xlen == 64
+LR_REG_IMM(double, 2)
+/* { dg-final { scan-assembler-times {\mth\.flrd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SR_REG_IMM(float, 1)
+/* { dg-final { scan-assembler-times {\mth\.fsrw\t[^\n\r]*1\M} 1 } } */
+#if __riscv_xlen == 64
+SR_REG_IMM(double, 3)
+/* { dg-final { scan-assembler-times {\mth\.fsrd\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not "slli" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
new file mode 100644
index 0000000..1bb231a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM(float, 0)
+/* { dg-final { scan-assembler-times {\mth\.flrw\t[^\n\r]*0\M} 1 } } */
+#if __riscv_xlen == 64
+LR_REG_IMM(double, 2)
+/* { dg-final { scan-assembler-times {\mth\.flrd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SR_REG_IMM(float, 1)
+/* { dg-final { scan-assembler-times {\mth\.fsrw\t[^\n\r]*1\M} 1 } } */
+#if __riscv_xlen == 64
+SR_REG_IMM(double, 3)
+/* { dg-final { scan-assembler-times {\mth\.fsrd\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\mslli\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
new file mode 100644
index 0000000..bc50fa7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM_UPD(float, 0)
+#if __riscv_xlen == 64
+LRU_REG_IMM_UPD(double, 2)
+#endif
+
+SRU_REG_IMM_UPD(float, 1)
+#if __riscv_xlen == 64
+SRU_REG_IMM_UPD(double, 3)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 1 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 3 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c
new file mode 100644
index 0000000..242be7a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadbb_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM_UPD(float, 0)
+#if __riscv_xlen == 64
+LRU_REG_IMM_UPD(double, 2)
+#endif
+
+SRU_REG_IMM_UPD(float, 1)
+#if __riscv_xlen == 64
+SRU_REG_IMM_UPD(double, 3)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 1 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 3 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c
new file mode 100644
index 0000000..e2a4f36
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadbb_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM(float, 0)
+/* { dg-final { scan-assembler-times {\mth\.flurw\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.flrw\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+LRU_REG_IMM(double, 2)
+/* { dg-final { scan-assembler-times {\mth\.flurd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SRU_REG_IMM(float, 1)
+/* { dg-final { scan-assembler-times {\mth\.fsurw\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.fsrw\t[^\n\r]*1\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+SRU_REG_IMM(double, 3)
+/* { dg-final { scan-assembler-times {\mth\.fsurd\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\mslli\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c
new file mode 100644
index 0000000..32783eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32imafc_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM(float, 0)
+/* { dg-final { scan-assembler-times {\mth\.flurw\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.flrw\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+LRU_REG_IMM(double, 2)
+/* { dg-final { scan-assembler-times {\mth\.flurd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SRU_REG_IMM(float, 1)
+/* { dg-final { scan-assembler-times {\mth\.fsurw\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.fsrw\t[^\n\r]*1\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+SRU_REG_IMM(double, 3)
+/* { dg-final { scan-assembler-times {\mth\.fsurd\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\mslli\M} } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h
new file mode 100644
index 0000000..a97f08c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h
@@ -0,0 +1,152 @@
+#ifndef XTHEADMEMIDX_HELPERS_H
+#define XTHEADMEMIDX_HELPERS_H
+
+#include <stdint.h>
+
+#define intX_t long
+#define uintX_t unsigned long
+
+#define PRE_DEC_LOAD(T, N) \
+ void \
+ T ## _pre_dec_load_ ## N (T *p) \
+ { \
+ extern void f ## T ## N (T*, uintX_t); \
+ p = p - N; \
+ T x = *p; \
+ f ## T ## N (p, x); \
+ }
+
+#define PRE_INC_LOAD(T, N) \
+ void \
+ T ## _pre_inc_load_ ## N (T *p) \
+ { \
+ extern void f ## T ## N (T*, uintX_t); \
+ p = p + N; \
+ T x = *p; \
+ f ## T ## N (p, x); \
+ }
+
+#define POST_DEC_LOAD(T, N) \
+ void \
+ T ## _post_dec_load_ ## N (T *p) \
+ { \
+ extern void f ## T ## N (T*, uintX_t); \
+ T x = *p; \
+ p = p - N; \
+ f ## T ## N (p, x); \
+ }
+
+#define POST_INC_LOAD(T,N) \
+ void \
+ T ## _post_inc_load_ ## N (T *p) \
+ { \
+ extern void f ## T ## N (T*,uintX_t); \
+ T x = *p; \
+ p = p + N; \
+ f ## T ## N (p, x); \
+ }
+
+#define PRE_DEC_STORE(T, N) \
+ T * \
+ T ## _pre_dec_store_ ## N (T *p, T v) \
+ { \
+ p = p - N; \
+ *p = v; \
+ return p; \
+ }
+
+#define PRE_INC_STORE(T, N) \
+ T * \
+ T ## _pre_inc_store_ ## N (T *p, T v) \
+ { \
+ p = p + N; \
+ *p = v; \
+ return p; \
+ }
+
+#define POST_DEC_STORE(T, N) \
+ T * \
+ T ## _post_dec_store_ ## N (T *p, T v) \
+ { \
+ *p = v; \
+ p = p - N; \
+ return p; \
+ }
+
+#define POST_INC_STORE(T, N) \
+ T * \
+ T ## _post_inc_store_ ## N (T *p, T v) \
+ { \
+ *p = v; \
+ p = p + N; \
+ return p; \
+ }
+
+#define LR_REG_IMM(T, IMM) \
+ intX_t \
+ lr_reg_imm_ ## T ## _ ## IMM (intX_t rs1, intX_t rs2) \
+ { \
+ return *(T*)(rs1 + (rs2 << IMM)); \
+ }
+
+#define SR_REG_IMM(T, IMM) \
+ void \
+ sr_reg_imm_ ## T ## _ ## IMM (intX_t rs1, intX_t rs2, T val) \
+ { \
+ *(T*)(rs1 + (rs2 << IMM)) = val; \
+ }
+
+#define LR_REG_IMM_UPD(T, IMM) \
+ intX_t \
+ lr_reg_imm_upd_ ## T ## _ ## IMM (intX_t *rs1, intX_t rs2) \
+ { \
+ *rs1 = *rs1 + (rs2 << IMM); \
+ return *(T*)(*rs1); \
+ }
+
+#define SR_REG_IMM_UPD(T, IMM) \
+ void \
+ sr_reg_imm_upd_ ## T ## _ ## IMM (intX_t *rs1, intX_t rs2, T val) \
+ { \
+ *rs1 = *rs1 + (rs2 << IMM); \
+ *(T*)(*rs1) = val; \
+ }
+
+#define LRU_REG_IMM(T, IMM) \
+ intX_t \
+ lru_reg_imm_ ## T ## IMM (intX_t rs1, intX_t rs2) \
+ { \
+ rs2 = (uint32_t)rs2; \
+ return *(T*)(rs1 + (rs2 << IMM)); \
+ }
+
+#define SRU_REG_IMM(T, IMM) \
+ void \
+ sr_reg_imm_ ## T ## _ ## IMM (intX_t rs1, intX_t rs2, T val) \
+ { \
+ rs2 = (uint32_t)rs2; \
+ *(T*)(rs1 + (rs2 << IMM)) = val; \
+ }
+
+#define LRU_REG_IMM_UPD(T, IMM) \
+ intX_t \
+ lru_reg_imm_upd_ ## T ## IMM (intX_t rs1, intX_t *rs2) \
+ { \
+ uintX_t rs2_32 = (uint32_t)*rs2; \
+ intX_t t = rs1 + (rs2_32 << IMM); \
+ intX_t v = *(T*)t; \
+ *rs2 = t; \
+ return v; \
+ }
+
+#define SRU_REG_IMM_UPD(T, IMM) \
+ void \
+ sr_reg_imm_upd_ ## T ## _ ## IMM (intX_t rs1, intX_t *rs2, T val) \
+ { \
+ uintX_t rs2_32 = (uint32_t)*rs2; \
+ intX_t t = rs1 + (rs2_32 << IMM); \
+ *(T*)t = val; \
+ *rs2 = t; \
+ }
+
+#endif /* XTHEADMEMIDX_HELPERS_H */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-update.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-update.c
new file mode 100644
index 0000000..5bbf668
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-update.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM_UPD(int8_t, 0)
+LR_REG_IMM_UPD(uint8_t, 1)
+LR_REG_IMM_UPD(int16_t, 2)
+LR_REG_IMM_UPD(uint16_t, 3)
+LR_REG_IMM_UPD(int32_t, 0)
+#if __riscv_xlen == 64
+LR_REG_IMM_UPD(uint32_t, 1)
+LR_REG_IMM_UPD(int64_t, 2)
+#endif
+
+SR_REG_IMM_UPD(int8_t, 3)
+SR_REG_IMM_UPD(int16_t, 0)
+SR_REG_IMM_UPD(int32_t, 1)
+#if __riscv_xlen == 64
+SR_REG_IMM_UPD(int64_t, 2)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 5 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 8 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c
new file mode 100644
index 0000000..cfa1d2e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM_UPD(int8_t, 0)
+LR_REG_IMM_UPD(uint8_t, 1)
+LR_REG_IMM_UPD(int16_t, 2)
+LR_REG_IMM_UPD(uint16_t, 3)
+LR_REG_IMM_UPD(int32_t, 0)
+#if __riscv_xlen == 64
+LR_REG_IMM_UPD(uint32_t, 1)
+LR_REG_IMM_UPD(int64_t, 2)
+#endif
+
+SR_REG_IMM_UPD(int8_t, 3)
+SR_REG_IMM_UPD(int16_t, 0)
+SR_REG_IMM_UPD(int32_t, 1)
+#if __riscv_xlen == 64
+SR_REG_IMM_UPD(int64_t, 2)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 5 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 8 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb.c
new file mode 100644
index 0000000..7988fdf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM(int8_t, 0)
+/* { dg-final { scan-assembler-times {\mth.lrb\t[^\n\r]*0\M} 1 } } */
+LR_REG_IMM(uint8_t, 1)
+/* { dg-final { scan-assembler-times {\mth.lrbu\t[^\n\r]*1\M} 1 } } */
+LR_REG_IMM(int16_t, 2)
+/* { dg-final { scan-assembler-times {\mth.lrh\t[^\n\r]*2\M} 1 } } */
+LR_REG_IMM(uint16_t, 3)
+/* { dg-final { scan-assembler-times {\mth.lrhu\t[^\n\r]*3\M} 1 } } */
+LR_REG_IMM(int32_t, 0)
+/* { dg-final { scan-assembler-times {\mth.lrw\t[^\n\r]*0\M} 1 } } */
+#if __riscv_xlen == 64
+LR_REG_IMM(uint32_t, 1)
+/* { dg-final { scan-assembler-times {\mth.lrwu\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+LR_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth.lrd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SR_REG_IMM(int8_t, 3)
+/* { dg-final { scan-assembler-times {\mth.srb\t[^\n\r]*3\M} 1 } } */
+SR_REG_IMM(int16_t, 0)
+/* { dg-final { scan-assembler-times {\mth.srh\t[^\n\r]*0\M} 1 } } */
+SR_REG_IMM(int32_t, 1)
+/* { dg-final { scan-assembler-times {\mth.srw\t[^\n\r]*1\M} 1 } } */
+#if __riscv_xlen == 64
+SR_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth.srd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\mslli\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index.c
new file mode 100644
index 0000000..92bb084
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-index.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LR_REG_IMM(int8_t, 0)
+/* { dg-final { scan-assembler-times {\mth.lrb\t[^\n\r]*0\M} 1 } } */
+LR_REG_IMM(uint8_t, 1)
+/* { dg-final { scan-assembler-times {\mth.lrbu\t[^\n\r]*1\M} 1 } } */
+LR_REG_IMM(int16_t, 2)
+/* { dg-final { scan-assembler-times {\mth.lrh\t[^\n\r]*2\M} 1 } } */
+LR_REG_IMM(uint16_t, 3)
+/* { dg-final { scan-assembler-times {\mth.lrhu\t[^\n\r]*3\M} 1 } } */
+LR_REG_IMM(int32_t, 0)
+/* { dg-final { scan-assembler-times {\mth.lrw\t[^\n\r]*0\M} 1 } } */
+#if __riscv_xlen == 64
+LR_REG_IMM(uint32_t, 1)
+/* { dg-final { scan-assembler-times {\mth.lrwu\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+LR_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth.lrd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SR_REG_IMM(int8_t, 3)
+/* { dg-final { scan-assembler-times {\mth.srb\t[^\n\r]*3\M} 1 } } */
+SR_REG_IMM(int16_t, 0)
+/* { dg-final { scan-assembler-times {\mth.srh\t[^\n\r]*0\M} 1 } } */
+SR_REG_IMM(int32_t, 1)
+/* { dg-final { scan-assembler-times {\mth.srw\t[^\n\r]*1\M} 1 } } */
+#if __riscv_xlen == 64
+SR_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth.srd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\mslli\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c
new file mode 100644
index 0000000..8430b8d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+/* We have a simm5 shifted by a imm2.
+ imm2 | range (simm5 << imm2)
+ 0 | -16..-1,0..15
+ 1 | -32..-2,0..30
+ 2 | -64..-4,0..60
+ 3 | -128..-8,0..120 */
+
+POST_INC_LOAD(int8_t, 1)
+/* { dg-final { scan-assembler {\mth.lbia[^\n\r]*1,0\M} } } */
+PRE_DEC_LOAD(int8_t, 32)
+/* { dg-final { scan-assembler {\mth.lbib[^\n\r]*-16,1\M} } } */
+
+POST_DEC_LOAD(uint8_t, 1)
+/* { dg-final { scan-assembler {\mth.lbuia[^\n\r]*-1,0\M} } } */
+PRE_INC_LOAD(uint8_t, 32)
+/* { dg-final { scan-assembler {\mth.lbuib[^\n\r]*8,2\M} } } */
+
+POST_INC_LOAD(int16_t, 1)
+/* { dg-final { scan-assembler {\mth.lhia[^\n\r]*2,0\M} } } */
+POST_DEC_LOAD(int16_t, 64)
+/* { dg-final { scan-assembler {\mth.lhia[^\n\r]*-16,3\M} } } */
+
+POST_DEC_LOAD(uint16_t, 1)
+/* { dg-final { scan-assembler {\mth.lhuia[^\n\r]*-2,0\M} } } */
+POST_INC_LOAD(uint16_t, 60)
+/* { dg-final { scan-assembler {\mth.lhuia[^\n\r]*15,3\M} } } */
+
+POST_INC_LOAD(int32_t, 1)
+/* { dg-final { scan-assembler {\mth.lwia[^\n\r]*4,0\M} } } */
+PRE_DEC_LOAD(int32_t, 32)
+/* { dg-final { scan-assembler {\mth.lwib[^\n\r]*-16,3\M} } } */
+
+#if __riscv_xlen == 64
+POST_DEC_LOAD(uint32_t, 1)
+/* { dg-final { scan-assembler {\mth.lwuia[^\n\r]*-4,0\M} { target { rv64 } } } } */
+PRE_INC_LOAD(uint32_t, 15)
+/* { dg-final { scan-assembler {\mth.lwuib[^\n\r]*15,2\M} { target { rv64 } } } } */
+
+POST_INC_LOAD(int64_t, 1)
+/* { dg-final { scan-assembler {\mth.ldia[^\n\r]*8,0\M} { target { rv64 } } } } */
+PRE_DEC_LOAD(int64_t, 16)
+/* { dg-final { scan-assembler {\mth.ldib[^\n\r]*-16,3\M} { target { rv64 } } } } */
+#endif
+
+POST_DEC_STORE(int8_t, 1)
+/* { dg-final { scan-assembler {\mth.sbia[^\n\r]*-1,0\M} } } */
+PRE_INC_STORE(int8_t, 120)
+/* { dg-final { scan-assembler {\mth.sbib[^\n\r]*15,3\M} } } */
+
+POST_INC_STORE(int16_t, 1)
+/* { dg-final { scan-assembler {\mth.shia[^\n\r]*2,0\M} } } */
+PRE_DEC_STORE(int16_t, 64)
+/* { dg-final { scan-assembler {\mth.shib[^\n\r]*-16,3\M} } } */
+
+POST_DEC_STORE(int32_t, 1)
+/* { dg-final { scan-assembler {\mth.swia[^\n\r]*-4,0\M} } } */
+PRE_INC_STORE(int32_t, 2)
+/* { dg-final { scan-assembler {\mth.swib[^\n\r]*8,0\M} } } */
+
+#if __riscv_xlen == 64
+POST_INC_STORE(int64_t, 1)
+/* { dg-final { scan-assembler {\mth.sdia[^\n\r]*8,0\M} { target { rv64 } } } } */
+PRE_DEC_STORE(int64_t, 8)
+/* { dg-final { scan-assembler {\mth.sdib[^\n\r]*-16,2\M} { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\m\taddi\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify.c
new file mode 100644
index 0000000..0bcd78d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+/* We have a simm5 shifted by a imm2.
+ imm2 | range (simm5 << imm2)
+ 0 | -16..-1,0..15
+ 1 | -32..-2,0..30
+ 2 | -64..-4,0..60
+ 3 | -128..-8,0..120 */
+
+POST_INC_LOAD(int8_t, 1)
+/* { dg-final { scan-assembler {\mth.lbia[^\n\r]*1,0\M} } } */
+PRE_DEC_LOAD(int8_t, 32)
+/* { dg-final { scan-assembler {\mth.lbib[^\n\r]*-16,1\M} } } */
+
+POST_DEC_LOAD(uint8_t, 1)
+/* { dg-final { scan-assembler {\mth.lbuia[^\n\r]*-1,0\M} } } */
+PRE_INC_LOAD(uint8_t, 32)
+/* { dg-final { scan-assembler {\mth.lbuib[^\n\r]*8,2\M} } } */
+
+POST_INC_LOAD(int16_t, 1)
+/* { dg-final { scan-assembler {\mth.lhia[^\n\r]*2,0\M} } } */
+POST_DEC_LOAD(int16_t, 64)
+/* { dg-final { scan-assembler {\mth.lhia[^\n\r]*-16,3\M} } } */
+
+POST_DEC_LOAD(uint16_t, 1)
+/* { dg-final { scan-assembler {\mth.lhuia[^\n\r]*-2,0\M} } } */
+POST_INC_LOAD(uint16_t, 60)
+/* { dg-final { scan-assembler {\mth.lhuia[^\n\r]*15,3\M} } } */
+
+POST_INC_LOAD(int32_t, 1)
+/* { dg-final { scan-assembler {\mth.lwia[^\n\r]*4,0\M} } } */
+PRE_DEC_LOAD(int32_t, 32)
+/* { dg-final { scan-assembler {\mth.lwib[^\n\r]*-16,3\M} } } */
+
+#if __riscv_xlen == 64
+POST_DEC_LOAD(uint32_t, 1)
+/* { dg-final { scan-assembler {\mth.lwuia[^\n\r]*-4,0\M} { target { rv64 } } } } */
+PRE_INC_LOAD(uint32_t, 15)
+/* { dg-final { scan-assembler {\mth.lwuib[^\n\r]*15,2\M} { target { rv64 } } } } */
+
+POST_INC_LOAD(int64_t, 1)
+/* { dg-final { scan-assembler {\mth.ldia[^\n\r]*8,0\M} { target { rv64 } } } } */
+PRE_DEC_LOAD(int64_t, 16)
+/* { dg-final { scan-assembler {\mth.ldib[^\n\r]*-16,3\M} { target { rv64 } } } } */
+#endif
+
+POST_DEC_STORE(int8_t, 1)
+/* { dg-final { scan-assembler {\mth.sbia[^\n\r]*-1,0\M} } } */
+PRE_INC_STORE(int8_t, 120)
+/* { dg-final { scan-assembler {\mth.sbib[^\n\r]*15,3\M} } } */
+
+POST_INC_STORE(int16_t, 1)
+/* { dg-final { scan-assembler {\mth.shia[^\n\r]*2,0\M} } } */
+PRE_DEC_STORE(int16_t, 64)
+/* { dg-final { scan-assembler {\mth.shib[^\n\r]*-16,3\M} } } */
+
+POST_DEC_STORE(int32_t, 1)
+/* { dg-final { scan-assembler {\mth.swia[^\n\r]*-4,0\M} } } */
+PRE_INC_STORE(int32_t, 2)
+/* { dg-final { scan-assembler {\mth.swib[^\n\r]*8,0\M} } } */
+
+#if __riscv_xlen == 64
+POST_INC_STORE(int64_t, 1)
+/* { dg-final { scan-assembler {\mth.sdia[^\n\r]*8,0\M} { target { rv64 } } } } */
+PRE_DEC_STORE(int64_t, 8)
+/* { dg-final { scan-assembler {\mth.sdib[^\n\r]*-16,2\M} { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\m\taddi\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-update.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-update.c
new file mode 100644
index 0000000..d3fd069
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-update.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM_UPD(int8_t, 0)
+LRU_REG_IMM_UPD(uint8_t, 1)
+LRU_REG_IMM_UPD(int16_t, 2)
+LRU_REG_IMM_UPD(uint16_t, 3)
+LRU_REG_IMM_UPD(int32_t, 0)
+#if __riscv_xlen == 64
+LRU_REG_IMM_UPD(uint32_t, 1)
+LRU_REG_IMM_UPD(int64_t, 2)
+#endif
+
+SRU_REG_IMM_UPD(int8_t, 3)
+SRU_REG_IMM_UPD(int16_t, 0)
+SRU_REG_IMM_UPD(int32_t, 1)
+#if __riscv_xlen == 64
+SRU_REG_IMM_UPD(int64_t, 2)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 5 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 8 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb-update.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb-update.c
new file mode 100644
index 0000000..ee0486a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb-update.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM_UPD(int8_t, 0)
+LRU_REG_IMM_UPD(uint8_t, 1)
+LRU_REG_IMM_UPD(int16_t, 2)
+LRU_REG_IMM_UPD(uint16_t, 3)
+LRU_REG_IMM_UPD(int32_t, 0)
+#if __riscv_xlen == 64
+LRU_REG_IMM_UPD(uint32_t, 1)
+LRU_REG_IMM_UPD(int64_t, 2)
+#endif
+
+SRU_REG_IMM_UPD(int8_t, 3)
+SRU_REG_IMM_UPD(int16_t, 0)
+SRU_REG_IMM_UPD(int32_t, 1)
+#if __riscv_xlen == 64
+SRU_REG_IMM_UPD(int64_t, 2)
+#endif
+
+/* If the shifted value is used later, we cannot eliminate it. */
+/* { dg-final { scan-assembler-times {\mslli\M} 5 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mslli\M} 8 { target { rv64 } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb.c
new file mode 100644
index 0000000..ccabe99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM(int8_t, 0)
+/* { dg-final { scan-assembler-times {\mth.lurb\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.lrb\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(uint8_t, 1)
+/* { dg-final { scan-assembler-times {\mth.lurbu\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.lrbu\t[^\n\r]*1\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(int16_t, 2)
+/* { dg-final { scan-assembler-times {\mth.lurh\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.lrh\t[^\n\r]*2\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(uint16_t, 3)
+/* { dg-final { scan-assembler-times {\mth.lurhu\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.lrhu\t[^\n\r]*3\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(int32_t, 0)
+/* { dg-final { scan-assembler-times {\mth.lurw\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.lrw\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+LRU_REG_IMM(uint32_t, 1)
+/* { dg-final { scan-assembler-times {\mth.lurwu\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+LRU_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth.lurd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SRU_REG_IMM(int8_t, 3)
+/* { dg-final { scan-assembler-times {\mth.surb\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.srb\t[^\n\r]*3\M} 1 { target { rv32 } } } } */
+SRU_REG_IMM(int16_t, 0)
+/* { dg-final { scan-assembler-times {\mth.surh\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.srh\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+SRU_REG_IMM(int32_t, 1)
+/* { dg-final { scan-assembler-times {\mth.surw\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth.srw\t[^\n\r]*1\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+SRU_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth.surd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\mslli\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex.c
new file mode 100644
index 0000000..369ffb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */
+
+#include "xtheadmemidx-helpers.h"
+
+LRU_REG_IMM(int8_t, 0)
+/* { dg-final { scan-assembler-times {\mth\.lurb\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.lrb\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(uint8_t, 1)
+/* { dg-final { scan-assembler-times {\mth\.lurbu\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.lrbu\t[^\n\r]*1\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(int16_t, 2)
+/* { dg-final { scan-assembler-times {\mth\.lurh\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.lrh\t[^\n\r]*2\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(uint16_t, 3)
+/* { dg-final { scan-assembler-times {\mth\.lurhu\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.lrhu\t[^\n\r]*3\M} 1 { target { rv32 } } } } */
+LRU_REG_IMM(int32_t, 0)
+/* { dg-final { scan-assembler-times {\mth\.lurw\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.lrw\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+LRU_REG_IMM(uint32_t, 1)
+/* { dg-final { scan-assembler-times {\mth\.lurwu\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+LRU_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth\.lurd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+SRU_REG_IMM(int8_t, 3)
+/* { dg-final { scan-assembler-times {\mth\.surb\t[^\n\r]*3\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.srb\t[^\n\r]*3\M} 1 { target { rv32 } } } } */
+SRU_REG_IMM(int16_t, 0)
+/* { dg-final { scan-assembler-times {\mth\.surh\t[^\n\r]*0\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.srh\t[^\n\r]*0\M} 1 { target { rv32 } } } } */
+SRU_REG_IMM(int32_t, 1)
+/* { dg-final { scan-assembler-times {\mth\.surw\t[^\n\r]*1\M} 1 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.srw\t[^\n\r]*1\M} 1 { target { rv32 } } } } */
+#if __riscv_xlen == 64
+SRU_REG_IMM(int64_t, 2)
+/* { dg-final { scan-assembler-times {\mth\.surd\t[^\n\r]*2\M} 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-not {\mslli\M} } } */
diff --git a/gcc/testsuite/gcc.target/s390/target-attribute/tattr-2b.c b/gcc/testsuite/gcc.target/s390/target-attribute/tattr-2b.c
new file mode 100644
index 0000000..7ae78fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/target-attribute/tattr-2b.c
@@ -0,0 +1,51 @@
+/* Functional tests for the "target" attribute and pragma. */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target target_attribute } */
+/* { dg-options "-O3 -march=zEC12 -mno-htm -fno-ipa-icf -save-temps" } */
+
+#pragma GCC target("htm")
+void p1(void)
+{
+#ifndef __HTM__
+#error __HTM__ is not defined
+#endif
+ __builtin_tend ();
+}
+#pragma GCC reset_options
+
+#pragma GCC target("no-htm")
+void p0(void)
+{
+#ifdef __HTM__
+#error __HTM__ is defined
+#endif
+ __builtin_tend (); /* { dg-error "is not supported without '-mhtm'" } */
+}
+#pragma GCC reset_options
+
+__attribute__ ((target("htm")))
+void a1(void)
+{
+#ifdef __HTM__
+#error __HTM__ is defined
+#endif
+ __builtin_tend ();
+}
+
+__attribute__ ((target("no-htm")))
+void a0(void)
+{
+#ifdef __HTM__
+#error __HTM__ is defined
+#endif
+ __builtin_tend (); /* { dg-error "is not supported without '-mhtm'" } */
+}
+
+void htmd(void)
+{
+#ifdef __HTM__
+#error __HTM__ is defined
+#endif
+ __builtin_tend (); /* { dg-error "is not supported without '-mhtm'" } */
+}
diff --git a/gcc/testsuite/gdc.dg/Wunused_value.d b/gcc/testsuite/gdc.dg/Wunused_value.d
new file mode 100644
index 0000000..0afc881
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/Wunused_value.d
@@ -0,0 +1,29 @@
+// { dg-do compile }
+// { dg-options "-Wunused-value" }
+
+@safe pure nothrow T t1(T)(T x)
+{
+ return x * x;
+}
+
+nothrow pure int f1(immutable(int)[] a)
+{
+ return 0;
+}
+
+nothrow pure int f2(immutable(int)* p)
+{
+ return 0;
+}
+
+void test()
+{
+ int x = 3;
+ t1(x); // { dg-warning "without side effects discards return value" }
+
+ auto fp = &t1!int;
+ fp(x); // { dg-warning "without side effects discards return value" }
+
+ f1([]); // { dg-warning "without side effects discards return value" }
+ f2(null); // { dg-warning "without side effects discards return value" }
+}
diff --git a/gcc/testsuite/gdc.dg/pr110712.d b/gcc/testsuite/gdc.dg/pr110712.d
new file mode 100644
index 0000000..ed24b6c
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110712.d
@@ -0,0 +1,23 @@
+// { dg-do compile { target { { i?86-*-* x86_64-*-* } && lp64 } } }
+import gcc.builtins : va_list = __builtin_va_list;
+
+void argpass(va_list *ap);
+
+void pr110712a(va_list ap)
+{
+ argpass(&ap); // { dg-error "cannot convert parameter" }
+}
+
+void pr110712b(va_list ap)
+{
+ va_list ap2 = ap; // { dg-error "cannot convert parameter" }
+}
+
+struct pr110712c
+{
+ this(va_list ap)
+ {
+ this.ap = ap; // { dg-error "cannot convert parameter" }
+ }
+ va_list ap;
+}
diff --git a/gcc/testsuite/gdc.dg/pr112270.d b/gcc/testsuite/gdc.dg/pr112270.d
new file mode 100644
index 0000000..591c798
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr112270.d
@@ -0,0 +1,7 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112270
+// { dg-do compile }
+class CPPNamespaceDeclaration { }
+bool isNamespaceEqual (CPPNamespaceDeclaration a)
+{
+ return a ? true : isNamespaceEqual(a);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail3882.d b/gcc/testsuite/gdc.test/fail_compilation/fail3882.d
index 27ddad4..9647f08 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail3882.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail3882.d
@@ -1,18 +1,17 @@
-// REQUIRED_ARGS: -w
-// PERMUTE_ARGS: -debug
-
-/******************************************/
-// https://issues.dlang.org/show_bug.cgi?id=3882
-
/*
+PERMUTE_ARGS: -debug
TEST_OUTPUT:
---
-fail_compilation/fail3882.d(23): Warning: calling `fail3882.strictlyPure!int.strictlyPure` without side effects discards return value of type `int`; prepend a `cast(void)` if intentional
-fail_compilation/fail3882.d(27): Warning: calling `fp` without side effects discards return value of type `int`; prepend a `cast(void)` if intentional
+fail_compilation/fail3882.d(32): Error: `@mustuse` on functions is reserved for future use
+fail_compilation/fail3882.d(33): Error: `@mustuse` on functions is reserved for future use
---
*/
+import core.attribute;
+
+/******************************************/
+// https://issues.dlang.org/show_bug.cgi?id=3882
-@safe pure nothrow T strictlyPure(T)(T x)
+@mustuse @safe pure nothrow T strictlyPure(T)(T x)
{
return x*x;
}
@@ -30,18 +29,8 @@ void main()
/******************************************/
// bugfix in TypeFunction::purityLevel
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail3882.d(48): Warning: calling `fail3882.f1` without side effects discards return value of type `int`; prepend a `cast(void)` if intentional
-fail_compilation/fail3882.d(49): Warning: calling `fail3882.f2` without side effects discards return value of type `int`; prepend a `cast(void)` if intentional
-Error: warnings are treated as errors
- Use -wi if you wish to treat warnings only as informational.
----
-*/
-
-nothrow pure int f1(immutable(int)[] a) { return 0; }
-nothrow pure int f2(immutable(int)* p) { return 0; }
+@mustuse nothrow pure int f1(immutable(int)[] a) { return 0; }
+@mustuse nothrow pure int f2(immutable(int)* p) { return 0; }
void test_bug()
{
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d b/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d
index ebefe33..6d3b223 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d
@@ -4,6 +4,8 @@
TEST_OUTPUT:
---
fail_compilation/imports/foo10727a.d(34): Error: undefined identifier `Frop`
+fail_compilation/imports/foo10727a.d(26): Error: template instance `foo10727a.CirBuff!(Foo)` error instantiating
+fail_compilation/imports/foo10727a.d(31): instantiated from here: `Bar!(Foo)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d b/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d
index 125ac12..4a59d5c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d
@@ -4,6 +4,8 @@
TEST_OUTPUT:
---
fail_compilation/imports/foo10727b.d(25): Error: undefined identifier `Frop`
+fail_compilation/imports/foo10727b.d(17): Error: template instance `foo10727b.CirBuff!(Foo)` error instantiating
+fail_compilation/imports/foo10727b.d(22): instantiated from here: `Bar!(Foo)`
---
*/
diff --git a/gcc/testsuite/gdc.test/runnable/issue24168.d b/gcc/testsuite/gdc.test/runnable/issue24168.d
new file mode 100644
index 0000000..c21a35b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/issue24168.d
@@ -0,0 +1,31 @@
+/*
+REQUIRED_ARGS: -fPIE
+DISABLED: win32 win64
+*/
+
+//https://issues.dlang.org/show_bug.cgi?id=24168
+
+int i = 42;
+
+bool foo(ref int a)
+{
+ return a == 42;
+}
+
+ref int bar()
+{
+ return i;
+}
+
+bool baz()
+{
+ static int i = 42;
+ return foo(i);
+}
+
+void main()
+{
+ assert(foo(i));
+ assert(bar() == 42);
+ assert(baz());
+}
diff --git a/gcc/testsuite/gfortran.dg/associate_55.f90 b/gcc/testsuite/gfortran.dg/associate_55.f90
index 2b9e8c7..245dbfc 100644
--- a/gcc/testsuite/gfortran.dg/associate_55.f90
+++ b/gcc/testsuite/gfortran.dg/associate_55.f90
@@ -26,7 +26,7 @@ contains
class(test_t), intent(inout) :: obj
integer, intent(in) :: a
associate (state => obj%state(TEST_STATES)) ! { dg-error "no IMPLICIT type" }
- state = a ! { dg-error "vector-indexed target" }
+ state = a ! { dg-error "cannot be used in a variable definition context" }
! state(TEST_STATE) = a
end associate
end subroutine test_alter_state2
diff --git a/gcc/testsuite/gfortran.dg/coarray/caf.exp b/gcc/testsuite/gfortran.dg/coarray/caf.exp
index d232be2..a10b17a 100644
--- a/gcc/testsuite/gfortran.dg/coarray/caf.exp
+++ b/gcc/testsuite/gfortran.dg/coarray/caf.exp
@@ -28,6 +28,7 @@
# Load procedures from common libraries.
load_lib gfortran-dg.exp
+load_lib atomic-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_FFLAGS
@@ -47,6 +48,7 @@ global gfortran_test_path
global gfortran_aux_module_flags
set gfortran_test_path $srcdir/$subdir
set gfortran_aux_module_flags $DEFAULT_FFLAGS
+
proc dg-compile-aux-modules { args } {
global gfortran_test_path
global gfortran_aux_module_flags
@@ -71,7 +73,15 @@ proc dg-compile-aux-modules { args } {
# Add -latomic only where supported. Assume built-in support elsewhere.
set maybe_atomic_lib ""
if [check_effective_target_libatomic_available] {
- set maybe_atomic_lib "-latomic"
+ if ![is_remote host] {
+ if [info exists TOOL_OPTIONS] {
+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
+ } else {
+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs]]"
+ }
+ }
+ set t [get_multilibs]
+ puts "maybe al $maybe_atomic_lib ml $t"
}
# Main loop.
@@ -97,14 +107,14 @@ foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ]]
foreach flags $option_list {
verbose "Testing $nshort (single), $flags" 1
set gfortran_aux_module_flags "-fcoarray=single $flags"
- dg-test $test "-fcoarray=single $flags $maybe_atomic_lib" ""
+ dg-test $test "-fcoarray=single $flags" $maybe_atomic_lib
cleanup-modules ""
}
foreach flags $option_list {
verbose "Testing $nshort (libcaf_single), $flags" 1
set gfortran_aux_module_flags "-fcoarray=lib $flags -lcaf_single"
- dg-test $test "-fcoarray=lib $flags -lcaf_single $maybe_atomic_lib" ""
+ dg-test $test "-fcoarray=lib $flags -lcaf_single" $maybe_atomic_lib
cleanup-modules ""
}
}
diff --git a/gcc/testsuite/gfortran.dg/dg.exp b/gcc/testsuite/gfortran.dg/dg.exp
index ee27603..73541ea 100644
--- a/gcc/testsuite/gfortran.dg/dg.exp
+++ b/gcc/testsuite/gfortran.dg/dg.exp
@@ -18,6 +18,7 @@
# Load support procs.
load_lib gfortran-dg.exp
+load_lib atomic-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_FFLAGS
@@ -53,13 +54,38 @@ proc dg-compile-aux-modules { args } {
}
}
+# coarray tests might need libatomic. Assume that it is either not needed or
+# provided by builtins if it's not available.
+set maybe_atomic_lib ""
+if [check_effective_target_libatomic_available] {
+ if ![is_remote host] {
+ if [info exists TOOL_OPTIONS] {
+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
+ } else {
+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs]]"
+ }
+ } else {
+ set maybe_atomic_lib ""
+ }
+ set t [get_multilibs]
+ puts "dg set al $maybe_atomic_lib ml $t"
+}
+
+set all_flags $DEFAULT_FFLAGS
+if { $maybe_atomic_lib != "" } {
+ foreach f $maybe_atomic_lib {
+ lappend all_flags $f
+ }
+}
+
+puts "revised FFLAGS $all_flags"
+
# Main loop.
gfortran-dg-runtest [lsort \
- [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $DEFAULT_FFLAGS
+ [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $all_flags
gfortran-dg-runtest [lsort \
- [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] "" $DEFAULT_FFLAGS
-
+ [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] "" $all_flags
# All done.
dg-finish
diff --git a/gcc/testsuite/gfortran.dg/goacc/if.f95 b/gcc/testsuite/gfortran.dg/goacc/if.f95
index 56f3711..753ef82 100644
--- a/gcc/testsuite/gfortran.dg/goacc/if.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/if.f95
@@ -1,3 +1,5 @@
+! See also 'self.f95'.
+
! { dg-do compile }
program test
@@ -12,12 +14,14 @@ program test
!$acc end parallel
!$acc parallel if (1) ! { dg-error "scalar LOGICAL expression" }
!$acc end parallel
- !$acc kernels if (i) ! { dg-error "scalar LOGICAL expression" }
- !$acc end kernels
+
!$acc kernels if ! { dg-error "Expected '\\(' after 'if'" }
!$acc kernels if () ! { dg-error "Invalid character" }
+ !$acc kernels if (i) ! { dg-error "scalar LOGICAL expression" }
+ !$acc end kernels
!$acc kernels if (1) ! { dg-error "scalar LOGICAL expression" }
!$acc end kernels
+
!$acc data if ! { dg-error "Expected '\\(' after 'if'" }
!$acc data if () ! { dg-error "Invalid character" }
!$acc data if (i) ! { dg-error "scalar LOGICAL expression" }
@@ -36,12 +40,14 @@ program test
!$acc end parallel
!$acc parallel if (i.gt.1)
!$acc end parallel
+
!$acc kernels if (x)
!$acc end kernels
!$acc kernels if (.true.)
!$acc end kernels
!$acc kernels if (i.gt.1)
!$acc end kernels
+
!$acc data if (x)
!$acc end data
!$acc data if (.true.)
diff --git a/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 b/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95
index ceb07fb..2ee578f 100644
--- a/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95
@@ -12,6 +12,7 @@ program test
logical :: l = .true.
!$acc kernels if(l) async num_gangs(i) num_workers(i) vector_length(i) &
+ !$acc self &
!$acc copy(i), copyin(j), copyout(k), create(m) &
!$acc no_create(n) &
!$acc present(o), pcopy(p), pcopyin(r), pcopyout(s), pcreate(t) &
@@ -27,7 +28,7 @@ end program test
! { dg-final { scan-tree-dump-times "num_gangs" 1 "original" } }
! { dg-final { scan-tree-dump-times "num_workers" 1 "original" } }
! { dg-final { scan-tree-dump-times "vector_length" 1 "original" } }
-
+! { dg-final { scan-tree-dump-times "self\\(1\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "map\\(tofrom:i\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "map\\(to:j\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "map\\(from:k\\)" 1 "original" } }
@@ -41,5 +42,5 @@ end program test
! { dg-final { scan-tree-dump-times "map\\(force_deviceptr:u\\)" 1 "original" } }
-! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels if\((?:D\.|_)[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } }
-! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single num_gangs\(1\) if\((?:D\.|_)[0-9]+\) async\(-1\)$} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels if\((?:D\.|_)[0-9]+\) self\(1\)$} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single num_gangs\(1\) if\((?:D\.|_)[0-9]+\) self\(1\) async\(-1\)$} 1 "omp_oacc_kernels_decompose" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95 b/gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95
index 6110d93..0d4ec11 100644
--- a/gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95
@@ -14,6 +14,7 @@ program test
logical :: l = .true.
!$acc parallel if(l) async num_gangs(i) num_workers(i) vector_length(i) &
+ !$acc self &
!$acc reduction(max:q), copy(i), copyin(j), copyout(k), create(m) &
!$acc no_create(n) &
!$acc present(o), pcopy(p), pcopyin(r), pcopyout(s), pcreate(t) &
@@ -33,7 +34,7 @@ end program test
! { dg-final { scan-tree-dump-times "num_gangs" 1 "original" } }
! { dg-final { scan-tree-dump-times "num_workers" 1 "original" } }
! { dg-final { scan-tree-dump-times "vector_length" 1 "original" } }
-
+! { dg-final { scan-tree-dump-times "self\\(1\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "reduction\\(max:q\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "map\\(tofrom:i\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "map\\(to:j\\)" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/self.f95 b/gcc/testsuite/gfortran.dg/goacc/self.f95
new file mode 100644
index 0000000..aa0f6fe
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/self.f95
@@ -0,0 +1,61 @@
+! See also 'if.f95'.
+
+! { dg-do compile }
+
+program test
+ implicit none
+
+ logical :: x
+ integer :: i
+
+ !$acc parallel self () ! { dg-error "Invalid character" }
+ !$acc parallel self (i) ! { dg-error "scalar LOGICAL expression" }
+ !$acc end parallel
+ !$acc parallel self (1) ! { dg-error "scalar LOGICAL expression" }
+ !$acc end parallel
+
+ !$acc kernels self () ! { dg-error "Invalid character" }
+ !$acc kernels self (i) ! { dg-error "scalar LOGICAL expression" }
+ !$acc end kernels
+ !$acc kernels self (1) ! { dg-error "scalar LOGICAL expression" }
+ !$acc end kernels
+
+ !$acc serial self () ! { dg-error "Invalid character" }
+ !$acc serial self (i) ! { dg-error "scalar LOGICAL expression" }
+ !$acc end serial
+ !$acc serial self (1) ! { dg-error "scalar LOGICAL expression" }
+ !$acc end serial
+
+ ! at most one self clause may appear
+ !$acc parallel self (.false.) self (.false.) { dg-error "Duplicated 'self' clause" }
+ !$acc kernels self (.false.) self (.false.) { dg-error "Duplicated 'self' clause" }
+ !$acc serial self (.false.) self (.false.) { dg-error "Duplicated 'self' clause" }
+
+ !$acc parallel self
+ !$acc end parallel
+ !$acc parallel self (x)
+ !$acc end parallel
+ !$acc parallel self (.true.)
+ !$acc end parallel
+ !$acc parallel self (i.gt.1)
+ !$acc end parallel
+
+ !$acc kernels self
+ !$acc end kernels
+ !$acc kernels self (x)
+ !$acc end kernels
+ !$acc kernels self (.true.)
+ !$acc end kernels
+ !$acc kernels self (i.gt.1)
+ !$acc end kernels
+
+ !$acc serial self
+ !$acc end serial
+ !$acc serial self (x)
+ !$acc end serial
+ !$acc serial self (.true.)
+ !$acc end serial
+ !$acc serial self (i.gt.1)
+ !$acc end serial
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_20.f90 b/gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_20.f90
new file mode 100644
index 0000000..777181c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_20.f90
@@ -0,0 +1,56 @@
+! { dg-do compile }
+!
+! This failed to compile the declare variant directive due to the C_PTR
+! arguments to foo being recognised as INTEGER(8)
+
+program adjust_args
+ use iso_c_binding, only: c_loc
+ implicit none
+
+ integer, parameter :: N = 1024
+ real, allocatable, target :: av(:), bv(:), cv(:)
+
+ call foo(c_loc(bv), c_loc(av), N)
+
+ !$omp target data map(to: av(:N)) map(from: cv(:N))
+ !$omp parallel
+ call foo(c_loc(cv), c_loc(av), N)
+ !$omp end parallel
+ !$omp end target data
+
+contains
+ subroutine foo_variant(c_d_bv, c_d_av, n)
+ use iso_c_binding, only: c_ptr, c_f_pointer
+ type(c_ptr), intent(in) :: c_d_bv, c_d_av
+ integer, intent(in) :: n
+ real, pointer :: f_d_bv(:)
+ real, pointer :: f_d_av(:)
+ integer :: i
+
+ call c_f_pointer(c_d_bv, f_d_bv, [n])
+ call c_f_pointer(c_d_av, f_d_av, [n])
+ !$omp target teams loop is_device_ptr(f_d_bv, f_d_av)
+ do i = 1, n
+ f_d_bv(i) = f_d_av(i) * i
+ end do
+ end subroutine
+
+
+ subroutine foo(c_bv, c_av, n)
+ use iso_c_binding, only: c_ptr, c_f_pointer
+ type(c_ptr), intent(in) :: c_bv, c_av
+ integer, intent(in) :: n
+ real, pointer :: f_bv(:)
+ real, pointer :: f_av(:)
+ integer :: i
+ !$omp declare variant(foo_variant) &
+ !$omp match(construct={parallel})
+
+ call c_f_pointer(c_bv, f_bv, [n])
+ call c_f_pointer(c_av, f_av, [n])
+ !$omp parallel loop
+ do i = 1, n
+ f_bv(i) = f_av(i) * i
+ end do
+ end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_21.f90 b/gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_21.f90
new file mode 100644
index 0000000..b410736
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/c_ptr_tests_21.f90
@@ -0,0 +1,56 @@
+! { dg-do compile }
+!
+! Ensure that C_PTR and C_FUNPTR are reported as incompatible types in variant
+! argument lists
+
+program adjust_args
+ use iso_c_binding, only: c_loc
+ implicit none
+
+ integer, parameter :: N = 1024
+ real, allocatable, target :: av(:), bv(:), cv(:)
+
+ call foo(c_loc(bv), c_loc(av), N)
+
+ !$omp target data map(to: av(:N)) map(from: cv(:N))
+ !$omp parallel
+ call foo(c_loc(cv), c_loc(av), N)
+ !$omp end parallel
+ !$omp end target data
+
+contains
+ subroutine foo_variant(c_d_bv, c_d_av, n)
+ use iso_c_binding, only: c_funptr, c_f_pointer
+ type(c_funptr), intent(in) :: c_d_bv, c_d_av
+ integer, intent(in) :: n
+ real, pointer :: f_d_bv(:)
+ real, pointer :: f_d_av(:)
+ integer :: i
+
+! call c_f_pointer(c_d_bv, f_d_bv, [n])
+! call c_f_pointer(c_d_av, f_d_av, [n])
+ !$omp target teams loop is_device_ptr(f_d_bv, f_d_av)
+ do i = 1, n
+ f_d_bv(i) = f_d_av(i) * i
+ end do
+ end subroutine
+
+
+ subroutine foo(c_bv, c_av, n)
+ use iso_c_binding, only: c_ptr, c_f_pointer
+ type(c_ptr), intent(in) :: c_bv, c_av
+ integer, intent(in) :: n
+ real, pointer :: f_bv(:)
+ real, pointer :: f_av(:)
+ integer :: i
+ !$omp declare variant(foo_variant) & ! { dg-error "variant 'foo_variant' and base 'foo' at .1. have incompatible types: Type mismatch in argument 'c_bv' .TYPE.c_ptr./TYPE.c_funptr.." }
+ !$omp match(construct={parallel})
+
+ call c_f_pointer(c_bv, f_bv, [n])
+ call c_f_pointer(c_av, f_av, [n])
+ !$omp parallel loop
+ do i = 1, n
+ f_bv(i) = f_av(i) * i
+ end do
+ end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.dg/pr104555.f90 b/gcc/testsuite/gfortran.dg/pr104555.f90
new file mode 100644
index 0000000..1fc5b5b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104555.f90
@@ -0,0 +1,32 @@
+! { dg-do compile }
+!
+! Test the fix for PR104555 in which the select type statement caused an
+! ICE because the selector expression was type(t) rather than class(t).
+!
+! Contributed by Gerhard Steinmetz <gscfq@t-online.de>
+!
+program p
+ type t
+ character(:), allocatable :: a
+ end type
+ call s(t("abcd"))
+ call s([t("efgh")])
+contains
+ subroutine s(x)
+ class(t) :: x(..)
+ select rank (x)
+ rank (0)
+ print *, "|", x%a, "|"
+ select type (y => x)
+ type is (t)
+ print *, "|", y%a, "|"
+ end select
+ rank (1)
+ print *, "|", x(1)%a, "|"
+ select type (y => x)
+ type is (t)
+ print *, "|", y(1)%a, "|"
+ end select
+ end select
+ end
+end
diff --git a/gcc/testsuite/gfortran.dg/pr104625.f90 b/gcc/testsuite/gfortran.dg/pr104625.f90
new file mode 100644
index 0000000..84e7a9a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104625.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+!
+! Check the fix for PR104625 in which the selectors in parentheses used
+! to cause ICEs. The "Unclassifiable statement" errors were uncovered once
+! the ICEs were fixed.
+!
+! Contributed by Gerhard Steinmetz <gscfq@t-online.de>
+!
+program p
+ implicit none
+ type t
+ integer :: a
+ end type
+contains
+ subroutine s(x)
+! class(t) :: x ! Was OK
+ class(t) :: x(:) ! Used to ICE in combination with below
+ class(t), allocatable :: r(:)
+
+ select type (y => x) ! OK
+ type is (t)
+ y%a = 99
+ end select
+ select type (z => (x)) ! Used to ICE
+ type is (t)
+ r = z(1) ! Used to give "Unclassifiable statement" error
+ z%a = 99 ! { dg-error "cannot be used in a variable definition" }
+ end select
+ select type (u => ((x))) ! Used to ICE
+ type is (t)
+ r = u(1) ! Used to give "Unclassifiable statement" error
+ u%a = 99 ! { dg-error "cannot be used in a variable definition" }
+ end select
+ end
+end
diff --git a/gcc/testsuite/gfortran.dg/pr104649.f90 b/gcc/testsuite/gfortran.dg/pr104649.f90
new file mode 100644
index 0000000..f301ffc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104649.f90
@@ -0,0 +1,44 @@
+! { dg-do compile }
+! { dg-options "-w" }
+! PR fortran/104649
+! Contributed by G.Steinmetz
+
+module m
+ interface
+ module subroutine s(x)
+ real :: x
+ end
+ end interface
+end
+submodule(m) m2
+contains
+ module subroutine s(*) ! { dg-error "conflicts with alternate return" }
+ end
+end
+
+module n
+ interface
+ module subroutine s(*)
+ end
+ end interface
+end
+submodule(n) n2
+contains
+ module subroutine s(x) ! { dg-error "formal argument is alternate return" }
+ real :: x
+ end
+end
+
+module p
+ interface
+ module subroutine s(x)
+ real :: x
+ end
+ end interface
+end
+submodule(p) p2
+contains
+ module subroutine s(y) ! { dg-error "Mismatch in MODULE PROCEDURE formal argument names" }
+ real :: y
+ end
+end
diff --git a/gcc/testsuite/gm2/pim/fail/largeconst.mod b/gcc/testsuite/gm2/pim/fail/largeconst.mod
index befb93e..0c1ca63 100644
--- a/gcc/testsuite/gm2/pim/fail/largeconst.mod
+++ b/gcc/testsuite/gm2/pim/fail/largeconst.mod
@@ -1,7 +1,7 @@
MODULE largeconst ;
CONST
- foo = 12345678912345678912345679123456789123456789123456789123456789123456791234567891234567891234567891234567891234567912345678912345678912345678912345678912345679123456789123456789 ;
+ foo = 123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890123456789012345678901234567901234567890123456789012345678901234567890123456790123456789012345678901234567890123456789012345679012345678901234567890 ;
BEGIN
END largeconst. \ No newline at end of file
diff --git a/gcc/testsuite/gm2/pim/fail/largeconst2.mod b/gcc/testsuite/gm2/pim/fail/largeconst2.mod
deleted file mode 100644
index f961388..0000000
--- a/gcc/testsuite/gm2/pim/fail/largeconst2.mod
+++ /dev/null
@@ -1,7 +0,0 @@
-MODULE largeconst2 ;
-
-CONST
- foo = 123456789123456789123456791234567891234567891234567891234567891234567912345678912345678912345678912345678912345679123456789123456789123456789123456789123456791234567891234567891234567891234567891234567912345678912345678912345678912345678912345679123456789123456789 ;
-
-BEGIN
-END largeconst2. \ No newline at end of file
diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testgetopt.mod b/gcc/testsuite/gm2/pimlib/run/pass/testgetopt.mod
new file mode 100644
index 0000000..3e322da
--- /dev/null
+++ b/gcc/testsuite/gm2/pimlib/run/pass/testgetopt.mod
@@ -0,0 +1,74 @@
+MODULE testgetopt ;
+
+FROM libc IMPORT printf, exit ;
+FROM GetOpt IMPORT InitLongOptions, KillLongOptions, AddLongOption,
+ GetOptLong, PtrToInteger, LongOptions ;
+FROM DynamicStrings IMPORT String, InitString, string ;
+IMPORT UnixArgs ;
+FROM Storage IMPORT ALLOCATE ;
+FROM SYSTEM IMPORT ADR ;
+
+
+(*
+ Assert -
+*)
+
+PROCEDURE Assert (condition: BOOLEAN) ;
+BEGIN
+ IF NOT condition
+ THEN
+ printf ("assert failed, condition is false\n") ;
+ exit (1)
+ END
+END Assert ;
+
+
+
+(*
+ test -
+*)
+
+PROCEDURE test ;
+VAR
+ result : INTEGER ;
+ optstring: String ;
+ i, val : INTEGER ;
+ ch : CHAR ;
+BEGIN
+ longopts := AddLongOption (longopts, 0, InitString ('help'), 0, result, 0) ;
+ longopts := AddLongOption (longopts, 1, InitString ('dir'), 1, result, 0) ;
+ longopts := AddLongOption (longopts, 2, NIL, 0, result, 0) ;
+ optstring := InitString ('hd:') ;
+ i := 1 ;
+ REPEAT
+ val := GetOptLong (UnixArgs.GetArgC (), UnixArgs.GetArgV (),
+ optstring, longopts, i) ;
+ IF val = 0
+ THEN
+ printf ("long option detected, result = %d, val = %d, index i = %d, optstring = %s\n",
+ result, val, i, string (optstring))
+ ELSIF val > 0
+ THEN
+ ch := VAL (CHAR, val) ;
+ CASE ch OF
+
+ 'h': printf ("short option 'h' seen\n")
+
+ ELSE
+ printf ("unknown short option '%c' seen\n", ch)
+ END
+ ELSE
+ printf ("unknown long option\n")
+ END ;
+ INC (i)
+ UNTIL val <= 0
+END test ;
+
+
+VAR
+ longopts: LongOptions ;
+BEGIN
+ longopts := InitLongOptions () ;
+ test ;
+ longopts := KillLongOptions (longopts)
+END testgetopt.
diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testnan.mod b/gcc/testsuite/gm2/pimlib/run/pass/testnan.mod
new file mode 100644
index 0000000..d3c061f
--- /dev/null
+++ b/gcc/testsuite/gm2/pimlib/run/pass/testnan.mod
@@ -0,0 +1,17 @@
+MODULE testnan ;
+
+FROM Builtins IMPORT isnan ;
+FROM libc IMPORT printf, exit ;
+
+VAR
+ x: REAL ;
+BEGIN
+ x := 0.0 / 0.0 ;
+ IF isnan (x) = 1
+ THEN
+ printf ("success isnan working from module Builtins\n")
+ ELSE
+ printf ("failure isnan is not working from module Builtins\n") ;
+ exit (1)
+ END
+END testnan.
diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 35e60ea..157b609 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -78,7 +78,7 @@ proc asan_link_flags_1 { paths lib } {
|| [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.${shlib_ext}"] } {
append flags " -B${gccpath}/libsanitizer/ "
append flags " -B${gccpath}/libsanitizer/${lib}/ "
- append flags " -L${gccpath}/libsanitizer/${lib}/.libs "
+ append flags " -B${gccpath}/libsanitizer/${lib}/.libs "
append ld_library_path ":${gccpath}/libsanitizer/${lib}/.libs"
}
} else {
diff --git a/gcc/testsuite/lib/atomic-dg.exp b/gcc/testsuite/lib/atomic-dg.exp
index 1589acd..ce1799c 100644
--- a/gcc/testsuite/lib/atomic-dg.exp
+++ b/gcc/testsuite/lib/atomic-dg.exp
@@ -33,7 +33,7 @@ proc atomic_link_flags { paths } {
if { [file exists "${gccpath}/libatomic/.libs/libatomic.a"]
|| [file exists "${gccpath}/libatomic/.libs/libatomic.${shlib_ext}"] } {
append flags " -B${gccpath}/libatomic/ "
- append flags " -L${gccpath}/libatomic/.libs"
+ append flags " -B${gccpath}/libatomic/.libs"
append ld_library_path ":${gccpath}/libatomic/.libs"
}
} else {
diff --git a/gcc/testsuite/lib/dg-pch.exp b/gcc/testsuite/lib/dg-pch.exp
index 6b09e8c..b6fefaa 100644
--- a/gcc/testsuite/lib/dg-pch.exp
+++ b/gcc/testsuite/lib/dg-pch.exp
@@ -100,6 +100,27 @@ proc dg-flags-pch { subdir test otherflags options suffix } {
# For the rest, the default is to compile to .s.
set dg-do-what-default compile
+ # Process the target selectors to see whether the remaining
+ # part of the test should be skipped.
+ #
+ # ??? This doesn't currently handle flag-specific skips,
+ # based on dg-options.
+ set dg-do-what [list compile "" P]
+ set dg-extra-tool-flags ""
+ foreach op [dg-get-options "./$bname$suffix"] {
+ switch [lindex $op 0] {
+ dg-require-effective-target -
+ dg-skip-if {
+ if { [catch "$op" msg] } {
+ perror "$bname$suffix: $msg for \"$op\""
+ }
+ }
+ }
+ }
+ if { [lindex ${dg-do-what} 1] == "N" } {
+ continue
+ }
+
set have_errs [llength [grep $test "{\[ \t\]\+dg-error\[ \t\]\+.*\[ \t\]\+}"]]
if { [ file_on_host exists "$bname$suffix.gch" ] } {
@@ -134,8 +155,7 @@ proc dg-flags-pch { subdir test otherflags options suffix } {
fail "$nshort $flags assembly comparison"
}
}
- } elseif { $pch_unsupported_debug == 0 \
- || [llength [grep $test "{\[ \t\]\+dg-require-effective-target\[ \t\]\+pch_supported_debug\[ \t\]\+.*\[ \t\]\+}"]] > 0 } {
+ } else {
verbose -log "pch file '$bname$suffix.gch' missing"
fail "$nshort $flags"
if { !$have_errs } {
diff --git a/gcc/testsuite/lib/target-libpath.exp b/gcc/testsuite/lib/target-libpath.exp
index 6d530fb..5dbb2d3 100644
--- a/gcc/testsuite/lib/target-libpath.exp
+++ b/gcc/testsuite/lib/target-libpath.exp
@@ -67,6 +67,7 @@ proc set_ld_library_path_env_vars { } {
global orig_dyld_library_path
global orig_path
global orig_gcc_exec_prefix
+ global ENABLE_DARWIN_AT_RPATH
global env
# Save the original GCC_EXEC_PREFIX.
@@ -133,6 +134,7 @@ proc set_ld_library_path_env_vars { } {
#
# Doing this is somewhat of a hack as ld_library_path gets repeated in
# SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables.
+ if { ![istarget *-*-darwin*] } {
if { $orig_ld_library_path_saved } {
setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path"
} else {
@@ -166,10 +168,22 @@ proc set_ld_library_path_env_vars { } {
} else {
setenv LD_LIBRARY_PATH_64 "$ld_library_path"
}
- if { $orig_dyld_library_path_saved } {
- setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path"
- } else {
- setenv DYLD_LIBRARY_PATH "$ld_library_path"
+ }
+ if { [istarget *-*-darwin*] } {
+ if { [info exists ENABLE_DARWIN_AT_RPATH] || [istarget *-*-darwin1\[5-9\]*]
+ || [istarget *-*-darwin2*] } {
+ # Either we are not using DYLD_LIBRARY_PATH or we're on a version of the
+ # OS for which it is not passed through system exes.
+ if [info exists env(DYLD_LIBRARY_PATH)] {
+ unsetenv DYLD_LIBRARY_PATH
+ }
+ } else {
+ if { $orig_dyld_library_path_saved } {
+ setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path"
+ } else {
+ setenv DYLD_LIBRARY_PATH "$ld_library_path"
+ }
+ }
}
if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
if { $orig_path_saved } {
@@ -179,6 +193,7 @@ proc set_ld_library_path_env_vars { } {
}
}
+ verbose -log "set paths"
verbose -log "LD_LIBRARY_PATH=[getenv LD_LIBRARY_PATH]"
verbose -log "LD_RUN_PATH=[getenv LD_RUN_PATH]"
verbose -log "SHLIB_PATH=[getenv SHLIB_PATH]"
diff --git a/gcc/testsuite/lib/target-supports-dg.exp b/gcc/testsuite/lib/target-supports-dg.exp
index a80970f..b5658c1 100644
--- a/gcc/testsuite/lib/target-supports-dg.exp
+++ b/gcc/testsuite/lib/target-supports-dg.exp
@@ -334,6 +334,23 @@ proc check-flags { args } {
# The args are within another list; pull them out.
set args [lindex $args 0]
+ # The next two arguments are optional. If they were not specified,
+ # use the defaults.
+ if { [llength $args] == 2 } {
+ lappend args "*"
+ }
+ if { [llength $args] == 3 } {
+ lappend args ""
+ }
+
+ # If the option strings are the defaults, or the same as the
+ # defaults, there is no need to call check_conditional_xfail to
+ # compare them to the actual options.
+ if { [string compare [lindex $args 2] "*"] == 0
+ && [string compare [lindex $args 3] "" ] == 0 } {
+ return 1
+ }
+
# Start the list with a dummy tool name so the list will match "*"
# if there are no flags.
set compiler_flags " toolname "
@@ -350,26 +367,9 @@ proc check-flags { args } {
append compiler_flags "[board_info $dest multilib_flags] "
}
- # The next two arguments are optional. If they were not specified,
- # use the defaults.
- if { [llength $args] == 2 } {
- lappend $args [list "*"]
- }
- if { [llength $args] == 3 } {
- lappend $args [list ""]
- }
-
- # If the option strings are the defaults, or the same as the
- # defaults, there is no need to call check_conditional_xfail to
- # compare them to the actual options.
- if { [string compare [lindex $args 2] "*"] == 0
- && [string compare [lindex $args 3] "" ] == 0 } {
- set result 1
- } else {
- # The target list might be an effective-target keyword, so replace
- # the original list with "*-*-*", since we already know it matches.
- set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]]
- }
+ # The target list might be an effective-target keyword, so replace
+ # the original list with "*-*-*", since we already know it matches.
+ set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]]
# Any value in this variable was left over from an earlier test.
set compiler_flags ""
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index f0b692a..a5f393e 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1903,6 +1903,17 @@ proc check_effective_target_rv_float_abi_soft { } {
}]
}
+# Return 1 if the target arch supports the atomic extension, 0 otherwise.
+# Cache the result.
+
+proc check_effective_target_riscv_a { } {
+ return [check_no_compiler_messages riscv_ext_a assembly {
+ #ifndef __riscv_a
+ #error "Not __riscv_a"
+ #endif
+ }]
+}
+
# Return 1 if the target arch supports the double precision floating point
# extension, 0 otherwise. Cache the result.
@@ -1925,6 +1936,17 @@ proc check_effective_target_riscv_v { } {
}]
}
+# Return 1 if the target arch supports the Zvfh extension, 0 otherwise.
+# Cache the result.
+
+proc check_effective_target_riscv_zvfh { } {
+ return [check_no_compiler_messages riscv_ext_zvfh assembly {
+ #ifndef __riscv_zvfh
+ #error "Not __riscv_zvfh"
+ #endif
+ }]
+}
+
# Return 1 if the target arch supports half float, 0 otherwise.
# Note, this differs from the test performed by
# /* dg-skip-if "" { *-*-* } { "*" } { "-march=rv*zfh*" } */
@@ -1939,6 +1961,17 @@ proc check_effective_target_riscv_zfh { } {
}]
}
+# Return 1 if the target arch supports the TSO memory ordering extension,
+# 0 otherwise. Cache the result.
+
+proc check_effective_target_riscv_ztso { } {
+ return [check_no_compiler_messages riscv_ext_ztso assembly {
+ #ifndef __riscv_ztso
+ #error "Not __riscv_ztso"
+ #endif
+ }]
+}
+
# Return 1 if we can execute code when using dg-add-options riscv_v
proc check_effective_target_riscv_v_ok { } {
@@ -1990,10 +2023,35 @@ proc check_effective_target_riscv_zfh_ok { } {
return 0
}
+# Return 1 if we can execute code when using dg-add-options riscv_zvfh
+
+proc check_effective_target_riscv_zvfh_ok { } {
+ # If the target already supports v without any added options,
+ # we may assume we can execute just fine.
+ if { [check_effective_target_riscv_zvfh] } {
+ return 1
+ }
+
+ # check if we can execute vector insns with the given hardware or
+ # simulator
+ set gcc_march [regsub {[[:alnum:]]*} [riscv_get_arch] &v]
+ if { [check_runtime ${gcc_march}_exec {
+ int main()
+ {
+ asm ("vsetivli zero,8,e16,m1,ta,ma");
+ asm ("vfadd.vv v8,v8,v16" : : : "v8");
+ return 0;
+ } } "-march=${gcc_march}"] } {
+ return 1
+ }
+
+ return 0
+}
+
proc riscv_get_arch { } {
set gcc_march ""
# ??? do we neeed to add more extensions to the list below?
- foreach ext { i m a f d q c v zicsr zifencei zfh zba zbb zbc zbs } {
+ foreach ext { i m a f d q c v zicsr zifencei zfh zba zbb zbc zbs zvfh ztso } {
if { [check_no_compiler_messages riscv_ext_$ext assembly [string map [list DEF __riscv_$ext] {
#ifndef DEF
#error "Not DEF"
@@ -2018,6 +2076,18 @@ proc riscv_get_arch { } {
return "$gcc_march"
}
+proc add_options_for_riscv_a { flags } {
+ if { [lsearch $flags -march=*] >= 0 } {
+ # If there are multiple -march flags, we have to adjust all of them.
+ set expanded_flags [regsub -all -- {((?:^|[[:space:]])-march=rv[[:digit:]]*)g+} $flags \\1imafd ]
+ return [regsub -all -- {((?:^|[[:space:]])-march=rv[[:digit:]]*[b-eg-rt-wy]*)a*} $expanded_flags \\1a ]
+ }
+ if { [check_effective_target_riscv_a] } {
+ return "$flags"
+ }
+ return "$flags -march=[regsub {(rv[[:digit:]]*[b-eg-rt-wy]*)a*} [riscv_get_arch] &a]"
+}
+
proc add_options_for_riscv_d { flags } {
if { [lsearch $flags -march=*] >= 0 } {
# If there are multiple -march flags, we have to adjust all of them.
@@ -2052,6 +2122,30 @@ proc add_options_for_riscv_zfh { flags } {
return "$flags -march=[riscv_get_arch]_zfh"
}
+proc add_options_for_riscv_ztso { flags } {
+ if { [lsearch $flags -march=*] >= 0 } {
+ # If there are multiple -march flags, we have to adjust all of them.
+ set flags [regsub -all -- {(?:^|[[:space:]])-march=[[:alnum:]_.]*} $flags &_ztso ]
+ return [regsub -all -- {((?:^|[[:space:]])-march=[[:alnum:]_.]*_ztso[[:alnum:]_.]*)_ztso} $flags \\1 ]
+ }
+ if { [check_effective_target_riscv_ztso] } {
+ return "$flags"
+ }
+ return "$flags -march=[riscv_get_arch]_ztso"
+}
+
+proc add_options_for_riscv_zvfh { flags } {
+ if { [lsearch $flags -march=*] >= 0 } {
+ # If there are multiple -march flags, we have to adjust all of them.
+ set flags [regsub -all -- {(?:^|[[:space:]])-march=[[:alnum:]_.]*} $flags &_zvfh ]
+ return [regsub -all -- {((?:^|[[:space:]])-march=[[:alnum:]_.]*_zvfh[[:alnum:]_.]*)_zvfh} $flags \\1 ]
+ }
+ if { [check_effective_target_riscv_zvfh] } {
+ return "$flags"
+ }
+ return "$flags -march=[riscv_get_arch]_zvfh"
+}
+
# Return 1 if the target OS supports running SSE executables, 0
# otherwise. Cache the result.
diff --git a/gcc/toplev.cc b/gcc/toplev.cc
index 8af9bf5..9a73489 100644
--- a/gcc/toplev.cc
+++ b/gcc/toplev.cc
@@ -99,7 +99,7 @@ static void general_init (const char *, bool);
static void backend_init (void);
static int lang_dependent_init (const char *);
static void init_asm_output (const char *);
-static void finalize (bool);
+static void finalize ();
static void crash_signal (int) ATTRIBUTE_NORETURN;
static void compile_file (void);
@@ -163,6 +163,7 @@ FILE *aux_info_file;
FILE *callgraph_info_file = NULL;
static bitmap callgraph_info_external_printed;
FILE *stack_usage_file = NULL;
+static bool no_backend = false;
/* The current working directory of a translation. It's generally the
directory from which compilation was initiated, but a preprocessed
@@ -1221,7 +1222,7 @@ parse_alignment_opts (void)
/* Process the options that have been parsed. */
static void
-process_options (bool no_backend)
+process_options ()
{
const char *language_string = lang_hooks.name;
@@ -1871,6 +1872,9 @@ lang_dependent_init (const char *name)
void
target_reinit (void)
{
+ if (no_backend)
+ return;
+
struct rtl_data saved_x_rtl;
rtx *saved_regno_reg_rtx;
tree saved_optimization_current_node;
@@ -1963,7 +1967,7 @@ dump_memory_report (const char *header)
/* Clean up: close opened files, etc. */
static void
-finalize (bool no_backend)
+finalize ()
{
/* Close the dump files. */
if (flag_gen_aux_info)
@@ -2045,7 +2049,7 @@ standard_type_bitsize (int bitsize)
/* Initialize the compiler, and compile the input file. */
static void
-do_compile (bool no_backend)
+do_compile ()
{
/* Don't do any more if an error has already occurred. */
if (!seen_error ())
@@ -2132,7 +2136,7 @@ do_compile (bool no_backend)
timevar_start (TV_PHASE_FINALIZE);
- finalize (no_backend);
+ finalize ();
timevar_stop (TV_PHASE_FINALIZE);
}
@@ -2273,13 +2277,13 @@ toplev::main (int argc, char **argv)
initialization based on the command line options. This hook also
sets the original filename if appropriate (e.g. foo.i -> foo.c)
so we can correctly initialize debug output. */
- bool no_backend = lang_hooks.post_options (&main_input_filename);
+ no_backend = lang_hooks.post_options (&main_input_filename);
- process_options (no_backend);
+ process_options ();
if (m_use_TV_TOTAL)
start_timevars ();
- do_compile (no_backend);
+ do_compile ();
if (flag_self_test && !seen_error ())
{
@@ -2324,6 +2328,7 @@ toplev::main (int argc, char **argv)
void
toplev::finalize (void)
{
+ no_backend = false;
rtl_initialized = false;
this_target_rtl->target_specific_initialized = false;
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 981112d..7150665 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -81,8 +81,9 @@ extern int flag_rerun_cse_after_global_opts;
extern void print_version (FILE *, const char *, bool);
-/* The hashtable, so that the C front ends can pass it to cpplib. */
+/* The hashtables, so that the C front ends can pass them to cpplib. */
extern struct ht *ident_hash;
+extern struct ht *ident_hash_extra;
/* Functions used to get and set GCC's notion of in what directory
compilation was started. */
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index ffeb20b..40a6f2a 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -878,7 +878,7 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
fallthru = false;
break;
case GIMPLE_RESX:
- make_eh_edges (last);
+ make_eh_edge (last);
fallthru = false;
break;
case GIMPLE_EH_DISPATCH:
@@ -894,7 +894,7 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
/* If this statement has reachable exception handlers, then
create abnormal edges to them. */
- make_eh_edges (last);
+ make_eh_edge (last);
/* BUILTIN_RETURN is really a return statement. */
if (gimple_call_builtin_p (last, BUILT_IN_RETURN))
@@ -911,7 +911,7 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
/* A GIMPLE_ASSIGN may throw internally and thus be considered
control-altering. */
if (is_ctrl_altering_stmt (last))
- make_eh_edges (last);
+ make_eh_edge (last);
fallthru = true;
break;
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 2c89b65..1343534 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -389,6 +389,9 @@ enum omp_clause_code {
/* OpenACC/OpenMP clause: if (scalar-expression). */
OMP_CLAUSE_IF,
+ /* OpenACC clause: self. */
+ OMP_CLAUSE_SELF,
+
/* OpenMP clause: num_threads (integer-expression). */
OMP_CLAUSE_NUM_THREADS,
@@ -1079,10 +1082,11 @@ struct GTY(()) tree_base {
unsigned spare1 : 8;
- /* This field is only used with TREE_TYPE nodes; the only reason it is
+ /* For _TYPE nodes, this is TYPE_ADDR_SPACE; the reason it is
present in tree_base instead of tree_type is to save space. The size
of the field must be large enough to hold addr_space_t values.
- For CONSTRUCTOR nodes this holds the clobber_kind enum. */
+ For CONSTRUCTOR nodes this holds the clobber_kind enum.
+ The C++ front-end uses this in IDENTIFIER_NODE and NAMESPACE_DECL. */
unsigned address_space : 8;
} bits;
diff --git a/gcc/tree-diagnostic.cc b/gcc/tree-diagnostic.cc
index a600f0e..cae400c 100644
--- a/gcc/tree-diagnostic.cc
+++ b/gcc/tree-diagnostic.cc
@@ -217,7 +217,7 @@ maybe_unwind_expanded_macro_loc (diagnostic_context *context,
This is the locus 2/ of the earlier comment. */
location_t resolved_exp_loc =
linemap_resolve_location (line_table,
- MACRO_MAP_EXPANSION_POINT_LOCATION (iter->map),
+ iter->map->get_expansion_point_location (),
LRK_MACRO_DEFINITION_LOCATION, NULL);
diagnostic_append_note (context, resolved_exp_loc,
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index 1cb8e08..6a30ed9 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -2275,7 +2275,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt)
if there is such a landing pad within the current function. */
edge
-make_eh_edges (gimple *stmt)
+make_eh_edge (gimple *stmt)
{
basic_block src, dst;
eh_landing_pad lp;
@@ -4921,7 +4921,7 @@ make_pass_cleanup_eh (gcc::context *ctxt)
#endif
/* Verify that BB containing STMT as the last statement, has precisely the
- edge that make_eh_edges would create. */
+ edge that make_eh_edge would create. */
DEBUG_FUNCTION bool
verify_eh_edges (gimple *stmt)
diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h
index 1382568..045424f 100644
--- a/gcc/tree-eh.h
+++ b/gcc/tree-eh.h
@@ -30,7 +30,7 @@ extern bool remove_stmt_from_eh_lp (gimple *);
extern int lookup_stmt_eh_lp_fn (struct function *, const gimple *);
extern int lookup_stmt_eh_lp (const gimple *);
extern bool make_eh_dispatch_edges (geh_dispatch *);
-extern edge make_eh_edges (gimple *);
+extern edge make_eh_edge (gimple *);
extern edge redirect_eh_edge (edge, basic_block);
extern void redirect_eh_dispatch_edge (geh_dispatch *, edge, basic_block);
extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool,
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index d63060c..00d0510 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -2615,7 +2615,7 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den,
}
else if (can_throw)
{
- make_eh_edges (copy_stmt);
+ make_eh_edge (copy_stmt);
update_probs = true;
}
@@ -3578,9 +3578,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
STRIP_USELESS_TYPE_CONVERSION (rhs);
- /* If we are in SSA form properly remap the default definition
- or assign to a dummy SSA name if the parameter is unused and
- we are not optimizing. */
+ /* If we are in SSA form properly remap the default definition. */
if (gimple_in_ssa_p (cfun) && is_gimple_reg (p))
{
if (def)
@@ -3590,11 +3588,6 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
SSA_NAME_IS_DEFAULT_DEF (def) = 0;
set_ssa_default_def (cfun, var, NULL);
}
- else if (!optimize)
- {
- def = make_ssa_name (var);
- init_stmt = gimple_build_assign (def, rhs);
- }
}
else if (!is_empty_type (TREE_TYPE (var)))
init_stmt = gimple_build_assign (var, rhs);
@@ -3653,6 +3646,23 @@ initialize_inlined_parameters (copy_body_data *id, gimple *stmt,
&& SSA_NAME_VAR (*defp) == var)
TREE_TYPE (*defp) = TREE_TYPE (var);
}
+ /* When not optimizing and the parameter is unused, assign to
+ a dummy SSA name. Do this after remapping the type above. */
+ else if (!optimize
+ && is_gimple_reg (p)
+ && i < gimple_call_num_args (stmt))
+ {
+ tree val = gimple_call_arg (stmt, i);
+ if (val != error_mark_node)
+ {
+ if (!useless_type_conversion_p (TREE_TYPE (p),
+ TREE_TYPE (val)))
+ val = force_value_to_type (TREE_TYPE (p), val);
+ def = make_ssa_name (var);
+ gimple *init_stmt = gimple_build_assign (def, val);
+ insert_init_stmt (id, bb, init_stmt);
+ }
+ }
}
}
diff --git a/gcc/tree-nested.cc b/gcc/tree-nested.cc
index d2fe3fc..51a7a03 100644
--- a/gcc/tree-nested.cc
+++ b/gcc/tree-nested.cc
@@ -1374,6 +1374,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
/* FALLTHRU */
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_DOACROSS:
@@ -2165,6 +2166,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
/* FALLTHRU */
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_SELF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_DOACROSS:
diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
index a62af05..28f27ad 100644
--- a/gcc/tree-object-size.cc
+++ b/gcc/tree-object-size.cc
@@ -1575,8 +1575,8 @@ parm_object_size (struct object_size_info *osi, tree var)
tree typesize = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (parm)));
tree sz = NULL_TREE;
- /* If we have an explicit access attribute with a usable size argument... */
- if (access && access->sizarg != UINT_MAX && !access->internal_p
+ /* If we have an access attribute with a usable size argument... */
+ if (access && access->sizarg != UINT_MAX
/* ... and either PARM is void * or has a type that is complete and has a
constant size... */
&& ((typesize && poly_int_tree_p (typesize))
@@ -1587,10 +1587,14 @@ parm_object_size (struct object_size_info *osi, tree var)
unsigned argpos = 0;
/* ... then walk through the parameters to pick the size parameter and
- safely scale it by the type size if needed. */
+ safely scale it by the type size if needed.
+
+ TODO: we could also compute the size of VLAs where the size is
+ given by a function parameter. */
for (arg = fnargs; arg; arg = TREE_CHAIN (arg), ++argpos)
- if (argpos == access->sizarg && INTEGRAL_TYPE_P (TREE_TYPE (arg)))
+ if (argpos == access->sizarg)
{
+ gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (arg)));
sz = get_or_create_ssa_default_def (cfun, arg);
if (sz != NULL_TREE)
{
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 58705c5..1fadd75 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -587,6 +587,13 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
pp_right_paren (pp);
break;
+ case OMP_CLAUSE_SELF:
+ pp_string (pp, "self(");
+ dump_generic_node (pp, OMP_CLAUSE_SELF_EXPR (clause),
+ spc, flags, false);
+ pp_right_paren (pp);
+ break;
+
case OMP_CLAUSE_NUM_THREADS:
pp_string (pp, "num_threads(");
dump_generic_node (pp, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
@@ -1453,7 +1460,6 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
false);
pp_right_paren (pp);
break;
-
default:
gcc_unreachable ();
}
diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index 95a15fe..a6524de 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -3353,11 +3353,13 @@ scev_finalize (void)
}
/* Returns true if the expression EXPR is considered to be too expensive
- for scev_const_prop. */
+ for scev_const_prop. Sets *COND_OVERFLOW_P to true when the
+ expression might contain a sub-expression that is subject to undefined
+ overflow behavior and conditionally evaluated. */
static bool
-expression_expensive_p (tree expr, hash_map<tree, uint64_t> &cache,
- uint64_t &cost)
+expression_expensive_p (tree expr, bool *cond_overflow_p,
+ hash_map<tree, uint64_t> &cache, uint64_t &cost)
{
enum tree_code code;
@@ -3444,7 +3446,7 @@ bitcount_call:
}
FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
- if (expression_expensive_p (arg, cache, op_cost))
+ if (expression_expensive_p (arg, cond_overflow_p, cache, op_cost))
return true;
*cache.get (expr) += op_cost;
cost += op_cost + 1;
@@ -3453,7 +3455,8 @@ bitcount_call:
if (code == COND_EXPR)
{
- if (expression_expensive_p (TREE_OPERAND (expr, 0), cache, op_cost)
+ if (expression_expensive_p (TREE_OPERAND (expr, 0), cond_overflow_p,
+ cache, op_cost)
|| (EXPR_P (TREE_OPERAND (expr, 1))
&& EXPR_P (TREE_OPERAND (expr, 2)))
/* If either branch has side effects or could trap. */
@@ -3461,11 +3464,13 @@ bitcount_call:
|| generic_expr_could_trap_p (TREE_OPERAND (expr, 1))
|| TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0))
|| generic_expr_could_trap_p (TREE_OPERAND (expr, 0))
- || expression_expensive_p (TREE_OPERAND (expr, 1),
+ || expression_expensive_p (TREE_OPERAND (expr, 1), cond_overflow_p,
cache, op_cost)
- || expression_expensive_p (TREE_OPERAND (expr, 2),
+ || expression_expensive_p (TREE_OPERAND (expr, 2), cond_overflow_p,
cache, op_cost))
return true;
+ /* Conservatively assume there's overflow for now. */
+ *cond_overflow_p = true;
*cache.get (expr) += op_cost;
cost += op_cost + 1;
return false;
@@ -3475,12 +3480,14 @@ bitcount_call:
{
case tcc_binary:
case tcc_comparison:
- if (expression_expensive_p (TREE_OPERAND (expr, 1), cache, op_cost))
+ if (expression_expensive_p (TREE_OPERAND (expr, 1), cond_overflow_p,
+ cache, op_cost))
return true;
/* Fallthru. */
case tcc_unary:
- if (expression_expensive_p (TREE_OPERAND (expr, 0), cache, op_cost))
+ if (expression_expensive_p (TREE_OPERAND (expr, 0), cond_overflow_p,
+ cache, op_cost))
return true;
*cache.get (expr) += op_cost;
cost += op_cost + 1;
@@ -3492,11 +3499,12 @@ bitcount_call:
}
bool
-expression_expensive_p (tree expr)
+expression_expensive_p (tree expr, bool *cond_overflow_p)
{
hash_map<tree, uint64_t> cache;
uint64_t expanded_size = 0;
- return (expression_expensive_p (expr, cache, expanded_size)
+ *cond_overflow_p = false;
+ return (expression_expensive_p (expr, cond_overflow_p, cache, expanded_size)
|| expanded_size > cache.elements ());
}
@@ -3796,6 +3804,7 @@ final_value_replacement_loop (class loop *loop)
niter_num)))
def = bit_def;
+ bool cond_overflow_p;
if (!tree_does_not_contain_chrecs (def)
|| chrec_contains_symbols_defined_in_loop (def, ex_loop->num)
/* Moving the computation from the loop may prolong life range
@@ -3809,7 +3818,7 @@ final_value_replacement_loop (class loop *loop)
he probably knows that n is not large, and does not want it
to be turned into n %= 45. */
- || expression_expensive_p (def))
+ || expression_expensive_p (def, &cond_overflow_p))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -3834,15 +3843,23 @@ final_value_replacement_loop (class loop *loop)
def = unshare_expr (def);
remove_phi_node (&psi, false);
+ /* Create the replacement statements. */
+ gimple_seq stmts;
+ def = force_gimple_operand (def, &stmts, false, NULL_TREE);
+ gassign *ass = gimple_build_assign (rslt, def);
+ gimple_set_location (ass,
+ gimple_phi_arg_location (phi, exit->dest_idx));
+ gimple_seq_add_stmt (&stmts, ass);
+
/* If def's type has undefined overflow and there were folded
casts, rewrite all stmts added for def into arithmetics
with defined overflow behavior. */
- if (folded_casts && ANY_INTEGRAL_TYPE_P (TREE_TYPE (def))
- && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (def)))
+ if ((folded_casts
+ && ANY_INTEGRAL_TYPE_P (TREE_TYPE (def))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (def)))
+ || cond_overflow_p)
{
- gimple_seq stmts;
gimple_stmt_iterator gsi2;
- def = force_gimple_operand (def, &stmts, true, NULL_TREE);
gsi2 = gsi_start (stmts);
while (!gsi_end_p (gsi2))
{
@@ -3861,17 +3878,11 @@ final_value_replacement_loop (class loop *loop)
}
}
else
- def = force_gimple_operand_gsi (&gsi, def, false, NULL_TREE,
- true, GSI_SAME_STMT);
-
- gassign *ass = gimple_build_assign (rslt, def);
- gimple_set_location (ass,
- gimple_phi_arg_location (phi, exit->dest_idx));
- gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
+ gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
if (dump_file)
{
fprintf (dump_file, "\n final stmt:\n ");
- print_gimple_stmt (dump_file, ass, 0);
+ print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (rslt), 0);
fprintf (dump_file, "\n");
}
}
diff --git a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h
index f35ca1b..a64ed78 100644
--- a/gcc/tree-scalar-evolution.h
+++ b/gcc/tree-scalar-evolution.h
@@ -36,7 +36,7 @@ extern tree resolve_mixers (class loop *, tree, bool *);
extern void gather_stats_on_scev_database (void);
extern bool final_value_replacement_loop (class loop *);
extern unsigned int scev_const_prop (void);
-extern bool expression_expensive_p (tree);
+extern bool expression_expensive_p (tree, bool *);
extern bool simple_iv_with_niters (class loop *, class loop *, tree,
struct affine_iv *, tree *, bool);
extern bool simple_iv (class loop *, class loop *, tree, struct affine_iv *,
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index f8dff8b..b985dee 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -4275,7 +4275,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
|| TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
- || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
+ || (TREE_CODE (rhs) == BIT_FIELD_REF && !sra_handled_bf_read_p (rhs))
+ || TREE_CODE (lhs) == BIT_FIELD_REF)
{
modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
gsi, false);
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 98e5b30..c333660 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -5527,7 +5527,8 @@ may_eliminate_iv (struct ivopts_data *data,
/* It is unlikely that computing the number of iterations using division
would be more profitable than keeping the original induction variable. */
- if (expression_expensive_p (*bound))
+ bool cond_overflow_p;
+ if (expression_expensive_p (*bound, &cond_overflow_p))
return false;
/* Sometimes, it is possible to handle the situation that the number of
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index 619b50f..b4611ac 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -1455,10 +1455,7 @@ hoist_guard (class loop *loop, edge guard)
cond_stmt = as_a <gcond *> (stmt);
extract_true_false_edges_from_block (guard_bb, &te, &fe);
/* Insert guard to PRE_HEADER. */
- if (!empty_block_p (pre_header))
- gsi = gsi_last_bb (pre_header);
- else
- gsi = gsi_start_bb (pre_header);
+ gsi = gsi_last_bb (pre_header);
/* Create copy of COND_STMT. */
new_cond_stmt = gimple_build_cond (gimple_cond_code (cond_stmt),
gimple_cond_lhs (cond_stmt),
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 312a6f9..bb55a4f 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -310,7 +310,9 @@ factor_out_conditional_operation (edge e0, edge e1, gphi *phi,
return NULL;
/* If arg1 is an INTEGER_CST, fold it to new type. */
if (INTEGRAL_TYPE_P (TREE_TYPE (new_arg0))
- && int_fits_type_p (arg1, TREE_TYPE (new_arg0)))
+ && (int_fits_type_p (arg1, TREE_TYPE (new_arg0))
+ || (TYPE_PRECISION (TREE_TYPE (new_arg0))
+ == TYPE_PRECISION (TREE_TYPE (arg1)))))
{
if (gimple_assign_cast_p (arg0_def_stmt))
{
@@ -322,8 +324,12 @@ factor_out_conditional_operation (edge e0, edge e1, gphi *phi,
if arg0_def_stmt is the only non-debug stmt in
its basic block, because then it is possible this
could enable further optimizations (minmax replacement
- etc.). See PR71016. */
- if (new_arg0 != gimple_cond_lhs (cond_stmt)
+ etc.). See PR71016.
+ Note no-op conversions don't have this issue as
+ it will not generate any zero/sign extend in that case. */
+ if ((TYPE_PRECISION (TREE_TYPE (new_arg0))
+ != TYPE_PRECISION (TREE_TYPE (arg1)))
+ && new_arg0 != gimple_cond_lhs (cond_stmt)
&& new_arg0 != gimple_cond_rhs (cond_stmt)
&& gimple_bb (arg0_def_stmt) == e0->src)
{
@@ -354,6 +360,10 @@ factor_out_conditional_operation (edge e0, edge e1, gphi *phi,
return NULL;
}
new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1);
+
+ /* Drop the overlow that fold_convert might add. */
+ if (TREE_OVERFLOW (new_arg1))
+ new_arg1 = drop_tree_overflow (new_arg1);
}
else
return NULL;
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 9c25512..43ca985 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1626,12 +1626,31 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
edge temp_e = redirect_edge_and_branch (exit, new_preheader);
flush_pending_stmts (temp_e);
}
-
/* Record the new SSA names in the cache so that we can skip materializing
them again when we fill in the rest of the LCSSA variables. */
for (auto phi : new_phis)
{
tree new_arg = gimple_phi_arg (phi, 0)->def;
+
+ if (!SSA_VAR_P (new_arg))
+ continue;
+ /* If the PHI MEM node dominates the loop then we shouldn't create
+ a new LC-SSSA PHI for it in the intermediate block. */
+ /* A MEM phi that consitutes a new DEF for the vUSE chain can either
+ be a .VDEF or a PHI that operates on MEM. And said definition
+ must not be inside the main loop. Or we must be a parameter.
+ In the last two cases we may remove a non-MEM PHI node, but since
+ they dominate both loops the removal is unlikely to cause trouble
+ as the exits must already be using them. */
+ if (virtual_operand_p (new_arg)
+ && (SSA_NAME_IS_DEFAULT_DEF (new_arg)
+ || !flow_bb_inside_loop_p (loop,
+ gimple_bb (SSA_NAME_DEF_STMT (new_arg)))))
+ {
+ auto gsi = gsi_for_stmt (phi);
+ remove_phi_node (&gsi, true);
+ continue;
+ }
new_phi_args.put (new_arg, gimple_phi_result (phi));
if (TREE_CODE (new_arg) != SSA_NAME)
@@ -1904,8 +1923,10 @@ iv_phi_p (stmt_vec_info stmt_info)
/* Return true if vectorizer can peel for nonlinear iv. */
static bool
vect_can_peel_nonlinear_iv_p (loop_vec_info loop_vinfo,
- enum vect_induction_op_type induction_type)
+ stmt_vec_info stmt_info)
{
+ enum vect_induction_op_type induction_type
+ = STMT_VINFO_LOOP_PHI_EVOLUTION_TYPE (stmt_info);
tree niters_skip;
/* Init_expr will be update by vect_update_ivs_after_vectorizer,
if niters or vf is unkown:
@@ -1926,11 +1947,31 @@ vect_can_peel_nonlinear_iv_p (loop_vec_info loop_vinfo,
return false;
}
+ /* Avoid compile time hog on vect_peel_nonlinear_iv_init. */
+ if (induction_type == vect_step_op_mul)
+ {
+ tree step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_info);
+ tree type = TREE_TYPE (step_expr);
+
+ if (wi::exact_log2 (wi::to_wide (step_expr)) == -1
+ && LOOP_VINFO_INT_NITERS(loop_vinfo) >= TYPE_PRECISION (type))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Avoid compile time hog on"
+ " vect_peel_nonlinear_iv_init"
+ " for nonlinear induction vec_step_op_mul"
+ " when iteration count is too big.\n");
+ return false;
+ }
+ }
+
/* Also doens't support peel for neg when niter is variable.
??? generate something like niter_expr & 1 ? init_expr : -init_expr? */
niters_skip = LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo);
if ((niters_skip != NULL_TREE
- && TREE_CODE (niters_skip) != INTEGER_CST)
+ && (TREE_CODE (niters_skip) != INTEGER_CST
+ || (HOST_WIDE_INT) TREE_INT_CST_LOW (niters_skip) < 0))
|| (!vect_use_loop_mask_for_alignment_p (loop_vinfo)
&& LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) < 0))
{
@@ -1991,7 +2032,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
induction_type = STMT_VINFO_LOOP_PHI_EVOLUTION_TYPE (phi_info);
if (induction_type != vect_step_op_add)
{
- if (!vect_can_peel_nonlinear_iv_p (loop_vinfo, induction_type))
+ if (!vect_can_peel_nonlinear_iv_p (loop_vinfo, phi_info))
return false;
continue;
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 4a8b0a1..40f167d 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -9222,12 +9222,17 @@ vect_peel_nonlinear_iv_init (gimple_seq* stmts, tree init_expr,
{
tree utype = unsigned_type_for (type);
init_expr = gimple_convert (stmts, utype, init_expr);
- unsigned skipn = TREE_INT_CST_LOW (skip_niters);
+ wide_int skipn = wi::to_wide (skip_niters);
wide_int begin = wi::to_wide (step_expr);
- for (unsigned i = 0; i != skipn - 1; i++)
- begin = wi::mul (begin, wi::to_wide (step_expr));
+ auto_mpz base, exp, mod, res;
+ wi::to_mpz (begin, base, TYPE_SIGN (type));
+ wi::to_mpz (skipn, exp, UNSIGNED);
+ mpz_ui_pow_ui (mod, 2, TYPE_PRECISION (type));
+ mpz_powm (res, base, exp, mod);
+ begin = wi::from_mpz (type, res, TYPE_SIGN (type));
tree mult_expr = wide_int_to_tree (utype, begin);
- init_expr = gimple_build (stmts, MULT_EXPR, utype, init_expr, mult_expr);
+ init_expr = gimple_build (stmts, MULT_EXPR, utype,
+ init_expr, mult_expr);
init_expr = gimple_convert (stmts, type, init_expr);
}
break;
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 24bf658..43d742e 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -564,6 +564,7 @@ vect_get_operand_map (const gimple *stmt, bool gather_scatter_p = false,
return arg1_map;
case IFN_MASK_GATHER_LOAD:
+ case IFN_MASK_LEN_GATHER_LOAD:
return arg1_arg4_map;
case IFN_MASK_STORE:
@@ -1158,7 +1159,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
if (cfn == CFN_MASK_LOAD
|| cfn == CFN_GATHER_LOAD
- || cfn == CFN_MASK_GATHER_LOAD)
+ || cfn == CFN_MASK_GATHER_LOAD
+ || cfn == CFN_MASK_LEN_GATHER_LOAD)
ldst_p = true;
else if (cfn == CFN_MASK_STORE)
{
@@ -1298,6 +1300,9 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
|| rhs_code == COMPONENT_REF
|| rhs_code == MEM_REF)))
|| (ldst_p
+ && (STMT_VINFO_GROUPED_ACCESS (stmt_info)
+ != STMT_VINFO_GROUPED_ACCESS (first_stmt_info)))
+ || (ldst_p
&& (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
!= STMT_VINFO_GATHER_SCATTER_P (first_stmt_info)))
|| first_stmt_ldst_p != ldst_p
@@ -1422,6 +1427,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))
&& rhs_code != CFN_GATHER_LOAD
&& rhs_code != CFN_MASK_GATHER_LOAD
+ && rhs_code != CFN_MASK_LEN_GATHER_LOAD
&& !STMT_VINFO_GATHER_SCATTER_P (stmt_info)
/* Not grouped loads are handled as externals for BB
vectorization. For loop vectorization we can handle
@@ -1924,7 +1930,8 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
if (gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt))
gcc_assert (gimple_call_internal_p (stmt, IFN_MASK_LOAD)
|| gimple_call_internal_p (stmt, IFN_GATHER_LOAD)
- || gimple_call_internal_p (stmt, IFN_MASK_GATHER_LOAD));
+ || gimple_call_internal_p (stmt, IFN_MASK_GATHER_LOAD)
+ || gimple_call_internal_p (stmt, IFN_MASK_LEN_GATHER_LOAD));
else if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
gcc_assert (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)));
else
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 337b24c..a920076 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -6058,14 +6058,16 @@ vectorizable_assignment (vec_info *vinfo,
/* But a conversion that does not change the bit-pattern is ok. */
&& !(INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
&& INTEGRAL_TYPE_P (TREE_TYPE (op))
- && (TYPE_PRECISION (TREE_TYPE (scalar_dest))
+ && (((TYPE_PRECISION (TREE_TYPE (scalar_dest))
> TYPE_PRECISION (TREE_TYPE (op)))
- && TYPE_UNSIGNED (TREE_TYPE (op))))
+ && TYPE_UNSIGNED (TREE_TYPE (op)))
+ || (TYPE_PRECISION (TREE_TYPE (scalar_dest))
+ == TYPE_PRECISION (TREE_TYPE (op))))))
{
if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "type conversion to/from bit-precision "
- "unsupported.\n");
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "type conversion to/from bit-precision "
+ "unsupported.\n");
return false;
}
@@ -8626,6 +8628,9 @@ vectorizable_store (vec_info *vinfo,
alias_off = build_int_cst (ref_type, 0);
stmt_vec_info next_stmt_info = first_stmt_info;
auto_vec<tree> vec_oprnds (ncopies);
+ /* For costing some adjacent vector stores, we'd like to cost with
+ the total number of them once instead of cost each one by one. */
+ unsigned int n_adjacent_stores = 0;
for (g = 0; g < group_size; g++)
{
running_off = offvar;
@@ -8683,10 +8688,7 @@ vectorizable_store (vec_info *vinfo,
store to avoid ICE like 110776. */
if (VECTOR_TYPE_P (ltype)
&& known_ne (TYPE_VECTOR_SUBPARTS (ltype), 1U))
- vect_get_store_cost (vinfo, stmt_info, 1,
- alignment_support_scheme,
- misalignment, &inside_cost,
- cost_vec);
+ n_adjacent_stores++;
else
inside_cost
+= record_stmt_cost (cost_vec, 1, scalar_store,
@@ -8743,11 +8745,18 @@ vectorizable_store (vec_info *vinfo,
break;
}
- if (costing_p && dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "vect_model_store_cost: inside_cost = %d, "
- "prologue_cost = %d .\n",
- inside_cost, prologue_cost);
+ if (costing_p)
+ {
+ if (n_adjacent_stores > 0)
+ vect_get_store_cost (vinfo, stmt_info, n_adjacent_stores,
+ alignment_support_scheme, misalignment,
+ &inside_cost, cost_vec);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_store_cost: inside_cost = %d, "
+ "prologue_cost = %d .\n",
+ inside_cost, prologue_cost);
+ }
return true;
}
@@ -8854,6 +8863,9 @@ vectorizable_store (vec_info *vinfo,
{
gcc_assert (!slp && grouped_store);
unsigned inside_cost = 0, prologue_cost = 0;
+ /* For costing some adjacent vector stores, we'd like to cost with
+ the total number of them once instead of cost each one by one. */
+ unsigned int n_adjacent_stores = 0;
for (j = 0; j < ncopies; j++)
{
gimple *new_stmt;
@@ -8919,10 +8931,7 @@ vectorizable_store (vec_info *vinfo,
if (costing_p)
{
- for (i = 0; i < vec_num; i++)
- vect_get_store_cost (vinfo, stmt_info, 1,
- alignment_support_scheme, misalignment,
- &inside_cost, cost_vec);
+ n_adjacent_stores += vec_num;
continue;
}
@@ -9012,11 +9021,18 @@ vectorizable_store (vec_info *vinfo,
STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt);
}
- if (costing_p && dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "vect_model_store_cost: inside_cost = %d, "
- "prologue_cost = %d .\n",
- inside_cost, prologue_cost);
+ if (costing_p)
+ {
+ if (n_adjacent_stores > 0)
+ vect_get_store_cost (vinfo, stmt_info, n_adjacent_stores,
+ alignment_support_scheme, misalignment,
+ &inside_cost, cost_vec);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_store_cost: inside_cost = %d, "
+ "prologue_cost = %d .\n",
+ inside_cost, prologue_cost);
+ }
return true;
}
@@ -9235,6 +9251,9 @@ vectorizable_store (vec_info *vinfo,
|| memory_access_type == VMAT_CONTIGUOUS_REVERSE);
unsigned inside_cost = 0, prologue_cost = 0;
+ /* For costing some adjacent vector stores, we'd like to cost with
+ the total number of them once instead of cost each one by one. */
+ unsigned int n_adjacent_stores = 0;
auto_vec<tree> result_chain (group_size);
auto_vec<tree, 1> vec_oprnds;
for (j = 0; j < ncopies; j++)
@@ -9396,9 +9415,7 @@ vectorizable_store (vec_info *vinfo,
if (costing_p)
{
- vect_get_store_cost (vinfo, stmt_info, 1,
- alignment_support_scheme, misalignment,
- &inside_cost, cost_vec);
+ n_adjacent_stores++;
if (!slp)
{
@@ -9568,6 +9585,11 @@ vectorizable_store (vec_info *vinfo,
if (costing_p)
{
+ if (n_adjacent_stores > 0)
+ vect_get_store_cost (vinfo, stmt_info, n_adjacent_stores,
+ alignment_support_scheme, misalignment,
+ &inside_cost, cost_vec);
+
/* When vectorizing a store into the function result assign
a penalty if the function returns in a multi-register location.
In this case we assume we'll end up with having to spill the
@@ -10275,6 +10297,9 @@ vectorizable_load (vec_info *vinfo,
unsigned HOST_WIDE_INT
elsz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (vectype)));
unsigned int n_groups = 0;
+ /* For costing some adjacent vector loads, we'd like to cost with
+ the total number of them once instead of cost each one by one. */
+ unsigned int n_adjacent_loads = 0;
for (j = 0; j < ncopies; j++)
{
if (nloads > 1 && !costing_p)
@@ -10288,10 +10313,7 @@ vectorizable_load (vec_info *vinfo,
avoid ICE, see PR110776. */
if (VECTOR_TYPE_P (ltype)
&& memory_access_type != VMAT_ELEMENTWISE)
- vect_get_load_cost (vinfo, stmt_info, 1,
- alignment_support_scheme, misalignment,
- false, &inside_cost, nullptr, cost_vec,
- cost_vec, true);
+ n_adjacent_loads++;
else
inside_cost += record_stmt_cost (cost_vec, 1, scalar_load,
stmt_info, 0, vect_body);
@@ -10385,11 +10407,19 @@ vectorizable_load (vec_info *vinfo,
false, &n_perms);
}
- if (costing_p && dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "vect_model_load_cost: inside_cost = %u, "
- "prologue_cost = 0 .\n",
- inside_cost);
+ if (costing_p)
+ {
+ if (n_adjacent_loads > 0)
+ vect_get_load_cost (vinfo, stmt_info, n_adjacent_loads,
+ alignment_support_scheme, misalignment, false,
+ &inside_cost, nullptr, cost_vec, cost_vec,
+ true);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: inside_cost = %u, "
+ "prologue_cost = 0 .\n",
+ inside_cost);
+ }
return true;
}
@@ -10694,6 +10724,9 @@ vectorizable_load (vec_info *vinfo,
gcc_assert (grouped_load && !slp);
unsigned int inside_cost = 0, prologue_cost = 0;
+ /* For costing some adjacent vector loads, we'd like to cost with
+ the total number of them once instead of cost each one by one. */
+ unsigned int n_adjacent_loads = 0;
for (j = 0; j < ncopies; j++)
{
if (costing_p)
@@ -10725,9 +10758,7 @@ vectorizable_load (vec_info *vinfo,
true);
}
}
- vect_get_load_cost (vinfo, stmt_info, 1, alignment_support_scheme,
- misalignment, false, &inside_cost,
- &prologue_cost, cost_vec, cost_vec, true);
+ n_adjacent_loads++;
continue;
}
@@ -10829,11 +10860,19 @@ vectorizable_load (vec_info *vinfo,
*vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0];
}
- if (costing_p && dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "vect_model_load_cost: inside_cost = %u, "
- "prologue_cost = %u .\n",
- inside_cost, prologue_cost);
+ if (costing_p)
+ {
+ if (n_adjacent_loads > 0)
+ vect_get_load_cost (vinfo, stmt_info, n_adjacent_loads,
+ alignment_support_scheme, misalignment, false,
+ &inside_cost, &prologue_cost, cost_vec,
+ cost_vec, true);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: inside_cost = %u, "
+ "prologue_cost = %u .\n",
+ inside_cost, prologue_cost);
+ }
return true;
}
@@ -11177,6 +11216,9 @@ vectorizable_load (vec_info *vinfo,
poly_uint64 group_elt = 0;
unsigned int inside_cost = 0, prologue_cost = 0;
+ /* For costing some adjacent vector loads, we'd like to cost with
+ the total number of them once instead of cost each one by one. */
+ unsigned int n_adjacent_loads = 0;
for (j = 0; j < ncopies; j++)
{
/* 1. Create the vector or array pointer update chain. */
@@ -11571,10 +11613,18 @@ vectorizable_load (vec_info *vinfo,
|| memory_access_type == VMAT_CONTIGUOUS_REVERSE
|| (memory_access_type == VMAT_CONTIGUOUS_PERMUTE
&& (!grouped_load || first_stmt_info_p)))
- vect_get_load_cost (vinfo, stmt_info, 1,
- alignment_support_scheme, misalignment,
- add_realign_cost, &inside_cost,
- &prologue_cost, cost_vec, cost_vec, true);
+ {
+ /* Leave realign cases alone to keep them simple. */
+ if (alignment_support_scheme == dr_explicit_realign_optimized
+ || alignment_support_scheme == dr_explicit_realign)
+ vect_get_load_cost (vinfo, stmt_info, 1,
+ alignment_support_scheme, misalignment,
+ add_realign_cost, &inside_cost,
+ &prologue_cost, cost_vec, cost_vec,
+ true);
+ else
+ n_adjacent_loads++;
+ }
}
else
{
@@ -11745,6 +11795,11 @@ vectorizable_load (vec_info *vinfo,
gcc_assert (memory_access_type == VMAT_CONTIGUOUS
|| memory_access_type == VMAT_CONTIGUOUS_REVERSE
|| memory_access_type == VMAT_CONTIGUOUS_PERMUTE);
+ if (n_adjacent_loads > 0)
+ vect_get_load_cost (vinfo, stmt_info, n_adjacent_loads,
+ alignment_support_scheme, misalignment, false,
+ &inside_cost, &prologue_cost, cost_vec, cost_vec,
+ true);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"vect_model_load_cost: inside_cost = %u, "
diff --git a/gcc/tree.cc b/gcc/tree.cc
index f9fa7b7..cfead15 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -280,6 +280,7 @@ unsigned const char omp_clause_num_ops[] =
1, /* OMP_CLAUSE__CONDTEMP_ */
1, /* OMP_CLAUSE__SCANTEMP_ */
1, /* OMP_CLAUSE_IF */
+ 1, /* OMP_CLAUSE_SELF */
1, /* OMP_CLAUSE_NUM_THREADS */
1, /* OMP_CLAUSE_SCHEDULE */
0, /* OMP_CLAUSE_NOWAIT */
@@ -371,6 +372,7 @@ const char * const omp_clause_code_name[] =
"_condtemp_",
"_scantemp_",
"if",
+ "self",
"num_threads",
"schedule",
"nowait",
diff --git a/gcc/tree.h b/gcc/tree.h
index 781297c..ac94bd7 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1724,6 +1724,8 @@ class auto_suppress_location_wrappers
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FINAL), 0)
#define OMP_CLAUSE_IF_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_IF), 0)
+#define OMP_CLAUSE_SELF_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SELF), 0)
#define OMP_CLAUSE_NUM_THREADS_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_THREADS),0)
#define OMP_CLAUSE_SCHEDULE_CHUNK_EXPR(NODE) \
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index f507ec5..fcf53ef 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1291,6 +1291,45 @@ irange::irange_single_pair_union (const irange &r)
return true;
}
+// Append R to this range, knowing that R occurs after all of these subranges.
+// Return TRUE as something must have changed.
+
+bool
+irange::union_append (const irange &r)
+{
+ // Check if the first range in R is an immmediate successor to the last
+ // range, ths requiring a merge.
+ signop sign = TYPE_SIGN (m_type);
+ wide_int lb = r.lower_bound ();
+ wide_int ub = upper_bound ();
+ unsigned start = 0;
+ if (widest_int::from (ub, sign) + 1
+ == widest_int::from (lb, sign))
+ {
+ m_base[m_num_ranges * 2 - 1] = r.m_base[1];
+ start = 1;
+ }
+ maybe_resize (m_num_ranges + r.m_num_ranges - start);
+ for ( ; start < r.m_num_ranges; start++)
+ {
+ // Merge the last ranges if it exceeds the maximum size.
+ if (m_num_ranges + 1 > m_max_ranges)
+ {
+ m_base[m_max_ranges * 2 - 1] = r.m_base[r.m_num_ranges * 2 - 1];
+ break;
+ }
+ m_base[m_num_ranges * 2] = r.m_base[start * 2];
+ m_base[m_num_ranges * 2 + 1] = r.m_base[start * 2 + 1];
+ m_num_ranges++;
+ }
+
+ if (!union_bitmask (r))
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
+ return true;
+}
+
// Return TRUE if anything changes.
bool
@@ -1322,6 +1361,11 @@ irange::union_ (const vrange &v)
if (m_num_ranges == 1 && r.m_num_ranges == 1)
return irange_single_pair_union (r);
+ signop sign = TYPE_SIGN (m_type);
+ // Check for an append to the end.
+ if (m_kind == VR_RANGE && wi::gt_p (r.lower_bound (), upper_bound (), sign))
+ return union_append (r);
+
// If this ranges fully contains R, then we need do nothing.
if (irange_contains_p (r))
return union_bitmask (r);
@@ -1340,7 +1384,6 @@ irange::union_ (const vrange &v)
// [Xi,Yi]..[Xn,Yn] U [Xj,Yj]..[Xm,Ym] --> [Xk,Yk]..[Xp,Yp]
auto_vec<wide_int, 20> res (m_num_ranges * 2 + r.m_num_ranges * 2);
unsigned i = 0, j = 0, k = 0;
- signop sign = TYPE_SIGN (m_type);
while (i < m_num_ranges * 2 && j < r.m_num_ranges * 2)
{
diff --git a/gcc/value-range.h b/gcc/value-range.h
index c00b151..e9d81d2 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -339,6 +339,7 @@ private:
bool set_range_from_bitmask ();
bool intersect (const wide_int& lb, const wide_int& ub);
+ bool union_append (const irange &r);
unsigned char m_num_ranges;
bool m_resizable;
unsigned char m_max_ranges;
diff --git a/gcc/var-tracking.cc b/gcc/var-tracking.cc
index d8dafa5..4a81ccb 100644
--- a/gcc/var-tracking.cc
+++ b/gcc/var-tracking.cc
@@ -107,6 +107,8 @@
#include "cfgrtl.h"
#include "cfganal.h"
#include "reload.h"
+#include "ira.h"
+#include "lra.h"
#include "calls.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
@@ -10131,7 +10133,9 @@ vt_initialize (void)
#else
reg = arg_pointer_rtx;
#endif
- elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
+ elim = (ira_use_lra_p
+ ? lra_eliminate_regs (reg, VOIDmode, NULL_RTX)
+ : eliminate_regs (reg, VOIDmode, NULL_RTX));
if (elim != reg)
{
if (GET_CODE (elim) == PLUS)
@@ -10151,7 +10155,9 @@ vt_initialize (void)
reg = arg_pointer_rtx;
fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
#endif
- elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
+ elim = (ira_use_lra_p
+ ? lra_eliminate_regs (reg, VOIDmode, NULL_RTX)
+ : eliminate_regs (reg, VOIDmode, NULL_RTX));
if (elim != reg)
{
if (GET_CODE (elim) == PLUS)
@@ -10183,7 +10189,9 @@ vt_initialize (void)
#else
reg = arg_pointer_rtx;
#endif
- elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
+ elim = (ira_use_lra_p
+ ? lra_eliminate_regs (reg, VOIDmode, NULL_RTX)
+ : eliminate_regs (reg, VOIDmode, NULL_RTX));
if (elim != reg)
{
if (GET_CODE (elim) == PLUS)
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index b0eff17..6ae35ed 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -4300,6 +4300,8 @@ output_constant_pool_contents (struct rtx_constant_pool *pool)
if (desc->mark < 0)
{
#ifdef ASM_OUTPUT_DEF
+ gcc_checking_assert (TARGET_SUPPORTS_ALIASES);
+
const char *name = XSTR (desc->sym, 0);
char label[256];
char buffer[256 + 32];
@@ -6280,6 +6282,10 @@ do_assemble_alias (tree decl, tree target)
IDENTIFIER_POINTER (id),
IDENTIFIER_POINTER (target));
# endif
+ /* If symbol aliases aren't actually supported... */
+ if (!TARGET_SUPPORTS_ALIASES)
+ /* ..., 'ASM_OUTPUT_DEF{,_FROM_DECLS}' better have raised an error. */
+ gcc_checking_assert (seen_error ());
#elif defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
{
const char *name;
@@ -6349,9 +6355,8 @@ assemble_alias (tree decl, tree target)
if (TREE_PUBLIC (decl))
error ("%qs symbol %q+D must have static linkage", "weakref", decl);
}
- else
+ else if (!TARGET_SUPPORTS_ALIASES)
{
-#if !defined (ASM_OUTPUT_DEF)
# if !defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL)
error_at (DECL_SOURCE_LOCATION (decl),
"alias definitions not supported in this configuration");
@@ -6372,7 +6377,7 @@ assemble_alias (tree decl, tree target)
return;
}
# endif
-#endif
+ gcc_unreachable ();
}
TREE_USED (decl) = 1;
@@ -7461,6 +7466,8 @@ default_strip_name_encoding (const char *str)
void
default_asm_output_anchor (rtx symbol)
{
+ gcc_checking_assert (TARGET_SUPPORTS_ALIASES);
+
char buffer[100];
sprintf (buffer, "*. + " HOST_WIDE_INT_PRINT_DEC,
diff --git a/include/ChangeLog b/include/ChangeLog
index f12680d..fea53c8 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2023-10-25 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * gomp-constants.h (GOACC_FLAG_LOCAL_DEVICE): New flag bit value.
+
2023-10-12 Zhang, Jun <jun.zhang@intel.com>
PR target/109812
diff --git a/include/gomp-constants.h b/include/gomp-constants.h
index 8d4e8e8..89b966e 100644
--- a/include/gomp-constants.h
+++ b/include/gomp-constants.h
@@ -304,6 +304,8 @@ enum gomp_map_kind
/* Force host fallback execution. */
#define GOACC_FLAG_HOST_FALLBACK (1 << 0)
+/* Execute on local device (i.e. host multicore CPU). */
+#define GOACC_FLAG_LOCAL_DEVICE (1 << 1)
/* For legacy reasons, in the ABI, the GOACC_FLAGs are encoded as an inverted
bitmask. */
diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog
index 4ea717e..cf10792 100644
--- a/libatomic/ChangeLog
+++ b/libatomic/ChangeLog
@@ -1,3 +1,33 @@
+2023-10-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR testsuite/109951
+ * configure.ac: 'AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET)'.
+ * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * testsuite/Makefile.in: Likewise.
+ * testsuite/lib/libatomic.exp (libatomic_init): If
+ '--with-build-sysroot=[...]' was specified, use it for build-tree
+ testing.
+ * testsuite/libatomic-site-extra.exp.in (GCC_UNDER_TEST): Don't
+ set.
+ (SYSROOT_CFLAGS_FOR_TARGET): Set.
+
+2023-10-23 Jan Beulich <jbeulich@suse.com>
+
+ * Makefile.am (all-multi): Drop commands.
+ * Makefile.in: Update accordingly.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * testsuite/lib/libatomic.exp: Pass correct flags on darwin.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am
index 3bb32f3..c0b8dea 100644
--- a/libatomic/Makefile.am
+++ b/libatomic/Makefile.am
@@ -154,12 +154,11 @@ endif
libatomic_convenience_la_SOURCES = $(libatomic_la_SOURCES)
libatomic_convenience_la_LIBADD = $(libatomic_la_LIBADD)
-# Override the automake generated all-multi rule to guarantee that all-multi
+# Amend the automake generated all-multi rule to guarantee that all-multi
# is not run in parallel with the %_.lo rules which generate $(DEPDIR)/*.Ppo
# makefile fragments to avoid broken *.Ppo getting included into the Makefile
# when it is reloaded during the build of all-multi.
all-multi: $(libatomic_la_LIBADD)
- $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
# target overrides
-include $(tmake_file)
diff --git a/libatomic/Makefile.in b/libatomic/Makefile.in
index 4164199..dc2330b 100644
--- a/libatomic/Makefile.in
+++ b/libatomic/Makefile.in
@@ -328,6 +328,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SIZES = @SIZES@
STRIP = @STRIP@
+SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
VERSION = @VERSION@
XCFLAGS = @XCFLAGS@
XLDFLAGS = @XLDFLAGS@
@@ -897,12 +898,11 @@ vpath % $(strip $(search_path))
%_.lo: Makefile
$(LTCOMPILE) $(M_DEPS) $(M_SIZE) $(M_IFUNC) -c -o $@ $(M_SRC)
-# Override the automake generated all-multi rule to guarantee that all-multi
+# Amend the automake generated all-multi rule to guarantee that all-multi
# is not run in parallel with the %_.lo rules which generate $(DEPDIR)/*.Ppo
# makefile fragments to avoid broken *.Ppo getting included into the Makefile
# when it is reloaded during the build of all-multi.
all-multi: $(libatomic_la_LIBADD)
- $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
# target overrides
-include $(tmake_file)
diff --git a/libatomic/configure b/libatomic/configure
index dc5f4bc..d579bab 100755
--- a/libatomic/configure
+++ b/libatomic/configure
@@ -656,6 +656,7 @@ LIBAT_BUILD_VERSIONED_SHLIB_FALSE
LIBAT_BUILD_VERSIONED_SHLIB_TRUE
OPT_LDFLAGS
SECTION_LDFLAGS
+SYSROOT_CFLAGS_FOR_TARGET
enable_aarch64_lse
libtool_VERSION
ENABLE_DARWIN_AT_RPATH_FALSE
@@ -11455,7 +11456,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11458 "configure"
+#line 11459 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11561,7 +11562,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11564 "configure"
+#line 11565 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11928,6 +11929,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
;;
esac
+
+
# Get target configury.
. ${srcdir}/configure.tgt
if test -n "$UNSUPPORTED"; then
diff --git a/libatomic/configure.ac b/libatomic/configure.ac
index 6919d21..5f2821a 100644
--- a/libatomic/configure.ac
+++ b/libatomic/configure.ac
@@ -172,6 +172,8 @@ case "$target" in
;;
esac
+AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET)
+
# Get target configury.
. ${srcdir}/configure.tgt
if test -n "$UNSUPPORTED"; then
diff --git a/libatomic/testsuite/Makefile.in b/libatomic/testsuite/Makefile.in
index b874ac5..247268f 100644
--- a/libatomic/testsuite/Makefile.in
+++ b/libatomic/testsuite/Makefile.in
@@ -198,6 +198,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SIZES = @SIZES@
STRIP = @STRIP@
+SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
VERSION = @VERSION@
XCFLAGS = @XCFLAGS@
XLDFLAGS = @XLDFLAGS@
diff --git a/libatomic/testsuite/lib/libatomic.exp b/libatomic/testsuite/lib/libatomic.exp
index 10f3847..432a67e 100644
--- a/libatomic/testsuite/lib/libatomic.exp
+++ b/libatomic/testsuite/lib/libatomic.exp
@@ -146,13 +146,22 @@ proc libatomic_init { args } {
set ALWAYS_CFLAGS ""
if { $blddir != "" } {
+ # If '--with-build-sysroot=[...]' was specified, use it for build-tree
+ # testing.
+ global SYSROOT_CFLAGS_FOR_TARGET
+ lappend ALWAYS_CFLAGS "additional_flags=${SYSROOT_CFLAGS_FOR_TARGET}"
+
lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/"
lappend ALWAYS_CFLAGS "additional_flags=-I${blddir}"
- lappend ALWAYS_CFLAGS "ldflags=-L${blddir}/.libs"
+ if [istarget *-*-darwin*] {
+ lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/.libs"
+ } else {
+ lappend ALWAYS_CFLAGS "ldflags=-L${blddir}/.libs"
+ }
}
lappend ALWAYS_CFLAGS "additional_flags=-I${srcdir}/.."
- if [istarget *-*-darwin*] {
+ if [istarget *-*-darwin\[89\]*] {
lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc"
}
diff --git a/libatomic/testsuite/libatomic-site-extra.exp.in b/libatomic/testsuite/libatomic-site-extra.exp.in
index c0d2666..5c81b77 100644
--- a/libatomic/testsuite/libatomic-site-extra.exp.in
+++ b/libatomic/testsuite/libatomic-site-extra.exp.in
@@ -1 +1 @@
-set GCC_UNDER_TEST {@CC@}
+set SYSROOT_CFLAGS_FOR_TARGET {@SYSROOT_CFLAGS_FOR_TARGET@}
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index 11395da..2e2fbb6 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,8 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog
index 6366a5d..ba05a7e 100644
--- a/libcc1/ChangeLog
+++ b/libcc1/ChangeLog
@@ -1,3 +1,7 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+
2023-08-11 Joseph Myers <joseph@codesourcery.com>
* configure: Regenerate.
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 9d2e4f5..d2d3311 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,33 @@
+2023-10-31 David Malcolm <dmalcolm@redhat.com>
+
+ * include/line-map.h
+ (line_map_macro::get_expansion_point_location): New accessor.
+ (line_map_macro::expansion): Rename field to...
+ (line_map_macro::mexpansion): Rename field to...
+ (MACRO_MAP_EXPANSION_POINT_LOCATION): Delete this function.
+ * line-map.cc (linemap_enter_macro): Update for renaming of field.
+ (linemap_macro_map_loc_to_exp_point): Update for removal of
+ MACRO_MAP_EXPANSION_POINT_LOCATION.
+
+2023-10-23 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/36887
+ * directives.cc (do_pragma_poison): Store in the extra hash map the
+ location from which an identifier has been poisoned.
+ * lex.cc (identifier_diagnostics_on_lex): When issuing a diagnostic
+ for the use of a poisoned identifier, also add a note indicating the
+ location from which it was poisoned.
+ * identifiers.cc (alloc_node): Convert to template function.
+ (_cpp_init_hashtable): Handle the new extra hash map.
+ (_cpp_destroy_hashtable): Likewise.
+ * include/cpplib.h (struct cpp_hashnode_extra): New struct.
+ (cpp_create_reader): Update prototype to...
+ * init.cc (cpp_create_reader): ...accept an argument for the extra
+ hash table and pass it to _cpp_init_hashtable.
+ * include/symtab.h (ht_lookup): New overload for convenience.
+ * internal.h (struct cpp_reader): Add EXTRA_HASH_TABLE member.
+ (_cpp_init_hashtable): Adjust prototype.
+
2023-10-08 David Malcolm <dmalcolm@redhat.com>
* include/line-map.h (LINEMAPS_ORDINARY_MAPS): Delete.
diff --git a/libcpp/directives.cc b/libcpp/directives.cc
index ee5419d..c5c938f 100644
--- a/libcpp/directives.cc
+++ b/libcpp/directives.cc
@@ -1737,6 +1737,9 @@ do_pragma_poison (cpp_reader *pfile)
NODE_NAME (hp));
_cpp_free_definition (hp);
hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
+ const auto data = (cpp_hashnode_extra *)
+ ht_lookup (pfile->extra_hash_table, hp->ident, HT_ALLOC);
+ data->poisoned_loc = tok->src_loc;
}
pfile->state.poisoned_ok = 0;
}
diff --git a/libcpp/identifiers.cc b/libcpp/identifiers.cc
index 7eccaa9..10cbbdf 100644
--- a/libcpp/identifiers.cc
+++ b/libcpp/identifiers.cc
@@ -27,24 +27,22 @@ along with this program; see the file COPYING3. If not see
#include "cpplib.h"
#include "internal.h"
-static hashnode alloc_node (cpp_hash_table *);
-
/* Return an identifier node for hashtable.c. Used by cpplib except
when integrated with the C front ends. */
+template<typename Node>
static hashnode
alloc_node (cpp_hash_table *table)
{
- cpp_hashnode *node;
-
- node = XOBNEW (&table->pfile->hash_ob, cpp_hashnode);
- memset (node, 0, sizeof (cpp_hashnode));
+ const auto node = XOBNEW (&table->pfile->hash_ob, Node);
+ memset (node, 0, sizeof (Node));
return HT_NODE (node);
}
/* Set up the identifier hash table. Use TABLE if non-null, otherwise
create our own. */
void
-_cpp_init_hashtable (cpp_reader *pfile, cpp_hash_table *table)
+_cpp_init_hashtable (cpp_reader *pfile, cpp_hash_table *table,
+ cpp_hash_table *extra_table)
{
struct spec_nodes *s;
@@ -52,13 +50,23 @@ _cpp_init_hashtable (cpp_reader *pfile, cpp_hash_table *table)
{
pfile->our_hashtable = 1;
table = ht_create (13); /* 8K (=2^13) entries. */
- table->alloc_node = alloc_node;
+ table->alloc_node = alloc_node<cpp_hashnode>;
+ }
- obstack_specify_allocation (&pfile->hash_ob, 0, 0, xmalloc, free);
+ if (extra_table == NULL)
+ {
+ pfile->our_extra_hashtable = true;
+ extra_table = ht_create (6); /* 64 entries. */
+ extra_table->alloc_node = alloc_node<cpp_hashnode_extra>;
}
+ if (pfile->our_hashtable || pfile->our_extra_hashtable)
+ obstack_specify_allocation (&pfile->hash_ob, 0, 0, xmalloc, free);
+
table->pfile = pfile;
+ extra_table->pfile = pfile;
pfile->hash_table = table;
+ pfile->extra_hash_table = extra_table;
/* Now we can initialize things that use the hash table. */
_cpp_init_directives (pfile);
@@ -80,10 +88,11 @@ void
_cpp_destroy_hashtable (cpp_reader *pfile)
{
if (pfile->our_hashtable)
- {
- ht_destroy (pfile->hash_table);
- obstack_free (&pfile->hash_ob, 0);
- }
+ ht_destroy (pfile->hash_table);
+ if (pfile->our_extra_hashtable)
+ ht_destroy (pfile->extra_hash_table);
+ if (pfile->our_hashtable || pfile->our_extra_hashtable)
+ obstack_free (&pfile->hash_ob, 0);
}
/* Returns the hash entry for the STR of length LEN, creating one
@@ -110,7 +119,12 @@ cpp_defined (cpp_reader *pfile, const unsigned char *str, int len)
/* We don't need a proxy since the hash table's identifier comes first
in cpp_hashnode. However, in case this is ever changed, we have a
static assertion for it. */
-extern char proxy_assertion_broken[offsetof (struct cpp_hashnode, ident) == 0 ? 1 : -1];
+static_assert (offsetof (cpp_hashnode, ident) == 0,
+ "struct cpp_hashnode must have a struct ht_identifier as"
+ " its first member");
+static_assert (offsetof (cpp_hashnode_extra, ident) == 0,
+ "struct cpp_hashnode_extra must have a struct ht_identifier as"
+ " its first member");
/* For all nodes in the hashtable, callback CB with parameters PFILE,
the node, and V. */
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index a0351d9..7afede4 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -1009,6 +1009,14 @@ struct GTY(()) cpp_hashnode {
union _cpp_hashnode_value GTY ((desc ("%1.type"))) value;
};
+/* Extra information we may need to store per identifier, which is needed rarely
+ enough that it's not worth adding directly into the main identifier hash. */
+struct GTY(()) cpp_hashnode_extra
+{
+ struct ht_identifier ident;
+ location_t poisoned_loc;
+};
+
/* A class for iterating through the source locations within a
string token (before escapes are interpreted, and before
concatenation). */
@@ -1055,12 +1063,15 @@ class cpp_substring_ranges
/* Call this first to get a handle to pass to other functions.
- If you want cpplib to manage its own hashtable, pass in a NULL
- pointer. Otherwise you should pass in an initialized hash table
- that cpplib will share; this technique is used by the C front
- ends. */
+ The first hash table argument is for associating a struct cpp_hashnode
+ with each identifier. The second hash table argument is for associating
+ a struct cpp_hashnode_extra with each identifier that needs one. For
+ either, pass in a NULL pointer if you want cpplib to create and manage
+ the hash table itself, or else pass a suitably initialized hash table to
+ be managed external to libcpp, as is done by the C-family frontends. */
extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *,
- class line_maps *);
+ class line_maps *,
+ struct ht * = nullptr);
/* Reset the cpp_reader's line_map. This is only used after reading a
PCH file. */
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index cb934e6..635d6d3 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -461,6 +461,15 @@ struct cpp_hashnode;
The offset from START_LOCATION is used to index into
MACRO_LOCATIONS; this holds the original location of the token. */
struct GTY((tag ("2"))) line_map_macro : public line_map {
+
+ /* Get the location of the expansion point of this macro map. */
+
+ location_t
+ get_expansion_point_location () const
+ {
+ return m_expansion;
+ }
+
/* Base is 4 bytes. */
/* The number of tokens inside the replacement-list of MACRO. */
@@ -535,7 +544,7 @@ struct GTY((tag ("2"))) line_map_macro : public line_map {
by the map that was current right before the current one. It
could have been either a macro or an ordinary map, depending on
if we are in a nested expansion context not. */
- location_t expansion;
+ location_t m_expansion;
/* Size is 20 or 32 (4 bytes padding on 64-bit). */
};
@@ -705,14 +714,6 @@ MACRO_MAP_LOCATIONS (const line_map_macro *macro_map)
return macro_map->macro_locations;
}
-/* Get the location of the expansion point of the macro map MAP. */
-
-inline location_t
-MACRO_MAP_EXPANSION_POINT_LOCATION (const line_map_macro *macro_map)
-{
- return macro_map->expansion;
-}
-
/* The abstraction of a set of location maps. There can be several
types of location maps. This abstraction contains the attributes
that are independent from the type of the map.
diff --git a/libcpp/include/symtab.h b/libcpp/include/symtab.h
index 0c713f2..4a2370e 100644
--- a/libcpp/include/symtab.h
+++ b/libcpp/include/symtab.h
@@ -81,6 +81,12 @@ extern hashnode ht_lookup (cpp_hash_table *, const unsigned char *,
extern hashnode ht_lookup_with_hash (cpp_hash_table *, const unsigned char *,
size_t, unsigned int,
enum ht_lookup_option);
+inline hashnode ht_lookup (cpp_hash_table *ht, const ht_identifier &id,
+ ht_lookup_option opt)
+{
+ return ht_lookup_with_hash (ht, id.str, id.len, id.hash_value, opt);
+}
+
#define HT_HASHSTEP(r, c) ((r) * 67 + ((c) - 113));
#define HT_HASHFINISH(r, len) ((r) + (len))
diff --git a/libcpp/init.cc b/libcpp/init.cc
index b97d7a7..18a7f04 100644
--- a/libcpp/init.cc
+++ b/libcpp/init.cc
@@ -191,7 +191,7 @@ init_library (void)
/* Initialize a cpp_reader structure. */
cpp_reader *
cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
- class line_maps *line_table)
+ class line_maps *line_table, cpp_hash_table *extra_table)
{
cpp_reader *pfile;
@@ -307,7 +307,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
_cpp_init_files (pfile);
- _cpp_init_hashtable (pfile, table);
+ _cpp_init_hashtable (pfile, table, extra_table);
return pfile;
}
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 33ed0a2..6a10e9d 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -555,6 +555,9 @@ struct cpp_reader
/* Identifier hash table. */
struct ht *hash_table;
+ /* Identifier ancillary data hash table. */
+ struct ht *extra_hash_table;
+
/* Expression parser stack. */
struct op *op_stack, *op_limit;
@@ -566,7 +569,7 @@ struct cpp_reader
struct spec_nodes spec_nodes;
/* Whether cpplib owns the hashtable. */
- bool our_hashtable;
+ bool our_hashtable, our_extra_hashtable;
/* Traditional preprocessing output buffer (a logical line). */
struct
@@ -704,7 +707,8 @@ extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *,
extern void _cpp_backup_tokens_direct (cpp_reader *, unsigned int);
/* In identifiers.cc */
-extern void _cpp_init_hashtable (cpp_reader *, cpp_hash_table *);
+extern void
+_cpp_init_hashtable (cpp_reader *, cpp_hash_table *, cpp_hash_table *);
extern void _cpp_destroy_hashtable (cpp_reader *);
/* In files.cc */
diff --git a/libcpp/lex.cc b/libcpp/lex.cc
index ce8ff61..5ca438a 100644
--- a/libcpp/lex.cc
+++ b/libcpp/lex.cc
@@ -2168,8 +2168,14 @@ identifier_diagnostics_on_lex (cpp_reader *pfile, cpp_hashnode *node)
/* It is allowed to poison the same identifier twice. */
if ((node->flags & NODE_POISONED) && !pfile->state.poisoned_ok)
- cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"",
- NODE_NAME (node));
+ {
+ cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"",
+ NODE_NAME (node));
+ const auto data = (cpp_hashnode_extra *)
+ ht_lookup (pfile->extra_hash_table, node->ident, HT_NO_INSERT);
+ if (data && data->poisoned_loc)
+ cpp_error_at (pfile, CPP_DL_NOTE, data->poisoned_loc, "poisoned here");
+ }
/* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the
replacement list of a variadic macro. */
diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc
index cd17353..cc9e14a 100644
--- a/libcpp/line-map.cc
+++ b/libcpp/line-map.cc
@@ -782,7 +782,7 @@ linemap_enter_macro (class line_maps *set, struct cpp_hashnode *macro_node,
map->macro_locations
= (location_t*) set->m_reallocator (nullptr,
2 * num_tokens * sizeof (location_t));
- map->expansion = expansion;
+ map->m_expansion = expansion;
memset (MACRO_MAP_LOCATIONS (map), 0,
2 * num_tokens * sizeof (location_t));
@@ -1225,7 +1225,7 @@ linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
linemap_assert ((location - MAP_START_LOCATION (map))
< MACRO_MAP_NUM_MACRO_TOKENS (map));
- return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
+ return map->get_expansion_point_location ();
}
/* LOCATION is the source location of a token that belongs to a macro
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index e421b03..21111ca 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,28 @@
+2023-10-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR testsuite/109951
+ * configure.ac: 'AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET)'.
+ <local.exp>: Don't set 'CC_FOR_TARGET', 'CXX_FOR_TARGET', instead
+ set 'SYSROOT_CFLAGS_FOR_TARGET'.
+ * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * include/Makefile.in: Likewise.
+ * man/Makefile.in: Likewise.
+ * testsuite/Makefile.in: Likewise.
+ * testsuite/lib/libffi.exp (libffi_target_compile): If
+ '--with-build-sysroot=[...]' was specified, use it for build-tree
+ testing.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * testsuite/lib/libffi.exp: Likewise.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
2023-08-23 Lulu Cheng <chenglulu@loongson.cn>
PR libffi/108682
diff --git a/libffi/Makefile.in b/libffi/Makefile.in
index 71469f7..e8ab5f2 100644
--- a/libffi/Makefile.in
+++ b/libffi/Makefile.in
@@ -383,6 +383,7 @@ SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
TARGET_OBJ = @TARGET_OBJ@
diff --git a/libffi/configure b/libffi/configure
index 2905455..f82a45b 100755
--- a/libffi/configure
+++ b/libffi/configure
@@ -666,6 +666,7 @@ TESTSUBDIR_TRUE
MAINT
MAINTAINER_MODE_FALSE
MAINTAINER_MODE_TRUE
+SYSROOT_CFLAGS_FOR_TARGET
READELF
ENABLE_DARWIN_AT_RPATH_FALSE
ENABLE_DARWIN_AT_RPATH_TRUE
@@ -11687,7 +11688,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11690 "configure"
+#line 11691 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11793,7 +11794,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11796 "configure"
+#line 11797 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15249,9 +15250,10 @@ _ACEOF
+
+
cat > local.exp <<EOF
-set CC_FOR_TARGET "$CC"
-set CXX_FOR_TARGET "$CXX"
+set SYSROOT_CFLAGS_FOR_TARGET "$SYSROOT_CFLAGS_FOR_TARGET"
set compiler_vendor "$ax_cv_c_compiler_vendor"
EOF
diff --git a/libffi/configure.ac b/libffi/configure.ac
index 716f20a..c89b246 100644
--- a/libffi/configure.ac
+++ b/libffi/configure.ac
@@ -62,9 +62,10 @@ AC_CHECK_TOOL(READELF, readelf)
# Test for 64-bit build.
AC_CHECK_SIZEOF([size_t])
+AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET)
+
cat > local.exp <<EOF
-set CC_FOR_TARGET "$CC"
-set CXX_FOR_TARGET "$CXX"
+set SYSROOT_CFLAGS_FOR_TARGET "$SYSROOT_CFLAGS_FOR_TARGET"
set compiler_vendor "$ax_cv_c_compiler_vendor"
EOF
diff --git a/libffi/include/Makefile.in b/libffi/include/Makefile.in
index 879cb72..9759f0d 100644
--- a/libffi/include/Makefile.in
+++ b/libffi/include/Makefile.in
@@ -255,6 +255,7 @@ SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
TARGET_OBJ = @TARGET_OBJ@
diff --git a/libffi/man/Makefile.in b/libffi/man/Makefile.in
index 9d4f966..18de1e8 100644
--- a/libffi/man/Makefile.in
+++ b/libffi/man/Makefile.in
@@ -237,6 +237,7 @@ SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
TARGET_OBJ = @TARGET_OBJ@
diff --git a/libffi/testsuite/Makefile.in b/libffi/testsuite/Makefile.in
index a19b523..27d48a7 100644
--- a/libffi/testsuite/Makefile.in
+++ b/libffi/testsuite/Makefile.in
@@ -210,6 +210,7 @@ SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
TARGET_OBJ = @TARGET_OBJ@
diff --git a/libffi/testsuite/lib/libffi.exp b/libffi/testsuite/lib/libffi.exp
index 15d3d5e..c1ae32d 100644
--- a/libffi/testsuite/lib/libffi.exp
+++ b/libffi/testsuite/lib/libffi.exp
@@ -337,8 +337,13 @@ proc libffi-init { args } {
verbose "libffi_dir $libffi_dir"
if { $libffi_dir != "" } {
set libffi_dir [file dirname ${libffi_dir}]
- set libffi_link_flags "-L${libffi_dir}/.libs"
- lappend libffi_link_flags "-L${blddircxx}/src/.libs"
+ if [istarget *-*-darwin*] {
+ set libffi_link_flags "-B${libffi_dir}/.libs"
+ lappend libffi_link_flags "-B${blddircxx}/src/.libs"
+ } else {
+ set libffi_link_flags "-L${libffi_dir}/.libs"
+ lappend libffi_link_flags "-L${blddircxx}/src/.libs"
+ }
}
set_ld_library_path_env_vars
@@ -369,6 +374,13 @@ proc libffi_target_compile { source dest type options } {
lappend options "ldflags=$wrap_flags"
}
+ if { $blddirffi != "" } {
+ # If '--with-build-sysroot=[...]' was specified, use it for build-tree
+ # testing.
+ global SYSROOT_CFLAGS_FOR_TARGET
+ lappend options "additional_flags=${SYSROOT_CFLAGS_FOR_TARGET}"
+ }
+
# TOOL_OPTIONS must come first, so that it doesn't override testcase
# specific options.
if [info exists TOOL_OPTIONS] {
@@ -382,7 +394,7 @@ proc libffi_target_compile { source dest type options } {
# Darwin needs a stack execution allowed flag.
if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"]
- || [istarget "*-*-darwin2*"] } {
+ || [istarget "x86_64-*-darwin2*"] } {
lappend options "additional_flags=-Wl,-allow_stack_execute"
lappend options "additional_flags=-Wl,-search_paths_first"
}
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 678364b..c346d58 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,39 @@
+2023-10-31 Alexandre Oliva <oliva@adacore.com>
+
+ * hardcfr.c: Adjust copyright year.
+
+2023-10-24 Sergei Trofimovich <siarheit@google.com>
+
+ * config/aarch64/heap-trampoline.c: Disable when libc is not
+ present.
+ * config/i386/heap-trampoline.c: Ditto.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/t-slibgcc-darwin: Generate libgcc_s
+ with an @rpath name.
+ * config.host: Handle Darwin rpaths.
+ * config/t-darwin-rpath: New file.
+
+2023-10-22 Andrew Burgess <andrew.burgess@embecosm.com>
+ Maxim Blinov <maxim.blinov@embecosm.com>
+ Iain Sandoe <iain@sandoe.co.uk>
+ Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * libgcc2.h (__builtin_nested_func_ptr_created): Declare.
+ (__builtin_nested_func_ptr_deleted): Declare.
+ * libgcc-std.ver.in: Add the new symbols.
+ * config/aarch64/heap-trampoline.c: Implement heap-based
+ trampolines for aarch64.
+ * config/aarch64/t-heap-trampoline: Add rule to build
+ config/aarch64/heap-trampoline.c
+ * config/i386/heap-trampoline.c: Implement heap-based
+ trampolines for x86_64.
+ * config/i386/t-heap-trampoline: Add rule to build
+ config/i386/heap-trampoline.cc
+ * config.host: Handle --enable-heap-trampolines on
+ x86_64-*-linux*, aarch64-*-linux*, x86_64-*-darwin*.
+
2023-10-20 Andrew Stubbs <ams@codesourcery.com>
* config/gcn/amdgcn_veclib.h (CDNA3_PLUS): Set false for __RDNA2__.
diff --git a/libgcc/config/aarch64/heap-trampoline.c b/libgcc/config/aarch64/heap-trampoline.c
index c8b8368..f222339 100644
--- a/libgcc/config/aarch64/heap-trampoline.c
+++ b/libgcc/config/aarch64/heap-trampoline.c
@@ -1,5 +1,8 @@
/* Copyright The GNU Toolchain Authors. */
+/* libc is required to allocate trampolines. */
+#ifndef inhibit_libc
+
#include <unistd.h>
#include <sys/mman.h>
#include <stdint.h>
@@ -170,3 +173,5 @@ __builtin_nested_func_ptr_deleted (void)
tramp_ctrl_curr = prev;
}
}
+
+#endif /* !inhibit_libc */
diff --git a/libgcc/config/i386/heap-trampoline.c b/libgcc/config/i386/heap-trampoline.c
index 96e13bf..4b9f436 100644
--- a/libgcc/config/i386/heap-trampoline.c
+++ b/libgcc/config/i386/heap-trampoline.c
@@ -1,5 +1,8 @@
/* Copyright The GNU Toolchain Authors. */
+/* libc is required to allocate trampolines. */
+#ifndef inhibit_libc
+
#include <unistd.h>
#include <sys/mman.h>
#include <stdint.h>
@@ -170,3 +173,5 @@ __builtin_nested_func_ptr_deleted (void)
tramp_ctrl_curr = prev;
}
}
+
+#endif /* !inhibit_libc */
diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 7496095..25ff067 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -1,5 +1,5 @@
/* Control flow redundancy hardening
- Copyright (C) 2022 Free Software Foundation, Inc.
+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <oliva@adacore.com>
This file is part of GCC.
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 02875cf..87c8eaf 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,10 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths
+
2023-09-28 Tobias Burnus <tobias@codesourcery.com>
* io/write.c (xtoa_big): Change a 'GCC diagnostic ignored
diff --git a/libgm2/ChangeLog b/libgm2/ChangeLog
index 5a3e9ed..7fda599 100644
--- a/libgm2/ChangeLog
+++ b/libgm2/ChangeLog
@@ -1,3 +1,52 @@
+2023-10-27 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/112110
+ * libm2iso/wrapclock.cc (timezone): Return 0 if unable
+ to get the timezone from the tm struct.
+
+2023-10-27 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/111530
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.h.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac (AC_CHECK_HEADERS): Include getopt.h.
+ (GM2_CHECK_LIB): getopt_long check.
+ (GM2_CHECK_LIB): getopt_long_only check.
+ * libm2cor/Makefile.in: Regenerate.
+ * libm2iso/Makefile.in: Regenerate.
+ * libm2log/Makefile.in: Regenerate.
+ * libm2min/Makefile.in: Regenerate.
+ * libm2pim/Makefile.in: Regenerate.
+ * libm2pim/cgetopt.cc: Re-write using conditional on configure
+ and long function code from libiberty/getopt.c.
+
+2023-10-25 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/111955
+ * libm2pim/wrapc.cc (isnan): Export new function.
+ (isnanf): Export new function.
+ (isnanl): Export new function.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+ * libm2cor/Makefile.am: Handle Darwin rpaths.
+ * libm2cor/Makefile.in: Regenerate.
+ * libm2iso/Makefile.am: Handle Darwin rpaths.
+ * libm2iso/Makefile.in: Regenerate.
+ * libm2log/Makefile.am: Handle Darwin rpaths.
+ * libm2log/Makefile.in: Regenerate.
+ * libm2min/Makefile.am: Handle Darwin rpaths.
+ * libm2min/Makefile.in: Regenerate.
+ * libm2pim/Makefile.am: Handle Darwin rpaths.
+ * libm2pim/Makefile.in: Regenerate.
+
2023-09-29 Gaius Mulley <gaiusmod2@gmail.com>
* libm2iso/wrapclock.cc (longint_t): New declaration.
diff --git a/libgm2/Makefile.in b/libgm2/Makefile.in
index 47fbf69..add0dd2 100644
--- a/libgm2/Makefile.in
+++ b/libgm2/Makefile.in
@@ -90,15 +90,15 @@ host_triplet = @host@
target_triplet = @target@
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/no-executables.m4 \
- $(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
- $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
- $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
diff --git a/libgm2/aclocal.m4 b/libgm2/aclocal.m4
index 832065f..c352303 100644
--- a/libgm2/aclocal.m4
+++ b/libgm2/aclocal.m4
@@ -1187,14 +1187,14 @@ AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
+m4_include([../libtool.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
m4_include([../config/acx.m4])
m4_include([../config/depstand.m4])
m4_include([../config/lead-dot.m4])
m4_include([../config/multi.m4])
m4_include([../config/no-executables.m4])
m4_include([../config/override.m4])
-m4_include([../libtool.m4])
-m4_include([../ltoptions.m4])
-m4_include([../ltsugar.m4])
-m4_include([../ltversion.m4])
-m4_include([../lt~obsolete.m4])
diff --git a/libgm2/config.h.in b/libgm2/config.h.in
index f91f5a4..a9d932f 100644
--- a/libgm2/config.h.in
+++ b/libgm2/config.h.in
@@ -63,6 +63,15 @@
/* function getgid exists */
#undef HAVE_GETGID
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* function getopt_long exists */
+#undef HAVE_GETOPT_LONG
+
+/* function getopt_long_only exists */
+#undef HAVE_GETOPT_LONG_ONLY
+
/* function getpid exists */
#undef HAVE_GETPID
diff --git a/libgm2/configure b/libgm2/configure
index d55a7f4..a0ad71e 100755
--- a/libgm2/configure
+++ b/libgm2/configure
@@ -4950,8 +4950,8 @@ fi
-for ac_header in limits.h stddef.h string.h strings.h stdlib.h \
- time.h \
+for ac_header in getopt.h limits.h stddef.h string.h strings.h \
+ stdlib.h time.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
sys/socket.h \
@@ -4973,7 +4973,6 @@ done
-
case ${build_alias} in
"") build_noncanonical=${build} ;;
*) build_noncanonical=${build_alias} ;;
@@ -12789,7 +12788,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12792 "configure"
+#line 12791 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12895,7 +12894,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12898 "configure"
+#line 12897 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -18061,6 +18060,144 @@ $as_echo "#define HAVE_GETGID 1" >>confdefs.h
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for getopt_long" >&5
+$as_echo_n "checking m2 front end checking c library for getopt_long... " >&6; }
+ if test x$gcc_no_link != xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getopt_long in -lc" >&5
+$as_echo_n "checking for getopt_long in -lc... " >&6; }
+if ${ac_cv_lib_c_getopt_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc $LIBS"
+if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getopt_long ();
+int
+main ()
+{
+return getopt_long ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c_getopt_long=yes
+else
+ ac_cv_lib_c_getopt_long=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_getopt_long" >&5
+$as_echo "$ac_cv_lib_c_getopt_long" >&6; }
+if test "x$ac_cv_lib_c_getopt_long" = xyes; then :
+
+$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h
+
+else
+
+ $as_echo "#undef HAVE_GETOPT_LONG" >>confdefs.h
+
+fi
+
+ else
+ if test "x$ac_cv_lib_c_getopt_long" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h
+
+ elif test "x$ac_cv_func_getopt_long" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h
+
+ else
+
+ $as_echo "#undef HAVE_GETOPT_LONG" >>confdefs.h
+
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for getopt_long_only" >&5
+$as_echo_n "checking m2 front end checking c library for getopt_long_only... " >&6; }
+ if test x$gcc_no_link != xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getopt_long_only in -lc" >&5
+$as_echo_n "checking for getopt_long_only in -lc... " >&6; }
+if ${ac_cv_lib_c_getopt_long_only+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc $LIBS"
+if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getopt_long_only ();
+int
+main ()
+{
+return getopt_long_only ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c_getopt_long_only=yes
+else
+ ac_cv_lib_c_getopt_long_only=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_getopt_long_only" >&5
+$as_echo "$ac_cv_lib_c_getopt_long_only" >&6; }
+if test "x$ac_cv_lib_c_getopt_long_only" = xyes; then :
+
+$as_echo "#define HAVE_GETOPT_LONG_ONLY 1" >>confdefs.h
+
+else
+
+ $as_echo "#undef HAVE_GETOPT_LONG_ONLY" >>confdefs.h
+
+fi
+
+ else
+ if test "x$ac_cv_lib_c_getopt_long_only" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG_ONLY 1" >>confdefs.h
+
+ elif test "x$ac_cv_func_getopt_long_only" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG_ONLY 1" >>confdefs.h
+
+ else
+
+ $as_echo "#undef HAVE_GETOPT_LONG_ONLY" >>confdefs.h
+
+ fi
+ fi
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for getpid" >&5
$as_echo_n "checking m2 front end checking c library for getpid... " >&6; }
if test x$gcc_no_link != xyes; then
diff --git a/libgm2/configure.ac b/libgm2/configure.ac
index 5701b95..11f4b50 100644
--- a/libgm2/configure.ac
+++ b/libgm2/configure.ac
@@ -92,8 +92,8 @@ AC_HEADER_SYS_WAIT
AC_CHECK_HEADER([math.h],
[AC_DEFINE([HAVE_MATH_H], [1], [have math.h])])
-AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h \
- time.h \
+AC_CHECK_HEADERS(getopt.h limits.h stddef.h string.h strings.h \
+ stdlib.h time.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
sys/socket.h \
@@ -102,7 +102,6 @@ AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h \
pthread.h stdarg.h stdio.h sys/types.h termios.h \
netinet/in.h netdb.h sys/uio.h sys/stat.h wchar.h)
-
AC_CANONICAL_HOST
ACX_NONCANONICAL_HOST
ACX_NONCANONICAL_TARGET
@@ -296,6 +295,8 @@ GM2_CHECK_LIB([c],[fcntl],[FCNTL])
GM2_CHECK_LIB([c],[fstat],[FSTAT])
GM2_CHECK_LIB([c],[getdents],[GETDENTS])
GM2_CHECK_LIB([c],[getgid],[GETGID])
+GM2_CHECK_LIB([c],[getopt_long],[GETOPT_LONG])
+GM2_CHECK_LIB([c],[getopt_long_only],[GETOPT_LONG_ONLY])
GM2_CHECK_LIB([c],[getpid],[GETPID])
GM2_CHECK_LIB([c],[gettimeofday],[GETTIMEOFD])
GM2_CHECK_LIB([c],[getuid],[GETUID])
diff --git a/libgm2/libm2cor/Makefile.in b/libgm2/libm2cor/Makefile.in
index 449a26b..a8a311e 100644
--- a/libgm2/libm2cor/Makefile.in
+++ b/libgm2/libm2cor/Makefile.in
@@ -108,15 +108,15 @@ target_triplet = @target@
@BUILD_CORLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
subdir = libm2cor
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/no-executables.m4 \
- $(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
- $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
- $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am
diff --git a/libgm2/libm2iso/Makefile.in b/libgm2/libm2iso/Makefile.in
index 6700664..21632b4 100644
--- a/libgm2/libm2iso/Makefile.in
+++ b/libgm2/libm2iso/Makefile.in
@@ -108,15 +108,15 @@ target_triplet = @target@
@BUILD_ISOLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
subdir = libm2iso
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/no-executables.m4 \
- $(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
- $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
- $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am
diff --git a/libgm2/libm2iso/wrapclock.cc b/libgm2/libm2iso/wrapclock.cc
index a4d62b7..31ddeb5 100644
--- a/libgm2/libm2iso/wrapclock.cc
+++ b/libgm2/libm2iso/wrapclock.cc
@@ -235,16 +235,9 @@ EXPORT(timezone) (void)
localtime_r (&time, &result);
return result.tm_gmtoff;
}
- else
-#endif
#endif
- {
-#if defined(HAVE_TIMEZONE)
- return timezone;
-#else
- return 0;
#endif
- }
+ return 0;
}
/* istimezone returns 1 if timezone in wrapclock.cc can resolve the
diff --git a/libgm2/libm2log/Makefile.in b/libgm2/libm2log/Makefile.in
index 9b9b416..e1e26f7 100644
--- a/libgm2/libm2log/Makefile.in
+++ b/libgm2/libm2log/Makefile.in
@@ -108,15 +108,15 @@ target_triplet = @target@
@BUILD_LOGLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
subdir = libm2log
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/no-executables.m4 \
- $(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
- $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
- $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am
diff --git a/libgm2/libm2min/Makefile.in b/libgm2/libm2min/Makefile.in
index 4a909c7..9d348b0 100644
--- a/libgm2/libm2min/Makefile.in
+++ b/libgm2/libm2min/Makefile.in
@@ -108,15 +108,15 @@ target_triplet = @target@
@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
subdir = libm2min
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/no-executables.m4 \
- $(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
- $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
- $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am
diff --git a/libgm2/libm2pim/Makefile.in b/libgm2/libm2pim/Makefile.in
index e64722e..d0256f8 100644
--- a/libgm2/libm2pim/Makefile.in
+++ b/libgm2/libm2pim/Makefile.in
@@ -108,15 +108,15 @@ target_triplet = @target@
@BUILD_PIMLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
subdir = libm2pim
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/no-executables.m4 \
- $(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
- $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
- $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am
diff --git a/libgm2/libm2pim/cgetopt.cc b/libgm2/libm2pim/cgetopt.cc
index a3954db..2e97648 100644
--- a/libgm2/libm2pim/cgetopt.cc
+++ b/libgm2/libm2pim/cgetopt.cc
@@ -1,6 +1,6 @@
/* cgetopt.cc provide access to the C getopt library.
-Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Copyright (C) 2009-2023 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
This file is part of GNU Modula-2.
@@ -28,63 +28,34 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <stdlib.h>
#include <getopt.h>
#include <m2rts.h>
+#include <stdio.h>
+#include <config.h>
#define EXPORT(FUNC) m2pim ## _cgetopt_ ## FUNC
#define M2EXPORT(FUNC) m2pim ## _M2_cgetopt_ ## FUNC
#define M2LIBNAME "m2pim"
+#if !defined(_)
+#define _(X) X
+#endif
+
extern "C" {char *EXPORT(optarg);}
extern "C" {int EXPORT(optind);}
extern "C" {int EXPORT(opterr);}
extern "C" {int EXPORT(optopt);}
-extern "C" char
-EXPORT(getopt) (int argc, char *argv[], char *optstring)
-{
- char r = getopt (argc, argv, optstring);
-
- EXPORT(optarg) = optarg;
- EXPORT(optind) = optind;
- EXPORT(opterr) = opterr;
- EXPORT(optopt) = optopt;
-
- if (r == (char)-1)
- return (char)0;
- return r;
-}
-
-extern "C" int
-EXPORT(getopt_long) (int argc, char *argv[], char *optstring,
- const struct option *longopts, int *longindex)
-{
- int r = getopt_long (argc, argv, optstring, longopts, longindex);
-
- EXPORT(optarg) = optarg;
- EXPORT(optind) = optind;
- EXPORT(opterr) = opterr;
- EXPORT(optopt) = optopt;
-
- return r;
-}
-
-extern "C" int
-EXPORT(getopt_long_only) (int argc, char *argv[], char *optstring,
- const struct option *longopts, int *longindex)
-{
- int r = getopt_long_only (argc, argv, optstring, longopts, longindex);
-
- EXPORT(optarg) = optarg;
- EXPORT(optind) = optind;
- EXPORT(opterr) = opterr;
- EXPORT(optopt) = optopt;
+int
+libiberty_getopt_long_only (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index);
+int
+libiberty_getopt_long (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index);
- return r;
-}
typedef struct cgetopt_Options_s
{
struct option *cinfo;
- unsigned int high;
+ unsigned int empty_slot;
} cgetopt_Options;
/* InitOptions a constructor for Options. */
@@ -94,7 +65,7 @@ EXPORT(InitOptions) (void)
{
cgetopt_Options *o = (cgetopt_Options *)malloc (sizeof (cgetopt_Options));
o->cinfo = (struct option *)malloc (sizeof (struct option));
- o->high = 0;
+ o->empty_slot = 1;
return o;
}
@@ -113,16 +84,21 @@ EXPORT(KillOptions) (cgetopt_Options *o)
extern "C" void
EXPORT(SetOption) (cgetopt_Options *o, unsigned int index, char *name,
- bool has_arg, int *flag, int val)
+ int has_arg, int *flag, int val)
{
- if (index > o->high)
+ if (index >= o->empty_slot)
{
o->cinfo
- = (struct option *)malloc (sizeof (struct option) * (index + 1));
- o->high = index + 1;
+ = (struct option *)realloc (o->cinfo,
+ sizeof (struct option) * (index + 1));
+ o->empty_slot = index + 1;
}
o->cinfo[index].name = name;
o->cinfo[index].has_arg = has_arg;
+ /* Set flag to NULL if name is NULL, as flag comes from a VAR parameter
+ (which cannot be NIL in modula-2). */
+ if (name == NULL)
+ flag = NULL;
o->cinfo[index].flag = flag;
o->cinfo[index].val = val;
}
@@ -136,6 +112,962 @@ EXPORT(GetLongOptionArray) (cgetopt_Options *o)
return o->cinfo;
}
+
+/* The following code has been taken from libiberty/getopt.c and is
+ conditionally compiled if long option support is absent on the target.
+ It has been changed just to deal with the long option functions as we
+ assume all targets have getopt. This code also keeps all data and code
+ static as the interface code only comes though functions defined in
+ cgetopt.def. */
+
+#if (! defined(HAVE_GETOPT_LONG_ONLY)) || (! defined(HAVE_GETOPT_LONG))
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+static char *cgetopt_optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+static int cgetopt_optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+static int __getopt_initialized = 0;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+static int cgetopt_opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+static int cgetopt_optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#if HAVE_STDLIB_H && HAVE_DECL_GETENV
+# include <stdlib.h>
+#elif !defined(getenv)
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+extern char *getenv (const char *);
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+#endif
+
+static char *
+my_index (const char *str, int chr)
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+ is valid for the getopt call we must make sure that the ARGV passed
+ to getopt is that one passed to the process. */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+ /* XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+ original_argc = argc;
+ original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (char **argv)
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = cgetopt_optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#ifdef _LIBC
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = (char *) malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (cgetopt_optind - last_nonopt);
+ last_nonopt = cgetopt_optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (int argc, char *const *argv, const char *optstring)
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = cgetopt_optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#ifdef _LIBC
+ if (posixly_correct == NULL
+ && argc == original_argc && argv == original_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+static
+int
+_getopt_internal (int argc, char *const *argv, const char *optstring,
+ const struct option *longopts,
+ int *longind, int long_only)
+{
+ cgetopt_optarg = NULL;
+
+ if (cgetopt_optind == 0 || !__getopt_initialized)
+ {
+ if (cgetopt_optind == 0)
+ cgetopt_optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#ifdef _LIBC
+# define NONOPTION_P (argv[cgetopt_optind][0] != '-' || argv[cgetopt_optind][1] == '\0' \
+ || (cgetopt_optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[cgetopt_optind] == '1'))
+#else
+# define NONOPTION_P (argv[cgetopt_optind][0] != '-' || argv[cgetopt_optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > cgetopt_optind)
+ last_nonopt = cgetopt_optind;
+ if (first_nonopt > cgetopt_optind)
+ first_nonopt = cgetopt_optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != cgetopt_optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != cgetopt_optind)
+ first_nonopt = cgetopt_optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (cgetopt_optind < argc && NONOPTION_P)
+ cgetopt_optind++;
+ last_nonopt = cgetopt_optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (cgetopt_optind != argc && !strcmp (argv[cgetopt_optind], "--"))
+ {
+ cgetopt_optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != cgetopt_optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = cgetopt_optind;
+ last_nonopt = argc;
+
+ cgetopt_optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (cgetopt_optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ cgetopt_optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ cgetopt_optarg = argv[cgetopt_optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[cgetopt_optind] + 1
+ + (longopts != NULL && argv[cgetopt_optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[cgetopt_optind][1] == '-'
+ || (long_only && (argv[cgetopt_optind][2] || !my_index (optstring, argv[cgetopt_optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (cgetopt_opterr)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[cgetopt_optind]);
+ nextchar += strlen (nextchar);
+ cgetopt_optind++;
+ cgetopt_optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ cgetopt_optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ cgetopt_optarg = nameend + 1;
+ else
+ {
+ if (cgetopt_opterr)
+ {
+ if (argv[cgetopt_optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[cgetopt_optind - 1][0], pfound->name);
+
+ nextchar += strlen (nextchar);
+
+ cgetopt_optopt = pfound->val;
+ return '?';
+ }
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (cgetopt_optind < argc)
+ cgetopt_optarg = argv[cgetopt_optind++];
+ else
+ {
+ if (cgetopt_opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[cgetopt_optind - 1]);
+ nextchar += strlen (nextchar);
+ cgetopt_optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[cgetopt_optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (cgetopt_opterr)
+ {
+ if (argv[cgetopt_optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[cgetopt_optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ cgetopt_optind++;
+ cgetopt_optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ const char *temp = my_index (optstring, c);
+
+ /* Increment `cgetopt_optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++cgetopt_optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (cgetopt_opterr)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ cgetopt_optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ cgetopt_optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ cgetopt_optind++;
+ }
+ else if (cgetopt_optind == argc)
+ {
+ if (cgetopt_opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ cgetopt_optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ cgetopt_optarg = argv[cgetopt_optind++];
+
+ /* cgetopt_optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = cgetopt_optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (cgetopt_opterr)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[cgetopt_optind]);
+ nextchar += strlen (nextchar);
+ cgetopt_optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ cgetopt_optarg = nameend + 1;
+ else
+ {
+ if (cgetopt_opterr)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (cgetopt_optind < argc)
+ cgetopt_optarg = argv[cgetopt_optind++];
+ else
+ {
+ if (cgetopt_opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[cgetopt_optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ cgetopt_optarg = nextchar;
+ cgetopt_optind++;
+ }
+ else
+ cgetopt_optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ cgetopt_optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ cgetopt_optind++;
+ }
+ else if (cgetopt_optind == argc)
+ {
+ if (cgetopt_opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ cgetopt_optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ cgetopt_optarg = argv[cgetopt_optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+libiberty_getopt_long (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index)
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+libiberty_getopt_long_only (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index)
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+#endif
+
+
+extern "C" char
+EXPORT(getopt) (int argc, char *argv[], char *optstring)
+{
+ char r = getopt (argc, argv, optstring);
+
+ EXPORT(optarg) = optarg;
+ EXPORT(optind) = optind;
+ EXPORT(opterr) = opterr;
+ EXPORT(optopt) = optopt;
+
+ if (r == (char)-1)
+ return (char)0;
+ return r;
+}
+
+extern "C" int
+EXPORT(getopt_long) (int argc, char *argv[], char *optstring,
+ const struct option *longopts, int *longindex)
+{
+#if defined(HAVE_GETOPT_LONG)
+ int r = getopt_long (argc, argv, optstring, longopts, longindex);
+
+ EXPORT(optarg) = optarg;
+ EXPORT(optind) = optind;
+ EXPORT(opterr) = opterr;
+ EXPORT(optopt) = optopt;
+#else
+ int r = libiberty_getopt_long (argc, argv, optstring, longopts, longindex);
+
+ EXPORT(optarg) = cgetopt_optarg;
+ EXPORT(optind) = cgetopt_optind;
+ EXPORT(opterr) = cgetopt_opterr;
+ EXPORT(optopt) = cgetopt_optopt;
+#endif
+
+ return r;
+}
+
+
+extern "C" int
+EXPORT(getopt_long_only) (int argc, char *argv[], char *optstring,
+ const struct option *longopts, int *longindex)
+{
+#if defined(HAVE_GETOPT_LONG_ONLY)
+ int r = getopt_long_only (argc, argv, optstring, longopts, longindex);
+
+ EXPORT(optarg) = optarg;
+ EXPORT(optind) = optind;
+ EXPORT(opterr) = opterr;
+ EXPORT(optopt) = optopt;
+#else
+ int r = libiberty_getopt_long_only (argc, argv, optstring, longopts, longindex);
+
+ EXPORT(optarg) = cgetopt_optarg;
+ EXPORT(optind) = cgetopt_optind;
+ EXPORT(opterr) = cgetopt_opterr;
+ EXPORT(optopt) = cgetopt_optopt;
+#endif
+
+ return r;
+}
+
+
/* GNU Modula-2 linking fodder. */
extern "C" void
diff --git a/libgm2/libm2pim/wrapc.cc b/libgm2/libm2pim/wrapc.cc
index c24d214..4d93050 100644
--- a/libgm2/libm2pim/wrapc.cc
+++ b/libgm2/libm2pim/wrapc.cc
@@ -277,6 +277,45 @@ EXPORT(isfinitef) (float x)
#endif
}
+/* isnan - provide non builtin alternative to the gcc builtin isnan.
+ Returns 1 if x is a NaN otherwise return 0. */
+
+extern "C" int
+EXPORT(isnan) (double x)
+{
+#if defined(FP_NAN)
+ return fpclassify (x) == FP_NAN;
+#else
+ return x != x;
+#endif
+}
+
+/* isnanf - provide non builtin alternative to the gcc builtin isnanf.
+ Returns 1 if x is a NaN otherwise return 0. */
+
+extern "C" int
+EXPORT(isnanf) (float x)
+{
+#if defined(FP_NAN)
+ return fpclassify (x) == FP_NAN;
+#else
+ return x != x;
+#endif
+}
+
+/* isnanl - provide non builtin alternative to the gcc builtin isnanl.
+ Returns 1 if x is a NaN otherwise return 0. */
+
+extern "C" int
+EXPORT(isnanl) (long double x)
+{
+#if defined(FP_NAN)
+ return fpclassify (x) == FP_NAN;
+#else
+ return x != x;
+#endif
+}
+
/* GNU Modula-2 linking hooks. */
extern "C" void
diff --git a/libgo/go/syscall/errstr.go b/libgo/go/syscall/errstr.go
index 9f688e2..02f228a 100644
--- a/libgo/go/syscall/errstr.go
+++ b/libgo/go/syscall/errstr.go
@@ -24,7 +24,7 @@ func Errstr(errnum int) string {
}
return string(b[:i])
}
- if errno != ERANGE {
+ if Errno(errno) != ERANGE {
return "strerror_r failure"
}
}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 1a20629..1073dfa7 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,36 @@
+2023-10-31 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c-c++-common/deep-copy-8.c: Add OpenACC
+ 'acc_map_data' variant.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * oacc-parallel.c (GOACC_data_start): Handle
+ 'GOACC_FLAG_LOCAL_DEVICE'.
+ (GOACC_parallel_keyed): Simplify accordingly.
+ * testsuite/libgomp.oacc-fortran/self-1.f90: Adjust.
+
+2023-10-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c-c++-common/if-1.c: Enhance.
+ * testsuite/libgomp.oacc-c-c++-common/self-1.c: Likewise.
+ * testsuite/libgomp.oacc-fortran/if-1.f90: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/if-self-1.c: New.
+ * testsuite/libgomp.oacc-fortran/self-1.f90: Likewise.
+
+2023-10-25 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * oacc-parallel.c (GOACC_parallel_keyed): Add code to handle
+ GOACC_FLAG_LOCAL_DEVICE case.
+ * testsuite/libgomp.oacc-c-c++-common/self-1.c: New test.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths
+
2023-10-20 Andrew Stubbs <ams@codesourcery.com>
* plugin/plugin-gcn.c (EF_AMDGPU_MACH_AMDGCN_GFX1030): New.
diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
index 363e665..16cf394 100644
--- a/libgomp/oacc-parallel.c
+++ b/libgomp/oacc-parallel.c
@@ -184,7 +184,10 @@ GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
/* Host fallback if "if" clause is false or if the current device is set to
the host. */
- if (flags & GOACC_FLAG_HOST_FALLBACK)
+ if ((flags & GOACC_FLAG_HOST_FALLBACK)
+ /* TODO: a proper pthreads based "multi-core CPU" local device
+ implementation. Currently, this is still the same as host-fallback. */
+ || (flags & GOACC_FLAG_LOCAL_DEVICE))
{
prof_info.device_type = acc_device_host;
api_info.device_type = prof_info.device_type;
@@ -446,7 +449,8 @@ GOACC_data_start (int flags_m, size_t mapnum,
/* Host fallback or 'do nothing'. */
if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
- || (flags & GOACC_FLAG_HOST_FALLBACK))
+ || (flags & GOACC_FLAG_HOST_FALLBACK)
+ || (flags & GOACC_FLAG_LOCAL_DEVICE))
{
prof_info.device_type = acc_device_host;
api_info.device_type = prof_info.device_type;
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-8.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-8.c
index 1b4cf2f..e705f78 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-8.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-8.c
@@ -12,8 +12,8 @@ struct dc
int *d;
};
-int
-main ()
+static void
+test (unsigned variant)
{
int n = 100, i, j, k;
struct dc v = { .a = 3 };
@@ -22,7 +22,16 @@ main ()
v.c = (int *) malloc (sizeof (int) * n);
v.d = (int *) malloc (sizeof (int) * n);
+ if (variant & 1)
+ {
#pragma acc enter data copyin(v)
+ }
+ else
+ {
+ void *v_d = acc_malloc (sizeof v);
+ acc_map_data (&v, v_d, sizeof v);
+ acc_memcpy_to_device (v_d, &v, sizeof v);
+ }
for (k = 0; k < 16; k++)
{
@@ -46,9 +55,25 @@ main ()
assert (!acc_is_present (v.d, sizeof (int) * n));
}
+ if (variant & 1)
+ {
#pragma acc exit data copyout(v)
+ }
+ else
+ {
+ void *v_d = acc_deviceptr (&v);
+ acc_unmap_data (&v);
+ acc_free (v_d);
+ }
assert (!acc_is_present (&v, sizeof (v)));
+}
+
+int
+main ()
+{
+ for (unsigned variant = 0; variant < 2; ++variant)
+ test (variant);
return 0;
}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c
index 5398905..f04c02f 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c
@@ -1,3 +1,7 @@
+/* OpenACC 'if' clause. */
+
+/* See also 'self-1.c'. */
+
#include <openacc.h>
#include <stdlib.h>
#include <stdbool.h>
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/if-self-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/if-self-1.c
new file mode 100644
index 0000000..f77edda
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/if-self-1.c
@@ -0,0 +1,36 @@
+/* Test 'if' and 'self' clause appearing together. */
+
+#include <openacc.h>
+
+static int test(float i, long double s)
+{
+ int ret;
+#pragma acc serial copyout(ret) if(i) self(s)
+ /* { dg-bogus {using 'vector_length \(32\)', ignoring 1} {} { xfail openacc_nvidia_accel_selected } .-1 } */
+ {
+ ret = acc_on_device(acc_device_host);
+ }
+ return ret;
+}
+
+int main()
+{
+ if (!test(0, 0))
+ __builtin_abort();
+
+ if (!test(0, 1))
+ __builtin_abort();
+
+#if ACC_MEM_SHARED
+ if (!test(1, 0))
+ __builtin_abort();
+#else
+ if (test(1, 0))
+ __builtin_abort();
+#endif
+
+ if (!test(1, 1))
+ __builtin_abort();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/self-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/self-1.c
new file mode 100644
index 0000000..d17e27c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/self-1.c
@@ -0,0 +1,967 @@
+/* OpenACC 'self' clause. */
+
+/* This is 'if-1.c' with 'self(!cond)' instead of 'if(cond)' on compute
+ constructs. */
+
+#include <openacc.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#define N 32
+
+int
+main(int argc, char **argv)
+{
+ float *a, *b, *d_a, *d_b, exp, exp2;
+ int i;
+ const int one = 1;
+ const int zero = 0;
+ int n;
+
+ a = (float *) malloc (N * sizeof (float));
+ b = (float *) malloc (N * sizeof (float));
+ d_a = (float *) acc_malloc (N * sizeof (float));
+ d_b = (float *) acc_malloc (N * sizeof (float));
+
+ for (i = 0; i < N; i++)
+ a[i] = 4.0;
+
+#pragma acc parallel copyin(a[0:N]) copyout(b[0:N]) self(0)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 5.0;
+#else
+ exp = 4.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 16.0;
+
+#pragma acc parallel self(1)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 17.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 8.0;
+
+#pragma acc parallel copyin(a[0:N]) copyout(b[0:N]) self(!one)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 9.0;
+#else
+ exp = 8.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 22.0;
+
+#pragma acc parallel self(!zero)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 23.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 16.0;
+
+#pragma acc parallel copyin(a[0:N]) copyout(b[0:N]) self(false)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 17.0;
+#else
+ exp = 16.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 76.0;
+
+#pragma acc parallel self(true)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 77.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 22.0;
+
+ n = 1;
+
+#pragma acc parallel copyin(a[0:N]) copyout(b[0:N]) self(!n)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 23.0;
+#else
+ exp = 22.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 18.0;
+
+ n = 0;
+
+#pragma acc parallel self(!n)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 19.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 49.0;
+
+ n = 1;
+
+#pragma acc parallel copyin(a[0:N]) copyout(b[0:N]) self(!(n + n))
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 50.0;
+#else
+ exp = 49.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 38.0;
+
+ n = 0;
+
+#pragma acc parallel self(!(n + n))
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 39.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 91.0;
+
+#pragma acc parallel copyin(a[0:N]) copyout(b[0:N]) self(!(-2))
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 92.0;
+#else
+ exp = 91.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 43.0;
+
+#pragma acc parallel copyin(a[0:N]) copyout(b[0:N]) self(one != 1)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 44.0;
+#else
+ exp = 43.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 87.0;
+
+#pragma acc parallel self(one != 0)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 88.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 3.0;
+ b[i] = 9.0;
+ }
+
+#if ACC_MEM_SHARED
+ exp = 0.0;
+ exp2 = 0.0;
+#else
+ acc_map_data (a, d_a, N * sizeof (float));
+ acc_map_data (b, d_b, N * sizeof (float));
+ exp = 3.0;
+ exp2 = 9.0;
+#endif
+
+#pragma acc update device(a[0:N], b[0:N]) if(1)
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 0.0;
+ b[i] = 0.0;
+ }
+
+#pragma acc update host(a[0:N], b[0:N]) if(1)
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != exp)
+ abort();
+
+ if (b[i] != exp2)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 6.0;
+ b[i] = 12.0;
+ }
+
+#pragma acc update device(a[0:N], b[0:N]) if(0)
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 0.0;
+ b[i] = 0.0;
+ }
+
+#pragma acc update host(a[0:N], b[0:N]) if(1)
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != exp)
+ abort();
+
+ if (b[i] != exp2)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 26.0;
+ b[i] = 21.0;
+ }
+
+#pragma acc update device(a[0:N], b[0:N]) if(1)
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 0.0;
+ b[i] = 0.0;
+ }
+
+#pragma acc update host(a[0:N], b[0:N]) if(0)
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != 0.0)
+ abort();
+
+ if (b[i] != 0.0)
+ abort();
+ }
+
+#if !ACC_MEM_SHARED
+ acc_unmap_data (a);
+ acc_unmap_data (b);
+#endif
+
+ acc_free (d_a);
+ acc_free (d_b);
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 4.0;
+ b[i] = 0.0;
+ }
+
+#pragma acc data copyin(a[0:N]) copyout(b[0:N]) if(1)
+{
+#pragma acc parallel present(a[0:N])
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ b[ii] = a[ii];
+ }
+ }
+}
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 4.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 8.0;
+ b[i] = 1.0;
+ }
+
+#pragma acc data copyin(a[0:N]) copyout(b[0:N]) if(0)
+{
+#if !ACC_MEM_SHARED
+ if (acc_is_present (a, N * sizeof (float)))
+ abort ();
+#endif
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+}
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 18.0;
+ b[i] = 21.0;
+ }
+
+#pragma acc data copyin(a[0:N]) if(1)
+{
+#if !ACC_MEM_SHARED
+ if (!acc_is_present (a, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc data copyout(b[0:N]) if(0)
+ {
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc data copyout(b[0:N]) if(1)
+ {
+#pragma acc parallel present(a[0:N]) present(b[0:N])
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ b[ii] = a[ii];
+ }
+ }
+ }
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+ }
+}
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 18.0)
+ abort ();
+ }
+
+#pragma acc enter data copyin (b[0:N]) if (0)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc exit data delete (b[0:N]) if (0)
+
+#pragma acc enter data copyin (b[0:N]) if (1)
+
+#if !ACC_MEM_SHARED
+ if (!acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc exit data delete (b[0:N]) if (1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc enter data copyin (b[0:N]) if (zero)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc exit data delete (b[0:N]) if (zero)
+
+#pragma acc enter data copyin (b[0:N]) if (one)
+
+#if !ACC_MEM_SHARED
+ if (!acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc exit data delete (b[0:N]) if (one)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc enter data copyin (b[0:N]) if (one == 0)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc exit data delete (b[0:N]) if (one == 0)
+
+#pragma acc enter data copyin (b[0:N]) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (!acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+#pragma acc exit data delete (b[0:N]) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b, N * sizeof (float)))
+ abort ();
+#endif
+
+ for (i = 0; i < N; i++)
+ a[i] = 4.0;
+
+#pragma acc kernels copyin(a[0:N]) copyout(b[0:N]) self(0)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 5.0;
+#else
+ exp = 4.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 16.0;
+
+#pragma acc kernels self(1)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 17.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 8.0;
+
+#pragma acc kernels copyin(a[0:N]) copyout(b[0:N]) self(!one)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 9.0;
+#else
+ exp = 8.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 22.0;
+
+#pragma acc kernels self(!zero)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 23.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 16.0;
+
+#pragma acc kernels copyin(a[0:N]) copyout(b[0:N]) self(false)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 17.0;
+#else
+ exp = 16.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 76.0;
+
+#pragma acc kernels self(true)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 77.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 22.0;
+
+ n = 1;
+
+#pragma acc kernels copyin(a[0:N]) copyout(b[0:N]) self(!n)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 23.0;
+#else
+ exp = 22.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 18.0;
+
+ n = 0;
+
+#pragma acc kernels self(!n)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 19.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 49.0;
+
+ n = 1;
+
+#pragma acc kernels copyin(a[0:N]) copyout(b[0:N]) self((n + n) == 0)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 50.0;
+#else
+ exp = 49.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 38.0;
+
+ n = 0;
+
+#pragma acc kernels self(!(n + n))
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 39.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 91.0;
+
+#pragma acc kernels copyin(a[0:N]) copyout(b[0:N]) self(!(-2))
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 92.0;
+#else
+ exp = 91.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 43.0;
+
+#pragma acc kernels copyin(a[0:N]) copyout(b[0:N]) self(one != 1)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+#if ACC_MEM_SHARED
+ exp = 44.0;
+#else
+ exp = 43.0;
+#endif
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != exp)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ a[i] = 87.0;
+
+#pragma acc kernels self(one != 0)
+ {
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ if (acc_on_device (acc_device_host))
+ b[ii] = a[ii] + 1;
+ else
+ b[ii] = a[ii];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (b[i] != 88.0)
+ abort();
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 3.0;
+ b[i] = 9.0;
+ }
+
+#if ACC_MEM_SHARED
+ exp = 0.0;
+ exp2 = 0.0;
+#else
+ acc_map_data (a, d_a, N * sizeof (float));
+ acc_map_data (b, d_b, N * sizeof (float));
+ exp = 3.0;
+ exp2 = 9.0;
+#endif
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/if-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/if-1.f90
index e0cfd91..5ba6509 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/if-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/if-1.f90
@@ -1,3 +1,7 @@
+! OpenACC 'if' clause.
+
+! See also 'self-1.f90'.
+
! { dg-do run }
! { dg-additional-options "-cpp" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/self-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/self-1.f90
new file mode 100644
index 0000000..6c1233d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/self-1.f90
@@ -0,0 +1,995 @@
+! OpenACC 'self' clause.
+
+! This is 'if-1.f90' with 'self(!cond)' instead of 'if(cond)' on compute
+! constructs.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+
+! { dg-additional-options "--param=openacc-kernels=decompose" }
+
+! { dg-additional-options "-fopt-info-note-omp" }
+! { dg-additional-options "-foffload=-fopt-info-note-omp" }
+
+! { dg-additional-options "--param=openacc-privatization=noisy" }
+! { dg-additional-options "-foffload=--param=openacc-privatization=noisy" }
+! Prune a few: uninteresting, and potentially varying depending on GCC configuration (data types):
+! { dg-prune-output {note: variable 'D\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} }
+
+! It's only with Tcl 8.5 (released in 2007) that "the variable 'varName'
+! passed to 'incr' may be unset, and in that case, it will be set to [...]",
+! so to maintain compatibility with earlier Tcl releases, we manually
+! initialize counter variables:
+! { dg-line l_dummy[variable c_compute 0] }
+! { dg-message "dummy" "" { target iN-VAl-Id } l_dummy } to avoid
+! "WARNING: dg-line var l_dummy defined, but not used". */
+
+program main
+ use openacc
+ implicit none
+
+ integer, parameter :: N = 8
+ integer, parameter :: one = 1
+ integer, parameter :: zero = 0
+ integer i, nn
+ real, allocatable :: a(:), b(:)
+ real exp, exp2
+
+ i = 0
+
+ allocate (a(N))
+ allocate (b(N))
+
+ a(:) = 4.0
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (1 /= 1) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ !TODO Unhandled 'CONST_DECL' instances for constant argument in 'acc_on_device' call.
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+#if ACC_MEM_SHARED
+ exp = 5.0
+#else
+ exp = 4.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 1
+ end do
+
+ a(:) = 16.0
+
+ !$acc parallel self (0 /= 1) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+ do i = 1, N
+ if (b(i) .ne. 17.0) STOP 2
+ end do
+
+ a(:) = 8.0
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (one /= 1) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+#if ACC_MEM_SHARED
+ exp = 9.0
+#else
+ exp = 8.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 3
+ end do
+
+ a(:) = 22.0
+
+ !$acc parallel self (zero /= 1) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+ do i = 1, N
+ if (b(i) .ne. 23.0) STOP 4
+ end do
+
+ a(:) = 16.0
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (.FALSE.) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+#if ACC_MEM_SHARED
+ exp = 17.0;
+#else
+ exp = 16.0;
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 5
+ end do
+
+ a(:) = 76.0
+
+ !$acc parallel self (.TRUE.) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+ do i = 1, N
+ if (b(i) .ne. 77.0) STOP 6
+ end do
+
+ a(:) = 22.0
+
+ nn = 1
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (nn /= 1) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+#if ACC_MEM_SHARED
+ exp = 23.0;
+#else
+ exp = 22.0;
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 7
+ end do
+
+ a(:) = 18.0
+
+ nn = 0
+
+ !$acc parallel self (nn /= 1) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+ do i = 1, N
+ if (b(i) .ne. 19.0) STOP 8
+ end do
+
+ a(:) = 49.0
+
+ nn = 1
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (.NOT. ((nn + nn) > 0)) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+#if ACC_MEM_SHARED
+ exp = 50.0
+#else
+ exp = 49.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 9
+ end do
+
+ a(:) = 38.0
+
+ nn = 0;
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (.NOT. ((nn + nn) > 0)) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+ do i = 1, N
+ if (b(i) .ne. 39.0) STOP 10
+ end do
+
+ a(:) = 91.0
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (.NOT. (-2 > 0)) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+ do i = 1, N
+ if (b(i) .ne. 92.0) STOP 11
+ end do
+
+ a(:) = 43.0
+
+ !$acc parallel copyin (a(1:N)) copyout (b(1:N)) self (one /= 1) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+#if ACC_MEM_SHARED
+ exp = 44.0
+#else
+ exp = 43.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 12
+ end do
+
+ a(:) = 87.0
+
+ !$acc parallel self (one /= 0) ! { dg-line l_compute[incr c_compute] }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end parallel
+
+ do i = 1, N
+ if (b(i) .ne. 88.0) STOP 13
+ end do
+
+ a(:) = 3.0
+ b(:) = 9.0
+
+#if ACC_MEM_SHARED
+ exp = 0.0
+ exp2 = 0.0
+#else
+ call acc_copyin (a, sizeof (a))
+ call acc_copyin (b, sizeof (b))
+ exp = 3.0;
+ exp2 = 9.0;
+#endif
+
+ !$acc update device (a(1:N), b(1:N)) if (1 == 1)
+
+ a(:) = 0.0
+ b(:) = 0.0
+
+ !$acc update host (a(1:N), b(1:N)) if (1 == 1)
+
+ do i = 1, N
+ if (a(i) .ne. exp) STOP 14
+ if (b(i) .ne. exp2) STOP 15
+ end do
+
+ a(:) = 6.0
+ b(:) = 12.0
+
+ !$acc update device (a(1:N), b(1:N)) if (0 == 1)
+
+ a(:) = 0.0
+ b(:) = 0.0
+
+ !$acc update host (a(1:N), b(1:N)) if (1 == 1)
+
+ do i = 1, N
+ if (a(i) .ne. exp) STOP 16
+ if (b(i) .ne. exp2) STOP 17
+ end do
+
+ a(:) = 26.0
+ b(:) = 21.0
+
+ !$acc update device (a(1:N), b(1:N)) if (1 == 1)
+
+ a(:) = 0.0
+ b(:) = 0.0
+
+ !$acc update host (a(1:N), b(1:N)) if (0 == 1)
+
+ do i = 1, N
+ if (a(i) .ne. 0.0) STOP 18
+ if (b(i) .ne. 0.0) STOP 19
+ end do
+
+#if !ACC_MEM_SHARED
+ call acc_copyout (a, sizeof (a))
+ call acc_copyout (b, sizeof (b))
+#endif
+
+ a(:) = 4.0
+ b(:) = 0.0
+
+ !$acc data copyin (a(1:N)) copyout (b(1:N)) if (1 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+
+ !$acc parallel present (a(1:N))
+ do i = 1, N
+ b(i) = a(i)
+ end do
+ !$acc end parallel
+ !$acc end data
+
+ do i = 1, N
+ if (b(i) .ne. 4.0) STOP 20
+ end do
+
+ a(:) = 8.0
+ b(:) = 1.0
+
+ !$acc data copyin (a(1:N)) copyout (b(1:N)) if (0 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: artificial} "" { target { ! openacc_host_selected } } .-1 }
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (a) .eqv. .TRUE.) STOP 21
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 22
+#endif
+
+ !$acc end data
+
+ a(:) = 18.0
+ b(:) = 21.0
+
+ !$acc data copyin (a(1:N)) if (1 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: artificial} "" { target { ! openacc_host_selected } } .-2 }
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (a) .eqv. .FALSE.) STOP 23
+#endif
+
+ !$acc data copyout (b(1:N)) if (0 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: artificial} "" { target { ! openacc_host_selected } } .-2 }
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 24
+#endif
+ !$acc data copyout (b(1:N)) if (1 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+
+ !$acc parallel present (a(1:N)) present (b(1:N))
+ do i = 1, N
+ b(i) = a(i)
+ end do
+ !$acc end parallel
+
+ !$acc end data
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 25
+#endif
+ !$acc end data
+ !$acc end data
+
+ do i = 1, N
+ if (b(1) .ne. 18.0) STOP 26
+ end do
+
+ !$acc enter data copyin (b(1:N)) if (0 == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 27
+#endif
+
+ !$acc exit data delete (b(1:N)) if (0 == 1)
+
+ !$acc enter data copyin (b(1:N)) if (1 == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .FALSE.) STOP 28
+#endif
+
+ !$acc exit data delete (b(1:N)) if (1 == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 29
+#endif
+
+ !$acc enter data copyin (b(1:N)) if (zero == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 30
+#endif
+
+ !$acc exit data delete (b(1:N)) if (zero == 1)
+
+ !$acc enter data copyin (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .FALSE.) STOP 31
+#endif
+
+ !$acc exit data delete (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 32
+#endif
+
+ !$acc enter data copyin (b(1:N)) if (one == 0)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 33
+#endif
+
+ !$acc exit data delete (b(1:N)) if (one == 0)
+
+ !$acc enter data copyin (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .FALSE.) STOP 34
+#endif
+
+ !$acc exit data delete (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 35
+#endif
+
+ a(:) = 4.0
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (1 /= 1) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+#if ACC_MEM_SHARED
+ exp = 5.0
+#else
+ exp = 4.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 36
+ end do
+
+ a(:) = 16.0
+
+ !$acc kernels self (0 /= 1) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+ do i = 1, N
+ if (b(i) .ne. 17.0) STOP 37
+ end do
+
+ a(:) = 8.0
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (one /= 1) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+#if ACC_MEM_SHARED
+ exp = 9.0
+#else
+ exp = 8.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 38
+ end do
+
+ a(:) = 22.0
+
+ !$acc kernels self (zero /= 1) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+ do i = 1, N
+ if (b(i) .ne. 23.0) STOP 39
+ end do
+
+ a(:) = 16.0
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (.FALSE.) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+#if ACC_MEM_SHARED
+ exp = 17.0;
+#else
+ exp = 16.0;
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 40
+ end do
+
+ a(:) = 76.0
+
+ !$acc kernels self (.TRUE.) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+ do i = 1, N
+ if (b(i) .ne. 77.0) STOP 41
+ end do
+
+ a(:) = 22.0
+
+ nn = 1
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (nn /= 1) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+#if ACC_MEM_SHARED
+ exp = 23.0;
+#else
+ exp = 22.0;
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 42
+ end do
+
+ a(:) = 18.0
+
+ nn = 0
+
+ !$acc kernels self (nn /= 1) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+ do i = 1, N
+ if (b(i) .ne. 19.0) STOP 43
+ end do
+
+ a(:) = 49.0
+
+ nn = 1
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (.NOT. ((nn + nn) > 0)) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+#if ACC_MEM_SHARED
+ exp = 50.0
+#else
+ exp = 49.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 44
+ end do
+
+ a(:) = 38.0
+
+ nn = 0;
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (.NOT. ((nn + nn) > 0)) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+ do i = 1, N
+ if (b(i) .ne. 39.0) STOP 45
+ end do
+
+ a(:) = 91.0
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (.NOT. (-2 > 0)) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+ do i = 1, N
+ if (b(i) .ne. 92.0) STOP 46
+ end do
+
+ a(:) = 43.0
+
+ !$acc kernels copyin (a(1:N)) copyout (b(1:N)) self (one /= 1) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+#if ACC_MEM_SHARED
+ exp = 44.0
+#else
+ exp = 43.0
+#endif
+
+ do i = 1, N
+ if (b(i) .ne. exp) STOP 47
+ end do
+
+ a(:) = 87.0
+
+ !$acc kernels self (one /= 0) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ ! { dg-note {variable 'C\.[0-9]+' declared in block potentially has improper OpenACC privatization level: 'const_decl'} "TODO" { target *-*-* } l_compute$c_compute }
+ if (acc_on_device (acc_device_host) .eqv. .TRUE.) then
+ b(i) = a(i) + 1
+ else
+ b(i) = a(i)
+ end if
+ end do
+ !$acc end kernels
+
+ do i = 1, N
+ if (b(i) .ne. 88.0) STOP 48
+ end do
+
+ a(:) = 3.0
+ b(:) = 9.0
+
+#if ACC_MEM_SHARED
+ exp = 0.0
+ exp2 = 0.0
+#else
+ call acc_copyin (a, sizeof (a))
+ call acc_copyin (b, sizeof (b))
+ exp = 3.0;
+ exp2 = 9.0;
+#endif
+
+ !$acc update device (a(1:N), b(1:N)) if (1 == 1)
+
+ a(:) = 0.0
+ b(:) = 0.0
+
+ !$acc update host (a(1:N), b(1:N)) if (1 == 1)
+
+ do i = 1, N
+ if (a(i) .ne. exp) STOP 49
+ if (b(i) .ne. exp2) STOP 50
+ end do
+
+ a(:) = 6.0
+ b(:) = 12.0
+
+ !$acc update device (a(1:N), b(1:N)) if (0 == 1)
+
+ a(:) = 0.0
+ b(:) = 0.0
+
+ !$acc update host (a(1:N), b(1:N)) if (1 == 1)
+
+ do i = 1, N
+ if (a(i) .ne. exp) STOP 51
+ if (b(i) .ne. exp2) STOP 52
+ end do
+
+ a(:) = 26.0
+ b(:) = 21.0
+
+ !$acc update device (a(1:N), b(1:N)) if (1 == 1)
+
+ a(:) = 0.0
+ b(:) = 0.0
+
+ !$acc update host (a(1:N), b(1:N)) if (0 == 1)
+
+ do i = 1, N
+ if (a(i) .ne. 0.0) STOP 53
+ if (b(i) .ne. 0.0) STOP 54
+ end do
+
+#if !ACC_MEM_SHARED
+ call acc_copyout (a, sizeof (a))
+ call acc_copyout (b, sizeof (b))
+#endif
+
+ a(:) = 4.0
+ b(:) = 0.0
+
+ !$acc data copyin (a(1:N)) copyout (b(1:N)) if (1 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+
+ !$acc kernels present (a(1:N)) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ b(i) = a(i)
+ end do
+ !$acc end kernels
+ !$acc end data
+
+ do i = 1, N
+ if (b(i) .ne. 4.0) STOP 55
+ end do
+
+ a(:) = 8.0
+ b(:) = 1.0
+
+ !$acc data copyin (a(1:N)) copyout (b(1:N)) if (0 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: artificial} "" { target { ! openacc_host_selected } } .-1 }
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (a) .eqv. .TRUE.) STOP 56
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 57
+#endif
+
+ !$acc end data
+
+ a(:) = 18.0
+ b(:) = 21.0
+
+ !$acc data copyin (a(1:N)) if (1 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: artificial} "" { target { ! openacc_host_selected } } .-2 }
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (a) .eqv. .FALSE.) STOP 58
+#endif
+
+ !$acc data copyout (b(1:N)) if (0 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: artificial} "" { target { ! openacc_host_selected } } .-2 }
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 59
+#endif
+ !$acc data copyout (b(1:N)) if (1 == 1)
+ ! { dg-note {variable 'parm\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+
+ !$acc kernels present (a(1:N)) present (b(1:N)) ! { dg-line l_compute[incr c_compute] }
+ ! { dg-note {OpenACC 'kernels' decomposition: variable 'i' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute$c_compute }
+ ! { dg-note {variable 'i' already made addressable} {} { target *-*-* } l_compute$c_compute } */
+ ! { dg-note {beginning 'parloops' part in OpenACC 'kernels' region} "" { target *-*-* } .+1 }
+ do i = 1, N
+ b(i) = a(i)
+ end do
+ !$acc end kernels
+
+ !$acc end data
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 60
+#endif
+ !$acc end data
+ !$acc end data
+
+ do i = 1, N
+ if (b(1) .ne. 18.0) STOP 61
+ end do
+
+ !$acc enter data copyin (b(1:N)) if (0 == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 62
+#endif
+
+ !$acc exit data delete (b(1:N)) if (0 == 1)
+
+ !$acc enter data copyin (b(1:N)) if (1 == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .FALSE.) STOP 63
+#endif
+
+ !$acc exit data delete (b(1:N)) if (1 == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 64
+#endif
+
+ !$acc enter data copyin (b(1:N)) if (zero == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 65
+#endif
+
+ !$acc exit data delete (b(1:N)) if (zero == 1)
+
+ !$acc enter data copyin (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .FALSE.) STOP 66
+#endif
+
+ !$acc exit data delete (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 67
+#endif
+
+ !$acc enter data copyin (b(1:N)) if (one == 0)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 68
+#endif
+
+ !$acc exit data delete (b(1:N)) if (one == 0)
+
+ !$acc enter data copyin (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .FALSE.) STOP 69
+#endif
+
+ !$acc exit data delete (b(1:N)) if (one == 1)
+
+#if !ACC_MEM_SHARED
+ if (acc_is_present (b) .eqv. .TRUE.) STOP 70
+#endif
+
+end program main
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index d8e6feb..e80a045 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,15 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * testsuite/lib/libitm.exp: Likewise.
+ * testsuite/libitm.c++/c++.exp: Likewise.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/libitm/testsuite/lib/libitm.exp b/libitm/testsuite/lib/libitm.exp
index da918d1..61bbfa0 100644
--- a/libitm/testsuite/lib/libitm.exp
+++ b/libitm/testsuite/lib/libitm.exp
@@ -159,6 +159,7 @@ proc libitm_init { args } {
}
if [istarget *-*-darwin*] {
+ lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/.libs"
lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc"
}
diff --git a/libitm/testsuite/libitm.c++/c++.exp b/libitm/testsuite/libitm.c++/c++.exp
index de45e7e..1b0ead0 100644
--- a/libitm/testsuite/libitm.c++/c++.exp
+++ b/libitm/testsuite/libitm.c++/c++.exp
@@ -56,8 +56,10 @@ if { $lang_test_file_found } {
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.C]]
+ set stdcxxadder ""
if { $blddir != "" } {
set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
+ set stdcxxadder "-B ${blddir}/${lang_library_path}"
} else {
set ld_library_path "$always_ld_library_path"
}
@@ -72,7 +74,7 @@ if { $lang_test_file_found } {
}
# Main loop.
- dg-runtest $tests "" $libstdcxx_includes
+ dg-runtest $tests $stdcxxadder $libstdcxx_includes
}
# All done.
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index b797888..030eebe 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,8 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog
index f8e1c02..bf6e94a 100644
--- a/libphobos/ChangeLog
+++ b/libphobos/ChangeLog
@@ -1,3 +1,17 @@
+2023-10-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/MERGE: Merge upstream druntime e48bc0987d.
+ * src/MERGE: Merge upstream phobos 2458e8f82.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+ * libdruntime/Makefile.am: Handle Darwin rpaths.
+ * libdruntime/Makefile.in: Regenerate.
+ * src/Makefile.am: Handle Darwin rpaths.
+ * src/Makefile.in: Regenerate.
+
2023-10-16 Iain Buclaw <ibuclaw@gdcproject.org>
* libdruntime/MERGE: Merge upstream druntime 4c18eed967.
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 7946002..2a0baf0 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-4c18eed9674e04c1ca89fbc8bd5c4e483eb5477c
+e48bc0987dfec35bc76a3015ee3e85906ce86dfd
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/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index 2508359..54f8767 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -11,6 +11,11 @@ module core.internal.array.construction;
import core.internal.traits : Unqual;
+debug(PRINTF)
+{
+ import core.stdc.stdio;
+}
+
/**
* Does array initialization (not assignment) from another array of the same element type.
* Params:
@@ -319,3 +324,165 @@ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted
assert(!didThrow);
assert(counter == 4);
}
+
+/**
+ * Allocate an array with the garbage collector. Also initalize elements if
+ * their type has an initializer. Otherwise, not zero-initialize the array.
+ *
+ * Has three variants:
+ * `_d_newarrayU` leaves elements uninitialized
+ * `_d_newarrayT` initializes to 0 or based on initializer
+ *
+ * Params:
+ * length = `.length` of resulting array
+ *
+ * Returns:
+ * newly allocated array
+ */
+T[] _d_newarrayU(T)(size_t length, bool isShared=false) pure nothrow @nogc @trusted
+{
+ alias PureType = T[] function(size_t length, bool isShared) pure nothrow @nogc @trusted;
+ return (cast(PureType) &_d_newarrayUImpl!T)(length, isShared);
+}
+
+T[] _d_newarrayUImpl(T)(size_t length, bool isShared=false) @trusted
+{
+ import core.exception : onOutOfMemoryError;
+ import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
+
+ size_t elemSize = T.sizeof;
+ size_t arraySize;
+
+ debug(PRINTF) printf("_d_newarrayU(length = x%zu, size = %zu)\n", length, elemSize);
+ if (length == 0 || elemSize == 0)
+ return null;
+
+ version (D_InlineAsm_X86)
+ {
+ asm pure nothrow @nogc
+ {
+ mov EAX, elemSize ;
+ mul EAX, length ;
+ mov arraySize, EAX ;
+ jnc Lcontinue ;
+ }
+ }
+ else version (D_InlineAsm_X86_64)
+ {
+ asm pure nothrow @nogc
+ {
+ mov RAX, elemSize ;
+ mul RAX, length ;
+ mov arraySize, RAX ;
+ jnc Lcontinue ;
+ }
+ }
+ else
+ {
+ import core.checkedint : mulu;
+
+ bool overflow = false;
+ arraySize = mulu(elemSize, length, overflow);
+ if (!overflow)
+ goto Lcontinue;
+ }
+
+Loverflow:
+ onOutOfMemoryError();
+ assert(0);
+
+Lcontinue:
+ auto info = __arrayAlloc!T(arraySize);
+ if (!info.base)
+ goto Loverflow;
+ debug(PRINTF) printf("p = %p\n", info.base);
+
+ auto arrstart = __arrayStart(info);
+
+ __setArrayAllocLength!T(info, arraySize, isShared);
+
+ return (cast(T*) arrstart)[0 .. length];
+}
+
+/// ditto
+T[] _d_newarrayT(T)(size_t length, bool isShared=false) @trusted
+{
+ T[] result = _d_newarrayU!T(length, isShared);
+
+ static if (__traits(isZeroInit, T))
+ {
+ import core.stdc.string : memset;
+ memset(result.ptr, 0, length * T.sizeof);
+ }
+ else
+ {
+ import core.internal.lifetime : emplaceInitializer;
+ foreach (ref elem; result)
+ emplaceInitializer(elem);
+ }
+
+ return result;
+}
+
+unittest
+{
+ {
+ // zero-initialization
+ struct S { int x, y; }
+ S[] s = _d_newarrayT!S(10);
+
+ assert(s !is null);
+ assert(s.length == 10);
+ foreach (ref elem; s)
+ {
+ assert(elem.x == 0);
+ assert(elem.y == 0);
+ }
+ }
+ {
+ // S.init
+ struct S { int x = 2, y = 3; }
+ S[] s = _d_newarrayT!S(10);
+
+ assert(s.length == 10);
+ foreach (ref elem; s)
+ {
+ assert(elem.x == 2);
+ assert(elem.y == 3);
+ }
+ }
+}
+
+unittest
+{
+ int pblits;
+
+ struct S
+ {
+ this(this) { pblits++; }
+ }
+
+ S[] s = _d_newarrayT!S(2);
+
+ assert(s.length == 2);
+ assert(pblits == 0);
+}
+
+version (D_ProfileGC)
+{
+ /**
+ * TraceGC wrapper around $(REF _d_newitemT, core,lifetime).
+ */
+ T[] _d_newarrayTTrace(T)(string file, int line, string funcname, size_t length, bool isShared) @trusted
+ {
+ version (D_TypeInfo)
+ {
+ import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
+ mixin(TraceHook!(T.stringof, "_d_newarrayT"));
+
+ return _d_newarrayT!T(length, isShared);
+ }
+ else
+ assert(0, "Cannot create new array if compiling without support for runtime type information!");
+ }
+}
diff --git a/libphobos/libdruntime/core/internal/array/utils.d b/libphobos/libdruntime/core/internal/array/utils.d
index a16005e..57eb14b 100644
--- a/libphobos/libdruntime/core/internal/array/utils.d
+++ b/libphobos/libdruntime/core/internal/array/utils.d
@@ -10,6 +10,25 @@
module core.internal.array.utils;
import core.internal.traits : Parameters;
+import core.memory : GC;
+
+alias BlkInfo = GC.BlkInfo;
+alias BlkAttr = GC.BlkAttr;
+
+private
+{
+ enum : size_t
+ {
+ PAGESIZE = 4096,
+ BIGLENGTHMASK = ~(PAGESIZE - 1),
+ SMALLPAD = 1,
+ MEDPAD = ushort.sizeof,
+ LARGEPREFIX = 16, // 16 bytes padding at the front of the array
+ LARGEPAD = LARGEPREFIX + 1,
+ MAXSMALLSIZE = 256-SMALLPAD,
+ MAXMEDSIZE = (PAGESIZE / 2) - MEDPAD
+ }
+}
auto gcStatsPure() nothrow pure
{
@@ -136,3 +155,220 @@ template isPostblitNoThrow(T) {
else
enum isPostblitNoThrow = true;
}
+
+/**
+ * Clear padding that might not be zeroed by the GC (it assumes it is within the
+ * requested size from the start, but it is actually at the end of the allocated
+ * block).
+ *
+ * Params:
+ * info = array allocation data
+ * arrSize = size of the array in bytes
+ * padSize = size of the padding in bytes
+ */
+void __arrayClearPad()(ref BlkInfo info, size_t arrSize, size_t padSize) nothrow pure
+{
+ import core.stdc.string;
+ if (padSize > MEDPAD && !(info.attr & BlkAttr.NO_SCAN) && info.base)
+ {
+ if (info.size < PAGESIZE)
+ memset(info.base + arrSize, 0, padSize);
+ else
+ memset(info.base, 0, LARGEPREFIX);
+ }
+}
+
+/**
+ * Allocate an array memory block by applying the proper padding and assigning
+ * block attributes if not inherited from the existing block.
+ *
+ * Params:
+ * arrSize = size of the allocated array in bytes
+ * Returns:
+ * `BlkInfo` with allocation metadata
+ */
+BlkInfo __arrayAlloc(T)(size_t arrSize) @trusted
+{
+ import core.checkedint;
+ import core.lifetime : TypeInfoSize;
+ import core.internal.traits : hasIndirections;
+
+ enum typeInfoSize = TypeInfoSize!T;
+ BlkAttr attr = BlkAttr.APPENDABLE;
+
+ size_t padSize = arrSize > MAXMEDSIZE ?
+ LARGEPAD :
+ ((arrSize > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + typeInfoSize);
+
+ bool overflow;
+ auto paddedSize = addu(arrSize, padSize, overflow);
+
+ if (overflow)
+ return BlkInfo();
+
+ /* `extern(C++)` classes don't have a classinfo pointer in their vtable,
+ * so the GC can't finalize them.
+ */
+ static if (typeInfoSize)
+ attr |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE;
+ static if (!hasIndirections!T)
+ attr |= BlkAttr.NO_SCAN;
+
+ auto bi = GC.qalloc(paddedSize, attr, typeid(T));
+ __arrayClearPad(bi, arrSize, padSize);
+ return bi;
+}
+
+/**
+ * Get the start of the array for the given block.
+ *
+ * Params:
+ * info = array metadata
+ * Returns:
+ * pointer to the start of the array
+ */
+void *__arrayStart()(return scope BlkInfo info) nothrow pure
+{
+ return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
+}
+
+/**
+ * Set the allocated length of the array block. This is called when an array
+ * is appended to or its length is set.
+ *
+ * The allocated block looks like this for blocks < PAGESIZE:
+ * `|elem0|elem1|elem2|...|elemN-1|emptyspace|N*elemsize|`
+ *
+ * The size of the allocated length at the end depends on the block size:
+ * a block of 16 to 256 bytes has an 8-bit length.
+ * a block with 512 to pagesize/2 bytes has a 16-bit length.
+ *
+ * For blocks >= pagesize, the length is a size_t and is at the beginning of the
+ * block. The reason we have to do this is because the block can extend into
+ * more pages, so we cannot trust the block length if it sits at the end of the
+ * block, because it might have just been extended. If we can prove in the
+ * future that the block is unshared, we may be able to change this, but I'm not
+ * sure it's important.
+ *
+ * In order to do put the length at the front, we have to provide 16 bytes
+ * buffer space in case the block has to be aligned properly. In x86, certain
+ * SSE instructions will only work if the data is 16-byte aligned. In addition,
+ * we need the sentinel byte to prevent accidental pointers to the next block.
+ * Because of the extra overhead, we only do this for page size and above, where
+ * the overhead is minimal compared to the block size.
+ *
+ * So for those blocks, it looks like:
+ * `|N*elemsize|padding|elem0|elem1|...|elemN-1|emptyspace|sentinelbyte|``
+ *
+ * where `elem0` starts 16 bytes after the first byte.
+ */
+bool __setArrayAllocLength(T)(ref BlkInfo info, size_t newLength, bool isShared, size_t oldLength = ~0)
+{
+ import core.atomic;
+ import core.lifetime : TypeInfoSize;
+
+ size_t typeInfoSize = TypeInfoSize!T;
+
+ if (info.size <= 256)
+ {
+ import core.checkedint;
+
+ bool overflow;
+ auto newLengthPadded = addu(newLength,
+ addu(SMALLPAD, typeInfoSize, overflow),
+ overflow);
+
+ if (newLengthPadded > info.size || overflow)
+ // new size does not fit inside block
+ return false;
+
+ auto length = cast(ubyte *)(info.base + info.size - typeInfoSize - SMALLPAD);
+ if (oldLength != ~0)
+ {
+ if (isShared)
+ {
+ return cas(cast(shared)length, cast(ubyte)oldLength, cast(ubyte)newLength);
+ }
+ else
+ {
+ if (*length == cast(ubyte)oldLength)
+ *length = cast(ubyte)newLength;
+ else
+ return false;
+ }
+ }
+ else
+ {
+ // setting the initial length, no cas needed
+ *length = cast(ubyte)newLength;
+ }
+ if (typeInfoSize)
+ {
+ auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof);
+ *typeInfo = cast()typeid(T);
+ }
+ }
+ else if (info.size < PAGESIZE)
+ {
+ if (newLength + MEDPAD + typeInfoSize > info.size)
+ // new size does not fit inside block
+ return false;
+ auto length = cast(ushort *)(info.base + info.size - typeInfoSize - MEDPAD);
+ if (oldLength != ~0)
+ {
+ if (isShared)
+ {
+ return cas(cast(shared)length, cast(ushort)oldLength, cast(ushort)newLength);
+ }
+ else
+ {
+ if (*length == oldLength)
+ *length = cast(ushort)newLength;
+ else
+ return false;
+ }
+ }
+ else
+ {
+ // setting the initial length, no cas needed
+ *length = cast(ushort)newLength;
+ }
+ if (typeInfoSize)
+ {
+ auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof);
+ *typeInfo = cast()typeid(T);
+ }
+ }
+ else
+ {
+ if (newLength + LARGEPAD > info.size)
+ // new size does not fit inside block
+ return false;
+ auto length = cast(size_t *)(info.base);
+ if (oldLength != ~0)
+ {
+ if (isShared)
+ {
+ return cas(cast(shared)length, cast(size_t)oldLength, cast(size_t)newLength);
+ }
+ else
+ {
+ if (*length == oldLength)
+ *length = newLength;
+ else
+ return false;
+ }
+ }
+ else
+ {
+ // setting the initial length, no cas needed
+ *length = newLength;
+ }
+ if (typeInfoSize)
+ {
+ auto typeInfo = cast(TypeInfo*)(info.base + size_t.sizeof);
+ *typeInfo = cast()typeid(T);
+ }
+ }
+ return true; // resize succeeded
+}
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index 3a55ca9..6b083ea 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -2731,7 +2731,8 @@ if (is(T == class))
{
import core.internal.traits : hasIndirections;
import core.exception : onOutOfMemoryError;
- import core.memory : GC, pureMalloc;
+ import core.memory : pureMalloc;
+ import core.memory : GC;
alias BlkAttr = GC.BlkAttr;
@@ -2820,11 +2821,11 @@ T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted
T* _d_newitemT(T)() @trusted
{
import core.internal.lifetime : emplaceInitializer;
- import core.internal.traits : hasElaborateDestructor, hasIndirections;
+ import core.internal.traits : hasIndirections;
import core.memory : GC;
auto flags = !hasIndirections!T ? GC.BlkAttr.NO_SCAN : GC.BlkAttr.NONE;
- immutable tiSize = hasElaborateDestructor!T ? size_t.sizeof : 0;
+ immutable tiSize = TypeInfoSize!T;
immutable itemSize = T.sizeof;
immutable totalSize = itemSize + tiSize;
if (tiSize)
@@ -3004,3 +3005,9 @@ version (D_ProfileGC)
assert(0, "Cannot create new `struct` if compiling without support for runtime type information!");
}
}
+
+template TypeInfoSize(T)
+{
+ import core.internal.traits : hasElaborateDestructor;
+ enum TypeInfoSize = hasElaborateDestructor!T ? size_t.sizeof : 0;
+}
diff --git a/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d b/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d
new file mode 100644
index 0000000..aa39ac4
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d
@@ -0,0 +1,41 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's ifaddrs.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.ifaddrs;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+import core.sys.posix.sys.socket : sockaddr;
+
+struct ifaddrs
+{
+ ifaddrs* ifa_next;
+ char* ifa_name;
+ uint ifa_flags;
+ sockaddr* ifa_addr;
+ sockaddr* ifa_netmask;
+ sockaddr* ifa_dstaddr;
+ void* ifa_data;
+}
+
+struct ifmaddrs
+{
+ ifmaddrs* ifma_next;
+ sockaddr* ifma_name;
+ sockaddr* ifma_addr;
+ sockaddr* ifma_lladdr;
+}
+
+int getifaddrs(ifaddrs**);
+void freeifaddrs(ifaddrs*);
+int getifmaddrs(ifmaddrs**);
+void freeifmaddrs(ifmaddrs*);
diff --git a/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d b/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d
new file mode 100644
index 0000000..9f83061
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d
@@ -0,0 +1,42 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's net/if_dl.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.net.if_dl;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+import core.sys.freebsd.sys.types : caddr_t, c_caddr_t;
+import core.sys.posix.sys.socket : sa_family_t, sockaddr;
+
+struct sockaddr_dl
+{
+ ubyte sdl_len;
+ sa_family_t sdl_family;
+ ushort sdl_index;
+ ubyte sdl_type;
+ ubyte sdl_nlen;
+ ubyte sdl_alen;
+ ubyte sdl_slen;
+ ubyte[46] sdl_data;
+}
+
+auto LLADDR()(sockaddr_dl* s) { return cast(caddr_t)(s.sdl_data.ptr + s.sdl_nlen); }
+auto CLLADDR()(const sockaddr_dl* s) { return cast(c_caddr_t)(s.sdl_data.ptr + s.sdl_nlen); }
+ushort LLINDEX()(const sockaddr_dl* s) { return s.sdl_index; }
+
+struct ifnet;
+sockaddr_dl* link_alloc_sdl(size_t, int);
+void link_free_sdl(sockaddr* sa);
+sockaddr_dl* link_init_sdl(ifnet*, sockaddr*, ubyte);
+
+void link_addr(const char*, sockaddr_dl*);
+char* link_ntoa(const sockaddr_dl*);
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/socket.d b/libphobos/libdruntime/core/sys/freebsd/sys/socket.d
new file mode 100644
index 0000000..6d61286
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/socket.d
@@ -0,0 +1,131 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's extensions to POSIX's sys/socket.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.sys.socket;
+
+public import core.sys.posix.sys.socket;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+// Creation flags, OR'ed into socket() and socketpair() type argument.
+enum : uint
+{
+ SOCK_CLOEXEC = 0x10000000,
+ SOCK_NONBLOCK = 0x20000000,
+}
+
+// Option flags per-socket.
+enum : uint
+{
+ SO_USELOOPBACK = 0x00000040,
+ SO_TIMESTAMP = 0x00000400,
+ SO_ACCEPTFILTER = 0x00001000,
+ SO_BINTIME = 0x00002000,
+
+ SO_NO_OFFLOAD = 0x00004000,
+ SO_NO_DDP = 0x00008000,
+ SO_REUSEPORT_LB = 0x00010000,
+ SO_RERROR = 0x00020000,
+}
+
+
+// Additional options, not kept in so_options.
+enum : uint
+{
+ SO_LABEL = 0x1009,
+ SO_PEERLABEL = 0x1010,
+ SO_LISTENQLIMIT = 0x1011,
+ SO_LISTENQLEN = 0x1012,
+ SO_LISTENINCQLEN = 0x1013,
+ SO_SETFIB = 0x1014,
+ SO_USER_COOKIE = 0x1015,
+ SO_PROTOCOL = 0x1016,
+ SO_PROTOTYPE = SO_PROTOCOL,
+ SO_TS_CLOCK = 0x1017,
+ SO_MAX_PACING_RATE = 0x1018,
+ SO_DOMAIN = 0x1019,
+
+ SO_TS_REALTIME_MICRO = 0,
+ SO_TS_BINTIME = 1,
+ SO_TS_REALTIME = 2,
+ SO_TS_MONOTONIC = 3,
+ SO_TS_DEFAULT = SO_TS_REALTIME_MICRO,
+ SO_TS_CLOCK_MAX = SO_TS_MONOTONIC,
+}
+
+/+
+ Space reserved for new socket options added by third-party vendors.
+ This range applies to all socket option levels. New socket options
+ in FreeBSD should always use an option value less than SO_VENDOR.
+ +/
+enum : uint
+{
+ SO_VENDOR = 0x80000000,
+}
+
+struct accept_filter_arg
+{
+ char[16] af_name;
+ char [256-16] af_arg;
+}
+
+// Address families.
+enum : uint
+{
+ AF_LOCAL = AF_UNIX,
+
+ AF_IMPLINK = 3,
+ AF_PUP = 4,
+ AF_CHAOS = 5,
+ AF_NETBIOS = 6,
+ AF_ISO = 7,
+ AF_OSI = AF_ISO,
+ AF_ECMA = 8,
+ AF_DATAKIT = 9,
+ AF_CCITT = 10,
+ AF_SNA = 11,
+ AF_DECnet = 12,
+ AF_DLI = 13,
+ AF_LAT = 14,
+ AF_HYLINK = 15,
+
+ AF_ROUTE = 17,
+ AF_LINK = 18,
+ pseudo_AF_XTP = 19,
+ AF_COIP = 20,
+ AF_CNT = 21,
+ pseudo_AF_RTIP = 22,
+
+ AF_SIP = 24,
+ pseudo_AF_PIP = 25,
+ AF_ISDN = 26,
+ AF_E164 = AF_ISDN,
+ pseudo_AF_KEY = 27,
+
+ AF_NATM = 29,
+ AF_ATM = 30,
+ pseudo_AF_HDRCMPLT = 31,
+ AF_NETGRAPH = 32,
+ AF_SLOW = 33,
+ AF_SCLUSTER = 34,
+ AF_ARP = 35,
+ AF_BLUETOOTH = 36,
+ AF_IEEE80211 = 37,
+ AF_NETLINK = 38,
+
+ AF_INET_SDP = 40,
+
+ AF_INET6_SDP = 42,
+ AF_HYPERV = 43,
+ AF_DIVERT = 44,
+ AF_MAX = 44,
+}
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/types.d b/libphobos/libdruntime/core/sys/freebsd/sys/types.d
new file mode 100644
index 0000000..b927ddf
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/types.d
@@ -0,0 +1,58 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's extensions to POSIX's sys/types.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.sys.types;
+
+public import core.sys.posix.sys.types;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+import core.stdc.config;
+
+alias caddr_t = ubyte*;
+alias c_caddr_t = const(ubyte)*;
+
+alias cpuwhich_t = int;
+alias cpulevel_t = int;
+alias cpusetid_t = int;
+
+alias critical_t = size_t;
+alias daddr_t = long;
+
+alias fixpt_t = uint;
+
+alias accmode_t = int;
+
+alias register_t = size_t;
+
+alias sbintime_t = long;
+
+alias segsz_t = size_t;
+
+alias u_register_t = size_t;
+
+alias cap_ioctl_t = size_t;
+
+alias kpaddr_t = ulong;
+alias kvaddr_t = ulong;
+alias ksize_t = ulong;
+alias kssize_t = long;
+
+alias vm_offset_t = size_t;
+alias vm_ooffset_t = ulong;
+alias vm_paddr_t = ulong;
+alias vm_pindex_t = ulong;
+alias vm_size_t = size_t;
+
+alias rman_res_t = ulong;
+
+alias syscallarg_t = register_t;
diff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d
index f0ce29f..642b383 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/types.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/types.d
@@ -187,7 +187,7 @@ else version (FreeBSD)
alias c_long ssize_t;
alias c_long time_t;
alias uint uid_t;
- alias uint fflags_t;
+ alias uint fflags_t; // non-standard
}
else version (NetBSD)
{
@@ -866,7 +866,7 @@ else version (Darwin)
}
else version (FreeBSD)
{
- alias int lwpid_t;
+ alias int lwpid_t; // non-standard
alias void* pthread_attr_t;
alias void* pthread_cond_t;
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index 294d34d..0111be0 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -4668,6 +4668,7 @@ version (D_ProfileGC)
public import core.internal.array.appending : _d_arrayappendTTrace;
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.appending : _d_arrayappendcTXImpl;
public import core.internal.array.comparison : __cmp;
@@ -4676,6 +4677,7 @@ public import core.internal.array.casting: __ArrayCast;
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.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/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index 1245374..af3c6bb 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -13,6 +13,7 @@
module rt.lifetime;
import core.attribute : weak;
+import core.internal.array.utils : __arrayStart, __arrayClearPad;
import core.memory;
debug(PRINTF) import core.stdc.stdio;
static import rt.tlsgc;
@@ -226,7 +227,6 @@ size_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc
private class ArrayAllocLengthLock
{}
-
/**
Set the allocated length of the array block. This is called
any time an array is appended to or its length is set.
@@ -387,14 +387,6 @@ private size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure
}
/**
- get the start of the array for the given block
- */
-private void *__arrayStart(return scope BlkInfo info) nothrow pure
-{
- return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
-}
-
-/**
get the padding required to allocate size bytes. Note that the padding is
NOT included in the passed in size. Therefore, do NOT call this function
with the size of an allocated block.
@@ -405,22 +397,6 @@ private size_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure @trus
}
/**
- clear padding that might not be zeroed by the GC (it assumes it is within the
- requested size from the start, but it is actually at the end of the allocated block)
- */
-private void __arrayClearPad(ref BlkInfo info, size_t arrsize, size_t padsize) nothrow pure
-{
- import core.stdc.string;
- if (padsize > MEDPAD && !(info.attr & BlkAttr.NO_SCAN) && info.base)
- {
- if (info.size < PAGESIZE)
- memset(info.base + arrsize, 0, padsize);
- else
- memset(info.base, 0, LARGEPREFIX);
- }
-}
-
-/**
allocate an array memory block by applying the proper padding and
assigning block attributes if not inherited from the existing block
*/
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 9a97927..a7bf856 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-d945686a4ff7d9fda0e2ee8d2ee201b66be2a287
+2458e8f82e3004197d8a66239a6b72e17264bb26
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/parallelism.d b/libphobos/src/std/parallelism.d
index 9b231f3..3fe8cd6 100644
--- a/libphobos/src/std/parallelism.d
+++ b/libphobos/src/std/parallelism.d
@@ -1581,7 +1581,7 @@ public:
auto logs = new double[10_000_000];
// Parallel foreach works with or without an index
- // variable. It can be iterate by ref if range.front
+ // variable. It can iterate by ref if range.front
// returns by ref.
// Iterate over logs using work units of size 100.
diff --git a/libphobos/src/std/range/primitives.d b/libphobos/src/std/range/primitives.d
index ef34a85..1a3fb06 100644
--- a/libphobos/src/std/range/primitives.d
+++ b/libphobos/src/std/range/primitives.d
@@ -540,13 +540,9 @@ private void putChar(R, E)(ref R r, E e)
if (isSomeChar!E)
{
// https://issues.dlang.org/show_bug.cgi?id=9186: Can't use (E[]).init
- ref const( char)[] cstringInit();
- ref const(wchar)[] wstringInit();
- ref const(dchar)[] dstringInit();
-
- enum csCond = is(typeof(doPut(r, cstringInit())));
- enum wsCond = is(typeof(doPut(r, wstringInit())));
- enum dsCond = is(typeof(doPut(r, dstringInit())));
+ enum csCond = is(typeof(doPut(r, (){ ref const( char)[] cstringInit(); return cstringInit(); }())));
+ enum wsCond = is(typeof(doPut(r, (){ ref const(wchar)[] wstringInit(); return wstringInit(); }())));
+ enum dsCond = is(typeof(doPut(r, (){ ref const(dchar)[] dstringInit(); return dstringInit(); }())));
//Use "max" to avoid static type demotion
enum ccCond = is(typeof(doPut(r, char.max)));
diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d
index 2ed7ee5..aa69aac 100644
--- a/libphobos/src/std/traits.d
+++ b/libphobos/src/std/traits.d
@@ -67,6 +67,7 @@
* $(LREF isAssignable)
* $(LREF isCovariantWith)
* $(LREF isImplicitlyConvertible)
+ * $(LREF isQualifierConvertible)
* ))
* $(TR $(TD Type Constructors) $(TD
* $(LREF InoutOf)
@@ -5167,6 +5168,62 @@ enum bool isImplicitlyConvertible(From, To) = is(From : To);
}
/**
+Is `From` $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible) to `To`?
+*/
+enum bool isQualifierConvertible(From, To) =
+ is(immutable From == immutable To) && is(From* : To*);
+
+///
+@safe unittest
+{
+ // Mutable and immmutable both convert to const...
+ static assert( isQualifierConvertible!(char, const(char)));
+ static assert( isQualifierConvertible!(immutable(char), const(char)));
+ // ...but const does not convert back to mutable or immutable
+ static assert(!isQualifierConvertible!(const(char), char));
+ static assert(!isQualifierConvertible!(const(char), immutable(char)));
+}
+
+@safe unittest
+{
+ import std.meta : AliasSeq;
+
+ alias Ts = AliasSeq!(int, const int, shared int, inout int, const shared int,
+ const inout int, inout shared int, const inout shared int, immutable int);
+
+ // https://dlang.org/spec/const3.html#implicit_qualifier_conversions
+ enum _ = 0;
+ static immutable bool[Ts.length][Ts.length] conversions = [
+ // m c s i cs ci is cis im
+ [1, 1, _, _, _, _, _, _, _], // mutable
+ [_, 1, _, _, _, _, _, _, _], // const
+ [_, _, 1, _, 1, _, _, _, _], // shared
+ [_, 1, _, 1, _, 1, _, _, _], // inout
+ [_, _, _, _, 1, _, _, _, _], // const shared
+ [_, 1, _, _, _, 1, _, _, _], // const inout
+ [_, _, _, _, 1, _, 1, 1, _], // inout shared
+ [_, _, _, _, 1, _, _, 1, _], // const inout shared
+ [_, 1, _, _, 1, 1, _, 1, 1], // immutable
+ ];
+
+ static foreach (i, From; Ts)
+ {
+ static foreach (j, To; Ts)
+ {
+ static assert(isQualifierConvertible!(From, To) == conversions[i][j],
+ "`isQualifierConvertible!(" ~ From.stringof ~ ", " ~ To.stringof ~ ")`"
+ ~ " should be `" ~ (conversions[i][j] ? "true" : "false") ~ "`");
+ }
+ }
+}
+
+@safe unittest
+{
+ // int* -> void* is not a qualifier conversion
+ static assert(!isQualifierConvertible!(int, void));
+}
+
+/**
Returns `true` iff a value of type `Rhs` can be assigned to a variable of
type `Lhs`.
diff --git a/libquadmath/ChangeLog b/libquadmath/ChangeLog
index 458e610..e449028 100644
--- a/libquadmath/ChangeLog
+++ b/libquadmath/ChangeLog
@@ -1,3 +1,17 @@
+2023-10-23 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR libquadmath/111928
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Remove AC_CHECK_LIBM.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/libquadmath/Makefile.in b/libquadmath/Makefile.in
index 068af55..dbcafb5 100644
--- a/libquadmath/Makefile.in
+++ b/libquadmath/Makefile.in
@@ -355,7 +355,6 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
-LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
diff --git a/libquadmath/configure b/libquadmath/configure
index 5bd9a07..fd52745 100755
--- a/libquadmath/configure
+++ b/libquadmath/configure
@@ -644,7 +644,6 @@ LIBQUAD_USE_SYMVER_GNU_FALSE
LIBQUAD_USE_SYMVER_GNU_TRUE
LIBQUAD_USE_SYMVER_FALSE
LIBQUAD_USE_SYMVER_TRUE
-LIBM
toolexeclibdir
toolexecdir
MAINT
@@ -10922,7 +10921,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10925 "configure"
+#line 10924 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11028,7 +11027,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11031 "configure"
+#line 11030 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12261,148 +12260,6 @@ esac
-LIBM=
-case $host in
-*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
- # These system don't have libm, or don't need it
- ;;
-*-ncr-sysv4.3*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5
-$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; }
-if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lmw $LIBS"
-if test x$gcc_no_link = xyes; then
- as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
-fi
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char _mwvalidcheckl ();
-int
-main ()
-{
-return _mwvalidcheckl ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_mw__mwvalidcheckl=yes
-else
- ac_cv_lib_mw__mwvalidcheckl=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5
-$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; }
-if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then :
- LIBM="-lmw"
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
-$as_echo_n "checking for cos in -lm... " >&6; }
-if ${ac_cv_lib_m_cos+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lm $LIBS"
-if test x$gcc_no_link = xyes; then
- as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
-fi
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char cos ();
-int
-main ()
-{
-return cos ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_m_cos=yes
-else
- ac_cv_lib_m_cos=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
-$as_echo "$ac_cv_lib_m_cos" >&6; }
-if test "x$ac_cv_lib_m_cos" = xyes; then :
- LIBM="$LIBM -lm"
-fi
-
- ;;
-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
-$as_echo_n "checking for cos in -lm... " >&6; }
-if ${ac_cv_lib_m_cos+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lm $LIBS"
-if test x$gcc_no_link = xyes; then
- as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
-fi
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char cos ();
-int
-main ()
-{
-return cos ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_m_cos=yes
-else
- ac_cv_lib_m_cos=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
-$as_echo "$ac_cv_lib_m_cos" >&6; }
-if test "x$ac_cv_lib_m_cos" = xyes; then :
- LIBM="-lm"
-fi
-
- ;;
-esac
-
-
-
for ac_header in fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
diff --git a/libquadmath/configure.ac b/libquadmath/configure.ac
index 94a3f21..23ac3ba 100644
--- a/libquadmath/configure.ac
+++ b/libquadmath/configure.ac
@@ -122,8 +122,6 @@ esac
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
-AC_CHECK_LIBM
-
AC_CHECK_HEADERS(fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h)
LIBQUAD_CHECK_MATH_H_SIGNGAM
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index 692e06b..5903f2c 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,17 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * asan/Makefile.am: Handle Darwin rpaths.
+ * asan/Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * hwasan/Makefile.am: Handle Darwin rpaths.
+ * hwasan/Makefile.in: Regenerate.
+ * lsan/Makefile.am: Handle Darwin rpaths.
+ * lsan/Makefile.in: Regenerate.
+ * tsan/Makefile.am: Handle Darwin rpaths.
+ * tsan/Makefile.in: Regenerate.
+ * ubsan/Makefile.am: Handle Darwin rpaths.
+ * ubsan/Makefile.in: Regenerate.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/libssp/ChangeLog b/libssp/ChangeLog
index 1b0c4f9..420abb6 100644
--- a/libssp/ChangeLog
+++ b/libssp/ChangeLog
@@ -1,3 +1,10 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.am: Handle Darwin rpaths.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 7e09e1a..6548dce 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,75 @@
+2023-10-30 François Dumont <fdumont@gcc.gnu.org>
+
+ * config/abi/pre/gnu-versioned-namespace.ver: Add comment on recently
+ added emul TLS symbols.
+
+2023-10-30 François Dumont <fdumont@gcc.gnu.org>
+
+ * src/experimental/contract.cc
+ [_GLIBCXX_INLINE_VERSION](handle_contract_violation): Rework comment.
+ Remove weak attribute.
+
+2023-10-29 François Dumont <fdumont@gcc.gnu.org>
+
+ * config/abi/pre/gnu-versioned-namespace.ver: Add missing emul TLS
+ symbols.
+
+2023-10-29 François Dumont <fdumont@gcc.gnu.org>
+
+ * src/experimental/contract.cc
+ [_GLIBCXX_INLINE_VERSION](handle_contract_violation): Provide symbol
+ without version namespace decoration for gcc.
+
+2023-10-26 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/112089
+ * include/std/shared_mutex (shared_lock::unlock): Change errc
+ constant to operation_not_permitted.
+ * testsuite/30_threads/shared_lock/locking/112089.cc: New test.
+
+2023-10-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/20_util/duration/io.cc: Double timeout using
+ dg-timeout-factor.
+ * testsuite/std/time/day/io.cc: Likewise.
+ * testsuite/std/time/format.cc: Likewise.
+ * testsuite/std/time/hh_mm_ss/io.cc: Likewise.
+ * testsuite/std/time/month/io.cc: Likewise.
+ * testsuite/std/time/month_day/io.cc: Likewise.
+ * testsuite/std/time/month_day_last/io.cc: Likewise.
+ * testsuite/std/time/month_weekday/io.cc: Likewise.
+ * testsuite/std/time/month_weekday_last/io.cc: Likewise.
+ * testsuite/std/time/weekday/io.cc: Likewise.
+ * testsuite/std/time/weekday_indexed/io.cc: Likewise.
+ * testsuite/std/time/weekday_last/io.cc: Likewise.
+ * testsuite/std/time/year/io.cc: Likewise.
+ * testsuite/std/time/year_month/io.cc: Likewise.
+ * testsuite/std/time/year_month_day/io.cc: Likewise.
+ * testsuite/std/time/year_month_day_last/io.cc: Likewise.
+ * testsuite/std/time/year_month_weekday/io.cc: Likewise.
+ * testsuite/std/time/year_month_weekday_last/io.cc: Likewise.
+ * testsuite/std/time/zoned_time/io.cc: Likewise.
+
+2023-10-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/111936
+ * src/libbacktrace/Makefile.am: Add -prefer-pic to libtool
+ compile commands.
+ * src/libbacktrace/Makefile.in: Regenerate.
+
+2023-10-24 Paul M. Bendixen <paulbendixen@gmail.com>
+
+ * include/Makefile.am: Move cstdarg, cstdalign and cstdbool to
+ freestanding.
+ * include/Makefile.in: Regenerate.
+
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+ * src/Makefile.am: Handle Darwin rpaths.
+ * src/Makefile.in: Regenerate.
+
2023-10-21 Jonathan Wakely <jwakely@redhat.com>
* include/bits/basic_string.h (_M_init_local_buf()): New
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index 9fab8be..986e0c5 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -79,6 +79,10 @@ GLIBCXX_8.0 {
# thread/mutex/condition_variable/future
__once_proxy;
+ # targets using emutls
+ __emutls_v._ZSt3__811__once_call;
+ __emutls_v._ZSt3__815__once_callable;
+
# std::__convert_to_v
_ZNSt3__814__convert_to_v*;
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 9c71c75..6209f39 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -850,6 +850,9 @@ c_base_builddir = .
c_base_freestanding = \
${c_base_srcdir}/cfloat \
${c_base_srcdir}/climits \
+ ${c_base_srcdir}/cstdalign \
+ ${c_base_srcdir}/cstdarg \
+ ${c_base_srcdir}/cstdbool \
${c_base_srcdir}/cstddef \
${c_base_srcdir}/cstdint \
${c_base_srcdir}/cstdlib
@@ -870,9 +873,6 @@ c_base_headers = \
${c_base_srcdir}/cmath \
${c_base_srcdir}/csetjmp \
${c_base_srcdir}/csignal \
- ${c_base_srcdir}/cstdalign \
- ${c_base_srcdir}/cstdarg \
- ${c_base_srcdir}/cstdbool \
${c_base_srcdir}/cstdio \
${c_base_srcdir}/cstring \
${c_base_srcdir}/ctgmath \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index d2c95ee..596fa0d 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -1195,6 +1195,9 @@ c_base_builddir = .
c_base_freestanding = \
${c_base_srcdir}/cfloat \
${c_base_srcdir}/climits \
+ ${c_base_srcdir}/cstdalign \
+ ${c_base_srcdir}/cstdarg \
+ ${c_base_srcdir}/cstdbool \
${c_base_srcdir}/cstddef \
${c_base_srcdir}/cstdint \
${c_base_srcdir}/cstdlib
@@ -1213,9 +1216,6 @@ c_base_freestanding = \
@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cmath \
@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/csetjmp \
@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/csignal \
-@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cstdalign \
-@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cstdarg \
-@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cstdbool \
@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cstdio \
@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cstring \
@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/ctgmath \
diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc++-v3/include/std/shared_mutex
index 4f236a1..f205c36 100644
--- a/libstdc++-v3/include/std/shared_mutex
+++ b/libstdc++-v3/include/std/shared_mutex
@@ -820,7 +820,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
unlock()
{
if (!_M_owns)
- __throw_system_error(int(errc::resource_deadlock_would_occur));
+ __throw_system_error(int(errc::operation_not_permitted));
_M_pm->unlock_shared();
_M_owns = false;
}
diff --git a/libstdc++-v3/src/experimental/contract.cc b/libstdc++-v3/src/experimental/contract.cc
index 504a6c0..39ad4bd 100644
--- a/libstdc++-v3/src/experimental/contract.cc
+++ b/libstdc++-v3/src/experimental/contract.cc
@@ -67,3 +67,12 @@ handle_contract_violation (const std::experimental::contract_violation &violatio
std::cerr << std::endl;
#endif
}
+
+#if _GLIBCXX_INLINE_VERSION
+// The compiler expects the contract_violation class to be in an unversioned
+// namespace, so provide a forwarding function with the expected symbol name.
+extern "C" void
+_Z25handle_contract_violationRKNSt12experimental18contract_violationE
+(const std::experimental::contract_violation &violation)
+{ handle_contract_violation(violation); }
+#endif
diff --git a/libstdc++-v3/src/libbacktrace/Makefile.am b/libstdc++-v3/src/libbacktrace/Makefile.am
index 492d3b6..e3cede9 100644
--- a/libstdc++-v3/src/libbacktrace/Makefile.am
+++ b/libstdc++-v3/src/libbacktrace/Makefile.am
@@ -49,9 +49,13 @@ WARN_FLAGS = -W -Wall -Wwrite-strings -Wmissing-format-attribute \
-Wcast-qual
C_WARN_FLAGS = $(WARN_FLAGS) -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wno-unused-but-set-variable
CXX_WARN_FLAGS = $(WARN_FLAGS) -Wno-unused-parameter
-AM_CFLAGS = $(C_WARN_FLAGS)
+AM_CFLAGS = \
+ $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+ $(C_WARN_FLAGS)
AM_CFLAGS += $(EXTRA_CFLAGS)
-AM_CXXFLAGS = $(CXX_WARN_FLAGS) -fno-rtti -fno-exceptions
+AM_CXXFLAGS = \
+ $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+ $(CXX_WARN_FLAGS) -fno-rtti -fno-exceptions
AM_CXXFLAGS += $(EXTRA_CXXFLAGS)
obj_prefix = std_stacktrace
diff --git a/libstdc++-v3/src/libbacktrace/Makefile.in b/libstdc++-v3/src/libbacktrace/Makefile.in
index a85c6d1..ce80d24 100644
--- a/libstdc++-v3/src/libbacktrace/Makefile.in
+++ b/libstdc++-v3/src/libbacktrace/Makefile.in
@@ -472,9 +472,10 @@ libstdc___libbacktrace_la_CPPFLAGS = \
C_WARN_FLAGS = $(WARN_FLAGS) -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wno-unused-but-set-variable
CXX_WARN_FLAGS = $(WARN_FLAGS) -Wno-unused-parameter
-AM_CFLAGS = $(C_WARN_FLAGS) $(EXTRA_CFLAGS)
-AM_CXXFLAGS = $(CXX_WARN_FLAGS) -fno-rtti -fno-exceptions \
- $(EXTRA_CXXFLAGS)
+AM_CFLAGS = $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+ $(C_WARN_FLAGS) $(EXTRA_CFLAGS)
+AM_CXXFLAGS = $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+ $(CXX_WARN_FLAGS) -fno-rtti -fno-exceptions $(EXTRA_CXXFLAGS)
obj_prefix = std_stacktrace
# Each FILE.c in SOURCES will be compiled to SHORTNAME-FILE.o
diff --git a/libstdc++-v3/testsuite/20_util/duration/io.cc b/libstdc++-v3/testsuite/20_util/duration/io.cc
index a652a34..d2b9de7 100644
--- a/libstdc++-v3/testsuite/20_util/duration/io.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/io.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++20 } }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/112089.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/112089.cc
new file mode 100644
index 0000000..432c175
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/112089.cc
@@ -0,0 +1,23 @@
+// { dg-do run { target c++14 } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+// PR libstdc++/112089 shared_lock::unlock should throw operation_not_permitted
+
+int main()
+{
+ std::shared_lock<std::shared_timed_mutex> l;
+ try
+ {
+ l.unlock();
+ VERIFY( false );
+ }
+ catch (const std::system_error& e)
+ {
+ VERIFY( e.code() == std::errc::operation_not_permitted );
+ }
+}
diff --git a/libstdc++-v3/testsuite/std/time/day/io.cc b/libstdc++-v3/testsuite/std/time/day/io.cc
index cf5cd34..3454657 100644
--- a/libstdc++-v3/testsuite/std/time/day/io.cc
+++ b/libstdc++-v3/testsuite/std/time/day/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/format.cc b/libstdc++-v3/testsuite/std/time/format.cc
index 97035e2..d6e3583 100644
--- a/libstdc++-v3/testsuite/std/time/format.cc
+++ b/libstdc++-v3/testsuite/std/time/format.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++20 } }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc b/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc
index e431f0c..8eb8042 100644
--- a/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc
+++ b/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++20 } }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/month/io.cc b/libstdc++-v3/testsuite/std/time/month/io.cc
index fb1c642..7e80a53 100644
--- a/libstdc++-v3/testsuite/std/time/month/io.cc
+++ b/libstdc++-v3/testsuite/std/time/month/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/month_day/io.cc b/libstdc++-v3/testsuite/std/time/month_day/io.cc
index 4dafbb2..30aa588 100644
--- a/libstdc++-v3/testsuite/std/time/month_day/io.cc
+++ b/libstdc++-v3/testsuite/std/time/month_day/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/month_day_last/io.cc b/libstdc++-v3/testsuite/std/time/month_day_last/io.cc
index 4f430d4..c12cee8 100644
--- a/libstdc++-v3/testsuite/std/time/month_day_last/io.cc
+++ b/libstdc++-v3/testsuite/std/time/month_day_last/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/month_weekday/io.cc b/libstdc++-v3/testsuite/std/time/month_weekday/io.cc
index ee841eb..82cac64 100644
--- a/libstdc++-v3/testsuite/std/time/month_weekday/io.cc
+++ b/libstdc++-v3/testsuite/std/time/month_weekday/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/month_weekday_last/io.cc b/libstdc++-v3/testsuite/std/time/month_weekday_last/io.cc
index 96a9ad9..47968d0 100644
--- a/libstdc++-v3/testsuite/std/time/month_weekday_last/io.cc
+++ b/libstdc++-v3/testsuite/std/time/month_weekday_last/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/weekday/io.cc b/libstdc++-v3/testsuite/std/time/weekday/io.cc
index 6f6a037..5ed9028 100644
--- a/libstdc++-v3/testsuite/std/time/weekday/io.cc
+++ b/libstdc++-v3/testsuite/std/time/weekday/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/weekday_indexed/io.cc b/libstdc++-v3/testsuite/std/time/weekday_indexed/io.cc
index 530138e..29255ad 100644
--- a/libstdc++-v3/testsuite/std/time/weekday_indexed/io.cc
+++ b/libstdc++-v3/testsuite/std/time/weekday_indexed/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/weekday_last/io.cc b/libstdc++-v3/testsuite/std/time/weekday_last/io.cc
index de88ad2..6f76922 100644
--- a/libstdc++-v3/testsuite/std/time/weekday_last/io.cc
+++ b/libstdc++-v3/testsuite/std/time/weekday_last/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/year/io.cc b/libstdc++-v3/testsuite/std/time/year/io.cc
index f26162d..6157afa 100644
--- a/libstdc++-v3/testsuite/std/time/year/io.cc
+++ b/libstdc++-v3/testsuite/std/time/year/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/year_month/io.cc b/libstdc++-v3/testsuite/std/time/year_month/io.cc
index 1b58a9e..7bb3442 100644
--- a/libstdc++-v3/testsuite/std/time/year_month/io.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/io.cc b/libstdc++-v3/testsuite/std/time/year_month_day/io.cc
index 636b305..15c5a9f 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_day/io.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_day/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/year_month_day_last/io.cc b/libstdc++-v3/testsuite/std/time/year_month_day_last/io.cc
index 0dcc1df..3241536 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_day_last/io.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_day_last/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/year_month_weekday/io.cc b/libstdc++-v3/testsuite/std/time/year_month_weekday/io.cc
index 77fec80c..65baf1d 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_weekday/io.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_weekday/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/year_month_weekday_last/io.cc b/libstdc++-v3/testsuite/std/time/year_month_weekday_last/io.cc
index 386f868..17f2244 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_weekday_last/io.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_weekday_last/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/std/time/zoned_time/io.cc b/libstdc++-v3/testsuite/std/time/zoned_time/io.cc
index 6f3ed4d..376b273 100644
--- a/libstdc++-v3/testsuite/std/time/zoned_time/io.cc
+++ b/libstdc++-v3/testsuite/std/time/zoned_time/io.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++20 } }
// { dg-require-effective-target cxx11_abi }
+// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog
index a1c115e..5c93ba9 100644
--- a/libvtv/ChangeLog
+++ b/libvtv/ChangeLog
@@ -1,3 +1,8 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog
index b900236..809c18f 100644
--- a/lto-plugin/ChangeLog
+++ b/lto-plugin/ChangeLog
@@ -1,3 +1,8 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.
diff --git a/zlib/ChangeLog b/zlib/ChangeLog
index 3f97261..0b7ddfd 100644
--- a/zlib/ChangeLog
+++ b/zlib/ChangeLog
@@ -1,3 +1,8 @@
+2023-10-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regenerate.
+ * configure.ac: Handle Darwin rpaths.
+
2023-08-07 Nick Alcock <nick.alcock@oracle.com>
* configure: Regenerate.