aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog315
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog422
-rw-r--r--gcc/ada/aspects.ads5
-rw-r--r--gcc/ada/atree.adb82
-rw-r--r--gcc/ada/checks.adb7
-rw-r--r--gcc/ada/cstand.adb12
-rw-r--r--gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst3
-rw-r--r--gcc/ada/einfo-utils.adb15
-rw-r--r--gcc/ada/einfo.ads40
-rw-r--r--gcc/ada/errout.adb27
-rw-r--r--gcc/ada/erroutc.adb49
-rw-r--r--gcc/ada/exp_aggr.adb7
-rw-r--r--gcc/ada/exp_attr.adb47
-rw-r--r--gcc/ada/exp_ch11.adb4
-rw-r--r--gcc/ada/exp_ch3.adb30
-rw-r--r--gcc/ada/exp_ch4.adb68
-rw-r--r--gcc/ada/exp_ch6.adb70
-rw-r--r--gcc/ada/exp_ch6.ads6
-rw-r--r--gcc/ada/exp_ch7.adb87
-rw-r--r--gcc/ada/exp_dbug.ads19
-rw-r--r--gcc/ada/exp_strm.adb8
-rw-r--r--gcc/ada/exp_unst.adb2
-rw-r--r--gcc/ada/exp_util.adb326
-rw-r--r--gcc/ada/fname.adb13
-rw-r--r--gcc/ada/freeze.adb3
-rw-r--r--gcc/ada/gen_il-fields.ads11
-rw-r--r--gcc/ada/gen_il-gen-gen_entities.adb7
-rw-r--r--gcc/ada/gen_il-gen-gen_nodes.adb38
-rw-r--r--gcc/ada/gen_il-gen.adb47
-rw-r--r--gcc/ada/gen_il-gen.ads12
-rw-r--r--gcc/ada/gen_il-internals.adb2
-rw-r--r--gcc/ada/ghost.adb8
-rw-r--r--gcc/ada/gnat_rm.texi5
-rw-r--r--gcc/ada/gnat_ugn.texi4
-rw-r--r--gcc/ada/inline.adb32
-rw-r--r--gcc/ada/libgnat/a-cbmutr.adb4
-rw-r--r--gcc/ada/libgnat/a-cimutr.adb4
-rw-r--r--gcc/ada/libgnat/a-comutr.adb4
-rw-r--r--gcc/ada/libgnat/s-dwalin.adb27
-rw-r--r--gcc/ada/libgnat/s-dwalin.ads11
-rw-r--r--gcc/ada/libgnat/s-stratt.adb17
-rw-r--r--gcc/ada/libgnat/s-stratt.ads2
-rw-r--r--gcc/ada/libgnat/s-stratt__cheri.adb17
-rw-r--r--gcc/ada/libgnat/s-trasym.adb4
-rw-r--r--gcc/ada/libgnat/s-trasym.ads3
-rw-r--r--gcc/ada/libgnat/s-trasym__dwarf.adb164
-rw-r--r--gcc/ada/locales.c30
-rw-r--r--gcc/ada/par-ch12.adb2
-rw-r--r--gcc/ada/par-ch13.adb158
-rw-r--r--gcc/ada/par-ch3.adb11
-rw-r--r--gcc/ada/par-ch6.adb64
-rw-r--r--gcc/ada/par-endh.adb28
-rw-r--r--gcc/ada/par.adb10
-rw-r--r--gcc/ada/rtsfind.ads2
-rw-r--r--gcc/ada/sem_attr.adb156
-rw-r--r--gcc/ada/sem_aux.adb3
-rw-r--r--gcc/ada/sem_ch12.adb177
-rw-r--r--gcc/ada/sem_ch13.adb116
-rw-r--r--gcc/ada/sem_ch3.adb79
-rw-r--r--gcc/ada/sem_ch6.adb181
-rw-r--r--gcc/ada/sem_ch7.adb7
-rw-r--r--gcc/ada/sem_ch8.adb42
-rw-r--r--gcc/ada/sem_disp.adb50
-rw-r--r--gcc/ada/sem_prag.adb2
-rw-r--r--gcc/ada/sem_res.adb28
-rw-r--r--gcc/ada/sem_util.adb163
-rw-r--r--gcc/ada/sem_util.ads22
-rw-r--r--gcc/ada/sinfo.ads68
-rw-r--r--gcc/ada/snames.adb-tmpl9
-rw-r--r--gcc/ada/snames.ads-tmpl7
-rw-r--r--gcc/ada/sprint.adb4
-rw-r--r--gcc/ada/style.adb14
-rw-r--r--gcc/ada/treepr.adb2
-rw-r--r--gcc/analyzer/checker-event.cc32
-rw-r--r--gcc/analyzer/checker-event.h10
-rw-r--r--gcc/c/ChangeLog18
-rw-r--r--gcc/c/c-decl.cc4
-rw-r--r--gcc/c/c-parser.cc33
-rw-r--r--gcc/c/c-tree.h2
-rw-r--r--gcc/c/c-typeck.cc35
-rw-r--r--gcc/config/aarch64/aarch64-option-extensions.def12
-rw-r--r--gcc/config/aarch64/aarch64.cc2
-rw-r--r--gcc/config/arc/simdext.md14
-rw-r--r--gcc/config/avr/avr.cc43
-rw-r--r--gcc/config/avr/avr.md67
-rw-r--r--gcc/config/i386/i386-expand.cc748
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.cc14
-rw-r--r--gcc/config/i386/i386.md44
-rw-r--r--gcc/config/loongarch/lasx.md69
-rw-r--r--gcc/config/loongarch/lasxintrin.h156
-rw-r--r--gcc/config/loongarch/loongarch-builtins.cc90
-rw-r--r--gcc/config/loongarch/loongarch-c.cc1
-rw-r--r--gcc/config/loongarch/loongarch-ftypes.def12
-rw-r--r--gcc/config/loongarch/loongarch-protos.h1
-rw-r--r--gcc/config/loongarch/loongarch.cc101
-rw-r--r--gcc/config/loongarch/loongarch.md37
-rw-r--r--gcc/config/loongarch/predicates.md5
-rw-r--r--gcc/config/riscv/bitmanip.md2
-rw-r--r--gcc/config/riscv/riscv-protos.h5
-rw-r--r--gcc/config/riscv/riscv-vsetvl.cc8
-rw-r--r--gcc/config/riscv/riscv.cc362
-rw-r--r--gcc/config/riscv/thead.md18
-rw-r--r--gcc/config/riscv/vector.md2
-rw-r--r--gcc/config/xtensa/xtensa.md29
-rwxr-xr-xgcc/configure129
-rw-r--r--gcc/cp/ChangeLog34
-rw-r--r--gcc/cp/decl2.cc7
-rw-r--r--gcc/cp/module.cc41
-rw-r--r--gcc/cp/name-lookup.cc19
-rw-r--r--gcc/cp/parser.cc4
-rw-r--r--gcc/diagnostics/paths.cc16
-rw-r--r--gcc/diagnostics/paths.h13
-rw-r--r--gcc/doc/extend.texi399
-rw-r--r--gcc/doc/tree-ssa.texi13
-rw-r--r--gcc/fortran/ChangeLog13
-rw-r--r--gcc/fortran/resolve.cc48
-rw-r--r--gcc/gimple.cc22
-rw-r--r--gcc/lra-constraints.cc5
-rw-r--r--gcc/m2/ChangeLog33
-rw-r--r--gcc/m2/gm2-compiler/M2StackSpell.mod59
-rw-r--r--gcc/m2/gm2-compiler/P1Build.bnf17
-rw-r--r--gcc/m2/gm2-compiler/P1SymBuild.mod6
-rw-r--r--gcc/m2/gm2-compiler/SymbolTable.def18
-rw-r--r--gcc/m2/gm2-compiler/SymbolTable.mod80
-rw-r--r--gcc/simplify-rtx.cc112
-rw-r--r--gcc/ssa-iterators.h30
-rw-r--r--gcc/symtab.cc2
-rw-r--r--gcc/testsuite/ChangeLog293
-rw-r--r--gcc/testsuite/g++.dg/abi/param2.C2
-rw-r--r--gcc/testsuite/g++.dg/analyzer/exception-path-1-sarif.py22
-rw-r--r--gcc/testsuite/g++.dg/analyzer/exception-path-1.C9
-rw-r--r--gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2-sarif.py23
-rw-r--r--gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2.C9
-rw-r--r--gcc/testsuite/g++.dg/lookup/koenig16.C22
-rw-r--r--gcc/testsuite/g++.dg/modules/adl-11_a.C21
-rw-r--r--gcc/testsuite/g++.dg/modules/adl-11_b.C12
-rw-r--r--gcc/testsuite/g++.dg/modules/builtin-9_a.C16
-rw-r--r--gcc/testsuite/g++.dg/modules/builtin-9_b.C8
-rw-r--r--gcc/testsuite/g++.dg/modules/clone-5_a.C25
-rw-r--r--gcc/testsuite/g++.dg/modules/clone-5_b.C9
-rw-r--r--gcc/testsuite/g++.dg/modules/convop-2_a.H10
-rw-r--r--gcc/testsuite/g++.dg/modules/convop-2_b.C5
-rw-r--r--gcc/testsuite/g++.dg/modules/inst-6_a.C14
-rw-r--r--gcc/testsuite/g++.dg/modules/inst-6_b.C12
-rw-r--r--gcc/testsuite/g++.dg/modules/internal-16.C30
-rw-r--r--gcc/testsuite/g++.dg/modules/namespace-15_a.C9
-rw-r--r--gcc/testsuite/g++.dg/modules/namespace-15_b.C5
-rw-r--r--gcc/testsuite/g++.target/aarch64/mv-cpu-features.C8
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct+union-1.cc17
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct+union-2.cc20
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct+union-3.cc27
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct+union-4.cc30
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-1.cc15
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-10.cc18
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-11.cc23
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-12.cc21
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-2.cc18
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-3.cc21
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-4.cc24
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-5.cc15
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-6.cc18
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-7.cc21
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-8.cc24
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-struct-9.cc15
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-union-1.cc15
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-union-2.cc18
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-union-3.cc21
-rw-r--r--gcc/testsuite/g++.target/riscv/abi/empty-union-4.cc24
-rw-r--r--gcc/testsuite/g++.target/riscv/riscv.exp1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-3-sarif.py23
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-3.c9
-rw-r--r--gcc/testsuite/gcc.dg/compat/pr83487-1_x.c1
-rw-r--r--gcc/testsuite/gcc.dg/compat/pr83487-1_y.c1
-rw-r--r--gcc/testsuite/gcc.dg/compat/pr83487-2_x.c1
-rw-r--r--gcc/testsuite/gcc.dg/compat/pr83487-2_y.c1
-rw-r--r--gcc/testsuite/gcc.dg/fold-vecperm-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/gnu-compoundlit-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/gnu-compoundlit-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/pr68090.c7
-rw-r--r--gcc/testsuite/gcc.dg/pr97986-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr97986-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr28814.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr122475.c13
-rw-r--r--gcc/testsuite/gcc.dg/vla-init-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vla-init-5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/fmv_priority.in23
-rw-r--r--gcc/testsuite/gcc.target/aarch64/fmv_priority1.c22
-rw-r--r--gcc/testsuite/gcc.target/aarch64/fmv_priority2.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c32
-rw-r--r--gcc/testsuite/gcc.target/arc/movv2hi-be.c32
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr84211-fuse-move-1.c3
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr92606.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-10.c105
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-11a.c79
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-11b.c74
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-11c.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-12.c41
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-13.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-14.c90
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-15.c114
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-1a.c123
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-1b.c98
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-1c.c94
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-1d.c226
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-2a.c165
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-2b.c173
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-2c.c184
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-2d.c195
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-3a.c133
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-3b.c140
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-3c.c151
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-4a.c123
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-4b.c130
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-4c.c141
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-5a.c109
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-5b.c120
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-5c.c130
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-6.c52
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-7.c42
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-8.c90
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-memmove-9.c63
-rw-r--r--gcc/testsuite/gcc.target/i386/pr122518.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/pr122534.c15
-rw-r--r--gcc/testsuite/gcc.target/loongarch/and-large-immediate-opt.c14
-rw-r--r--gcc/testsuite/gcc.target/loongarch/extendsidi2-combine.c13
-rw-r--r--gcc/testsuite/gcc.target/loongarch/imm-load.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/lasx-xvpermi_q-opt.c44
-rw-r--r--gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c23
-rw-r--r--gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c17
-rw-r--r--gcc/testsuite/gcc.target/loongarch/mulh_wu.c10
-rw-r--r--gcc/testsuite/gcc.target/loongarch/spill-less.c14
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vec_pack_unpack_256.c18
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-builtin.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256-result.c68
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256.c92
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128-result.c69
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128.c86
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256-result.c97
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256.c95
-rw-r--r--gcc/testsuite/gcc.target/powerpc/rlwimi-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-1.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-2.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-3.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-4.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-1.c15
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-10.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-11.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-12.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-2.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-3.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-4.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-5.c15
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-6.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-7.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-8.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-struct-9.c15
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-union-1.c15
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-union-2.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-union-3.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/abi/empty-union-4.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr52345.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr67731.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/riscv.exp2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122321.c150
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr119115.c2
-rw-r--r--gcc/testsuite/gcc.target/sh/pr67731.c25
-rw-r--r--gcc/testsuite/gcc.target/sparc/cbcond-1.c4
-rw-r--r--gcc/testsuite/gcc.target/sparc/cbcond-2.c4
-rw-r--r--gcc/testsuite/gcc.target/sparc/overflow-3.c2
-rw-r--r--gcc/testsuite/gcc.target/sparc/overflow-4.c4
-rw-r--r--gcc/testsuite/gcc.target/sparc/overflow-5.c2
-rw-r--r--gcc/testsuite/gcc.target/sparc/small-struct-1.c4
-rw-r--r--gcc/testsuite/gfortran.dg/pr122513-2.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/pr122513.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/pure_result.f9049
-rw-r--r--gcc/testsuite/gm2.dg/spell/iso/fail/badimport2.mod12
-rw-r--r--gcc/testsuite/gm2.dg/spell/iso/fail/badimport3.mod17
-rw-r--r--gcc/testsuite/gm2.dg/spell/iso/fail/badimport4.mod17
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst15.adb27
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst15_pkg-g.ads8
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst15_pkg.ads37
-rw-r--r--gcc/testsuite/gnat.dg/specs/abstract1.ads9
-rw-r--r--gcc/testsuite/gnat.dg/specs/unknown_discr1.ads23
-rw-r--r--gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-child.ads17
-rw-r--r--gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-g.ads21
-rw-r--r--gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-inst.ads3
-rw-r--r--gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg.ads9
-rw-r--r--gcc/testsuite/gnat.dg/use_type4.adb29
-rw-r--r--gcc/testsuite/gnat.dg/vect19.adb17
-rw-r--r--gcc/testsuite/gnat.dg/vect19.ads7
-rw-r--r--gcc/testsuite/gnat.dg/vect19_pkg.adb12
-rw-r--r--gcc/testsuite/gnat.dg/vect19_pkg.ads9
-rw-r--r--gcc/tree-vect-loop.cc4
296 files changed, 11271 insertions, 1569 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 00f62e1..8091f67 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,318 @@
+2025-11-03 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/122534
+ * config/i386/i386.md (@test<mode>_ccno_1):
+ Use <general_szext_operand> as operand 1 predicate.
+ (testqi_ccz_1): Use general_operand as operand 1 predicate.
+ (*testdi_1): Use x86_64_szext_general_operand as operand 1 predicate.
+ (*testqi_1_maybe_si): Use general_operand as operand 1 predicate.
+ Add (n,*a) alternative to allow UV pairing for pentium processor.
+ (*test<mode>_1): Use <general_operand> as operand 1 predicate.
+
+2025-11-03 Sam James <sam@gentoo.org>
+
+ * configure: Regenerate.
+
+2025-11-03 Jeff Law <jlaw@ventanamicro.com>
+
+ PR rtl-optimization/122536
+ * simplify-rtx.cc (simplify_context::simplify_binary_operation_1): Fix
+ guard against variable bit extracts in recent change.
+
+2025-11-03 Thomas Schwinge <tschwinge@baylibre.com>
+
+ PR ipa/122512
+ * symtab.cc: Fix 'static_assert'.
+
+2025-11-03 Loeka Rogge <loeka@synopsys.com>
+
+ * config/arc/simdext.md(movv2hi_insn): Change order for movv2hi
+ for big-endian.
+
+2025-11-03 Tobias Burnus <tburnus@baylibre.com>
+
+ PR libgomp/122281
+ PR middle-end/105001
+ * gimple.cc (gimple_copy): Add missing unshare_expr for
+ GIMPLE_OMP_ATOMIC_LOAD and GIMPLE_OMP_ATOMIC_STORE.
+
+2025-11-03 Alfie Richards <alfie.richards@arm.com>
+
+ PR c/122202
+ * doc/extend.texi (target function attribute): Update to describe FMV
+ behaviour.
+ (target_version function attribute): New section.
+ (target_clones attribute): Update to descrbe new behaviour with
+ target_version.
+ (Function Multiversioning): Update to discuss both target_version and
+ target based FMV.
+
+2025-11-03 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/riscv.cc (riscv_flatten_aggregate_field): Skip
+ empty unions and zero-length arrays when flattening aggregate
+ fields for ABI classification.
+ (riscv_pass_aggregate_in_fpr_pair_p): Refactor to use separate
+ field parsing and emit ABI change warning for affected types.
+ (riscv_pass_aggregate_in_fpr_and_gpr_p): Likewise.
+
+2025-11-03 Alfie Richards <alfie.richards@arm.com>
+
+ * config/aarch64/aarch64-option-extensions.def (dit): New fmv feature.
+ (dpb): New fmv feature.
+ (dpb2): New fmv feature.
+ (memtag): Change to also define an FMV feature.
+ (ssbs): Change to also define an FMV feature.
+ (bti): New fmv feature.
+ * config/aarch64/aarch64.cc (FEAT_SSBS): Add macro.
+ (FEAT_MEMTAG): Ditto.
+
+2025-11-03 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
+
+ * config/xtensa/xtensa.md (int_iterator ANY_ROUND):
+ Specify "flag_unsafe_math_optimizations" in the condition of the
+ UNSPEC_ROUND element.
+ (int_attr c_round): Remove.
+ (l<m_round>sfsi2, *l<m_round>sfsi2_2x, *l<m_round>sfsi2_scaled):
+ Remove " && <c_round>" from the conditions.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * config/loongarch/loongarch.cc (loongarch_modes_tieable_p):
+ Make MODE_FLOAT and MODE_INT tieable.
+ * config/loongarch/loongarch.md: Adjust constraints.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * config/loongarch/loongarch.md
+ (and_load_zero_extend<mode>): New combiner.
+ * config/loongarch/predicates.md
+ (mask_operand): New predicate.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * config/loongarch/lasx.md (lasx_xvpermi_q_<LASX:mode>):
+ Add new splitter for optimization.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * config/loongarch/loongarch-protos.h
+ (loongarch_use_bstrins_bstrpick_for_and): New proto.
+ * config/loongarch/loongarch.cc
+ (loongarch_use_bstrins_bstrpick_for_and): Decide whether
+ to optimize.
+ (loongarch_rtx_costs): Adjust the cost of AND operation.
+ * config/loongarch/loongarch.md
+ (bstrins_bstrpick_for_and_imm<mode>): New insn_and_split.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * config/loongarch/loongarch.cc
+ (loongarch_can_change_mode_class): Support for conversion
+ between scalar INT and scalar FP.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * config/loongarch/loongarch.cc (loongarch_rtx_costs):
+ Correct the cost of mulh.{w[u]|d[u]}.
+
+2025-11-03 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/122475
+ * tree-vect-loop.cc (vectorizable_reduction): Check for neutral_op.
+
+2025-11-03 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/90262
+ * config/i386/i386-expand.cc (ix86_expand_unroll_movmem): New.
+ (ix86_expand_n_move_movmem): Likewise.
+ (ix86_expand_load_movmem): Likewise.
+ (ix86_expand_store_movmem): Likewise.
+ (ix86_expand_n_overlapping_move_movmem): Likewise.
+ (ix86_expand_less_move_movmem): Likewise.
+ (ix86_expand_movmem): Likewise.
+ * config/i386/i386-protos.h (ix86_expand_movmem): Likewise.
+ * config/i386/i386.md (movmem<mode>): Likewise.
+
+2025-11-03 Shreya Munnangi <smunnangi1@ventanamicro.com>
+
+ PR target/52345
+ * simplify-rtx.cc (simplify_relational_operation_1): Optimize boolean
+ IOR equality tests.
+
+2025-11-03 chenxiaolong <chenxiaolong@loongson.cn>
+
+ * config/loongarch/lasx.md (vec_cast<mode>): New template
+ implemention.
+ (vec_insert_lo_<mode>): Dito.
+ (vec_insert_hi_<mode>): Dito.
+ * config/loongarch/lasxintrin.h (defined): Test for adding
+ the builtin function.
+ (__lasx_cast_128_s): Dito.
+ (__lasx_cast_128_d): Dito.
+ (__lasx_cast_128): Dito.
+ (__lasx_concat_128_s): Dito.
+ (__lasx_concat_128_d): Dito.
+ (__lasx_concat_128): Dito.
+ (__lasx_extract_128_lo_s): Dito.
+ (__lasx_extract_128_hi_s): Dito.
+ (__lasx_extract_128_lo_d): Dito.
+ (__lasx_extract_128_hi_d): Dito.
+ (__lasx_extract_128_lo): Dito.
+ (__lasx_extract_128_hi): Dito.
+ (__lasx_insert_128_lo_s): Dito.
+ (__lasx_insert_128_hi_s): Dito.
+ (__lasx_insert_128_lo_d): Dito.
+ (__lasx_insert_128_hi_d): Dito.
+ (__lasx_insert_128_lo): Dito.
+ (__lasx_insert_128_hi): Dito.
+ * config/loongarch/loongarch-builtins.cc
+ (CODE_FOR_lasx_extract_128_lo_s): Add builtins and register
+ icode.
+ (CODE_FOR_lasx_extract_128_hi_s): Dito.
+ (CODE_FOR_lasx_extract_128_lo_d): Dito.
+ (CODE_FOR_lasx_extract_128_hi_d): Dito.
+ (CODE_FOR_lasx_extract_128_lo): Dito.
+ (CODE_FOR_lasx_extract_128_hi): Dito.
+ (CODE_FOR_lasx_insert_128_lo_s): Dito.
+ (CODE_FOR_lasx_insert_128_hi_s): Dito.
+ (CODE_FOR_lasx_insert_128_lo_d): Dito.
+ (CODE_FOR_lasx_insert_128_hi_d): Dito.
+ (CODE_FOR_lasx_insert_128_lo): Dito.
+ (CODE_FOR_lasx_insert_128_hi): Dito.
+ (CODE_FOR_lasx_concat_128_s): Dito.
+ (CODE_FOR_lasx_concat_128_d): Dito.
+ (CODE_FOR_lasx_concat_128): Dito.
+ (CODE_FOR_lasx_cast_128_s): Dito.
+ (CODE_FOR_lasx_cast_128_d): Dito.
+ (CODE_FOR_lasx_cast_128): Dito.
+ (loongarch_expand_builtin_direct): For the newly added
+ insertion or extraction, construct the parallel parameter
+ corresponding to the operand.
+ * config/loongarch/loongarch-c.cc
+ (loongarch_update_cpp_builtins): Define
+ __loongarch_asx_sx_conv.
+ * config/loongarch/loongarch-ftypes.def: Declare the type
+ of the builtin function.
+ * doc/extend.texi: Add document description.
+
+2025-11-03 Lulu Cheng <chenglulu@loongson.cn>
+
+ * config/loongarch/loongarch.cc (loongarch_move_integer):
+ No new virtual register is allocated during immediate load.
+
+2025-11-03 Lulu Cheng <chenglulu@loongson.cn>
+
+ PR target/122477
+ * config/loongarch/loongarch.cc
+ (loongarch_split_reduction): Added handling of scalar mode.
+
+2025-11-02 Jeff Law <jlaw@ventanamicro.com>
+
+ * config/riscv/bitmanip.md (rotrsi3): Use the sign extended form
+ for 32 bit rotates on TARGET_64BIT, even for constant counts.
+ * config/riscv/thead.md (th_srrisi3_extended): New pattern.
+ (th_srri<mode>3): Adjust formatting.
+
+2025-11-02 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/122518
+ * config/i386/i386.cc (ix86_canonicalize_comparison): Convert
+ (compare (minus (a b)) a) to (compare (a b)) to
+ match *sub<mode>_3 pattern.
+
+2025-11-02 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/122527
+ * config/avr/avr.cc (avr_load_libgcc_p): Return false if
+ the address-space is not ADDR_SPACE_FLASH.
+ (avr_out_lpm_no_lpmx [addr=REG]): Handle sizes of 3 and 4 bytes.
+
+2025-11-02 Georg-Johann Lay <avr@gjlay.de>
+
+ PR tree-optimization/118012
+ PR tree-optimization/122505
+ * config/avr/avr.md (mulpsi3): Also allow the insn condition
+ in the case where avropt_pr118012 && !AVR_TINY.
+ (*mulpsi3): Handle split for the !AVR_HAVE_MUL case.
+ (*mulpsi3-nomul.libgcc_split, *mulpsi3-nomul.libgcc): New insns.
+
+2025-11-02 Richard Biener <rguenther@suse.de>
+
+ * doc/tree-ssa.texi: Remove outdated info on FOR_EACH_IMM_USE_STMT
+ iteration, clarify SSA operand parts.
+ * ssa-iterators.h: Update toplevel comment.
+
+2025-11-02 Sam James <sam@gentoo.org>
+
+ * .simplify-rtx.cc.swo: Removed.
+
+2025-11-01 Shreya Munnangi <smunnangi1@ventanamicro.com>
+
+ PR target/67731
+ * simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
+ Handle IOR of single bit bitfields from the same object.
+
+2025-11-01 Jeff Law <jlaw@ventanamicro.com>
+
+ * config/riscv/riscv-protos.h (has_vtype_op): Add prototype.
+ (mask_agnostic_p, get_avl, vsetvl_insn_p): Likewise.
+ * config/riscv/riscv-vsetvl.cc (has_vtype_op): No longer static.
+ (vsetvl_insn_p, get_avl_mask_agnostic_p): Likewise.
+ * config/riscv/riscv.cc (struct last_vcofnig): New structure.
+ (clear_vconfig): New function.
+ (compatible_with_last_vconfig, riscv_sched_init): Likewise.
+ (riscv_sched_reorder): Likewise.
+ (TARGET_SCHED_INIT, TARGET_SCHED_REORDER): Define.
+ * config/riscv/vector.md ("*mov<mode>"): Set has_vtype_op, has_vl_op
+ attributes.
+ * .simplify-rtx.cc.swo: New file.
+
+2025-11-01 Jeff Law <jlaw@ventanamicro.com>
+
+ PR rtl-optimization/122321
+ * lra-constraints.cc (update_equiv): Make sure REGNO is in
+ ira_reg_equiv before trying to update ira_reg_equiv.
+
+2025-11-01 Martin Uecker <uecker@tugraz.at>
+
+ * doc/extend.texi: Document new extension.
+
+2025-11-01 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
+
+ * config/xtensa/xtensa.md (negsf2):
+ Add another insn pattern that is valid when TARGET_DENSITY is
+ enabled and both the source and destination are address registers.
+
+2025-11-01 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
+
+ * config/xtensa/xtensa.md
+ (c_enum "unspec", int_iterator ANY_ROUND): Add UNSPEC_ROUND.
+ (int_attr m_round): Add a pair of UNSPEC_ROUND and "round".
+ (int_attr c_round): New integer iterator attribute, that expands
+ to "flag_unsafe_math_optimizations" in the case of UNSPEC_ROUND,
+ and to "1" otherwise.
+ (l<m_round>sfsi2, *l<m_round>sfsi2_2x, *l<m_round>sfsi2_scaled):
+ Append " && <c_round>" to the conditions.
+
+2025-11-01 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
+
+ * config/xtensa/xtensa.md (*fix<s_fix>_truncsfsi2_scaled,
+ *float<s_float>sisf2_scaled, *l<m_round>sfsi2_scaled):
+ Remove 'F'-constraint.
+
+2025-11-01 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ PR ipa/122512
+ * cgraph.h (enum toplevel_type): Add TOPLEVEL_MAX. Add comment
+ about keeping toplevel_type_names in sync.
+ * symtab.cc (symtab_type_names): Rename to ...
+ (toplevel_type_names): Add new types and add an assert about
+ the size.
+ (symtab_node::get_symtab_type_string): Use toplevel_type_names
+ instead of symtab_type_names.
+ (symtab_node::dump_base): Likewise.
+
2025-10-31 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
PR tree-optimization/122437
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 38eec11..23733dc 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20251101
+20251104
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index f91fc31..c99021a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,425 @@
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/78175
+ * sem_ch12.adb (Hide_Current_Scope): Deal with a transient scope
+ as current scope.
+ (Remove_Parent): Likewise.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/55324
+ * par-ch3.adb (P_Type_Declaration): Give a better error message
+ for illegal "abstract" in a type derivation.
+
+2025-11-03 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_util.adb (Get_Current_Value_Condition): Guard against orphaned
+ references in rewritten if-expressions.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_rm/representation_clauses_and_pragmas.rst (Address
+ Clauses): Adjust description of alignment checks.
+ * sem_ch13.adb (Address_Clause_Check_Record): Remove now unused
+ Alignment_Checks_Suppressed component.
+ (Alignment_Checks_Suppressed): Delete.
+ (Analyze_Attribute_Definition_Clause) <Attribute_Alignment>: Do not
+ consider the status of range checks to decide whether to generate an
+ alignment check. Always generate it if an alignment clause is also
+ given for the entity.
+ <Attribute_Alignment>: Generate an alignment check if an address
+ clause is also given for the entity.
+ (Register_Address_Clause_Check): Adjust for above removal.
+ (Validate_Address_Clauses): Test the Check_Address_Alignment flag
+ on the clause to decide whether to give the warning.
+ * gnat_rm.texi: Regenerate.
+ * gnat_ugn.texi: Regenerate.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.adb (Apply_Address_Clause_Check): Adjust self-reference in
+ the opening comment.
+
+2025-11-03 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_util.adb (Find_In_Enclosing_Context): Refactor from handling of
+ IF statements.
+ (Get_Current_Value_Condition): Reuse IF code for WHILE statements.
+
+2025-11-03 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_util.adb (Get_Current_Value_Condition): Rewrite to not rely on
+ Sloc and End_Span of an if statement.
+
+2025-11-03 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Update_Semantic_Fields): Preserve tree structure when
+ copying scalar range of a discrete type.
+
+2025-11-03 Piotr Trojanek <trojanek@adacore.com>
+
+ * inline.adb (Process_Sloc): Remove.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/61127
+ * sem_ch12.adb (Associations.Match_Positional): Remove the always
+ false condition that guards the error on a positional box.
+
+2025-11-03 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_disp.adb (Check_Dispatching_Call): Remove "elsif" that does error
+ checking for abstract tag-indeterminate calls (seems to be no longer
+ needed).
+
+2025-11-03 Marc Poulhiès <poulhies@adacore.com>
+
+ * exp_ch7.adb (Fixup_Inner_Scopes): Adjust to handle N_Freeze_Entity nodes.
+ * exp_unst.adb (Get_Level): Assert when the function didn't find the
+ nested level (indicates that inner sub has scope pointing higher in
+ the stack)
+
+2025-11-03 Ronan Desplanques <desplanques@adacore.com>
+
+ * fname.adb (Is_Predefined_File_Name): Tweak.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * gen_il-gen-gen_nodes.adb (N_Exception_Declaration):
+ Change Expression from Sm to Sy, to match other Expression fields.
+ * gen_il-gen.adb (Setter_Needs_Parent):
+ Expression no longer needs to be a special case.
+ (Check_For_Syntactic_Field_Mismatch):
+ Do not exempt Expression from the Sy/Sm mixing rule.
+ This was the last such case, so remove all the exemption code.
+ * gen_il-gen.ads: Update comments to match new code.
+ * sinfo.ads (N_Exception_Declaration):
+ Document the meaning of the Expression field, because it
+ doesn't follow from the RM syntax of exception_declaration.
+ * exp_ch11.adb: Minor comment fixes.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch13.adb (Analyze_Attribute_Definition_Clause)
+ <Attribute_Size>: Tweak wording of existing error message for the
+ size of all elementary objects. Move error handling for aliased
+ objects into the block for objects and give a similar error for
+ (nonaliased) floating-point objects.
+
+2025-11-03 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_attr.adb (Rewrite_Attribute_Proc_Call)<Attribute_Put_Image>:
+ Fix call to Analyze.
+
+2025-11-03 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_attr.adb (Resolve_Attribute): Remove rewriting of a slice
+ address expression.
+
+2025-11-03 Viljar Indus <indus@adacore.com>
+
+ * libgnat/a-cbmutr.adb (Put_Image): Fix the condition and starting point
+ for printing the tree.
+ * libgnat/a-cimutr.adb (Put_Image): Likewise.
+ * libgnat/a-comutr.adb (Put_Image): Likewise.
+
+2025-11-03 Viljar Indus <indus@adacore.com>
+
+ * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Avoid disabling
+ the expander for ignored ghost regions if Codepeer_Mode is active.
+ * sem_ch7.adb (Analyze_Package_Body_Helper): Likewise.
+ * freeze.adb (Freeze_Entity): Avoid triggering special freezing
+ action for entities within ignored ghost regions in Codepeer_Mode.
+
+2025-11-03 Viljar Indus <indus@adacore.com>
+
+ * ghost.adb (Is_Ok_Context): consider ghost prefix to always
+ be a valid ghost context.
+
+2025-11-03 Denis Mazzucato <mazzucato@adacore.com>
+
+ * errout.adb (Set_Msg_Node): Support N_Attribute_Reference and
+ nodes that denotes direct attribute definitions.
+ * exp_dbug.ads: Description for the encoding of direct attribute
+ definitions as tick are hard to deal in entity names.
+ * erroutc.adb
+ (Set_Msg_Insertion_Name): Replace underscore between prefix and
+ attribute name in direct attribute definitions; at this point we
+ lost the semantic information of node type and we resort to match
+ the string name as described in exp_dbug.adb.
+ * exp_aggr.adb (Convert_To_Positional): Use Needs_Construction and
+ Has_Default_Constructor.
+ * exp_ch3.adb (Build_Record_Init_Proc)
+ (Expand_N_Object_Declaration): Likewise.
+ * exp_attr.adb (Expand_N_Attribute_Reference): Likewise.
+ * exp_ch4.adb (Expand_N_Allocator): Likewise.
+ * exp_ch6.adb
+ (Prepend_Constructor_Procedure_Prologue): Use
+ Is_Constructor_Procedure.
+ (Make_Parent_Constructor_Call): Use
+ Direct_Attribute_Definition_Name.
+ * gen_il-fields.ads: Remove Constructor_List and Constructor_Name.
+ * gen_il-gen-gen_entities.adb: Likewise.
+ * einfo.ads (Needs_Construction): Add description.
+ (Has_Delayed_Aspects): Adjust indentation.
+ * par-ch13.adb (P_Attribute_Designators): Parse attribute
+ designators.
+ (P_Representation_Clause): Use P_Attribute_Designators.
+ * par-ch6.adb (P_Subprogram): Support attribute designators in
+ subprogram name.
+ (Rewrites_Entity_If_Direct_Attribute_Def): Fix the specification
+ node in case of direct attribute definitions.
+ * par-endh.adb (Check_End, Same_Label): Likewise.
+ * par.adb (P_Attribute_Designators): Specification.
+ * sem_attr.adb (Analyze_Attribute): Error when using 'Constructor
+ outside procedure specification.
+ (Analyze_Attribute): Add error handling code.
+ * sem_ch3.adb (Analyze_Aspect_Specifications): Likewise.
+ * sem_ch6.adb (Analyze_Direct_Attribute_Definition): Handle direct
+ attribute definitions. Add error handling code for the
+ 'Construction attribute and set constructor flags when necessary.
+ (Analyze_Subprogram_Specification): Use
+ Analyze_Direct_Attribute_Definition.
+ * sem_util.adb (Direct_Attribute_Definition_Name): Name of
+ entities created for direct attribute definitions. We emit an
+ error if multiple attributes.
+ (Is_Direct_Attribute_Subp_Spec): Helper to check whether a
+ subprogram specification is a direct attribute definition.
+ (Is_Constructor_Procedure): Helper to check whether a subprogram
+ is a constructor procedure.
+ (Has_Default_Constructor): Check whether the default constructor
+ exists.
+ (Default_Constructor): Not used anymore.
+ (Parameter_Count): Likewise.
+ (Process_End_Label): Get_Attribute_Reference_Name_String encodes
+ also direct attribute definition end labels.
+ * sem_util.ads: Likewise.
+ * snames.ads-tmpl: Support for 'Constructor attribute.
+ * snames.adb-tmpl (Is_Direct_Attribute_Definition_Name): Helper to
+ check attributes allowed in direct attribute definitions.
+ * aspects.ads: Remove constructor aspect.
+ * sem_ch13.adb: Likewise.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/122161
+ * sem_ch12.adb: Improve the description of Check_Generic_Actuals,
+ Restore_Private_Views and Switch_View, and alphabetize them.
+ (Check_Generic_Actuals): Make actuals visible only if needed.
+ (Install_Formal_Packages): Pass exact Is_Formal_Box parameter and
+ remove call to Set_Is_Hidden.
+ (Instantiate_Formal_Package): Use Next_Non_Pragma consistently in
+ the loop computing the visibility of actuals.
+ (Analyze_Package_Instantiation): Use named second parameter in the
+ call to Restore_Private_Views.
+ (Analyze_Subprogram_Instantiation): Likewise.
+ (Instantiate_Package_Body): Likewise and for Check_Generic_Actuals.
+ (Instantiate_Subprogram_Body): Likewise.
+ (Restore_Env): Replace call to Restore_Private_Views.
+ (Restore_Private_Views): Remove default value for second parameter
+ and test of presence for first parameter. Consistently clear the
+ Is_Potentially_Use_Visible flag when setting the Is_Hidden flag.
+ Remove call to Set_Is_Hidden for a formal package of the enclosing
+ generic unit, if any.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * gen_il-gen.adb (N_Short_Circuit):
+ Make Actions syntactic.
+ (N_Case_Expression_Alternative): Likewise.
+ * gen_il-gen-gen_nodes.adb (Create_Type):
+ No longer exempt Actions from the syntactic/semantic ordering rule.
+ (Check_For_Syntactic_Field_Mismatch):
+ No longer exempt Actions from the syntactic/semantic mixing rule.
+ * sinfo.ads (N_Compound_Statement):
+ Add comment.
+
+2025-11-03 Marc Poulhiès <poulhies@adacore.com>
+
+ * sem_aux.adb (Enclosing_Dynamic_Scope): Remove comment.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * einfo.ads: Remove unused fields.
+ * gen_il-fields.ads: Likewise.
+ * gen_il-gen-gen_entities.adb: Likewise.
+ * gen_il-gen-gen_nodes.adb: Likewise.
+ * sinfo.ads: Likewise.
+ * gen_il-gen.adb (Compile): Remove obsolete comment.
+
+2025-11-03 Ronan Desplanques <desplanques@adacore.com>
+
+ * libgnat/s-stratt__cheri.adb (W_80IEEE): New procedure.
+
+2025-11-03 Ronan Desplanques <desplanques@adacore.com>
+
+ * libgnat/s-stratt.adb (W_80IEEE): Make constant local.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * einfo.ads (Has_Pragma_Controlled): Remove.
+ (Is_Activation_Record): Document usage by llvm.
+ * gen_il-fields.ads (Opt_Field_Enum):
+ Remove Has_Pragma_Controlled.
+ * gen_il-gen-gen_entities.adb (Access_Kind):
+ Remove Has_Pragma_Controlled.
+ * sem_prag.adb:
+ Remove setting of Has_Pragma_Controlled.
+ * sinfo.ads (Corresponding_Entry_Body):
+ Document usage by codepeer.
+
+2025-11-03 Alexandre Oliva <oliva@adacore.com>
+
+ * exp_ch3.adb (Expand_N_Object_Declaration): Insert ctor call
+ after representation clauses.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * atree.adb (Same_Node_To_Fetch_From):
+ Use Node_To_Fetch_From_If_Set, and remove handler.
+ * einfo-utils.adb (Root_Type_If_Set):
+ Return Empty if Base_Type_If_Set returns Empty.
+ Return Empty if we find Etype (T) = Empty.
+ (Underlying_Type): Use "Has_Non_Limited_View..." instead
+ of "Present (Non_Limited_View...)", because the latter raises
+ an exception when given the wrong Ekind.
+
+2025-11-03 Ronan Desplanques <desplanques@adacore.com>
+
+ * gen_il-fields.ads (Is_IEEE_Extended_Precision): New flag.
+ * gen_il-gen-gen_entities.adb: Likewise.
+ * gen_il-internals.adb (Image): Likewise.
+ * treepr.adb (Image): Likewise.
+ * einfo.ads: Document new flag.
+ * cstand.adb (Copy_Float_Type, Register_Float_Type): Use new flag.
+ * libgnat/s-stratt.ads (W_80IEEE): New procedure.
+ * libgnat/s-stratt.adb (W_80IEEE): Likewise.
+ * exp_strm.adb (Get_Primitives): Select new procedure when
+ appropriate.
+ * rtsfind.ads: Register new runtime procedure.
+ * sem_ch3.adb (Build_Derived_Numeric_Type,
+ Analyze_Subtype_Declaration): Propagate new flag.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/122160
+ * sem_res.adb (Resolve_Op_Concat_Rest): Do not build the subtype of
+ the second operand again if it has already been built.
+ (Resolve_String_Literal): Do not defer the creation of the subtype
+ for the right operand of a concatenation whose left operand may be
+ the null string.
+
+2025-11-03 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_ch6.ads (Make_Build_In_Place_Call_In_Allocator): Simplify comment.
+ * exp_ch6.adb (Make_Build_In_Place_Call_In_Allocator): Remove obsolete
+ comment about not being able to allocate fixed-size controlled results
+ on the caller side, and replace another obsolete comment with a simpler
+ comment. Call Build_Allocate_Deallocate_Proc when the function doesn't
+ need a BIPalloc formal to ensure that function results with controlled
+ parts allocated on the caller side will be chained for finalization.
+ (Make_Build_In_Place_Call_In_Object_Declaration): Call Needs_BIP_Collection
+ on the function's Entity_Id rather than the function call.
+ (Needs_BIP_Collection): If a BIP function doesn't need a BIPalloc formal
+ then it doesn't need a BIP collection either; return False in that case.
+ (Needs_BIP_Alloc_Form): Remove test of Needs_BIP_Collection.
+ * exp_ch7.adb (Expand_Cleanup_Actions): Move test of Uses_Sec_Stack
+ to be the first conjunct in setting of Needs_Sec_Stack_Mark, and put
+ the other tests in a disjunction subsidiary to that. Improve preceding
+ comment.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * gen_il-gen-gen_nodes.adb: Rename Default_Expression to be
+ Expression.
+ * gen_il-gen.adb (Check_For_Syntactic_Field_Mismatch): Do not
+ exempt Default_Expression from the rule.
+ * par-ch12.adb (P_Formal_Object_Declarations): Use renamed setter.
+ * sem_ch12.adb (Default): Use renamed getter.
+ (Analyze_Formal_Object_Declaration): Likewise.
+ * sprint.adb (Sprint_Node_Actual): Use renamed getter.
+ * sinfo.ads: Fix comments.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * style.adb (Check_Xtra_Parens_Precedence):
+ Give warning based on Original_Node.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/122161
+ * sem_ch12.adb (Check_Generic_Actuals): Consistently set the
+ Is_Potentially_Use_Visible flag on actuals whenever the Is_Hidden
+ flag is cleared.
+ (Restore_Private_Views): Clear the Is_Potentially_Use_Visible flag
+ explicitly on the entities of an actual package.
+
+2025-11-03 Ronan Desplanques <desplanques@adacore.com>
+
+ * libgnat/s-trasym.ads (Calling_Entity): New function.
+ * libgnat/s-trasym.adb (Calling_Entity): Add dummy body.
+ * libgnat/s-trasym__dwarf.adb (Calling_Entity): New function.
+ (Symbolic_Traceback, Symbolic_Traceback_No_Lock,
+ Module_Symbolic_Traceback, Multi_Module_Symbolic_Traceback): Add
+ Subprg_Name_Only parameter and corresponding functionality.
+ (Symbolic_Traceback_No_Lock): Fix typo in documentation comment.
+ * libgnat/s-dwalin.ads (Symbolic_Traceback): Likewise.
+ * libgnat/s-dwalin.adb (Symbolic_Traceback): Likewise.
+
+2025-11-03 Bob Duff <duff@adacore.com>
+
+ * gen_il-gen-gen_nodes.adb (N_Op):
+ Make Chars syntactic, and move it down into subclasses
+ N_Binary_Op and N_Unary_Op.
+ * gen_il-gen.adb (Create_Type):
+ Do not exempt Chars from the ordering rule.
+ (Exception_To_Inheritance_Rule): Exempt Chars from the
+ inheritance rule.
+ (Check_For_Syntactic_Field_Mismatch):
+ Do not exempt Chars from the syntactic mismatch rule.
+ This is the main point of this change.
+ (Put_Make_Bodies): The Nmake functions for types in N_Op
+ will now take a Chars parameter, which should always
+ default to No_Name. This will be overwritten by the
+ special-case Set_Chars call. Assert that it is in
+ fact defaulted.
+ * exp_ch4.adb (Expand_Array_Comparison):
+ Use the Nkind instead of the Chars, which seems cleaner.
+ Use a case instead of an elsif chain.
+ * sem_attr.adb (Proper_Op): Minor cleanup.
+ * sem_ch8.adb: Minor reformatting.
+ * sem_res.adb (Operator_Kind): Tighten up the result subtype.
+
+2025-11-03 Viljar Indus <indus@adacore.com>
+
+ * exp_attr.adb (Expand_N_Attribute_Reference): Use the
+ First_Subtype when creating the procedure for stream
+ attributes.
+ (Get_Array_Stream_Item_Type): New method for calculating
+ the type for the Item argument for streaming methods.
+
+2025-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * locales.c (is_iso_639_3): New static function.
+ (c_get_language_code): Use it to validate the ISO-639-3 code
+ before returning it.
+
+2025-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/58881
+ * sem_ch3.adb (Build_Derived_Private_Type): Build the underlying
+ full view when the derivation occurs in the public part of the
+ scope of the parent.
+ (Build_Derived_Record_Type): Propagate Has_Unknown_Discriminants
+ in the same circumstances.
+ (Constrain_Discriminated_Type): Give a specific error message for
+ any type with the Has_Unknown_Discriminants flag.
+
+2025-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/52319
+ * sem_ch8.adb (End_Use_Package): Use the scope of the operator.
+
2025-10-30 Eric Botcazou <ebotcazou@adacore.com>
PR ada/15610
diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
index ab87f54..5d242ed 100644
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -81,7 +81,6 @@ package Aspects is
Aspect_Bit_Order,
Aspect_Component_Size,
Aspect_Constant_Indexing,
- Aspect_Constructor, -- GNAT
Aspect_Contract_Cases, -- GNAT
Aspect_Convention,
Aspect_CPU,
@@ -440,7 +439,6 @@ package Aspects is
Aspect_Bit_Order => Expression,
Aspect_Component_Size => Expression,
Aspect_Constant_Indexing => Name,
- Aspect_Constructor => Name,
Aspect_Contract_Cases => Expression,
Aspect_Convention => Name,
Aspect_CPU => Expression,
@@ -547,7 +545,6 @@ package Aspects is
Aspect_Component_Size => True,
Aspect_Constant_Indexing => False,
Aspect_Contract_Cases => False,
- Aspect_Constructor => False,
Aspect_Convention => True,
Aspect_CPU => False,
Aspect_Default_Component_Value => True,
@@ -723,7 +720,6 @@ package Aspects is
Aspect_Constant_After_Elaboration => Name_Constant_After_Elaboration,
Aspect_Constant_Indexing => Name_Constant_Indexing,
Aspect_Contract_Cases => Name_Contract_Cases,
- Aspect_Constructor => Name_Constructor,
Aspect_Convention => Name_Convention,
Aspect_CPU => Name_CPU,
Aspect_CUDA_Device => Name_CUDA_Device,
@@ -997,7 +993,6 @@ package Aspects is
Aspect_Asynchronous => Always_Delay,
Aspect_Attach_Handler => Always_Delay,
Aspect_Constant_Indexing => Always_Delay,
- Aspect_Constructor => Always_Delay,
Aspect_CPU => Always_Delay,
Aspect_CUDA_Device => Always_Delay,
Aspect_CUDA_Global => Always_Delay,
diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb
index 327bc2d..a13438a 100644
--- a/gcc/ada/atree.adb
+++ b/gcc/ada/atree.adb
@@ -1005,61 +1005,49 @@ package body Atree is
Old_Kind : constant Entity_Kind := Ekind (Old_N);
- function Same_Node_To_Fetch_From
- (N : Node_Or_Entity_Id; Field : Node_Or_Entity_Field)
- return Boolean;
- -- True if the field should be fetched from N. For most fields, this is
- -- true. However, if the field is a "root type only" field, then this is
- -- true only if N is the root type. If this is false, then we should not
- -- do Reinit_Field_To_Zero, and we should not fail below, because the
- -- field is not vanishing from the root type. Similar comments apply to
- -- "base type only" and "implementation base type only" fields.
- --
- -- We need to ignore exceptions here, because in some cases,
- -- Node_To_Fetch_From is being called before the relevant (root, base)
- -- type has been set, so we fail some assertions.
-
- function Same_Node_To_Fetch_From
- (N : Node_Or_Entity_Id; Field : Node_Or_Entity_Field)
- return Boolean is
- begin
- return N = Node_To_Fetch_From (N, Field);
- exception
- when others => return False; -- ignore the exception
- end Same_Node_To_Fetch_From;
-
-- Start of processing for Check_Vanishing_Fields
begin
for J in Entity_Field_Table (Old_Kind)'Range loop
declare
F : constant Entity_Field := Entity_Field_Table (Old_Kind) (J);
- begin
- if not Same_Node_To_Fetch_From (Old_N, F) then
- null; -- no check in this case
- elsif not Field_Checking.Field_Present (New_Kind, F) then
- if not Field_Is_Initial_Zero (Old_N, F) then
- Write_Str ("# ");
- Write_Str (Osint.Get_First_Main_File_Name);
- Write_Str (": ");
- Write_Str (Old_Kind'Img);
- Write_Str (" --> ");
- Write_Str (New_Kind'Img);
- Write_Str (" Nonzero field ");
- Write_Str (F'Img);
- Write_Str (" is vanishing ");
-
- if New_Kind = E_Void or else Old_Kind = E_Void then
- Write_Line ("(E_Void case)");
- else
- Write_Line ("(non-E_Void case)");
- end if;
+ Same_Node_To_Fetch_From : constant Boolean :=
+ Old_N = Node_To_Fetch_From_If_Set (Old_N, F);
+ -- True if the field F should be fetched from Old_N. For most
+ -- fields, this is True. However, if F is a "root type only"
+ -- field, then it should be fetched from the root type, so this is
+ -- true only if Old_N is the root type. If this is False, then we
+ -- should not have done Reinit_Field_To_Zero, and we should not
+ -- fail below, because the field is not vanishing from this node.
+ -- We use the ..._If_Set function to avoid failing when the root
+ -- type has not yet been set. Similar comments apply to "base type
+ -- only" and "implementation base type only" fields.
- Write_Str (" ...mutating node ");
- Write_Int (Nat (Old_N));
- Write_Line ("");
- raise Program_Error;
+ begin
+ if Same_Node_To_Fetch_From
+ and then not Field_Checking.Field_Present (New_Kind, F)
+ and then not Field_Is_Initial_Zero (Old_N, F)
+ then
+ Write_Str ("# ");
+ Write_Str (Osint.Get_First_Main_File_Name);
+ Write_Str (": ");
+ Write_Str (Old_Kind'Img);
+ Write_Str (" --> ");
+ Write_Str (New_Kind'Img);
+ Write_Str (" Nonzero field ");
+ Write_Str (F'Img);
+ Write_Str (" is vanishing ");
+
+ if New_Kind = E_Void or else Old_Kind = E_Void then
+ Write_Line ("(E_Void case)");
+ else
+ Write_Line ("(non-E_Void case)");
end if;
+
+ Write_Str (" ...mutating node ");
+ Write_Int (Nat (Old_N));
+ Write_Line ("");
+ raise Program_Error;
end if;
end;
end loop;
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index c30e5f1..39cf37e 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -596,9 +596,10 @@ package body Checks is
-- Note: we do not check for checks suppressed here, since that check
-- was done in Sem_Ch13 when the address clause was processed. We are
-- only called if checks were not suppressed. The reason for this is
- -- that we have to delay the call to Apply_Alignment_Check till freeze
- -- time (so that all types etc are elaborated), but we have to check
- -- the status of check suppressing at the point of the address clause.
+ -- that we have to delay the call to Apply_Address_Clause_Check till
+ -- freeze time (so that all types etc are elaborated), but we have to
+ -- check the status of check suppressing at the point of the address
+ -- clause.
if No (AC)
or else not Check_Address_Alignment (AC)
diff --git a/gcc/ada/cstand.adb b/gcc/ada/cstand.adb
index cdf2b5d..8dd169a 100644
--- a/gcc/ada/cstand.adb
+++ b/gcc/ada/cstand.adb
@@ -298,6 +298,7 @@ package body CStand is
Build_Float_Type
(To, UI_To_Int (Digits_Value (From)), Float_Rep (From),
UI_To_Int (Esize (From)), UI_To_Int (Alignment (From)));
+ Set_Is_IEEE_Extended_Precision (To, Is_IEEE_Extended_Precision (From));
end Copy_Float_Type;
----------------------
@@ -2100,17 +2101,22 @@ package body CStand is
Size : Positive;
Alignment : Natural)
is
- pragma Unreferenced (Precision);
- -- See Build_Float_Type for the rationale
-
Ent : constant Entity_Id := New_Standard_Entity (Name);
+ IEEE_Extended_Precision_Size : constant := 80;
begin
Set_Defining_Identifier (New_Node (N_Full_Type_Declaration, Stloc), Ent);
Set_Scope (Ent, Standard_Standard);
Build_Float_Type
(Ent, Pos (Digs), Float_Rep, Int (Size), Nat (Alignment / 8));
+ -- We mostly disregard Precision, see Build_Float_Type for the
+ -- rationale. The only thing we use it for is to detect 80-bit IEEE
+ -- extended precision, in order to adjust the behavior of 'Write.
+ if Precision = IEEE_Extended_Precision_Size then
+ Set_Is_IEEE_Extended_Precision (Ent);
+ end if;
+
Append_New_Elmt (Ent, Back_End_Float_Types);
end Register_Float_Type;
diff --git a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
index 7250f65..65bb187 100644
--- a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
@@ -1580,8 +1580,7 @@ machines with strict alignment requirements, GNAT
checks (at compile time if possible, generating a warning, or at execution
time with a run-time check) that the alignment is appropriate. If the
run-time check fails, then ``Program_Error`` is raised. This run-time
-check is suppressed if range checks are suppressed, or if the special GNAT
-check Alignment_Check is suppressed, or if
+check is suppressed if the GNAT check Alignment_Check is suppressed, or if
``pragma Restrictions (No_Elaboration_Code)`` is in effect. It is also
suppressed by default on non-strict alignment machines (such as the x86).
diff --git a/gcc/ada/einfo-utils.adb b/gcc/ada/einfo-utils.adb
index b0acb25..6d10a7f 100644
--- a/gcc/ada/einfo-utils.adb
+++ b/gcc/ada/einfo-utils.adb
@@ -2622,13 +2622,20 @@ package body Einfo.Utils is
begin
return T : Opt_N_Entity_Id := Base_Type_If_Set (Id) do
- if Ekind (T) = E_Class_Wide_Type then
+ if No (T) then
+ null;
+ elsif Ekind (T) = E_Class_Wide_Type then
T := Etype (T);
else
loop
Etyp := Etype (T);
- exit when No (Etyp) or else T = Etyp
+ if No (Etyp) then
+ T := Empty;
+ exit;
+ end if;
+
+ exit when T = Etyp
or else
(Is_Private_Type (T) and then Etyp = Full_View (T))
or else
@@ -3086,7 +3093,7 @@ package body Einfo.Utils is
elsif Ekind (Id) = E_Class_Wide_Type
and then From_Limited_With (Id)
- and then Present (Non_Limited_View (Id))
+ and then Has_Non_Limited_View (Id)
then
return Underlying_Type (Non_Limited_View (Id));
@@ -3118,7 +3125,7 @@ package body Einfo.Utils is
-- then we return the Underlying_Type of its nonlimited view.
elsif From_Limited_With (Id)
- and then Present (Non_Limited_View (Id))
+ and then Has_Non_Limited_View (Id)
then
return Underlying_Type (Non_Limited_View (Id));
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index b9548a7..8e41d0f 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -1585,11 +1585,11 @@ package Einfo is
-- type derivation.
-- Has_Delayed_Aspects
--- Defined in all entities. Set if the Rep_Item chain for the entity has
--- one or more N_Aspect_Definition nodes chained which are not to be
--- evaluated till the freeze point. The aspect definition expression
--- clause has been preanalyzed to get visibility at the point of use,
--- but no other action has been taken.
+-- Defined in all entities. Set if the Rep_Item chain for the entity has
+-- one or more N_Aspect_Definition nodes chained which are not to be
+-- evaluated till the freeze point. The aspect definition expression
+-- clause has been preanalyzed to get visibility at the point of use,
+-- but no other action has been taken.
-- Has_Delayed_Freeze
-- Defined in all entities. Set to indicate that an explicit freeze
@@ -1889,10 +1889,6 @@ package Einfo is
-- 5. N_Range_Constraint - when the range expression uses the
-- discriminant of the enclosing type.
--- Has_Pragma_Controlled [implementation base type only]
--- Defined in access type entities. It is set if a pragma Controlled
--- applies to the access type.
-
-- Has_Pragma_Elaborate_Body
-- Defined in all entities. Set in compilation unit entities if a
-- pragma Elaborate_Body applies to the compilation unit.
@@ -2383,7 +2379,7 @@ package Einfo is
-- Is_Activation_Record
-- Applies to E_In_Parameters generated in Exp_Unst for nested
-- subprograms, to mark the added formal that carries the activation
--- record created in the enclosing subprogram.
+-- record created in the enclosing subprogram. Used by the llvm back end.
-- Is_Actual_Subtype
-- Defined on all types, true for the generated constrained subtypes
@@ -2596,7 +2592,7 @@ package Einfo is
-- Is_Discriminant_Check_Function
-- Defined in all entities. Set only in E_Function entities for functions
--- created to do discriminant checks.
+-- created to do discriminant checks. Used by CodePeer.
-- Is_Discriminal (synthesized)
-- Applies to all entities, true for renamings of discriminants. Such
@@ -3471,10 +3467,6 @@ package Einfo is
-- as its corresponding record type, but whose parent is the full view
-- of the parent in the original type extension.
--- Is_Unimplemented
--- Defined in all entities. Set for any entity to which a valid pragma
--- or aspect Unimplemented applies.
-
-- Is_Unsigned_Type
-- Defined in all types, but can be set only for discrete and fixed-point
-- type and subtype entities. This flag is only valid if the entity is
@@ -3552,6 +3544,15 @@ package Einfo is
-- a wrapper to handle inherited class-wide pre/post conditions that call
-- overridden primitives or as a wrapper of a controlling function.
+-- Is_IEEE_Extended_Precision
+-- Defined in floating point types and subtypes. Indicates that the type
+-- corresponds to the 80-bit IEEE extended precision format. That format
+-- effectively uses 80 bits per value, but we set its Size to a larger
+-- value for the reasons explained in the documentation comment of
+-- Build_Float_Type. We also perform some extra work to consistently set
+-- the extra bits to zero in the 'Write implementation, which is why we
+-- need this flag.
+
-- Itype_Printed
-- Defined in all type and subtype entities. Set in Itypes if the Itype
-- has been printed by Sprint. This is used to avoid printing an Itype
@@ -3705,6 +3706,11 @@ package Einfo is
-- preelaborable initialization at freeze time (this has to be deferred
-- to the freeze point because of the rule about overriding Initialize).
+-- Needs_Construction
+-- Defined in all type and subtype entities. Set only for record type
+-- entities for which at least one ancestor has specified a constructor
+-- through the 'Constructor direct attribute definition.
+
-- Needs_Debug_Info
-- Defined in all entities. Set if the entity requires normal debugging
-- information to be generated. This is true of all entities that have
@@ -5018,7 +5024,6 @@ package Einfo is
-- Is_Thunk
-- Is_Trivial_Subprogram
-- Is_Unchecked_Union
- -- Is_Unimplemented
-- Is_Visible_Formal
-- Kill_Elaboration_Checks
-- Low_Bound_Tested
@@ -5130,6 +5135,7 @@ package Einfo is
-- May_Inherit_Delayed_Rep_Aspects
-- Must_Be_On_Byte_Boundary
-- Must_Have_Preelab_Init
+ -- Needs_Construction
-- Optimize_Alignment_Space
-- Optimize_Alignment_Time
-- Partial_View_Has_Unknown_Discr
@@ -5211,7 +5217,6 @@ package Einfo is
-- Associated_Storage_Pool (root type only)
-- Finalization_Collection (root type only)
-- Storage_Size_Variable (base type only)
- -- Has_Pragma_Controlled (base type only)
-- Has_Storage_Size_Clause (base type only)
-- Is_Access_Constant
-- Is_Local_Anonymous_Access
@@ -5529,6 +5534,7 @@ package Einfo is
-- Digits_Value
-- Float_Rep (Float_Rep_Kind)
-- Default_Aspect_Value (base type only)
+ -- Is_IEEE_Extended_Precision
-- Scalar_Range
-- Static_Real_Or_String_Predicate
-- Machine_Emax_Value (synth)
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 472fbbe..220523c 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -163,8 +163,8 @@ package body Errout is
procedure Set_Msg_Node (Node : Node_Id);
-- Add the sequence of characters for the name associated with the given
-- node to the current message. For N_Designator, N_Selected_Component,
- -- N_Defining_Program_Unit_Name, and N_Expanded_Name, the Prefix is
- -- included as well.
+ -- N_Defining_Program_Unit_Name, N_Expanded_Name, and N_Attribute_Reference
+ -- the Prefix is included as well.
procedure Set_Posted (N : Node_Id);
-- Sets the Error_Posted flag on the given node, and all its parents that
@@ -3800,6 +3800,29 @@ package body Errout is
Set_Msg_Node (Selector_Name (Node));
return;
+ when N_Attribute_Reference =>
+ Set_Msg_Node (Prefix (Node));
+ Set_Msg_Char (''');
+ Get_Unqualified_Decoded_Name_String (Attribute_Name (Node));
+ Adjust_Name_Case (Global_Name_Buffer, Sloc (Node));
+ Set_Msg_Name_Buffer;
+ return;
+
+ when N_Defining_Identifier =>
+
+ -- Handle direct attribute definitions
+
+ if Parent_Kind (Node) in N_Subprogram_Specification
+ and then Original_Node (Parent (Node)) /= Parent (Node)
+ and then Nkind (Defining_Unit_Name
+ (Original_Node (Parent (Node))))
+ = N_Attribute_Reference
+ then
+ Set_Msg_Node
+ (Defining_Unit_Name (Original_Node (Parent (Node))));
+ return;
+ end if;
+
when others =>
null;
end case;
diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb
index 14a11ff..bbbe245 100644
--- a/gcc/ada/erroutc.adb
+++ b/gcc/ada/erroutc.adb
@@ -1579,6 +1579,46 @@ package body Erroutc is
----------------------------
procedure Set_Msg_Insertion_Name is
+ procedure Replace_With_Attribute_Definition;
+ -- This procedure handles direct attribute definition names of the form:
+ -- 'D' Prefix_Name "_" Attribute_Name "_Att"
+ -- Specifically, it replace the current Namet.Global_Name_Buffer with an
+ -- all lowercase string of the prefix, and a tick attribute; at this
+ -- stage there is no way to recognize more than an ending attribute ???
+ --
+ -- Note that, at this point, it is not possible to restore the original
+ -- casing thus lowercase is default.a
+
+ procedure Replace_With_Attribute_Definition is
+ First : constant Integer := 2;
+ Last : constant Integer := Name_Len - 4;
+ Att_Buf : Bounded_String (Max_Length => Name_Len - 7);
+ begin
+ Until_Tick :
+ for J in First .. Last loop
+
+ -- J could be at the position separating the prefix from the
+ -- attribute name.
+
+ if Name_Buffer (J) = '_' then
+ Att_Buf.Length := 0;
+ Append (Att_Buf, Name_Buffer (J + 1 .. Last));
+ Set_Casing (Att_Buf, All_Lower_Case);
+ if Is_Direct_Attribute_Definition_Name (Name_Find (Att_Buf))
+ then
+ Name_Buffer (J) := ''';
+ exit Until_Tick;
+ end if;
+ end if;
+ end loop Until_Tick;
+
+ -- Remove prefix 'D' and suffix "_Att"
+
+ Name_Buffer (1 .. Last - 1) := Name_Buffer (2 .. Last);
+ Name_Len := Last - 1;
+ Set_Casing (All_Lower_Case);
+ end Replace_With_Attribute_Definition;
+
begin
if Error_Msg_Name_1 = No_Name then
null;
@@ -1624,7 +1664,14 @@ package body Erroutc is
-- Else output with surrounding quotes in proper casing mode
else
- Set_Casing (Identifier_Casing (Flag_Source));
+ if Name_Buffer (1) = 'D'
+ and then Name_Buffer (Name_Len - 3 .. Name_Len) = "_Att"
+ then
+ Replace_With_Attribute_Definition;
+ else
+ Set_Casing (Identifier_Casing (Flag_Source));
+ end if;
+
Set_Msg_Quote;
Set_Msg_Name_Buffer;
Set_Msg_Quote;
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index d62b735..6b6b0ab 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -4914,11 +4914,10 @@ package body Exp_Aggr is
-- IP procedure.
if Has_Default_Init_Comps (N)
- or else Present (Constructor_Name (Ctyp))
+ or else Needs_Construction (Ctyp)
or else (Is_Access_Type (Ctyp)
- and then Present
- (Constructor_Name
- (Directly_Designated_Type (Ctyp))))
+ and then Needs_Construction
+ (Directly_Designated_Type (Ctyp)))
then
return;
end if;
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index a0a550d..086ef91 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -1906,6 +1906,9 @@ package body Exp_Attr is
function Get_Integer_Type (Typ : Entity_Id) return Entity_Id;
-- Return a small integer type appropriate for the enumeration type
+ function Get_Array_Stream_Item_Type (Typ : Entity_Id) return Entity_Id;
+ -- For non-scalar types return the first subtype of Typ.
+
procedure Rewrite_Attribute_Proc_Call (Pname : Entity_Id);
-- Rewrites an attribute for Read, Write, Output, or Put_Image with a
-- call to the appropriate TSS procedure. Pname is the entity for the
@@ -2066,6 +2069,19 @@ package body Exp_Attr is
return Small_Integer_Type_For (Siz, Uns => Is_Unsigned_Type (Typ));
end Get_Integer_Type;
+ --------------------------------
+ -- Get_Array_Stream_Item_Type --
+ --------------------------------
+
+ function Get_Array_Stream_Item_Type (Typ : Entity_Id) return Entity_Id is
+ First_Sub_Typ : constant Entity_Id := First_Subtype (Typ);
+ begin
+ if Is_Private_Type (First_Sub_Typ) then
+ return Typ;
+ end if;
+ return First_Sub_Typ;
+ end Get_Array_Stream_Item_Type;
+
---------------------------------
-- Rewrite_Attribute_Proc_Call --
---------------------------------
@@ -4482,6 +4498,7 @@ package body Exp_Attr is
P_Type : constant Entity_Id := Entity (Pref);
B_Type : constant Entity_Id := Base_Type (P_Type);
U_Type : constant Entity_Id := Underlying_Type (P_Type);
+ I_Type : Entity_Id := P_Type;
Strm : constant Node_Id := First (Exprs);
Fname : Entity_Id;
Decl : Node_Id;
@@ -4633,8 +4650,9 @@ package body Exp_Attr is
new Build_And_Insert_Type_Attr_Subp
(Build_Array_Input_Function);
begin
+ I_Type := Get_Array_Stream_Item_Type (U_Type);
Build_And_Insert_Array_Input_Func
- (Typ => Full_Base (U_Type),
+ (Typ => I_Type,
Decl => Decl,
Subp => Fname,
Attr_Ref => N);
@@ -4784,8 +4802,13 @@ package body Exp_Attr is
Relocate_Node (Strm)));
Set_Controlling_Argument (Call, Cntrl);
- Rewrite (N, Unchecked_Convert_To (P_Type, Call));
- Analyze_And_Resolve (N, P_Type);
+ if Is_Private_Type (P_Type) or else Is_Class_Wide_Type (P_Type) then
+ Rewrite (N, Unchecked_Convert_To (P_Type, Call));
+ Analyze_And_Resolve (N, P_Type);
+ else
+ Rewrite (N, Call);
+ Analyze_And_Resolve (N, I_Type);
+ end if;
if Nkind (Parent (N)) = N_Object_Declaration then
Freeze_Stream_Subprogram (Fname);
@@ -5142,7 +5165,8 @@ package body Exp_Attr is
Make_Selected_Component (Loc,
Prefix => New_Occurrence_Of (Result_Id, Loc),
Selector_Name => Make_Identifier (Loc,
- Chars (Constructor_Name (Typ))));
+ Direct_Attribute_Definition_Name
+ (Typ, Name_Constructor)));
begin
Set_Is_Prefixed_Call (Proc_Name);
@@ -5818,7 +5842,7 @@ package body Exp_Attr is
(Build_Array_Output_Procedure);
begin
Build_And_Insert_Array_Output_Proc
- (Typ => Full_Base (U_Type),
+ (Typ => Get_Array_Stream_Item_Type (U_Type),
Decl => Decl,
Subp => Pname,
Attr_Ref => N);
@@ -6280,7 +6304,7 @@ package body Exp_Attr is
/= RTU_Entity (Interfaces_C))
then
Rewrite (N, Build_String_Put_Image_Call (N));
- Analyze (N);
+ Analyze (N, Suppress => All_Checks);
return;
elsif Is_Array_Type (U_Type) then
@@ -6295,10 +6319,10 @@ package body Exp_Attr is
begin
Build_And_Insert_Array_Put_Image_Proc
- (Typ => U_Type,
+ (Typ => Get_Array_Stream_Item_Type (U_Type),
Decl => Decl,
- Subp => Pname,
- Attr_Ref => N);
+ Subp => Pname,
+ Attr_Ref => N);
end;
Cached_Attribute_Ops.Put_Image_Map.Set (U_Type, Pname);
@@ -6746,7 +6770,7 @@ package body Exp_Attr is
(Build_Array_Read_Procedure);
begin
Build_And_Insert_Array_Read_Proc
- (Typ => Full_Base (U_Type),
+ (Typ => Get_Array_Stream_Item_Type (U_Type),
Decl => Decl,
Subp => Pname,
Attr_Ref => N);
@@ -8461,7 +8485,7 @@ package body Exp_Attr is
(Build_Array_Write_Procedure);
begin
Build_And_Insert_Array_Write_Proc
- (Typ => Full_Base (U_Type),
+ (Typ => Get_Array_Stream_Item_Type (U_Type),
Decl => Decl,
Subp => Pname,
Attr_Ref => N);
@@ -8577,6 +8601,7 @@ package body Exp_Attr is
| Attribute_Bit_Order
| Attribute_Class
| Attribute_Compiler_Version
+ | Attribute_Constructor
| Attribute_Default_Bit_Order
| Attribute_Default_Scalar_Storage_Order
| Attribute_Definite
diff --git a/gcc/ada/exp_ch11.adb b/gcc/ada/exp_ch11.adb
index ee6010a7..a6b1718 100644
--- a/gcc/ada/exp_ch11.adb
+++ b/gcc/ada/exp_ch11.adb
@@ -1031,7 +1031,7 @@ package body Exp_Ch11 is
-- "hoisted" (i.e., Is_Statically_Allocated and not Is_Library_Level)
-- entity must also be either Library_Level or hoisted. It turns out
-- that this would be incompatible with the current treatment of an
- -- object which is local to a subprogram, subject to an Export pragma,
+ -- object that is local to a subprogram, subject to an Export pragma,
-- not subject to an address clause, and whose declaration contains
-- references to other local (non-hoisted) objects (e.g., in the initial
-- value expression).
@@ -1558,7 +1558,7 @@ package body Exp_Ch11 is
Build_Location_String (Buf, Loc);
-- If the exception is a renaming, use the exception that it
- -- renames (which might be a predefined exception, e.g.).
+ -- renames (which might be a predefined exception).
if Present (Renamed_Entity (Id)) then
Id := Renamed_Entity (Id);
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 60224c1..db41ab7 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -3185,8 +3185,8 @@ package body Exp_Ch3 is
if Parent_Subtype_Renaming_Discrims then
Append_List_To (Body_Stmts, Build_Init_Call_Thru (Parameters));
- elsif Present (Constructor_Name (Rec_Type)) then
- if Present (Default_Constructor (Rec_Type)) then
+ elsif Needs_Construction (Rec_Type) then
+ if Has_Default_Constructor (Rec_Type) then
-- The 'Make attribute reference (with no arguments) will
-- generate a call to the one-parameter constructor procedure.
@@ -3810,8 +3810,8 @@ package body Exp_Ch3 is
-- Expand components with constructors to have the 'Make
-- attribute.
- elsif Present (Constructor_Name (Typ))
- and then Present (Default_Constructor (Typ))
+ elsif Needs_Construction (Typ)
+ and then Has_Default_Constructor (Typ)
then
Set_Expression (Decl,
Make_Attribute_Reference (Loc,
@@ -4560,7 +4560,7 @@ package body Exp_Ch3 is
-- since the call is generated, there had better be a routine
-- at the other end of the call, even if it does nothing).
- -- 10. The type has a specified Constructor aspect.
+ -- 10. The type needs construction with constructors.
-- Note: the reason we exclude the CPP_Class case is because in this
-- case the initialization is performed by the C++ constructors, and
@@ -4577,7 +4577,7 @@ package body Exp_Ch3 is
or else Is_Tagged_Type (Rec_Id)
or else Is_Concurrent_Record_Type (Rec_Id)
or else Has_Task (Rec_Id)
- or else Present (Constructor_Name (Rec_Id))
+ or else Needs_Construction (Rec_Id)
then
return True;
end if;
@@ -7587,8 +7587,8 @@ package body Exp_Ch3 is
if No (Expr)
and then Constant_Present (N)
- and then (No (Constructor_Name (Typ))
- or else No (Default_Constructor (Typ)))
+ and then (not Needs_Construction (Typ)
+ or else not Has_Default_Constructor (Typ))
then
return;
end if;
@@ -7619,8 +7619,8 @@ package body Exp_Ch3 is
if Comes_From_Source (N)
and then No (Expr)
- and then Present (Constructor_Name (Typ))
- and then Present (Default_Constructor (Typ))
+ and then Needs_Construction (Typ)
+ and then Has_Default_Constructor (Typ)
then
Expr := Make_Attribute_Reference (Loc,
Attribute_Name => Name_Make,
@@ -8286,6 +8286,16 @@ package body Exp_Ch3 is
Set_Must_Not_Freeze (Id_Ref);
Set_Assignment_OK (Id_Ref);
+ -- Avoid separating an object declaration from
+ -- its representation clauses.
+
+ while Present (Next (Init_After))
+ and then Nkind (Next (Init_After)) in
+ N_Attribute_Definition_Clause
+ loop
+ Init_After := Next (Init_After);
+ end loop;
+
Insert_Actions_After (Init_After,
Build_Initialization_Call (N, Id_Ref, Typ,
Constructor_Ref => Expr));
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 8fba1c4..5971db3 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -1432,46 +1432,48 @@ package body Exp_Ch4 is
-- For (a <= b) we convert to not (a > b)
- if Chars (N) = Name_Op_Le then
- Rewrite (N,
- Make_Op_Not (Loc,
- Right_Opnd =>
- Make_Op_Gt (Loc,
- Left_Opnd => Op1,
- Right_Opnd => Op2)));
- Analyze_And_Resolve (N, Standard_Boolean);
- return;
+ case Nkind (N) is
+ when N_Op_Le =>
+ Rewrite (N,
+ Make_Op_Not (Loc,
+ Right_Opnd =>
+ Make_Op_Gt (Loc,
+ Left_Opnd => Op1,
+ Right_Opnd => Op2)));
+ Analyze_And_Resolve (N, Standard_Boolean);
+ return;
- -- For < the Boolean expression is
- -- greater__nn (op2, op1)
+ -- For < the Boolean expression is
+ -- greater__nn (op2, op1)
- elsif Chars (N) = Name_Op_Lt then
- Func_Body := Make_Array_Comparison_Op (Typ1, N);
+ when N_Op_Lt =>
+ Func_Body := Make_Array_Comparison_Op (Typ1, N);
- -- Switch operands
+ -- Switch operands
- Op1 := Right_Opnd (N);
- Op2 := Left_Opnd (N);
+ Op1 := Right_Opnd (N);
+ Op2 := Left_Opnd (N);
- -- For (a >= b) we convert to not (a < b)
+ -- For (a >= b) we convert to not (a < b)
- elsif Chars (N) = Name_Op_Ge then
- Rewrite (N,
- Make_Op_Not (Loc,
- Right_Opnd =>
- Make_Op_Lt (Loc,
- Left_Opnd => Op1,
- Right_Opnd => Op2)));
- Analyze_And_Resolve (N, Standard_Boolean);
- return;
+ when N_Op_Ge =>
+ Rewrite (N,
+ Make_Op_Not (Loc,
+ Right_Opnd =>
+ Make_Op_Lt (Loc,
+ Left_Opnd => Op1,
+ Right_Opnd => Op2)));
+ Analyze_And_Resolve (N, Standard_Boolean);
+ return;
- -- For > the Boolean expression is
- -- greater__nn (op1, op2)
+ -- For > the Boolean expression is
+ -- greater__nn (op1, op2)
- else
- pragma Assert (Chars (N) = Name_Op_Gt);
- Func_Body := Make_Array_Comparison_Op (Typ1, N);
- end if;
+ when N_Op_Gt =>
+ Func_Body := Make_Array_Comparison_Op (Typ1, N);
+
+ when others => raise Program_Error;
+ end case;
Func_Name := Defining_Unit_Name (Specification (Func_Body));
Expr :=
@@ -4496,7 +4498,7 @@ package body Exp_Ch4 is
-- Here we set no initialization on types with constructors since we
-- generate initialization for the separately.
- if Present (Constructor_Name (Directly_Designated_Type (PtrT)))
+ if Needs_Construction (Directly_Designated_Type (PtrT))
and then Nkind (Expression (N)) = N_Identifier
then
Set_No_Initialization (N, False);
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index d48b8f2..d209ab0 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -6250,9 +6250,9 @@ package body Exp_Ch6 is
procedure Prepend_Constructor_Procedure_Prologue
(Spec_Id : Entity_Id; Body_Id : Entity_Id; L : List_Id);
-- If N is the body of a constructor procedure (that is, a procedure
- -- named in a Constructor aspect specification for the type of the
- -- procedure's first parameter), then prepend and analyze the
- -- associated initialization code for that parameter.
+ -- named T'Constructor where T is the type of the procedure's first
+ -- parameter), then prepend and analyze the associated initialization
+ -- code for that parameter.
-- This has nothing to do with CPP constructors.
----------------
@@ -6339,16 +6339,10 @@ package body Exp_Ch6 is
function First_Param_Type return Entity_Id is
(Implementation_Base_Type (Etype (First_Formal (Spec_Id))));
- Is_Constructor_Procedure : constant Boolean :=
- Nkind (Specification (N)) = N_Procedure_Specification
- and then Present (First_Formal (Spec_Id))
- and then Present (Constructor_Name (First_Param_Type))
- and then Chars (Spec_Id) = Chars (Constructor_Name
- (First_Param_Type))
- and then Ekind (First_Formal (Spec_Id)) = E_In_Out_Parameter
- and then Scope (Spec_Id) = Scope (First_Param_Type);
begin
- if not Is_Constructor_Procedure then
+ if not (Nkind (Specification (N)) = N_Procedure_Specification
+ and then Is_Constructor_Procedure (Spec_Id))
+ then
return; -- the usual case
end if;
@@ -6539,7 +6533,8 @@ package body Exp_Ch6 is
Attribute_Name => Name_Super),
Selector_Name =>
Make_Identifier (Loc,
- Chars (Constructor_Name (Parent_Type))));
+ Direct_Attribute_Definition_Name
+ (Parent_Type, Name_Constructor)));
begin
Set_Is_Prefixed_Call (Proc_Name);
@@ -9096,27 +9091,6 @@ package body Exp_Ch6 is
-- tagged, the called function itself must perform the allocation of
-- the return object, so we pass parameters indicating that.
- -- But that's also the case when the result subtype needs finalization
- -- actions because the caller side allocation may result in undesirable
- -- finalization. Consider the following example:
- --
- -- function Make_Lim_Ctrl return Lim_Ctrl is
- -- begin
- -- return Result : Lim_Ctrl := raise Program_Error do
- -- null;
- -- end return;
- -- end Make_Lim_Ctrl;
- --
- -- Obj : Lim_Ctrl_Ptr := new Lim_Ctrl'(Make_Lim_Ctrl);
- --
- -- Even though the size of limited controlled type Lim_Ctrl is known,
- -- allocating Obj at the caller side will chain Obj on Lim_Ctrl_Ptr's
- -- finalization collection. The subsequent call to Make_Lim_Ctrl will
- -- fail during the initialization actions for Result, which means that
- -- Result (and Obj by extension) should not be finalized. However Obj
- -- will be finalized when access type Lim_Ctrl_Ptr goes out of scope
- -- since it is already attached on the its finalization collection.
-
if Needs_BIP_Alloc_Form (Function_Id) then
Temp_Init := Empty;
@@ -9281,11 +9255,7 @@ package body Exp_Ch6 is
end if;
end;
- -- When the function has a controlling result, an allocation-form
- -- parameter must be passed indicating that the caller is allocating
- -- the result object. This is needed because such a function can be
- -- called as a dispatching operation and must be treated similarly
- -- to functions with unconstrained result subtypes.
+ -- Add implicit actuals for the BIP formal parameters, if any
Add_Unconstrained_Actuals_To_Build_In_Place_Call
(Func_Call,
@@ -9310,6 +9280,14 @@ package body Exp_Ch6 is
Add_Access_Actual_To_Build_In_Place_Call
(Func_Call, Function_Id, Return_Obj_Actual);
+ -- If the allocation is done in the caller, create a custom Allocate
+ -- procedure if need be.
+
+ if not Needs_BIP_Alloc_Form (Function_Id) then
+ Build_Allocate_Deallocate_Proc
+ (Declaration_Node (Return_Obj_Access), Mark => Allocator);
+ end if;
+
-- Finally, replace the allocator node with a reference to the temp
Rewrite (Allocator, New_Occurrence_Of (Return_Obj_Access, Loc));
@@ -9771,7 +9749,7 @@ package body Exp_Ch6 is
-- ensure that the heap allocation can properly chain the object
-- and later finalize it when the library unit goes out of scope.
- if Needs_BIP_Collection (Func_Call) then
+ if Needs_BIP_Collection (Function_Id) then
Build_Finalization_Collection
(Typ => Ptr_Typ,
For_Lib_Level => True,
@@ -10334,6 +10312,12 @@ package body Exp_Ch6 is
Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));
begin
+ -- No need for BIP_Collection if allocation is always done in the caller
+
+ if not Needs_BIP_Alloc_Form (Func_Id) then
+ return False;
+ end if;
+
-- A formal for the finalization collection is needed for build-in-place
-- functions whose result type needs finalization or is a tagged type.
-- Tagged primitive build-in-place functions need such a formal because
@@ -10358,12 +10342,6 @@ package body Exp_Ch6 is
Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));
begin
- -- See Make_Build_In_Place_Call_In_Allocator for the rationale
-
- if Needs_BIP_Collection (Func_Id) then
- return True;
- end if;
-
-- A formal giving the allocation method is needed for build-in-place
-- functions whose result type is returned on the secondary stack or
-- is a tagged type. Tagged primitive build-in-place functions need
diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads
index 5919627..3867270 100644
--- a/gcc/ada/exp_ch6.ads
+++ b/gcc/ada/exp_ch6.ads
@@ -301,10 +301,8 @@ package Exp_Ch6 is
-- BIP_Alloc_Form parameter (see type BIP_Formal_Kind).
function Needs_BIP_Collection (Func_Id : Entity_Id) return Boolean;
- -- Ada 2005 (AI-318-02): Return True if the result subtype of function
- -- Func_Id might need finalization actions. This includes build-in-place
- -- functions with tagged result types, since they can be invoked via
- -- dispatching calls, and descendant types may require finalization.
+ -- Ada 2005 (AI-318-02): Return True if the function needs an implicit
+ -- BIP_Collection parameter (see type BIP_Formal_Kind).
function Needs_BIP_Task_Actuals (Func_Id : Entity_Id) return Boolean;
-- Return True if the function returns an object of a type that has tasks.
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 62e9d2c..600d333 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -4758,18 +4758,18 @@ package body Exp_Ch7 is
-- We mark the secondary stack if it is used in this construct, and
-- we're not returning a function result on the secondary stack, except
- -- that a build-in-place function that might or might not return on the
- -- secondary stack always needs a mark. A run-time test is required in
- -- the case where the build-in-place function has a BIP_Alloc extra
- -- parameter (see Create_Finalizer).
+ -- that a build-in-place function that only conditionally returns on
+ -- the secondary stack will also need a mark. A run-time test for doing
+ -- the release call is needed in the case where the build-in-place
+ -- function has a BIP_Alloc_Form parameter (see Create_Finalizer).
Needs_Sec_Stack_Mark : constant Boolean :=
- (Uses_Sec_Stack (Scop)
- and then
- not Sec_Stack_Needed_For_Return (Scop))
- or else
- (Is_Build_In_Place_Function (Scop)
- and then Needs_BIP_Alloc_Form (Scop));
+ Uses_Sec_Stack (Scop)
+ and then
+ (not Sec_Stack_Needed_For_Return (Scop)
+ or else
+ (Is_Build_In_Place_Function (Scop)
+ and then Needs_BIP_Alloc_Form (Scop)));
Needs_Custom_Cleanup : constant Boolean :=
Nkind (N) = N_Block_Statement
@@ -9244,7 +9244,7 @@ package body Exp_Ch7 is
procedure Unnest_Loop (Loop_Stmt : Node_Id) is
- procedure Fixup_Inner_Scopes (Loop_Or_Block : Node_Id);
+ procedure Fixup_Inner_Scopes (N : Node_Id);
-- This procedure fixes the scope for 2 identified cases of incorrect
-- scope information.
--
@@ -9271,6 +9271,9 @@ package body Exp_Ch7 is
-- leaves the Tree in an incoherent state (i.e. the inner procedure must
-- have its enclosing procedure in its scope ancestries).
+ -- The same issue exists for freeze nodes with associated TSS: the node
+ -- is moved but the TSS procedures are not correctly nested.
+
-- 2) The second case happens when an object declaration is created
-- within a loop used to initialize the 'others' components of an
-- aggregate that is nested within a transient scope. When the transient
@@ -9298,40 +9301,62 @@ package body Exp_Ch7 is
-- an actual entity set). But unfortunately this proved harder to
-- implement ???
- procedure Fixup_Inner_Scopes (Loop_Or_Block : Node_Id) is
- Stmt : Node_Id;
- Loop_Or_Block_Ent : Entity_Id;
- Ent_To_Fix : Entity_Id;
- Decl : Node_Id := Empty;
+ procedure Fixup_Inner_Scopes (N : Node_Id) is
+ Stmt : Node_Id := Empty;
+ Ent : Entity_Id;
+ Ent_To_Fix : Entity_Id;
+ Decl : Node_Id := Empty;
+ Elmt : Elmt_Id := No_Elmt;
begin
- pragma Assert (Nkind (Loop_Or_Block) in
- N_Loop_Statement | N_Block_Statement);
-
- Loop_Or_Block_Ent := Entity (Identifier (Loop_Or_Block));
- if Nkind (Loop_Or_Block) = N_Loop_Statement then
- Stmt := First (Statements (Loop_Or_Block));
- else -- N_Block_Statement
- Stmt := First
- (Statements (Handled_Statement_Sequence (Loop_Or_Block)));
- Decl := First (Declarations (Loop_Or_Block));
+ pragma
+ Assert
+ (Nkind (N)
+ in N_Loop_Statement | N_Block_Statement | N_Freeze_Entity);
+
+ if Nkind (N) = N_Freeze_Entity then
+ Ent := Scope (Entity (N));
+ else
+ Ent := Entity (Identifier (N));
end if;
+ case Nkind (N) is
+ when N_Loop_Statement =>
+ Stmt := First (Statements (N));
+
+ when N_Block_Statement =>
+ Stmt := First (Statements (Handled_Statement_Sequence (N)));
+ Decl := First (Declarations (N));
+
+ when N_Freeze_Entity =>
+ if Present (TSS_Elist (N)) then
+ Elmt := First_Elmt (TSS_Elist (N));
+ while Present (Elmt) loop
+ Ent_To_Fix := Node (Elmt);
+ Set_Scope (Ent_To_Fix, Ent);
+ Next_Elmt (Elmt);
+ end loop;
+ end if;
+
+ when others =>
+ pragma Assert (False);
+ end case;
+
-- Fix scopes for any object declaration found in the block
while Present (Decl) loop
if Nkind (Decl) = N_Object_Declaration then
Ent_To_Fix := Defining_Identifier (Decl);
- Set_Scope (Ent_To_Fix, Loop_Or_Block_Ent);
+ Set_Scope (Ent_To_Fix, Ent);
end if;
Next (Decl);
end loop;
while Present (Stmt) loop
- if Nkind (Stmt) = N_Block_Statement
- and then Is_Abort_Block (Stmt)
+ if Nkind (Stmt) = N_Block_Statement and then Is_Abort_Block (Stmt)
then
Ent_To_Fix := Entity (Identifier (Stmt));
- Set_Scope (Ent_To_Fix, Loop_Or_Block_Ent);
- elsif Nkind (Stmt) in N_Block_Statement | N_Loop_Statement
+ Set_Scope (Ent_To_Fix, Ent);
+ elsif Nkind (Stmt)
+ in N_Block_Statement | N_Loop_Statement | N_Freeze_Entity
then
Fixup_Inner_Scopes (Stmt);
end if;
diff --git a/gcc/ada/exp_dbug.ads b/gcc/ada/exp_dbug.ads
index 1a64888..0786c40 100644
--- a/gcc/ada/exp_dbug.ads
+++ b/gcc/ada/exp_dbug.ads
@@ -193,6 +193,25 @@ package Exp_Dbug is
-- extra__messages__Oeq__2
----------------------------------
+ -- Direct Attribute Definitions --
+ ----------------------------------
+
+ -- Direct attribute definitions are subprogram declarations where the
+ -- subprogram name is an attribute reference, eg.:
+ -- procedure T'Constructor (Self...
+ -- defines a constructor. The above rules applied to direct attribute
+ -- definitions would result in names with quotation marks, which are
+ -- typically hard to deal with down the chain. To avoid this problem,
+ -- names of such definitions are encoded with as:
+
+ -- 'D' Prefix_Name '_' Attribute_Name "_Att"
+
+ -- For instance, the constructor above is encoded as Dt_constructor_Att.
+
+ -- Note that, attribute reference with multiple attributes are not
+ -- supported yet ???
+
+ ----------------------------------
-- Resolving Other Name Clashes --
----------------------------------
diff --git a/gcc/ada/exp_strm.adb b/gcc/ada/exp_strm.adb
index 3bb6966..f933a2e 100644
--- a/gcc/ada/exp_strm.adb
+++ b/gcc/ada/exp_strm.adb
@@ -501,6 +501,14 @@ package body Exp_Strm is
then
return Prims (RE_I_LF, RE_W_LF);
+ elsif Is_IEEE_Extended_Precision (U_Type) then
+ -- For 80-bit IEEE extended precision values, we use a special
+ -- write routine that sets the unused bytes to zero. The reason
+ -- why we don't set Stream_Size to 80 and stream only the
+ -- meaningful bits is that the user is allowed to select the XDR
+ -- implementation of streaming at bind time, and XDR does not
+ -- allow 80 bits floating point values.
+ return Prims (RE_I_LLF, RE_W_80IEEE);
elsif P_Size = Standard_Long_Long_Float_Size then
return Prims (RE_I_LLF, RE_W_LLF);
else
diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb
index 58f6689..9a1ed70 100644
--- a/gcc/ada/exp_unst.adb
+++ b/gcc/ada/exp_unst.adb
@@ -220,6 +220,8 @@ package body Exp_Unst is
else
Lev := Lev + 1;
S := Enclosing_Subprogram (S);
+
+ pragma Assert (Present (S));
end if;
end loop;
end Get_Level;
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 4d88626..e2d2554 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -7317,6 +7317,134 @@ package body Exp_Util is
Loc : constant Source_Ptr := Sloc (Var);
Ent : constant Entity_Id := Entity (Var);
+ procedure Find_In_Enclosing_Context
+ (Stmt : Node_Id; Current, Previous : in out Node_Id);
+ -- Locate an object reference inside a composite statement Stmt. On
+ -- entry, Previous and Current should be an object reference and its
+ -- parent, respectively. When search is successful, Current is Stmt and
+ -- Previous is its child node, so the caller can determine in which part
+ -- of the statement the original reference was. When search fails, both
+ -- Current and Previous are Empty.
+
+ function Is_Transient_Action (N : Node_Id) return Boolean;
+ -- Returns True for nodes that belong to a transient action and so they
+ -- have no parent, because they have not been inserted to the tree yet.
+
+ -------------------------------
+ -- Find_In_Enclosing_Context --
+ -------------------------------
+
+ procedure Find_In_Enclosing_Context
+ (Stmt : Node_Id; Current, Previous : in out Node_Id)
+ is
+ begin
+ loop
+ -- If we fall off the top of the tree, then that's odd, but
+ -- perhaps it could occur in some error situation, and the safest
+ -- response is simply to assume that the outcome of the condition
+ -- is unknown. No point in bombing during an attempt to optimize
+ -- things.
+
+ if No (Current) then
+
+ -- In particular, we expect to miss the enclosing conditional
+ -- statement for:
+ -- * references within a freezing action (because their
+ -- location is unrelated to the conditional statement),
+ -- * validity checks (becuase for references inside the
+ -- condition they are inserted before the conditional
+ -- statement itself),
+ -- * source locations before and after the conditionaal
+ -- statement.
+
+ pragma Assert
+ (Inside_Freezing_Actions > 0
+ or else
+ (Ekind (Entity (Var)) = E_Variable
+ and then Present (Validated_Object (Entity (Var))))
+ or else
+ Loc < Sloc (Stmt)
+ or else
+ Loc >= Sloc (Stmt) + Text_Ptr (UI_To_Int (End_Span (Stmt)))
+ or else
+ Serious_Errors_Detected > 0);
+
+ return;
+
+ -- We found the enclosing conditional statement
+
+ elsif Current = Stmt then
+ return;
+
+ -- For itype declarations follow their associated node
+
+ elsif Nkind (Current) = N_Subtype_Declaration
+ and then Is_Itype (Defining_Identifier (Current))
+ then
+ Previous := Current;
+ Current :=
+ Associated_Node_For_Itype (Defining_Identifier (Previous));
+
+ -- If associated node has not been set yet, we can use the
+ -- related expression, which is set earlier.
+ -- ??? this should be investigated
+
+ if No (Current) then
+ Current :=
+ Related_Expression (Defining_Identifier (Previous));
+ end if;
+ pragma Assert (Present (Current));
+
+ -- Same for itypes that have no declaration
+
+ elsif Nkind (Current) = N_Defining_Identifier
+ and then Is_Itype (Current)
+ then
+ pragma Assert (No (Parent (Current)));
+ Previous := Current;
+ Current := Associated_Node_For_Itype (Previous);
+
+ -- For transient actions follow where they will be inserted
+
+ elsif Is_Transient_Action (Current) then
+ Previous := Current;
+ Current :=
+ Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped;
+
+ -- Otherwise, continue climbing
+
+ else
+ Previous := Current;
+ Current := Parent (Current);
+ end if;
+ end loop;
+ end Find_In_Enclosing_Context;
+
+ -------------------------
+ -- Is_Transient_Action --
+ -------------------------
+
+ function Is_Transient_Action (N : Node_Id) return Boolean is
+ begin
+ if Scope_Stack.Last >= Scope_Stack.First
+ and then Scope_Is_Transient
+ and then Is_List_Member (N)
+ then
+ declare
+ Transient_Actions : Scope_Actions renames
+ Scope_Stack.Table (Scope_Stack.Last).Actions_To_Be_Wrapped;
+ begin
+ for Action_Kind in Scope_Actions'Range loop
+ if List_Containing (N) = Transient_Actions (Action_Kind) then
+ return True;
+ end if;
+ end loop;
+ end;
+ end if;
+
+ return False;
+ end Is_Transient_Action;
+
procedure Process_Current_Value_Condition (N : Node_Id; S : Boolean);
-- N is an expression which holds either True (S = True) or False (S =
-- False) in the condition. This procedure digs out the expression and
@@ -7490,156 +7618,71 @@ package body Exp_Util is
declare
CV : constant Node_Id := Current_Value (Ent);
Sens : Boolean;
- Stm : Node_Id;
begin
- -- If statement. Condition is known true in THEN section, known False
- -- in any ELSIF or ELSE part, and unknown outside the IF statement.
-
- if Nkind (CV) = N_If_Statement then
+ -- For IF statement the condition is known true in THEN section,
+ -- known False in any ELSIF or ELSE part, and unknown outside the
+ -- IF statement.
- -- Before start of IF statement
-
- if Loc < Sloc (CV) then
- return;
-
- -- In condition of IF statement
-
- elsif In_Subtree (N => Var, Root => Condition (CV)) then
- return;
+ if Nkind (CV) in N_If_Statement | N_Elsif_Part then
- -- After end of IF statement
-
- elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
- return;
- end if;
-
- -- At this stage we know that we are within the IF statement, but
- -- unfortunately, the tree does not record the SLOC of the ELSE so
- -- we cannot use a simple SLOC comparison to distinguish between
- -- the then/else statements, so we have to climb the tree.
+ -- At this stage we know that we are within the conditional
+ -- statement, but we have to climb the tree to know in which
+ -- part, e.g. in THEN or ELSE statements of an IF statement.
declare
- N : Node_Id;
-
- begin
- N := Parent (Var);
- while Parent (N) /= CV loop
- N := Parent (N);
+ If_Stmt : constant Node_Id :=
+ (if Nkind (CV) = N_If_Statement
+ then CV
+ else Parent (CV));
- -- If we fall off the top of the tree, then that's odd, but
- -- perhaps it could occur in some error situation, and the
- -- safest response is simply to assume that the outcome of
- -- the condition is unknown. No point in bombing during an
- -- attempt to optimize things.
+ Previous : Node_Id := Var;
+ Current : Node_Id := Parent (Var);
- if No (N) then
- return;
- end if;
- end loop;
-
- -- Now we have N pointing to a node whose parent is the IF
- -- statement in question, so now we can tell if we are within
- -- the THEN statements.
-
- if Is_List_Member (N)
- and then List_Containing (N) = Then_Statements (CV)
- then
- Sens := True;
-
- -- If the variable reference does not come from source, we
- -- cannot reliably tell whether it appears in the else part.
- -- In particular, if it appears in generated code for a node
- -- that requires finalization, it may be attached to a list
- -- that has not been yet inserted into the code. For now,
- -- treat it as unknown.
+ begin
+ -- An ELSIF part whose condition is false could have been
+ -- already rewritten into NULL statement and we are already
+ -- past the statements inside that ELSIF part.
- elsif not Comes_From_Source (N) then
+ if Nkind (If_Stmt) /= N_If_Statement then
+ pragma Assert
+ (Nkind (CV) = N_Elsif_Part
+ and then Is_Rewrite_Substitution (If_Stmt));
return;
-
- -- Otherwise we must be in ELSIF or ELSE part
-
- else
- Sens := False;
end if;
- end;
- -- ELSIF part. Condition is known true within the referenced
- -- ELSIF, known False in any subsequent ELSIF or ELSE part,
- -- and unknown before the ELSE part or after the IF statement.
-
- elsif Nkind (CV) = N_Elsif_Part then
-
- -- if the Elsif_Part had condition_actions, the elsif has been
- -- rewritten as a nested if, and the original elsif_part is
- -- detached from the tree, so there is no way to obtain useful
- -- information on the current value of the variable.
- -- Can this be improved ???
-
- if No (Parent (CV)) then
- return;
- end if;
-
- Stm := Parent (CV);
-
- -- If the tree has been otherwise rewritten there is nothing
- -- else to be done either.
-
- if Nkind (Stm) /= N_If_Statement then
- return;
- end if;
-
- -- Before start of ELSIF part
-
- if Loc < Sloc (CV) then
- return;
+ Find_In_Enclosing_Context (If_Stmt, Current, Previous);
- -- In condition of ELSIF part
-
- elsif In_Subtree (N => Var, Root => Condition (CV)) then
- return;
-
- -- After end of IF statement
+ -- Check whether the reference is in the IF, THEN or ELSE/ELSIF
+ -- part.
- elsif Loc >= Sloc (Stm) +
- Text_Ptr (UI_To_Int (End_Span (Stm)))
- then
- return;
- end if;
+ if Current = If_Stmt then
- -- Again we lack the SLOC of the ELSE, so we need to climb the
- -- tree to see if we are within the ELSIF part in question.
+ -- Ignore references from within the IF condition itself
- declare
- N : Node_Id;
+ if Previous = Condition (If_Stmt) then
+ return;
- begin
- N := Parent (Var);
- while Parent (N) /= Stm loop
- N := Parent (N);
+ -- Guard against if-statements coming from if-statements
+ -- with broken chain of parents.
- -- If we fall off the top of the tree, then that's odd, but
- -- perhaps it could occur in some error situation, and the
- -- safest response is simply to assume that the outcome of
- -- the condition is unknown. No point in bombing during an
- -- attempt to optimize things.
+ elsif Is_List_Member (Previous) then
+ pragma Assert (
+ List_Containing (Previous)
+ in Then_Statements (If_Stmt)
+ | Elsif_Parts (If_Stmt)
+ | Else_Statements (If_Stmt));
- if No (N) then
+ Sens :=
+ (if CV = If_Stmt
+ then List_Containing (Previous) = Then_Statements (CV)
+ else Previous = CV);
+ else
+ pragma Assert (From_Conditional_Expression (If_Stmt));
return;
end if;
- end loop;
-
- -- Now we have N pointing to a node whose parent is the IF
- -- statement in question, so see if is the ELSIF part we want.
- -- the THEN statements.
-
- if N = CV then
- Sens := True;
-
- -- Otherwise we must be in subsequent ELSIF or ELSE part
-
else
- Sens := False;
+ return;
end if;
end;
@@ -7650,26 +7693,31 @@ package body Exp_Util is
declare
Loop_Stmt : constant Node_Id := Parent (CV);
+ Previous : Node_Id := Var;
+ Current : Node_Id := Parent (Var);
+
begin
- -- Before start of body of loop
+ pragma Assert (Nkind (Loop_Stmt) = N_Loop_Statement);
- if Loc < Sloc (Loop_Stmt) then
- return;
+ Find_In_Enclosing_Context (Loop_Stmt, Current, Previous);
- -- In condition of while loop
+ -- Check whether the reference is inside the WHILE loop
- elsif In_Subtree (N => Var, Root => Condition (CV)) then
- return;
+ if Current = Loop_Stmt then
- -- After end of LOOP statement
+ -- Ignore references from within the WHILE condition itself
- elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
- return;
+ if Previous = Iteration_Scheme (Loop_Stmt) then
+ return;
- -- We are within the body of the loop
+ else
+ pragma Assert
+ (List_Containing (Previous) = Statements (Loop_Stmt));
+ Sens := True;
+ end if;
else
- Sens := True;
+ return;
end if;
end;
diff --git a/gcc/ada/fname.adb b/gcc/ada/fname.adb
index 6022d3b..c914c55 100644
--- a/gcc/ada/fname.adb
+++ b/gcc/ada/fname.adb
@@ -134,19 +134,6 @@ package body Fname is
Renamings_Included : Boolean := True) return Boolean
is
begin
- -- Definitely false if longer than 12 characters (8.3), except for the
- -- Interfaces packages and also the implementation units of the 128-bit
- -- types under System.
-
- if Fname'Length > 12
- and then Fname (Fname'First .. Fname'First + 1) /= "i-"
- and then Fname (Fname'First .. Fname'First + 1) /= "s-"
- and then not Has_Prefix (Fname, "system-")
- and then not Has_Prefix (Fname, "interfac__")
- then
- return False;
- end if;
-
if not Has_Internal_Extension (Fname) then
return False;
end if;
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index d8fdc30..66145e5 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -8382,7 +8382,8 @@ package body Freeze is
-- and Per-Object Expressions" will suppress the insertion, and the
-- freeze node will be dropped on the floor.
- if Saved_Ghost_Config.Ghost_Mode = Ignore
+ if not CodePeer_Mode
+ and then Saved_Ghost_Config.Ghost_Mode = Ignore
and then Ghost_Config.Ghost_Mode /= Ignore
and then Present (Ghost_Config.Ignored_Ghost_Region)
then
diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads
index 6cd1355..d25006c 100644
--- a/gcc/ada/gen_il-fields.ads
+++ b/gcc/ada/gen_il-fields.ads
@@ -131,7 +131,6 @@ package Gen_IL.Fields is
Corresponding_Stub,
Dcheck_Function,
Declarations,
- Default_Expression,
Default_Storage_Pool,
Default_Name,
Default_Subtype_Mark,
@@ -153,7 +152,6 @@ package Gen_IL.Fields is
Do_Length_Check,
Do_Overflow_Check,
Do_Range_Check,
- Do_Storage_Check,
Elaborate_All_Desirable,
Elaborate_All_Present,
Elaborate_Desirable,
@@ -161,7 +159,6 @@ package Gen_IL.Fields is
Else_Actions,
Else_Statements,
Elsif_Parts,
- Enclosing_Variant,
End_Label,
End_Span,
Entity_Or_Associated_Node,
@@ -204,7 +201,6 @@ package Gen_IL.Fields is
Generic_Parent,
Generic_Parent_Type,
Handled_Statement_Sequence,
- Handler_List_Entry,
Has_Created_Identifier,
Has_Dereference_Action,
Has_Dynamic_Length_Check,
@@ -283,7 +279,6 @@ package Gen_IL.Fields is
Is_Static_Coextension,
Is_Static_Expression,
Is_Structural,
- Is_Subprogram_Descriptor,
Is_Task_Allocation_Block,
Is_Task_Body_Procedure,
Is_Task_Master,
@@ -376,7 +371,6 @@ package Gen_IL.Fields is
Reason,
Record_Extension_Part,
Redundant_Use,
- Renaming_Exception,
Result_Definition,
Return_Object_Declarations,
Return_Statement_Entity,
@@ -480,8 +474,6 @@ package Gen_IL.Fields is
Component_Clause,
Component_Size,
Component_Type,
- Constructor_List,
- Constructor_Name,
Continue_Mark,
Contract,
Contract_Wrapper,
@@ -614,7 +606,6 @@ package Gen_IL.Fields is
Has_Own_Invariants,
Has_Partial_Visible_Refinement,
Has_Per_Object_Constraint,
- Has_Pragma_Controlled,
Has_Pragma_Elaborate_Body,
Has_Pragma_Inline,
Has_Pragma_Inline_Always,
@@ -808,7 +799,6 @@ package Gen_IL.Fields is
Is_Unchecked_Union,
Is_Underlying_Full_View,
Is_Underlying_Record_View,
- Is_Unimplemented,
Is_Unsigned_Type,
Is_Uplevel_Referenced_Entity,
Is_Valued_Procedure,
@@ -818,6 +808,7 @@ package Gen_IL.Fields is
Is_Volatile_Object,
Is_Volatile_Full_Access,
Is_Wrapper,
+ Is_IEEE_Extended_Precision,
Itype_Printed,
Kill_Elaboration_Checks,
Known_To_Have_Preelab_Init,
diff --git a/gcc/ada/gen_il-gen-gen_entities.adb b/gcc/ada/gen_il-gen-gen_entities.adb
index bd091cb..d3ac63a 100644
--- a/gcc/ada/gen_il-gen-gen_entities.adb
+++ b/gcc/ada/gen_il-gen-gen_entities.adb
@@ -203,7 +203,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (Is_Unchecked_Union, Flag, Impl_Base_Type_Only),
Sm (Is_Underlying_Full_View, Flag),
Sm (Is_Underlying_Record_View, Flag, Base_Type_Only),
- Sm (Is_Unimplemented, Flag),
Sm (Is_Uplevel_Referenced_Entity, Flag),
Sm (Is_Visible_Formal, Flag),
Sm (Is_Visible_Lib_Unit, Flag),
@@ -456,8 +455,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Pre => "Ekind (Base_Type (N)) in Access_Subprogram_Kind"),
Sm (Class_Wide_Equivalent_Type, Node_Id),
Sm (Class_Wide_Type, Node_Id),
- Sm (Constructor_List, Elist_Id),
- Sm (Constructor_Name, Node_Id),
Sm (Contract, Node_Id),
Sm (Current_Use_Clause, Node_Id),
Sm (Derived_Type_Link, Node_Id),
@@ -630,7 +627,8 @@ begin -- Gen_IL.Gen.Gen_Entities
-- first named subtype).
Ab (Float_Kind, Real_Kind,
- (Sm (Digits_Value, Upos)));
+ (Sm (Digits_Value, Upos),
+ Sm (Is_IEEE_Extended_Precision, Flag)));
Cc (E_Floating_Point_Type, Float_Kind);
-- Floating point type, used for the anonymous base type of the
@@ -646,7 +644,6 @@ begin -- Gen_IL.Gen.Gen_Entities
(Sm (Associated_Storage_Pool, Node_Id, Root_Type_Only),
Sm (Directly_Designated_Type, Node_Id),
Sm (Finalization_Collection, Node_Id, Root_Type_Only),
- Sm (Has_Pragma_Controlled, Flag, Impl_Base_Type_Only),
Sm (Has_Storage_Size_Clause, Flag, Impl_Base_Type_Only),
Sm (Is_Access_Constant, Flag),
Sm (Is_Local_Anonymous_Access, Flag),
diff --git a/gcc/ada/gen_il-gen-gen_nodes.adb b/gcc/ada/gen_il-gen-gen_nodes.adb
index 9ce2511..e6e00ff 100644
--- a/gcc/ada/gen_il-gen-gen_nodes.adb
+++ b/gcc/ada/gen_il-gen-gen_nodes.adb
@@ -192,14 +192,24 @@ begin -- Gen_IL.Gen.Gen_Nodes
(Sy (Char_Literal_Value, Unat)));
Ab (N_Op, N_Has_Entity,
- (Sm (Chars, Name_Id),
- Sm (Do_Overflow_Check, Flag),
+ (Sm (Do_Overflow_Check, Flag),
Sm (Has_Private_View, Flag),
Sm (Has_Secondary_Private_View, Flag)));
Ab (N_Binary_Op, N_Op,
(Sy (Left_Opnd, Node_Id),
- Sy (Right_Opnd, Node_Id)));
+ Sy (Right_Opnd, Node_Id),
+ Sy (Chars, Name_Id, Default_No_Name)));
+ -- N_Binary_Op and N_Unary_Op do not strictly need Chars, since the value
+ -- is fully determined by the Nkind. However, for example, Errout refers to
+ -- Chars without knowing statically whether the Nkind is in N_Op.
+ -- In any case, we don't inherit Chars from N_Op, because we want it to
+ -- come after the other syntactic fields, so that positional notation can
+ -- be used in calls to Make_Op_Add and friends.
+ --
+ -- Make_Op_Add and friends will now have a Chars parameter. Callers
+ -- should always use the default, because the Chars field is set
+ -- properly as a special case (see Gen_IL.Gen).
Cc (N_Op_Add, N_Binary_Op);
@@ -259,7 +269,8 @@ begin -- Gen_IL.Gen.Gen_Nodes
Cc (N_Op_Shift_Right_Arithmetic, N_Op_Shift);
Ab (N_Unary_Op, N_Op,
- (Sy (Right_Opnd, Node_Id)));
+ (Sy (Right_Opnd, Node_Id),
+ Sy (Chars, Name_Id, Default_No_Name)));
Cc (N_Op_Abs, N_Unary_Op);
Cc (N_Op_Minus, N_Unary_Op);
@@ -290,7 +301,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
Ab (N_Short_Circuit, N_Subexpr,
(Sy (Left_Opnd, Node_Id),
Sy (Right_Opnd, Node_Id),
- Sm (Actions, List_Id)));
+ Sy (Actions, List_Id, Default_No_List)));
Cc (N_And_Then, N_Short_Circuit);
Cc (N_Or_Else, N_Short_Circuit);
@@ -403,7 +414,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sy (Null_Exclusion_Present, Flag, Default_False),
Sy (Expression, Node_Id, Default_Empty),
Sm (For_Special_Return_Object, Flag),
- Sm (Do_Storage_Check, Flag),
Sm (Is_Dynamic_Coextension, Flag),
Sm (Is_Static_Coextension, Flag),
Sm (No_Initialization, Flag),
@@ -515,7 +525,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sy (Null_Exclusion_Present, Flag, Default_False),
Sy (Access_Definition, Node_Id, Default_Empty),
Sy (Subtype_Mark, Node_Id, Default_Empty),
- Sy (Default_Expression, Node_Id, Default_Empty),
+ Sy (Expression, Node_Id, Default_Empty),
Sy (Aspect_Specifications, List_Id, Default_No_List),
Sm (More_Ids, Flag),
Sm (Prev_Ids, Flag)));
@@ -568,8 +578,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sm (Assignment_OK, Flag),
Sm (Corresponding_Generic_Association, Node_Id),
Sm (Exception_Junk, Flag),
- Sm (Handler_List_Entry, Node_Id),
- Sm (Is_Subprogram_Descriptor, Flag),
Sm (More_Ids, Flag),
Sm (No_Initialization, Flag),
Sm (Prev_Ids, Flag),
@@ -730,7 +738,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sm (Activation_Chain_Entity, Node_Id),
Sm (Acts_As_Spec, Flag),
Sm (Corresponding_Entry_Body, Node_Id),
- Sm (Do_Storage_Check, Flag),
Sm (Has_Relative_Deadline_Pragma, Flag),
Sm (Is_Entry_Barrier_Function, Flag),
Sm (Is_Protected_Subprogram_Body, Flag),
@@ -1154,9 +1161,9 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sm (Target, Node_Id)));
Cc (N_Case_Expression_Alternative, Node_Kind,
- (Sm (Actions, List_Id),
- Sy (Discrete_Choices, List_Id),
+ (Sy (Discrete_Choices, List_Id),
Sy (Expression, Node_Id, Default_Empty),
+ Sy (Actions, List_Id, Default_No_List),
Sm (Has_SP_Choice, Flag)));
Cc (N_Case_Statement_Alternative, Node_Kind,
@@ -1283,10 +1290,9 @@ begin -- Gen_IL.Gen.Gen_Nodes
Cc (N_Exception_Declaration, N_Declaration,
(Sy (Defining_Identifier, Node_Id),
Sy (Aspect_Specifications, List_Id, Default_No_List),
- Sm (Expression, Node_Id),
+ Sy (Expression, Node_Id, Default_Empty),
Sm (More_Ids, Flag),
- Sm (Prev_Ids, Flag),
- Sm (Renaming_Exception, Node_Id)));
+ Sm (Prev_Ids, Flag)));
Cc (N_Exception_Handler, Node_Kind,
(Sy (Choice_Parameter, Node_Id, Default_Empty),
@@ -1426,7 +1432,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sy (Parameter_Type, Node_Id),
Sy (Expression, Node_Id, Default_Empty),
Sy (Aspect_Specifications, List_Id, Default_No_List),
- Sm (Default_Expression, Node_Id),
Sm (More_Ids, Flag),
Sm (Prev_Ids, Flag)));
@@ -1531,7 +1536,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
(Sy (Discrete_Choices, List_Id),
Sy (Component_List, Node_Id),
Sm (Dcheck_Function, Node_Id),
- Sm (Enclosing_Variant, Node_Id),
Sm (Has_SP_Choice, Flag),
Sm (Present_Expr, Uint)));
diff --git a/gcc/ada/gen_il-gen.adb b/gcc/ada/gen_il-gen.adb
index 5eb1a58..873c3cd 100644
--- a/gcc/ada/gen_il-gen.adb
+++ b/gcc/ada/gen_il-gen.adb
@@ -167,7 +167,6 @@ package body Gen_IL.Gen is
-- Check that syntactic fields precede semantic fields. Note that this
-- check is happening before we compute inherited fields.
- -- Exempt Chars and Actions from this rule, for now.
declare
Semantic_Seen : Boolean := False;
@@ -178,11 +177,8 @@ package body Gen_IL.Gen is
raise Illegal with
"syntactic fields must precede semantic ones " & Image (T);
end if;
-
else
- if Fields (J).F not in Chars | Actions then
- Semantic_Seen := True;
- end if;
+ Semantic_Seen := True;
end if;
end loop;
end;
@@ -509,14 +505,11 @@ package body Gen_IL.Gen is
Node_Field_Types_Used, Entity_Field_Types_Used : Type_Set;
Setter_Needs_Parent : Field_Set :=
- (Actions | Expression | Then_Actions | Else_Actions => True,
+ (Then_Actions | Else_Actions => True,
others => False);
-- Set of fields where the setter should set the Parent. True for
- -- syntactic fields of type Node_Id and List_Id, but with some
- -- exceptions. Expression is syntactic AND semantic, and the Parent
- -- is needed. Default_Expression is also both, but the Parent is not
- -- needed. Then_Actions and Else_Actions are not syntactic, but the
- -- Parent is needed.
+ -- syntactic fields of type Node_Id and List_Id. Then_Actions and
+ -- Else_Actions are not syntactic, but the Parent is needed.
--
-- Computed in Check_For_Syntactic_Field_Mismatch.
@@ -896,7 +889,7 @@ package body Gen_IL.Gen is
-- For example, Left_Opnd comes before Right_Opnd,
-- which wouldn't be the case if Right_Opnd were
-- inherited from N_Op.
- ((T = N_Op and then F = Right_Opnd)
+ ((T = N_Op and then F in Right_Opnd | Chars)
or else (T = N_Renaming_Declaration and then F = Name)
or else (T = N_Generic_Renaming_Declaration and then F = Name)
or else F in Defining_Unit_Name
@@ -1301,26 +1294,15 @@ package body Gen_IL.Gen is
end if;
end loop;
- -- The following fields violate this rule. We might want to
- -- simplify by getting rid of these cases, but we allow them
- -- for now. At least, we don't want to add any new cases of
- -- syntactic/semantic mismatch.
+ if Syntactic_Seen and Semantic_Seen then
+ raise Illegal with
+ "syntactic/semantic mismatch for " & Image (F);
+ end if;
- if F in Chars | Actions | Expression | Default_Expression
+ if Field_Table (F).Field_Type in Traversed_Field_Type
+ and then Syntactic_Seen
then
- pragma Assert (Syntactic_Seen and Semantic_Seen);
-
- else
- if Syntactic_Seen and Semantic_Seen then
- raise Illegal with
- "syntactic/semantic mismatch for " & Image (F);
- end if;
-
- if Field_Table (F).Field_Type in Traversed_Field_Type
- and then Syntactic_Seen
- then
- Setter_Needs_Parent (F) := True;
- end if;
+ Setter_Needs_Parent (F) := True;
end if;
end;
end if;
@@ -2675,7 +2657,7 @@ package body Gen_IL.Gen is
if Is_Descendant (N_Op, T) then
-- Special cases for N_Op nodes: fill in the Chars and Entity
- -- fields even though they were not passed in.
+ -- fields. Assert that the Chars passed in is defaulted.
declare
Op : constant String := Image_Sans_N (T);
@@ -2705,6 +2687,7 @@ package body Gen_IL.Gen is
-- "Op_", but the Name_Id constant does not.
begin
+ Put (S, "pragma Assert (Chars = No_Name);" & LF);
Put (S, "Set_Chars (N, Name_" & Op_Name & ");" & LF);
Put (S, "Set_Entity (N, Standard_" & Op & ");" & LF);
end;
@@ -2990,7 +2973,7 @@ package body Gen_IL.Gen is
(if T in Entity_Type and then F in Node_Field then
" -- N" else "");
-- A comment to put out for fields of entities that are
- -- shared with nodes, such as Chars.
+ -- shared with nodes.
begin
while First_Bit < Type_Bit_Size_Aligned (T) loop
diff --git a/gcc/ada/gen_il-gen.ads b/gcc/ada/gen_il-gen.ads
index cb364ad..149afe1 100644
--- a/gcc/ada/gen_il-gen.ads
+++ b/gcc/ada/gen_il-gen.ads
@@ -48,14 +48,12 @@
-- If a field is syntactic, then the constructors in Nmake take a parameter to
-- initialize that field. In addition, the tree-traversal routines in Atree
-- (Traverse_Func and Traverse_Proc) traverse syntactic fields that are of
--- type Node_Id (or subtypes of Node_Id) or List_Id. Finally, (with some
--- exceptions documented in the body) the setter for a syntactic node or list
--- field "Set_F (N, Val)" will set the Parent of Val to N, unless Val is Empty
--- or Error[_List].
+-- type Node_Id (or subtypes of Node_Id) or List_Id. Finally, the setter for a
+-- syntactic node or list field "Set_F (N, Val)" will set the Parent of Val to
+-- N, unless Val is Empty or Error[_List].
--
--- Note that the same field can be syntactic in some node types but semantic
--- in other node types. This is an added complexity that we might want to
--- eliminate someday. We shouldn't add any new such cases.
+-- No syntactic/semantic mixing: the same field cannot be syntactic in some
+-- node types but semantic in other node types.
--
-- A "program" written in the Gen_IL.Gen language consists of calls to the
-- "Create_..." routines below, followed by a call to Compile, also below. In
diff --git a/gcc/ada/gen_il-internals.adb b/gcc/ada/gen_il-internals.adb
index 77685f2..bd2d480 100644
--- a/gcc/ada/gen_il-internals.adb
+++ b/gcc/ada/gen_il-internals.adb
@@ -311,6 +311,8 @@ package body Gen_IL.Internals is
return "Is_Elaboration_Warnings_OK_Id";
when Is_Elaboration_Warnings_OK_Node =>
return "Is_Elaboration_Warnings_OK_Node";
+ when Is_IEEE_Extended_Precision =>
+ return "Is_IEEE_Extended_Precision";
when Is_Known_Guaranteed_ABE =>
return "Is_Known_Guaranteed_ABE";
when Is_RACW_Stub_Type =>
diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
index e7a55ef..d49d94d 100644
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -740,6 +740,14 @@ package body Ghost is
then
return True;
+ -- It is always legal to use a ghost prefix. More complex
+ -- scenarios are analyzed for the selector.
+
+ elsif Nkind (Par) = N_Selected_Component
+ and then Prefix (Par) = Prev
+ then
+ return True;
+
elsif Is_OK_Declaration (Par) then
return True;
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 68a3c14..23c9977 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT Reference Manual , Oct 17, 2025
+GNAT Reference Manual , Oct 31, 2025
AdaCore
@@ -20724,8 +20724,7 @@ machines with strict alignment requirements, GNAT
checks (at compile time if possible, generating a warning, or at execution
time with a run-time check) that the alignment is appropriate. If the
run-time check fails, then @code{Program_Error} is raised. This run-time
-check is suppressed if range checks are suppressed, or if the special GNAT
-check Alignment_Check is suppressed, or if
+check is suppressed if the GNAT check Alignment_Check is suppressed, or if
@code{pragma Restrictions (No_Elaboration_Code)} is in effect. It is also
suppressed by default on non-strict alignment machines (such as the x86).
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 86b2cbc..4789757 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Oct 06, 2025
+GNAT User's Guide for Native Platforms , Oct 31, 2025
AdaCore
@@ -30333,8 +30333,8 @@ to permit their use in free software.
@printindex ge
-@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ }
@anchor{d2}@w{ }
+@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ }
@c %**end of body
@bye
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index 9e60fa8..a966c28 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -3380,15 +3380,6 @@ package body Inline is
-- be performed in a separate pass, using an instantiation of the
-- previous subprogram over aspect specifications reachable from N.
- function Process_Sloc (Nod : Node_Id) return Traverse_Result;
- -- If the call being expanded is that of an internal subprogram, set the
- -- sloc of the generated block to that of the call itself, so that the
- -- expansion is skipped by the "next" command in gdb. Same processing
- -- for a subprogram in a predefined file, e.g. Ada.Tags. If
- -- Debug_Generated_Code is true, suppress this change to simplify our
- -- own development. Same in GNATprove mode, to ensure that warnings and
- -- diagnostics point to the proper location.
-
procedure Reset_Dispatching_Calls (N : Node_Id);
-- In subtree N search for occurrences of dispatching calls that use the
-- Ada 2005 Object.Operation notation and the object is a formal of the
@@ -3647,22 +3638,6 @@ package body Inline is
procedure Replace_Formals_In_Aspects is
new Traverse_Proc (Process_Formals_In_Aspects);
- ------------------
- -- Process_Sloc --
- ------------------
-
- function Process_Sloc (Nod : Node_Id) return Traverse_Result is
- begin
- if not Debug_Generated_Code then
- Set_Sloc (Nod, Sloc (N));
- Set_Comes_From_Source (Nod, False);
- end if;
-
- return OK;
- end Process_Sloc;
-
- procedure Reset_Slocs is new Traverse_Proc (Process_Sloc);
-
------------------------------
-- Reset_Dispatching_Calls --
------------------------------
@@ -4176,13 +4151,6 @@ package body Inline is
Replace_Formals_In_Aspects (Blk);
Set_Parent (Blk, N);
- if GNATprove_Mode then
- null;
-
- elsif not Comes_From_Source (Subp) or else Is_Predef then
- Reset_Slocs (Blk);
- end if;
-
if Is_Unc_Decl then
-- No action needed since return statement has been already removed
diff --git a/gcc/ada/libgnat/a-cbmutr.adb b/gcc/ada/libgnat/a-cbmutr.adb
index 9d9d21d..bd6b135 100644
--- a/gcc/ada/libgnat/a-cbmutr.adb
+++ b/gcc/ada/libgnat/a-cbmutr.adb
@@ -2357,11 +2357,11 @@ is
end Rec;
begin
- if First_Child (Root (V)) = No_Element then
+ if Is_Empty (V) then
Array_Before (S);
Array_After (S);
else
- Rec (First_Child (Root (V)));
+ Rec (Root (V));
end if;
end Put_Image;
diff --git a/gcc/ada/libgnat/a-cimutr.adb b/gcc/ada/libgnat/a-cimutr.adb
index b84eb16..0c6d338 100644
--- a/gcc/ada/libgnat/a-cimutr.adb
+++ b/gcc/ada/libgnat/a-cimutr.adb
@@ -1910,11 +1910,11 @@ is
end Rec;
begin
- if First_Child (Root (V)) = No_Element then
+ if Is_Empty (V) then
Array_Before (S);
Array_After (S);
else
- Rec (First_Child (Root (V)));
+ Rec (Root (V));
end if;
end Put_Image;
diff --git a/gcc/ada/libgnat/a-comutr.adb b/gcc/ada/libgnat/a-comutr.adb
index df3741b..2d6393d 100644
--- a/gcc/ada/libgnat/a-comutr.adb
+++ b/gcc/ada/libgnat/a-comutr.adb
@@ -1844,11 +1844,11 @@ is
end Rec;
begin
- if First_Child (Root (V)) = No_Element then
+ if Is_Empty (V) then
Array_Before (S);
Array_After (S);
else
- Rec (First_Child (Root (V)));
+ Rec (Root (V));
end if;
end Put_Image;
diff --git a/gcc/ada/libgnat/s-dwalin.adb b/gcc/ada/libgnat/s-dwalin.adb
index 1e97a47..713aad4 100644
--- a/gcc/ada/libgnat/s-dwalin.adb
+++ b/gcc/ada/libgnat/s-dwalin.adb
@@ -1912,11 +1912,12 @@ package body System.Dwarf_Lines is
------------------------
procedure Symbolic_Traceback
- (Cin : Dwarf_Context;
- Traceback : STE.Tracebacks_Array;
- Suppress_Hex : Boolean;
- Symbol_Found : out Boolean;
- Res : in out System.Bounded_Strings.Bounded_String)
+ (Cin : Dwarf_Context;
+ Traceback : STE.Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Symbol_Found : out Boolean;
+ Res : in out System.Bounded_Strings.Bounded_String)
is
use Ada.Characters.Handling;
C : Dwarf_Context := Cin;
@@ -1953,7 +1954,7 @@ package body System.Dwarf_Lines is
-- If we're not requested to suppress hex addresses, emit it now.
- if not Suppress_Hex then
+ if not Suppress_Hex and then not Subprg_Name_Only then
Append_Address (Res, Addr_In_Traceback);
Append (Res, ' ');
end if;
@@ -2006,10 +2007,12 @@ package body System.Dwarf_Lines is
Append (Res, "???");
end if;
- Append (Res, " at ");
- Append (Res, String (File_Name (1 .. Last)));
- Append (Res, ':');
- Append (Res, Line_Image (2 .. Line_Image'Last));
+ if not Subprg_Name_Only then
+ Append (Res, " at ");
+ Append (Res, String (File_Name (1 .. Last)));
+ Append (Res, ':');
+ Append (Res, Line_Image (2 .. Line_Image'Last));
+ end if;
end;
else
if Subprg_Name.Len > 0 then
@@ -2020,7 +2023,9 @@ package body System.Dwarf_Lines is
Append (Res, "???");
end if;
- Append (Res, " at ???");
+ if not Subprg_Name_Only then
+ Append (Res, " at ???");
+ end if;
end if;
Append (Res, ASCII.LF);
diff --git a/gcc/ada/libgnat/s-dwalin.ads b/gcc/ada/libgnat/s-dwalin.ads
index c65d66e..641e515 100644
--- a/gcc/ada/libgnat/s-dwalin.ads
+++ b/gcc/ada/libgnat/s-dwalin.ads
@@ -80,11 +80,12 @@ package System.Dwarf_Lines is
-- Read symbol information to speed up Symbolic_Traceback.
procedure Symbolic_Traceback
- (Cin : Dwarf_Context;
- Traceback : STE.Tracebacks_Array;
- Suppress_Hex : Boolean;
- Symbol_Found : out Boolean;
- Res : in out System.Bounded_Strings.Bounded_String);
+ (Cin : Dwarf_Context;
+ Traceback : STE.Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Symbol_Found : out Boolean;
+ Res : in out System.Bounded_Strings.Bounded_String);
-- Generate a string for a traceback suitable for displaying to the user.
-- If one or more symbols are found, Symbol_Found is set to True. This
-- allows the caller to fall back to hexadecimal addresses.
diff --git a/gcc/ada/libgnat/s-stratt.adb b/gcc/ada/libgnat/s-stratt.adb
index 844c530..9315ae1 100644
--- a/gcc/ada/libgnat/s-stratt.adb
+++ b/gcc/ada/libgnat/s-stratt.adb
@@ -1036,4 +1036,21 @@ package body System.Stream_Attributes is
Ada.Streams.Write (Stream.all, From_WWC (Item));
end W_WWC;
+ procedure W_80IEEE (Stream : not null access RST; Item : Long_Long_Float) is
+ begin
+ if XDR_Support then
+ XDR.W_LLF (Stream, Item);
+ return;
+ end if;
+
+ declare
+ X : S_LLF := From_LLF (Item);
+
+ N_IEEE_Extended_Precision_Bytes : constant := 10;
+ begin
+ X (N_IEEE_Extended_Precision_Bytes + 1 .. X'Last) := (others => 0);
+ Ada.Streams.Write (Stream.all, X);
+ end;
+ end W_80IEEE;
+
end System.Stream_Attributes;
diff --git a/gcc/ada/libgnat/s-stratt.ads b/gcc/ada/libgnat/s-stratt.ads
index 87f1357..9f27f5a 100644
--- a/gcc/ada/libgnat/s-stratt.ads
+++ b/gcc/ada/libgnat/s-stratt.ads
@@ -171,6 +171,8 @@ package System.Stream_Attributes is
procedure W_WC (Stream : not null access RST; Item : Wide_Character);
procedure W_WWC (Stream : not null access RST; Item : Wide_Wide_Character);
+ procedure W_80IEEE (Stream : not null access RST; Item : Long_Long_Float);
+
function Block_IO_OK return Boolean;
-- Indicate whether the current setting supports block IO. See
-- System.Strings.Stream_Ops (s-ststop) for details on block IO.
diff --git a/gcc/ada/libgnat/s-stratt__cheri.adb b/gcc/ada/libgnat/s-stratt__cheri.adb
index aefb8b3..9e336f3 100644
--- a/gcc/ada/libgnat/s-stratt__cheri.adb
+++ b/gcc/ada/libgnat/s-stratt__cheri.adb
@@ -1016,4 +1016,21 @@ package body System.Stream_Attributes is
Ada.Streams.Write (Stream.all, From_WWC (Item));
end W_WWC;
+ procedure W_80IEEE (Stream : not null access RST; Item : Long_Long_Float) is
+ begin
+ if XDR_Support then
+ XDR.W_LLF (Stream, Item);
+ return;
+ end if;
+
+ declare
+ X : S_LLF := From_LLF (Item);
+
+ N_IEEE_Extended_Precision_Bytes : constant := 10;
+ begin
+ X (N_IEEE_Extended_Precision_Bytes + 1 .. X'Last) := (others => 0);
+ Ada.Streams.Write (Stream.all, X);
+ end;
+ end W_80IEEE;
+
end System.Stream_Attributes;
diff --git a/gcc/ada/libgnat/s-trasym.adb b/gcc/ada/libgnat/s-trasym.adb
index 96a1925..5bab088 100644
--- a/gcc/ada/libgnat/s-trasym.adb
+++ b/gcc/ada/libgnat/s-trasym.adb
@@ -123,4 +123,8 @@ package body System.Traceback.Symbolic is
null;
end Enable_Cache;
+ function Calling_Entity return String is
+ begin
+ return "???";
+ end Calling_Entity;
end System.Traceback.Symbolic;
diff --git a/gcc/ada/libgnat/s-trasym.ads b/gcc/ada/libgnat/s-trasym.ads
index 96b26cb..59939ce 100644
--- a/gcc/ada/libgnat/s-trasym.ads
+++ b/gcc/ada/libgnat/s-trasym.ads
@@ -105,4 +105,7 @@ package System.Traceback.Symbolic is
-- with default value), but backward compatibility for direct calls
-- is supported.
+ function Calling_Entity return String;
+ -- Return the name of the caller of the current subprogram if it's
+ -- available. Otherwise return "???".
end System.Traceback.Symbolic;
diff --git a/gcc/ada/libgnat/s-trasym__dwarf.adb b/gcc/ada/libgnat/s-trasym__dwarf.adb
index 479b5d3..09026c9 100644
--- a/gcc/ada/libgnat/s-trasym__dwarf.adb
+++ b/gcc/ada/libgnat/s-trasym__dwarf.adb
@@ -96,13 +96,16 @@ package body System.Traceback.Symbolic is
-- Initialize Exec_Module if not already initialized
function Symbolic_Traceback
- (Traceback : System.Traceback_Entries.Tracebacks_Array;
- Suppress_Hex : Boolean) return String;
+ (Traceback : System.Traceback_Entries.Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean) return String;
function Symbolic_Traceback
(E : Ada.Exceptions.Exception_Occurrence;
Suppress_Hex : Boolean) return String;
-- Suppress_Hex means do not print any hexadecimal addresses, even if the
- -- symbol is not available.
+ -- symbol is not available. Subprg_Name_Only means to only print the
+ -- subprogram name for each frame, as opposed to the complete description
+ -- of the frame.
function Lt (Left, Right : Module_Cache_Acc) return Boolean;
-- Sort function for Module_Cache
@@ -166,30 +169,34 @@ package body System.Traceback.Symbolic is
-- Non-symbolic traceback (simply write addresses in hexa)
procedure Symbolic_Traceback_No_Lock
- (Traceback : Tracebacks_Array;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String);
- -- Like the public Symbolic_Traceback_No_Lock except there is no provision
- -- against concurrent accesses.
+ (Traceback : Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String);
+ -- Like the public Symbolic_Traceback except there is no provision against
+ -- concurrent accesses.
procedure Module_Symbolic_Traceback
- (Traceback : Tracebacks_Array;
- Module : Module_Cache;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String);
+ (Traceback : Tracebacks_Array;
+ Module : Module_Cache;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String);
-- Returns the Traceback for a given module
procedure Multi_Module_Symbolic_Traceback
- (Traceback : Tracebacks_Array;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String);
+ (Traceback : Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String);
-- Build string containing symbolic traceback for the given call chain
procedure Multi_Module_Symbolic_Traceback
- (Traceback : Tracebacks_Array;
- Module : Module_Cache;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String);
+ (Traceback : Tracebacks_Array;
+ Module : Module_Cache;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String);
-- Likewise but using Module
Max_String_Length : constant := 4096;
@@ -328,6 +335,36 @@ package body System.Traceback.Symbolic is
Module_Cache_Array_Sort (Modules_Cache.all);
end Enable_Cache;
+ function Calling_Entity return String is
+ N_Skipped_Frames : constant Natural := 3;
+ -- We ask Call_Chain to skip the following frames:
+ --
+ -- 1. The frame of Call_Chain itself.
+ -- 2. The frame of Calling_Entity.
+ -- 3. The frame of Calling_Entity's caller.
+ --
+ -- The frame above that is the function the caller is looking for.
+
+ Traceback : Tracebacks_Array (1 .. 1);
+ Len : Natural;
+ begin
+ Call_Chain (Traceback, 1, Len, Skip_Frames => N_Skipped_Frames);
+
+ if Len = 0 then
+ return "???";
+ end if;
+
+ declare
+ With_Trailing_Newline : constant String :=
+ Symbolic_Traceback
+ (Traceback, Suppress_Hex => True, Subprg_Name_Only => True);
+ begin
+ return
+ With_Trailing_Newline
+ (With_Trailing_Newline'First .. With_Trailing_Newline'Last - 1);
+ end;
+ end Calling_Entity;
+
---------------------
-- Executable_Name --
---------------------
@@ -450,14 +487,15 @@ package body System.Traceback.Symbolic is
-------------------------------
procedure Module_Symbolic_Traceback
- (Traceback : Tracebacks_Array;
- Module : Module_Cache;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String)
+ (Traceback : Tracebacks_Array;
+ Module : Module_Cache;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String)
is
Success : Boolean;
begin
- if Symbolic.Module_Name.Is_Supported then
+ if Symbolic.Module_Name.Is_Supported and then not Subprg_Name_Only then
Append (Res, '[');
Append (Res, Module.Name.all);
Append (Res, ']' & ASCII.LF);
@@ -467,11 +505,13 @@ package body System.Traceback.Symbolic is
(Module.C,
Traceback,
Suppress_Hex,
+ Subprg_Name_Only,
Success,
Res);
if not Success then
- Hexa_Traceback (Traceback, Suppress_Hex, Res);
+ Hexa_Traceback
+ (Traceback, Suppress_Hex or else Subprg_Name_Only, Res);
end if;
-- We must not allow an unhandled exception here, since this function
@@ -487,9 +527,10 @@ package body System.Traceback.Symbolic is
-------------------------------------
procedure Multi_Module_Symbolic_Traceback
- (Traceback : Tracebacks_Array;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String)
+ (Traceback : Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String)
is
F : constant Natural := Traceback'First;
begin
@@ -514,6 +555,7 @@ package body System.Traceback.Symbolic is
Multi_Module_Symbolic_Traceback
(Traceback,
Modules_Cache (Mid).all,
+ Subprg_Name_Only,
Suppress_Hex,
Res);
return;
@@ -527,6 +569,7 @@ package body System.Traceback.Symbolic is
Multi_Module_Symbolic_Traceback
(Traceback (F + 1 .. Traceback'Last),
Suppress_Hex,
+ Subprg_Name_Only,
Res);
end;
else
@@ -534,10 +577,7 @@ package body System.Traceback.Symbolic is
-- First try the executable
if Is_Inside (Exec_Module.C, Traceback (F)) then
Multi_Module_Symbolic_Traceback
- (Traceback,
- Exec_Module,
- Suppress_Hex,
- Res);
+ (Traceback, Exec_Module, Suppress_Hex, Subprg_Name_Only, Res);
return;
end if;
@@ -553,10 +593,7 @@ package body System.Traceback.Symbolic is
Init_Module (Module, Success, M_Name, Load_Addr);
if Success then
Multi_Module_Symbolic_Traceback
- (Traceback,
- Module,
- Suppress_Hex,
- Res);
+ (Traceback, Module, Suppress_Hex, Subprg_Name_Only, Res);
Close_Module (Module);
else
-- Module not found
@@ -564,6 +601,7 @@ package body System.Traceback.Symbolic is
Multi_Module_Symbolic_Traceback
(Traceback (F + 1 .. Traceback'Last),
Suppress_Hex,
+ Subprg_Name_Only,
Res);
end if;
end;
@@ -571,10 +609,11 @@ package body System.Traceback.Symbolic is
end Multi_Module_Symbolic_Traceback;
procedure Multi_Module_Symbolic_Traceback
- (Traceback : Tracebacks_Array;
- Module : Module_Cache;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String)
+ (Traceback : Tracebacks_Array;
+ Module : Module_Cache;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String)
is
Pos : Positive;
begin
@@ -599,10 +638,12 @@ package body System.Traceback.Symbolic is
(Traceback (Traceback'First .. Pos - 1),
Module,
Suppress_Hex,
+ Subprg_Name_Only,
Res);
Multi_Module_Symbolic_Traceback
(Traceback (Pos .. Traceback'Last),
Suppress_Hex,
+ Subprg_Name_Only,
Res);
end Multi_Module_Symbolic_Traceback;
@@ -633,23 +674,22 @@ package body System.Traceback.Symbolic is
--------------------------------
procedure Symbolic_Traceback_No_Lock
- (Traceback : Tracebacks_Array;
- Suppress_Hex : Boolean;
- Res : in out Bounded_String)
- is
+ (Traceback : Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean;
+ Res : in out Bounded_String) is
begin
if Symbolic.Module_Name.Is_Supported then
- Multi_Module_Symbolic_Traceback (Traceback, Suppress_Hex, Res);
+ Multi_Module_Symbolic_Traceback
+ (Traceback, Suppress_Hex, Subprg_Name_Only, Res);
else
if Exec_Module_State = Failed then
Append (Res, "Call stack traceback locations:" & ASCII.LF);
- Hexa_Traceback (Traceback, Suppress_Hex, Res);
+ Hexa_Traceback
+ (Traceback, Suppress_Hex or else Subprg_Name_Only, Res);
else
Module_Symbolic_Traceback
- (Traceback,
- Exec_Module,
- Suppress_Hex,
- Res);
+ (Traceback, Exec_Module, Suppress_Hex, Subprg_Name_Only, Res);
end if;
end if;
end Symbolic_Traceback_No_Lock;
@@ -662,8 +702,9 @@ package body System.Traceback.Symbolic is
-- Copied from Ada.Exceptions.Exception_Data
function Symbolic_Traceback
- (Traceback : Tracebacks_Array;
- Suppress_Hex : Boolean) return String
+ (Traceback : Tracebacks_Array;
+ Suppress_Hex : Boolean;
+ Subprg_Name_Only : Boolean) return String
is
Load_Address : constant Address := Get_Executable_Load_Address;
Res : Bounded_String (Max_Length => Max_String_Length);
@@ -671,12 +712,13 @@ package body System.Traceback.Symbolic is
begin
System.Soft_Links.Lock_Task.all;
Init_Exec_Module;
- if Load_Address /= Null_Address then
+ if not Subprg_Name_Only and then Load_Address /= Null_Address then
Append (Res, LDAD_Header);
Append_Address (Res, Load_Address);
Append (Res, ASCII.LF);
end if;
- Symbolic_Traceback_No_Lock (Traceback, Suppress_Hex, Res);
+ Symbolic_Traceback_No_Lock
+ (Traceback, Suppress_Hex, Subprg_Name_Only, Res);
System.Soft_Links.Unlock_Task.all;
return To_String (Res);
@@ -690,13 +732,17 @@ package body System.Traceback.Symbolic is
function Symbolic_Traceback
(Traceback : System.Traceback_Entries.Tracebacks_Array) return String is
begin
- return Symbolic_Traceback (Traceback, Suppress_Hex => False);
+ return
+ Symbolic_Traceback
+ (Traceback, Suppress_Hex => False, Subprg_Name_Only => False);
end Symbolic_Traceback;
function Symbolic_Traceback_No_Hex
(Traceback : System.Traceback_Entries.Tracebacks_Array) return String is
begin
- return Symbolic_Traceback (Traceback, Suppress_Hex => True);
+ return
+ Symbolic_Traceback
+ (Traceback, Suppress_Hex => True, Subprg_Name_Only => False);
end Symbolic_Traceback_No_Hex;
function Symbolic_Traceback
@@ -704,9 +750,11 @@ package body System.Traceback.Symbolic is
Suppress_Hex : Boolean) return String
is
begin
- return Symbolic_Traceback
+ return
+ Symbolic_Traceback
(Ada.Exceptions.Traceback.Tracebacks (E),
- Suppress_Hex);
+ Suppress_Hex,
+ False);
end Symbolic_Traceback;
function Symbolic_Traceback
diff --git a/gcc/ada/locales.c b/gcc/ada/locales.c
index a3f884c..89c5b7b 100644
--- a/gcc/ada/locales.c
+++ b/gcc/ada/locales.c
@@ -646,7 +646,7 @@ str_get_last_byte (char *lc_all) {
return last_byte;
}
-/* Utility function to search in the iso_639_1 table for an iso-639-1 code;
+/* Utility function to search in the iso_639 table for an iso-639-1 code;
returns the corresponding iso-639-3 code or NULL if not found. */
static char*
@@ -670,7 +670,30 @@ iso_639_1_to_639_3(char* iso_639_1_code) {
return NULL;
}
-/* Utility function to search in the iso_639_1 table for a language name;
+/* Utility function to search in the iso_639 table for an iso-639-3 code;
+ returns 1 if found or 0 if not found. */
+
+static int
+is_iso_639_3(char* iso_639_3_code) {
+ int len = ARRAY_SIZE (iso_639);
+ char **p = iso_639;
+ int j;
+
+ p = p + 1;
+ for (j=0; j < len/3; j++) {
+ char* s1 = iso_639_3_code;
+ char* s2 = *p;
+
+ if (s1[0]==s2[0] && s1[1]==s2[1] && s1[2]==s2[2])
+ return 1;
+
+ p = p + 3;
+ }
+
+ return 0;
+}
+
+/* Utility function to search in the iso_639 table for a language name;
returns the corresponding iso-639-3 code or NULL if not found. */
static char*
@@ -772,7 +795,8 @@ c_get_language_code (char4 p) {
/* Copy the ISO-639-3 code (adding a null terminator) */
} else if (lang_length == 3) {
- str_copy(iso_639_3_code, lc_all, lang_length);
+ if (is_iso_639_3(lc_all))
+ str_copy(iso_639_3_code, lc_all, lang_length);
/* Handle conversion of language name to ISO-639-3 */
diff --git a/gcc/ada/par-ch12.adb b/gcc/ada/par-ch12.adb
index 7bd449d..18cd907 100644
--- a/gcc/ada/par-ch12.adb
+++ b/gcc/ada/par-ch12.adb
@@ -466,7 +466,7 @@ package body Ch12 is
end if;
No_Constraint;
- Set_Default_Expression (Decl_Node, Init_Expr_Opt);
+ Set_Expression (Decl_Node, Init_Expr_Opt);
P_Aspect_Specifications (Decl_Node, Semicolon => True);
if Ident > 1 then
diff --git a/gcc/ada/par-ch13.adb b/gcc/ada/par-ch13.adb
index dbb894f..00b780b 100644
--- a/gcc/ada/par-ch13.adb
+++ b/gcc/ada/par-ch13.adb
@@ -632,6 +632,77 @@ package body Ch13 is
return Aspects;
end Get_Aspect_Specifications;
+ -----------------------------
+ -- P_Attribute_Designators --
+ -----------------------------
+
+ function P_Attribute_Designators (Initial_Prefix : Node_Id) return Node_Id
+ is
+ Accumulator : Node_Id := Initial_Prefix;
+ Designator : Name_Id;
+ begin
+ while Token = Tok_Apostrophe loop
+
+ Scan; -- past apostrophe
+
+ Designator := No_Name;
+
+ if Token = Tok_Identifier then
+ Designator := Token_Name;
+
+ -- Note that the parser must complain in case of an internal
+ -- attribute name that comes from source since internal names are
+ -- meant to be used only by the compiler.
+
+ if not Is_Attribute_Name (Designator)
+ and then (not Is_Internal_Attribute_Name (Designator)
+ or else Comes_From_Source (Token_Node))
+ then
+ Signal_Bad_Attribute;
+ end if;
+
+ if Style_Check then
+ Style.Check_Attribute_Name (False);
+ end if;
+
+ -- Here for case of attribute designator is not an identifier
+
+ else
+ if Token = Tok_Delta then
+ Designator := Name_Delta;
+
+ elsif Token = Tok_Digits then
+ Designator := Name_Digits;
+
+ elsif Token = Tok_Access then
+ Designator := Name_Access;
+
+ else
+ Error_Msg_AP ("attribute designator expected");
+ raise Error_Resync;
+ end if;
+
+ if Style_Check then
+ Style.Check_Attribute_Name (True);
+ end if;
+ end if;
+
+ -- Here we have an OK attribute scanned, and the corresponding
+ -- Attribute identifier node is stored in Designator.
+
+ declare
+ Temp : constant Node_Id := Accumulator;
+ begin
+ Accumulator := New_Node (N_Attribute_Reference, Prev_Token_Ptr);
+ Set_Prefix (Accumulator, Temp);
+ end;
+ Set_Attribute_Name (Accumulator, Designator);
+ Scan;
+ end loop;
+
+ return Accumulator;
+ end P_Attribute_Designators;
+
--------------------------------------------
-- 13.1 Representation Clause (also I.7) --
--------------------------------------------
@@ -674,8 +745,6 @@ package body Ch13 is
function P_Representation_Clause return Node_Id is
For_Loc : Source_Ptr;
Name_Node : Node_Id;
- Prefix_Node : Node_Id;
- Attr_Name : Name_Id;
Identifier_Node : Node_Id;
Rep_Clause_Node : Node_Id;
Expr_Node : Node_Id;
@@ -693,8 +762,7 @@ package body Ch13 is
-- Check case of qualified name to give good error message
if Token = Tok_Dot then
- Error_Msg_SC
- ("representation clause requires simple name!");
+ Error_Msg_SC ("representation clause requires simple name!");
loop
exit when Token /= Tok_Dot;
@@ -706,80 +774,28 @@ package body Ch13 is
-- Attribute Definition Clause
if Token = Tok_Apostrophe then
+ Name_Node := P_Attribute_Designators (Identifier_Node);
- -- Allow local names of the form a'b'.... This enables
- -- us to parse class-wide streams attributes correctly.
-
- Name_Node := Identifier_Node;
- while Token = Tok_Apostrophe loop
-
- Scan; -- past apostrophe
-
- Identifier_Node := Token_Node;
- Attr_Name := No_Name;
-
- if Token = Tok_Identifier then
- Attr_Name := Token_Name;
-
- -- Note that the parser must complain in case of an internal
- -- attribute name that comes from source since internal names
- -- are meant to be used only by the compiler.
-
- if not Is_Attribute_Name (Attr_Name)
- and then (not Is_Internal_Attribute_Name (Attr_Name)
- or else Comes_From_Source (Token_Node))
- then
- Signal_Bad_Attribute;
- end if;
-
- if Style_Check then
- Style.Check_Attribute_Name (False);
- end if;
-
- -- Here for case of attribute designator is not an identifier
-
- else
- if Token = Tok_Delta then
- Attr_Name := Name_Delta;
-
- elsif Token = Tok_Digits then
- Attr_Name := Name_Digits;
+ -- Check for Address clause which needs to be marked for use in
+ -- optimizing performance of Exp_Util.Following_Address_Clause.
- elsif Token = Tok_Access then
- Attr_Name := Name_Access;
-
- else
- Error_Msg_AP ("attribute designator expected");
- raise Error_Resync;
- end if;
-
- if Style_Check then
- Style.Check_Attribute_Name (True);
- end if;
- end if;
-
- -- Here we have an OK attribute scanned, and the corresponding
- -- Attribute identifier node is stored in Ident_Node.
-
- Prefix_Node := Name_Node;
- Name_Node := New_Node (N_Attribute_Reference, Prev_Token_Ptr);
- Set_Prefix (Name_Node, Prefix_Node);
- Set_Attribute_Name (Name_Node, Attr_Name);
- Scan;
-
- -- Check for Address clause which needs to be marked for use in
- -- optimizing performance of Exp_Util.Following_Address_Clause.
+ declare
+ Cursor : Node_Id := Name_Node;
+ begin
+ while Nkind (Prefix (Cursor)) = N_Attribute_Reference loop
+ Cursor := Prefix (Cursor);
+ end loop;
- if Attr_Name = Name_Address
- and then Nkind (Prefix_Node) = N_Identifier
+ if Attribute_Name (Cursor) = Name_Address
+ and then Nkind (Prefix (Cursor)) = N_Identifier
then
- Set_Name_Table_Boolean1 (Chars (Prefix_Node), True);
+ Set_Name_Table_Boolean1 (Chars (Prefix (Cursor)), True);
end if;
- end loop;
+ end;
Rep_Clause_Node := New_Node (N_Attribute_Definition_Clause, For_Loc);
- Set_Name (Rep_Clause_Node, Prefix_Node);
- Set_Chars (Rep_Clause_Node, Attr_Name);
+ Set_Name (Rep_Clause_Node, Prefix (Name_Node));
+ Set_Chars (Rep_Clause_Node, Attribute_Name (Name_Node));
T_Use;
Expr_Node := P_Expression_No_Right_Paren;
diff --git a/gcc/ada/par-ch3.adb b/gcc/ada/par-ch3.adb
index 56c1b89..ee0958d 100644
--- a/gcc/ada/par-ch3.adb
+++ b/gcc/ada/par-ch3.adb
@@ -757,8 +757,7 @@ package body Ch3 is
Typedef_Node := P_Derived_Type_Def_Or_Private_Ext_Decl;
if Saved_Token = Tok_Synchronized then
- if Nkind (Typedef_Node) =
- N_Derived_Type_Definition
+ if Nkind (Typedef_Node) = N_Derived_Type_Definition
then
Error_Msg_N
("SYNCHRONIZED not allowed for record extension",
@@ -864,7 +863,13 @@ package body Ch3 is
Set_Abstract_Present (Typedef_Node, Abstract_Present);
elsif Abstract_Present then
- Error_Msg ("ABSTRACT not allowed here, ignored", Abstract_Loc);
+ if Nkind (Typedef_Node) = N_Derived_Type_Definition then
+ Error_Msg
+ ("ABSTRACT allowed only for record extension, ignored",
+ Abstract_Loc);
+ else
+ Error_Msg ("ABSTRACT not allowed here, ignored", Abstract_Loc);
+ end if;
end if;
Decl_Node := New_Node (N_Full_Type_Declaration, Type_Loc);
diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb
index a6418a5..2be3670 100644
--- a/gcc/ada/par-ch6.adb
+++ b/gcc/ada/par-ch6.adb
@@ -128,7 +128,8 @@ package body Ch6 is
-- This routine scans out a subprogram declaration, subprogram body,
-- subprogram renaming declaration or subprogram generic instantiation.
- -- It also handles the new Ada 2012 expression function form
+ -- It also handles the new Ada 2012 expression function form, and the GNAT
+ -- extension for direct attribute definition.
-- SUBPROGRAM_DECLARATION ::=
-- SUBPROGRAM_SPECIFICATION
@@ -141,6 +142,9 @@ package body Ch6 is
-- SUBPROGRAM_SPECIFICATION ::=
-- procedure DEFINING_PROGRAM_UNIT_NAME PARAMETER_PROFILE
-- | function DEFINING_DESIGNATOR PARAMETER_AND_RESULT_PROFILE
+ -- | procedure LOCAL_NAME'ATTRIBUTE_DESIGNATOR PARAMETER_PROFILE
+ -- | function LOCAL_NAME'ATTRIBUTE_DESIGNATOR
+ -- PARAMETER_AND_RESULT_PROFILE
-- PARAMETER_PROFILE ::= [FORMAL_PART]
@@ -190,6 +194,13 @@ package body Ch6 is
function Contains_Import_Aspect (Aspects : List_Id) return Boolean;
-- Return True if Aspects contains an Import aspect.
+ procedure Rewrite_Entity_If_Direct_Attribute_Def
+ (Name : Node_Id; Spec : Node_Id);
+ -- In case of direct attribute definitions this procedure rewrites the
+ -- defining unit name of the specification node with a new entity. It is
+ -- essential to maintain the information that the original node comes
+ -- from a direct attribute definition.
+
----------------------------
-- Contains_Import_Aspect --
----------------------------
@@ -208,6 +219,39 @@ package body Ch6 is
return False;
end Contains_Import_Aspect;
+ --------------------------------------------
+ -- Rewrite_Entity_If_Direct_Attribute_Def --
+ --------------------------------------------
+
+ procedure Rewrite_Entity_If_Direct_Attribute_Def
+ (Name : Node_Id; Spec : Node_Id)
+ is
+ New_Entity, Copy_Spec : Node_Id;
+ begin
+ if Nkind (Name) = N_Attribute_Reference
+ and then Is_Direct_Attribute_Definition_Name (Attribute_Name (Name))
+ then
+ -- Note that, this workaround is needed to retain the info that
+ -- the current subprogram comes from a direct attribute
+ -- definition. Otherwise, we would need to add an entity flag
+ -- Is_Constructor. Currently this flag already exists and could be
+ -- misleading as it refer to CPP constructors ???
+
+ Copy_Spec := New_Copy (Spec);
+
+ New_Entity := Make_Defining_Identifier (Sloc (Name),
+ Direct_Attribute_Definition_Name
+ (Prefix (Name), Attribute_Name (Name)));
+ Set_Comes_From_Source (New_Entity);
+ Set_Parent (New_Entity, Copy_Spec);
+
+ Set_Defining_Unit_Name (Copy_Spec, New_Entity);
+ Rewrite (Spec, Copy_Spec);
+ end if;
+ end Rewrite_Entity_If_Direct_Attribute_Def;
+
+ -- Local variables
+
Specification_Node : Node_Id;
Name_Node : Node_Id;
Aspects : List_Id;
@@ -232,6 +276,8 @@ package body Ch6 is
Is_Overriding : Boolean := False;
Not_Overriding : Boolean := False;
+ -- Start of processing for P_Subprogram
+
begin
-- Set up scope stack entry. Note that the Labl field will be set later
@@ -343,11 +389,19 @@ package body Ch6 is
Name_Node := P_Defining_Program_Unit_Name;
end if;
+ -- Deal with direct attribute definition in subprogram specification
+
+ if Token = Tok_Apostrophe then
+ Error_Msg_GNAT_Extension ("direct attribute definition", Token_Ptr);
+
+ Name_Node := P_Attribute_Designators (Name_Node);
+ end if;
+
Scopes (Scope.Last).Labl := Name_Node;
Ignore (Tok_Colon);
-- Deal with generic instantiation, the one case in which we do not
- -- have a subprogram specification as part of whatever we are parsing
+ -- have a subprogram specification as part of whatever we are parsing.
if Token = Tok_Is then
Save_Scan_State (Scan_State); -- at the IS
@@ -940,6 +994,9 @@ package body Ch6 is
Parse_Decls_Begin_End (Body_Node);
end if;
+ Rewrite_Entity_If_Direct_Attribute_Def
+ (Name_Node, Specification_Node);
+
return Body_Node;
end Scan_Body_Or_Expression_Function;
end if;
@@ -952,6 +1009,9 @@ package body Ch6 is
Set_Specification (Decl_Node, Specification_Node);
Aspects := Get_Aspect_Specifications (Semicolon => False);
+ Rewrite_Entity_If_Direct_Attribute_Def
+ (Name_Node, Specification_Node);
+
-- Aspects may be present on a subprogram body. The source parsed
-- so far is that of its specification. Go parse the body and attach
-- the collected aspects, if any, to the body.
diff --git a/gcc/ada/par-endh.adb b/gcc/ada/par-endh.adb
index 8166705..8637e07 100644
--- a/gcc/ada/par-endh.adb
+++ b/gcc/ada/par-endh.adb
@@ -156,12 +156,12 @@ package body Endh is
function Same_Label (Label1, Label2 : Node_Id) return Boolean;
-- This function compares the two names associated with the given nodes.
-- If they are both simple (i.e. have Chars fields), then they have to
- -- be the same name. Otherwise they must both be N_Selected_Component
- -- nodes, referring to the same set of names, or Label1 is an N_Designator
- -- referring to the same set of names as the N_Defining_Program_Unit_Name
- -- in Label2. Any other combination returns False. This routine is used
- -- to compare the End_Labl scanned from the End line with the saved label
- -- value in the scope stack.
+ -- be the same name. If they are both N_Selected_Component or
+ -- N_Attribute_Reference nodes, they must refer to the same set of names.
+ -- Otherwise, Label1 must be a N_Designator referring to the same set of
+ -- names as the N_Defining_Program_Unit_Name in Label2. Any other
+ -- combination returns False. This routine is used to compare the End_Labl
+ -- scanned from the End line with the saved label value in the scope stack.
---------------
-- Check_End --
@@ -270,6 +270,16 @@ package body Endh is
end if;
End_Labl := P_Designator;
+
+ -- Case of direct attribute definition
+
+ if Token = Tok_Apostrophe then
+ Error_Msg_GNAT_Extension
+ ("direct attribute definition", Token_Ptr);
+
+ End_Labl := P_Attribute_Designators (End_Labl);
+ end if;
+
End_Labl_Present := True;
-- We have now scanned out a name. Here is where we do a check
@@ -1359,6 +1369,12 @@ package body Endh is
return Same_Label (Prefix (Label1), Prefix (Label2)) and then
Same_Label (Selector_Name (Label1), Selector_Name (Label2));
+ elsif Nkind (Label1) = N_Attribute_Reference
+ and then Nkind (Label2) = N_Attribute_Reference
+ then
+ return Same_Label (Prefix (Label1), Prefix (Label2)) and then
+ Attribute_Name (Label1) = Attribute_Name (Label2);
+
elsif Nkind (Label1) = N_Designator
and then Nkind (Label2) = N_Defining_Program_Unit_Name
then
diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb
index 8ced09d..6fc4bed 100644
--- a/gcc/ada/par.adb
+++ b/gcc/ada/par.adb
@@ -1019,6 +1019,16 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
package Ch13 is
function P_Representation_Clause return Node_Id;
+ function P_Attribute_Designators
+ (Initial_Prefix : Node_Id) return Node_Id;
+ -- This procedure parses trailing apostrophes and attribute designators,
+ -- i.e., the "'b'c..." suffix in "a'b'c...". "a" must have already been
+ -- parsed into Initial_Prefix and the scan pointer must be pointing
+ -- right past "a". If no apostrophe is found we just return
+ -- Initial_Prefix, otherwise the return value is a chain of
+ -- N_Attribute_Reference nodes, nested via the Prefix field and ending
+ -- with Initial_Prefix.
+
function Aspect_Specifications_Present
(Strict : Boolean := Ada_Version < Ada_2012) return Boolean;
-- This function tests whether the next keyword is WITH followed by
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index c82af11..ee529e1 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -1900,6 +1900,7 @@ package Rtsfind is
RE_W_U24, -- System.Stream_Attributes
RE_W_WC, -- System.Stream_Attributes
RE_W_WWC, -- System.Stream_Attributes
+ RE_W_80IEEE, -- System.Stream_Attributes
RE_Storage_Array_Input, -- System.Strings.Stream_Ops
RE_Storage_Array_Input_Blk_IO, -- System.Strings.Stream_Ops
@@ -3565,6 +3566,7 @@ package Rtsfind is
RE_W_U24 => System_Stream_Attributes,
RE_W_WC => System_Stream_Attributes,
RE_W_WWC => System_Stream_Attributes,
+ RE_W_80IEEE => System_Stream_Attributes,
RE_Storage_Array_Input => System_Strings_Stream_Ops,
RE_Storage_Array_Input_Blk_IO => System_Strings_Stream_Ops,
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index e9e245a..20270c2 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -3957,6 +3957,13 @@ package body Sem_Attr is
Error_Attr_P
("prefix of % attribute must be object of discriminated type");
+ -----------------
+ -- Constructor --
+ -----------------
+
+ when Attribute_Constructor =>
+ Error_Attr_P ("attribute% can only be used to define constructors");
+
---------------
-- Copy_Sign --
---------------
@@ -5180,12 +5187,17 @@ package body Sem_Attr is
Expr : Entity_Id;
begin
if not All_Extensions_Allowed then
- Error_Msg_GNAT_Extension ("Make attribute", Loc);
+ Error_Msg_GNAT_Extension ("attribute %", Loc);
return;
end if;
+ Check_Type;
Set_Etype (N, Etype (P));
+ if not Needs_Construction (Entity (P)) then
+ Error_Msg_NE ("no available constructor for&", N, Entity (P));
+ end if;
+
if Present (Expressions (N)) then
Expr := First (Expressions (N));
while Present (Expr) loop
@@ -5197,6 +5209,9 @@ package body Sem_Attr is
Next (Expr);
end loop;
+
+ elsif not Has_Default_Constructor (Entity (P)) then
+ Error_Msg_NE ("no default constructor for&", N, Entity (P));
end if;
end;
@@ -11144,6 +11159,7 @@ package body Sem_Attr is
| Attribute_Class
| Attribute_Code_Address
| Attribute_Compiler_Version
+ | Attribute_Constructor
| Attribute_Count
| Attribute_Default_Bit_Order
| Attribute_Default_Scalar_Storage_Order
@@ -12477,70 +12493,6 @@ package body Sem_Attr is
Set_Address_Taken (Entity (P));
end if;
- if Nkind (P) = N_Slice then
-
- -- Arr (X .. Y)'address is identical to Arr (X)'address,
- -- even if the array is packed and the slice itself is not
- -- addressable. Transform the prefix into an indexed component.
-
- -- Note that the transformation is safe only if we know that
- -- the slice is non-null. That is because a null slice can have
- -- an out of bounds index value.
-
- -- Right now, gigi blows up if given 'Address on a slice as a
- -- result of some incorrect freeze nodes generated by the front
- -- end, and this covers up that bug in one case, but the bug is
- -- likely still there in the cases not handled by this code ???
-
- -- It's not clear what 'Address *should* return for a null
- -- slice with out of bounds indexes, this might be worth an ARG
- -- discussion ???
-
- -- One approach would be to do a length check unconditionally,
- -- and then do the transformation below unconditionally, but
- -- analyze with checks off, avoiding the problem of the out of
- -- bounds index. This approach would interpret the address of
- -- an out of bounds null slice as being the address where the
- -- array element would be if there was one, which is probably
- -- as reasonable an interpretation as any ???
-
- declare
- Loc : constant Source_Ptr := Sloc (P);
- D : constant Node_Id := Discrete_Range (P);
- Lo : Node_Id;
-
- begin
- if Is_Entity_Name (D)
- and then
- Not_Null_Range
- (Type_Low_Bound (Entity (D)),
- Type_High_Bound (Entity (D)))
- then
- Lo :=
- Make_Attribute_Reference (Loc,
- Prefix => (New_Occurrence_Of (Entity (D), Loc)),
- Attribute_Name => Name_First);
-
- elsif Nkind (D) = N_Range
- and then Not_Null_Range (Low_Bound (D), High_Bound (D))
- then
- Lo := Low_Bound (D);
-
- else
- Lo := Empty;
- end if;
-
- if Present (Lo) then
- Rewrite (P,
- Make_Indexed_Component (Loc,
- Prefix => Relocate_Node (Prefix (P)),
- Expressions => New_List (Lo)));
-
- Analyze_And_Resolve (P);
- end if;
- end;
- end if;
-
------------------
-- Body_Version --
------------------
@@ -12805,45 +12757,43 @@ package body Sem_Attr is
and then Scope (Op) = Standard_Standard
and then not Strict
then
- declare
- Op_Chars : constant Any_Operator_Name := Chars (Op);
- -- Nonassociative ops like division are unlikely
- -- to come up in practice, but they are legal.
- begin
- case Op_Chars is
- when Name_Op_Add
- | Name_Op_Subtract
- | Name_Op_Multiply
- | Name_Op_Divide
- | Name_Op_Expon
- =>
- return Is_Numeric_Type (Typ);
-
- when Name_Op_Mod | Name_Op_Rem =>
- return Is_Numeric_Type (Typ)
- and then Is_Discrete_Type (Typ);
-
- when Name_Op_And | Name_Op_Or | Name_Op_Xor =>
- -- No Boolean array operators in Standard
- return Is_Boolean_Type (Typ)
- or else Is_Modular_Integer_Type (Typ);
+ -- Nonassociative ops like division are unlikely to
+ -- come up in practice, but they are legal.
+
+ case Any_Operator_Name'(Chars (Op)) is
+ when Name_Op_Add
+ | Name_Op_Subtract
+ | Name_Op_Multiply
+ | Name_Op_Divide
+ | Name_Op_Expon
+ =>
+ return Is_Numeric_Type (Typ);
+
+ when Name_Op_Mod | Name_Op_Rem =>
+ return Is_Numeric_Type (Typ)
+ and then Is_Discrete_Type (Typ);
+
+ when Name_Op_And | Name_Op_Or | Name_Op_Xor =>
+ -- No Boolean array operators in Standard
+ return Is_Boolean_Type (Typ)
+ or else Is_Modular_Integer_Type (Typ);
+
+ when Name_Op_Concat =>
+ return Is_Array_Type (Typ)
+ and then Number_Dimensions (Typ) = 1;
+
+ when Name_Op_Eq | Name_Op_Ne
+ | Name_Op_Lt | Name_Op_Le
+ | Name_Op_Gt | Name_Op_Ge
+ =>
+ return Is_Boolean_Type (Typ);
+
+ when Name_Op_Abs | Name_Op_Not =>
+ -- unary ops were already handled
+
+ raise Program_Error;
+ end case;
- when Name_Op_Concat =>
- return Is_Array_Type (Typ)
- and then Number_Dimensions (Typ) = 1;
-
- when Name_Op_Eq | Name_Op_Ne
- | Name_Op_Lt | Name_Op_Le
- | Name_Op_Gt | Name_Op_Ge
- =>
- return Is_Boolean_Type (Typ);
-
- when Name_Op_Abs | Name_Op_Not =>
- -- unary ops were already handled
- pragma Assert (False);
- raise Program_Error;
- end case;
- end;
else
return False;
end if;
diff --git a/gcc/ada/sem_aux.adb b/gcc/ada/sem_aux.adb
index 58a4beb..107e27e 100644
--- a/gcc/ada/sem_aux.adb
+++ b/gcc/ada/sem_aux.adb
@@ -184,9 +184,6 @@ package body Sem_Aux is
-- Normal case, search enclosing scopes
- -- Note: the test for Present (S) should not be required, it defends
- -- against an ill-formed tree.
-
S := Scope (Ent);
loop
-- If we somehow got an empty value for Scope, the tree must be
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index deb19ee..363abe3 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -599,8 +599,8 @@ package body Sem_Ch12 is
-- whose views can change between the point of instantiation and the point
-- of instantiation of the body. In addition, mark the generic renamings
-- as generic actuals, so that they are not compatible with other actuals.
- -- Recurse on an actual that is a formal package whose declaration has
- -- a box.
+ -- For an instantiation of a formal package that is declared with a box or
+ -- contains defaulted parameters, make the corresponding actuals visible.
function Component_Type_For_Private_View (T : Entity_Id) return Entity_Id;
-- Return the component type of array type T, with the following addition:
@@ -810,11 +810,11 @@ package body Sem_Ch12 is
-- the suffix is removed is added to Prims_List to restore them later.
procedure Install_Parent (P : Entity_Id; In_Body : Boolean := False);
- -- When compiling an instance of a child unit the parent (which is
- -- itself an instance) is an enclosing scope that must be made
- -- immediately visible. This procedure is also used to install the non-
- -- generic parent of a generic child unit when compiling its body, so
- -- that full views of types in the parent are made visible.
+ -- When compiling an instance of a child unit, the parent P is an enclosing
+ -- scope that must be made immediately visible. In_Body is True if this is
+ -- done for an instance body and False for an instance spec. Note that the
+ -- procedure does not insert P on the scope stack above the current scope,
+ -- but instead pushes P and then pushes an extra copy of the current scope.
-- The functions Instantiate_... perform various legality checks and build
-- the declarations for instantiated generic parameters. In all of these
@@ -930,7 +930,7 @@ package body Sem_Ch12 is
-- subprogram declaration N.
procedure Remove_Parent (In_Body : Boolean := False);
- -- Reverse effect after instantiation of child is complete
+ -- Reverse Install_Parent's effect after instantiation of child is complete
function Renames_Standard_Subprogram (Subp : Entity_Id) return Boolean;
-- Determine whether Subp renames one of the subprograms defined in the
@@ -944,6 +944,13 @@ package body Sem_Ch12 is
-- Restore suffix 'P' to primitives of Prims_List and leave Prims_List
-- set to No_Elist.
+ procedure Restore_Private_Views (Pack_Id : Entity_Id; Is_Package : Boolean);
+ -- Restore the private views of external types, and unmark the generic
+ -- renamings of actuals, so that they become compatible subtypes again.
+ -- Reset the visibility of the actuals (some of them may have been made
+ -- visible by Check_Generic_Actuals). For subprograms, Pack_Id is the
+ -- wrapper package built to hold the renamings and Is_Package is False.
+
procedure Set_Instance_Env
(Gen_Unit : Entity_Id;
Act_Unit : Entity_Id);
@@ -958,6 +965,10 @@ package body Sem_Ch12 is
-- Associate analyzed generic parameter with corresponding instance. Used
-- for semantic checks at instantiation time.
+ procedure Switch_View (T : Entity_Id);
+ -- Switch the partial and full views of a type, as well as those of its
+ -- private dependents (i.e. its subtypes and derived types).
+
function True_Parent (N : Node_Id) return Node_Id;
-- For a subunit, return parent of corresponding stub, else return
-- parent of node.
@@ -1080,18 +1091,6 @@ package body Sem_Ch12 is
Table_Increment => 100,
Table_Name => "Instance_Envs");
- procedure Restore_Private_Views
- (Pack_Id : Entity_Id;
- Is_Package : Boolean := True);
- -- Restore the private views of external types, and unmark the generic
- -- renamings of actuals, so that they become compatible subtypes again.
- -- For subprograms, Pack_Id is the package constructed to hold the
- -- renamings.
-
- procedure Switch_View (T : Entity_Id);
- -- Switch the partial and full views of a type and its private
- -- dependents (i.e. its subtypes and derived types).
-
------------------------------------
-- Structures for Error Reporting --
------------------------------------
@@ -1607,8 +1606,8 @@ package body Sem_Ch12 is
return Result : Actual_Rec do
case Nkind (Un_Formal) is
when N_Formal_Object_Declaration =>
- if Present (Default_Expression (Un_Formal)) then
- Result := (Name_Exp, Default_Expression (Un_Formal));
+ if Present (Expression (Un_Formal)) then
+ Result := (Name_Exp, Expression (Un_Formal));
end if;
when N_Formal_Type_Declaration =>
if Present (Default_Subtype_Mark (Un_Formal)) then
@@ -1663,18 +1662,14 @@ package body Sem_Ch12 is
if Box_Present (Src_Assoc) then
Assoc.Actual := (Kind => Box_Actual);
- if False then -- ???
- -- Disable this for now, because we have various
- -- code that needs to be updated.
- Error_Msg_N
- ("box requires named notation", Src_Assoc);
- end if;
+ Error_Msg_N ("box requires named notation", Src_Assoc);
else
Assoc.Actual :=
(Name_Exp,
Explicit_Generic_Actual_Parameter (Src_Assoc));
pragma Assert (Present (Assoc.Actual.Name_Exp));
end if;
+
Assoc.Actual_Origin := From_Explicit_Actual;
Next (Src_Assoc);
@@ -2557,7 +2552,7 @@ package body Sem_Ch12 is
(Defining_Identifier
(Assoc.Un_Formal), Sloc (N)),
Explicit_Generic_Actual_Parameter =>
- New_Copy_Tree (Default_Expression (Assoc.Un_Formal))));
+ New_Copy_Tree (Expression (Assoc.Un_Formal))));
end if;
end if;
@@ -3361,7 +3356,7 @@ package body Sem_Ch12 is
---------------------------------------
procedure Analyze_Formal_Object_Declaration (N : Node_Id) is
- E : constant Node_Id := Default_Expression (N);
+ E : constant Node_Id := Expression (N);
Id : constant Node_Id := Defining_Identifier (N);
K : Entity_Kind;
@@ -5696,7 +5691,7 @@ package body Sem_Ch12 is
Check_Formal_Packages (Act_Decl_Id);
Restore_Hidden_Primitives (Vis_Prims_List);
- Restore_Private_Views (Act_Decl_Id);
+ Restore_Private_Views (Act_Decl_Id, Is_Package => True);
Inherit_Context (Gen_Decl, N);
@@ -7218,7 +7213,7 @@ package body Sem_Ch12 is
if not Is_Intrinsic_Subprogram (Act_Decl_Id) then
Inherit_Context (Gen_Decl, N);
- Restore_Private_Views (Pack_Id, False);
+ Restore_Private_Views (Pack_Id, Is_Package => False);
-- If the context requires a full instantiation, mark node for
-- subsequent construction of the body.
@@ -8571,9 +8566,6 @@ package body Sem_Ch12 is
Set_Is_Generic_Actual_Type (Full_View (E));
end if;
- Set_Is_Hidden (E, False);
- Set_Is_Potentially_Use_Visible (E, In_Use (Instance));
-
-- We constructed the generic actual type as a subtype of the
-- supplied type. This means that it normally would not inherit
-- subtype specific attributes of the actual, which is wrong for
@@ -8627,21 +8619,15 @@ package body Sem_Ch12 is
(Renamed_Entity (E),
Is_Formal_Box =>
Box_Present (Parent (Associated_Formal_Package (E))));
-
- Set_Is_Hidden (E, False);
end if;
-
- -- If this is a subprogram instance (in a wrapper package) the
- -- actual is fully visible.
-
- elsif Is_Wrapper_Package (Instance) then
- Set_Is_Hidden (E, False);
+ end if;
-- If the formal package is declared with a box, or if the formal
- -- parameter is defaulted, it is visible in the body.
+ -- parameter is defaulted, the actual is visible in the instance.
- elsif Is_Formal_Box or else Is_Visible_Formal (E) then
+ if Is_Formal_Box or else Is_Visible_Formal (E) then
Set_Is_Hidden (E, False);
+ Set_Is_Potentially_Use_Visible (E, In_Use (Instance));
end if;
-- Check directly the type of the actual objects, including the
@@ -11182,10 +11168,20 @@ package body Sem_Ch12 is
------------------------
procedure Hide_Current_Scope is
- C : constant Entity_Id := Current_Scope;
+ C : Entity_Id;
E : Entity_Id;
begin
+ C := Current_Scope;
+
+ -- The analysis of the actual parameters may have created a transient
+ -- scope after the extra copy of the current scope was pushed onto the
+ -- stack, so we need to skip it.
+
+ if Scope_Is_Transient then
+ C := Scope (C);
+ end if;
+
Set_Is_Hidden_Open_Scope (C);
E := First_Entity (C);
@@ -11208,7 +11204,6 @@ package body Sem_Ch12 is
Set_Is_Immediately_Visible (C, False);
Append_Elmt (C, Hidden_Entities);
end if;
-
end Hide_Current_Scope;
--------------
@@ -11660,8 +11655,10 @@ package body Sem_Ch12 is
null;
elsif Present (Associated_Formal_Package (E)) then
- Check_Generic_Actuals (Renamed_Entity (E), True);
- Set_Is_Hidden (E, False);
+ Check_Generic_Actuals
+ (Renamed_Entity (E),
+ Is_Formal_Box =>
+ Box_Present (Parent (Associated_Formal_Package (E))));
-- Find formal package in generic unit that corresponds to
-- (instance of) formal package in instance.
@@ -12450,7 +12447,7 @@ package body Sem_Ch12 is
(Nkind (Actual_Of_Formal) = N_Package_Instantiation);
end if;
- Next (Actual_Of_Formal);
+ Next_Non_Pragma (Actual_Of_Formal);
-- A formal subprogram may be overloaded, so advance in
-- the list of actuals to make sure we do not match two
@@ -13236,7 +13233,7 @@ package body Sem_Ch12 is
end if;
end;
- elsif Present (Default_Expression (Formal)) then
+ elsif Present (Expression (Formal)) then
-- Use default to construct declaration
@@ -13254,7 +13251,7 @@ package body Sem_Ch12 is
Null_Exclusion_Present => Null_Exclusion_Present (Formal),
Object_Definition => Def,
Expression => New_Copy_Tree
- (Default_Expression (Formal)));
+ (Expression (Formal)));
Copy_Ghost_Aspect (Formal, To => Decl_Node);
Set_Corresponding_Generic_Association
@@ -13679,7 +13676,7 @@ package body Sem_Ch12 is
Set_Defining_Unit_Name (Act_Body, Act_Body_Name);
Set_Corresponding_Spec (Act_Body, Act_Decl_Id);
- Check_Generic_Actuals (Act_Decl_Id, False);
+ Check_Generic_Actuals (Act_Decl_Id, Is_Formal_Box => False);
Check_Initialized_Types;
-- Install primitives hidden at the point of the instantiation but
@@ -13927,7 +13924,7 @@ package body Sem_Ch12 is
-- the two mechanisms swap exactly the same entities, in particular
-- the private entities dependent on the primary private entities.
- Restore_Private_Views (Act_Decl_Id);
+ Restore_Private_Views (Act_Decl_Id, Is_Package => True);
-- Remove the current unit from visibility if this is an instance
-- that is not elaborated on the fly for inlining purposes.
@@ -14174,7 +14171,7 @@ package body Sem_Ch12 is
Set_Corresponding_Spec (Act_Body, Act_Decl_Id);
Set_Has_Completion (Act_Decl_Id);
- Check_Generic_Actuals (Pack_Id, False);
+ Check_Generic_Actuals (Pack_Id, Is_Formal_Box => False);
-- Generate a reference to link the visible subprogram instance to
-- the generic body, which for navigation purposes is the only
@@ -14245,7 +14242,7 @@ package body Sem_Ch12 is
Inherit_Context (Gen_Body, Inst_Node);
- Restore_Private_Views (Pack_Id, False);
+ Restore_Private_Views (Pack_Id, Is_Package => False);
if Par_Installed then
Remove_Parent (In_Body => True);
@@ -16960,20 +16957,33 @@ package body Sem_Ch12 is
procedure Remove_Parent (In_Body : Boolean := False) is
S : Entity_Id := Current_Scope;
- -- S is the scope containing the instantiation just completed. The scope
- -- stack contains the parent instances of the instantiation, followed by
- -- the original S.
+ -- S is the extra copy of the current scope that has been pushed by
+ -- Install_Parent. The scope stack next contains the parents of the
+ -- instance followed by the original S.
Cur_P : Entity_Id;
E : Entity_Id;
- P : Entity_Id;
Hidden : Elmt_Id;
+ P : Entity_Id;
+ SE : Scope_Stack_Entry;
begin
- -- After child instantiation is complete, remove from scope stack the
- -- extra copy of the current scope, and then remove parent instances.
-
if not In_Body then
+ -- If the analysis of the actual parameters has created a transient
+ -- scope after the extra copy of the current scope was pushed onto
+ -- the stack, we first need to save this transient scope and pop it.
+
+ if Scope_Is_Transient then
+ SE := Scope_Stack.Table (Scope_Stack.Last);
+ Scope_Stack.Decrement_Last;
+ S := Current_Scope;
+ else
+ SE := (Is_Transient => False, others => <>);
+ end if;
+
+ -- After child instantiation is complete, remove from scope stack the
+ -- extra copy of the current scope, and then remove the parents.
+
Pop_Scope;
while Current_Scope /= S loop
@@ -17057,6 +17067,12 @@ package body Sem_Ch12 is
Next_Elmt (Hidden);
end loop;
+ -- Restore the transient scope that was popped on entry, if any
+
+ if SE.Is_Transient then
+ Scope_Stack.Append (SE);
+ end if;
+
else
-- Each body is analyzed separately, and there is no context that
-- needs preserving from one body instance to the next, so remove all
@@ -17093,10 +17109,18 @@ package body Sem_Ch12 is
Saved : Instance_Env renames Instance_Envs.Table (Instance_Envs.Last);
begin
- if No (Current_Instantiated_Parent.Act_Id) then
- -- Restore environment after subprogram inlining
+ -- Restore environment after subprogram inlining
- Restore_Private_Views (Empty);
+ if No (Current_Instantiated_Parent.Act_Id) then
+ declare
+ M : Elmt_Id;
+ begin
+ M := First_Elmt (Exchanged_Views);
+ while Present (M) loop
+ Exchange_Declarations (Node (M));
+ Next_Elmt (M);
+ end loop;
+ end;
end if;
Current_Instantiated_Parent := Saved.Instantiated_Parent;
@@ -17115,9 +17139,7 @@ package body Sem_Ch12 is
-- Restore_Private_Views --
---------------------------
- procedure Restore_Private_Views
- (Pack_Id : Entity_Id;
- Is_Package : Boolean := True)
+ procedure Restore_Private_Views (Pack_Id : Entity_Id; Is_Package : Boolean)
is
M : Elmt_Id;
E : Entity_Id;
@@ -17136,6 +17158,7 @@ package body Sem_Ch12 is
procedure Restore_Nested_Formal (Formal : Entity_Id) is
pragma Assert (Ekind (Formal) = E_Package);
Ent : Entity_Id;
+
begin
if Present (Renamed_Entity (Formal))
and then Denotes_Formal_Package (Renamed_Entity (Formal), True)
@@ -17198,16 +17221,13 @@ package body Sem_Ch12 is
Next_Elmt (M);
end loop;
- if No (Pack_Id) then
- return;
- end if;
-
-- Make the generic formal parameters private, and make the formal types
-- into subtypes of the actuals again.
E := First_Entity (Pack_Id);
while Present (E) loop
- Set_Is_Hidden (E, True);
+ Set_Is_Hidden (E);
+ Set_Is_Potentially_Use_Visible (E, False);
if Is_Type (E)
and then Nkind (Parent (E)) = N_Subtype_Declaration
@@ -17231,6 +17251,7 @@ package body Sem_Ch12 is
(Entity (Subtype_Indication (Parent (E))))
then
null;
+
else
Set_Is_Generic_Actual_Type (E, False);
@@ -17275,7 +17296,7 @@ package body Sem_Ch12 is
-- If the actual is itself a formal package for the enclosing
-- generic, or the actual for such a formal package, it remains
-- visible on exit from the instance, and therefore nothing needs
- -- to be done either, except to keep it accessible.
+ -- to be done either.
if Is_Package and then Renamed_Entity (E) = Pack_Id then
exit;
@@ -17286,7 +17307,7 @@ package body Sem_Ch12 is
elsif
Denotes_Formal_Package (Renamed_Entity (E), True, Pack_Id)
then
- Set_Is_Hidden (E, False);
+ null;
else
declare
@@ -17301,8 +17322,8 @@ package body Sem_Ch12 is
exit when Ekind (Id) = E_Package
and then Renamed_Entity (Id) = Act_P;
- Set_Is_Hidden (Id, True);
- Set_Is_Potentially_Use_Visible (Id, In_Use (Act_P));
+ Set_Is_Hidden (Id);
+ Set_Is_Potentially_Use_Visible (Id, False);
if Ekind (Id) = E_Package then
Restore_Nested_Formal (Id);
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index f7be890..31af1bb 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -442,11 +442,6 @@ package body Sem_Ch13 is
Off : Boolean;
-- Whether the address is offset within Y in the second case
-
- Alignment_Checks_Suppressed : Boolean;
- -- Whether alignment checks are suppressed by an active scope suppress
- -- setting. We need to save the value in order to be able to reuse it
- -- after the back end has been run.
end record;
package Address_Clause_Checks is new Table.Table (
@@ -457,26 +452,6 @@ package body Sem_Ch13 is
Table_Increment => 200,
Table_Name => "Address_Clause_Checks");
- function Alignment_Checks_Suppressed
- (ACCR : Address_Clause_Check_Record) return Boolean;
- -- Return whether the alignment check generated for the address clause
- -- is suppressed.
-
- ---------------------------------
- -- Alignment_Checks_Suppressed --
- ---------------------------------
-
- function Alignment_Checks_Suppressed
- (ACCR : Address_Clause_Check_Record) return Boolean
- is
- begin
- if Checks_May_Be_Suppressed (ACCR.X) then
- return Is_Check_Suppressed (ACCR.X, Alignment_Check);
- else
- return ACCR.Alignment_Checks_Suppressed;
- end if;
- end Alignment_Checks_Suppressed;
-
-----------------------------------------
-- Adjust_Record_For_Reverse_Bit_Order --
-----------------------------------------
@@ -5041,16 +5016,6 @@ package body Sem_Ch13 is
Analyze_Aspect_Implicit_Dereference;
goto Continue;
- when Aspect_Constructor =>
- if not All_Extensions_Allowed then
- Error_Msg_Name_1 := Nam;
- Error_Msg_GNAT_Extension ("aspect %", Loc);
- goto Continue;
- end if;
-
- Set_Constructor_Name (E, Expr);
- Set_Needs_Construction (E);
-
-- Dimension
when Aspect_Dimension =>
@@ -7096,11 +7061,15 @@ package body Sem_Ch13 is
end if;
end;
- -- Entity has delayed freeze, so we will generate an
+ -- The entity has delayed freeze, so we will generate an
-- alignment check at the freeze point unless suppressed.
+ -- We will unconditionally generate it when the alignment
+ -- is specified in addition to the address, to compensate
+ -- for the check being suppressed by default on machines
+ -- that do not need strict alignment of memory accesses.
- if not Range_Checks_Suppressed (U_Ent)
- and then not Alignment_Checks_Suppressed (U_Ent)
+ if not Alignment_Checks_Suppressed (U_Ent)
+ or else Present (Alignment_Clause (U_Ent))
then
Set_Check_Address_Alignment (N);
end if;
@@ -7175,6 +7144,14 @@ package body Sem_Ch13 is
if Is_Array_Type (U_Ent) then
Set_Alignment (Base_Type (U_Ent), Align);
end if;
+
+ -- See the Attribute_Address case above for the rationale
+
+ if not Is_Type (U_Ent)
+ and then Present (Address_Clause (U_Ent))
+ then
+ Set_Check_Address_Alignment (Address_Clause (U_Ent));
+ end if;
end if;
end Alignment;
@@ -7844,7 +7821,7 @@ package body Sem_Ch13 is
end if;
end if;
- -- For Object'Size, set Esize only
+ -- For objects, set Esize only
else
if Is_Elementary_Type (Etyp)
@@ -7858,26 +7835,37 @@ package body Sem_Ch13 is
Error_Msg_Uint_2 :=
UI_From_Int (System_Max_Integer_Size);
Error_Msg_N
- ("size for primitive object must be a power of 2 in "
- & "the range ^-^", N);
- end if;
+ ("size for elementary object must be a power of 2 "
+ & "in the range ^-^", N);
- Set_Esize (U_Ent, Size);
- end if;
+ -- As per RM 13.1(25/5), only a confirming size clause
+ -- (i.e. Size = Type'Object_Size) for aliased objects
+ -- of elementary types is required to be supported.
+ -- We reject nonconfirming clauses for these objects.
- -- As of RM 13.1, only confirming size
- -- (i.e. (Size = Esize (Etyp))) for aliased object of
- -- elementary type must be supported.
- -- GNAT rejects nonconfirming size for such object.
+ elsif Is_Aliased (U_Ent)
+ and then Is_Elementary_Type (Etyp)
+ and then Size /= Esize (Etyp)
+ then
+ Error_Msg_N
+ ("nonconfirming Size for aliased object is not "
+ & "supported", N);
- if Is_Aliased (U_Ent)
- and then Is_Elementary_Type (Etyp)
- and then Known_Esize (U_Ent)
- and then Size /= Esize (Etyp)
- then
- Error_Msg_N
- ("nonconfirming Size for aliased object is not "
- & "supported", N);
+ -- We also reject nonconfirming clauses for (nonaliased)
+ -- objects of floating-point types because smaller sizes
+ -- would require integer operations to access the objects
+ -- and larger sizes would require integer operations to
+ -- manipulate the padding bits.
+
+ elsif Is_Floating_Point_Type (Etyp)
+ and then Size /= Esize (Etyp)
+ then
+ Error_Msg_N
+ ("nonconfirming Size for floating-point object is "
+ & "not supported", N);
+ end if;
+
+ Set_Esize (U_Ent, Size);
end if;
-- Handle extension aspect 'Size'Class which allows for
@@ -11753,8 +11741,7 @@ package body Sem_Ch13 is
-- name, so we need to verify that one of these interpretations is
-- the one available at the freeze point.
- elsif A_Id in Aspect_Constructor
- | Aspect_Destructor
+ elsif A_Id in Aspect_Destructor
| Aspect_Input
| Aspect_Output
| Aspect_Read
@@ -12050,8 +12037,7 @@ package body Sem_Ch13 is
-- Special case, the expression of these aspects is just an entity
-- that does not need any resolution, so just analyze.
- when Aspect_Constructor
- | Aspect_Input
+ when Aspect_Input
| Aspect_Output
| Aspect_Put_Image
| Aspect_Read
@@ -16670,9 +16656,8 @@ package body Sem_Ch13 is
Y : Entity_Id;
Off : Boolean)
is
- ACS : constant Boolean := Scope_Suppress.Suppress (Alignment_Check);
begin
- Address_Clause_Checks.Append ((N, X, A, Y, Off, ACS));
+ Address_Clause_Checks.Append ((N, X, A, Y, Off));
end Register_Address_Clause_Check;
------------------------
@@ -17357,9 +17342,6 @@ package body Sem_Ch13 is
=>
null;
- when Aspect_Constructor =>
- null;
-
when Aspect_Dynamic_Predicate
| Aspect_Ghost_Predicate
| Aspect_Predicate
@@ -19125,7 +19107,7 @@ package body Sem_Ch13 is
-- Check for known value not multiple of alignment
if No (ACCR.Y) then
- if not Alignment_Checks_Suppressed (ACCR)
+ if Check_Address_Alignment (ACCR.N)
and then X_Alignment /= 0
and then ACCR.A mod X_Alignment /= 0
then
@@ -19170,7 +19152,7 @@ package body Sem_Ch13 is
-- Note: we do not check the alignment if we gave a size
-- warning, since it would likely be redundant.
- elsif not Alignment_Checks_Suppressed (ACCR)
+ elsif Check_Address_Alignment (ACCR.N)
and then Y_Alignment /= Uint_0
and then
(Y_Alignment < X_Alignment
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index aa15166..233f823 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -5246,6 +5246,15 @@ package body Sem_Ch3 is
and then Nkind (E) = N_Aggregate
then
Act_T := Etype (E);
+
+ elsif Needs_Construction (T)
+ and then not Has_Init_Expression (N)
+ and then not Has_Default_Constructor (T)
+ and then not Suppress_Initialization (Id)
+ and then Comes_From_Source (N)
+ then
+ Error_Msg_NE ("no default constructor for&",
+ Object_Definition (N), T);
end if;
-- Check No_Wide_Characters restriction
@@ -5944,6 +5953,8 @@ package body Sem_Ch3 is
Set_Scalar_Range (Id, Scalar_Range (T));
Set_Digits_Value (Id, Digits_Value (T));
Set_Is_Constrained (Id, Is_Constrained (T));
+ Set_Is_IEEE_Extended_Precision
+ (Id, Is_IEEE_Extended_Precision (T));
-- If the floating point type has dimensions, these will be
-- inherited subsequently when Analyze_Dimensions is called.
@@ -8206,10 +8217,14 @@ package body Sem_Ch3 is
Set_Digits_Value (Implicit_Base, Digits_Value (Parent_Base));
Set_Float_Rep (Implicit_Base, Float_Rep (Parent_Base));
+ Set_Is_IEEE_Extended_Precision
+ (Implicit_Base, Is_IEEE_Extended_Precision (Parent_Base));
if No_Constraint then
Set_Digits_Value (Derived_Type, Digits_Value (Parent_Type));
end if;
+ Set_Is_IEEE_Extended_Precision
+ (Derived_Type, Is_IEEE_Extended_Precision (Parent_Base));
elsif Is_Fixed_Point_Type (Parent_Type) then
@@ -8500,26 +8515,28 @@ package body Sem_Ch3 is
Full_P := Full_View (Parent_Type);
-- A type extension of a type with unknown discriminants is an
- -- indefinite type that the back-end cannot handle directly.
+ -- indefinite type that the back end cannot handle directly.
-- We treat it as a private type, and build a completion that is
-- derived from the full view of the parent, and hopefully has
- -- known discriminants.
+ -- known discriminants. Note that the type will nevertheless be
+ -- turned into a public type in Build_Derived_Record_Type as for
+ -- any other extension; the only difference is the completion.
-- If the full view of the parent type has an underlying record view,
- -- use it to generate the underlying record view of this derived type
+ -- use it to generate the underlying record view of the derived type
-- (required for chains of derivations with unknown discriminants).
- -- Minor optimization: we avoid the generation of useless underlying
- -- record view entities if the private type declaration has unknown
- -- discriminants but its corresponding full view has no
- -- discriminants.
+ -- Minor optimization: we avoid creating useless underlying record
+ -- view entities when the private type has unknown discriminants but
+ -- its corresponding full view has no discriminants.
if Has_Unknown_Discriminants (Parent_Type)
and then Present (Full_P)
and then (Has_Discriminants (Full_P)
or else Present (Underlying_Record_View (Full_P)))
- and then not In_Open_Scopes (Par_Scope)
- and then Expander_Active
+ and then (not In_Open_Scopes (Par_Scope)
+ or else not (In_Package_Body (Par_Scope)
+ or else In_Private_Part (Par_Scope)))
then
declare
Full_Der : constant Entity_Id := Make_Temporary (Loc, 'T');
@@ -8534,7 +8551,7 @@ package body Sem_Ch3 is
-- Build anonymous completion, as a derivation from the full
-- view of the parent. This is not a completion in the usual
- -- sense, because the current type is not private.
+ -- sense, because the derived type is no longer private.
Decl :=
Make_Full_Type_Declaration (Loc,
@@ -8557,8 +8574,18 @@ package body Sem_Ch3 is
Underlying_Record_View (Full_P));
end if;
+ -- If the extension is done in the public part of the scope of
+ -- the parent, its visible declarations have been installed, so
+ -- we first need to uninstall them before reinstalling both the
+ -- private and the visible declarations in this order.
+
+ if In_Open_Scopes (Par_Scope) then
+ Uninstall_Declarations (Par_Scope);
+ end if;
+
Install_Private_Declarations (Par_Scope);
Install_Visible_Declarations (Par_Scope);
+
Insert_Before (N, Decl);
-- Mark entity as an underlying record view before analysis,
@@ -8582,6 +8609,13 @@ package body Sem_Ch3 is
Uninstall_Declarations (Par_Scope);
+ -- If the extension is done in the public part of the scope of
+ -- the parent, reinstall the visible declarations only.
+
+ if In_Open_Scopes (Par_Scope) then
+ Install_Visible_Declarations (Par_Scope);
+ end if;
+
if Etype (Full_Der) = Any_Type then
pragma Assert (Serious_Errors_Detected > 0);
return;
@@ -10007,13 +10041,15 @@ package body Sem_Ch3 is
or else Unknown_Discriminants_Present (N));
-- The partial view of the parent may have unknown discriminants,
- -- but if the full view has discriminants and the parent type is
- -- in scope they must be inherited.
+ -- but when its full view has discriminants and is visible, then
+ -- these discriminants must be inherited.
elsif Has_Unknown_Discriminants (Parent_Type)
and then
(not Has_Discriminants (Parent_Type)
- or else not In_Open_Scopes (Scope (Parent_Base)))
+ or else not In_Open_Scopes (Scope (Parent_Base))
+ or else not (In_Package_Body (Scope (Parent_Base))
+ or else In_Private_Part (Scope (Parent_Base))))
then
Set_Has_Unknown_Discriminants (Derived_Type);
end if;
@@ -15144,19 +15180,20 @@ package body Sem_Ch3 is
Fixup_Bad_Constraint;
return;
- -- Check that the type has visible discriminants. The type may be
- -- a private type with unknown discriminants whose full view has
- -- discriminants which are invisible.
+ -- Check that the type has known discriminants
- elsif not Has_Discriminants (T)
- or else
- (Has_Unknown_Discriminants (T)
- and then Is_Private_Type (T))
- then
+ elsif Has_Unknown_Discriminants (T) then
+ Error_Msg_N ("invalid constraint: type has unknown discriminants", C);
+ Fixup_Bad_Constraint;
+ return;
+
+ elsif not Has_Discriminants (T) then
Error_Msg_N ("invalid constraint: type has no discriminant", C);
Fixup_Bad_Constraint;
return;
+ -- And is not already constrained
+
elsif Is_Constrained (E)
or else (Ekind (E) = E_Class_Wide_Subtype
and then Present (Discriminant_Constraint (E)))
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 5e84889..b752a6b 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -3843,7 +3843,8 @@ package body Sem_Ch6 is
-- user entities, as internally generated entitities might still need
-- to be expanded (e.g. those generated for types).
- if Present (Ghost_Config.Ignored_Ghost_Region)
+ if not CodePeer_Mode
+ and then Present (Ghost_Config.Ignored_Ghost_Region)
and then Comes_From_Source (Body_Id)
then
Expander_Active := False;
@@ -5029,7 +5030,9 @@ package body Sem_Ch6 is
end if;
<<Leave>>
- if Present (Ghost_Config.Ignored_Ghost_Region) then
+ if not CodePeer_Mode
+ and then Present (Ghost_Config.Ignored_Ghost_Region)
+ then
Expander_Active := Saved_EA;
end if;
@@ -5270,10 +5273,95 @@ package body Sem_Ch6 is
-- both subprogram bodies and subprogram declarations (specs).
function Analyze_Subprogram_Specification (N : Node_Id) return Entity_Id is
+ procedure Analyze_Direct_Attribute_Definition (Designator : Entity_Id);
+ -- This procedure checks whether the direct attribute definition for N
+ -- is correct for the given attribute name, and analyzes it.
+
function Is_Invariant_Procedure_Or_Body (E : Entity_Id) return Boolean;
-- Determine whether entity E denotes the spec or body of an invariant
-- procedure.
+ -----------------------------------------
+ -- Analyze_Direct_Attribute_Definition --
+ -----------------------------------------
+
+ procedure Analyze_Direct_Attribute_Definition (Designator : Entity_Id) is
+ Att_N : constant Node_Id := Original_Node (N);
+ Prefix_E : constant Entity_Id :=
+ Get_Name_Entity_Id (Chars (Prefix (Defining_Unit_Name (Att_N))));
+ Att_Name : constant Name_Id :=
+ Attribute_Name (Defining_Unit_Name (Att_N));
+ begin
+ pragma Assert (N /= Att_N);
+
+ if not Is_Direct_Attribute_Definition_Name (Att_Name) then
+ Error_Msg_Name_1 := Att_Name;
+ Error_Msg_N
+ ("direct definition syntax not supported for attribute%",
+ Designator);
+ end if;
+
+ -- Handle each kind of attribute separately
+
+ case Att_Name is
+
+ when Name_Constructor =>
+ Error_Msg_Name_1 := Att_Name;
+
+ -- No further action required in a subprogram body
+
+ if Parent_Kind (N) not in N_Subprogram_Declaration then
+ return;
+
+ elsif No (Prefix_E) or else not Is_Type (Prefix_E) then
+ Error_Msg_N
+ ("prefix& of attribute% must be a type",
+ Prefix (Defining_Unit_Name (Att_N)));
+
+ elsif Ekind (Designator) /= E_Procedure then
+ Error_Msg_N
+ ("attribute% can only be specified to a procedure", N);
+
+ elsif No (First_Formal (Designator))
+ or else Etype (First_Formal (Designator)) /= Prefix_E
+ or else Ekind (First_Formal (Designator))
+ /= E_In_Out_Parameter
+ then
+ declare
+ Problem : constant Source_Ptr :=
+ (if No (First_Formal (Designator))
+ then Sloc (N)
+ else Sloc (First_Formal (Designator)));
+ begin
+ Error_Msg_Node_1 := Defining_Unit_Name (Att_N);
+ Error_Msg_Node_2 := Prefix_E;
+ Error_Msg
+ ("& must have a first IN OUT formal of type&", Problem);
+ end;
+
+ elsif Is_Frozen (Prefix_E)
+ or else Current_Scope /= Scope (Prefix_E)
+ then
+ Error_Msg_Sloc := Sloc (Freeze_Node (Prefix_E));
+ Error_Msg_N
+ ("& must be defined before freezing#", Designator);
+
+ elsif Parent_Kind (Enclosing_Package_Or_Subprogram (Designator))
+ /= N_Package_Specification
+ then
+ Error_Msg_N
+ ("& is required to be a primitive operation", Designator);
+
+ else
+ Set_Needs_Construction (Prefix_E);
+ end if;
+
+ when others =>
+ null;
+
+ end case;
+ end Analyze_Direct_Attribute_Definition;
+
------------------------------------
-- Is_Invariant_Procedure_Or_Body --
------------------------------------
@@ -5416,89 +5504,6 @@ package body Sem_Ch6 is
End_Scope;
- -- Register the subprogram in a Constructor_List when it is a valid
- -- constructor.
-
- if All_Extensions_Allowed
- and then Present (First_Formal (Designator))
- then
-
- declare
- First_Form_Type : constant Entity_Id :=
- Etype (First_Formal (Designator));
-
- Construct : Elmt_Id;
- begin
- -- Valid constructors have a "controlling" formal of a type
- -- with the Constructor aspect specified. Additionally, the
- -- subprogram name must match value described by the aspect.
-
- -- Additionally, constructor declarations must exist within the
- -- same scope as the type declaration and before the type is
- -- frozen.
-
- -- For example:
- --
- -- type Foo is null record with Constructor => Bar;
- --
- -- procedure Bar (Self : in out Foo);
- --
-
- if Present (Constructor_Name (First_Form_Type))
- and then Current_Scope = Scope (First_Form_Type)
- and then Chars (Constructor_Name (First_Form_Type))
- = Chars (Designator)
- and then Ekind (Designator) = E_Procedure
- and then Nkind (Parent (N)) = N_Subprogram_Declaration
- then
- -- If the constructor list is empty than we don't have to
- -- look for duplicates - we simply create the list and
- -- add it.
-
- if No (Constructor_List (First_Form_Type)) then
- Set_Constructor_List
- (First_Form_Type, New_Elmt_List (Designator));
-
- -- Otherwise, we need to check the constructor hasen't
- -- already been added (e.g. a specification and body) and
- -- that there isn't a constructor with the same number of
- -- type of formals.
-
- -- NOTE: The Constructor_List is sorted by the number of
- -- parameters.
-
- else
- Construct := First_Elmt
- (Constructor_List (First_Form_Type));
-
- -- Skip over constructors with less than the number of
- -- parameters than Designator ???
-
- -- Loop through the constructors looking for ones which
- -- "match."
-
- Outter : loop
-
- -- When we are at the end of the constructor list we
- -- know there are no matches, so it is safe to add.
-
- if No (Construct) then
- Append_Elmt
- (Designator,
- Constructor_List (First_Form_Type));
- exit Outter;
- end if;
-
- -- Loop through the formals and check the formals
- -- match on type ???
-
- Next_Elmt (Construct);
- end loop Outter;
- end if;
- end if;
- end;
- end if;
-
-- The subprogram scope is pushed and popped around the processing of
-- the return type for consistency with call above to Process_Formals
-- (which itself can call Analyze_Return_Type), and to ensure that any
@@ -5511,6 +5516,12 @@ package body Sem_Ch6 is
End_Scope;
end if;
+ -- Handle subprogram specification directly referencing an attribute
+
+ if Is_Direct_Attribute_Subp_Spec (N) then
+ Analyze_Direct_Attribute_Definition (Designator);
+ end if;
+
-- Function case
if Nkind (N) = N_Function_Specification then
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index 989e6bf..6032487 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -835,7 +835,8 @@ package body Sem_Ch7 is
-- user entities, as internally generated entities might still need
-- to be expanded (e.g. those generated for types).
- if Present (Ghost_Config.Ignored_Ghost_Region)
+ if not CodePeer_Mode
+ and then Present (Ghost_Config.Ignored_Ghost_Region)
and then Comes_From_Source (Body_Id)
then
Expander_Active := False;
@@ -1148,7 +1149,9 @@ package body Sem_Ch7 is
end if;
end if;
- if Present (Ghost_Config.Ignored_Ghost_Region) then
+ if not CodePeer_Mode and then
+ Present (Ghost_Config.Ignored_Ghost_Region)
+ then
Expander_Active := Saved_EA;
end if;
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index e9d00d0..fe7f311 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -136,7 +136,7 @@ package body Sem_Ch8 is
-- the order of their corresponding scopes on the scope stack. For
-- example, if package P and the enclosing scope both contain entities
-- named E, then when compiling the package body the chain for E will
- -- hold the global entity first, and the local one (corresponding to
+ -- hold the global entity first, and the local one (corresponding to
-- the current inner scope) next. As a result, name resolution routines
-- do not assume any relative ordering of the homonym chains, either
-- for scope nesting or to order of appearance of context clauses.
@@ -207,7 +207,7 @@ package body Sem_Ch8 is
-- a private or incomplete type declaration, or a protected type speci-
-- fication) and re-chained when compiling the second view.
- -- In the case of operators, we do not make operators on derived types
+ -- In the case of operators, we do not make operators on derived types
-- explicit. As a result, the notation P."+" may denote either a user-
-- defined function with name "+", or else an implicit declaration of the
-- operator "+" in package P. The resolution of expanded names always
@@ -1892,7 +1892,7 @@ package body Sem_Ch8 is
Old_S := Find_Renamed_Entity (N, Selector_Name (Nam), New_S);
if Old_S = Any_Id then
- Error_Msg_N ("no subprogram or entry matches specification", N);
+ Error_Msg_N ("no subprogram or entry matches specification", N);
else
if Is_Body then
Check_Subtype_Conformant (New_S, Old_S, N);
@@ -2073,7 +2073,7 @@ package body Sem_Ch8 is
end if;
if Old_S = Any_Id then
- Error_Msg_N ("no subprogram or entry matches specification", N);
+ Error_Msg_N ("no subprogram or entry matches specification", N);
else
if Is_Body then
@@ -3848,7 +3848,7 @@ package body Sem_Ch8 is
elsif Ekind (Old_S) /= E_Operator then
-- If this a defaulted subprogram for a class-wide actual there is
- -- no check for mode conformance, given that the signatures don't
+ -- no check for mode conformance, given that the signatures don't
-- match (the source mentions T but the actual mentions T'Class).
if CW_Actual then
@@ -5213,7 +5213,7 @@ package body Sem_Ch8 is
-- An entity in the current scope is not necessarily the first one
-- on its homonym chain. Find its predecessor if any,
-- If it is an internal entity, it will not be in the visibility
- -- chain altogether, and there is nothing to unchain.
+ -- chain altogether, and there is nothing to unchain.
if Id /= Current_Entity (Id) then
Prev := Current_Entity (Id);
@@ -5248,7 +5248,7 @@ package body Sem_Ch8 is
Set_Name_Entity_Id (Chars (Id), Outer);
elsif Scope (Prev) /= Scope (Id) then
- Set_Homonym (Prev, Outer);
+ Set_Homonym (Prev, Outer);
end if;
<<Next_Ent>>
@@ -5330,11 +5330,6 @@ package body Sem_Ch8 is
---------------------
procedure End_Use_Package (N : Node_Id) is
- Pack : Entity_Id;
- Pack_Name : Node_Id;
- Id : Entity_Id;
- Elmt : Elmt_Id;
-
function Type_In_Use (T : Entity_Id; P : Entity_Id) return Boolean;
-- Check whether type T is declared in P and appears in an active
-- use_type clause.
@@ -5349,6 +5344,14 @@ package body Sem_Ch8 is
return Scope (BT) = P and then (In_Use (T) or else In_Use (BT));
end Type_In_Use;
+ -- Local variables
+
+ Elmt : Elmt_Id;
+ Id : Entity_Id;
+ Pack : Entity_Id;
+ Pack_Name : Node_Id;
+ Scop : Entity_Id;
+
-- Start of processing for End_Use_Package
begin
@@ -5373,17 +5376,20 @@ package body Sem_Ch8 is
-- Preserve use-visibility of operators that are primitive
-- operators of a type that is use-visible through an active
- -- use_type_clause.
+ -- use_type_clause. Note that we compare with the scope of
+ -- the operator and not Pack itself, lest Pack be a renaming.
+
+ Scop := Scope (Id);
if Nkind (Id) = N_Defining_Operator_Symbol
and then
- (Type_In_Use (Etype (Id), Pack)
- or else Type_In_Use (Etype (First_Formal (Id)), Pack)
+ (Type_In_Use (Etype (Id), Scop)
+ or else Type_In_Use (Etype (First_Formal (Id)), Scop)
or else
(Present (Next_Formal (First_Formal (Id)))
and then
Type_In_Use
- (Etype (Next_Formal (First_Formal (Id))), Pack)))
+ (Etype (Next_Formal (First_Formal (Id))), Scop)))
then
null;
else
@@ -9942,9 +9948,7 @@ package body Sem_Ch8 is
and then Scope (S) /= Standard_Standard
and then not Is_Child_Unit (S)
then
- if Nkind (E) not in N_Entity then
- return;
- end if;
+ pragma Assert (Nkind (E) in N_Entity);
-- Copy categorization flags from Scope (S) to S, this is not done
-- when Scope (S) is Standard_Standard since propagation is from
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 5a8bd58..4a940e7f 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -586,7 +586,6 @@ package body Sem_Disp is
Actual : Node_Id;
Formal : Entity_Id;
Control : Node_Id := Empty;
- Func : Entity_Id;
Subp_Entity : constant Entity_Id := Entity (Name (N));
Indeterm_Ctrl_Type : Entity_Id := Empty;
@@ -1099,55 +1098,6 @@ package body Sem_Disp is
Check_Dispatching_Context (N);
- elsif Nkind (N) /= N_Function_Call then
-
- -- The call is not dispatching, so check that there aren't any
- -- tag-indeterminate abstract calls left among its actuals.
-
- Actual := First_Actual (N);
- while Present (Actual) loop
- if Is_Tag_Indeterminate (Actual) then
-
- -- Function call case
-
- if Nkind (Original_Node (Actual)) = N_Function_Call then
- Func := Entity (Name (Original_Node (Actual)));
-
- -- If the actual is an attribute then it can't be abstract
- -- (the only current case of a tag-indeterminate attribute
- -- is the stream Input attribute).
-
- elsif Nkind (Original_Node (Actual)) = N_Attribute_Reference
- then
- Func := Empty;
-
- -- Ditto if it is an explicit dereference
-
- elsif Nkind (Original_Node (Actual)) = N_Explicit_Dereference
- then
- Func := Empty;
-
- -- Only other possibility is a qualified expression whose
- -- constituent expression is itself a call.
-
- else
- Func :=
- Entity (Name (Original_Node
- (Expression (Original_Node (Actual)))));
- end if;
-
- if Present (Func) and then Is_Abstract_Subprogram (Func) then
- Error_Msg_N
- ("call to abstract function must be dispatching",
- Actual);
- end if;
- end if;
-
- Next_Actual (Actual);
- end loop;
-
- Check_Dispatching_Context (N);
-
elsif Nkind (Parent (N)) in N_Subexpr then
Check_Dispatching_Context (N);
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 0dc2e4f..0ebf421 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -16449,8 +16449,6 @@ package body Sem_Prag is
or else not Is_Access_Type (Entity (Arg))
then
Error_Pragma_Arg ("pragma% requires access type", Arg1);
- else
- Set_Has_Pragma_Controlled (Base_Type (Entity (Arg)));
end if;
end Controlled;
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 4d46755..bf9d5e1 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -262,9 +262,8 @@ package body Sem_Res is
function Operator_Kind
(Op_Name : Name_Id;
- Is_Binary : Boolean) return Node_Kind;
- -- Utility to map the name of an operator into the corresponding Node. Used
- -- by other node rewriting procedures.
+ Is_Binary : Boolean) return N_Op;
+ -- Map the name of an operator into the corresponding Node_Kind
procedure Resolve_Actuals (N : Node_Id; Nam : Entity_Id);
-- Resolve actuals of call, and add default expressions for missing ones.
@@ -1986,7 +1985,7 @@ package body Sem_Res is
function Operator_Kind
(Op_Name : Name_Id;
- Is_Binary : Boolean) return Node_Kind
+ Is_Binary : Boolean) return N_Op
is
Kind : Node_Kind;
@@ -10812,7 +10811,12 @@ package body Sem_Res is
and then Is_Character_Type (Component_Type (Typ))
then
Set_String_Literal_Subtype (Op1, Typ);
- Set_String_Literal_Subtype (Op2, Typ);
+
+ -- See Resolve_String_Literal for the asymmetry
+
+ if Ekind (Etype (Op2)) /= E_String_Literal_Subtype then
+ Set_String_Literal_Subtype (Op2, Typ);
+ end if;
end if;
end Resolve_Op_Concat_Rest;
@@ -12032,11 +12036,14 @@ package body Sem_Res is
begin
-- For a string appearing in a concatenation, defer creation of the
-- string_literal_subtype until the end of the resolution of the
- -- concatenation, because the literal may be constant-folded away. This
- -- is a useful optimization for long concatenation expressions.
+ -- concatenation, because the literal may be constant-folded away.
+ -- This is a useful optimization for long concatenation expressions,
+ -- but it cannot be done if the string is the right operand and the
+ -- left operand may be null, because 4.5.3(5) says that the result is
+ -- the right operand and, in particular, has its original subtype.
-- If the string is an aggregate built for a single character (which
- -- happens in a non-static context) or a is null string to which special
+ -- happens in a non-static context) or is a null string to which special
-- checks may apply, we build the subtype. Wide strings must also get a
-- string subtype if they come from a one character aggregate. Strings
-- generated by attributes might be static, but it is often hard to
@@ -12049,6 +12056,11 @@ package body Sem_Res is
or else Nkind (Parent (N)) /= N_Op_Concat
or else (N /= Left_Opnd (Parent (N))
and then N /= Right_Opnd (Parent (N)))
+ or else (N = Right_Opnd (Parent (N))
+ and then
+ (Nkind (Left_Opnd (Parent (N))) /= N_String_Literal
+ or else
+ String_Length (Strval (Left_Opnd (Parent (N)))) = 0))
or else ((Typ = Standard_Wide_String
or else Typ = Standard_Wide_Wide_String)
and then Nkind (Original_Node (N)) /= N_String_Literal);
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index a8984c8..cacf29c 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -6332,6 +6332,26 @@ package body Sem_Util is
end Conditional_Delay;
--------------------------------------
+ -- Direct_Attribute_Definition_Name --
+ --------------------------------------
+
+ function Direct_Attribute_Definition_Name
+ (Prefix : Entity_Id; Att_Name : Name_Id) return Name_Id is
+ begin
+ if Nkind (Prefix) = N_Attribute_Reference then
+ Error_Msg_N ("attribute streams not supported in "
+ & "direct attribute definitions",
+ Prefix);
+ end if;
+
+ pragma Assert (Is_Attribute_Name (Att_Name));
+ return New_External_Name
+ (Related_Id => Chars (Prefix),
+ Suffix => "_" & Get_Name_String (Att_Name) & "_Att",
+ Prefix => 'D');
+ end Direct_Attribute_Definition_Name;
+
+ --------------------------------------
-- Copy_Assertion_Policy_Attributes --
--------------------------------------
@@ -6832,30 +6852,6 @@ package body Sem_Util is
return Is_Class_Wide_Type (Typ) or else Needs_Finalization (Typ);
end CW_Or_Needs_Finalization;
- -------------------------
- -- Default_Constructor --
- -------------------------
-
- function Default_Constructor (Typ : Entity_Id) return Entity_Id is
- Construct : Elmt_Id;
- begin
- pragma Assert (Is_Type (Typ));
- if No (Constructor_Name (Typ)) or else No (Constructor_List (Typ)) then
- return Empty;
- end if;
-
- Construct := First_Elmt (Constructor_List (Typ));
- while Present (Construct) loop
- if Parameter_Count (Elists.Node (Construct)) = 1 then
- return Elists.Node (Construct);
- end if;
-
- Next_Elmt (Construct);
- end loop;
-
- return Empty;
- end Default_Constructor;
-
---------------------
-- Defining_Entity --
---------------------
@@ -11850,6 +11846,35 @@ package body Sem_Util is
(First_Discriminant (Typ)));
end Has_Defaulted_Discriminants;
+ -----------------------------
+ -- Has_Default_Constructor --
+ -----------------------------
+
+ function Has_Default_Constructor (Typ : Entity_Id) return Boolean is
+ Cursor : Entity_Id;
+ begin
+ pragma Assert (Is_Type (Typ));
+ if not Needs_Construction (Typ) then
+ return False;
+ end if;
+
+ -- Iterate through all homonyms to find the default constructor
+
+ Cursor := Get_Name_Entity_Id
+ (Direct_Attribute_Definition_Name (Typ, Name_Constructor));
+ while Present (Cursor) loop
+ if Is_Constructor_Procedure (Cursor)
+ and then No (Next_Formal (First_Formal (Cursor)))
+ then
+ return True;
+ end if;
+
+ Cursor := Homonym (Cursor);
+ end loop;
+
+ return False;
+ end Has_Default_Constructor;
+
-------------------
-- Has_Denormals --
-------------------
@@ -16249,6 +16274,17 @@ package body Sem_Util is
and then Attribute_Name (N) = Name_Result;
end Is_Attribute_Result;
+ -----------------------------------
+ -- Is_Direct_Attribute_Subp_Spec --
+ -----------------------------------
+
+ function Is_Direct_Attribute_Subp_Spec (N : Node_Id) return Boolean is
+ begin
+ return Nkind (N) in N_Subprogram_Specification
+ and then Nkind (Defining_Unit_Name (Original_Node (N)))
+ = N_Attribute_Reference;
+ end Is_Direct_Attribute_Subp_Spec;
+
-------------------------
-- Is_Attribute_Update --
-------------------------
@@ -16684,6 +16720,28 @@ package body Sem_Util is
end if;
end Is_Constant_Bound;
+ ------------------------------
+ -- Is_Constructor_Procedure --
+ ------------------------------
+
+ function Is_Constructor_Procedure (Subp : Entity_Id) return Boolean is
+ First_Param : Entity_Id;
+ begin
+ if not (Present (First_Formal (Subp))
+ and then Ekind (First_Formal (Subp)) = E_In_Out_Parameter
+ and then Is_Direct_Attribute_Subp_Spec (Parent (Subp))
+ and then Attribute_Name (Defining_Unit_Name
+ (Original_Node (Parent (Subp))))
+ = Name_Constructor)
+ then
+ return False;
+ end if;
+
+ First_Param := Implementation_Base_Type (Etype (First_Formal (Subp)));
+ return Scope (Subp) = Scope (First_Param)
+ and then Needs_Construction (First_Param);
+ end Is_Constructor_Procedure;
+
---------------------------
-- Is_Container_Element --
---------------------------
@@ -24817,10 +24875,20 @@ package body Sem_Util is
-- Scalar_Range
if Is_Discrete_Type (Id) then
+
+ -- The scalar range of the source entity had a parent, so the
+ -- scalar range of the newly created entity should also have a
+ -- parent, so that the AST structure is the same.
+
+ pragma Assert (Present (Parent (Scalar_Range (Id))));
+
Set_Scalar_Range (Id, Node_Id (
Copy_Field_With_Replacement
(Field => Union_Id (Scalar_Range (Id)),
Semantic => True)));
+
+ pragma Assert (No (Parent (Scalar_Range (Id))));
+ Set_Parent (Scalar_Range (Id), Id);
end if;
-- Scope
@@ -26669,24 +26737,6 @@ package body Sem_Util is
return Empty;
end Param_Entity;
- ---------------------
- -- Parameter_Count --
- ---------------------
-
- function Parameter_Count (Subp : Entity_Id) return Nat is
- Result : Nat := 0;
- Param : Entity_Id;
- begin
- Param := First_Entity (Subp);
- while Present (Param) loop
- Result := Result + 1;
-
- Param := Next_Entity (Param);
- end loop;
-
- return Result;
- end Parameter_Count;
-
----------------------
-- Policy_In_Effect --
----------------------
@@ -27097,6 +27147,11 @@ package body Sem_Util is
-- the case where Ent is a child unit. This procedure generates an
-- appropriate cross-reference entry. E is the corresponding entity.
+ procedure Get_Attribute_Reference_Name_String (N : Node_Id);
+ -- This procedure append to the Global_Name_Buffer the decoded string
+ -- name of the attribute reference N, including apostrophes and multiple
+ -- prefixes.
+
-------------------------
-- Generate_Parent_Ref --
-------------------------
@@ -27118,6 +27173,21 @@ package body Sem_Util is
end if;
end Generate_Parent_Ref;
+ -----------------------------------------
+ -- Get_Attribute_Reference_Name_String --
+ -----------------------------------------
+
+ procedure Get_Attribute_Reference_Name_String (N : Node_Id) is
+ begin
+ if Nkind (N) /= N_Attribute_Reference then
+ Get_Decoded_Name_String (Chars (N));
+ else
+ Get_Attribute_Reference_Name_String (Prefix (N));
+ Append (Global_Name_Buffer, ''');
+ Get_Decoded_Name_String (Attribute_Name (N));
+ end if;
+ end Get_Attribute_Reference_Name_String;
+
-- Start of processing for Process_End_Label
begin
@@ -27198,9 +27268,12 @@ package body Sem_Util is
-- If the end label is not for the given entity, then either we have
-- some previous error, or this is a generic instantiation for which
-- we do not need to make a cross-reference in this case anyway. In
- -- either case we simply ignore the call.
+ -- either case we simply ignore the call. Matching label for direct
+ -- attribute definitions are checked elsewhere.
- if Chars (Ent) /= Chars (Endl) then
+ if Nkind (Endl) /= N_Attribute_Reference
+ and then Chars (Ent) /= Chars (Endl)
+ then
return;
end if;
@@ -27227,7 +27300,7 @@ package body Sem_Util is
-- mean the semicolon immediately following the label). This is
-- done for the sake of the 'e' or 't' entry generated below.
- Get_Decoded_Name_String (Chars (Endl));
+ Get_Attribute_Reference_Name_String (Endl);
Set_Sloc (Endl, Sloc (Endl) + Source_Ptr (Name_Len));
end if;
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index ee9ecd2..71889b2 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -569,6 +569,10 @@ package Sem_Util is
-- of Old_Ent is set and Old_Ent has not yet been Frozen (i.e. Is_Frozen is
-- False).
+ function Direct_Attribute_Definition_Name
+ (Prefix : Entity_Id; Att_Name : Name_Id) return Name_Id;
+ -- Returns the name used for entities of direct attribute definitions.
+
procedure Copy_Assertion_Policy_Attributes (New_Prag, Old_Prag : Node_Id);
-- Copy Is_Checked, Is_Ignored and Ghost_Assertion_Level attributes from
-- Old_Node.
@@ -674,10 +678,6 @@ package Sem_Util is
-- as Needs_Finalization except with pragma Restrictions (No_Finalization),
-- in which case we know that class-wide objects do not need finalization.
- function Default_Constructor (Typ : Entity_Id) return Entity_Id;
- -- Determine the default constructor (e.g. the constructor with only one
- -- formal parameter) for a given type Typ.
-
function Defining_Entity (N : Node_Id) return Entity_Id;
-- Given a declaration N, returns the associated defining entity. If the
-- declaration has a specification, the entity is obtained from the
@@ -1407,6 +1407,9 @@ package Sem_Util is
function Has_Defaulted_Discriminants (Typ : Entity_Id) return Boolean;
-- Simple predicate to test for defaulted discriminants
+ function Has_Default_Constructor (Typ : Entity_Id) return Boolean;
+ -- Determine whether Typ has a constructor with only one formal parameter.
+
function Has_Denormals (E : Entity_Id) return Boolean;
-- Determines if the floating-point type E supports denormal numbers.
-- Returns False if E is not a floating-point type.
@@ -1880,6 +1883,10 @@ package Sem_Util is
function Is_Attribute_Result (N : Node_Id) return Boolean;
-- Determine whether node N denotes attribute 'Result
+ function Is_Direct_Attribute_Subp_Spec (N : Node_Id) return Boolean;
+ -- Determine whether N denotes a direct attribute definition subprogram
+ -- specification node.
+
function Is_Attribute_Update (N : Node_Id) return Boolean;
-- Determine whether node N denotes attribute 'Update
@@ -1914,6 +1921,10 @@ package Sem_Util is
-- enumeration literal, or an expression composed of constant-bound
-- subexpressions which are evaluated by means of standard operators.
+ function Is_Constructor_Procedure (Subp : Entity_Id) return Boolean;
+ -- Returns True if Subp's name directly references an attribute, has a
+ -- first in out formal that needs construction within the same scope.
+
function Is_Container_Element (Exp : Node_Id) return Boolean;
-- This routine recognizes expressions that denote an element of one of
-- the predefined containers, when the source only contains an indexing
@@ -2973,9 +2984,6 @@ package Sem_Util is
-- WARNING: this routine should be used in debugging scenarios such as
-- tracking down undefined symbols as it is fairly low level.
- function Parameter_Count (Subp : Entity_Id) return Nat;
- -- Return the number of parameters for a given subprogram Subp.
-
function Param_Entity (N : Node_Id) return Entity_Id;
-- Given an expression N, determines if the expression is a reference
-- to a formal (of a subprogram or entry), and if so returns the Id
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 2c15b80..8a35fdc 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -690,7 +690,6 @@ package Sinfo is
-- Do_Discriminant_Check
-- Do_Length_Check
- -- Do_Storage_Check
-- These flags are used in some specific cases by the front end, either
-- during semantic analysis or during expansion, and cannot be expected
@@ -1003,9 +1002,10 @@ package Sinfo is
-- to the defining entity for the corresponding body (NOT the node for
-- the body itself).
- -- Corresponding_Entry_Body
+ -- Corresponding_Entry_Body
-- Defined in N_Subprogram_Body. Set for subprogram bodies that implement
-- a protected type entry; points to the body for the entry.
+ -- Used by codepeer.
-- Corresponding_Formal_Spec
-- This field is set in subprogram renaming declarations, where it points
@@ -1057,13 +1057,6 @@ package Sinfo is
-- This field is present in an N_Variant node, It references the entity
-- for the discriminant checking function for the variant.
- -- Default_Expression
- -- This field is Empty if there is no default expression. If there is a
- -- simple default expression (one with no side effects), then this field
- -- simply contains a copy of the Expression field (both point to the tree
- -- for the default expression). Default_Expression is used for
- -- conformance checking.
-
-- Default_Storage_Pool
-- This field is present in N_Compilation_Unit_Aux nodes. It is set to a
-- copy of Opt.Default_Pool at the end of the compilation unit. See
@@ -1151,14 +1144,6 @@ package Sinfo is
-- listed above (e.g. in a return statement), an additional type
-- conversion node is introduced to represent the required check.
- -- Do_Storage_Check
- -- This flag is set in an N_Allocator node to indicate that a storage
- -- check is required for the allocation, or in an N_Subprogram_Body node
- -- to indicate that a stack check is required in the subprogram prologue.
- -- The N_Allocator case is handled by the routine that expands the call
- -- to the runtime routine. The N_Subprogram_Body case is handled by the
- -- backend, and all the semantics does is set the flag.
-
-- Elaborate_Present
-- This flag is set in the N_With_Clause node to indicate that pragma
-- Elaborate pragma appears for the with'ed units.
@@ -1188,12 +1173,6 @@ package Sinfo is
-- need for this field, so in the tree passed to Gigi, this field is
-- always set to No_List.
- -- Enclosing_Variant
- -- This field is present in the N_Variant node and identifies the Node_Id
- -- corresponding to the immediately enclosing variant when the variant is
- -- nested, and N_Empty otherwise. Set during semantic processing of the
- -- variant part of a record type.
-
-- Entity
-- Appears in all direct names (identifiers, character literals, and
-- operator symbols), as well as expanded names, and attributes that
@@ -1394,14 +1373,6 @@ package Sinfo is
-- Generic_Parent_Type is also used in an instance to determine whether a
-- private operation overrides an inherited one.
- -- Handler_List_Entry
- -- This field is present in N_Object_Declaration nodes. It is set only
- -- for the Handler_Record entry generated for an exception in zero cost
- -- exception handling mode. It references the corresponding item in the
- -- handler list, and is used to delete this entry if the corresponding
- -- handler is deleted during optimization. For further details on why
- -- this is required, see Exp_Ch11.Remove_Handler_Entries.
-
-- Has_Dereference_Action
-- This flag is present in N_Explicit_Dereference nodes. It is set to
-- indicate that the expansion has aready produced a call to primitive
@@ -1884,11 +1855,6 @@ package Sinfo is
-- the generic unit on the actual parameters done in the outermost scope
-- where it would be legal to declare an identical named instantiation.
- -- Is_Subprogram_Descriptor
- -- Present in N_Object_Declaration, and set only for the object
- -- declaration generated for a subprogram descriptor in fast exception
- -- mode. See Exp_Ch11 for details of use.
-
-- Is_Task_Allocation_Block
-- A flag set in a Block_Statement node to indicate that it is the
-- expansion of a task allocator, or the allocator of an object
@@ -2237,14 +2203,6 @@ package Sinfo is
-- to indicate that a use is redundant (and therefore need not be undone
-- on scope exit).
- -- Renaming_Exception
- -- Present in N_Exception_Declaration node. Used to point back to the
- -- exception renaming for an exception declared within a subprogram.
- -- What happens is that an exception declared in a subprogram is moved
- -- to the library level with a unique name, and the original exception
- -- becomes a renaming. This link from the library level exception to the
- -- renaming declaration allows registering of the proper exception name.
-
-- Return_Statement_Entity
-- Present in N_Simple_Return_Statement and N_Extended_Return_Statement.
-- Points to an E_Return_Statement representing the return statement.
@@ -3020,14 +2978,12 @@ package Sinfo is
-- Null_Exclusion_Present
-- Object_Definition subtype indic./array type def./access def.
-- Expression (set to Empty if not present)
- -- Handler_List_Entry
-- Corresponding_Generic_Association
-- More_Ids (set to False if no more identifiers in list)
-- Prev_Ids (set to False if no previous identifiers in list)
-- No_Initialization
-- Assignment_OK
-- Exception_Junk
- -- Is_Subprogram_Descriptor
-- Has_Init_Expression
-- Suppress_Assignment_Checks
@@ -3632,7 +3588,6 @@ package Sinfo is
-- Sloc points to WHEN
-- Discrete_Choices
-- Component_List
- -- Enclosing_Variant
-- Present_Expr
-- Dcheck_Function
-- Has_SP_Choice
@@ -4853,7 +4808,6 @@ package Sinfo is
-- Null_Exclusion_Present
-- No_Initialization
-- Is_Static_Coextension
- -- Do_Storage_Check
-- Is_Dynamic_Coextension
-- plus fields for expression
@@ -5505,10 +5459,9 @@ package Sinfo is
-- Out_Present
-- Null_Exclusion_Present
-- Parameter_Type subtype mark or access definition
- -- Expression (set to Empty if no default expression present)
+ -- Expression (set to Empty if no default expression)
-- More_Ids (set to False if no more identifiers in list)
-- Prev_Ids (set to False if no previous identifiers in list)
- -- Default_Expression
---------------
-- 6.1 Mode --
@@ -5541,7 +5494,6 @@ package Sinfo is
-- At_End_Proc (set to Empty if no clean up procedure)
-- Acts_As_Spec
-- Bad_Is_Detected used only by parser
- -- Do_Storage_Check
-- Has_Relative_Deadline_Pragma
-- Is_Entry_Barrier_Function
-- Is_Protected_Subprogram_Body
@@ -6887,11 +6839,16 @@ package Sinfo is
-- N_Exception_Declaration
-- Sloc points to EXCEPTION
-- Defining_Identifier
- -- Expression
- -- Renaming_Exception
+ -- Expression (see below)
-- More_Ids (set to False if no more identifiers in list)
-- Prev_Ids (set to False if no previous identifiers in list)
+ -- Expression is not present in the syntax; it is set during expansion.
+ -- An exception_declaration is treated by the back end like an object of
+ -- type Standard.Exception_Type, and Expression is the initial value.
+ -- Expression is a syntactic field to match the Expression fields of
+ -- other node kinds.
+
------------------------------------------
-- 11.2 Handled Sequence Of Statements --
------------------------------------------
@@ -7236,7 +7193,7 @@ package Sinfo is
-- Null_Exclusion_Present (set to False if not present)
-- Subtype_Mark (set to Empty if not present)
-- Access_Definition (set to Empty if not present)
- -- Default_Expression (set to Empty if no default expression)
+ -- Expression (set to Empty if no default expression)
-- More_Ids (set to False if no more identifiers in list)
-- Prev_Ids (set to False if no previous identifiers in list)
@@ -7987,6 +7944,9 @@ package Sinfo is
-- N_Compound_Statement
-- Actions
+ -- Note that N_Compound_Statement is unrelated to the Ada syntax rule
+ -- for compound_statement.
+
--------------
-- Contract --
--------------
diff --git a/gcc/ada/snames.adb-tmpl b/gcc/ada/snames.adb-tmpl
index fcfd390..b5f53cd 100644
--- a/gcc/ada/snames.adb-tmpl
+++ b/gcc/ada/snames.adb-tmpl
@@ -412,6 +412,15 @@ package body Snames is
end if;
end Is_Convention_Name;
+ -----------------------------------------
+ -- Is_Direct_Attribute_Definition_Name --
+ -----------------------------------------
+
+ function Is_Direct_Attribute_Definition_Name (N : Name_Id) return Boolean is
+ begin
+ return Is_Attribute_Name (N) and then N = Name_Constructor;
+ end Is_Direct_Attribute_Definition_Name;
+
------------------------------
-- Is_Entity_Attribute_Name --
------------------------------
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index d6fe60b..cb07f97 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -147,7 +147,6 @@ package Snames is
-- Names of aspects for which there are no matching pragmas or attributes
-- so that they need to be included for aspect specification use.
- Name_Constructor : constant Name_Id := N + $;
Name_Default_Value : constant Name_Id := N + $;
Name_Default_Component_Value : constant Name_Id := N + $;
Name_Designated_Storage_Model : constant Name_Id := N + $;
@@ -956,6 +955,7 @@ package Snames is
Name_Component_Size : constant Name_Id := N + $;
Name_Compose : constant Name_Id := N + $;
Name_Constrained : constant Name_Id := N + $;
+ Name_Constructor : constant Name_Id := N + $;
Name_Count : constant Name_Id := N + $;
Name_Default_Bit_Order : constant Name_Id := N + $; -- GNAT
Name_Default_Scalar_Storage_Order : constant Name_Id := N + $; -- GNAT
@@ -1500,6 +1500,7 @@ package Snames is
Attribute_Component_Size,
Attribute_Compose,
Attribute_Constrained,
+ Attribute_Constructor,
Attribute_Count,
Attribute_Default_Bit_Order,
Attribute_Default_Scalar_Storage_Order,
@@ -2077,6 +2078,10 @@ package Snames is
-- mode. This is the mechanism for considering this pragma illegal in
-- normal GNAT programs.
+ function Is_Direct_Attribute_Definition_Name (N : Name_Id) return Boolean;
+ -- Test to see if the name N is the name of a recognized attribute and is
+ -- allowed to be directly referenced in subprogram specification.
+
function Is_Entity_Attribute_Name (N : Name_Id) return Boolean;
-- Test to see if the name N is the name of a recognized entity attribute,
-- i.e. an attribute reference that returns an entity.
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index f5caa3d..8c49864 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -1963,9 +1963,9 @@ package body Sprint is
Sprint_Node (Access_Definition (Node));
end if;
- if Present (Default_Expression (Node)) then
+ if Present (Expression (Node)) then
Write_Str (" := ");
- Sprint_Node (Default_Expression (Node));
+ Sprint_Node (Expression (Node));
end if;
Write_Char (';');
diff --git a/gcc/ada/style.adb b/gcc/ada/style.adb
index 6e5688d..56d1060 100644
--- a/gcc/ada/style.adb
+++ b/gcc/ada/style.adb
@@ -345,12 +345,14 @@ package body Style is
begin
if Style_Check_Xtra_Parens_Precedence
and then
- Paren_Count (N) >
- (if Nkind (N) in N_Case_Expression
- | N_Expression_With_Actions
- | N_If_Expression
- | N_Quantified_Expression
- | N_Raise_Expression
+ Paren_Count (Original_Node (N)) >
+ (if Nkind (Original_Node (N)) in N_Case_Expression
+ | N_Expression_With_Actions
+ | N_If_Expression
+ | N_Quantified_Expression
+ | N_Raise_Expression
+ | N_In
+ | N_Not_In
then 1
else 0)
then
diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb
index fbad71a..9d78987 100644
--- a/gcc/ada/treepr.adb
+++ b/gcc/ada/treepr.adb
@@ -338,6 +338,8 @@ package body Treepr is
return "Is_Elaboration_Checks_OK_Id";
when F_Is_Elaboration_Warnings_OK_Id =>
return "Is_Elaboration_Warnings_OK_Id";
+ when F_Is_IEEE_Extended_Precision =>
+ return "Is_IEEE_Extended_Precision";
when F_Is_RACW_Stub_Type =>
return "Is_RACW_Stub_Type";
when F_LSP_Subprogram =>
diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
index 790ebc7..3e54c2a 100644
--- a/gcc/analyzer/checker-event.cc
+++ b/gcc/analyzer/checker-event.cc
@@ -833,6 +833,14 @@ start_cfg_edge_event::should_print_expr_p (tree expr)
return false;
}
+/* class catch_cfg_edge_event : public cfg_edge_event. */
+
+diagnostics::paths::event::meaning
+catch_cfg_edge_event::get_meaning () const
+{
+ return meaning (verb::catch_);
+}
+
/* class call_event : public superedge_event. */
/* call_event's ctor. */
@@ -1034,6 +1042,12 @@ setjmp_event::print_desc (pretty_printer &pp) const
get_user_facing_name (m_setjmp_call));
}
+diagnostics::paths::event::meaning
+setjmp_event::get_meaning () const
+{
+ return meaning (verb::setjmp_);
+}
+
/* Implementation of checker_event::prepare_for_emission vfunc for setjmp_event.
Record this setjmp's event ID into the path, so that rewind events can
@@ -1066,6 +1080,12 @@ rewind_event::get_setjmp_caller () const
return m_eedge->m_dest->get_function ()->decl;
}
+diagnostics::paths::event::meaning
+rewind_event::get_meaning () const
+{
+ return meaning (verb::longjmp_);
+}
+
/* rewind_event's ctor. */
rewind_event::rewind_event (const exploded_edge *eedge,
@@ -1163,6 +1183,12 @@ rewind_to_setjmp_event::prepare_for_emission (checker_path *path,
/* class throw_event : public checker_event. */
+diagnostics::paths::event::meaning
+throw_event::get_meaning () const
+{
+ return meaning (verb::throw_);
+}
+
/* class explicit_throw_event : public throw_event. */
void
explicit_throw_event::print_desc (pretty_printer &pp) const
@@ -1205,6 +1231,12 @@ unwind_event::print_desc (pretty_printer &pp) const
pp_printf (&pp, "unwinding stack frame");
}
+diagnostics::paths::event::meaning
+unwind_event::get_meaning () const
+{
+ return meaning (verb::unwind_);
+}
+
/* class warning_event : public checker_event. */
/* Implementation of diagnostics::paths::event::print_desc vfunc for
diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h
index 909e388..fc51be1 100644
--- a/gcc/analyzer/checker-event.h
+++ b/gcc/analyzer/checker-event.h
@@ -539,6 +539,8 @@ public:
pp_string (&pp, "...catching exception here");
}
+ meaning get_meaning () const override;
+
private:
tree m_type;
};
@@ -666,6 +668,8 @@ public:
void print_desc (pretty_printer &pp) const final override;
+ meaning get_meaning () const override;
+
void prepare_for_emission (checker_path *path,
pending_diagnostic *pd,
diagnostics::paths::event_id_t emission_id) final override;
@@ -688,6 +692,8 @@ public:
tree get_setjmp_caller () const;
const exploded_edge *get_eedge () const { return m_eedge; }
+ meaning get_meaning () const override;
+
protected:
rewind_event (const exploded_edge *eedge,
enum event_kind kind,
@@ -754,6 +760,8 @@ public:
{
}
+ meaning get_meaning () const override;
+
protected:
const exploded_node *m_enode;
const gcall &m_throw_call;
@@ -817,6 +825,8 @@ public:
{
}
+ meaning get_meaning () const override;
+
void print_desc (pretty_printer &pp) const final override;
int m_num_frames;
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 274e2a7..23cc53a 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,21 @@
+2025-11-01 Martin Uecker <uecker@tugraz.at>
+
+ * c-decl.cc (build_compound_literal): Add error.
+ * c-parser.cc (c_parser_braced_init): Take bool argument for
+ variable size instead of DECL.
+ (c_parser_initializer,c_parser_initval): Adapt.
+ (c_parser_postfix_expression_after_paren_type): Change
+ error to pedwarn.
+ * c-typeck.cc (process_init_element): Add error for
+ variable-size compound literal with static or constexpr.
+
+2025-11-01 Martin Uecker <uecker@tugraz.at>
+
+ PR c/97986
+ * c-parser.cc (c_parser_postfix_expression): Adapt.
+ * c-tree.h (c_build_va_arg): Adapt prototype.
+ * c-typeck.cc (c_build_va_arg): Handle UB.
+
2025-10-30 Qing Zhao <qing.zhao@oracle.com>
* c-typeck.cc (build_access_with_size_for_counted_by): When the element
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 2b31a43..1e1da2d 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -6536,6 +6536,10 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const,
return error_mark_node;
}
+ if ((TREE_STATIC (decl) || C_DECL_DECLARED_CONSTEXPR (decl))
+ && C_TYPE_VARIABLE_SIZE (type))
+ error_at (loc, "storage size isn%'t constant");
+
if (TREE_STATIC (decl)
&& !verify_type_context (loc, TCTX_STATIC_STORAGE, type))
return error_mark_node;
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 0cf3f92..9b3a786 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -1767,7 +1767,7 @@ static tree c_parser_simple_asm_expr (c_parser *);
static tree c_parser_gnu_attributes (c_parser *);
static struct c_expr c_parser_initializer (c_parser *, tree);
static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
- struct obstack *, tree);
+ struct obstack *, bool);
static void c_parser_initelt (c_parser *, struct obstack *);
static void c_parser_initval (c_parser *, struct c_expr *,
struct obstack *);
@@ -6459,7 +6459,9 @@ static struct c_expr
c_parser_initializer (c_parser *parser, tree decl)
{
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
- return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
+ return c_parser_braced_init (parser, NULL_TREE, false, NULL,
+ decl != error_mark_node
+ && C_DECL_VARIABLE_SIZE (decl));
else
{
struct c_expr ret;
@@ -6499,12 +6501,12 @@ location_t last_init_list_comma;
compound literal, and NULL_TREE for other initializers and for
nested braced lists. NESTED_P is true for nested braced lists,
false for the list of a compound literal or the list that is the
- top-level initializer in a declaration. DECL is the declaration for
- the top-level initializer for a declaration, otherwise NULL_TREE. */
+ top-level initializer in a declaration. VARSIZE_P indicates
+ wether the object to be initialized has a variable size. */
static struct c_expr
c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
- struct obstack *outer_obstack, tree decl)
+ struct obstack *outer_obstack, bool varsize_p)
{
struct c_expr ret;
struct obstack braced_init_obstack;
@@ -6532,7 +6534,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
}
else
{
- if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
+ if (varsize_p)
error_at (brace_loc,
"variable-sized object may not be initialized except "
"with an empty initializer");
@@ -6826,7 +6828,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after,
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
init = c_parser_braced_init (parser, NULL_TREE, true,
- braced_init_obstack, NULL_TREE);
+ braced_init_obstack, false);
else
{
init = c_parser_expr_no_commas (parser, after);
@@ -11793,15 +11795,9 @@ c_parser_postfix_expression (c_parser *parser)
else
{
tree type_expr = NULL_TREE;
+ tree type = groktypename (t1, &type_expr, NULL);
expr.value = c_build_va_arg (start_loc, e1.value, loc,
- groktypename (t1, &type_expr, NULL));
- if (type_expr)
- {
- expr.value = build2 (C_MAYBE_CONST_EXPR,
- TREE_TYPE (expr.value), type_expr,
- expr.value);
- C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
- }
+ type, type_expr);
set_c_expr_source_range (&expr, start_loc, end_loc);
}
}
@@ -13516,10 +13512,11 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
|| (scspecs && scspecs->storage_class == csc_static)
|| constexpr_p), constexpr_p, &richloc);
type = groktypename (type_name, &type_expr, &type_expr_const);
+ bool varsize_p = false;
if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
{
- error_at (type_loc, "compound literal has variable size");
- type = error_mark_node;
+ pedwarn (type_loc, OPT_Wpedantic, "compound literal has variable size");
+ varsize_p = true;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
@@ -13544,7 +13541,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
(TYPE_QUALS (type_no_array)
| TYPE_QUAL_CONST));
}
- init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
+ init = c_parser_braced_init (parser, type, false, NULL, varsize_p);
if (constexpr_p)
finish_underspecified_init (NULL_TREE, underspec_state);
finish_init ();
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index f367cda..ff63d69 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -917,7 +917,7 @@ extern tree c_omp_finish_mapper_clauses (tree);
extern tree c_omp_mapper_lookup (tree, tree);
extern tree c_omp_extract_mapper_directive (tree);
extern tree c_omp_map_array_section (location_t, tree);
-extern tree c_build_va_arg (location_t, tree, location_t, tree);
+extern tree c_build_va_arg (location_t, tree, location_t, tree, tree);
extern tree c_finish_transaction (location_t, tree, int);
extern bool c_tree_equal (tree, tree);
extern tree c_build_function_call_vec (location_t, const vec<location_t>&,
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index bc0fb6b..2cef463 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -12734,7 +12734,9 @@ retry:
if (constructor_max_index != NULL_TREE
&& (tree_int_cst_lt (constructor_max_index, constructor_index)
- || integer_all_onesp (constructor_max_index)))
+ || integer_all_onesp (constructor_max_index))
+ /* For VLA we got an error already. */
+ && !C_TYPE_VARIABLE_SIZE (constructor_type))
{
pedwarn_init (loc, 0,
"excess elements in array initializer");
@@ -18435,7 +18437,8 @@ c_build_qualified_type (tree type, int type_quals, tree orig_qual_type,
/* Build a VA_ARG_EXPR for the C parser. */
tree
-c_build_va_arg (location_t loc1, tree expr, location_t loc2, tree type)
+c_build_va_arg (location_t loc1, tree expr, location_t loc2, tree type,
+ tree type_expr)
{
if (error_operand_p (type))
return error_mark_node;
@@ -18459,10 +18462,36 @@ c_build_va_arg (location_t loc1, tree expr, location_t loc2, tree type)
type);
return error_mark_node;
}
+ else if (TREE_CODE (type) == ARRAY_TYPE && C_TYPE_VARIABLE_SIZE (type)
+ && !flag_isoc99)
+ {
+ error_at (loc2, "second argument to %<va_arg%> is an array type %qT",
+ type);
+ return error_mark_node;
+ }
else if (warn_cxx_compat && TREE_CODE (type) == ENUMERAL_TYPE)
warning_at (loc2, OPT_Wc___compat,
"C++ requires promoted type, not enum type, in %<va_arg%>");
- return build_va_arg (loc2, expr, type);
+
+ if (flag_isoc99 && TREE_CODE (type) == ARRAY_TYPE)
+ {
+ warning_at (loc2, 0, "second argument to %<va_arg%> is an array type %qT",
+ type);
+ /* We create a trap but evaluate side effects first. */
+ tree trapfn = builtin_decl_explicit (BUILT_IN_TRAP);
+ trapfn = build_call_expr_loc (loc2, trapfn, 0);
+ tree e2 = build2 (COMPOUND_EXPR, void_type_node, expr, trapfn);
+ /* Return a compound literal of the right type. */
+ tree e1 = build_compound_literal (loc2, type, NULL, true, 0, NULL);
+ expr = build2 (COMPOUND_EXPR, type, e2, e1);
+ }
+ else
+ expr = build_va_arg (loc2, expr, type);
+
+ if (type_expr)
+ expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), type_expr, expr);
+
+ return expr;
}
/* Return truthvalue of whether T1 is the same tree structure as T2.
diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def
index a70375c05..083515d 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -155,6 +155,12 @@ AARCH64_OPT_EXTENSION("fp16fml", F16FML, (), (F16), (), "asimdfhm")
AARCH64_FMV_FEATURE("fp16fml", FP16FML, (F16FML))
+AARCH64_FMV_FEATURE("dit", DIT, ())
+
+AARCH64_FMV_FEATURE("dpb", DPB, ())
+
+AARCH64_FMV_FEATURE("dpb2", DPB2, ())
+
AARCH64_OPT_FMV_EXTENSION("jscvt", JSCVT, (FP), (), (), "jscvt")
AARCH64_OPT_FMV_EXTENSION("fcma", FCMA, (SIMD), (), (), "fcma")
@@ -209,13 +215,15 @@ AARCH64_OPT_EXTENSION("sve2p1", SVE2p1, (SVE2), (), (), "sve2p1")
AARCH64_OPT_FMV_EXTENSION("sme", SME, (BF16, FCMA, F16, F16FML), (), (), "sme")
-AARCH64_OPT_EXTENSION("memtag", MEMTAG, (), (), (), "")
+AARCH64_OPT_FMV_EXTENSION("memtag", MEMTAG, (), (), (), "")
AARCH64_OPT_FMV_EXTENSION("sb", SB, (), (), (), "sb")
AARCH64_OPT_EXTENSION("predres", PREDRES, (), (), (), "")
-AARCH64_OPT_EXTENSION("ssbs", SSBS, (), (), (), "ssbs")
+AARCH64_OPT_FMV_EXTENSION("ssbs", SSBS, (), (), (), "ssbs")
+
+AARCH64_FMV_FEATURE("bti", BTI, ())
AARCH64_OPT_EXTENSION("profile", PROFILE, (), (), (), "")
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 6f6dea6..74e2f20 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -20380,6 +20380,8 @@ typedef struct
/* The "rdma" alias uses a different FEAT_NAME to avoid a duplicate
feature_deps name. */
#define FEAT_RDMA FEAT_RDM
+#define FEAT_SSBS FEAT_SSBS2
+#define FEAT_MEMTAG FEAT_MEMTAG2
/* FMV features are listed in priority order, to make it easier to sort target
strings. */
diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md
index a53b2ba..53e0c83 100644
--- a/gcc/config/arc/simdext.md
+++ b/gcc/config/arc/simdext.md
@@ -1438,11 +1438,15 @@
"reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
[(set (match_dup 0) (match_dup 2))]
{
- HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
- intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
-
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
- operands[2] = GEN_INT (trunc_int_for_mode (intval, SImode));
+ int hi = TARGET_BIG_ENDIAN ? 0 : 1;
+ int lo = TARGET_BIG_ENDIAN ? 1 : 0;
+ HOST_WIDE_INT hi_val = INTVAL (XVECEXP (operands[1], 0, hi));
+ HOST_WIDE_INT lo_val = INTVAL (XVECEXP (operands[1], 0, lo));
+ hi_val = zext_hwi (hi_val, 16);
+ lo_val = zext_hwi (lo_val, 16);
+ HOST_WIDE_INT intval = lo_val | (hi_val << 16);
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ operands[2] = GEN_INT (trunc_int_for_mode (intval, SImode));
}
[(set_attr "type" "move,move,load,store")
(set_attr "predicable" "yes,yes,no,no")
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 227c12a..0bdba55 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -3272,7 +3272,8 @@ avr_load_libgcc_p (rtx op)
return (n_bytes > 2
&& !AVR_HAVE_LPMX
- && avr_mem_flash_p (op));
+ && avr_mem_flash_p (op)
+ && MEM_ADDR_SPACE (op) == ADDR_SPACE_FLASH);
}
@@ -3624,6 +3625,46 @@ avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
avr_asm_len ("sbiw %2,1", xop, plen, 1);
break; /* 2 */
+
+ /* cases 3 and 4 are only needed with ELPM but no ELPMx. */
+
+ case 3:
+ if (REGNO (dest) == REG_Z - 2
+ && !reg_unused_after (insn, all_regs_rtx[REG_31]))
+ avr_asm_len ("push r31", xop, plen, 1);
+
+ avr_asm_len ("%4lpm $ mov %A0,%3 $ adiw %2,1", xop, plen, 3);
+ avr_asm_len ("%4lpm $ mov %B0,%3 $ adiw %2,1", xop, plen, 3);
+ avr_asm_len ("%4lpm $ mov %C0,%3", xop, plen, 2);
+
+ if (REGNO (dest) == REG_Z - 2)
+ {
+ if (!reg_unused_after (insn, all_regs_rtx[REG_31]))
+ avr_asm_len ("pop r31", xop, plen, 1);
+ }
+ else if (!reg_unused_after (insn, addr))
+ avr_asm_len ("sbiw %2,2", xop, plen, 1);
+
+ break; /* 3 */
+
+ case 4:
+ avr_asm_len ("%4lpm $ mov %A0,%3 $ adiw %2,1", xop, plen, 3);
+ avr_asm_len ("%4lpm $ mov %B0,%3 $ adiw %2,1", xop, plen, 3);
+ if (REGNO (dest) != REG_Z - 2)
+ {
+ avr_asm_len ("%4lpm $ mov %C0,%3 $ adiw %2,1", xop, plen, 3);
+ avr_asm_len ("%4lpm $ mov %D0,%3", xop, plen, 2);
+ if (!reg_unused_after (insn, addr))
+ avr_asm_len ("sbiw %2,3", xop, plen, 1);
+ }
+ else
+ {
+ avr_asm_len ("%4lpm $ push %3 $ adiw %2,1", xop, plen, 3);
+ avr_asm_len ("%4lpm $ mov %D0,%3", xop, plen, 2);
+ avr_asm_len ("pop $C0", xop, plen, 1);
+ }
+
+ break; /* 4 */
}
break; /* REG */
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 30a02a4..d73cf96 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -3947,9 +3947,17 @@
(match_operand:PSI 2 "nonmemory_operand" "")))
(clobber (reg:HI 26))
(clobber (reg:DI 18))])]
- "AVR_HAVE_MUL"
+ "AVR_HAVE_MUL
+ || (avropt_pr118012
+ /* AVR_TINY passes args on the stack, so we cannot work
+ around PR118012 like this. */
+ && ! AVR_TINY)"
{
- if (s8_operand (operands[2], PSImode))
+ if (!AVR_HAVE_MUL)
+ {
+ operands[2] = force_reg (PSImode, operands[2]);
+ }
+ else if (s8_operand (operands[2], PSImode))
{
rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
@@ -4038,7 +4046,9 @@
(match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
(clobber (reg:HI 26))
(clobber (reg:DI 18))]
- "AVR_HAVE_MUL && !reload_completed"
+ "!reload_completed
+ && (AVR_HAVE_MUL
+ || (avropt_pr118012 && !AVR_TINY))"
{ gcc_unreachable(); }
"&& 1"
[(set (reg:PSI 18)
@@ -4048,13 +4058,30 @@
(parallel [(set (reg:PSI 22)
(mult:PSI (reg:PSI 22)
(reg:PSI 18)))
- (clobber (reg:QI 21))
- (clobber (reg:QI 25))
- (clobber (reg:HI 26))])
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (match_dup 5))])
(set (match_dup 0)
(reg:PSI 22))]
{
- if (s8_operand (operands[2], PSImode))
+ if (AVR_HAVE_MUL)
+ {
+ operands[3] = gen_rtx_REG (QImode, REG_21);
+ operands[4] = gen_rtx_REG (QImode, REG_25);
+ operands[5] = gen_rtx_REG (HImode, REG_26);
+ }
+ else
+ {
+ operands[3] = gen_rtx_REG (SImode, REG_18);
+ operands[4] = gen_rtx_SCRATCH (QImode);
+ operands[5] = gen_rtx_SCRATCH (HImode);
+ }
+
+ if (!AVR_HAVE_MUL)
+ {
+ operands[2] = force_reg (PSImode, operands[2]);
+ }
+ else if (s8_operand (operands[2], PSImode))
{
rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
@@ -4106,6 +4133,32 @@
"%~call __mulpsi3"
[(set_attr "type" "xcall")])
+(define_insn_and_split "*mulpsi3-nomul.libgcc_split"
+ [(set (reg:PSI 22)
+ (mult:PSI (reg:PSI 22)
+ (reg:PSI 18)))
+ (clobber (reg:SI 18))
+ (clobber (scratch:QI))
+ (clobber (scratch:HI))]
+ "!AVR_HAVE_MUL && avropt_pr118012 && !AVR_TINY"
+ "#"
+ "&& reload_completed"
+ [(scratch)]
+ { DONE_ADD_CCC })
+
+(define_insn "*mulpsi3-nomul.libgcc"
+ [(set (reg:PSI 22)
+ (mult:PSI (reg:PSI 22)
+ (reg:PSI 18)))
+ (clobber (reg:SI 18))
+ (clobber (scratch:QI))
+ (clobber (scratch:HI))
+ (clobber (reg:CC REG_CC))]
+ "reload_completed
+ && !AVR_HAVE_MUL && avropt_pr118012 && !AVR_TINY"
+ "%~call __mulpsi3"
+ [(set_attr "type" "xcall")])
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 24-bit signed/unsigned division and modulo.
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index a1f1b26..c131f7c 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -9995,6 +9995,754 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
return true;
}
+/* Fully unroll memmove of known size with up to 8 registers. */
+
+static bool
+ix86_expand_unroll_movmem (rtx dst, rtx src, rtx destreg, rtx srcreg,
+ unsigned HOST_WIDE_INT count,
+ machine_mode mode)
+{
+ /* If 8 registers registers can cover all memory, load them into
+ registers and store them together to avoid possible address
+ overlap between source and destination. */
+ unsigned HOST_WIDE_INT moves = count / GET_MODE_SIZE (mode);
+ if (moves == 0)
+ {
+ mode = smallest_int_mode_for_size
+ (count * BITS_PER_UNIT).require ();
+ if (count == GET_MODE_SIZE (mode))
+ moves = 1;
+ else
+ {
+ /* Reduce the smallest move size by half so that MOVES == 1. */
+ mode = smallest_int_mode_for_size
+ (GET_MODE_BITSIZE (mode) / 2).require ();
+ moves = count / GET_MODE_SIZE (mode);
+ gcc_assert (moves == 1);
+ }
+ }
+ else if (moves > 8)
+ return false;
+
+ unsigned int i;
+ rtx tmp[9];
+
+ for (i = 0; i < moves; i++)
+ tmp[i] = gen_reg_rtx (mode);
+
+ rtx srcmem = change_address (src, mode, srcreg);
+ for (i = 0; i < moves; i++)
+ {
+ emit_move_insn (tmp[i], srcmem);
+ srcmem = offset_address (srcmem,
+ GEN_INT (GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ }
+
+ unsigned int epilogue_size = count & (GET_MODE_SIZE (mode) - 1);
+ machine_mode epilogue_mode = VOIDmode;
+ if (epilogue_size)
+ {
+ /* Handle the remaining bytes with overlapping move. */
+ epilogue_mode = smallest_int_mode_for_size
+ (epilogue_size * BITS_PER_UNIT).require ();
+ tmp[8] = gen_reg_rtx (epilogue_mode);
+ srcmem = adjust_address (srcmem, epilogue_mode, 0);
+ srcmem = offset_address (srcmem, GEN_INT (epilogue_size), 1);
+ srcmem = offset_address (srcmem,
+ GEN_INT (-GET_MODE_SIZE (epilogue_mode)),
+ GET_MODE_SIZE (epilogue_mode));
+ emit_move_insn (tmp[8], srcmem);
+ }
+
+ rtx destmem = change_address (dst, mode, destreg);
+ for (i = 0; i < moves; i++)
+ {
+ emit_move_insn (destmem, tmp[i]);
+ destmem = offset_address (destmem,
+ GEN_INT (GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ }
+
+ if (epilogue_size)
+ {
+ /* Use overlapping move. */
+ destmem = adjust_address (destmem, epilogue_mode, 0);
+ destmem = offset_address (destmem, GEN_INT (epilogue_size), 1);
+ destmem = offset_address (destmem,
+ GEN_INT (-GET_MODE_SIZE (epilogue_mode)),
+ GET_MODE_SIZE (epilogue_mode));
+ emit_move_insn (destmem, tmp[8]);
+ }
+
+ return true;
+}
+
+/* Expand memmove of size with MOVES * mode size and MOVES <= 4. If
+ FORWARD is true, copy forward. Otherwise copy backward. */
+
+static void
+ix86_expand_n_move_movmem (rtx destmem, rtx srcmem, machine_mode mode,
+ unsigned int moves, bool forward)
+{
+ gcc_assert (moves <= 4);
+
+ unsigned int i;
+ rtx tmp[8];
+
+ for (i = 0; i < moves; i++)
+ tmp[i] = gen_reg_rtx (mode);
+
+ rtx step;
+ if (forward)
+ step = GEN_INT (GET_MODE_SIZE (mode));
+ else
+ step = GEN_INT (-GET_MODE_SIZE (mode));
+
+ /* Load MOVES. */
+ for (i = 0; i < moves - 1; i++)
+ {
+ emit_move_insn (tmp[i], srcmem);
+ srcmem = offset_address (srcmem, step, GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (tmp[i], srcmem);
+
+ /* Store MOVES. */
+ for (i = 0; i < moves - 1; i++)
+ {
+ emit_move_insn (destmem, tmp[i]);
+ destmem = offset_address (destmem, step, GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (destmem, tmp[i]);
+}
+
+/* Load MOVES of mode size into REGS. If LAST is true, load the
+ last MOVES. Otherwise, load the first MOVES. */
+
+static void
+ix86_expand_load_movmem (rtx src, rtx srcreg, rtx count_exp,
+ machine_mode mode, unsigned int moves,
+ rtx regs[], bool last)
+{
+ unsigned int i;
+
+ for (i = 0; i < moves; i++)
+ regs[i] = gen_reg_rtx (mode);
+
+ rtx srcmem = change_address (src, mode, srcreg);
+ rtx step;
+ if (last)
+ {
+ srcmem = offset_address (srcmem, count_exp, 1);
+ step = GEN_INT (-GET_MODE_SIZE (mode));
+ srcmem = offset_address (srcmem, step, GET_MODE_SIZE (mode));
+ }
+ else
+ step = GEN_INT (GET_MODE_SIZE (mode));
+
+ for (i = 0; i < moves - 1; i++)
+ {
+ emit_move_insn (regs[i], srcmem);
+ srcmem = offset_address (srcmem, step, GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (regs[i], srcmem);
+}
+
+/* Store MOVES of mode size into REGS. If LAST is true, store the
+ last MOVES. Otherwise, store the first MOVES. */
+
+static void
+ix86_expand_store_movmem (rtx dst, rtx destreg, rtx count_exp,
+ machine_mode mode, unsigned int moves,
+ rtx regs[], bool last)
+{
+ unsigned int i;
+
+ rtx destmem = change_address (dst, mode, destreg);
+ rtx step;
+ if (last)
+ {
+ destmem = offset_address (destmem, count_exp, 1);
+ step = GEN_INT (-GET_MODE_SIZE (mode));
+ destmem = offset_address (destmem, step, GET_MODE_SIZE (mode));
+ }
+ else
+ step = GEN_INT (GET_MODE_SIZE (mode));
+
+ for (i = 0; i < moves - 1; i++)
+ {
+ emit_move_insn (destmem, regs[i]);
+ destmem = offset_address (destmem, step, GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (destmem, regs[i]);
+}
+
+/* Expand memmove of size between (MOVES / 2) * mode size and
+ MOVES * mode size with overlapping load and store. MOVES is even.
+ MOVES >= 2 and MOVES <= 8. */
+
+static void
+ix86_expand_n_overlapping_move_movmem (rtx dst, rtx src, rtx destreg,
+ rtx srcreg, rtx count_exp,
+ machine_mode mode,
+ unsigned int moves)
+{
+ gcc_assert (moves >= 2 && moves <= 8 && (moves & 1) == 0);
+
+ unsigned int half_moves = moves / 2;
+ unsigned int i, j;
+ rtx tmp[8];
+
+ for (i = 0; i < moves; i++)
+ tmp[i] = gen_reg_rtx (mode);
+
+ rtx base_srcmem = change_address (src, mode, srcreg);
+
+ /* Load the first half. */
+ rtx srcmem = base_srcmem;
+ for (i = 0; i < half_moves - 1; i++)
+ {
+ emit_move_insn (tmp[i], srcmem);
+ srcmem = offset_address (srcmem,
+ GEN_INT (GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (tmp[i], srcmem);
+
+ /* Load the second half. */
+ srcmem = offset_address (base_srcmem, count_exp, 1);
+ srcmem = offset_address (srcmem,
+ GEN_INT (-GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ for (j = half_moves, i = 0; i < half_moves - 1; i++, j++)
+ {
+ emit_move_insn (tmp[j], srcmem);
+ srcmem = offset_address (srcmem,
+ GEN_INT (-GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (tmp[j], srcmem);
+
+ rtx base_destmem = change_address (dst, mode, destreg);
+
+ /* Store the first half. */
+ rtx destmem = base_destmem;
+ for (i = 0; i < half_moves - 1; i++)
+ {
+ emit_move_insn (destmem, tmp[i]);
+ destmem = offset_address (destmem,
+ GEN_INT (GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (destmem, tmp[i]);
+
+ /* Store the second half. */
+ destmem = offset_address (base_destmem, count_exp, 1);
+ destmem = offset_address (destmem, GEN_INT (-GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ for (j = half_moves, i = 0; i < half_moves - 1; i++, j++)
+ {
+ emit_move_insn (destmem, tmp[j]);
+ destmem = offset_address (destmem, GEN_INT (-GET_MODE_SIZE (mode)),
+ GET_MODE_SIZE (mode));
+ }
+ emit_move_insn (destmem, tmp[j]);
+}
+
+/* Expand memmove of size < mode size which is <= 64. */
+
+static void
+ix86_expand_less_move_movmem (rtx dst, rtx src, rtx destreg,
+ rtx srcreg, rtx count_exp,
+ unsigned HOST_WIDE_INT min_size,
+ machine_mode mode,
+ rtx_code_label *done_label)
+{
+ bool skip = false;
+ machine_mode count_mode = counter_mode (count_exp);
+
+ rtx_code_label *between_32_63_label
+ = GET_MODE_SIZE (mode) > 32 ? gen_label_rtx () : nullptr;
+ /* Jump to BETWEEN_32_64_LABEL if size >= 32 and size < 64. */
+ if (between_32_63_label)
+ {
+ if (min_size && min_size >= 32)
+ {
+ emit_jump_insn (gen_jump (between_32_63_label));
+ emit_barrier ();
+ skip = true;
+ }
+ else
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (32), GEU,
+ nullptr, count_mode, 1,
+ between_32_63_label);
+ }
+
+ rtx_code_label *between_16_31_label
+ = (!skip && GET_MODE_SIZE (mode) > 16) ? gen_label_rtx () : nullptr;
+ /* Jump to BETWEEN_16_31_LABEL if size >= 16 and size < 31. */
+ if (between_16_31_label)
+ {
+ if (min_size && min_size >= 16)
+ {
+ emit_jump_insn (gen_jump (between_16_31_label));
+ emit_barrier ();
+ skip = true;
+ }
+ else
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (16), GEU,
+ nullptr, count_mode, 1,
+ between_16_31_label);
+ }
+
+ rtx_code_label *between_8_15_label
+ = (!skip && GET_MODE_SIZE (mode) > 8) ? gen_label_rtx () : nullptr;
+ /* Jump to BETWEEN_8_15_LABEL if size >= 8 and size < 15. */
+ if (between_8_15_label)
+ {
+ if (min_size && min_size >= 8)
+ {
+ emit_jump_insn (gen_jump (between_8_15_label));
+ emit_barrier ();
+ skip = true;
+ }
+ else
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (8), GEU,
+ nullptr, count_mode, 1,
+ between_8_15_label);
+ }
+
+ rtx_code_label *between_4_7_label
+ = (!skip && GET_MODE_SIZE (mode) > 4) ? gen_label_rtx () : nullptr;
+ /* Jump to BETWEEN_4_7_LABEL if size >= 4 and size < 7. */
+ if (between_4_7_label)
+ {
+ if (min_size && min_size >= 4)
+ {
+ emit_jump_insn (gen_jump (between_4_7_label));
+ emit_barrier ();
+ skip = true;
+ }
+ else
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (4), GEU,
+ nullptr, count_mode, 1,
+ between_4_7_label);
+ }
+
+ rtx_code_label *between_2_3_label
+ = (!skip && GET_MODE_SIZE (mode) > 2) ? gen_label_rtx () : nullptr;
+ /* Jump to BETWEEN_2_3_LABEL if size >= 2 and size < 3. */
+ if (between_2_3_label)
+ {
+ if (min_size && min_size >= 2)
+ {
+ emit_jump_insn (gen_jump (between_2_3_label));
+ emit_barrier ();
+ skip = true;
+ }
+ else
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (1), GT,
+ nullptr, count_mode, 1,
+ between_2_3_label);
+ }
+
+ if (!skip)
+ {
+ rtx_code_label *zero_label
+ = min_size == 0 ? gen_label_rtx () : nullptr;
+ /* Skip if size == 0. */
+ if (zero_label)
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (1), LT,
+ nullptr, count_mode, 1,
+ zero_label,
+ profile_probability::unlikely ());
+
+ /* Move 1 byte. */
+ rtx tmp0 = gen_reg_rtx (QImode);
+ rtx srcmem = change_address (src, QImode, srcreg);
+ emit_move_insn (tmp0, srcmem);
+ rtx destmem = change_address (dst, QImode, destreg);
+ emit_move_insn (destmem, tmp0);
+
+ if (zero_label)
+ emit_label (zero_label);
+
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (between_32_63_label)
+ {
+ emit_label (between_32_63_label);
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
+ count_exp, OImode, 2);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (between_16_31_label)
+ {
+ emit_label (between_16_31_label);
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
+ count_exp, TImode, 2);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (between_8_15_label)
+ {
+ emit_label (between_8_15_label);
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
+ count_exp, DImode, 2);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (between_4_7_label)
+ {
+ emit_label (between_4_7_label);
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
+ count_exp, SImode, 2);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (between_2_3_label)
+ {
+ emit_label (between_2_3_label);
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
+ count_exp, HImode, 2);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+}
+
+/* Expand movmem with overlapping unaligned loads and stores:
+ 1. Load all sources into registers and store them together to avoid
+ possible address overlap between source and destination.
+ 2. For known size, first try to fully unroll with 8 registers.
+ 3. For size <= 2 * MOVE_MAX, load all sources into 2 registers first
+ and then store them together.
+ 4. For size > 2 * MOVE_MAX and size <= 4 * MOVE_MAX, load all sources
+ into 4 registers first and then store them together.
+ 5. For size > 4 * MOVE_MAX and size <= 8 * MOVE_MAX, load all sources
+ into 8 registers first and then store them together.
+ 6. For size > 8 * MOVE_MAX,
+ a. If address of destination > address of source, copy backward
+ with a 4 * MOVE_MAX loop with unaligned loads and stores. Load
+ the first 4 * MOVE_MAX into 4 registers before the loop and
+ store them after the loop to support overlapping addresses.
+ b. Otherwise, copy forward with a 4 * MOVE_MAX loop with unaligned
+ loads and stores. Load the last 4 * MOVE_MAX into 4 registers
+ before the loop and store them after the loop to support
+ overlapping addresses.
+ */
+
+bool
+ix86_expand_movmem (rtx operands[])
+{
+ /* Since there are much less registers available in 32-bit mode, don't
+ inline movmem in 32-bit mode. */
+ if (!TARGET_64BIT)
+ return false;
+
+ rtx dst = operands[0];
+ rtx src = operands[1];
+ rtx count_exp = operands[2];
+ rtx expected_size_exp = operands[5];
+ rtx min_size_exp = operands[6];
+ rtx probable_max_size_exp = operands[8];
+ unsigned HOST_WIDE_INT count = HOST_WIDE_INT_0U;
+ HOST_WIDE_INT expected_size = HOST_WIDE_INT_M1U;
+ unsigned HOST_WIDE_INT min_size = HOST_WIDE_INT_0U;
+ unsigned HOST_WIDE_INT probable_max_size = HOST_WIDE_INT_M1U;
+
+ if (CONST_INT_P (count_exp))
+ {
+ min_size = probable_max_size = count = expected_size
+ = INTVAL (count_exp);
+ /* When COUNT is 0, there is nothing to do. */
+ if (!count)
+ return true;
+ }
+ else
+ {
+ if (min_size_exp)
+ min_size = INTVAL (min_size_exp);
+ if (probable_max_size_exp)
+ probable_max_size = INTVAL (probable_max_size_exp);
+ if (CONST_INT_P (expected_size_exp))
+ expected_size = INTVAL (expected_size_exp);
+ }
+
+ /* Make sure we don't need to care about overflow later on. */
+ if (count > (HOST_WIDE_INT_1U << 30))
+ return false;
+
+ addr_space_t dst_as = MEM_ADDR_SPACE (dst);
+ addr_space_t src_as = MEM_ADDR_SPACE (src);
+ int dynamic_check;
+ bool noalign;
+ enum stringop_alg alg = decide_alg (count, expected_size, min_size,
+ probable_max_size, false, false,
+ dst_as, src_as, &dynamic_check,
+ &noalign, false);
+ if (alg == libcall)
+ return false;
+
+ rtx destreg = ix86_copy_addr_to_reg (XEXP (dst, 0));
+ rtx srcreg = ix86_copy_addr_to_reg (XEXP (src, 0));
+
+ unsigned int move_max = MOVE_MAX;
+ machine_mode mode = smallest_int_mode_for_size
+ (move_max * BITS_PER_UNIT).require ();
+ if (probable_max_size && probable_max_size < move_max)
+ {
+ /* Get a usable MOVE_MAX. */
+ mode = smallest_int_mode_for_size
+ (probable_max_size * BITS_PER_UNIT).require ();
+ /* Reduce MOVE_MAX by half so that MOVE_MAX can be used. */
+ if (GET_MODE_SIZE (mode) > probable_max_size)
+ mode = smallest_int_mode_for_size
+ (GET_MODE_BITSIZE (mode) / 2).require ();
+ move_max = GET_MODE_SIZE (mode);
+ }
+
+ /* Try to fully unroll memmove of known size first. */
+ if (count
+ && ix86_expand_unroll_movmem (dst, src, destreg, srcreg, count,
+ mode))
+ return true;
+
+ rtx_code_label *done_label = gen_label_rtx ();
+
+ rtx_code_label *less_vec_label = nullptr;
+ if (min_size == 0 || min_size < move_max)
+ less_vec_label = gen_label_rtx ();
+
+ machine_mode count_mode = counter_mode (count_exp);
+
+ /* Jump to LESS_VEC_LABEL if size < MOVE_MAX. */
+ if (less_vec_label)
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (move_max), LTU,
+ nullptr, count_mode, 1,
+ less_vec_label);
+
+ rtx_code_label *more_2x_vec_label = nullptr;
+ if (probable_max_size == 0 || probable_max_size > 2 * move_max)
+ more_2x_vec_label = gen_label_rtx ();
+
+ /* Jump to MORE_2X_VEC_LABEL if size > 2 * MOVE_MAX. */
+ if (more_2x_vec_label)
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (2 * move_max), GTU,
+ nullptr, count_mode, 1,
+ more_2x_vec_label);
+
+ if (min_size == 0 || min_size <= 2 * move_max)
+ {
+ /* Size >= MOVE_MAX and size <= 2 * MOVE_MAX. */
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
+ count_exp, mode, 2);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (less_vec_label)
+ {
+ /* Size < MOVE_MAX. */
+ emit_label (less_vec_label);
+ ix86_expand_less_move_movmem (dst, src, destreg, srcreg,
+ count_exp, min_size, mode,
+ done_label);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (more_2x_vec_label)
+ {
+ /* Size > 2 * MOVE_MAX and destination may overlap with source. */
+ emit_label (more_2x_vec_label);
+
+ rtx_code_label *more_8x_vec_label = nullptr;
+ if (probable_max_size == 0 || probable_max_size > 8 * move_max)
+ more_8x_vec_label = gen_label_rtx ();
+
+ /* Jump to MORE_8X_VEC_LABEL if size > 8 * MOVE_MAX. */
+ if (more_8x_vec_label)
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (8 * move_max), GTU,
+ nullptr, count_mode, 1,
+ more_8x_vec_label);
+
+ rtx_code_label *last_4x_vec_label = nullptr;
+ if (min_size == 0 || min_size < 4 * move_max)
+ last_4x_vec_label = gen_label_rtx ();
+
+ /* Jump to LAST_4X_VEC_LABEL if size < 4 * MOVE_MAX. */
+ if (last_4x_vec_label)
+ emit_cmp_and_jump_insns (count_exp, GEN_INT (4 * move_max), LTU,
+ nullptr, count_mode, 1,
+ last_4x_vec_label);
+
+ if (probable_max_size == 0 || probable_max_size > 4 * move_max)
+ {
+ /* Size > 4 * MOVE_MAX and size <= 8 * MOVE_MAX. */
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg,
+ srcreg, count_exp,
+ mode, 8);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (last_4x_vec_label)
+ {
+ /* Size > 2 * MOVE_MAX and size <= 4 * MOVE_MAX. */
+ emit_label (last_4x_vec_label);
+ ix86_expand_n_overlapping_move_movmem (dst, src, destreg,
+ srcreg, count_exp,
+ mode, 4);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+
+ if (more_8x_vec_label)
+ {
+ /* Size > 8 * MOVE_MAX. */
+ emit_label (more_8x_vec_label);
+
+ rtx loop_count = gen_reg_rtx (count_mode);
+ emit_move_insn (loop_count, count_exp);
+
+ /* Jump to MORE_8X_VEC_BACKWARD_LABEL if source address is
+ lower than destination address. */
+ rtx_code_label *more_8x_vec_backward_label = gen_label_rtx ();
+ emit_cmp_and_jump_insns (srcreg, destreg, LTU, nullptr,
+ GET_MODE (destreg), 1,
+ more_8x_vec_backward_label);
+
+ /* Skip if source == destination which is less common. */
+ emit_cmp_and_jump_insns (srcreg, destreg, EQ, nullptr,
+ GET_MODE (destreg), 1, done_label,
+ profile_probability::unlikely ());
+
+ rtx base_destreg = gen_reg_rtx (GET_MODE (destreg));
+ emit_move_insn (base_destreg, destreg);
+
+ /* Load the last 4 * MOVE_MAX. */
+ rtx regs[4];
+ ix86_expand_load_movmem (src, srcreg, count_exp, mode,
+ ARRAY_SIZE (regs), regs, true);
+
+ rtx srcmem = change_address (src, mode, srcreg);
+ rtx destmem = change_address (dst, mode, destreg);
+
+ /* Copy forward with a 4 * MOVE_MAX loop. */
+ rtx_code_label *loop_4x_vec_forward_label = gen_label_rtx ();
+ emit_label (loop_4x_vec_forward_label);
+
+ ix86_expand_n_move_movmem (destmem, srcmem, mode, 4, true);
+
+ rtx tmp;
+ rtx delta = GEN_INT (4 * MOVE_MAX);
+
+ /* Decrement LOOP_COUNT by 4 * MOVE_MAX. */
+ tmp = expand_simple_binop (GET_MODE (loop_count), MINUS,
+ loop_count, delta, nullptr, 1,
+ OPTAB_DIRECT);
+ if (tmp != loop_count)
+ emit_move_insn (loop_count, tmp);
+
+ /* Increment DESTREG and SRCREG by 4 * MOVE_MAX. */
+ tmp = expand_simple_binop (GET_MODE (destreg), PLUS,
+ destreg, delta, nullptr, 1,
+ OPTAB_DIRECT);
+ if (tmp != destreg)
+ emit_move_insn (destreg, tmp);
+ tmp = expand_simple_binop (GET_MODE (srcreg), PLUS, srcreg,
+ delta, nullptr, 1, OPTAB_DIRECT);
+ if (tmp != srcreg)
+ emit_move_insn (srcreg, tmp);
+
+ /* Stop if LOOP_EXP <= 4 * MOVE_MAX. */
+ emit_cmp_and_jump_insns (loop_count, delta, GTU, nullptr,
+ GET_MODE (loop_count), 1,
+ loop_4x_vec_forward_label);
+
+ /* Store the last 4 * MOVE_MAX. */
+ ix86_expand_store_movmem (dst, base_destreg, count_exp, mode,
+ ARRAY_SIZE (regs), regs, true);
+
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+
+ /* Copy backward with a 4 * MOVE_MAX loop. */
+ emit_label (more_8x_vec_backward_label);
+
+ base_destreg = gen_reg_rtx (GET_MODE (destreg));
+ emit_move_insn (base_destreg, destreg);
+
+ /* Load the first 4 * MOVE_MAX. */
+ ix86_expand_load_movmem (src, srcreg, count_exp, mode,
+ ARRAY_SIZE (regs), regs, false);
+
+ /* Increment DESTREG and SRCREG by COUNT_EXP. */
+ tmp = expand_simple_binop (GET_MODE (destreg), PLUS,
+ destreg, count_exp, nullptr, 1,
+ OPTAB_DIRECT);
+ if (tmp != destreg)
+ emit_move_insn (destreg, tmp);
+ tmp = expand_simple_binop (GET_MODE (srcreg), PLUS, srcreg,
+ count_exp, nullptr, 1, OPTAB_DIRECT);
+ if (tmp != srcreg)
+ emit_move_insn (srcreg, tmp);
+
+ srcmem = change_address (src, mode, srcreg);
+ destmem = change_address (dst, mode, destreg);
+ rtx step = GEN_INT (-GET_MODE_SIZE (mode));
+ srcmem = offset_address (srcmem, step, GET_MODE_SIZE (mode));
+ destmem = offset_address (destmem, step, GET_MODE_SIZE (mode));
+
+ rtx_code_label *loop_4x_vec_backward_label = gen_label_rtx ();
+ emit_label (loop_4x_vec_backward_label);
+
+ ix86_expand_n_move_movmem (destmem, srcmem, mode, 4, false);
+
+ /* Decrement LOOP_COUNT by 4 * MOVE_MAX. */
+ tmp = expand_simple_binop (GET_MODE (loop_count), MINUS,
+ loop_count, delta, nullptr, 1,
+ OPTAB_DIRECT);
+ if (tmp != loop_count)
+ emit_move_insn (loop_count, tmp);
+
+ /* Decrement DESTREG and SRCREG by 4 * MOVE_MAX. */
+ tmp = expand_simple_binop (GET_MODE (destreg), MINUS,
+ destreg, delta, nullptr, 1,
+ OPTAB_DIRECT);
+ if (tmp != destreg)
+ emit_move_insn (destreg, tmp);
+ tmp = expand_simple_binop (GET_MODE (srcreg), MINUS, srcreg,
+ delta, nullptr, 1, OPTAB_DIRECT);
+ if (tmp != srcreg)
+ emit_move_insn (srcreg, tmp);
+
+ /* Stop if LOOP_EXP <= 4 * MOVE_MAX. */
+ emit_cmp_and_jump_insns (loop_count, delta, GTU, nullptr,
+ GET_MODE (loop_count), 1,
+ loop_4x_vec_backward_label);
+
+ /* Store the first 4 * MOVE_MAX. */
+ ix86_expand_store_movmem (dst, base_destreg, count_exp, mode,
+ ARRAY_SIZE (regs), regs, false);
+
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+ }
+ }
+
+ emit_label (done_label);
+
+ return true;
+}
+
/* Expand cmpstrn or memcmp. */
bool
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index bdb8bb9..5ff414a 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -78,6 +78,7 @@ extern void substitute_vpternlog_operands (rtx[]);
extern bool ix86_expand_strlen (rtx, rtx, rtx, rtx);
extern bool ix86_expand_set_or_cpymem (rtx, rtx, rtx, rtx, rtx, rtx,
rtx, rtx, rtx, rtx, bool);
+extern bool ix86_expand_movmem (rtx[]);
extern bool ix86_expand_cmpstrn_or_cmpmem (rtx, rtx, rtx, rtx, rtx, bool);
extern enum reg_class ix86_insn_base_reg_class (rtx_insn *);
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 587b2bd..6b6febc 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -598,6 +598,20 @@ ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
}
}
+ /* SUB (a, b) underflows precisely when a < b. Convert
+ (compare (minus (a b)) a) to (compare (a b))
+ to match *sub<mode>_3 pattern. */
+ if (!op0_preserve_value
+ && (*code == GTU || *code == LEU)
+ && GET_CODE (*op0) == MINUS
+ && rtx_equal_p (XEXP (*op0, 0), *op1))
+ {
+ *op1 = XEXP (*op0, 1);
+ *op0 = XEXP (*op0, 0);
+ *code = (int) swap_condition ((enum rtx_code) *code);
+ return;
+ }
+
/* Swap operands of GTU comparison to canonicalize
addcarry/subborrow comparison. */
if (!op0_preserve_value
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index b812d8b..4a2232e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12213,7 +12213,7 @@
(compare:CCNO
(and:SWI48
(match_operand:SWI48 0 "nonimmediate_operand")
- (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
+ (match_operand:SWI48 1 "<general_szext_operand>"))
(const_int 0)))])
(define_expand "testqi_ccz_1"
@@ -12221,7 +12221,7 @@
(compare:CCZ
(and:QI
(match_operand:QI 0 "nonimmediate_operand")
- (match_operand:QI 1 "nonmemory_operand"))
+ (match_operand:QI 1 "general_operand"))
(const_int 0)))])
(define_insn "*testdi_1"
@@ -12229,7 +12229,7 @@
(compare
(and:DI
(match_operand:DI 0 "nonimmediate_operand" "%r,rm")
- (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
+ (match_operand:DI 1 "x86_64_szext_general_operand" "Z,re"))
(const_int 0)))]
"TARGET_64BIT
&& ix86_match_ccmode
@@ -12242,7 +12242,8 @@
(satisfies_constraint_Z (operands[1])
&& (!CONST_INT_P (operands[1])
|| val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
- ? CCZmode : CCNOmode)"
+ ? CCZmode : CCNOmode)
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"@
test{l}\t{%k1, %k0|%k0, %k1}
test{q}\t{%1, %0|%0, %1}"
@@ -12253,12 +12254,13 @@
[(set (reg FLAGS_REG)
(compare
(and:QI
- (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
- (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
+ (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
+ (match_operand:QI 1 "general_operand" "q,n,n,n"))
(const_int 0)))]
"ix86_match_ccmode (insn,
CONST_INT_P (operands[1])
- && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
+ && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
if (get_attr_mode (insn) == MODE_SI)
{
@@ -12270,7 +12272,7 @@
}
[(set_attr "type" "test")
(set (attr "mode")
- (cond [(eq_attr "alternative" "2")
+ (cond [(eq_attr "alternative" "3")
(const_string "SI")
(and (match_test "optimize_insn_for_size_p ()")
(and (match_operand 0 "ext_QIreg_operand")
@@ -12278,16 +12280,17 @@
(const_string "SI")
]
(const_string "QI")))
- (set_attr "pent_pair" "uv,np,np")])
+ (set_attr "pent_pair" "uv,uv,np,np")])
(define_insn "*test<mode>_1"
[(set (reg FLAGS_REG)
(compare
(and:SWI124
(match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
- (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
- (const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)"
+ (match_operand:SWI124 1 "<general_operand>" "<r>,<i>,<i>"))
+ (const_int 0)))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"test{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "test")
(set_attr "mode" "<MODE>")
@@ -25708,6 +25711,23 @@
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
+(define_expand "movmem<mode>"
+ [(use (match_operand:BLK 0 "memory_operand"))
+ (use (match_operand:BLK 1 "memory_operand"))
+ (use (match_operand:SWI48 2 "nonmemory_operand"))
+ (use (match_operand:SWI48 3 "const_int_operand"))
+ (use (match_operand:SI 4 "const_int_operand"))
+ (use (match_operand:SI 5 "const_int_operand"))
+ (use (match_operand:SI 6 ""))
+ (use (match_operand:SI 7 ""))
+ (use (match_operand:SI 8 ""))]
+ ""
+{
+ if (ix86_expand_movmem (operands))
+ DONE;
+ FAIL;
+})
+
(define_expand "cpymem<mode>"
[(use (match_operand:BLK 0 "memory_operand"))
(use (match_operand:BLK 1 "memory_operand"))
diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 7a91473..71dd25d0 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -130,6 +130,7 @@
;; Only used for splitting insert_d and copy_{u,s}.d.
(define_mode_iterator LASX_WD [V4DI V4DF V8SI V8SF])
+(define_mode_iterator LASX_PART [V4DI V4DF V8SF])
;; Only used for copy256_{u,s}.w.
(define_mode_iterator LASX_W [V8SI V8SF])
@@ -514,7 +515,7 @@
(set_attr "mode" "<MODE>")])
;; xvpermi.q
-(define_insn "lasx_xvpermi_q_<LASX:mode>"
+(define_insn_and_split "lasx_xvpermi_q_<LASX:mode>"
[(set (match_operand:LASX 0 "register_operand" "=f")
(unspec:LASX
[(match_operand:LASX 1 "register_operand" "0")
@@ -525,6 +526,37 @@
{
return "xvpermi.q\t%u0,%u2,%3";
}
+ "&& ((INTVAL (operands[3]) & 0xee) == 0x0
+ || (INTVAL (operands[3]) & 0xee) == 0x22)"
+ [(const_int 0)]
+{
+ HOST_WIDE_INT selector = INTVAL (operands[3]);
+ /* Reduce the dependency caused by using output operands[0] as input. */
+ switch (INTVAL (operands[3]))
+ {
+ case 0x22:
+ case 0x23:
+ case 0x33:
+ selector -= 0x22;
+ operands[2] = operands[1];
+ /* FALLTHRU. */
+ case 0x0:
+ case 0x1:
+ case 0x11:
+ emit_insn (gen_lasx_xvpermi_d_<mode> (operands[0], operands[2],
+ GEN_INT (selector * 0xa + 0x44)));
+ break;
+ case 0x10:
+ emit_move_insn (operands[0], operands[2]);
+ break;
+ case 0x32:
+ emit_move_insn (operands[0], operands[1]);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ DONE;
+}
[(set_attr "type" "simd_splat")
(set_attr "mode" "<MODE>")])
@@ -672,6 +704,41 @@
[(set_attr "move_type" "fmove")
(set_attr "mode" "<MODE>")])
+;; vr0 -> low xr0
+;;
+(define_insn "vec_cast<mode>"
+ [(set (match_operand:LASX_PART 0 "register_operand" "=f")
+ (subreg:LASX_PART
+ (match_operand:<VHMODE256_ALL> 1 "register_operand" "0") 0))]
+ "ISA_HAS_LASX"
+ ""
+ [(set_attr "type" "simd_splat")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "vec_insert_lo_<mode>"
+ [(set (match_operand:LASX_PART 0 "register_operand" "=f")
+ (vec_concat:LASX_PART
+ (match_operand:<VHMODE256_ALL> 2 "register_operand" "f")
+ (vec_select:<VHMODE256_ALL>
+ (match_operand:LASX_PART 1 "register_operand" "0")
+ (match_operand:LASX_PART 3 "vect_par_cnst_high_half"))))]
+ "ISA_HAS_LASX"
+ "xvpermi.q\t%u0,%u2,0x30"
+ [(set_attr "type" "simd_splat")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "vec_insert_hi_<mode>"
+ [(set (match_operand:LASX_PART 0 "register_operand" "=f")
+ (vec_concat:LASX_PART
+ (vec_select:<VHMODE256_ALL>
+ (match_operand:LASX_PART 1 "register_operand" "0")
+ (match_operand:LASX_PART 3 "vect_par_cnst_low_half"))
+ (match_operand:<VHMODE256_ALL> 2 "register_operand" "f")))]
+ "ISA_HAS_LASX"
+ "xvpermi.q\t%u0,%u2,0x02"
+ [(set_attr "type" "simd_splat")
+ (set_attr "mode" "<MODE>")])
+
(define_expand "vec_perm<mode>"
[(match_operand:LASX 0 "register_operand")
(match_operand:LASX 1 "register_operand")
diff --git a/gcc/config/loongarch/lasxintrin.h b/gcc/config/loongarch/lasxintrin.h
index 6bcffc2..6c34ede 100644
--- a/gcc/config/loongarch/lasxintrin.h
+++ b/gcc/config/loongarch/lasxintrin.h
@@ -23,6 +23,8 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
+#include <lsxintrin.h>
+
#ifndef _GCC_LOONGSON_ASXINTRIN_H
#define _GCC_LOONGSON_ASXINTRIN_H 1
@@ -5368,5 +5370,159 @@ __m256i __lasx_xvfcmp_sun_s (__m256 _1, __m256 _2)
#define __lasx_xvrepli_w(/*si10*/ _1) \
((__m256i)__builtin_lasx_xvrepli_w ((_1)))
+#if defined (__loongarch_asx_sx_conv)
+/* Add builtin interfaces for 128 and 256 vector conversions.
+ For the assembly instruction format of some functions of the following vector
+ conversion, it is not described exactly in accordance with the format of the
+ generated assembly instruction.
+ In the front end of the Rust language, different built-in functions are called
+ by analyzing the format of assembly instructions. The data types of instructions
+ are all defined based on the interfaces of the defined functions, in the
+ following order: output, input... . */
+/* Assembly instruction format: xd, vj. */
+/* Data types in instruction templates: V8SF, V4SF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256 __lasx_cast_128_s (__m128 _1)
+{
+ return (__m256)__builtin_lasx_cast_128_s ((v4f32)_1);
+}
+
+/* Assembly instruction format: xd, vj. */
+/* Data types in instruction templates: V4DF, V2DF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256d __lasx_cast_128_d (__m128d _1)
+{
+ return (__m256d)__builtin_lasx_cast_128_d ((v2f64)_1);
+}
+
+/* Assembly instruction format: xd, vj. */
+/* Data types in instruction templates: V4DI, V2DI. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256i __lasx_cast_128 (__m128i _1)
+{
+ return (__m256i)__builtin_lasx_cast_128 ((v2i64)_1);
+}
+
+/* Assembly instruction format: xd, vj, vk. */
+/* Data types in instruction templates: V8SF, V4SF, V4SF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256 __lasx_concat_128_s (__m128 _1, __m128 _2)
+{
+ return (__m256)__builtin_lasx_concat_128_s ((v4f32)_1, (v4f32)_2);
+}
+
+/* Assembly instruction format: xd, vj, vk. */
+/* Data types in instruction templates: V4DF, V2DF, V2DF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256d __lasx_concat_128_d (__m128d _1, __m128d _2)
+{
+ return (__m256d)__builtin_lasx_concat_128_d ((v2f64)_1, (v2f64)_2);
+}
+
+/* Assembly instruction format: xd, vj, vk. */
+/* Data types in instruction templates: V4DI, V2DI, V2DI. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256i __lasx_concat_128 (__m128i _1, __m128i _2)
+{
+ return (__m256i)__builtin_lasx_concat_128 ((v2i64)_1, (v2i64)_2);
+}
+
+/* Assembly instruction format: vd, xj. */
+/* Data types in instruction templates: V4SF, V8SF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m128 __lasx_extract_128_lo_s (__m256 _1)
+{
+ return (__m128)__builtin_lasx_extract_128_lo_s ((v8f32)_1);
+}
+
+/* Assembly instruction format: vd, xj. */
+/* Data types in instruction templates: V4SF, V8SF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m128 __lasx_extract_128_hi_s (__m256 _1)
+{
+ return (__m128)__builtin_lasx_extract_128_hi_s ((v8f32)_1);
+}
+
+/* Assembly instruction format: vd, xj. */
+/* Data types in instruction templates: V2DF, V4DF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m128d __lasx_extract_128_lo_d (__m256d _1)
+{
+ return (__m128d)__builtin_lasx_extract_128_lo_d ((v4f64)_1);
+}
+
+/* Assembly instruction format: vd, xj. */
+/* Data types in instruction templates: V2DF, V4DF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m128d __lasx_extract_128_hi_d (__m256d _1)
+{
+ return (__m128d)__builtin_lasx_extract_128_hi_d ((v4f64)_1);
+}
+
+/* Assembly instruction format: vd, xj. */
+/* Data types in instruction templates: V2DI, V4DI. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m128i __lasx_extract_128_lo (__m256i _1)
+{
+ return (__m128i)__builtin_lasx_extract_128_lo ((v4i64)_1);
+}
+
+/* Assembly instruction format: vd, xj. */
+/* Data types in instruction templates: V2DI, V4DI. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m128i __lasx_extract_128_hi (__m256i _1)
+{
+ return (__m128i)__builtin_lasx_extract_128_hi ((v4i64)_1);
+}
+
+/* Assembly instruction format: xd, xj, vk. */
+/* Data types in instruction templates: V8SF, V8SF, V4SF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256 __lasx_insert_128_lo_s (__m256 _1, __m128 _2)
+{
+ return (__m256)__builtin_lasx_insert_128_lo_s ((v8f32)_1, (v4f32)_2);
+}
+
+/* Assembly instruction format: xd, xj, vk. */
+/* Data types in instruction templates: V8SF, V8SF, V4SF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256 __lasx_insert_128_hi_s (__m256 _1, __m128 _2)
+{
+ return (__m256)__builtin_lasx_insert_128_hi_s ((v8f32)_1, (v4f32)_2);
+}
+
+/* Assembly instruction format: xd, xj, vk. */
+/* Data types in instruction templates: V4DF, V4DF, V2DF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256d __lasx_insert_128_lo_d (__m256d _1, __m128d _2)
+{
+ return (__m256d)__builtin_lasx_insert_128_lo_d ((v4f64)_1, (v2f64)_2);
+}
+
+/* Assembly instruction format: xd, xj, vk. */
+/* Data types in instruction templates: V4DF, V4DF, V2DF. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256d __lasx_insert_128_hi_d (__m256d _1, __m128d _2)
+{
+ return (__m256d)__builtin_lasx_insert_128_hi_d ((v4f64)_1, (v2f64)_2);
+}
+
+/* Assembly instruction format: xd, xj, vk. */
+/* Data types in instruction templates: V4DI, V4DI, V2DI. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256i __lasx_insert_128_lo (__m256i _1, __m128i _2)
+{
+ return (__m256i)__builtin_lasx_insert_128_lo ((v4i64)_1, (v2i64)_2);
+}
+
+/* Assembly instruction format: xd, xj, vk. */
+/* Data types in instruction templates: V4DI, V4DI, V2DI. */
+extern __inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__m256i __lasx_insert_128_hi (__m256i _1, __m128i _2)
+{
+ return (__m256i)__builtin_lasx_insert_128_hi ((v4i64)_1, (v2i64)_2);
+}
+
+#endif /* defined(__loongarch_asx_sx_conv). */
#endif /* defined(__loongarch_asx). */
#endif /* _GCC_LOONGSON_ASXINTRIN_H. */
diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc
index 9493ded..312d876 100644
--- a/gcc/config/loongarch/loongarch-builtins.cc
+++ b/gcc/config/loongarch/loongarch-builtins.cc
@@ -865,6 +865,27 @@ AVAIL_ALL (lasx_frecipe, ISA_HAS_LASX && ISA_HAS_FRECIPE)
#define CODE_FOR_lasx_xvmaddwod_q_du CODE_FOR_lasx_maddwod_q_du_punned
#define CODE_FOR_lasx_xvmaddwod_q_du_d CODE_FOR_lasx_maddwod_q_du_d_punned
+
+/* Add mutual conversion between 128 and 256 vectors. */
+#define CODE_FOR_lasx_extract_128_lo_s CODE_FOR_vec_extract_lo_v8sf
+#define CODE_FOR_lasx_extract_128_hi_s CODE_FOR_vec_extract_hi_v8sf
+#define CODE_FOR_lasx_extract_128_lo_d CODE_FOR_vec_extract_lo_v4df
+#define CODE_FOR_lasx_extract_128_hi_d CODE_FOR_vec_extract_hi_v4df
+#define CODE_FOR_lasx_extract_128_lo CODE_FOR_vec_extract_lo_v4di
+#define CODE_FOR_lasx_extract_128_hi CODE_FOR_vec_extract_hi_v4di
+#define CODE_FOR_lasx_insert_128_lo_s CODE_FOR_vec_insert_lo_v8sf
+#define CODE_FOR_lasx_insert_128_hi_s CODE_FOR_vec_insert_hi_v8sf
+#define CODE_FOR_lasx_insert_128_lo_d CODE_FOR_vec_insert_lo_v4df
+#define CODE_FOR_lasx_insert_128_hi_d CODE_FOR_vec_insert_hi_v4df
+#define CODE_FOR_lasx_insert_128_lo CODE_FOR_vec_insert_lo_v4di
+#define CODE_FOR_lasx_insert_128_hi CODE_FOR_vec_insert_hi_v4di
+#define CODE_FOR_lasx_concat_128_s CODE_FOR_vec_concatv8sf
+#define CODE_FOR_lasx_concat_128_d CODE_FOR_vec_concatv4df
+#define CODE_FOR_lasx_concat_128 CODE_FOR_vec_concatv4di
+#define CODE_FOR_lasx_cast_128_s CODE_FOR_vec_castv8sf
+#define CODE_FOR_lasx_cast_128_d CODE_FOR_vec_castv4df
+#define CODE_FOR_lasx_cast_128 CODE_FOR_vec_castv4di
+
static const struct loongarch_builtin_description loongarch_builtins[] = {
#define LARCH_MOVFCSR2GR 0
DIRECT_BUILTIN (movfcsr2gr, LARCH_USI_FTYPE_UQI, hard_float),
@@ -2407,7 +2428,25 @@ static const struct loongarch_builtin_description loongarch_builtins[] = {
LASX_BUILTIN (xvssrarni_bu_h, LARCH_UV32QI_FTYPE_UV32QI_V32QI_USI),
LASX_BUILTIN (xvssrarni_hu_w, LARCH_UV16HI_FTYPE_UV16HI_V16HI_USI),
LASX_BUILTIN (xvssrarni_wu_d, LARCH_UV8SI_FTYPE_UV8SI_V8SI_USI),
- LASX_BUILTIN (xvssrarni_du_q, LARCH_UV4DI_FTYPE_UV4DI_V4DI_USI)
+ LASX_BUILTIN (xvssrarni_du_q, LARCH_UV4DI_FTYPE_UV4DI_V4DI_USI),
+ LASX_BUILTIN (extract_128_lo_s, LARCH_V4SF_FTYPE_V8SF),
+ LASX_BUILTIN (extract_128_hi_s, LARCH_V4SF_FTYPE_V8SF),
+ LASX_BUILTIN (extract_128_lo_d, LARCH_V2DF_FTYPE_V4DF),
+ LASX_BUILTIN (extract_128_hi_d, LARCH_V2DF_FTYPE_V4DF),
+ LASX_BUILTIN (extract_128_lo, LARCH_V2DI_FTYPE_V4DI),
+ LASX_BUILTIN (extract_128_hi, LARCH_V2DI_FTYPE_V4DI),
+ LASX_BUILTIN (insert_128_lo_s, LARCH_V8SF_FTYPE_V8SF_V4SF),
+ LASX_BUILTIN (insert_128_hi_s, LARCH_V8SF_FTYPE_V8SF_V4SF),
+ LASX_BUILTIN (insert_128_lo_d, LARCH_V4DF_FTYPE_V4DF_V2DF),
+ LASX_BUILTIN (insert_128_hi_d, LARCH_V4DF_FTYPE_V4DF_V2DF),
+ LASX_BUILTIN (insert_128_lo, LARCH_V4DI_FTYPE_V4DI_V2DI),
+ LASX_BUILTIN (insert_128_hi, LARCH_V4DI_FTYPE_V4DI_V2DI),
+ LASX_BUILTIN (concat_128_s, LARCH_V8SF_FTYPE_V4SF_V4SF),
+ LASX_BUILTIN (concat_128_d, LARCH_V4DF_FTYPE_V2DF_V2DF),
+ LASX_BUILTIN (concat_128, LARCH_V4DI_FTYPE_V2DI_V2DI),
+ LASX_BUILTIN (cast_128_s, LARCH_V8SF_FTYPE_V4SF),
+ LASX_BUILTIN (cast_128_d, LARCH_V4DF_FTYPE_V2DF),
+ LASX_BUILTIN (cast_128, LARCH_V4DI_FTYPE_V2DI)
};
/* Index I is the function declaration for loongarch_builtins[I], or null if
@@ -3001,6 +3040,10 @@ loongarch_expand_builtin_direct (enum insn_code icode, rtx target, tree exp,
{
struct expand_operand ops[MAX_RECOG_OPERANDS];
int opno, argno;
+ /* For vector extraction/insertion operations, sel_high_p being true
+ indicates that the high of the data is selected/retained from the
+ vector register. */
+ bool sel_high_p = true;
/* Map any target to operand 0. */
opno = 0;
@@ -3019,6 +3062,51 @@ loongarch_expand_builtin_direct (enum insn_code icode, rtx target, tree exp,
create_input_operand (&ops[1], CONST1_RTX (ops[0].mode), ops[0].mode);
return loongarch_expand_builtin_insn (icode, 3, ops, has_target_p);
+ case CODE_FOR_vec_extract_lo_v8sf:
+ case CODE_FOR_vec_extract_lo_v4df:
+ case CODE_FOR_vec_extract_lo_v4di:
+ sel_high_p = false;
+ /* Fall through. */
+ case CODE_FOR_vec_extract_hi_v8sf:
+ case CODE_FOR_vec_extract_hi_v4df:
+ case CODE_FOR_vec_extract_hi_v4di:
+ {
+ /* The selection method for constructing the high/low half. */
+ loongarch_prepare_builtin_arg (&ops[1], exp, 0);
+ int nelts = GET_MODE_NUNITS (GET_MODE (ops[1].value));
+ int half_nelts = nelts / 2;
+ int base = sel_high_p ? half_nelts : 0;
+
+ rtx pat_rtx
+ = loongarch_gen_stepped_int_parallel (half_nelts, base, 1);
+ create_input_operand (&ops[2], pat_rtx, ops[1].mode);
+
+ return loongarch_expand_builtin_insn (icode, 3, ops, has_target_p);
+ }
+
+ case CODE_FOR_vec_insert_hi_v8sf:
+ case CODE_FOR_vec_insert_hi_v4df:
+ case CODE_FOR_vec_insert_hi_v4di:
+ sel_high_p = false;
+ /* Fall through. */
+ case CODE_FOR_vec_insert_lo_v8sf:
+ case CODE_FOR_vec_insert_lo_v4df:
+ case CODE_FOR_vec_insert_lo_v4di:
+ {
+ /* The selection method for constructing the high/low half. */
+ loongarch_prepare_builtin_arg (&ops[1], exp, 0);
+ loongarch_prepare_builtin_arg (&ops[2], exp, 1);
+ int nelts = GET_MODE_NUNITS (GET_MODE (ops[1].value));
+ int half_nelts = nelts / 2;
+ int base = sel_high_p ? half_nelts : 0;
+
+ rtx pat_rtx
+ = loongarch_gen_stepped_int_parallel (half_nelts, base, 1);
+ create_input_operand (&ops[3], pat_rtx, ops[1].mode);
+
+ return loongarch_expand_builtin_insn (icode, 4, ops, has_target_p);
+ }
+
default:
break;
}
diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc
index effdcf0..fc031a6 100644
--- a/gcc/config/loongarch/loongarch-c.cc
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -132,6 +132,7 @@ loongarch_update_cpp_builtins (cpp_reader *pfile)
loongarch_def_or_undef (ISA_HAS_LSX, "__loongarch_simd", pfile);
loongarch_def_or_undef (ISA_HAS_LSX, "__loongarch_sx", pfile);
loongarch_def_or_undef (ISA_HAS_LASX, "__loongarch_asx", pfile);
+ loongarch_def_or_undef (ISA_HAS_LASX, "__loongarch_asx_sx_conv", pfile);
builtin_undef ("__loongarch_simd_width");
if (ISA_HAS_LSX)
diff --git a/gcc/config/loongarch/loongarch-ftypes.def b/gcc/config/loongarch/loongarch-ftypes.def
index 337f2c2..68b1b44 100644
--- a/gcc/config/loongarch/loongarch-ftypes.def
+++ b/gcc/config/loongarch/loongarch-ftypes.def
@@ -42,6 +42,12 @@ DEF_LARCH_FTYPE (1, (USI, USI))
DEF_LARCH_FTYPE (1, (UDI, USI))
DEF_LARCH_FTYPE (1, (USI, UQI))
DEF_LARCH_FTYPE (1, (VOID, USI))
+DEF_LARCH_FTYPE (1, (V4SF, V8SF))
+DEF_LARCH_FTYPE (1, (V2DF, V4DF))
+DEF_LARCH_FTYPE (1, (V2DI, V4DI))
+DEF_LARCH_FTYPE (1, (V8SF, V4SF))
+DEF_LARCH_FTYPE (1, (V4DF, V2DF))
+DEF_LARCH_FTYPE (1, (V4DI, V2DI))
DEF_LARCH_FTYPE (2, (VOID, UQI, USI))
DEF_LARCH_FTYPE (2, (VOID, UHI, USI))
@@ -58,6 +64,12 @@ DEF_LARCH_FTYPE (2, (SI, SI, SI))
DEF_LARCH_FTYPE (2, (SI, DI, SI))
DEF_LARCH_FTYPE (2, (USI, USI, USI))
DEF_LARCH_FTYPE (2, (UDI, UDI, USI))
+DEF_LARCH_FTYPE (2, (V8SF, V4SF, V4SF))
+DEF_LARCH_FTYPE (2, (V4DF, V2DF, V2DF))
+DEF_LARCH_FTYPE (2, (V4DI, V2DI, V2DI))
+DEF_LARCH_FTYPE (2, (V8SF, V8SF, V4SF))
+DEF_LARCH_FTYPE (2, (V4DF, V4DF, V2DF))
+DEF_LARCH_FTYPE (2, (V4DI, V4DI, V2DI))
DEF_LARCH_FTYPE (3, (VOID, USI, USI, SI))
DEF_LARCH_FTYPE (3, (VOID, USI, UDI, SI))
diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h
index bec4368..e00dd89 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -159,6 +159,7 @@ extern bool loongarch_use_ins_ext_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
extern bool loongarch_check_zero_div_p (void);
extern bool loongarch_pre_reload_split (void);
extern int loongarch_use_bstrins_for_ior_with_mask (machine_mode, rtx *);
+extern bool loongarch_use_bstrins_bstrpick_for_and (rtx, machine_mode);
extern rtx loongarch_rewrite_mem_for_simple_ldst (rtx);
union loongarch_gen_fn_ptrs
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index f7ce3aa..d11fe49 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -3439,13 +3439,8 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
x = GEN_INT (codes[0].value);
for (i = 1; i < num_ops; i++)
{
- if (!can_create_pseudo_p ())
- {
- emit_insn (gen_rtx_SET (temp, x));
- x = temp;
- }
- else
- x = force_reg (mode, x);
+ emit_insn (gen_rtx_SET (temp, x));
+ x = temp;
set_unique_reg_note (get_last_insn (), REG_EQUAL,
GEN_INT (codes[i-1].curr_value));
@@ -3803,6 +3798,34 @@ loongarch_use_bstrins_for_ior_with_mask_1 (machine_mode mode,
return 0;
}
+/* Check if it is possible to optimize AND operation with an immediate:
+ a. immediate is loaded by more than 1 instruction
+ b. can use bstrpick.d + bstrins.d. */
+
+bool
+loongarch_use_bstrins_bstrpick_for_and (rtx op, machine_mode mode)
+{
+ if (!TARGET_64BIT)
+ return false;
+
+ /* Avoid aggressive optimization of combine before reload. */
+ if (!reload_completed)
+ return false;
+
+ /* It's meaningless if the OP is not splittable
+ and skip the cases already supported in AND operation. */
+ if (!splittable_const_int_operand (op, mode) || and_operand (op, mode))
+ return false;
+
+ int leading_zero_bit = __builtin_clzll (UINTVAL (op));
+ unsigned HOST_WIDE_INT mask = (~0ULL) << (64 - leading_zero_bit);
+
+ if (ins_zero_bitmask_operand (GEN_INT (UINTVAL (op) | mask), mode))
+ return true;
+
+ return false;
+}
+
/* Return the cost of moving between two registers of mode MODE. */
static int
@@ -3922,14 +3945,24 @@ loongarch_rtx_costs (rtx x, machine_mode mode, int outer_code,
return false;
case AND:
- /* Check for a *clear_upper32 pattern and treat it like a zero
- extension. See the pattern's comment for details. */
- if (TARGET_64BIT && mode == DImode && CONST_INT_P (XEXP (x, 1))
- && UINTVAL (XEXP (x, 1)) == 0xffffffff)
+ if (TARGET_64BIT && mode == DImode && CONST_INT_P (XEXP (x, 1)))
{
- *total = (loongarch_zero_extend_cost (XEXP (x, 0))
- + set_src_cost (XEXP (x, 0), mode, speed));
- return true;
+ /* Check for a *clear_upper32 pattern and treat it like a zero
+ extension. See the pattern's comment for details. */
+ if (UINTVAL (XEXP (x, 1)) == 0xffffffff)
+ {
+ *total = (loongarch_zero_extend_cost (XEXP (x, 0))
+ + set_src_cost (XEXP (x, 0), mode, speed));
+ return true;
+ }
+ /* Check if it can be done by bstrpick.d and bstrins.d. */
+ else if (loongarch_use_bstrins_bstrpick_for_and (XEXP (x, 1), mode))
+ {
+ /* The pattern will be split into 2 insns. */
+ *total = (COSTS_N_INSNS (2)
+ + set_src_cost (XEXP (x, 0), mode, speed));
+ return true;
+ }
}
/* (AND (NOT op0) (NOT op1) is a nor operation that can be done in
a single instruction. */
@@ -3983,9 +4016,34 @@ loongarch_rtx_costs (rtx x, machine_mode mode, int outer_code,
speed);
return true;
+ case LSHIFTRT:
+ /* Correct the cost of mulh.{w[u]/d[u]}. */
+ if (outer_code == TRUNCATE && CONST_INT_P (XEXP (x, 1))
+ && INTVAL (XEXP (x, 1)) == (GET_MODE_BITSIZE (mode) / 2)
+ && GET_CODE (XEXP (x, 0)) == MULT
+ && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == ZERO_EXTEND)
+ || (GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == SIGN_EXTEND))
+ && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == REG)
+ {
+ if (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SImode
+ && GET_MODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == SImode)
+ {
+ *total = loongarch_cost->int_mult_si;
+ return true;
+ }
+ if (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == DImode
+ && GET_MODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == DImode)
+ {
+ *total = loongarch_cost->int_mult_di;
+ return true;
+ }
+ }
+ /* Fall through. */
case ASHIFT:
case ASHIFTRT:
- case LSHIFTRT:
case ROTATE:
case ROTATERT:
if (CONSTANT_P (XEXP (x, 1)))
@@ -4234,7 +4292,8 @@ loongarch_rtx_costs (rtx x, machine_mode mode, int outer_code,
machine_mode
loongarch_split_reduction (machine_mode mode)
{
- if (LSX_SUPPORTED_MODE_P (mode))
+ if (!VECTOR_MODE_P (mode)
+ || LSX_SUPPORTED_MODE_P (mode))
return mode;
return mode_for_vector (as_a <scalar_mode> (GET_MODE_INNER (mode)),
@@ -7087,6 +7146,10 @@ static bool
loongarch_can_change_mode_class (machine_mode from, machine_mode to,
reg_class_t rclass)
{
+ if ((INTEGRAL_MODE_P (from) && FLOAT_MODE_P (to))
+ || (INTEGRAL_MODE_P (to) && FLOAT_MODE_P (from)))
+ return true;
+
/* Allow conversions between different LSX/LASX vector modes. */
if (LASX_SUPPORTED_MODE_P (from) && LASX_SUPPORTED_MODE_P (to))
return true;
@@ -7133,7 +7196,11 @@ loongarch_modes_tieable_p (machine_mode mode1, machine_mode mode2)
prefer to put one of them in FPRs. */
return (mode1 == mode2
|| (!loongarch_mode_ok_for_mov_fmt_p (mode1)
- && !loongarch_mode_ok_for_mov_fmt_p (mode2)));
+ && !loongarch_mode_ok_for_mov_fmt_p (mode2))
+ || (GET_MODE_CLASS(mode1) == MODE_FLOAT
+ && GET_MODE_CLASS(mode2) == MODE_INT)
+ || (GET_MODE_CLASS(mode2) == MODE_FLOAT
+ && GET_MODE_CLASS(mode1) == MODE_INT));
}
/* Implement TARGET_PREFERRED_RELOAD_CLASS. */
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 625f30c..2f4817d 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -1636,6 +1636,21 @@
operands[3] = tmp;
})
+(define_insn "and_load_zero_extend<mode>"
+ [(set (match_operand:X 0 "register_operand" "=r,r,r,r,r,r")
+ (and:X (match_operand:X 1 "memory_operand" "%m,m,m,k,k,k")
+ (match_operand:X 2 "mask_operand" "Yb,Yh,Yw,Yb,Yh,Yw")))]
+ ""
+ "@
+ ld.bu\t%0,%1
+ ld.hu\t%0,%1
+ ld.wu\t%0,%1
+ ldx.bu\t%0,%1
+ ldx.hu\t%0,%1
+ ldx.wu\t%0,%1"
+ [(set_attr "move_type" "load,load,load,load,load,load")
+ (set_attr "mode" "<MODE>")])
+
;; We always avoid the shift operation in bstrins_<mode>_for_ior_mask
;; if possible, but the result may be sub-optimal when one of the masks
;; is (1 << N) - 1 and one of the src register is the dest register.
@@ -1670,6 +1685,24 @@
DONE;
})
+(define_insn_and_split "bstrins_bstrpick_for_and_imm<mode>"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (and:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "const_int_operand" "i")))]
+ "loongarch_use_bstrins_bstrpick_for_and (operands[2], <MODE>mode)"
+ "#"
+ "&& true"
+ [(const_int 0)]
+{
+ unsigned HOST_WIDE_INT op2 = INTVAL (operands[2]);
+ int leading_zero_bit = __builtin_clzll (op2);
+ unsigned HOST_WIDE_INT mask = (~0ULL) << (64 - leading_zero_bit);
+ emit_insn (gen_extzv<mode> (operands[0], operands[1],
+ GEN_INT (64 - leading_zero_bit), const0_rtx));
+ emit_insn (gen_and<mode>3 (operands[0], operands[0], GEN_INT (op2 | mask)));
+}
+ [(set_attr "length" "8")])
+
(define_insn "*iorhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(ior:HI (match_operand:HI 1 "register_operand" "%r,r")
@@ -2306,8 +2339,8 @@
})
(define_insn_and_split "*movsi_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,w,*f,f,*r,*m")
- (match_operand:SI 1 "move_operand" "r,Yd,w,rJ,*r*J,m,*f,*f"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,w,f,f,r,*m")
+ (match_operand:SI 1 "move_operand" "r,Yd,w,rJ,rJ,m,f,*f"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
{ return loongarch_output_move (operands); }
diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md
index 34cf74d..8460618 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -413,6 +413,11 @@
(match_operand 0 "low_bitmask_operand")
(match_operand 0 "ins_zero_bitmask_operand")))
+(define_predicate "mask_operand"
+ (ior (match_operand 0 "qi_mask_operand")
+ (match_operand 0 "hi_mask_operand")
+ (match_operand 0 "si_mask_operand")))
+
(define_predicate "const_call_insn_operand"
(match_code "const,symbol_ref,label_ref")
{
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 697198f..166ddd9 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -357,7 +357,7 @@
{
if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
FAIL;
- if (TARGET_64BIT && register_operand (operands[2], QImode))
+ if (TARGET_64BIT)
{
rtx t = gen_reg_rtx (DImode);
emit_insn (gen_rotrsi3_sext (t, operands[1], operands[2]));
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index cdb706a..570acb1 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -209,6 +209,11 @@ rtl_opt_pass * make_pass_insert_landing_pad (gcc::context *ctxt);
rtl_opt_pass * make_pass_vector_permconst (gcc::context *ctxt);
rtl_opt_pass * make_pass_bclr_lowest_set_bit (gcc::context *ctxt);
+/* Routines implemented in riscv-vsetvl.cc. */
+extern bool has_vtype_op (rtx_insn *);
+extern bool mask_agnostic_p (rtx_insn *);
+extern rtx get_avl (rtx_insn *);
+extern bool vsetvl_insn_p (rtx_insn *);
/* Routines implemented in riscv-string.c. */
extern bool riscv_expand_block_compare (rtx, rtx, rtx, rtx);
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 3586d0c..580ac9c 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -258,7 +258,7 @@ policy_to_str (bool agnostic_p)
/* Return true if it is an RVV instruction depends on VTYPE global
status register. */
-static bool
+bool
has_vtype_op (rtx_insn *rinsn)
{
return recog_memoized (rinsn) >= 0 && get_attr_has_vtype_op (rinsn);
@@ -306,7 +306,7 @@ vector_config_insn_p (rtx_insn *rinsn)
}
/* Return true if it is vsetvldi or vsetvlsi. */
-static bool
+bool
vsetvl_insn_p (rtx_insn *rinsn)
{
if (!rinsn || !vector_config_insn_p (rinsn))
@@ -386,7 +386,7 @@ get_vl (rtx_insn *rinsn)
}
/* Helper function to get AVL operand. */
-static rtx
+rtx
get_avl (rtx_insn *rinsn)
{
if (vsetvl_insn_p (rinsn) || vsetvl_discard_result_insn_p (rinsn))
@@ -411,7 +411,7 @@ get_default_ma ()
}
/* Helper function to get MA operand. */
-static bool
+bool
mask_agnostic_p (rtx_insn *rinsn)
{
/* If it doesn't have MA, we return agnostic by default. */
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 63404d3..e186c6a 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5886,11 +5886,47 @@ static int
riscv_flatten_aggregate_field (const_tree type, riscv_aggregate_field *fields,
int n, HOST_WIDE_INT offset,
bool ignore_zero_width_bit_field_p,
+ bool ignore_empty_union_and_zero_len_array_p,
bool vls_p = false, unsigned abi_vlen = 0)
{
int max_aggregate_field = vls_p ? 8 : 2;
switch (TREE_CODE (type))
{
+ case UNION_TYPE:
+ {
+ if (!ignore_empty_union_and_zero_len_array_p)
+ return -1;
+ /* Empty union should ignore. */
+ if (TYPE_SIZE (type) == NULL || integer_zerop (TYPE_SIZE (type)))
+ return n;
+ /* Or all union member are empty union or empty struct. */
+ for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
+ {
+ if (TREE_CODE (f) != FIELD_DECL)
+ continue;
+ int m;
+ HOST_WIDE_INT pos = offset + int_byte_position (f);
+ switch (TREE_CODE (TREE_TYPE (f)))
+ {
+ case ARRAY_TYPE:
+ case UNION_TYPE:
+ case RECORD_TYPE:
+ m = riscv_flatten_aggregate_field (
+ TREE_TYPE (f), fields, n, pos,
+ ignore_zero_width_bit_field_p,
+ true);
+ /* Any non-empty struct/union/array will stop the flatten. */
+ if (m != n)
+ return -1;
+ break;
+ default:
+ /* Any member are not struct, union or array will stop the
+ flatten. */
+ return -1;
+ }
+ }
+ return n;
+ }
case RECORD_TYPE:
/* Can't handle incomplete types nor sizes that are not fixed. */
if (!COMPLETE_TYPE_P (type)
@@ -5916,7 +5952,9 @@ riscv_flatten_aggregate_field (const_tree type, riscv_aggregate_field *fields,
{
HOST_WIDE_INT pos = offset + int_byte_position (f);
n = riscv_flatten_aggregate_field (
- TREE_TYPE (f), fields, n, pos, ignore_zero_width_bit_field_p,
+ TREE_TYPE (f), fields, n, pos,
+ ignore_zero_width_bit_field_p,
+ ignore_empty_union_and_zero_len_array_p,
vls_p, abi_vlen);
}
if (n < 0)
@@ -5930,14 +5968,20 @@ riscv_flatten_aggregate_field (const_tree type, riscv_aggregate_field *fields,
riscv_aggregate_field subfields[8];
tree index = TYPE_DOMAIN (type);
tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
+
+ /* Array with zero size member should be ignored. */
+ if (ignore_empty_union_and_zero_len_array_p && integer_zerop (elt_size))
+ return n;
+
int n_subfields
- = riscv_flatten_aggregate_field (TREE_TYPE (type), subfields, 0,
- offset,
- ignore_zero_width_bit_field_p, vls_p,
- abi_vlen);
+ = riscv_flatten_aggregate_field (
+ TREE_TYPE (type), subfields, 0,
+ offset,
+ ignore_zero_width_bit_field_p,
+ ignore_empty_union_and_zero_len_array_p,
+ vls_p, abi_vlen);
/* Can't handle incomplete types nor sizes that are not fixed. */
- if (n_subfields <= 0
- || !COMPLETE_TYPE_P (type)
+ if (!COMPLETE_TYPE_P (type)
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
|| !index
|| !TYPE_MAX_VALUE (index)
@@ -5947,6 +5991,15 @@ riscv_flatten_aggregate_field (const_tree type, riscv_aggregate_field *fields,
|| !tree_fits_uhwi_p (elt_size))
return -1;
+ /* Zero-length array with empty union/struct should be ignored. */
+ if (ignore_empty_union_and_zero_len_array_p && n_subfields == 0
+ && integer_zerop (TYPE_MIN_VALUE (index))
+ && integer_all_onesp (TYPE_MAX_VALUE (index)))
+ return n;
+
+ if (n_subfields <= 0)
+ return -1;
+
n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
- tree_to_uhwi (TYPE_MIN_VALUE (index));
gcc_assert (n_elts >= 0);
@@ -6026,14 +6079,25 @@ static int
riscv_flatten_aggregate_argument (const_tree type,
riscv_aggregate_field *fields,
bool ignore_zero_width_bit_field_p,
+ bool ignore_empty_union_and_zero_len_array_p,
bool vls_p = false, unsigned abi_vlen = 0)
{
if (!type || TREE_CODE (type) != RECORD_TYPE)
return -1;
return riscv_flatten_aggregate_field (type, fields, 0, 0,
- ignore_zero_width_bit_field_p, vls_p,
- abi_vlen);
+ ignore_zero_width_bit_field_p,
+ ignore_empty_union_and_zero_len_array_p,
+ vls_p, abi_vlen);
+}
+
+static bool
+riscv_any_non_float_type_field (riscv_aggregate_field *fields, int n)
+{
+ for (int i = 0; i < n; i++)
+ if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
+ return true;
+ return false;
}
/* See whether TYPE is a record whose fields should be returned in one or
@@ -6044,24 +6108,18 @@ riscv_pass_aggregate_in_fpr_pair_p (const_tree type,
riscv_aggregate_field fields[2])
{
static int warned = 0;
+ if (!type)
+ return 0;
/* This is the old ABI, which differs for C++ and C. */
- int n_old = riscv_flatten_aggregate_argument (type, fields, false);
- for (int i = 0; i < n_old; i++)
- if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
- {
- n_old = -1;
- break;
- }
+ int n_old = riscv_flatten_aggregate_argument (type, fields, false, false);
+ if (riscv_any_non_float_type_field (fields, n_old))
+ n_old = -1;
/* This is the new ABI, which is the same for C++ and C. */
- int n_new = riscv_flatten_aggregate_argument (type, fields, true);
- for (int i = 0; i < n_new; i++)
- if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
- {
- n_new = -1;
- break;
- }
+ int n_new = riscv_flatten_aggregate_argument (type, fields, true, false);
+ if (riscv_any_non_float_type_field (fields, n_new))
+ n_new = -1;
if ((n_old != n_new) && (warned == 0))
{
@@ -6070,7 +6128,58 @@ riscv_pass_aggregate_in_fpr_pair_p (const_tree type,
warned = 1;
}
- return n_new > 0 ? n_new : 0;
+ /* ABI with fixing flatten empty union. */
+ int n_new2 = riscv_flatten_aggregate_argument (type, fields, true, true);
+ if (riscv_any_non_float_type_field (fields, n_new2))
+ n_new2 = -1;
+
+ bool num_fpr = riscv_pass_mode_in_fpr_p (TYPE_MODE (type));
+
+ /* There is a special case for struct with zero length array with struct and a
+ floating point member.
+ e.g:
+ struct S0ae_1f {
+ struct {
+ } e1[0];
+ float f;
+ };
+
+ This case we will got 1, but legacy ABI will got -1, however legacy ABI
+ will got 1 in later logic, so we should consider this case as compatible.
+ */
+ bool compatible_p = n_new2 == 1 && n_new == -1 && num_fpr == 1;
+
+ if ((n_new2 != n_new)
+ && !compatible_p && (warned == 0))
+ {
+ warning (OPT_Wpsabi, "ABI for flattened empty union and zero "
+ "length array changed in GCC 16");
+ warned = 1;
+ }
+
+ return n_new2 > 0 ? n_new2 : 0;
+}
+
+struct riscv_aggregate_field_info_t {
+ unsigned num_fpr;
+ unsigned num_gpr;
+
+ riscv_aggregate_field_info_t ()
+ : num_fpr (0), num_gpr (0)
+ {}
+};
+
+static riscv_aggregate_field_info_t
+riscv_parse_aggregate_field_info (riscv_aggregate_field *fields, int n)
+{
+ riscv_aggregate_field_info_t info;
+ for (int i = 0; i < n; i++)
+ {
+ info.num_fpr += SCALAR_FLOAT_TYPE_P (fields[i].type);
+ info.num_gpr += INTEGRAL_TYPE_P (fields[i].type);
+ }
+
+ return info;
}
/* See whether TYPE is a record whose fields should be returned in one or
@@ -6084,35 +6193,48 @@ riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type,
static int warned = 0;
/* This is the old ABI, which differs for C++ and C. */
- unsigned num_int_old = 0, num_float_old = 0;
- int n_old = riscv_flatten_aggregate_argument (type, fields, false);
- for (int i = 0; i < n_old; i++)
- {
- num_float_old += SCALAR_FLOAT_TYPE_P (fields[i].type);
- num_int_old += INTEGRAL_TYPE_P (fields[i].type);
- }
+ int n_old = riscv_flatten_aggregate_argument (type, fields, false, false);
+ riscv_aggregate_field_info_t old_info;
+ old_info = riscv_parse_aggregate_field_info (fields, n_old);
/* This is the new ABI, which is the same for C++ and C. */
- unsigned num_int_new = 0, num_float_new = 0;
- int n_new = riscv_flatten_aggregate_argument (type, fields, true);
- for (int i = 0; i < n_new; i++)
- {
- num_float_new += SCALAR_FLOAT_TYPE_P (fields[i].type);
- num_int_new += INTEGRAL_TYPE_P (fields[i].type);
- }
+ int n_new = riscv_flatten_aggregate_argument (type, fields, true, false);
+ riscv_aggregate_field_info_t new_info;
+ new_info = riscv_parse_aggregate_field_info (fields, n_new);
+
+ bool values_changed = old_info.num_fpr != new_info.num_fpr
+ || old_info.num_gpr != new_info.num_gpr;
+ bool old_is_one_one = old_info.num_fpr == 1 && old_info.num_gpr == 1;
+ bool new_is_one_one = new_info.num_fpr == 1 && new_info.num_gpr == 1;
- if (((num_int_old == 1 && num_float_old == 1
- && (num_int_old != num_int_new || num_float_old != num_float_new))
- || (num_int_new == 1 && num_float_new == 1
- && (num_int_old != num_int_new || num_float_old != num_float_new)))
- && (warned == 0))
+ if (values_changed
+ && (old_is_one_one || new_is_one_one)
+ && warned == 0)
{
warning (OPT_Wpsabi, "ABI for flattened struct with zero-length "
"bit-fields changed in GCC 10");
warned = 1;
}
- return num_int_new == 1 && num_float_new == 1;
+ /* ABI with fixing flatten empty union. */
+ int n_new2 = riscv_flatten_aggregate_argument (type, fields, true, true);
+ riscv_aggregate_field_info_t new2_info;
+ new2_info = riscv_parse_aggregate_field_info (fields, n_new2);
+
+ values_changed = new_info.num_fpr != new2_info.num_fpr
+ || new_info.num_gpr != new2_info.num_gpr;
+ bool new2_is_one_one = new2_info.num_fpr == 1 && new2_info.num_gpr == 1;
+
+ if (values_changed
+ && (new_is_one_one || new2_is_one_one)
+ && warned == 0)
+ {
+ warning (OPT_Wpsabi, "ABI for flattened empty union and zero "
+ "length array changed in GCC 16");
+ warned = 1;
+ }
+
+ return new2_is_one_one;
}
/* Return the representation of an argument passed or returned in an FPR
@@ -6466,7 +6588,7 @@ riscv_pass_aggregate_in_vr (struct riscv_arg_info *info,
riscv_aggregate_field fields[8];
unsigned int abi_vlen = riscv_get_cc_abi_vlen (cum->variant_cc);
int i;
- int n = riscv_flatten_aggregate_argument (type, fields, true,
+ int n = riscv_flatten_aggregate_argument (type, fields, true, true,
/* vls_p */ true, abi_vlen);
if (n == -1)
@@ -10576,6 +10698,71 @@ riscv_issue_rate (void)
return tune_param->issue_rate;
}
+/* Structure for very basic vector configuration tracking in the scheduler. */
+struct last_vconfig
+{
+ bool valid;
+ bool ta;
+ bool ma;
+ uint8_t sew;
+ uint8_t vlmul;
+ rtx avl;
+} last_vconfig;
+
+/* Clear LAST_VCONFIG so we have no known state. */
+static void
+clear_vconfig (void)
+{
+ memset (&last_vconfig, 0, sizeof (last_vconfig));
+}
+
+/* Return TRUE if INSN is a vector insn needing a particular
+ vector configuration that is trivially equal to the last
+ vector insn issued. Return FALSE otherwise. */
+static bool
+compatible_with_last_vconfig (rtx_insn *insn)
+{
+ /* We might be able to extract the data from a preexisting vsetvl. */
+ if (vsetvl_insn_p (insn))
+ return false;
+
+ /* Nothing to do for these cases. */
+ if (!NONDEBUG_INSN_P (insn) || !has_vtype_op (insn))
+ return false;
+
+ extract_insn_cached (insn);
+
+ rtx avl = get_avl (insn);
+ if (avl != last_vconfig.avl)
+ return false;
+
+ if (get_sew (insn) != last_vconfig.sew)
+ return false;
+
+ if (get_vlmul (insn) != last_vconfig.vlmul)
+ return false;
+
+ if (tail_agnostic_p (insn) != last_vconfig.ta)
+ return false;
+
+ if (mask_agnostic_p (insn) != last_vconfig.ma)
+ return false;
+
+ /* No differences found, they're trivially compatible. */
+ return true;
+}
+
+/* Implement TARGET_SCHED_INIT, we use this to track the vector configuration
+ of the last issued vector instruction. We can then use that information
+ to potentially adjust the ready queue to issue instructions of a compatible
+ vector configuration instead of a conflicting configuration. That will
+ reduce the number of vsetvl instructions we ultimately emit. */
+static void
+riscv_sched_init (FILE *, int, int)
+{
+ clear_vconfig ();
+}
+
/* Implement TARGET_SCHED_VARIABLE_ISSUE. */
static int
riscv_sched_variable_issue (FILE *, int, rtx_insn *insn, int more)
@@ -10600,9 +10787,88 @@ riscv_sched_variable_issue (FILE *, int, rtx_insn *insn, int more)
an assert so we can find and fix this problem. */
gcc_assert (insn_has_dfa_reservation_p (insn));
+ /* If this is a vector insn with vl/vtype info, then record the last
+ vector configuration. */
+ if (vsetvl_insn_p (insn))
+ clear_vconfig ();
+ else if (NONDEBUG_INSN_P (insn) && has_vtype_op (insn))
+ {
+ extract_insn_cached (insn);
+
+ rtx avl = get_avl (insn);
+ if (avl == RVV_VLMAX)
+ avl = const0_rtx;
+
+ if (!avl || !CONST_INT_P (avl))
+ clear_vconfig ();
+ else
+ {
+ last_vconfig.valid = true;
+ last_vconfig.avl = avl;
+ last_vconfig.sew = get_sew (insn);
+ last_vconfig.vlmul = get_vlmul (insn);
+ last_vconfig.ta = tail_agnostic_p (insn);
+ last_vconfig.ma = mask_agnostic_p (insn);
+ }
+ }
+
return more - 1;
}
+/* Implement TARGET_SCHED_REORDER. The goal here is to look at the ready
+ queue and reorder it ever so slightly to encourage issing an insn with
+ the same vector configuration as the most recently issued vector
+ instruction. That will reduce vsetvl instructions. */
+static int
+riscv_sched_reorder (FILE *, int, rtx_insn **ready, int *nreadyp, int)
+{
+ /* If we don't have a valid prior vector configuration, then there is
+ no point in reordering the ready queue, similarly if there is
+ just one entry in the queue. */
+ if (!last_vconfig.valid || *nreadyp == 1)
+ return riscv_issue_rate ();
+
+ return riscv_issue_rate ();
+ int nready = *nreadyp;
+ int priority = INSN_PRIORITY (ready[nready - 1]);
+ for (int i = nready - 1; i >= 0; i--)
+ {
+ rtx_insn *insn = ready[i];
+
+ /* On a high performance core, vsetvl instructions should be
+ inexpensive. Removing them is very much a secondary concern, so
+ be extremely conservative with reordering, essentially only
+ allowing reordering within the highest priority value.
+
+ Lower end cores may benefit from more flexibility here. That
+ tuning is left to those who understand their core's behavior
+ and can thoroughly benchmark the result. Assuming such
+ designs appear, we can probably put an entry in the tuning
+ structure to indicate how much difference in priority to allow. */
+ if (INSN_PRIORITY (insn) < priority)
+ break;
+
+ if (compatible_with_last_vconfig (insn))
+ {
+ /* This entry is compatible with the last vconfig and has
+ the same priority as the most important insn. So swap
+ it so that we keep the vector configuration as-is and
+ ultimately eliminate a vsetvl.
+
+ Note no need to swap if this is the first entry in the
+ queue. */
+ if (i == nready - 1)
+ break;
+
+ std::swap (ready[i], ready[nready - 1]);
+ break;
+ }
+ }
+
+ return riscv_issue_rate ();
+}
+
+
/* Implement TARGET_SCHED_MACRO_FUSION_P. Return true if target supports
instruction fusion of some sort. */
@@ -16011,9 +16277,15 @@ riscv_prefetch_offset_address_p (rtx x, machine_mode mode)
#undef TARGET_SCHED_MACRO_FUSION_PAIR_P
#define TARGET_SCHED_MACRO_FUSION_PAIR_P riscv_macro_fusion_pair_p
+#undef TARGET_SCHED_INIT
+#define TARGET_SCHED_INIT riscv_sched_init
+
#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE riscv_sched_variable_issue
+#undef TARGET_SCHED_REORDER
+#define TARGET_SCHED_REORDER riscv_sched_reorder
+
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST riscv_sched_adjust_cost
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 20e82e6..42171a5 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -34,7 +34,7 @@
(define_insn "*th_srri<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=r")
(rotatert:GPR (match_operand:GPR 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "n")))]
+ (match_operand 2 "const_int_operand" "n")))]
"TARGET_XTHEADBB && (TARGET_64BIT || <MODE>mode == SImode)"
{
bool wform = TARGET_64BIT && (<MODE>mode == SImode);
@@ -45,6 +45,22 @@
[(set_attr "type" "bitmanip")
(set_attr "mode" "<GPR:MODE>")])
+;; Version with explicit sign extension to facilitate sign extension
+;; removal.
+(define_insn "*th_srrisi3_extended"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (rotatert:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand" "n"))))]
+ "TARGET_XTHEADBB && TARGET_64BIT"
+ {
+ operands[2] = GEN_INT (INTVAL (operands[2])
+ & (GET_MODE_BITSIZE (SImode) - 1));
+ return "th.srriw\t%0,%1,%2";
+ }
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "SI")])
+
(define_insn "*th_ext<mode>4"
[(set (match_operand:GPR 0 "register_operand" "=r")
(sign_extract:GPR (match_operand:GPR 1 "register_operand" "r")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 3cb87bf..9d34725 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -1437,6 +1437,8 @@
[(set_attr "type" "vlde,vste,vmov")
(set_attr "mode" "<MODE>")
(set (attr "merge_op_idx") (const_int INVALID_ATTRIBUTE))
+ (set (attr "has_vl_op") (const_string "false"))
+ (set (attr "has_vtype_op") (const_string "false"))
(set (attr "avl_type_idx") (const_int INVALID_ATTRIBUTE))
(set (attr "mode_idx") (const_int INVALID_ATTRIBUTE))]
)
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 4ba7f54..1e88a60 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -43,6 +43,7 @@
UNSPEC_FRAME_BLOCKAGE
UNSPEC_CEIL
UNSPEC_FLOOR
+ UNSPEC_ROUND
])
(define_c_enum "unspecv" [
@@ -102,10 +103,12 @@
(define_code_attr m_float [(float "float") (unsigned_float "ufloat")])
(define_code_attr s_float [(float "") (unsigned_float "uns")])
-;; This iterator and attribute allow FP-to-integer rounding of two types
+;; This iterator and attribute allow FP-to-integer rounding of three types
;; to be generated from one template.
-(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR])
-(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")])
+(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR
+ (UNSPEC_ROUND "flag_unsafe_math_optimizations")])
+(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")
+ (UNSPEC_ROUND "round")])
;; Attributes.
@@ -691,13 +694,15 @@
})
(define_insn "negsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (match_operand:SF 1 "register_operand" "f")))]
+ [(set (match_operand:SF 0 "register_operand")
+ (neg:SF (match_operand:SF 1 "register_operand")))
+ (clobber (match_scratch:SI 2))]
"TARGET_HARD_FLOAT"
- "neg.s\t%0, %1"
- [(set_attr "type" "farith")
- (set_attr "mode" "SF")
- (set_attr "length" "3")])
+ {@ [cons: =0, 1, =2; attrs: type, length]
+ [D, D, &a; arith , 7] movi.n\t%2, 1\;slli\t%2, %2, 31\;add.n\t%0, %1, %2
+ [f, f, X; farith, 3] neg.s\t%0, %1
+ }
+ [(set_attr "mode" "SF")])
;; Logical instructions.
@@ -1139,7 +1144,7 @@
(define_insn "*fix<s_fix>_truncsfsi2_scaled"
[(set (match_operand:SI 0 "register_operand" "=a")
(any_fix:SI (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "fix_scaling_operand" "F"))))]
+ (match_operand:SF 2 "fix_scaling_operand" ""))))]
"TARGET_HARD_FLOAT"
"<m_fix>.s\t%0, %1, %U2"
[(set_attr "type" "fconv")
@@ -1158,7 +1163,7 @@
(define_insn "*float<s_float>sisf2_scaled"
[(set (match_operand:SF 0 "register_operand" "=f")
(mult:SF (any_float:SF (match_operand:SI 1 "register_operand" "a"))
- (match_operand:SF 2 "float_scaling_operand" "F")))]
+ (match_operand:SF 2 "float_scaling_operand" "")))]
"TARGET_HARD_FLOAT"
"<m_float>.s\t%0, %1, %V2"
[(set_attr "type" "fconv")
@@ -1187,7 +1192,7 @@
(define_insn "*l<m_round>sfsi2_scaled"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "fix_scaling_operand" "F"))] ANY_ROUND))]
+ (match_operand:SF 2 "fix_scaling_operand" ""))] ANY_ROUND))]
"TARGET_HARD_FLOAT"
"<m_round>.s\t%0, %1, %U2"
[(set_attr "type" "fconv")
diff --git a/gcc/configure b/gcc/configure
index 962511f..611f691 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -16498,15 +16498,7 @@ rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $clang_cv_is_clang" >&5
$as_echo "$clang_cv_is_clang" >&6; }
- plugin_file=
- if test $clang_cv_is_clang = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang plugin file" >&5
-$as_echo_n "checking for clang plugin file... " >&6; }
- plugin_names="LLVMgold.so"
- for plugin in $plugin_names; do
- plugin_file=`${CC} ${CFLAGS} --print-file-name $plugin`
- if test x$plugin_file = x$plugin; then
- if test -n "$ac_tool_prefix"; then
+ if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}llvm-config", so it can be a program name with args.
set dummy ${ac_tool_prefix}llvm-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -16598,22 +16590,31 @@ else
LLVM_CONFIG="$ac_cv_prog_LLVM_CONFIG"
fi
- if test "$?" != 0; then
- as_fn_error $? "Required tool 'llvm-config' not found on PATH." "$LINENO" 5
- fi
- clang_lib_dir=`$LLVM_CONFIG --libdir`
- if test -f $clang_lib_dir/$plugin; then
- plugin_file=$clang_lib_dir/$plugin
- fi
- if test x$plugin_file != x$plugin; then
+ plugin_file=
+ if test $clang_cv_is_clang = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang plugin file" >&5
+$as_echo_n "checking for clang plugin file... " >&6; }
+ plugin_names="LLVMgold.so"
+ for plugin in $plugin_names; do
+ plugin_file=`${CC} ${CFLAGS} --print-file-name $plugin`
+ if test "$plugin_file" != "$plugin"; then
+ break;
+ fi
+ if test -n "${LLVM_CONFIG}"; then
+ plugin_file=`${LLVM_CONFIG} --libdir`/$plugin
+ if test -f "$plugin_file"; then
break;
fi
fi
+ plugin_file=
done
- if test -z $plugin_file; then
- as_fn_error $? "Couldn't find clang plugin file for $CC." "$LINENO" 5
- fi
- if test -n "$ac_tool_prefix"; then
+ if test -z "$plugin_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_file" >&5
+$as_echo "$plugin_file" >&6; }
+ if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -16705,42 +16706,26 @@ else
AR="$ac_cv_prog_AR"
fi
- if test "${AR}" = "" ; then
- as_fn_error $? "Required archive tool 'ar' not found on PATH." "$LINENO" 5
- fi
- plugin_option="--plugin $plugin_file"
- touch conftest.c
- ${AR} $plugin_option rc conftest.a conftest.c
- if test "$?" != 0; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5
+ if test -z "${AR}"; then
+ as_fn_error $? "Required archive tool 'ar' not found on PATH." "$LINENO" 5
+ fi
+ plugin_option="--plugin $plugin_file"
+ touch conftest.c
+ ${AR} $plugin_option rc conftest.a conftest.c
+ if test "$?" != 0; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5
$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;}
- plugin_file=
+ plugin_file=
+ fi
+ rm -f conftest.*
fi
- rm -f conftest.*
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_file" >&5
-$as_echo "$plugin_file" >&6; }
fi
plugin_file="$plugin_file"
if test -n "$plugin_file"; then
plugin_option="--plugin $plugin_file"
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -plugin option" >&5
-$as_echo_n "checking for -plugin option... " >&6; }
-
-plugin_names="liblto_plugin.so liblto_plugin-0.dll cyglto_plugin-0.dll"
-plugin_option=
-for plugin in $plugin_names; do
- plugin_so=`${CC} ${CFLAGS} --print-prog-name $plugin`
- if test x$plugin_so = x$plugin; then
- plugin_so=`${CC} ${CFLAGS} --print-file-name $plugin`
- fi
- if test x$plugin_so != x$plugin; then
- plugin_option="--plugin $plugin_so"
- break
- fi
-done
-if test -n "$ac_tool_prefix"; then
+ if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -16832,25 +16817,39 @@ else
AR="$ac_cv_prog_AR"
fi
-if test "${AR}" = "" ; then
+if test -z "${AR}"; then
as_fn_error $? "Required archive tool 'ar' not found on PATH." "$LINENO" 5
fi
-touch conftest.c
-${AR} $plugin_option rc conftest.a conftest.c
-if test "$?" != 0; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5
-$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;}
- plugin_option=
-fi
-rm -f conftest.*
-if test -n "$plugin_option"; then
- plugin_option="$plugin_option"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_option" >&5
-$as_echo "$plugin_option" >&6; }
-else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -plugin option" >&5
+$as_echo_n "checking for -plugin option... " >&6; }
+plugin_names="liblto_plugin.so liblto_plugin-0.dll cyglto_plugin-0.dll"
+plugin_option=
+for plugin in $plugin_names; do
+ plugin_so=`${CC} ${CFLAGS} --print-prog-name $plugin`
+ if test x$plugin_so = x$plugin; then
+ plugin_so=`${CC} ${CFLAGS} --print-file-name $plugin`
+ fi
+ if test x$plugin_so != x$plugin; then
+ plugin_option="--plugin $plugin_so"
+ break
+ fi
+done
+if test -z "$plugin_option"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_option" >&5
+$as_echo "$plugin_option" >&6; }
+ touch conftest.c
+ ${AR} $plugin_option rc conftest.a conftest.c
+ if test "$?" != 0; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5
+$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;}
+ plugin_option=
+ fi
+ rm -f conftest.*
fi
+plugin_option="$plugin_option"
fi
if test -n "$ac_tool_prefix"; then
@@ -21873,7 +21872,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 21876 "configure"
+#line 21875 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -21979,7 +21978,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 21982 "configure"
+#line 21981 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 73c2a03..9a8c394 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,37 @@
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * name-lookup.cc (name_lookup::adl_class_fns): Include all
+ namespace-scope friends.
+
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * name-lookup.cc (pushdecl): Discard built-in sooner.
+
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * module.cc (trees_in::decl_value): Don't add an instantiation to
+ CLASSTYPE_MEMBER_VEC.
+
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * module.cc (module_state::write_namespaces): Handle
+ TREE_DEPRECATED.
+ (module_state::read_namespaces): Likewise.
+
+2025-11-02 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/122421
+ * module.cc (trees_in::read_var_def): Don't handle class-scope
+ variables anymore.
+ (trees_in::read_class_def): Handle them here instead.
+
+2025-11-01 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/122381
+ * module.cc (trees_out::core_vals): Write BASELINK_OPTYPE (aka
+ TREE_CHAIN).
+ (trees_in::core_vals): Read it.
+
2025-10-30 Jakub Jelinek <jakub@redhat.com>
* std-name-hint.gperf: Remove duplicate entries for ispanstream
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 0073f83..9e135af 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2885,7 +2885,12 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data)
break;
}
addressable:
- if (! TREE_PUBLIC (t))
+ if (decl_linkage (t) == lk_none)
+ tpvis = type_visibility (TREE_TYPE (t));
+ /* Decls that have had their visibility constrained will report
+ as external linkage, but we still want to transitively constrain
+ if we refer to them, so just check TREE_PUBLIC instead. */
+ else if (!TREE_PUBLIC (t))
tpvis = VISIBILITY_ANON;
else
tpvis = DECL_VISIBILITY (t);
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 81357a8..e9cacf1 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6733,6 +6733,7 @@ trees_out::core_vals (tree t)
WT (((lang_tree_node *)t)->baselink.binfo);
WT (((lang_tree_node *)t)->baselink.functions);
WT (((lang_tree_node *)t)->baselink.access_binfo);
+ WT (((lang_tree_node *)t)->baselink.common.chain);
break;
case CONSTRAINT_INFO:
@@ -7302,6 +7303,7 @@ trees_in::core_vals (tree t)
RT (((lang_tree_node *)t)->baselink.binfo);
RTU (((lang_tree_node *)t)->baselink.functions);
RT (((lang_tree_node *)t)->baselink.access_binfo);
+ RT (((lang_tree_node *)t)->baselink.common.chain);
break;
case CONSTRAINT_INFO:
@@ -8994,11 +8996,14 @@ trees_in::decl_value ()
dump (dumper::TREE) && dump ("CDTOR %N is %scloned",
decl, cloned_p ? "" : "not ");
if (cloned_p)
- build_cdtor_clones (decl, flags & 2, flags & 4,
- /* Update the member vec, if there is
- one (we're in a different cluster
- to the class defn). */
- CLASSTYPE_MEMBER_VEC (DECL_CONTEXT (decl)));
+ {
+ /* Update the member vec, if there is one (we're in a different
+ cluster to the class defn) and this isn't a primary template
+ specialization (as in tsubst_function_decl). */
+ bool up = (CLASSTYPE_MEMBER_VEC (DECL_CONTEXT (decl))
+ && !primary_template_specialization_p (decl));
+ build_cdtor_clones (decl, flags & 2, flags & 4, up);
+ }
}
}
@@ -13046,12 +13051,11 @@ trees_in::read_var_def (tree decl, tree maybe_template)
if (DECL_EXPLICIT_INSTANTIATION (decl)
&& !DECL_EXTERNAL (decl))
setup_explicit_instantiation_definition_linkage (decl);
- if (DECL_IMPLICIT_INSTANTIATION (decl)
- || (DECL_EXPLICIT_INSTANTIATION (decl)
- && !DECL_EXTERNAL (decl))
- || (DECL_CLASS_SCOPE_P (decl)
- && !DECL_VTABLE_OR_VTT_P (decl)
- && !DECL_TEMPLATE_INFO (decl)))
+ /* Class static data members are handled in read_class_def. */
+ if (!DECL_CLASS_SCOPE_P (decl)
+ && (DECL_IMPLICIT_INSTANTIATION (decl)
+ || (DECL_EXPLICIT_INSTANTIATION (decl)
+ && !DECL_EXTERNAL (decl))))
note_vague_linkage_variable (decl);
}
if (!dyn_init)
@@ -13465,6 +13469,10 @@ trees_in::read_class_def (tree defn, tree maybe_template)
DECL_ACCESS (d) = tree_cons (type, access, list);
}
}
+
+ if (TREE_CODE (decl) == VAR_DECL
+ && TREE_CODE (maybe_template) != TEMPLATE_DECL)
+ note_vague_linkage_variable (decl);
}
}
@@ -17241,13 +17249,16 @@ module_state::write_namespaces (elf_out *to, vec<depset *> spaces,
flags |= 4;
if (DECL_MODULE_EXPORT_P (ns))
flags |= 8;
+ if (TREE_DEPRECATED (ns))
+ flags |= 16;
dump () && dump ("Writing namespace:%u %N%s%s%s%s",
b->cluster, ns,
flags & 1 ? ", public" : "",
flags & 2 ? ", inline" : "",
flags & 4 ? ", purview" : "",
- flags & 8 ? ", export" : "");
+ flags & 8 ? ", export" : "",
+ flags & 16 ? ", deprecated" : "");
sec.u (b->cluster);
sec.u (to->name (DECL_NAME (ns)));
write_namespace (sec, b->deps[0]);
@@ -17323,7 +17334,8 @@ module_state::read_namespaces (unsigned num)
flags & 1 ? ", public" : "",
flags & 2 ? ", inline" : "",
flags & 4 ? ", purview" : "",
- flags & 8 ? ", export" : "");
+ flags & 8 ? ", export" : "",
+ flags & 16 ? ", deprecated" : "");
bool visible_p = ((flags & 8)
|| ((flags & 1)
&& (flags & 4)
@@ -17344,6 +17356,9 @@ module_state::read_namespaces (unsigned num)
DECL_MODULE_EXPORT_P (inner) = true;
}
+ if (flags & 16)
+ TREE_DEPRECATED (inner) = true;
+
if (tags)
DECL_ATTRIBUTES (inner)
= tree_cons (get_identifier ("abi_tag"), tags, DECL_ATTRIBUTES (inner));
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index b753061..ef13604 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -1372,11 +1372,14 @@ name_lookup::adl_class_fns (tree type)
{
tree fn = TREE_VALUE (friends);
- /* Only interested in global functions with potentially hidden
- (i.e. unqualified) declarations. */
+ /* Before C++20, ADL just makes hidden friends visible, so we
+ only include functions in the same namespace. After C++20,
+ include all namespace-scope functions. */
if (!context)
context = decl_namespace_context (type);
- if (CP_DECL_CONTEXT (fn) != context)
+ if (cxx_dialect < cxx20
+ ? CP_DECL_CONTEXT (fn) != context
+ : !DECL_NAMESPACE_SCOPE_P (fn))
continue;
dedup (true);
@@ -4063,6 +4066,11 @@ pushdecl (tree decl, bool hiding)
}
}
+ /* Skip a hidden builtin we failed to match already. There can
+ only be one. */
+ if (old && anticipated_builtin_p (old))
+ old = OVL_CHAIN (old);
+
/* Check for redeclaring an import. */
if (slot && *slot && TREE_CODE (*slot) == BINDING_VECTOR)
if (tree match
@@ -4081,11 +4089,6 @@ pushdecl (tree decl, bool hiding)
/* We are pushing a new decl. */
- /* Skip a hidden builtin we failed to match already. There can
- only be one. */
- if (old && anticipated_builtin_p (old))
- old = OVL_CHAIN (old);
-
if (hiding)
; /* Hidden bindings don't shadow anything. */
else
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 5836122..f642900 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -83,7 +83,7 @@ enum non_integral_constant {
NIC_FUNC_CALL,
/* an increment */
NIC_INC,
- /* an decrement */
+ /* a decrement */
NIC_DEC,
/* an array reference */
NIC_ARRAY_REF,
@@ -3782,7 +3782,7 @@ cp_parser_non_integral_constant_expression (cp_parser *parser,
"cannot appear in a constant-expression");
return true;
case NIC_DEC:
- error ("an decrement "
+ error ("a decrement "
"cannot appear in a constant-expression");
return true;
case NIC_ARRAY_REF:
diff --git a/gcc/diagnostics/paths.cc b/gcc/diagnostics/paths.cc
index 824b810..8e29dae 100644
--- a/gcc/diagnostics/paths.cc
+++ b/gcc/diagnostics/paths.cc
@@ -97,6 +97,22 @@ event::meaning::maybe_get_verb_str (enum verb v)
return "branch";
case verb::danger:
return "danger";
+
+ /* Special control flow operations.
+
+ These are not part of SARIF v2.1.0 section 3.38.8, but the
+ spec allows other values; see
+ https://github.com/oasis-tcs/sarif-spec/issues/735 */
+ case verb::throw_:
+ return "throw";
+ case verb::catch_:
+ return "catch";
+ case verb::unwind_:
+ return "unwind";
+ case verb::setjmp_:
+ return "setjmp";
+ case verb::longjmp_:
+ return "longjmp";
}
}
diff --git a/gcc/diagnostics/paths.h b/gcc/diagnostics/paths.h
index d30c420..f7dff8d 100644
--- a/gcc/diagnostics/paths.h
+++ b/gcc/diagnostics/paths.h
@@ -96,7 +96,14 @@ class event
return_,
branch,
- danger
+ danger,
+
+ // Special control flow operations:
+ throw_,
+ catch_,
+ unwind_, // unwinding stack frame(s) during exception-handling
+ setjmp_,
+ longjmp_
};
enum class noun
{
@@ -131,6 +138,10 @@ class event
m_property (property::unknown)
{
}
+ meaning (enum verb verb)
+ : m_verb (verb), m_noun (noun::unknown), m_property (property::unknown)
+ {
+ }
meaning (enum verb verb, enum noun noun)
: m_verb (verb), m_noun (noun), m_property (property::unknown)
{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8aaedae..7427825 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1131,6 +1131,14 @@ such an initializer, as shown here:
char **foo = (char *[]) @{ "x", "y", "z" @};
@end smallexample
+As a GNU extension, GCC allows compound literals with a variable size.
+In this case, only empty initialization is allowed.
+
+@smallexample
+int n = 4;
+char (*p)[n] = &(char[n])@{ @};
+@end smallexample
+
Compound literals for scalar types and union types are also allowed. In
the following example the variable @code{i} is initialized to the value
@code{2}, the result of incrementing the unnamed object created by
@@ -3463,12 +3471,41 @@ Function Attributes}, @ref{PowerPC Function Attributes},
@ref{ARM Function Attributes}, @ref{AArch64 Function Attributes},
and @ref{S/390 Function Attributes} for details.
+On targets supporting @code{target} function multiversioning (x86), when using
+C++, you can declare multiple functions with the same signatures but different
+@code{target} attribute values, and the correct version is chosen by the
+dynamic linker. In the example below, two function versions are produced
+with differing mangling. Additionally an ifunc resolver is created to
+select the correct version to populate the @code{func} symbol.
+
+@smallexample
+int func (void) __attribute__ ((target ("arch=core2"))) @{ return 1; @}
+int func (void) __attribute__ ((target ("sse3"))) @{ return 2; @}
+@end smallexample
+
+Declarations annotated with @code{target} cannot be used in combination with
+declarations annotated with @code{target_clones} in a single multiversioned
+function definition.
+
+@xref{Function Multiversioning} for more details.
+
+@cindex @code{target_version} function attribute
+@item target_version (@var{option})
+On targets with @code{target_version} function multiversioning (AArch64 and
+RISC-V) in C or C++, you can declare multiple functions with
+@code{target_version} or @code{target_clones} attributes to define a function
+version set.
+
+@xref{Function Multiversioning} for more details.
+
@cindex @code{target_clones} function attribute
@item target_clones (@var{options})
The @code{target_clones} attribute is used to specify that a function
be cloned into multiple versions compiled with different target options
-than specified on the command line. The supported options and restrictions
-are the same as for @code{target} attribute.
+than specified on the command line.
+
+For the x86 and PowerPC targets, the supported options and restrictions
+are the same as for the @code{target} attribute.
For instance, on an x86, you could compile a function with
@code{target_clones("sse4.1,avx")}. GCC creates two function clones,
@@ -3480,16 +3517,20 @@ function clones, one compiled with @option{-mcpu=power9} and another
with the default options. GCC must be configured to use GLIBC 2.23 or
newer in order to use the @code{target_clones} attribute.
-It also creates a resolver function (see
-the @code{ifunc} attribute above) that dynamically selects a clone
-suitable for current architecture. The resolver is created only if there
-is a usage of a function with @code{target_clones} attribute.
+@code{target_clones} works similarly for targets that support the
+@code{target_version} attribute (AArch64 and RISC-V). The attribute takes
+multiple arguments, and generates a versioned clone for each. A function
+annotated with @code{target_clones} is equivalent to the same function
+duplicated for each valid version string in the argument, where each
+version is instead annotated with @code{target_version}. This means that a
+@code{target_clones} annotated function definition can be used in combination
+with @code{target_version} annotated functions definitions and other
+@code{target_clones} annotated function definitions.
-Note that any subsequent call of a function without @code{target_clone}
-from a @code{target_clone} caller will not lead to copying
-(target clone) of the called function.
-If you want to enforce such behavior,
-we recommend declaring the calling function with the @code{flatten} attribute?
+For these targets the supported options and restrictions are the same as for
+the @code{target_version} attribute.
+
+@xref{Function Multiversioning} for more details.
@cindex @code{unavailable} function attribute
@item unavailable
@@ -19693,7 +19734,16 @@ into the data cache. The instruction is issued in slot I1@.
These built-in functions are available for LoongArch.
-Data Type Description:
+@menu
+* Data Types::
+* Directly-mapped Builtin Functions::
+* Directly-mapped Division Builtin Functions::
+* Other Builtin Functions::
+@end menu
+
+@node Data Types
+@subsubsection Data Types
+
@itemize
@item @code{imm0_31}, a compile-time constant in range 0 to 31;
@item @code{imm0_16383}, a compile-time constant in range 0 to 16383;
@@ -19701,6 +19751,9 @@ Data Type Description:
@item @code{imm_n2048_2047}, a compile-time constant in range -2048 to 2047;
@end itemize
+@node Directly-mapped Builtin Functions
+@subsubsection Directly-mapped Builtin Functions
+
The intrinsics provided are listed below:
@smallexample
unsigned int __builtin_loongarch_movfcsr2gr (imm0_31)
@@ -19824,6 +19877,9 @@ function you need to include @code{larchintrin.h}.
void __break (imm0_32767)
@end smallexample
+@node Directly-mapped Division Builtin Functions
+@subsubsection Directly-mapped Division Builtin Functions
+
These intrinsic functions are available by including @code{larchintrin.h} and
using @option{-mfrecipe}.
@smallexample
@@ -19833,6 +19889,9 @@ using @option{-mfrecipe}.
double __frsqrte_d (double);
@end smallexample
+@node Other Builtin Functions
+@subsubsection Other Builtin Functions
+
Additional built-in functions are available for LoongArch family
processors to efficiently use 128-bit floating-point (__float128)
values.
@@ -19859,6 +19918,15 @@ GCC provides intrinsics to access the LSX (Loongson SIMD Extension) instructions
The interface is made available by including @code{<lsxintrin.h>} and using
@option{-mlsx}.
+@menu
+* SX Data Types::
+* Directly-mapped SX Builtin Functions::
+* Directly-mapped SX Division Builtin Functions::
+@end menu
+
+@node SX Data Types
+@subsubsection SX Data Types
+
The following vectors typedefs are included in @code{lsxintrin.h}:
@itemize
@@ -19886,6 +19954,9 @@ input/output values manipulated:
@item @code{imm_n2048_2047}, an integer literal in range -2048 to 2047.
@end itemize
+@node Directly-mapped SX Builtin Functions
+@subsubsection Directly-mapped SX Builtin Functions
+
For convenience, GCC defines functions @code{__lsx_vrepli_@{b/h/w/d@}} and
@code{__lsx_b[n]z_@{v/b/h/w/d@}}, which are implemented as follows:
@@ -20669,6 +20740,9 @@ __m128i __lsx_vxori_b (__m128i, imm0_255);
__m128i __lsx_vxor_v (__m128i, __m128i);
@end smallexample
+@node Directly-mapped SX Division Builtin Functions
+@subsubsection Directly-mapped SX Division Builtin Functions
+
These intrinsic functions are available by including @code{lsxintrin.h} and
using @option{-mfrecipe} and @option{-mlsx}.
@smallexample
@@ -20685,6 +20759,16 @@ GCC provides intrinsics to access the LASX (Loongson Advanced SIMD Extension)
instructions. The interface is made available by including @code{<lasxintrin.h>}
and using @option{-mlasx}.
+@menu
+* ASX Data Types::
+* Directly-mapped ASX Builtin Functions::
+* Directly-mapped ASX Division Builtin Functions::
+* Directly-mapped SX and ASX Conversion Builtin Functions::
+@end menu
+
+@node ASX Data Types
+@subsubsection ASX Data Types
+
The following vectors typedefs are included in @code{lasxintrin.h}:
@itemize
@@ -20713,6 +20797,9 @@ input/output values manipulated:
@item @code{imm_n2048_2047}, an integer literal in range -2048 to 2047.
@end itemize
+@node Directly-mapped ASX Builtin Functions
+@subsubsection Directly-mapped ASX Builtin Functions
+
For convenience, GCC defines functions @code{__lasx_xvrepli_@{b/h/w/d@}} and
@code{__lasx_b[n]z_@{v/b/h/w/d@}}, which are implemented as follows:
@@ -21517,6 +21604,9 @@ __m256i __lasx_xvxori_b (__m256i, imm0_255);
__m256i __lasx_xvxor_v (__m256i, __m256i);
@end smallexample
+@node Directly-mapped ASX Division Builtin Functions
+@subsubsection Directly-mapped ASX Division Builtin Functions
+
These intrinsic functions are available by including @code{lasxintrin.h} and
using @option{-mfrecipe} and @option{-mlasx}.
@smallexample
@@ -21526,6 +21616,213 @@ __m256d __lasx_xvfrsqrte_d (__m256d);
__m256 __lasx_xvfrsqrte_s (__m256);
@end smallexample
+@node Directly-mapped SX and ASX Conversion Builtin Functions
+@subsubsection Directly-mapped SX and ASX Conversion Builtin Functions
+
+For convenience, the @code{lsxintrin.h} file was imported into @code{
+lasxintrin.h} and 18 new interface functions for 128 and 256 vector
+conversions were added, using the @option{-mlasx} option.
+@smallexample
+__m256 __lasx_cast_128_s (__m128);
+__m256d __lasx_cast_128_d (__m128d);
+__m256i __lasx_cast_128 (__m128i);
+__m256 __lasx_concat_128_s (__m128, __m128);
+__m256d __lasx_concat_128_d (__m128d, __m128d);
+__m256i __lasx_concat_128 (__m128i, __m128i);
+__m128 __lasx_extract_128_lo_s (__m256);
+__m128 __lasx_extract_128_hi_s (__m256);
+__m128d __lasx_extract_128_lo_d (__m256d);
+__m128d __lasx_extract_128_hi_d (__m256d);
+__m128i __lasx_extract_128_lo (__m256i);
+__m128i __lasx_extract_128_hi (__m256i);
+__m256 __lasx_insert_128_lo_s (__m256, __m128);
+__m256 __lasx_insert_128_hi_s (__m256, __m128);
+__m256d __lasx_insert_128_lo_d (__m256d, __m128d);
+__m256d __lasx_insert_128_hi_d (__m256d, __m128d);
+__m256i __lasx_insert_128_lo (__m256i, __m128i);
+__m256i __lasx_insert_128_hi (__m256i, __m128i);
+@end smallexample
+
+When gcc does not support interfaces for 128 and 256 conversions,
+use the following code for equivalent substitution.
+
+@smallexample
+
+ #ifndef __loongarch_asx_sx_conv
+
+ #include <lasxintrin.h>
+ #include <lsxintrin.h>
+ __m256 inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_cast_128_s (__m128 src)
+ @{
+ __m256 dest;
+ asm ("" : "=f"(dest) : "0"(src));
+ return dest;
+ @}
+
+ __m256d inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_cast_128_d (__m128d src)
+ @{
+ __m256d dest;
+ asm ("" : "=f"(dest) : "0"(src));
+ return dest;
+ @}
+
+ __m256i inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_cast_128 (__m128i src)
+ @{
+ __m256i dest;
+ asm ("" : "=f"(dest) : "0"(src));
+ return dest;
+ @}
+
+ __m256 inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_concat_128_s (__m128 src1, __m128 src2)
+ @{
+ __m256 dest;
+ asm ("xvpermi.q %u0,%u2,0x02\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m256d inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_concat_128_d (__m128d src1, __m128d src2)
+ @{
+ __m256d dest;
+ asm ("xvpermi.q %u0,%u2,0x02\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m256i inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_concat_128 (__m128i src1, __m128i src2)
+ @{
+ __m256i dest;
+ asm ("xvpermi.q %u0,%u2,0x02\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m128 inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_extract_128_lo_s (__m256 src)
+ @{
+ __m128 dest;
+ asm ("" : "=f"(dest) : "0"(src));
+ return dest;
+ @}
+
+ __m128d inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_extract_128_lo_d (__m256d src)
+ @{
+ __m128d dest;
+ asm ("" : "=f"(dest) : "0"(src));
+ return dest;
+ @}
+
+ __m128i inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_extract_128_lo (__m256i src)
+ @{
+ __m128i dest;
+ asm ("" : "=f"(dest) : "0"(src));
+ return dest;
+ @}
+
+ __m128 inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_extract_128_hi_s (__m256 src)
+ @{
+ __m128 dest;
+ asm ("xvpermi.d %u0,%u1,0xe\n"
+ : "=f"(dest)
+ : "f"(src));
+ return dest;
+ @}
+
+ __m128d inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_extract_128_hi_d (__m256d src)
+ @{
+ __m128d dest;
+ asm ("xvpermi.d %u0,%u1,0xe\n"
+ : "=f"(dest)
+ : "f"(src));
+ return dest;
+ @}
+
+ __m128i inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_extract_128_hi (__m256i src)
+ @{
+ __m128i dest;
+ asm ("xvpermi.d %u0,%u1,0xe\n"
+ : "=f"(dest)
+ : "f"(src));
+ return dest;
+ @}
+
+ __m256 inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_insert_128_lo_s (__m256 src1, __m128 src2)
+ @{
+ __m256 dest;
+ asm ("xvpermi.q %u0,%u2,0x30\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m256d inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_insert_128_lo_d (__m256d a, __m128d b)
+ @{
+ __m256d dest;
+ asm ("xvpermi.q %u0,%u2,0x30\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m256i inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_insert_128_lo (__m256i src1, __m128i src2)
+ @{
+ __m256i dest;
+ asm ("xvpermi.q %u0,%u2,0x30\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m256 inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_insert_128_hi_s (__m256 src1, __m128 src2)
+ @{
+ __m256 dest;
+ asm ("xvpermi.q %u0,%u2,0x02\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m256d inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_insert_128_hi_d (__m256d src1, __m128d src2)
+ @{
+ __m256d dest;
+ asm ("xvpermi.q %u0,%u2,0x02\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+
+ __m256i inline __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ __lasx_insert_128_hi (__m256i src1, __m128i src2)
+ @{
+ __m256i dest;
+ asm ("xvpermi.q %u0,%u2,0x02\n"
+ : "=f"(dest)
+ : "0"(src1), "f"(src2));
+ return dest;
+ @}
+ #endif
+
+@end smallexample
+
@node MIPS DSP Built-in Functions
@subsection MIPS DSP Built-in Functions
@@ -30674,11 +30971,79 @@ For the effects of the @code{hot} attribute on functions, see
@section Function Multiversioning
@cindex function versions
-With the GNU C++ front end, for x86 targets, you may specify multiple
-versions of a function, where each function is specialized for a
-specific target feature. At runtime, the appropriate version of the
-function is automatically executed depending on the characteristics of
-the execution platform. Here is an example.
+Function multiversioning is a mechanism that enables compiling multiple
+versions of a function, each specialized for different combinations of
+architecture extensions. Additionally, the compiler generates a resolver that
+the dynamic linker uses to detect architecture support and choose the
+appropriate version at runtime.
+
+Function multiversioning relies on the indirect function extension to the ELF
+standard, and therefore Binutils version 2.20.1 or higher and GNU C Library
+version 2.11.1 are required to use this feature.
+
+There are two versions of function multiversioning supported by GCC.
+
+For targets supporting the @code{target_version} attribute (AArch64 and RISC-V),
+when compiling for C or C++, a function version set can be defined by a
+combination of function definitions with @code{target_version} and
+@code{target_clones} attributes, across translation units.
+
+For example:
+
+@smallexample
+// fmv.h:
+int foo ();
+int foo [[gnu::target_clones("sve", "sve2")]] ();
+int foo [[gnu::target_version("dotprod;priority=1")]] ();
+
+// fmv1.cc
+#include "fmv.h"
+
+int foo ()
+@{
+ // The default version of foo.
+ return 0;
+@}
+
+// fmv2.cc:
+#include "fmv.h"
+
+int foo [[gnu::target_clones("sve", "sve2")]] ()
+@{
+ // foo versions for sve and sve2
+ return 1;
+@}
+
+int foo [[gnu::target_version("dotprod")]] ()
+@{
+ // foo version for dotprod extension
+ return 2;
+@}
+
+// main.cc
+#include "fmv.h"
+
+int main ()
+@{
+ int (*p)() = &foo;
+ assert ((*p) () == foo ());
+ return 0;
+@}
+@end smallexample
+
+This example results in 4 versions of the foo function being generated, and
+a resolver which is used by the dynamic linker to choose the correct version.
+
+For the AArch64 target GCC implements function multiversionsing, with the
+semantics and version strings as specified in the
+@ref{ARM C Language Extensions (ACLE)}.
+
+For targets that support multiversioning with the @code{target} attribute
+(x86) a multiversioned function can be defined with either multiple function
+definitions with the @code{target} attribute (in C++) within a translation unit,
+or a single definition with the @code{target_clones} attribute.
+
+Here is an example.
@smallexample
__attribute__ ((target ("default")))
diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi
index dc6a111..25aa006 100644
--- a/gcc/doc/tree-ssa.texi
+++ b/gcc/doc/tree-ssa.texi
@@ -355,7 +355,7 @@ FOR_EACH_PHI_OR_STMT_DEF (def_operand_p, phi, iter, flags)
Immediate use information is now always available. Using the immediate use
iterators, you may examine every use of any @code{SSA_NAME}. For instance,
-to change each use of @code{ssa_var} to @code{ssa_var2} and call fold_stmt on
+to change each use of @code{ssa_var} to @code{val} and call fold_stmt on
each stmt after that is done:
@smallexample
@@ -367,8 +367,9 @@ each stmt after that is done:
FOR_EACH_IMM_USE_STMT (stmt, iterator, ssa_var)
@{
FOR_EACH_IMM_USE_ON_STMT (imm_use_p, iterator)
- SET_USE (imm_use_p, ssa_var_2);
+ SET_USE (imm_use_p, val);
fold_stmt (stmt);
+ update_stmt (stmt);
@}
@end smallexample
@@ -389,9 +390,7 @@ terminated early; a destructor takes care of that when leaving the
@code{FOR_EACH_IMM_USE_STMT} scope.
There are checks in @code{verify_ssa} which verify that the immediate use list
-is up to date, as well as checking that an optimization didn't break from the
-loop without using this macro. It is safe to simply 'break'; from a
-@code{FOR_EACH_IMM_USE_FAST} traverse.
+is up to date.
Some useful functions and macros:
@enumerate
@@ -412,7 +411,9 @@ isn't located in a @code{PHI} node.
@end enumerate
Note that uses are not put into an immediate use list until their statement is
-actually inserted into the instruction stream via a @code{bsi_*} routine.
+actually inserted into the instruction stream via a @code{gsi_*} routine
+which calls @code{update_stmt} to re-scan SSA operands and update the
+immediate use lists.
It is also still possible to utilize lazy updating of statements, but this
should be used only when absolutely required. Both alias analysis and the
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 0d937eb..ffaf520 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,16 @@
+2025-11-03 Steve Kargl <kargls@comcast.net>
+
+ PR fortran/122513
+ * resolve.cc (check_default_none_expr): Do not allow an
+ iterator in a locality spec. Allow a named constant to be
+ used within the loop.
+
+2025-11-01 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/78640
+ * resolve.cc (resolve_fl_procedure): Check function result of a
+ pure function against F2018:C1585.
+
2025-10-31 Yuao Ma <c8ef@outlook.com>
* intrinsic.texi: Fix typo.
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index ecd2ada..5fa408e 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -8461,7 +8461,20 @@ check_default_none_expr (gfc_expr **e, int *, void *data)
break;
ns2 = ns2->parent;
}
- if (ns2 != NULL)
+
+ /* A DO CONCURRENT iterator cannot appear in a locality spec. */
+ if (sym->ns->code->ext.concur.forall_iterator)
+ {
+ gfc_forall_iterator *iter
+ = sym->ns->code->ext.concur.forall_iterator;
+ for (; iter; iter = iter->next)
+ if (iter->var->symtree
+ && strcmp(sym->name, iter->var->symtree->name) == 0)
+ return 0;
+ }
+
+ /* A named constant is not a variable, so skip test. */
+ if (ns2 != NULL && sym->attr.flavor != FL_PARAMETER)
{
gfc_error ("Variable %qs at %L not specified in a locality spec "
"of DO CONCURRENT at %L but required due to "
@@ -15385,6 +15398,39 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
return false;
}
+ /* F2018:C1585: "The function result of a pure function shall not be both
+ polymorphic and allocatable, or have a polymorphic allocatable ultimate
+ component." */
+ if (sym->attr.pure && sym->result && sym->ts.u.derived)
+ {
+ if (sym->ts.type == BT_CLASS
+ && sym->attr.class_ok
+ && CLASS_DATA (sym->result)
+ && CLASS_DATA (sym->result)->attr.allocatable)
+ {
+ gfc_error ("Result variable %qs of pure function at %L is "
+ "polymorphic allocatable",
+ sym->result->name, &sym->result->declared_at);
+ return false;
+ }
+
+ if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->components)
+ {
+ gfc_component *c = sym->ts.u.derived->components;
+ for (; c; c = c->next)
+ if (c->ts.type == BT_CLASS
+ && CLASS_DATA (c)
+ && CLASS_DATA (c)->attr.allocatable)
+ {
+ gfc_error ("Result variable %qs of pure function at %L has "
+ "polymorphic allocatable component %qs",
+ sym->result->name, &sym->result->declared_at,
+ c->name);
+ return false;
+ }
+ }
+ }
+
if (sym->attr.is_bind_c && sym->attr.is_c_interop != 1)
{
gfc_formal_arglist *curr_arg;
diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index 102e21f..b968a45 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -2283,6 +2283,28 @@ gimple_copy (gimple *stmt)
}
}
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ {
+ gomp_atomic_load *g = as_a <gomp_atomic_load *> (copy);
+ gimple_omp_atomic_load_set_lhs (g,
+ unshare_expr (gimple_omp_atomic_load_lhs (g)));
+ gimple_omp_atomic_load_set_rhs (g,
+ unshare_expr (gimple_omp_atomic_load_rhs (g)));
+ break;
+ }
+ case GIMPLE_OMP_ATOMIC_STORE:
+ {
+ gomp_atomic_store *g = as_a <gomp_atomic_store *> (copy);
+ gimple_omp_atomic_store_set_val (g,
+ unshare_expr (gimple_omp_atomic_store_val (g)));
+ break;
+ }
+ default:
+ break;
+ }
+
/* Make copy of operands. */
for (i = 0; i < num_ops; i++)
gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 48ce7578..1bbf21f 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -523,6 +523,11 @@ update_equiv (int regno)
{
rtx x;
+ /* If REGNO is beyond the length of the equivalence array structure,
+ then there's nothing to update. */
+ if (regno >= ira_reg_equiv_len)
+ return;
+
if ((x = ira_reg_equiv[regno].memory) != NULL_RTX)
ira_reg_equiv[regno].memory
= simplify_replace_fn_rtx (x, NULL_RTX, loc_equivalence_callback,
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog
index bb307bb..737ab12 100644
--- a/gcc/m2/ChangeLog
+++ b/gcc/m2/ChangeLog
@@ -1,3 +1,36 @@
+2025-11-02 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/122499
+ * gm2-compiler/M2StackSpell.mod (PushName): Add comment.
+ (GetSpellHint): Rewrite.
+ (GetExportedSpellHint): New procedure function.
+ (GetScopeSpellHint): New procedure function.
+ * gm2-compiler/P1Build.bnf (IdentScope): Rewrite.
+ (PossiblyExportIdent): Ditto.
+ * gm2-compiler/P1SymBuild.mod (BuildImportInnerModule): Add
+ parameter to AddNameToImportList.
+ * gm2-compiler/SymbolTable.def (GetUnknownOnImport): New
+ procedure function.
+ (GetUnknownDeclScope): Ditto.
+ (AddNameToScope): Add tok parameter.
+ (AddNameToImportList): Ditto.
+ * gm2-compiler/SymbolTable.mod (SymUndefined): New field
+ declScope.
+ New field onImport.
+ (MakeObject): Add tok parameter.
+ (FillInUnknownFields): Initialize declScope.
+ Initialize onImport.
+ (GetUnknownOnImport): New procedure function.
+ (GetUnknownDeclScope): Ditto.
+ (AddNameToScope): Pass tok to MakeObject.
+ (AddNameToImportList): Add tok parameter.
+ Pass tok to MakeObject.
+ (GetDeclaredSym): Add parameters to FillInUnknownFields.
+ (RequestSym): Ditto.
+ (FetchUnknownFromModule): Ditto.
+ (FetchUnknownFromDefImp): Ditto.
+ (FetchUnknownFrom): Ditto.
+
2025-10-30 Gaius Mulley <gaiusmod2@gmail.com>
PR modula2/122485
diff --git a/gcc/m2/gm2-compiler/M2StackSpell.mod b/gcc/m2/gm2-compiler/M2StackSpell.mod
index ac58c1c..06ce923 100644
--- a/gcc/m2/gm2-compiler/M2StackSpell.mod
+++ b/gcc/m2/gm2-compiler/M2StackSpell.mod
@@ -23,8 +23,10 @@ IMPLEMENTATION MODULE M2StackSpell ;
FROM SymbolTable IMPORT NulSym, IsModule, IsDefImp, IsRecord,
IsEnumeration, IsProcedure, GetNth,
- GetSymName, GetSym, GetLocalSym,
- UnknownReported,
+ GetSymName, GetSym, GetLocalSym, GetScope,
+ UnknownReported, IsUnknown,
+ GetUnknownOnImport, GetUnknownDeclScope,
+ ForeachExportedDo,
ForeachProcedureDo, ForeachLocalSymDo,
ForeachFieldEnumerationDo ;
@@ -179,8 +181,9 @@ VAR
PushCount : CARDINAL ;
PushCandidate: Candidates ;
+
(*
- PushName -
+ PushName - push a name to the candidate vec.
*)
PROCEDURE PushName (sym: CARDINAL) ;
@@ -279,7 +282,7 @@ BEGIN
cand := m2spellcheck.InitCandidates () ;
IF PushCandidates (cand, sym) > 1
THEN
- content := m2spellcheck.FindClosestCharStar (cand, string (misspelt)) ;
+ content := m2spellcheck.FindClosestCharStar (cand, string (misspelt))
ELSE
content := NIL
END ;
@@ -310,6 +313,52 @@ END AddPunctuation ;
*)
PROCEDURE GetSpellHint (unknown: CARDINAL) : String ;
+BEGIN
+ IF IsUnknown (unknown) AND
+ GetUnknownOnImport (unknown) AND
+ (GetUnknownDeclScope (unknown) # GetScope (unknown))
+ THEN
+ (* It was created during an import statement. *)
+ RETURN GetExportedSpellHint (unknown, GetUnknownDeclScope (unknown))
+ END ;
+ RETURN GetScopeSpellHint (unknown)
+END GetSpellHint ;
+
+
+(*
+ GetExportedSpellHint - return a string describing a spelling hint
+ using the module exported identifiers.
+*)
+
+PROCEDURE GetExportedSpellHint (unknown, module: CARDINAL) : String ;
+VAR
+ content : ConstCharStar ;
+ misspell,
+ HintStr : String ;
+BEGIN
+ misspell := InitStringCharStar (KeyToCharStar (GetSymName (unknown))) ;
+ HintStr := NIL ;
+ PushCount := 0 ;
+ PushCandidate := m2spellcheck.InitCandidates () ;
+ ForeachExportedDo (module, PushName) ;
+ ForeachLocalSymDo (module, PushName) ;
+ IF PushCount > 0
+ THEN
+ content := m2spellcheck.FindClosestCharStar (PushCandidate,
+ string (misspell)) ;
+ HintStr := BuildHintStr (HintStr, content)
+ END ;
+ m2spellcheck.KillCandidates (PushCandidate) ;
+ RETURN AddPunctuation (HintStr, '?')
+END GetExportedSpellHint ;
+
+
+(*
+ GetScopeSpellHint - return a string describing a spelling hint
+ using the visible scopes.
+*)
+
+PROCEDURE GetScopeSpellHint (unknown: CARDINAL) : String ;
VAR
i, n : CARDINAL ;
sym : CARDINAL ;
@@ -331,7 +380,7 @@ BEGIN
INC (i)
END ;
RETURN AddPunctuation (HintStr, '?')
-END GetSpellHint ;
+END GetScopeSpellHint ;
(*
diff --git a/gcc/m2/gm2-compiler/P1Build.bnf b/gcc/m2/gm2-compiler/P1Build.bnf
index 4cbdf17..d56a286 100644
--- a/gcc/m2/gm2-compiler/P1Build.bnf
+++ b/gcc/m2/gm2-compiler/P1Build.bnf
@@ -358,9 +358,12 @@ END Ident ;
*)
PROCEDURE IdentScope (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
+VAR
+ tokpos: CARDINAL ;
BEGIN
- Ident(stopset0, stopset1, stopset2) ;
- AddNameToScope(LastIdent)
+ tokpos := GetTokenNo () ;
+ Ident (stopset0, stopset1, stopset2) ;
+ AddNameToScope (tokpos, LastIdent)
END IdentScope ;
@@ -374,14 +377,14 @@ PROCEDURE PossiblyExportIdent (stopset0: SetOfStop0; stopset1: SetOfStop1; stops
VAR
nothing: CARDINAL ;
BEGIN
- AddNameToScope(makekey(currentstring)) ;
- PushTFtok(makekey(currentstring), identtok, GetTokenNo()) ;
+ AddNameToScope (GetTokenNo (), makekey (currentstring)) ;
+ PushTFtok (makekey (currentstring), identtok, GetTokenNo ()) ;
CheckExplicitExported ;
- IF NOT IsAutoPushOn()
+ IF NOT IsAutoPushOn ()
THEN
- PopT(nothing)
+ PopT (nothing)
END ;
- Expect(identtok, stopset0, stopset1, stopset2)
+ Expect (identtok, stopset0, stopset1, stopset2)
END PossiblyExportIdent ;
diff --git a/gcc/m2/gm2-compiler/P1SymBuild.mod b/gcc/m2/gm2-compiler/P1SymBuild.mod
index d6c0f2f..33d12bd 100644
--- a/gcc/m2/gm2-compiler/P1SymBuild.mod
+++ b/gcc/m2/gm2-compiler/P1SymBuild.mod
@@ -39,6 +39,7 @@ FROM M2Reserved IMPORT ImportTok, ExportTok, QualifiedTok, UnQualifiedTok,
FROM FifoQueue IMPORT PutEnumerationIntoFifoQueue ;
FROM P0SymBuild IMPORT EnterBlock, LeaveBlock ;
+FROM libc IMPORT printf ;
FROM SymbolTable IMPORT NulSym,
ModeOfAddr,
@@ -472,9 +473,6 @@ BEGIN
OperandT(n+1)) ;
i := 1 ;
WHILE i<=n DO
-(*
- WriteString('Importing ') ; WriteKey(Operand(j)) ; WriteString(' from ') ; WriteKey(GetSymName(ModSym)) ; WriteLn ;
-*)
Sym := GetExported (OperandTok (n+1-i),
ModSym, OperandT (n+1-i)) ;
PutImported (Sym) ;
@@ -619,7 +617,7 @@ BEGIN
(* Ident List contains list of objects *)
i := 1 ;
WHILE i<=n DO
- AddNameToImportList (OperandT (i)) ;
+ AddNameToImportList (OperandTok (i), OperandT (i)) ;
INC (i)
END
ELSE
diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def
index 09a5590..2a2f201 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.def
+++ b/gcc/m2/gm2-compiler/SymbolTable.def
@@ -2136,6 +2136,20 @@ PROCEDURE UnknownReported (sym: CARDINAL) ;
(*
+ GetUnknownOnImport - returns the onimport field of unknown sym.
+*)
+
+PROCEDURE GetUnknownOnImport (sym: CARDINAL) : BOOLEAN ;
+
+
+(*
+ GetUnknownDeclScope - returns the decl scope of unknown sym.
+*)
+
+PROCEDURE GetUnknownDeclScope (sym: CARDINAL) : CARDINAL ;
+
+
+(*
IsReallyPointer - returns TRUE is sym is a pointer, address or a
type declared as a pointer or address.
*)
@@ -2613,7 +2627,7 @@ PROCEDURE ResolveConstructorTypes ;
current scope.
*)
-PROCEDURE AddNameToScope (n: Name) ;
+PROCEDURE AddNameToScope (tok: CARDINAL; n: Name) ;
(*
@@ -2621,7 +2635,7 @@ PROCEDURE AddNameToScope (n: Name) ;
module.
*)
-PROCEDURE AddNameToImportList (n: Name) ;
+PROCEDURE AddNameToImportList (tok: CARDINAL; n: Name) ;
(*
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod
index 023bd49..25170fb 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -230,6 +230,10 @@ TYPE
SymUndefined = RECORD
name : Name ; (* Index into name array, name *)
(* of record. *)
+ declScope : CARDINAL ; (* Scope where unknown is *)
+ (* created. *)
+ onImport : BOOLEAN ; (* Was it created during an *)
+ (* import? *)
oafamily : CARDINAL ; (* The oafamily for this sym *)
errorScope: ErrorScope ; (* Title scope used if an *)
(* error is emitted. *)
@@ -1591,7 +1595,7 @@ END IsError ;
MakeObject - creates an object node.
*)
-PROCEDURE MakeObject (name: Name) : CARDINAL ;
+PROCEDURE MakeObject (tok: CARDINAL; name: Name) : CARDINAL ;
VAR
pSym: PtrToSymbol ;
Sym : CARDINAL ;
@@ -1601,8 +1605,8 @@ BEGIN
WITH pSym^ DO
SymbolType := ObjectSym ;
Object.name := name ;
- InitWhereDeclared(Object.At) ;
- InitWhereFirstUsed(Object.At)
+ InitWhereDeclaredTok (tok, Object.At) ;
+ InitWhereFirstUsedTok (tok, Object.At)
END ;
RETURN( Sym )
END MakeObject ;
@@ -8647,7 +8651,7 @@ BEGIN
THEN
(* Make unknown *)
NewSym (Sym) ;
- FillInUnknownFields (tok, Sym, SymName) ;
+ FillInUnknownFields (tok, Sym, SymName, NulSym, FALSE) ;
(* Add to unknown tree *)
AddSymToUnknownTree (ScopePtr, SymName, Sym)
(*
@@ -8684,7 +8688,7 @@ BEGIN
THEN
(* Make unknown. *)
NewSym (Sym) ;
- FillInUnknownFields (tok, Sym, SymName) ;
+ FillInUnknownFields (tok, Sym, SymName, NulSym, FALSE) ;
(* Add to unknown tree *)
AddSymToUnknownTree (ScopePtr, SymName, Sym)
(*
@@ -9252,7 +9256,7 @@ BEGIN
IF Sym=NulSym
THEN
NewSym (Sym) ;
- FillInUnknownFields (tok, Sym, SymName) ;
+ FillInUnknownFields (tok, Sym, SymName, ModSym, TRUE) ;
PutSymKey (Unresolved, SymName, Sym)
END
END
@@ -9283,7 +9287,7 @@ BEGIN
IF Sym=NulSym
THEN
NewSym(Sym) ;
- FillInUnknownFields (tok, Sym, SymName) ;
+ FillInUnknownFields (tok, Sym, SymName, ModSym, TRUE) ;
PutSymKey (Unresolved, SymName, Sym)
END
END
@@ -9310,7 +9314,7 @@ BEGIN
IF Sym=NulSym
THEN
NewSym(Sym) ;
- FillInUnknownFields (tok, Sym, SymName) ;
+ FillInUnknownFields (tok, Sym, SymName, scope, TRUE) ;
PutSymKey(Unresolved, SymName, Sym)
END
END |
@@ -9319,7 +9323,7 @@ BEGIN
IF Sym=NulSym
THEN
NewSym(Sym) ;
- FillInUnknownFields (tok, Sym, SymName) ;
+ FillInUnknownFields (tok, Sym, SymName, scope, TRUE) ;
PutSymKey(Unresolved, SymName, Sym)
END
END |
@@ -9328,7 +9332,7 @@ BEGIN
IF Sym=NulSym
THEN
NewSym(Sym) ;
- FillInUnknownFields (tok, Sym, SymName) ;
+ FillInUnknownFields (tok, Sym, SymName, NulSym, FALSE) ;
PutSymKey(Unresolved, SymName, Sym)
END
END
@@ -9599,7 +9603,8 @@ BEGIN
CheckForUnknowns (tokno, name, ExportUnQualifiedTree,
'EXPORT UNQUALIFIED') ;
CheckForSymbols (ExportRequest,
- 'requested by another modules import (symbols have not been exported by the appropriate definition module)') ;
+ 'requested by another module import' +
+ ' and the symbol has not been exported by the appropriate definition module') ;
CheckForUnknowns (tokno, name, Unresolved, 'unresolved') ;
CheckForUnknowns (tokno, name, LocalSymbols, 'locally used')
END |
@@ -9752,12 +9757,12 @@ PROCEDURE CheckForSymbols (Tree: SymbolTree; a: ARRAY OF CHAR) ;
VAR
s: String ;
BEGIN
- IF NOT IsEmptyTree(Tree)
+ IF DoesTreeContainAny (Tree, IsUnreportedUnknown)
THEN
s := InitString ("the symbols are unknown at the end of module {%1Ea} when ") ;
s := ConCat (s, Mark(InitString(a))) ;
MetaErrorString1 (s, MainModule) ;
- ForeachNodeDo(Tree, SymbolError)
+ ForeachNodeDo (Tree, SymbolError)
END
END CheckForSymbols ;
@@ -11708,10 +11713,11 @@ END IsProcedureAnyNoReturn ;
(*
- FillInUnknownFields -
+ FillInUnknownFields - fills in all fields for the undefined sym.
*)
-PROCEDURE FillInUnknownFields (tok: CARDINAL; sym: CARDINAL; SymName: Name) ;
+PROCEDURE FillInUnknownFields (tok: CARDINAL; sym: CARDINAL; SymName: Name;
+ descscope: CARDINAL; onimport: BOOLEAN) ;
VAR
pSym: PtrToSymbol ;
BEGIN
@@ -11722,6 +11728,8 @@ BEGIN
name := SymName ;
oafamily := NulSym ;
errorScope := GetCurrentErrorScope () ;
+ declScope := descscope ;
+ onImport := onimport ;
InitWhereFirstUsedTok (tok, At)
END
END
@@ -11729,6 +11737,34 @@ END FillInUnknownFields ;
(*
+ GetUnknownOnImport - returns the onimport field of unknown sym.
+*)
+
+PROCEDURE GetUnknownOnImport (sym: CARDINAL) : BOOLEAN ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ Assert (IsUnknown (sym)) ;
+ pSym := GetPsym (sym) ;
+ RETURN pSym^.Undefined.onImport
+END GetUnknownOnImport ;
+
+
+(*
+ GetUnknownDeclScope - returns the decl scope of unknown sym.
+*)
+
+PROCEDURE GetUnknownDeclScope (sym: CARDINAL) : CARDINAL ;
+VAR
+ pSym: PtrToSymbol ;
+BEGIN
+ Assert (IsUnknown (sym)) ;
+ pSym := GetPsym (sym) ;
+ RETURN pSym^.Undefined.declScope
+END GetUnknownDeclScope ;
+
+
+(*
FillInPointerFields - given a new symbol, sym, make it a pointer symbol
and initialize its fields.
*)
@@ -12985,7 +13021,7 @@ END AddNameTo ;
current scope.
*)
-PROCEDURE AddNameToScope (n: Name) ;
+PROCEDURE AddNameToScope (tok: CARDINAL; n: Name) ;
VAR
pSym : PtrToSymbol ;
scope: CARDINAL ;
@@ -12995,9 +13031,9 @@ BEGIN
WITH pSym^ DO
CASE SymbolType OF
- ProcedureSym: AddNameTo(Procedure.NamedObjects, MakeObject(n)) |
- ModuleSym : AddNameTo(Module.NamedObjects, MakeObject(n)) |
- DefImpSym : AddNameTo(DefImp.NamedObjects, MakeObject(n))
+ ProcedureSym: AddNameTo(Procedure.NamedObjects, MakeObject (tok, n)) |
+ ModuleSym : AddNameTo(Module.NamedObjects, MakeObject (tok, n)) |
+ DefImpSym : AddNameTo(DefImp.NamedObjects, MakeObject (tok, n))
ELSE
InternalError ('expecting - DefImp')
@@ -13011,7 +13047,7 @@ END AddNameToScope ;
module.
*)
-PROCEDURE AddNameToImportList (n: Name) ;
+PROCEDURE AddNameToImportList (tok: CARDINAL; n: Name) ;
VAR
pSym : PtrToSymbol ;
scope: CARDINAL ;
@@ -13021,8 +13057,8 @@ BEGIN
WITH pSym^ DO
CASE SymbolType OF
- ModuleSym: AddNameTo(Module.NamedImports, MakeObject(n)) |
- DefImpSym: AddNameTo(DefImp.NamedImports, MakeObject(n))
+ ModuleSym: AddNameTo (Module.NamedImports, MakeObject (tok, n)) |
+ DefImpSym: AddNameTo (DefImp.NamedImports, MakeObject (tok, n))
ELSE
InternalError ('expecting - DefImp or Module symbol')
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index c4de035..59a86c6 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -3673,6 +3673,63 @@ simplify_context::simplify_binary_operation_1 (rtx_code code,
&& GET_MODE_CLASS (mode) != MODE_CC)
return CONSTM1_RTX (mode);
+ /* IOR of two single bit bitfields extracted from the same object.
+ Bitfields are represented as an AND based extraction */
+ if (GET_CODE (op0) == AND
+ && GET_CODE (op1) == AND
+ /* Verify both AND operands are logical right shifts. */
+ && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
+ && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
+ /* Verify both bitfields are extracted from the same object. */
+ && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
+ /* Verify both fields are a single bit (could be generalized). */
+ && XEXP (op0, 1) == CONST1_RTX (mode)
+ && XEXP (op1, 1) == CONST1_RTX (mode)
+ /* Verify bit positions (for cases with variable bit position). */
+ && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
+ && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
+ {
+ unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
+ unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
+ unsigned HOST_WIDE_INT mask
+ = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
+
+ rtx m = GEN_INT (mask);
+ rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
+ t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
+ return t;
+ }
+
+ /* IOR of multiple single bit bitfields extracted from the same object
+ (building on previous case).
+ First bitfield is represented as an AND based extraction, as done
+ above. Second represented as NE based extraction, from
+ output above. */
+ if (GET_CODE (op0) == AND
+ && GET_CODE (op1) == NE
+ /* Verify AND operand is logical right shift. */
+ && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
+ /* Verify NE operand is an AND (based on output above). */
+ && GET_CODE (XEXP (op1, 0)) == AND
+ /* Verify both bitfields are extracted from the same object. */
+ && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
+ /* Verify masking is with a single bit and that we have a NE 0
+ comparison for the other operand. */
+ && XEXP (op0, 1) == CONST1_RTX (mode)
+ && XEXP (op1, 1) == CONST0_RTX (mode)
+ /* Verify bit position. */
+ && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
+ {
+ unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
+ unsigned HOST_WIDE_INT mask
+ = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
+
+ rtx m = GEN_INT (mask);
+ rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
+ t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
+ return t;
+ }
+
/* Convert (ior (plus (A - 1)) (neg A)) to -1. */
if (match_plus_neg_pattern (op0, op1, mode))
return CONSTM1_RTX (mode);
@@ -4127,6 +4184,46 @@ simplify_context::simplify_binary_operation_1 (rtx_code code,
not do an AND. */
if ((nzop0 & ~val1) == 0)
return op0;
+
+ /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
+ (and (lshiftrt (subreg X) shift) mask).
+
+ Keeps shift and AND in the same mode, improving recognition.
+ Only applied when subreg is a lowpart, shift is valid,
+ and no precision is lost. */
+ if (SUBREG_P (op0) && subreg_lowpart_p (op0)
+ && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
+ && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
+ && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
+ && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
+ && ((INTVAL (XEXP (XEXP (op0, 0), 1))
+ + floor_log2 (val1))
+ < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
+ {
+ tem = XEXP (XEXP (op0, 0), 0);
+ if (SUBREG_P (tem))
+ {
+ if (subreg_lowpart_p (tem))
+ tem = SUBREG_REG (tem);
+ else
+ tem = NULL_RTX;
+ }
+ if (tem != NULL_RTX)
+ {
+ offset = subreg_lowpart_offset (mode, GET_MODE (tem));
+ tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
+ offset);
+ if (tem)
+ {
+ unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
+ rtx shiftamtrtx = gen_int_shift_amount (mode,
+ shiftamt);
+ op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
+ shiftamtrtx);
+ return simplify_gen_binary (AND, mode, op0, op1);
+ }
+ }
+ }
}
nzop1 = nonzero_bits (trueop1, mode);
/* If we are clearing all the nonzero bits, the result is zero. */
@@ -6394,6 +6491,21 @@ simplify_context::simplify_relational_operation_1 (rtx_code code,
/* Canonicalize (LEU x 0) as (EQ x 0). */
if (code == LEU)
return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
+
+ if ((code == NE || code == EQ)
+ /* Verify op0 is IOR */
+ && GET_CODE (op0) == IOR
+ /* only enters if op1 is 0 */
+ /* Verify IOR operand is NE */
+ && GET_CODE (XEXP (op0, 0)) == NE
+ /* Verfiy second NE operand is 0 */
+ && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (mode))
+ {
+ rtx t = gen_rtx_IOR (mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
+ t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
+ return t;
+ }
+
}
else if (op1 == const1_rtx)
{
diff --git a/gcc/ssa-iterators.h b/gcc/ssa-iterators.h
index 03d701c..0822a98 100644
--- a/gcc/ssa-iterators.h
+++ b/gcc/ssa-iterators.h
@@ -36,25 +36,17 @@ along with GCC; see the file COPYING3. If not see
base for a circular list, and initially this is the only node in
the list.
- Fast iteration allows each use to be examined, but does not allow
- any modifications to the uses or stmts.
-
- Normal iteration allows insertion, deletion, and modification. the
- iterator manages this by inserting a marker node into the list
- immediately before the node currently being examined in the list.
- this marker node is uniquely identified by having null stmt *and* a
- null use pointer.
-
- When iterating to the next use, the iteration routines check to see
- if the node after the marker has changed. if it has, then the node
- following the marker is now the next one to be visited. if not, the
- marker node is moved past that node in the list (visualize it as
- bumping the marker node through the list). this continues until
- the marker node is moved to the original anchor position. the
- marker node is then removed from the list.
-
- If iteration is halted early, the marker node must be removed from
- the list before continuing. */
+ Fast iteration via FOR_EACH_IMM_USE_FAST allows each use to be
+ examined, but does not allow any modifications to the uses or stmts.
+
+ Safe iteration via FOR_EACH_IMM_USE_STMT and FOR_EACH_IMM_USE_ON_STMT
+ allows insertion, deletion, and modification of SSA operands within
+ the current stmt iterated. The iterator manages this by re-sorting
+ the immediate uses to batch uses on a single stmt after each other
+ and inserts a marker node into the list immediately after the node
+ ending the current batch. This marker node is uniquely identified by
+ having null stmt *and* a null use pointer. */
+
struct imm_use_iterator
{
/* This is the current use the iterator is processing. */
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index fb2aca5..3dbfad3 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -882,7 +882,7 @@ static const char * const toplevel_type_names[] =
"variable",
};
-static_assert (ARRAY_SIZE(toplevel_type_names)==TOPLEVEL_MAX);
+static_assert (ARRAY_SIZE(toplevel_type_names) == TOPLEVEL_MAX, "");
/* Dump the visibility of the symbol. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 013121d..7a2f15e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,296 @@
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/generic_inst15.adb: New test.
+ * gnat.dg/generic_inst15_pkg-g.ads: New helper.
+ * gnat.dg/generic_inst15_pkg.ads: Likewise.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/abstract1.ads: New test.
+
+2025-11-03 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/122534
+ * gcc.target/i386/pr122534.c: New test.
+
+2025-11-03 Robin Dapp <rdapp.gcc@gmail.com>
+
+ * gcc.target/riscv/rvv/base/pr119115.c: Add -std=gnu99.
+
+2025-11-03 Steve Kargl <kargls@comcast.net>
+
+ PR fortran/122513
+ * gfortran.dg/pr122513.f90: New test.
+
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/lookup/koenig16.C: New test.
+ * g++.dg/modules/adl-11_a.C: New file.
+ * g++.dg/modules/adl-11_b.C: New file.
+
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/modules/builtin-9_a.C: New test.
+ * g++.dg/modules/builtin-9_b.C: New test.
+
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/modules/clone-5_a.C: New test.
+ * g++.dg/modules/clone-5_b.C: New test.
+
+2025-11-03 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/modules/namespace-15_a.C: New test.
+ * g++.dg/modules/namespace-15_b.C: New test.
+
+2025-11-03 Georg-Johann Lay <avr@gjlay.de>
+
+ * gcc.target/avr/torture/pr92606.c: Use LPM even if LPMx
+ is available.
+
+2025-11-03 Loeka Rogge <loeka@synopsys.com>
+
+ * gcc.target/arc/movv2hi-be.c: New test.
+
+2025-11-03 Kito Cheng <kito.cheng@sifive.com>
+
+ * g++.dg/abi/param2.C: Add -Wno-psabi option for RISC-V.
+ * g++.target/riscv/abi/empty-struct+union-1.cc: New test.
+ * g++.target/riscv/abi/empty-struct+union-2.cc: New test.
+ * g++.target/riscv/abi/empty-struct+union-3.cc: New test.
+ * g++.target/riscv/abi/empty-struct+union-4.cc: New test.
+ * g++.target/riscv/abi/empty-struct-1.cc: New test.
+ * g++.target/riscv/abi/empty-struct-2.cc: New test.
+ * g++.target/riscv/abi/empty-struct-3.cc: New test.
+ * g++.target/riscv/abi/empty-struct-4.cc: New test.
+ * g++.target/riscv/abi/empty-struct-5.cc: New test.
+ * g++.target/riscv/abi/empty-struct-6.cc: New test.
+ * g++.target/riscv/abi/empty-struct-7.cc: New test.
+ * g++.target/riscv/abi/empty-struct-8.cc: New test.
+ * g++.target/riscv/abi/empty-struct-9.cc: New test.
+ * g++.target/riscv/abi/empty-struct-10.cc: New test.
+ * g++.target/riscv/abi/empty-struct-11.cc: New test.
+ * g++.target/riscv/abi/empty-struct-12.cc: New test.
+ * g++.target/riscv/abi/empty-union-1.cc: New test.
+ * g++.target/riscv/abi/empty-union-2.cc: New test.
+ * g++.target/riscv/abi/empty-union-3.cc: New test.
+ * g++.target/riscv/abi/empty-union-4.cc: New test.
+ * g++.target/riscv/riscv.exp: Add abi subdirectory.
+ * gcc.dg/compat/pr83487-1_x.c: Add -Wno-psabi option for RISC-V.
+ * gcc.dg/compat/pr83487-1_y.c: Likewise.
+ * gcc.dg/compat/pr83487-2_x.c: Likewise.
+ * gcc.dg/compat/pr83487-2_y.c: Likewise.
+ * gcc.dg/torture/pr28814.c: Likewise.
+ * gcc.target/riscv/abi/empty-struct+union-1.c: New test.
+ * gcc.target/riscv/abi/empty-struct+union-2.c: New test.
+ * gcc.target/riscv/abi/empty-struct+union-3.c: New test.
+ * gcc.target/riscv/abi/empty-struct+union-4.c: New test.
+ * gcc.target/riscv/abi/empty-struct-1.c: New test.
+ * gcc.target/riscv/abi/empty-struct-2.c: New test.
+ * gcc.target/riscv/abi/empty-struct-3.c: New test.
+ * gcc.target/riscv/abi/empty-struct-4.c: New test.
+ * gcc.target/riscv/abi/empty-struct-5.c: New test.
+ * gcc.target/riscv/abi/empty-struct-6.c: New test.
+ * gcc.target/riscv/abi/empty-struct-7.c: New test.
+ * gcc.target/riscv/abi/empty-struct-8.c: New test.
+ * gcc.target/riscv/abi/empty-struct-9.c: New test.
+ * gcc.target/riscv/abi/empty-struct-10.c: New test.
+ * gcc.target/riscv/abi/empty-struct-11.c: New test.
+ * gcc.target/riscv/abi/empty-struct-12.c: New test.
+ * gcc.target/riscv/abi/empty-union-1.c: New test.
+ * gcc.target/riscv/abi/empty-union-2.c: New test.
+ * gcc.target/riscv/abi/empty-union-3.c: New test.
+ * gcc.target/riscv/abi/empty-union-4.c: New test.
+ * gcc.target/riscv/riscv.exp: Add abi subdirectory.
+
+2025-11-03 Alfie Richards <alfie.richards@arm.com>
+
+ PR target/122405
+ * g++.target/aarch64/mv-cpu-features.C: Add HWCAP_ATOMICS and
+ HWCAP2_RNG defines.
+
+2025-11-03 Alfie Richards <alfie.richards@arm.com>
+
+ * gcc.target/aarch64/fmv_priority.in: Update for new features.
+ * gcc.target/aarch64/fmv_priority1.c: Ditto.
+ * gcc.target/aarch64/fmv_priority2.c: Ditto.
+
+2025-11-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/vect19.ads, gnat.dg/vect19.adb: New test.
+ * gnat.dg/vect19_pkg.ads, gnat.dg/vect19_pkg.adb: New helper.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * gcc.target/loongarch/mode-tieable-opt.c: New test.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * gcc.target/loongarch/mem-and-mask-opt.c: New test.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * gcc.target/loongarch/vec_pack_unpack_256.c: Adjust to changed
+ lasx_xvpermi_q_<LASX:mode> template.
+ * gcc.target/loongarch/vector/lasx/lasx-builtin.c: Ditto.
+ * gcc.target/loongarch/lasx-xvpermi_q-opt.c: New test.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * gcc.target/loongarch/and-large-immediate-opt.c: New test.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * gcc.target/loongarch/extendsidi2-combine.c: New test.
+ * gcc.target/loongarch/spill-less.c: New test.
+
+2025-11-03 Guo Jie <guojie@loongson.cn>
+
+ * gcc.target/loongarch/mulh_wu.c: New test.
+
+2025-11-03 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/122475
+ * gcc.dg/vect/pr122475.c: New test.
+ * gcc.target/aarch64/sve/vect-reduc-bool-19.c: New test.
+ * gcc.target/aarch64/sve/vect-reduc-bool-20.c: New test.
+
+2025-11-03 H.J. Lu <hjl.tools@gmail.com>
+
+ * gcc.target/i386/builtin-memmove-1a.c: New test.
+ * gcc.target/i386/builtin-memmove-1b.c: Likewise.
+ * gcc.target/i386/builtin-memmove-1c.c: Likewise.
+ * gcc.target/i386/builtin-memmove-1d.c: Likewise.
+ * gcc.target/i386/builtin-memmove-2a.c: Likewise.
+ * gcc.target/i386/builtin-memmove-2b.c: Likewise.
+ * gcc.target/i386/builtin-memmove-2c.c: Likewise.
+ * gcc.target/i386/builtin-memmove-2d.c: Likewise.
+ * gcc.target/i386/builtin-memmove-3a.c: Likewise.
+ * gcc.target/i386/builtin-memmove-3b.c: Likewise.
+ * gcc.target/i386/builtin-memmove-3c.c: Likewise.
+ * gcc.target/i386/builtin-memmove-4a.c: Likewise.
+ * gcc.target/i386/builtin-memmove-4b.c: Likewise.
+ * gcc.target/i386/builtin-memmove-4c.c: Likewise.
+ * gcc.target/i386/builtin-memmove-5a.c: Likewise.
+ * gcc.target/i386/builtin-memmove-5b.c: Likewise.
+ * gcc.target/i386/builtin-memmove-5c.c: Likewise.
+ * gcc.target/i386/builtin-memmove-6.c: Likewise.
+ * gcc.target/i386/builtin-memmove-7.c: Likewise.
+ * gcc.target/i386/builtin-memmove-8.c: Likewise.
+ * gcc.target/i386/builtin-memmove-9.c: Likewise.
+ * gcc.target/i386/builtin-memmove-10.c: Likewise.
+ * gcc.target/i386/builtin-memmove-11a.c: Likewise.
+ * gcc.target/i386/builtin-memmove-11b.c: Likewise.
+ * gcc.target/i386/builtin-memmove-11c.c: Likewise.
+ * gcc.target/i386/builtin-memmove-12.c: Likewise.
+ * gcc.target/i386/builtin-memmove-13.c: Likewise.
+ * gcc.target/i386/builtin-memmove-14.c: Likewise.
+ * gcc.target/i386/builtin-memmove-15.c: Likewise.
+
+2025-11-03 Shreya Munnangi <smunnangi1@ventanamicro.com>
+
+ PR target/52345
+ * gcc.target/riscv/pr52345.c: Add new test cases.
+
+2025-11-03 chenxiaolong <chenxiaolong@loongson.cn>
+
+ * gcc.target/loongarch/vector/lasx/vect-concat-128-256-result.c: New test.
+ * gcc.target/loongarch/vector/lasx/vect-concat-128-256.c: New test.
+ * gcc.target/loongarch/vector/lasx/vect-extract-256-128-result.c: New test.
+ * gcc.target/loongarch/vector/lasx/vect-extract-256-128.c: New test.
+ * gcc.target/loongarch/vector/lasx/vect-insert-128-256-result.c: New test.
+ * gcc.target/loongarch/vector/lasx/vect-insert-128-256.c: New test.
+
+2025-11-03 Lulu Cheng <chenglulu@loongson.cn>
+
+ * gcc.target/loongarch/imm-load.c: Modify.
+
+2025-11-02 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/122499
+ * gm2.dg/spell/iso/fail/badimport2.mod: New test.
+ * gm2.dg/spell/iso/fail/badimport3.mod: New test.
+ * gm2.dg/spell/iso/fail/badimport4.mod: New test.
+
+2025-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/sparc/small-struct-1.c: Run only on Solaris.
+
+2025-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/sparc/cbcond-1.c: Accept reverse branches.
+ * gcc.target/sparc/cbcond-2.c: Likewise.
+ * gcc.target/sparc/overflow-3.c: Likewise.
+ * gcc.target/sparc/overflow-4.c: Likewise.
+ * gcc.target/sparc/overflow-5.c: Likewise.
+
+2025-11-02 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/122518
+ * gcc.target/i386/pr122518.c: New test.
+
+2025-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/unknown_discr1.ads: New test.
+ * gnat.dg/specs/unknown_discr1_pkg.ads: New helper.
+ * gnat.dg/specs/unknown_discr1_pkg-child.ads: Likewise.
+ * gnat.dg/specs/unknown_discr1_pkg-g.ads: Likewise.
+ * gnat.dg/specs/unknown_discr1_pkg-inst.ads: Likewise.
+
+2025-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/use_type4.adb: New test.
+
+2025-11-02 Georg-Johann Lay <avr@gjlay.de>
+
+ * gcc.target/avr/torture/pr84211-fuse-move-1.c: Add -fno-lto.
+
+2025-11-02 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/122421
+ * g++.dg/modules/inst-6_a.C: New test.
+ * g++.dg/modules/inst-6_b.C: New test.
+
+2025-11-01 Shreya Munnangi <smunnangi1@ventanamicro.com>
+
+ PR target/67731
+ * gcc.target/riscv/pr67731.c: New test.
+ * gcc.target/sh/pr67731.c: New test.
+
+2025-11-01 Jeff Law <jlaw@ventanamicro.com>
+
+ PR rtl-optimization/122321
+ * gcc.target/riscv/rvv/autovec/pr122321.c: New test.
+
+2025-11-01 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/78640
+ * gfortran.dg/pure_result.f90: New test.
+
+2025-11-01 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/122381
+ * g++.dg/modules/convop-2_a.H: New test.
+ * g++.dg/modules/convop-2_b.C: New test.
+
+2025-11-01 Martin Uecker <uecker@tugraz.at>
+
+ * gcc.dg/gnu-compoundlit-1.c: New test.
+ * gcc.dg/gnu-compoundlit-2.c: New test.
+ * gcc.dg/pr68090.c: Adapt.
+ * gcc.dg/vla-init-4.c: Adapt.
+ * gcc.dg/vla-init-5.c: Adapt.
+
+2025-11-01 Martin Uecker <uecker@tugraz.at>
+
+ PR c/97986
+ * gcc.dg/pr97986-1.c: New test.
+ * gcc.dg/pr97986-2.c: New test.
+
+2025-11-01 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ * gcc.dg/fold-vecperm-1.c: Test at forwprop3.
+
2025-10-31 Tamar Christina <tamar.christina@arm.com>
PR target/121853
diff --git a/gcc/testsuite/g++.dg/abi/param2.C b/gcc/testsuite/g++.dg/abi/param2.C
index d28387a..4752717 100644
--- a/gcc/testsuite/g++.dg/abi/param2.C
+++ b/gcc/testsuite/g++.dg/abi/param2.C
@@ -1,7 +1,7 @@
// PR target/20795
// Test passing aligned empty aggregate
// { dg-do compile }
-// { dg-options "-Wno-psabi" { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+// { dg-options "-Wno-psabi" { target { { { i?86-*-* x86_64-*-* } && ilp32 } || { riscv*-*-* } } } }
struct S { union {} a; } __attribute__((aligned));
diff --git a/gcc/testsuite/g++.dg/analyzer/exception-path-1-sarif.py b/gcc/testsuite/g++.dg/analyzer/exception-path-1-sarif.py
new file mode 100644
index 0000000..8958d96
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/exception-path-1-sarif.py
@@ -0,0 +1,22 @@
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_kinds(sarif):
+ result = get_result_by_index(sarif, 0)
+
+ assert result['level'] == 'note'
+
+ events = result["codeFlows"][0]["threadFlows"][0]['locations']
+
+ # Event "(1)": "throwing exception of type 'value_error' here..." (index == 0)
+ assert events[0]['location']['message']['text'] == "throwing exception of type 'value_error' here..."
+ assert events[0]['kinds'] == ["throw"]
+
+ # Event "(2)": "...catching exception of type 'value_error' here" (index == 1)
+ assert events[1]['location']['message']['text'] == "...catching exception of type 'value_error' here"
+ assert events[1]['kinds'] == ["catch"]
diff --git a/gcc/testsuite/g++.dg/analyzer/exception-path-1.C b/gcc/testsuite/g++.dg/analyzer/exception-path-1.C
index 486ca193..d923d62 100644
--- a/gcc/testsuite/g++.dg/analyzer/exception-path-1.C
+++ b/gcc/testsuite/g++.dg/analyzer/exception-path-1.C
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-fdiagnostics-add-output=sarif" } */
+
/* Verify that we follow the correct paths when we know the typeinfo of
an exception. */
@@ -32,3 +34,10 @@ int test ()
__analyzer_dump_path (); // { dg-bogus "path" }
return 0;
}
+
+/* Verify that some JSON was written to a file with the expected name. */
+/* { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest exception-path-1.C "exception-path-1-sarif.py" } } */
diff --git a/gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2-sarif.py b/gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2-sarif.py
new file mode 100644
index 0000000..b817a64
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2-sarif.py
@@ -0,0 +1,23 @@
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_kinds(sarif):
+ result = get_result_by_index(sarif, 0)
+
+ assert result['level'] == 'note'
+
+ events = result["codeFlows"][0]["threadFlows"][0]['locations']
+
+ assert events[-4]['location']['message']['text'] == "throwing exception of type 'value_error' here..."
+ assert events[-4]['kinds'] == ["throw"]
+
+ assert events[-3]['location']['message']['text'] == "unwinding 2 stack frames"
+ assert events[-3]['kinds'] == ["unwind"]
+
+ assert events[-2]['location']['message']['text'] == "...catching exception of type 'value_error' here"
+ assert events[-2]['kinds'] == ["catch"]
diff --git a/gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2.C b/gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2.C
index 2608f17..aa1ff89 100644
--- a/gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2.C
+++ b/gcc/testsuite/g++.dg/analyzer/exception-path-unwind-multiple-2.C
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-fdiagnostics-add-output=sarif" } */
+
/* Verify that we follow the correct paths when we know the typeinfo of
an exception: interprocedural case where unwind multiple frame,
failing to match the type. */
@@ -53,3 +55,10 @@ int outer ()
__analyzer_dump_path (); // { dg-bogus "path" }
return 0;
}
+
+/* Verify that some JSON was written to a file with the expected name. */
+/* { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest exception-path-unwind-multiple-2.C "exception-path-unwind-multiple-2-sarif.py" } } */
diff --git a/gcc/testsuite/g++.dg/lookup/koenig16.C b/gcc/testsuite/g++.dg/lookup/koenig16.C
new file mode 100644
index 0000000..1d6e4e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/koenig16.C
@@ -0,0 +1,22 @@
+// Before P1787 (C++20), only hidden friends are included in ADL.
+// After P1787, all friends are included.
+
+namespace N {
+ namespace NN {
+ struct A;
+ }
+ using NN::A;
+ void fn (A);
+ namespace NN {
+ struct A {
+ friend void N::fn (A);
+ };
+ }
+ void fn (A) { }
+}
+
+int main()
+{
+ N::A a;
+ fn(a); // { dg-error "not declared" "" { target c++17_down } }
+}
diff --git a/gcc/testsuite/g++.dg/modules/adl-11_a.C b/gcc/testsuite/g++.dg/modules/adl-11_a.C
new file mode 100644
index 0000000..063dd89
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/adl-11_a.C
@@ -0,0 +1,21 @@
+// Before P1787 (C++20), only hidden friends are included in ADL.
+// After P1787, all friends are included.
+
+// { dg-additional-options "-fmodules -Wno-global-module" }
+
+export module M;
+
+namespace N {
+ namespace NN {
+ export struct A;
+ }
+ export using NN::A;
+
+ export void fn (A);
+
+ namespace NN {
+ struct A {
+ friend void N::fn (A);
+ };
+ }
+}
diff --git a/gcc/testsuite/g++.dg/modules/adl-11_b.C b/gcc/testsuite/g++.dg/modules/adl-11_b.C
new file mode 100644
index 0000000..f178915
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/adl-11_b.C
@@ -0,0 +1,12 @@
+// Before P1787 (C++20), only hidden friends are included in ADL.
+// After P1787, all friends are included.
+
+// { dg-additional-options -fmodules }
+
+import M;
+
+int main()
+{
+ N::A a;
+ fn(a); // { dg-error "not declared" "" { target c++17_down } }
+}
diff --git a/gcc/testsuite/g++.dg/modules/builtin-9_a.C b/gcc/testsuite/g++.dg/modules/builtin-9_a.C
new file mode 100644
index 0000000..69b0e37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/builtin-9_a.C
@@ -0,0 +1,16 @@
+// Test that the built-in clog doesn't interfere with redeclaring the import.
+
+// { dg-additional-options "-fmodules -Wno-global-module" }
+
+module;
+
+namespace std {
+ class ostream;
+ extern ostream clog;
+}
+
+export module M;
+
+namespace std {
+ export using std::clog;
+}
diff --git a/gcc/testsuite/g++.dg/modules/builtin-9_b.C b/gcc/testsuite/g++.dg/modules/builtin-9_b.C
new file mode 100644
index 0000000..30ea013
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/builtin-9_b.C
@@ -0,0 +1,8 @@
+// { dg-additional-options -fmodules }
+
+import M;
+
+namespace std {
+ class ostream;
+ extern ostream clog;
+}
diff --git a/gcc/testsuite/g++.dg/modules/clone-5_a.C b/gcc/testsuite/g++.dg/modules/clone-5_a.C
new file mode 100644
index 0000000..4a72e8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/clone-5_a.C
@@ -0,0 +1,25 @@
+// Test that a random instantiation of a constructor template doesn't end up in
+// the overload set for other arguments.
+
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-fmodules" }
+
+export module M;
+
+export {
+ inline int i;
+
+ template <class T>
+ struct A {
+ A(const T* p, unsigned long len) { ++i; }
+ template <class B, class E>
+ requires (!__is_convertible(E,unsigned long))
+ A(B,E) { ++i; }
+ };
+
+ inline void f()
+ {
+ const char *const p = nullptr;
+ A<char> a (p, p); // instantiate A<const char *, const char *>
+ }
+}
diff --git a/gcc/testsuite/g++.dg/modules/clone-5_b.C b/gcc/testsuite/g++.dg/modules/clone-5_b.C
new file mode 100644
index 0000000..f66b465
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/clone-5_b.C
@@ -0,0 +1,9 @@
+// { dg-additional-options -fmodules }
+
+import M;
+
+int main()
+{
+ const char *const p = nullptr;
+ A<char> (p, 0);
+}
diff --git a/gcc/testsuite/g++.dg/modules/convop-2_a.H b/gcc/testsuite/g++.dg/modules/convop-2_a.H
new file mode 100644
index 0000000..62bb210
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/convop-2_a.H
@@ -0,0 +1,10 @@
+// PR c++/122381
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+template <typename T> struct color_ref {
+ operator int() const { return 0; }
+ int foo(color_ref x) {
+ return x.operator int();
+ }
+};
diff --git a/gcc/testsuite/g++.dg/modules/convop-2_b.C b/gcc/testsuite/g++.dg/modules/convop-2_b.C
new file mode 100644
index 0000000..d1e829e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/convop-2_b.C
@@ -0,0 +1,5 @@
+// PR c++/122381
+// { dg-additional-options "-fmodules" }
+
+import "convop-2_a.H";
+template struct color_ref<int>;
diff --git a/gcc/testsuite/g++.dg/modules/inst-6_a.C b/gcc/testsuite/g++.dg/modules/inst-6_a.C
new file mode 100644
index 0000000..7f35cc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/inst-6_a.C
@@ -0,0 +1,14 @@
+// PR c++/122421
+// { dg-additional-options "-fmodules" }
+// { dg-module-cmi M }
+
+export module M;
+
+export template <typename T> struct Type {
+ static const int arr[3];
+};
+
+extern template const int Type<double>::arr[3];
+template <typename T> const int Type<T>::arr[] = { 42, 43, 44 };
+
+export Type<int> ti;
diff --git a/gcc/testsuite/g++.dg/modules/inst-6_b.C b/gcc/testsuite/g++.dg/modules/inst-6_b.C
new file mode 100644
index 0000000..5a8092c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/inst-6_b.C
@@ -0,0 +1,12 @@
+// PR c++/122421
+// { dg-additional-options "-fmodules" }
+
+import M;
+
+int main() {
+ const int& a = Type<int>::arr[0];
+ const int& b = Type<double>::arr[0];
+}
+
+// { dg-final { scan-assembler {_ZNW1M4TypeIiE3arrE:} } }
+// { dg-final { scan-assembler-not {_ZNW1M4TypeIdE3arrE:} } }
diff --git a/gcc/testsuite/g++.dg/modules/internal-16.C b/gcc/testsuite/g++.dg/modules/internal-16.C
new file mode 100644
index 0000000..4a928ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/internal-16.C
@@ -0,0 +1,30 @@
+// PR c++/122253
+// { dg-additional-options "-fmodules -Wtemplate-names-tu-local" }
+
+export module M;
+
+template <int> struct ic {};
+struct S {
+ constexpr operator int() const { return 5; }
+ constexpr int operator&() const { return 8; }
+};
+
+template <typename T> inline void a(T) {
+ T a;
+ static T b;
+ ic<a>{};
+ ic<b>{};
+ ic<&a>{};
+ ic<&b>{};
+}
+
+template <typename T> inline auto b(T x) {
+ return [&](auto y) {
+ return [=](auto z) {
+ return ic<(int)x + (int)&y + (int)z>{};
+ };
+ };
+}
+
+template void a(S);
+ic<5 + 8 + 5> x = b(S{})(S{})(S{});
diff --git a/gcc/testsuite/g++.dg/modules/namespace-15_a.C b/gcc/testsuite/g++.dg/modules/namespace-15_a.C
new file mode 100644
index 0000000..7c0c0e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/namespace-15_a.C
@@ -0,0 +1,9 @@
+// Test that namespace deprecation is represented in the gcm.
+
+// { dg-additional-options "-fmodules" }
+
+export module M;
+
+export {
+ namespace [[deprecated]] N { }
+}
diff --git a/gcc/testsuite/g++.dg/modules/namespace-15_b.C b/gcc/testsuite/g++.dg/modules/namespace-15_b.C
new file mode 100644
index 0000000..5128e82
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/namespace-15_b.C
@@ -0,0 +1,5 @@
+// { dg-additional-options -fmodules }
+
+import M;
+
+using namespace N; // { dg-warning "deprecated" }
diff --git a/gcc/testsuite/g++.target/aarch64/mv-cpu-features.C b/gcc/testsuite/g++.target/aarch64/mv-cpu-features.C
index ad6accd..56e2916 100644
--- a/gcc/testsuite/g++.target/aarch64/mv-cpu-features.C
+++ b/gcc/testsuite/g++.target/aarch64/mv-cpu-features.C
@@ -41,6 +41,14 @@ int impl ()
#define _IFUNC_ARG_HWCAP (1ULL << 62)
#endif
+#ifndef HWCAP_ATOMICS
+#define HWCAP_ATOMICS (1 << 8)
+#endif
+
+#ifndef HWCAP2_RNG
+#define HWCAP2_RNG (1 << 16)
+#endif
+
extern "C" void
__init_cpu_features_resolver (unsigned long hwcap, const ifunc_arg_t *arg);
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-1.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-1.cc
new file mode 100644
index 0000000..69a1350
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-1.cc
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Su2e_1f {
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ float f;
+};
+struct Su2e_1f echo_Su2e_1f(int i, float f, struct Su2e_1f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-2.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-2.cc
new file mode 100644
index 0000000..763477c
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-2.cc
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Su2e_2f {
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ float f;
+ float g;
+};
+struct Su2e_2f echo_Su2e_2f(int i, float f, struct Su2e_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+8 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+8 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-3.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-3.cc
new file mode 100644
index 0000000..5c9ce31
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-3.cc
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smu2e_1f {
+ union {
+ struct {
+ } e1, e2;
+ } u1;
+ struct {
+ float f;
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ } ue;
+ union {
+ struct {
+ } e1, e2;
+ } u2;
+};
+struct Smu2e_1f echo_Smu2e_1f(int i, float f, struct Smu2e_1f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-4.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-4.cc
new file mode 100644
index 0000000..ecefc94
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct+union-4.cc
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smu2e_2f {
+ union {
+ struct {
+ } e1, e2;
+ } u1;
+ struct {
+ float f;
+ float g;
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ } ue;
+ union {
+ struct {
+ } e1, e2;
+ } u2;
+};
+struct Smu2e_2f echo_Smu2e_2f(int i, float f, struct Smu2e_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+8 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+8 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-1.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-1.cc
new file mode 100644
index 0000000..81f563e
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-1.cc
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Se_1f {
+ struct {
+ } e1;
+ float f;
+};
+struct Se_1f echo_Se_1f(int i, float f, struct Se_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-10.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-10.cc
new file mode 100644
index 0000000..167f54c
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-10.cc
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S1ae_2f {
+ struct {
+ } e1[1];
+ float f;
+ float g;
+};
+struct S1ae_2f echo_S1ae_2f(int i, float f, struct S1ae_2f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(mem.*:DI .*\[.* s\+0 .*\]\)[[:space:]]+\(reg.*:DI \d+ a1\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(mem.*:DI .*\[.* s\+8 .*\]\)[[:space:]]+\(reg.*:DI \d+ a2\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:DI \d+ a0 .*\)[[:space:]]+\(subreg:DI \(reg.*:TI \d+ \[ <retval> \]\) 0\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:DI \d+ a1 .*\)[[:space:]]+\(subreg:DI \(reg.*:TI \d+ \[ <retval> \]\) 8\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-11.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-11.cc
new file mode 100644
index 0000000..057994d
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-11.cc
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm1ae_1f {
+ struct {
+ } e1[1];
+ struct {
+ float f;
+ struct {
+ } e[1];
+ } fe;
+ struct {
+ } e2[1];
+};
+struct Sm1ae_1f echo_Sm1ae_1f(int i, float f, struct Sm1ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(mem.*:DI .*\[.* s\+0 .*\]\)[[:space:]]+\(reg.*:DI \d+ a1\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(mem.*:DI .*\[.* s\+8 .*\]\)[[:space:]]+\(reg.*:DI \d+ a2\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:DI \d+ a0 .*\)[[:space:]]+\(subreg:DI \(reg.*:TI \d+ \[ <retval> \]\) 0\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:DI \d+ a1 .*\)[[:space:]]+\(subreg:DI \(reg.*:TI \d+ \[ <retval> \]\) 8\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-12.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-12.cc
new file mode 100644
index 0000000..d8f0154
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-12.cc
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm1ae_2f {
+ struct {
+ } e1[1];
+ struct {
+ float f;
+ float g;
+ struct {
+ } e[1];
+ } fe;
+ struct {
+ } e2[1];
+};
+struct Sm1ae_2f echo_Sm1ae_2f(int i, float f, struct Sm1ae_2f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\[.* \.result_ptr\+0 .*\]} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-2.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-2.cc
new file mode 100644
index 0000000..9d5669c
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-2.cc
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Se_2f {
+ struct {
+ } e1;
+ float f;
+ float g;
+};
+struct Se_2f echo_Se_2f(int i, float f, struct Se_2f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+8 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+8 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-3.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-3.cc
new file mode 100644
index 0000000..7b9e71a
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-3.cc
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sme_1f {
+ struct {
+ } e1;
+ struct {
+ float f;
+ struct {
+ } e;
+ } fe;
+ struct {
+ } e2;
+};
+struct Sme_1f echo_Sme_1f(int i, float f, struct Sme_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-4.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-4.cc
new file mode 100644
index 0000000..aaec892
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-4.cc
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sme_2f {
+ struct {
+ } e1;
+ struct {
+ float f;
+ float g;
+ struct {
+ } e;
+ } fe;
+ struct {
+ } e2;
+};
+struct Sme_2f echo_Sme_2f(int i, float f, struct Sme_2f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+8 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+8 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-5.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-5.cc
new file mode 100644
index 0000000..0ae1e41
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-5.cc
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S0ae_1f {
+ struct {
+ } e1[0];
+ float f;
+};
+struct S0ae_1f echo_S0ae_1f(int i, float f, struct S0ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-6.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-6.cc
new file mode 100644
index 0000000..d3d0b65
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-6.cc
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S0ae_2f {
+ struct {
+ } e1[0];
+ float f;
+ float g;
+};
+struct S0ae_2f echo_S0ae_2f(int i, float f, struct S0ae_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-7.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-7.cc
new file mode 100644
index 0000000..9eae13d
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-7.cc
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm0ae_1f {
+ struct {
+ } e1[0];
+ struct {
+ float f;
+ struct {
+ } e[0];
+ } fe;
+ struct {
+ } e2[0];
+};
+struct Sm0ae_1f echo_Sm0ae_1f(int i, float f, struct Sm0ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-8.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-8.cc
new file mode 100644
index 0000000..e7c81f4
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-8.cc
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm0ae_2f {
+ struct {
+ } e1[0];
+ struct {
+ float f;
+ float g;
+ struct {
+ } e[0];
+ } fe;
+ struct {
+ } e2[0];
+};
+struct Sm0ae_2f echo_Sm0ae_2f(int i, float f, struct Sm0ae_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-struct-9.cc b/gcc/testsuite/g++.target/riscv/abi/empty-struct-9.cc
new file mode 100644
index 0000000..d36d50b
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-struct-9.cc
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S1ae_1f {
+ struct {
+ } e1[1];
+ float f;
+};
+struct S1ae_1f echo_S1ae_1f(int i, float f, struct S1ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(mem.*:DI .*\[.* s\+0 .*\]\)[[:space:]]+\(reg.*:DI \d+ a1\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:DI \d+ a0\)[[:space:]]+\(reg.*:DI \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-union-1.cc b/gcc/testsuite/g++.target/riscv/abi/empty-union-1.cc
new file mode 100644
index 0000000..e3c2376
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-union-1.cc
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Seu_1f {
+ union {
+ } e1;
+ float f;
+};
+struct Seu_1f echo_Seu_1f(int i, float f, struct Seu_1f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-union-2.cc b/gcc/testsuite/g++.target/riscv/abi/empty-union-2.cc
new file mode 100644
index 0000000..d7b7d05
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-union-2.cc
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S2eu_2f {
+ union {
+ } e1;
+ float f;
+ float g;
+};
+struct S2eu_2f echo_S2eu_2f(int i, float f, struct S2eu_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+8 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+8 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-union-3.cc b/gcc/testsuite/g++.target/riscv/abi/empty-union-3.cc
new file mode 100644
index 0000000..f12af7a
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-union-3.cc
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smeu_1f {
+ union {
+ } e1;
+ struct {
+ float f;
+ union {
+ } e;
+ } fe;
+ union {
+ } e2;
+};
+struct Smeu_1f echo_Smeu_1f(int i, float f, struct Smeu_1f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/abi/empty-union-4.cc b/gcc/testsuite/g++.target/riscv/abi/empty-union-4.cc
new file mode 100644
index 0000000..ab8c56e
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/abi/empty-union-4.cc
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smeu_2f {
+ union {
+ } e1;
+ struct {
+ float f;
+ float g;
+ union {
+ } e;
+ } fe;
+ union {
+ } e2;
+};
+struct Smeu_2f echo_Smeu_2f(int i, float f, struct Smeu_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+8 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+8 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/riscv.exp b/gcc/testsuite/g++.target/riscv/riscv.exp
index f58e688..e268bd8 100644
--- a/gcc/testsuite/g++.target/riscv/riscv.exp
+++ b/gcc/testsuite/g++.target/riscv/riscv.exp
@@ -29,6 +29,7 @@ dg-init
# Main loop.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/abi/*.cc]] "" ""
# All done.
dg-finish
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-3-sarif.py b/gcc/testsuite/gcc.dg/analyzer/setjmp-3-sarif.py
new file mode 100644
index 0000000..922d338
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-3-sarif.py
@@ -0,0 +1,23 @@
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_kinds(sarif):
+ result = get_result_by_index(sarif, 0)
+
+ assert result['level'] == 'note'
+
+ events = result["codeFlows"][0]["threadFlows"][0]['locations']
+
+ assert events[1]['location']['message']['text'] == "'setjmp' called here"
+ assert events[1]['kinds'] == ["setjmp"]
+
+ assert events[6]['location']['message']['text'] == "rewinding from 'longjmp' in 'inner'..."
+ assert events[6]['kinds'] == ["longjmp"]
+
+ assert events[7]['location']['message']['text'].startswith("...to 'setjmp' in 'outer'")
+ assert events[7]['kinds'] == ["longjmp"]
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c
index 3e4f870..a19ce84 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c
@@ -1,4 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+/* { dg-additional-options "-fdiagnostics-add-output=sarif" } */
+
/* { dg-enable-nn-line-numbers "" } */
/* { dg-require-effective-target indirect_jumps } */
@@ -107,3 +109,10 @@ void outer (void)
| | (11) here
|
{ dg-end-multiline-output "" } */
+
+/* Verify that some JSON was written to a file with the expected name. */
+/* { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest setjmp-3.c "setjmp-3-sarif.py" } } */
diff --git a/gcc/testsuite/gcc.dg/compat/pr83487-1_x.c b/gcc/testsuite/gcc.dg/compat/pr83487-1_x.c
index b5b208f..22b71cf 100644
--- a/gcc/testsuite/gcc.dg/compat/pr83487-1_x.c
+++ b/gcc/testsuite/gcc.dg/compat/pr83487-1_x.c
@@ -1,4 +1,5 @@
/* { dg-options "-fno-common" { target { hppa*-*-hpux* } } } */
+/* { dg-options "-Wno-psabi" { target { riscv*-*-* } } } */
#include "pr83487-1.h"
extern
diff --git a/gcc/testsuite/gcc.dg/compat/pr83487-1_y.c b/gcc/testsuite/gcc.dg/compat/pr83487-1_y.c
index ad336dd..cf275d8 100644
--- a/gcc/testsuite/gcc.dg/compat/pr83487-1_y.c
+++ b/gcc/testsuite/gcc.dg/compat/pr83487-1_y.c
@@ -1,4 +1,5 @@
/* { dg-options "-fno-common" { target { hppa*-*-hpux* } } } */
+/* { dg-options "-Wno-psabi" { target { riscv*-*-* } } } */
#include "pr83487-1.h"
struct A a;
diff --git a/gcc/testsuite/gcc.dg/compat/pr83487-2_x.c b/gcc/testsuite/gcc.dg/compat/pr83487-2_x.c
index 7103194..399ac86 100644
--- a/gcc/testsuite/gcc.dg/compat/pr83487-2_x.c
+++ b/gcc/testsuite/gcc.dg/compat/pr83487-2_x.c
@@ -1,3 +1,4 @@
/* { dg-options "-fno-common" { target { hppa*-*-hpux* } } } */
+/* { dg-options "-Wno-psabi" { target { riscv*-*-* } } } */
#define PR83487_LARGE
#include "pr83487-1_x.c"
diff --git a/gcc/testsuite/gcc.dg/compat/pr83487-2_y.c b/gcc/testsuite/gcc.dg/compat/pr83487-2_y.c
index e176783..dc6c1f8 100644
--- a/gcc/testsuite/gcc.dg/compat/pr83487-2_y.c
+++ b/gcc/testsuite/gcc.dg/compat/pr83487-2_y.c
@@ -1,3 +1,4 @@
/* { dg-options "-fno-common" { target { hppa*-*-hpux* } } } */
+/* { dg-options "-Wno-psabi" { target { riscv*-*-* } } } */
#define PR83487_LARGE
#include "pr83487-1_y.c"
diff --git a/gcc/testsuite/gcc.dg/fold-vecperm-1.c b/gcc/testsuite/gcc.dg/fold-vecperm-1.c
index 5d4456b..878d392 100644
--- a/gcc/testsuite/gcc.dg/fold-vecperm-1.c
+++ b/gcc/testsuite/gcc.dg/fold-vecperm-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-forwprop3" } */
typedef int v4si __attribute__((vector_size(16)));
typedef short v8hi __attribute__((vector_size(16)));
@@ -20,4 +20,4 @@ int128 concat (int128 a, int128 b) {
return res;
}
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "forwprop3" } } */
diff --git a/gcc/testsuite/gcc.dg/gnu-compoundlit-1.c b/gcc/testsuite/gcc.dg/gnu-compoundlit-1.c
new file mode 100644
index 0000000..a7f3496
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu-compoundlit-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu23" } */
+
+int g(int n, int (*p)[n]);
+int f(int n)
+{
+ return g(n, &(int[n]){ });
+}
+
+void h(int n)
+{
+ (int[n]){ 1 }; /* { dg-error "empty initializer" } */
+}
+
+void i(int n)
+{
+ (static int[3]){ };
+ (static int[n]){ }; /* { dg-error "storage size" } */
+ (constexpr int[3]){ };
+ (constexpr int[n]){ }; /* { dg-error "storage size" } */
+ (register int[3]){ }; /* { dg-error "register" } */
+ (register int[n]){ }; /* { dg-error "register" } */
+ (_Thread_local int[3]){ }; /* { dg-error "_Thread_local" } */
+ (_Thread_local int[n]){ }; /* { dg-error "_Thread_local" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/gnu-compoundlit-2.c b/gcc/testsuite/gcc.dg/gnu-compoundlit-2.c
new file mode 100644
index 0000000..dcc5775
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu-compoundlit-2.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu23 -Wall" } */
+
+[[gnu::noinline,gnu::noipa]]
+static bool f(int n)
+{
+ struct foo { char a[n]; };
+ struct foo x = { };
+
+ return 0 == __builtin_memcmp(&x, &(struct foo){ }, sizeof x);
+}
+
+int main()
+{
+ if (!f(7))
+ __builtin_abort();
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr68090.c b/gcc/testsuite/gcc.dg/pr68090.c
index 87b3b93..84e0ca4 100644
--- a/gcc/testsuite/gcc.dg/pr68090.c
+++ b/gcc/testsuite/gcc.dg/pr68090.c
@@ -1,13 +1,18 @@
/* PR c/68090 */
/* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "--pedantic-error" } */
void
fn (int i)
{
(int[(0, 1)]) { 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int[i]) { 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int[(0, i)]) { 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int [][i]){ 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int [][(1, 2)]){ 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
}
diff --git a/gcc/testsuite/gcc.dg/pr97986-1.c b/gcc/testsuite/gcc.dg/pr97986-1.c
new file mode 100644
index 0000000..87ee3d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97986-1.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu23" } */
+
+#include <stdarg.h>
+
+int f(int n, ...)
+{
+ __label__ b, d;
+ va_list ap;
+ va_start(ap, n);
+ _Static_assert(5 == sizeof(va_arg(ap, char[5]))); /* { dg-warning "array type" } */
+ void g(void) { n++; goto b; }
+ int *a = va_arg((g(), ap), int[n]); /* { dg-warning "array type" } */
+b:
+ void h(void) { n++; goto d; }
+ typeof(va_arg(ap, int[(h(), n)])) c; /* { dg-warning "array type" } */
+d:
+ return n;
+}
+
+int main()
+{
+ if (9 != f(7))
+ __builtin_abort();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr97986-2.c b/gcc/testsuite/gcc.dg/pr97986-2.c
new file mode 100644
index 0000000..fc23a57
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97986-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c90" } */
+
+#include <stdarg.h>
+
+
+int f(int n, ...)
+{
+ va_list ap;
+ va_start(ap, n);
+ _Static_assert(5 == sizeof(va_arg(ap, char[5])));
+ va_arg(ap, int[n]); /* { dg-error "array type" } */
+ int * a = va_arg(ap, int[3]); /* { dg-error "invalid use of non-lvalue array" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/torture/pr28814.c b/gcc/testsuite/gcc.dg/torture/pr28814.c
index cf641ca..e835ff5 100644
--- a/gcc/testsuite/gcc.dg/torture/pr28814.c
+++ b/gcc/testsuite/gcc.dg/torture/pr28814.c
@@ -1,4 +1,5 @@
/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-Wno-psabi" { target { riscv*-*-* } } } */
struct w49
{
diff --git a/gcc/testsuite/gcc.dg/vect/pr122475.c b/gcc/testsuite/gcc.dg/vect/pr122475.c
new file mode 100644
index 0000000..ed229c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr122475.c
@@ -0,0 +1,13 @@
+/* { dg-additional-options "-march=armv8-a+sve" { target aarch64*-*-* } } */
+/* Check that we don't ICE. */
+int a;
+int b;
+int main() {
+ for (char t = 0; t < 14; t += 2)
+ for (int u = 0; u < 242; u += 4) {
+ a = a < 0 ? a : 0;
+ b = b < 0 ? b : 0;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" { target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vla-init-4.c b/gcc/testsuite/gcc.dg/vla-init-4.c
index 06351d0..7d1aa5b 100644
--- a/gcc/testsuite/gcc.dg/vla-init-4.c
+++ b/gcc/testsuite/gcc.dg/vla-init-4.c
@@ -4,4 +4,4 @@
/* { dg-options "" } */
const int i = 1;
-void foo() { char *p = (char [i]){ "" }; } /* { dg-error "compound literal has variable size" } */
+void foo() { char *p = (char [i]){ "" }; } /* { dg-error "variable-sized object" } */
diff --git a/gcc/testsuite/gcc.dg/vla-init-5.c b/gcc/testsuite/gcc.dg/vla-init-5.c
index aa9f491..2c249ec 100644
--- a/gcc/testsuite/gcc.dg/vla-init-5.c
+++ b/gcc/testsuite/gcc.dg/vla-init-5.c
@@ -4,4 +4,4 @@
/* { dg-options "" } */
const int i = 1;
-void foo() { void *p = (char [][i]){ "" }; } /* { dg-error "compound literal has variable size" } */
+void foo() { void *p = (char [][i]){ "" }; } /* { dg-error "variable-sized object" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority.in b/gcc/testsuite/gcc.target/aarch64/fmv_priority.in
index 93209bc..4637369 100644
--- a/gcc/testsuite/gcc.target/aarch64/fmv_priority.in
+++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority.in
@@ -30,10 +30,12 @@ int fn [[gnu::target_version("fp16")]] (int) { return 1; }
int fn_fp16(int) asm("fn._Mfp16");
int fn [[gnu::target_version("fp16fml")]] (int) { return 1; }
int fn_fp16fml(int) asm("fn._Mfp16fml");
-/* TODO: These FMV features are not yet supported in GCC. */
-// int fn [[gnu::target_version("dit")]] (int) { return 1; }
-// int fn [[gnu::target_version("dpb")]] (int) { return 1; }
-// int fn [[gnu::target_version("dpb2")]] (int) { return 1; }
+int fn [[gnu::target_version("dit")]] (int) { return 1; }
+int fn_dit(int) asm("fn._Mdit");
+int fn [[gnu::target_version("dpb")]] (int) { return 1; }
+int fn_dpb(int) asm("fn._Mdpb");
+int fn [[gnu::target_version("dpb2")]] (int) { return 1; }
+int fn_dpb2(int) asm("fn._Mdpb2");
int fn [[gnu::target_version("jscvt")]] (int) { return 1; }
int fn_jscvt(int) asm("fn._Mjscvt");
int fn [[gnu::target_version("fcma")]] (int) { return 1; }
@@ -68,15 +70,14 @@ int fn [[gnu::target_version("sve2-sm4")]] (int) { return 1; }
int fn_sve2_sm4(int) asm("fn._Msve2_sm4");
int fn [[gnu::target_version("sve2+sme")]] (int) { return 1; }
int fn_sve2_sme(int) asm("fn._Msve2Msme");
-/* TODO: This FMV features is not yet supported in GCC. */
-// int fn [[gnu::target_version("memtag")]] (int) { return 1; }
+int fn [[gnu::target_version("memtag")]] (int) { return 1; }
+int fn_memtag(int) asm("fn._Mmemtag");
int fn [[gnu::target_version("sb")]] (int) { return 1; }
int fn_sb(int) asm("fn._Msb");
-/* TODO: This FMV feature is not yet supported in GCC. */
-// int fn [[gnu::target_version("ssbs")]] (int) { return 1; }
-// int fn_ssbs(int) asm("fn._Mssbs");
-/* TODO: This FMV feature is not yet supported in GCC. */
-// int fn [[gnu::target_version("bti")]] (int) { return 1; }
+int fn [[gnu::target_version("ssbs")]] (int) { return 1; }
+int fn_ssbs(int) asm("fn._Mssbs");
+int fn [[gnu::target_version("bti")]] (int) { return 1; }
+int fn_bti(int) asm("fn._Mbti");
int fn [[gnu::target_version("wfxt")]] (int) { return 1; }
int fn_wfxt(int) asm("fn._Mwfxt");
int fn [[gnu::target_version("sve2+sme-f64f64")]] (int) { return 1; }
diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c b/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c
index 942b7a7..6075ccf 100644
--- a/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c
+++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c
@@ -81,14 +81,14 @@ int main () {
if(resolver() != &fn_fp16fml) return 1;
setCPUFeature (FEAT_DIT);
- // if(resolver() != &fn_dit) return 1;
- //
+ if(resolver() != &fn_dit) return 1;
+
setCPUFeature (FEAT_DPB);
- // if(resolver() != &fn_dpb) return 1;
- //
+ if(resolver() != &fn_dpb) return 1;
+
setCPUFeature (FEAT_DPB2);
- // if(resolver() != &fn_dpb2) return 1;
- //
+ if(resolver() != &fn_dpb2) return 1;
+
setCPUFeature (FEAT_JSCVT);
if (resolver () != &fn_jscvt) return 1;
@@ -102,8 +102,8 @@ int main () {
if (resolver () != &fn_rcpc2) return 1;
setCPUFeature (FEAT_RCPC3);
- // if(resolver() != &fn_rcpc3) return 1;
- //
+ if(resolver() != &fn_rcpc3) return 1;
+
setCPUFeature (FEAT_FRINTTS);
if (resolver () != &fn_frintts) return 1;
@@ -141,16 +141,16 @@ int main () {
if (resolver () != &fn_sve2_sme) return 1;
setCPUFeature(FEAT_MEMTAG2);
- // if(resolver() != &fn_memtag) return 1;
+ if(resolver() != &fn_memtag) return 1;
setCPUFeature (FEAT_SB);
if (resolver () != &fn_sb) return 1;
setCPUFeature(FEAT_SSBS2);
- // if(resolver() != &fn_ssbs) return 1;
+ if(resolver() != &fn_ssbs) return 1;
setCPUFeature(FEAT_BTI);
- // if(resolver() != &fn_bti) return 1;
+ if(resolver() != &fn_bti) return 1;
setCPUFeature (FEAT_WFXT);
if (resolver () != &fn_wfxt) return 1;
diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c b/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c
index dbeb15e..9464015 100644
--- a/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c
+++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c
@@ -14,7 +14,9 @@
/* { dg-final { scan-ipa-dump-times "fn\._Msm4/\[0-9\]+\\nfn\._MrdmaMrdm/\[0-9\]+\\nfn\._Mcrc/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Mcrc/\[0-9\]+\\nfn\._Msha2/\[0-9\]+\\nfn\._Msha3/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Msha3/\[0-9\]+\\nfn\._Maes/\[0-9\]+\\nfn\._Mfp16/\[0-9\]+\\n" 1 "targetclone1" } } */
-/* { dg-final { scan-ipa-dump-times "fn\._Mfp16/\[0-9\]+\\nfn\._Mfp16fml/\[0-9\]+\\nfn\._Mjscvt/\[0-9\]+\\n" 1 "targetclone1" } } */
+/* { dg-final { scan-ipa-dump-times "fn\._Mfp16/\[0-9\]+\\nfn\._Mfp16fml/\[0-9\]+\\nfn\._Mdit/\[0-9\]+\\n" 1 "targetclone1" } } */
+/* { dg-final { scan-ipa-dump-times "fn\._Mdit/\[0-9\]+\\nfn\._Mdpb/\[0-9\]+\\nfn\._Mdpb2/\[0-9\]+\\n" 1 "targetclone1" } } */
+/* { dg-final { scan-ipa-dump-times "fn\._Mdpb2/\[0-9\]+\\nfn\._Mjscvt/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Mjscvt/\[0-9\]+\\nfn\._Mfcma/\[0-9\]+\\nfn\._Mrcpc/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Mrcpc/\[0-9\]+\\nfn\._Mrcpc2/\[0-9\]+\\nfn\._Mrcpc3/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Mrcpc3/\[0-9\]+\\nfn\._Mfrintts/\[0-9\]+\\nfn\._Mi8mm/\[0-9\]+\\n" 1 "targetclone1" } } */
@@ -23,7 +25,9 @@
/* { dg-final { scan-ipa-dump-times "fn\._Mf64mm/\[0-9\]+\\nfn\._Msve2/\[0-9\]+\\nfn\._Msve2_aes/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Msve2_aes/\[0-9\]+\\nfn\._Msve2_bitperm/\[0-9\]+\\nfn\._Msve2_sha3/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Msve2_sha3/\[0-9\]+\\nfn\._Msve2_sm4/\[0-9\]+\\nfn\._Msve2Msme/\[0-9\]+\\n" 1 "targetclone1" } } */
-/* { dg-final { scan-ipa-dump-times "fn\._Msve2Msme/\[0-9\]+\\nfn\._Msb/\[0-9\]+\\nfn\._Mwfxt/\[0-9\]+\\n" 1 "targetclone1" } } */
+/* { dg-final { scan-ipa-dump-times "fn\._Msve2Msme/\[0-9\]+\\nfn\._Mmemtag/\[0-9\]+\\nfn\._Msb/\[0-9\]+\\n" 1 "targetclone1" } } */
+/* { dg-final { scan-ipa-dump-times "fn\._Msb/\[0-9\]+\\nfn\._Mssbs/\[0-9\]+\\nfn\._Mbti/\[0-9\]+\\n" 1 "targetclone1" } } */
+/* { dg-final { scan-ipa-dump-times "fn\._Mbti/\[0-9\]+\\nfn\._Mwfxt/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Mwfxt/\[0-9\]+\\nfn\._Msve2Msme_f64f64/\[0-9\]+\\nfn\._Msve2Msme_i16i64/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Msve2Msme_i16i64/\[0-9\]+\\nfn\._Msve2Msme2/\[0-9\]+\\nfn\._Mmops/\[0-9\]+\\n" 1 "targetclone1" } } */
/* { dg-final { scan-ipa-dump-times "fn\._Mmops/\[0-9\]+\\nfn\._Mcssc/\[0-9\]+\\n" 1 "targetclone1" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c
new file mode 100644
index 0000000..6492c44
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mautovec-preference=sve-only -fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */
+
+int p[128];
+
+bool __attribute__((noipa))
+fand (int n, bool r1, bool r2)
+{
+ bool r = true;
+ for (int i = 0; i < (n/2); i+=2)
+ {
+ r &= (p[i] != 0) & r1;
+ r &= (p[i+1] != 0) & r2;
+ }
+ return r;
+}
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c
new file mode 100644
index 0000000..83c5c20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mautovec-preference=sve-only -fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+void vec_slp_cmp (char* restrict a, char* restrict b, int n) {
+ bool x0 = b[0] != 0;
+ bool x1 = b[1] != 0;
+ bool x2 = b[2] != 0;
+ bool x3 = b[3] != 0;
+ for (int i = 0; i < n; ++i) {
+ x0 &= (a[i * 4] != 0);
+ x1 &= (a[i * 4 + 1] != 0);
+ x2 &= (a[i * 4 + 2] != 0);
+ x3 &= (a[i * 4 + 3] != 0);
+ }
+ b[0] = x0;
+ b[1] = x1;
+ b[2] = x2;
+ b[3] = x3;
+}
+
+void vec_slp_cmp1 (char* restrict a, char* restrict b, int n) {
+ bool x0 = b[0] != 0;
+ for (int i = 0; i < n; ++i) {
+ x0 &= (a[i] != 0);
+ }
+ b[0] = x0;
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" { target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movv2hi-be.c b/gcc/testsuite/gcc.target/arc/movv2hi-be.c
new file mode 100644
index 0000000..7d4b8e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movv2hi-be.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+typedef short v2hi __attribute__((vector_size(4)));
+
+__attribute__((noinline)) void foo3(short a)
+{
+ if (a != 520)
+ {
+ __builtin_abort();
+ }
+}
+
+__attribute__((noinline)) void foo2(v2hi v)
+{
+ foo3(v[0]);
+}
+
+__attribute__((noinline)) void foo(v2hi *v)
+{
+ foo2(*v);
+}
+
+int main (void)
+{
+ v2hi v;
+ v[0] = 520;
+ v[1] = -1;
+ foo(&v);
+ foo2(v);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr84211-fuse-move-1.c b/gcc/testsuite/gcc.target/avr/torture/pr84211-fuse-move-1.c
index 82ce227..4924e9d 100644
--- a/gcc/testsuite/gcc.target/avr/torture/pr84211-fuse-move-1.c
+++ b/gcc/testsuite/gcc.target/avr/torture/pr84211-fuse-move-1.c
@@ -1,5 +1,6 @@
/* { dg-do run } */
-/* { dg-additional-options -std=gnu99 } */
+/* Disable LTO since it has problems with flobal asm. */
+/* { dg-additional-options { -std=gnu99 -fno-lto } } */
#define USE_VALUE 0
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr92606.c b/gcc/testsuite/gcc.target/avr/torture/pr92606.c
index a391d7e..99d1ca6 100644
--- a/gcc/testsuite/gcc.target/avr/torture/pr92606.c
+++ b/gcc/testsuite/gcc.target/avr/torture/pr92606.c
@@ -14,10 +14,10 @@ typedef uint32_t T;
{ \
uint16_t __addr16 = (uint16_t)(X); \
uint32_t __result; \
- __asm__ __volatile__ ("lpm %A0, Z+" "\n\t" \
- "lpm %B0, Z+" "\n\t" \
- "lpm %C0, Z+" "\n\t" \
- "lpm %D0, Z" "\n\t" \
+ __asm__ __volatile__ ("lpm $ mov %A0,r0 $ adiw %1,1" "\n\t" \
+ "lpm $ mov %B0,r0 $ adiw %1,1" "\n\t" \
+ "lpm $ mov %C0,r0 $ adiw %1,1" "\n\t" \
+ "lpm $ mov %D0,r0" \
: "=r" (__result), "+z" (__addr16)); \
__result; \
}))
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-10.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-10.c
new file mode 100644
index 0000000..43d6489
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-10.c
@@ -0,0 +1,105 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$63, %rdx
+** ja .L12
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L12:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$128, %rdx
+** jbe .L13
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L6
+** je .L1
+** movdqu -16\(%rax,%rdx\), %xmm7
+** movdqu -32\(%rax,%rdx\), %xmm6
+** movdqu -48\(%rax,%rdx\), %xmm5
+** movdqu -64\(%rax,%rdx\), %xmm4
+**.L7:
+** movdqu \(%rax\), %xmm3
+** subq \$64, %rsi
+** addq \$64, %rcx
+** addq \$64, %rax
+** movdqu -48\(%rax\), %xmm2
+** movdqu -32\(%rax\), %xmm1
+** movdqu -16\(%rax\), %xmm0
+** movups %xmm3, -64\(%rcx\)
+** movups %xmm2, -48\(%rcx\)
+** movups %xmm1, -32\(%rcx\)
+** movups %xmm0, -16\(%rcx\)
+** cmpq \$64, %rsi
+** ja .L7
+** movups %xmm7, -16\(%rdi,%rdx\)
+** movups %xmm6, -32\(%rdi,%rdx\)
+** movups %xmm5, -48\(%rdi,%rdx\)
+** movups %xmm4, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** movdqu \(%rsi\), %xmm7
+** movdqu 16\(%rsi\), %xmm6
+** movdqu 32\(%rsi\), %xmm5
+** movdqu 48\(%rsi\), %xmm4
+** movdqu -16\(%rsi,%rdx\), %xmm3
+** movdqu -32\(%rsi,%rdx\), %xmm2
+** movdqu -48\(%rsi,%rdx\), %xmm1
+** movdqu -64\(%rsi,%rdx\), %xmm0
+** movups %xmm7, \(%rdi\)
+** movups %xmm6, 16\(%rdi\)
+** movups %xmm5, 32\(%rdi\)
+** movups %xmm4, 48\(%rdi\)
+** movups %xmm3, -16\(%rdi,%rdx\)
+** movups %xmm2, -32\(%rdi,%rdx\)
+** movups %xmm1, -48\(%rdi,%rdx\)
+** movups %xmm0, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movdqu \(%rax\), %xmm3
+** movdqu 16\(%rax\), %xmm2
+** leaq \(%rdi,%rdx\), %rcx
+** movdqu 32\(%rax\), %xmm1
+** movdqu 48\(%rax\), %xmm0
+** addq %rdx, %rax
+**.L8:
+** movdqu -16\(%rax\), %xmm7
+** movdqu -32\(%rax\), %xmm6
+** subq \$64, %rsi
+** subq \$64, %rcx
+** movdqu -48\(%rax\), %xmm5
+** movdqu -64\(%rax\), %xmm4
+** subq \$64, %rax
+** movups %xmm7, 48\(%rcx\)
+** movups %xmm6, 32\(%rcx\)
+** movups %xmm5, 16\(%rcx\)
+** movups %xmm4, \(%rcx\)
+** cmpq \$64, %rsi
+** ja .L8
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, 32\(%rdi\)
+** movups %xmm0, 48\(%rdi\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n >= 64)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-11a.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-11a.c
new file mode 100644
index 0000000..3f4e2ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-11a.c
@@ -0,0 +1,79 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_xmm:
+**.LFB0:
+** .cfi_startproc
+** movq %rdi, %rax
+** movl \$512, %edx
+** cmpq %rdi, %rsi
+** jb .L5
+** je .L1
+** movdqu 496\(%rsi\), %xmm7
+** movdqu 480\(%rsi\), %xmm6
+** movdqu 464\(%rsi\), %xmm5
+** movdqu 448\(%rsi\), %xmm4
+**.L6:
+** movdqu \(%rsi\), %xmm3
+** movdqu 16\(%rsi\), %xmm2
+** subl \$64, %edx
+** addq \$64, %rax
+** movdqu 32\(%rsi\), %xmm1
+** movdqu 48\(%rsi\), %xmm0
+** addq \$64, %rsi
+** movups %xmm3, -64\(%rax\)
+** movups %xmm2, -48\(%rax\)
+** movups %xmm1, -32\(%rax\)
+** movups %xmm0, -16\(%rax\)
+** cmpl \$64, %edx
+** ja .L6
+** movups %xmm7, 496\(%rdi\)
+** movups %xmm6, 480\(%rdi\)
+** movups %xmm5, 464\(%rdi\)
+** movups %xmm4, 448\(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movdqu \(%rsi\), %xmm7
+** movdqu 16\(%rsi\), %xmm6
+** leaq 512\(%rdi\), %rax
+** addq \$512, %rsi
+** movdqu -480\(%rsi\), %xmm5
+** movdqu -464\(%rsi\), %xmm4
+**.L7:
+** movdqu -16\(%rsi\), %xmm3
+** subl \$64, %edx
+** subq \$64, %rax
+** subq \$64, %rsi
+** movdqu 32\(%rsi\), %xmm2
+** movdqu 16\(%rsi\), %xmm1
+** movdqu \(%rsi\), %xmm0
+** movups %xmm3, 48\(%rax\)
+** movups %xmm2, 32\(%rax\)
+** movups %xmm1, 16\(%rax\)
+** movups %xmm0, \(%rax\)
+** cmpl \$64, %edx
+** ja .L7
+** movups %xmm7, \(%rdi\)
+** movups %xmm6, 16\(%rdi\)
+** movups %xmm5, 32\(%rdi\)
+** movups %xmm4, 48\(%rdi\)
+**.L1:
+** ret
+** .cfi_endproc
+**...
+*/
+
+#ifndef gcc_memmove
+#define gcc_memmove gcc_memmove_xmm
+#endif
+
+void
+gcc_memmove (void *a, void *b)
+{
+ __builtin_memmove (a, b, 512);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-11b.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-11b.c
new file mode 100644
index 0000000..031dd12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-11b.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx512f -march=x86-64-v3 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_ymm:
+**.LFB0:
+** .cfi_startproc
+** movq %rdi, %rax
+** movl \$512, %edx
+** cmpq %rdi, %rsi
+** jb .L5
+** je .L10
+** vmovdqu 480\(%rsi\), %ymm7
+** vmovdqu 448\(%rsi\), %ymm6
+** vmovdqu 416\(%rsi\), %ymm5
+** vmovdqu 384\(%rsi\), %ymm4
+**.L6:
+** vmovdqu \(%rsi\), %ymm3
+** vmovdqu 32\(%rsi\), %ymm2
+** addl \$-128, %edx
+** subq \$-128, %rax
+** vmovdqu 64\(%rsi\), %ymm1
+** vmovdqu 96\(%rsi\), %ymm0
+** subq \$-128, %rsi
+** vmovdqu %ymm3, -128\(%rax\)
+** vmovdqu %ymm2, -96\(%rax\)
+** vmovdqu %ymm1, -64\(%rax\)
+** vmovdqu %ymm0, -32\(%rax\)
+** cmpl \$128, %edx
+** ja .L6
+** vmovdqu %ymm7, 480\(%rdi\)
+** vmovdqu %ymm6, 448\(%rdi\)
+** vmovdqu %ymm5, 416\(%rdi\)
+** vmovdqu %ymm4, 384\(%rdi\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** vmovdqu \(%rsi\), %ymm7
+** vmovdqu 32\(%rsi\), %ymm6
+** leaq 512\(%rdi\), %rax
+** addq \$512, %rsi
+** vmovdqu -448\(%rsi\), %ymm5
+** vmovdqu -416\(%rsi\), %ymm4
+**.L7:
+** vmovdqu -32\(%rsi\), %ymm3
+** addl \$-128, %edx
+** addq \$-128, %rax
+** addq \$-128, %rsi
+** vmovdqu 64\(%rsi\), %ymm2
+** vmovdqu 32\(%rsi\), %ymm1
+** vmovdqu \(%rsi\), %ymm0
+** vmovdqu %ymm3, 96\(%rax\)
+** vmovdqu %ymm2, 64\(%rax\)
+** vmovdqu %ymm1, 32\(%rax\)
+** vmovdqu %ymm0, \(%rax\)
+** cmpl \$128, %edx
+** ja .L7
+** vmovdqu %ymm7, \(%rdi\)
+** vmovdqu %ymm6, 32\(%rdi\)
+** vmovdqu %ymm5, 64\(%rdi\)
+** vmovdqu %ymm4, 96\(%rdi\)
+** vzeroupper
+**.L10:
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_ymm
+#include "builtin-memmove-11a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-11c.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-11c.c
new file mode 100644
index 0000000..9c5e2c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-11c.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mmove-max=512 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_zmm:
+**.LFB0:
+** .cfi_startproc
+** vmovdqu64 \(%(e|r)si\), %zmm7
+** vmovdqu64 64\(%(e|r)si\), %zmm6
+** vmovdqu64 128\(%(e|r)si\), %zmm5
+** vmovdqu64 192\(%(e|r)si\), %zmm4
+** vmovdqu64 256\(%(e|r)si\), %zmm3
+** vmovdqu64 320\(%(e|r)si\), %zmm2
+** vmovdqu64 384\(%(e|r)si\), %zmm1
+** vmovdqu64 448\(%(e|r)si\), %zmm0
+** vmovdqu64 %zmm7, \(%(e|r)di\)
+** vmovdqu64 %zmm6, 64\(%(e|r)di\)
+** vmovdqu64 %zmm5, 128\(%(e|r)di\)
+** vmovdqu64 %zmm4, 192\(%(e|r)di\)
+** vmovdqu64 %zmm3, 256\(%(e|r)di\)
+** vmovdqu64 %zmm2, 320\(%(e|r)di\)
+** vmovdqu64 %zmm1, 384\(%(e|r)di\)
+** vmovdqu64 %zmm0, 448\(%(e|r)di\)
+** vzeroupper
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_zmm
+#include "builtin-memmove-11a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-12.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-12.c
new file mode 100644
index 0000000..270df03
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-12.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**foo:
+**.LFB0:
+** .cfi_startproc
+** movdqu a\+20\(%rip\), %xmm5
+** movdqu a\+36\(%rip\), %xmm4
+** movdqu a\+52\(%rip\), %xmm3
+** movdqu a\+68\(%rip\), %xmm2
+** movdqu a\+84\(%rip\), %xmm1
+** movdqu a\+100\(%rip\), %xmm0
+** movups %xmm5, a\+24\(%rip\)
+** movq a\+116\(%rip\), %rax
+** movdqu a\+4\(%rip\), %xmm6
+** movups %xmm4, a\+40\(%rip\)
+** movl %edi, a\+4\(%rip\)
+** movq %rax, a\+120\(%rip\)
+** movups %xmm6, a\+8\(%rip\)
+** movups %xmm3, a\+56\(%rip\)
+** movups %xmm2, a\+72\(%rip\)
+** movups %xmm1, a\+88\(%rip\)
+** movups %xmm0, a\+104\(%rip\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define N 32
+
+int a[N];
+
+void
+foo (int x)
+{
+ __builtin_memmove (a + 2, a + 1, sizeof a - 2 * sizeof *a);
+ a[1] = x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-13.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-13.c
new file mode 100644
index 0000000..1c71cce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-13.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**foo:
+**.LFB0:
+** .cfi_startproc
+** movl a\+3\(%rip\), %eax
+** movl %eax, a\(%rip\)
+** movzbl a\+7\(%rip\), %eax
+** movb %al, a\+4\(%rip\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+char a[8] = "12345678";
+
+void
+foo (void)
+{
+ __builtin_memmove (a, a + 3, sizeof a - 3);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-14.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-14.c
new file mode 100644
index 0000000..009c61d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-14.c
@@ -0,0 +1,90 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$64, %rdx
+** jbe .L12
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L12:
+** cmpl \$16, %edx
+** jnb .L13
+** cmpl \$8, %edx
+** jnb .L6
+** cmpl \$4, %edx
+** jnb .L7
+** cmpl \$1, %edx
+** ja .L8
+** jb .L1
+** movzbl \(%rsi\), %eax
+** movb %al, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** cmpl \$32, %edx
+** ja .L5
+** movl %edx, %edx
+** movdqu \(%rsi\), %xmm1
+** movdqu -16\(%rsi,%rdx\), %xmm0
+** movups %xmm1, \(%rdi\)
+** movups %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movl %edx, %edx
+** movdqu \(%rsi\), %xmm3
+** movdqu 16\(%rsi\), %xmm2
+** addq %rdx, %rsi
+** movdqu -16\(%rsi\), %xmm1
+** movdqu -32\(%rsi\), %xmm0
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, -16\(%rdi,%rdx\)
+** movups %xmm0, -32\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movl %edx, %edx
+** movq \(%rsi\), %rcx
+** movq -8\(%rsi,%rdx\), %rax
+** movq %rcx, \(%rdi\)
+** movq %rax, -8\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movl %edx, %edx
+** movl \(%rsi\), %ecx
+** movl -4\(%rsi,%rdx\), %eax
+** movl %ecx, \(%rdi\)
+** movl %eax, -4\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** movl %edx, %edx
+** movzwl \(%rsi\), %ecx
+** movzwl -2\(%rsi,%rdx\), %eax
+** movw %cx, \(%rdi\)
+** movw %ax, -2\(%rdi,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n <= 64)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-15.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-15.c
new file mode 100644
index 0000000..c1ccf44
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-15.c
@@ -0,0 +1,114 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$66, %rdx
+** jbe .L12
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L12:
+** cmpl \$16, %edx
+** jnb .L13
+** cmpl \$8, %edx
+** jnb .L6
+** cmpl \$4, %edx
+** jnb .L7
+** cmpl \$1, %edx
+** ja .L8
+** jb .L1
+** movzbl \(%rsi\), %eax
+** movb %al, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** cmpl \$32, %edx
+** ja .L5
+** movl %edx, %edx
+** movdqu \(%rsi\), %xmm1
+** movdqu -16\(%rsi,%rdx\), %xmm0
+** movups %xmm1, \(%rdi\)
+** movups %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** cmpl \$64, %edx
+** jnb .L14
+** movl %edx, %edx
+** movdqu \(%rsi\), %xmm3
+** movdqu 16\(%rsi\), %xmm2
+** addq %rdx, %rsi
+** movdqu -16\(%rsi\), %xmm1
+** movdqu -32\(%rsi\), %xmm0
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, -16\(%rdi,%rdx\)
+** movups %xmm0, -32\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movl %edx, %edx
+** movq \(%rsi\), %rcx
+** movq -8\(%rsi,%rdx\), %rax
+** movq %rcx, \(%rdi\)
+** movq %rax, -8\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L14:
+** movl %edx, %edx
+** movdqu \(%rsi\), %xmm7
+** movdqu 16\(%rsi\), %xmm6
+** movdqu 32\(%rsi\), %xmm5
+** movdqu 48\(%rsi\), %xmm4
+** addq %rdx, %rsi
+** movdqu -16\(%rsi\), %xmm3
+** movdqu -32\(%rsi\), %xmm2
+** movdqu -48\(%rsi\), %xmm1
+** movdqu -64\(%rsi\), %xmm0
+** movups %xmm7, \(%rdi\)
+** movups %xmm6, 16\(%rdi\)
+** movups %xmm5, 32\(%rdi\)
+** movups %xmm4, 48\(%rdi\)
+** movups %xmm3, -16\(%rdi,%rdx\)
+** movups %xmm2, -32\(%rdi,%rdx\)
+** movups %xmm1, -48\(%rdi,%rdx\)
+** movups %xmm0, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movl %edx, %edx
+** movl \(%rsi\), %ecx
+** movl -4\(%rsi,%rdx\), %eax
+** movl %ecx, \(%rdi\)
+** movl %eax, -4\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** movl %edx, %edx
+** movzwl \(%rsi\), %ecx
+** movzwl -2\(%rsi,%rdx\), %eax
+** movw %cx, \(%rdi\)
+** movw %ax, -2\(%rdi,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n <= 66)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-1a.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-1a.c
new file mode 100644
index 0000000..3459875
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-1a.c
@@ -0,0 +1,123 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } {^\t?\.} } } */
+
+/*
+**memmove7:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movl \(%(?:r|e)si\), %edx
+** movl 3\(%(?:r|e)si\), %eax
+** movl %edx, \(%(?:r|e)di\)
+** movl %eax, 3\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove13:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq \(%(?:r|e)si\), %rdx
+** movq 5\(%(?:r|e)si\), %rax
+** movq %rdx, \(%(?:r|e)di\)
+** movq %rax, 5\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove31:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movdqu \(%(?:r|e)si\), %xmm1
+** movdqu 15\(%(?:r|e)si\), %xmm0
+** movups %xmm1, \(%(?:r|e)di\)
+** movups %xmm0, 15\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove39:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movdqu \(%(?:r|e)si\), %xmm1
+** movdqu 16\(%(?:r|e)si\), %xmm0
+** movq 31\(%(?:r|e)si\), %rax
+** movups %xmm0, 16\(%(?:r|e)di\)
+** movups %xmm1, \(%(?:r|e)di\)
+** movq %rax, 31\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove61:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movdqu \(%(?:r|e)si\), %xmm3
+** movdqu 16\(%(?:r|e)si\), %xmm2
+** movdqu 32\(%(?:r|e)si\), %xmm1
+** movdqu 45\(%(?:r|e)si\), %xmm0
+** movups %xmm3, \(%(?:r|e)di\)
+** movups %xmm1, 32\(%(?:r|e)di\)
+** movups %xmm2, 16\(%(?:r|e)di\)
+** movups %xmm0, 45\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove69:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movdqu \(%(?:r|e)si\), %xmm3
+** movdqu 16\(%(?:r|e)si\), %xmm2
+** movdqu 32\(%(?:r|e)si\), %xmm1
+** movdqu 48\(%(?:r|e)si\), %xmm0
+** movq 61\(%(?:r|e)si\), %rax
+** movups %xmm3, \(%(?:r|e)di\)
+** movups %xmm0, 48\(%(?:r|e)di\)
+** movups %xmm2, 16\(%(?:r|e)di\)
+** movq %rax, 61\(%(?:r|e)di\)
+** movups %xmm1, 32\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove93:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movdqu \(%(?:r|e)si\), %xmm5
+** movdqu 16\(%(?:r|e)si\), %xmm4
+** movdqu 32\(%(?:r|e)si\), %xmm3
+** movdqu 48\(%(?:r|e)si\), %xmm2
+** movdqu 64\(%(?:r|e)si\), %xmm1
+** movdqu 77\(%(?:r|e)si\), %xmm0
+** movups %xmm5, \(%(?:r|e)di\)
+** movups %xmm4, 16\(%(?:r|e)di\)
+** movups %xmm1, 64\(%(?:r|e)di\)
+** movups %xmm3, 32\(%(?:r|e)di\)
+** movups %xmm2, 48\(%(?:r|e)di\)
+** movups %xmm0, 77\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+#define TEST(n) \
+ void \
+ memmove##n (void *a, void *b) \
+ { \
+ __builtin_memmove (a, b, n); \
+ }
+
+TEST (7)
+TEST (13)
+TEST (31)
+TEST (39)
+TEST (61)
+TEST (69)
+TEST (93)
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-1b.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-1b.c
new file mode 100644
index 0000000..25d008c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-1b.c
@@ -0,0 +1,98 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx512f -march=x86-64-v3 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } {^\t?\.} } } */
+
+/*
+**memmove7:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movl \(%(?:r|e)si\), %edx
+** movl 3\(%(?:r|e)si\), %eax
+** movl %edx, \(%(?:r|e)di\)
+** movl %eax, 3\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove13:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq \(%(?:r|e)si\), %rdx
+** movq 5\(%(?:r|e)si\), %rax
+** movq %rdx, \(%(?:r|e)di\)
+** movq %rax, 5\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove31:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu \(%(?:r|e)si\), %xmm1
+** vmovdqu 15\(%(?:r|e)si\), %xmm0
+** vmovdqu %xmm1, \(%(?:r|e)di\)
+** vmovdqu %xmm0, 15\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove39:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu \(%(?:r|e)si\), %ymm0
+** movq 31\(%(?:r|e)si\), %rax
+** vmovdqu %ymm0, \(%(?:r|e)di\)
+** movq %rax, 31\(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+/*
+**memmove61:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu \(%(?:r|e)si\), %ymm1
+** vmovdqu 29\(%(?:r|e)si\), %ymm0
+** vmovdqu %ymm1, \(%(?:r|e)di\)
+** vmovdqu %ymm0, 29\(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+/*
+**memmove69:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu 32\(%(?:r|e)si\), %ymm0
+** movq 61\(%(?:r|e)si\), %rax
+** vmovdqu \(%(?:r|e)si\), %ymm1
+** vmovdqu %ymm0, 32\(%(?:r|e)di\)
+** movq %rax, 61\(%(?:r|e)di\)
+** vmovdqu %ymm1, \(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+/*
+**memmove93:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu \(%(?:r|e)si\), %ymm2
+** vmovdqu 32\(%(?:r|e)si\), %ymm1
+** vmovdqu 61\(%(?:r|e)si\), %ymm0
+** vmovdqu %ymm1, 32\(%(?:r|e)di\)
+** vmovdqu %ymm2, \(%(?:r|e)di\)
+** vmovdqu %ymm0, 61\(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+#include "builtin-memmove-1a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-1c.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-1c.c
new file mode 100644
index 0000000..9eb9a39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-1c.c
@@ -0,0 +1,94 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mmove-max=512 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } {^\t?\.} } } */
+
+/*
+**memmove7:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movl \(%(?:r|e)si\), %edx
+** movl 3\(%(?:r|e)si\), %eax
+** movl %edx, \(%(?:r|e)di\)
+** movl %eax, 3\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove13:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq \(%(?:r|e)si\), %rdx
+** movq 5\(%(?:r|e)si\), %rax
+** movq %rdx, \(%(?:r|e)di\)
+** movq %rax, 5\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove31:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu \(%(?:r|e)si\), %xmm1
+** vmovdqu 15\(%(?:r|e)si\), %xmm0
+** vmovdqu %xmm1, \(%(?:r|e)di\)
+** vmovdqu %xmm0, 15\(%(?:r|e)di\)
+** ret
+**...
+*/
+
+/*
+**memmove39:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu \(%(?:r|e)si\), %ymm0
+** movq 31\(%(?:r|e)si\), %rax
+** vmovdqu %ymm0, \(%(?:r|e)di\)
+** movq %rax, 31\(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+/*
+**memmove61:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu \(%(?:r|e)si\), %ymm1
+** vmovdqu 29\(%(?:r|e)si\), %ymm0
+** vmovdqu %ymm1, \(%(?:r|e)di\)
+** vmovdqu %ymm0, 29\(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+/*
+**memmove69:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu64 \(%(?:r|e)si\), %zmm0
+** movq 61\(%(?:r|e)si\), %rax
+** vmovdqu64 %zmm0, \(%(?:r|e)di\)
+** movq %rax, 61\(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+/*
+**memmove93:
+**.LFB[0-9]+:
+** .cfi_startproc
+** vmovdqu64 \(%(?:r|e)si\), %zmm1
+** vmovdqu 61\(%(?:r|e)si\), %ymm0
+** vmovdqu64 %zmm1, \(%(?:r|e)di\)
+** vmovdqu %ymm0, 61\(%(?:r|e)di\)
+** vzeroupper
+** ret
+**...
+*/
+
+#include "builtin-memmove-1a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-1d.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-1d.c
new file mode 100644
index 0000000..ffa7575
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-1d.c
@@ -0,0 +1,226 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mgeneral-regs-only -march=x86-64 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**memmove7:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movl \(%rsi\), %edx
+** movl 3\(%rsi\), %eax
+** movl %edx, \(%rdi\)
+** movl %eax, 3\(%rdi\)
+** ret
+**...
+*/
+
+/*
+**memmove13:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq \(%rsi\), %rdx
+** movq 5\(%rsi\), %rax
+** movq %rdx, \(%rdi\)
+** movq %rax, 5\(%rdi\)
+** ret
+**...
+*/
+
+/*
+**memmove31:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq \(%(e|r)si\), %r8
+** movq 8\(%(e|r)si\), %rcx
+** movq 16\(%(e|r)si\), %rdx
+** movq 23\(%(e|r)si\), %rax
+** movq %r8, \(%(e|r)di\)
+** movq %rdx, 16\(%(e|r)di\)
+** movq %rcx, 8\(%(e|r)di\)
+** movq %rax, 23\(%(e|r)di\)
+** ret
+**...
+*/
+
+/*
+**memmove39:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq \(%rsi\), %r9
+** movq 8\(%rsi\), %r8
+** movq 16\(%rsi\), %rcx
+** movq 24\(%rsi\), %rdx
+** movq 31\(%rsi\), %rax
+** movq %r9, \(%rdi\)
+** movq %rdx, 24\(%rdi\)
+** movq %r8, 8\(%rdi\)
+** movq %rcx, 16\(%rdi\)
+** movq %rax, 31\(%rdi\)
+** ret
+**...
+*/
+
+/*
+**memmove61:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq 8\(%rsi\), %r11
+** movq 16\(%rsi\), %r10
+** pushq %rbx
+** .cfi_def_cfa_offset 16
+** .cfi_offset 3, -16
+** movq 24\(%rsi\), %r9
+** movq \(%rsi\), %rbx
+** movq 32\(%rsi\), %r8
+** movq 40\(%rsi\), %rcx
+** movq 48\(%rsi\), %rdx
+** movq 53\(%rsi\), %rax
+** movq %rbx, \(%rdi\)
+** movq %r11, 8\(%rdi\)
+** popq %rbx
+** .cfi_def_cfa_offset 8
+** movq %rdx, 48\(%rdi\)
+** movq %r10, 16\(%rdi\)
+** movq %r9, 24\(%rdi\)
+** movq %r8, 32\(%rdi\)
+** movq %rcx, 40\(%rdi\)
+** movq %rax, 53\(%rdi\)
+** ret
+**...
+*/
+
+/*
+**memmove69:
+**.LFB5:
+** .cfi_startproc
+** movq 16\(%rsi\), %r11
+** movq 24\(%rsi\), %r10
+** pushq %rbp
+** .cfi_def_cfa_offset 16
+** .cfi_offset 6, -16
+** movq 32\(%rsi\), %r9
+** movq \(%rsi\), %rbp
+** pushq %rbx
+** .cfi_def_cfa_offset 24
+** .cfi_offset 3, -24
+** movq 40\(%rsi\), %r8
+** movq 8\(%rsi\), %rbx
+** movq 48\(%rsi\), %rcx
+** movq 56\(%rsi\), %rdx
+** movq 61\(%rsi\), %rax
+** movq %rbp, \(%rdi\)
+** movq %rbx, 8\(%rdi\)
+** popq %rbx
+** .cfi_def_cfa_offset 16
+** movq %rdx, 56\(%rdi\)
+** popq %rbp
+** .cfi_def_cfa_offset 8
+** movq %r11, 16\(%rdi\)
+** movq %r10, 24\(%rdi\)
+** movq %r9, 32\(%rdi\)
+** movq %r8, 40\(%rdi\)
+** movq %rcx, 48\(%rdi\)
+** movq %rax, 61\(%rdi\)
+** ret
+**...
+*/
+
+/*
+**memmove93:
+**.LFB[0-9]+:
+** .cfi_startproc
+** sub(l|q) \$24, %(e|r)sp
+** .cfi_def_cfa_offset 32
+** mov(l|q) %(e|r)si, %(e|r)ax
+** movl \$93, %ecx
+** cmp(l|q) %(e|r)di, %(e|r)si
+** jb .L14
+** je .L10
+** movq %rbx, \(%(e|r)sp\)
+** mov(l|q) %(e|r)di, %(e|r)dx
+** movq %r14, 8\(%(e|r)sp\)
+** movq %r15, 16\(%(e|r)sp\)
+** .cfi_offset 3, -32
+** .cfi_offset 14, -24
+** .cfi_offset 15, -16
+** movq 85\(%(e|r)si\), %r14
+** movq 77\(%(e|r)si\), %r15
+** movq 69\(%(e|r)si\), %r10
+** movq 61\(%(e|r)si\), %r11
+**.L15:
+** movq 8\(%(e|r)ax\), %r9
+** movq 16\(%(e|r)ax\), %r8
+** subl \$32, %ecx
+** add(l|q) \$32, %(e|r)dx
+** movq 24\(%(e|r)ax\), %rsi
+** movq \(%(e|r)ax\), %rbx
+** add(l|q) \$32, %(e|r)ax
+** movq %r9, -24\(%(e|r)dx\)
+** movq %rbx, -32\(%(e|r)dx\)
+** movq %r8, -16\(%(e|r)dx\)
+** movq %rsi, -8\(%(e|r)dx\)
+** cmpl \$32, %ecx
+** ja .L15
+** movq %r10, 69\(%(e|r)di\)
+** movq \(%(e|r)sp\), %rbx
+** .cfi_restore 3
+** movq %r11, 61\(%(e|r)di\)
+** movq %r14, 85\(%(e|r)di\)
+** movq 8\(%(e|r)sp\), %r14
+** .cfi_restore 14
+** movq %r15, 77\(%(e|r)di\)
+** movq 16\(%(e|r)sp\), %r15
+** .cfi_restore 15
+**.L10:
+** add(l|q) \$24, %(e|r)sp
+** .cfi_remember_state
+** .cfi_def_cfa_offset 8
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L14:
+** .cfi_restore_state
+** movq %rbx, \(%(e|r)sp\)
+** lea(l|q) 93\(%(e|r)di\), %(e|r)dx
+** add(l|q) \$93, %(e|r)ax
+** movq %r14, 8\(%(e|r)sp\)
+** movq %r15, 16\(%(e|r)sp\)
+** .cfi_offset 3, -32
+** .cfi_offset 14, -24
+** .cfi_offset 15, -16
+** movq \(%(e|r)si\), %r14
+** movq 8\(%(e|r)si\), %r15
+** movq 16\(%(e|r)si\), %r10
+** movq 24\(%(e|r)si\), %r11
+**.L16:
+** movq -16\(%(e|r)ax\), %r9
+** movq -24\(%(e|r)ax\), %r8
+** subl \$32, %ecx
+** sub(l|q) \$32, %(e|r)dx
+** movq -32\(%(e|r)ax\), %rsi
+** movq -8\(%(e|r)ax\), %rbx
+** sub(l|q) \$32, %(e|r)ax
+** movq %r9, 16\(%(e|r)dx\)
+** movq %rbx, 24\(%(e|r)dx\)
+** movq %r8, 8\(%(e|r)dx\)
+** movq %rsi, \(%(e|r)dx\)
+** cmpl \$32, %ecx
+** ja .L16
+** movq %r14, \(%(e|r)di\)
+** movq \(%(e|r)sp\), %rbx
+** .cfi_restore 3
+** movq %r15, 8\(%(e|r)di\)
+** movq 8\(%(e|r)sp\), %r14
+** .cfi_restore 14
+** movq %r10, 16\(%(e|r)di\)
+** movq 16\(%(e|r)sp\), %r15
+** .cfi_restore 15
+** movq %r11, 24\(%(e|r)di\)
+** add(l|q) \$24, %(e|r)sp
+** .cfi_def_cfa_offset 8
+** ret
+**...
+*/
+
+#include "builtin-memmove-1a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-2a.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-2a.c
new file mode 100644
index 0000000..0a7e704
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-2a.c
@@ -0,0 +1,165 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_xmm:
+**.LFB0:
+** .cfi_startproc
+** movq %rdi, %rax
+** movq %rsi, %rcx
+** cmpq \$16, %rdx
+** jb .L3
+** cmpq \$32, %rdx
+** jbe .L17
+** cmpq \$128, %rdx
+** jbe .L18
+** movq %rdx, %rsi
+** cmpq %rdi, %rcx
+** jb .L11
+** je .L2
+** movdqu -16\(%rcx,%rdx\), %xmm7
+** movdqu -32\(%rcx,%rdx\), %xmm6
+** movdqu -48\(%rcx,%rdx\), %xmm5
+** movdqu -64\(%rcx,%rdx\), %xmm4
+**.L12:
+** movdqu \(%rcx\), %xmm3
+** subq \$64, %rsi
+** addq \$64, %rdi
+** addq \$64, %rcx
+** movdqu -48\(%rcx\), %xmm2
+** movdqu -32\(%rcx\), %xmm1
+** movdqu -16\(%rcx\), %xmm0
+** movups %xmm3, -64\(%rdi\)
+** movups %xmm2, -48\(%rdi\)
+** movups %xmm1, -32\(%rdi\)
+** movups %xmm0, -16\(%rdi\)
+** cmpq \$64, %rsi
+** ja .L12
+** movups %xmm7, -16\(%rax,%rdx\)
+** movups %xmm6, -32\(%rax,%rdx\)
+** movups %xmm5, -48\(%rax,%rdx\)
+** movups %xmm4, -64\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L3:
+** cmpq \$8, %rdx
+** jb .L19
+** movq \(%rsi\), %rdi
+** movq -8\(%rsi,%rdx\), %rcx
+** movq %rdi, \(%rax\)
+** movq %rcx, -8\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L19:
+** cmpq \$4, %rdx
+** jnb .L6
+** cmpq \$1, %rdx
+** ja .L7
+** jb .L2
+** movzbl \(%rsi\), %edx
+** movb %dl, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L17:
+** movdqu \(%rsi\), %xmm1
+** movdqu -16\(%rsi,%rdx\), %xmm0
+** movups %xmm1, \(%rdi\)
+** movups %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L18:
+** cmpq \$64, %rdx
+** jb .L10
+** movdqu \(%rsi\), %xmm7
+** movdqu 16\(%rsi\), %xmm6
+** movdqu 32\(%rsi\), %xmm5
+** movdqu 48\(%rsi\), %xmm4
+** movdqu -16\(%rsi,%rdx\), %xmm3
+** movdqu -32\(%rsi,%rdx\), %xmm2
+** movdqu -48\(%rsi,%rdx\), %xmm1
+** movdqu -64\(%rsi,%rdx\), %xmm0
+** movups %xmm7, \(%rdi\)
+** movups %xmm6, 16\(%rdi\)
+** movups %xmm5, 32\(%rdi\)
+** movups %xmm4, 48\(%rdi\)
+** movups %xmm3, -16\(%rdi,%rdx\)
+** movups %xmm2, -32\(%rdi,%rdx\)
+** movups %xmm1, -48\(%rdi,%rdx\)
+** movups %xmm0, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movl \(%rsi\), %edi
+** movl -4\(%rsi,%rdx\), %ecx
+** movl %edi, \(%rax\)
+** movl %ecx, -4\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L11:
+** movdqu \(%rcx\), %xmm7
+** movdqu 16\(%rcx\), %xmm6
+** leaq \(%rdi,%rdx\), %rdi
+** movdqu 32\(%rcx\), %xmm5
+** movdqu 48\(%rcx\), %xmm4
+** addq %rdx, %rcx
+**.L13:
+** movdqu -16\(%rcx\), %xmm3
+** movdqu -32\(%rcx\), %xmm2
+** subq \$64, %rsi
+** subq \$64, %rdi
+** movdqu -48\(%rcx\), %xmm1
+** movdqu -64\(%rcx\), %xmm0
+** subq \$64, %rcx
+** movups %xmm3, 48\(%rdi\)
+** movups %xmm2, 32\(%rdi\)
+** movups %xmm1, 16\(%rdi\)
+** movups %xmm0, \(%rdi\)
+** cmpq \$64, %rsi
+** ja .L13
+** movups %xmm7, \(%rax\)
+** movups %xmm6, 16\(%rax\)
+** movups %xmm5, 32\(%rax\)
+** movups %xmm4, 48\(%rax\)
+**.L2:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L10:
+** movdqu \(%rsi\), %xmm3
+** movdqu 16\(%rsi\), %xmm2
+** movdqu -16\(%rsi,%rdx\), %xmm1
+** movdqu -32\(%rsi,%rdx\), %xmm0
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, -16\(%rdi,%rdx\)
+** movups %xmm0, -32\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movzwl \(%rsi\), %edi
+** movzwl -2\(%rsi,%rdx\), %ecx
+** movw %di, \(%rax\)
+** movw %cx, -2\(%rax,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+#ifndef gcc_memmove
+#define gcc_memmove gcc_memmove_xmm
+#endif
+
+void *
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ return __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-2b.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-2b.c
new file mode 100644
index 0000000..0596ca7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-2b.c
@@ -0,0 +1,173 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx512f -march=x86-64-v3 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_ymm:
+**.LFB0:
+** .cfi_startproc
+** movq %rdi, %rax
+** movq %rsi, %rcx
+** cmpq \$32, %rdx
+** jb .L3
+** cmpq \$64, %rdx
+** jbe .L18
+** cmpq \$256, %rdx
+** jbe .L19
+** movq %rdx, %rsi
+** cmpq %rdi, %rcx
+** jb .L12
+** je .L2
+** vmovdqu -32\(%rcx,%rdx\), %ymm7
+** vmovdqu -64\(%rcx,%rdx\), %ymm6
+** vmovdqu -96\(%rcx,%rdx\), %ymm5
+** vmovdqu -128\(%rcx,%rdx\), %ymm4
+**.L13:
+** vmovdqu \(%rcx\), %ymm3
+** addq \$-128, %rsi
+** subq \$-128, %rdi
+** subq \$-128, %rcx
+** vmovdqu -96\(%rcx\), %ymm2
+** vmovdqu -64\(%rcx\), %ymm1
+** vmovdqu -32\(%rcx\), %ymm0
+** vmovdqu %ymm3, -128\(%rdi\)
+** vmovdqu %ymm2, -96\(%rdi\)
+** vmovdqu %ymm1, -64\(%rdi\)
+** vmovdqu %ymm0, -32\(%rdi\)
+** cmpq \$128, %rsi
+** ja .L13
+** vmovdqu %ymm7, -32\(%rax,%rdx\)
+** vmovdqu %ymm6, -64\(%rax,%rdx\)
+** vmovdqu %ymm5, -96\(%rax,%rdx\)
+** vmovdqu %ymm4, -128\(%rax,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L3:
+** cmpq \$16, %rdx
+** jb .L20
+** vmovdqu \(%rsi\), %xmm1
+** vmovdqu -16\(%rsi,%rdx\), %xmm0
+** vmovdqu %xmm1, \(%rdi\)
+** vmovdqu %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L20:
+** cmpq \$8, %rdx
+** jnb .L6
+** cmpq \$4, %rdx
+** jnb .L7
+** cmpq \$1, %rdx
+** ja .L8
+** jb .L2
+** movzbl \(%rsi\), %edx
+** movb %dl, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L18:
+** vmovdqu \(%rsi\), %ymm1
+** vmovdqu -32\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm1, \(%rdi\)
+** vmovdqu %ymm0, -32\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L19:
+** cmpq \$128, %rdx
+** jb .L11
+** vmovdqu \(%rsi\), %ymm7
+** vmovdqu 32\(%rsi\), %ymm6
+** vmovdqu 64\(%rsi\), %ymm5
+** vmovdqu 96\(%rsi\), %ymm4
+** vmovdqu -32\(%rsi,%rdx\), %ymm3
+** vmovdqu -64\(%rsi,%rdx\), %ymm2
+** vmovdqu -96\(%rsi,%rdx\), %ymm1
+** vmovdqu -128\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm7, \(%rdi\)
+** vmovdqu %ymm6, 32\(%rdi\)
+** vmovdqu %ymm5, 64\(%rdi\)
+** vmovdqu %ymm4, 96\(%rdi\)
+** vmovdqu %ymm3, -32\(%rdi,%rdx\)
+** vmovdqu %ymm2, -64\(%rdi,%rdx\)
+** vmovdqu %ymm1, -96\(%rdi,%rdx\)
+** vmovdqu %ymm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movq \(%rsi\), %rdi
+** movq -8\(%rsi,%rdx\), %rcx
+** movq %rdi, \(%rax\)
+** movq %rcx, -8\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L12:
+** vmovdqu \(%rcx\), %ymm7
+** vmovdqu 32\(%rcx\), %ymm6
+** leaq \(%rdi,%rdx\), %rdi
+** vmovdqu 64\(%rcx\), %ymm5
+** vmovdqu 96\(%rcx\), %ymm4
+** addq %rdx, %rcx
+**.L14:
+** vmovdqu -32\(%rcx\), %ymm3
+** vmovdqu -64\(%rcx\), %ymm2
+** addq \$-128, %rsi
+** addq \$-128, %rdi
+** vmovdqu -96\(%rcx\), %ymm1
+** vmovdqu -128\(%rcx\), %ymm0
+** addq \$-128, %rcx
+** vmovdqu %ymm3, 96\(%rdi\)
+** vmovdqu %ymm2, 64\(%rdi\)
+** vmovdqu %ymm1, 32\(%rdi\)
+** vmovdqu %ymm0, \(%rdi\)
+** cmpq \$128, %rsi
+** ja .L14
+** vmovdqu %ymm7, \(%rax\)
+** vmovdqu %ymm6, 32\(%rax\)
+** vmovdqu %ymm5, 64\(%rax\)
+** vmovdqu %ymm4, 96\(%rax\)
+** vzeroupper
+**.L2:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L11:
+** vmovdqu \(%rsi\), %ymm3
+** vmovdqu 32\(%rsi\), %ymm2
+** vmovdqu -32\(%rsi,%rdx\), %ymm1
+** vmovdqu -64\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm3, \(%rdi\)
+** vmovdqu %ymm2, 32\(%rdi\)
+** vmovdqu %ymm1, -32\(%rdi,%rdx\)
+** vmovdqu %ymm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movl \(%rsi\), %edi
+** movl -4\(%rsi,%rdx\), %ecx
+** movl %edi, \(%rax\)
+** movl %ecx, -4\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** movzwl \(%rsi\), %edi
+** movzwl -2\(%rsi,%rdx\), %ecx
+** movw %di, \(%rax\)
+** movw %cx, -2\(%rax,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_ymm
+#include "builtin-memmove-2a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-2c.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-2c.c
new file mode 100644
index 0000000..cb3cb9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-2c.c
@@ -0,0 +1,184 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mmove-max=512 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_zmm:
+**.LFB0:
+** .cfi_startproc
+** movq %rdi, %rax
+** movq %rsi, %rcx
+** cmpq \$64, %rdx
+** jb .L3
+** cmpq \$128, %rdx
+** jbe .L19
+** cmpq \$512, %rdx
+** jbe .L20
+** movq %rdx, %rsi
+** cmpq %rdi, %rcx
+** jb .L13
+** je .L2
+** vmovdqu64 -64\(%rcx,%rdx\), %zmm7
+** vmovdqu64 -128\(%rcx,%rdx\), %zmm6
+** vmovdqu64 -192\(%rcx,%rdx\), %zmm5
+** vmovdqu64 -256\(%rcx,%rdx\), %zmm4
+**.L14:
+** vmovdqu64 \(%rcx\), %zmm3
+** vmovdqu64 64\(%rcx\), %zmm2
+** subq \$256, %rsi
+** addq \$256, %rdi
+** vmovdqu64 128\(%rcx\), %zmm1
+** addq \$256, %rcx
+** vmovdqu64 -64\(%rcx\), %zmm0
+** vmovdqu64 %zmm3, -256\(%rdi\)
+** vmovdqu64 %zmm2, -192\(%rdi\)
+** vmovdqu64 %zmm1, -128\(%rdi\)
+** vmovdqu64 %zmm0, -64\(%rdi\)
+** cmpq \$256, %rsi
+** ja .L14
+** vmovdqu64 %zmm7, -64\(%rax,%rdx\)
+** vmovdqu64 %zmm6, -128\(%rax,%rdx\)
+** vmovdqu64 %zmm5, -192\(%rax,%rdx\)
+** vmovdqu64 %zmm4, -256\(%rax,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L3:
+** cmpq \$32, %rdx
+** jb .L21
+** vmovdqu \(%rsi\), %ymm1
+** vmovdqu -32\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm1, \(%rdi\)
+** vmovdqu %ymm0, -32\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L21:
+** cmpq \$16, %rdx
+** jnb .L6
+** cmpq \$8, %rdx
+** jnb .L7
+** cmpq \$4, %rdx
+** jnb .L8
+** cmpq \$1, %rdx
+** ja .L9
+** jb .L2
+** movzbl \(%rsi\), %edx
+** movb %dl, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L19:
+** vmovdqu64 \(%rsi\), %zmm1
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm1, \(%rdi\)
+** vmovdqu64 %zmm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L20:
+** cmpq \$256, %rdx
+** jb .L12
+** vmovdqu64 \(%rsi\), %zmm7
+** vmovdqu64 64\(%rsi\), %zmm6
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm3
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm2
+** vmovdqu64 128\(%rsi\), %zmm5
+** vmovdqu64 192\(%rsi\), %zmm4
+** vmovdqu64 -192\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -256\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm7, \(%rdi\)
+** vmovdqu64 %zmm6, 64\(%rdi\)
+** vmovdqu64 %zmm5, 128\(%rdi\)
+** vmovdqu64 %zmm4, 192\(%rdi\)
+** vmovdqu64 %zmm3, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm2, -128\(%rdi,%rdx\)
+** vmovdqu64 %zmm1, -192\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -256\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** vmovdqu \(%rsi\), %xmm1
+** vmovdqu -16\(%rsi,%rdx\), %xmm0
+** vmovdqu %xmm1, \(%rdi\)
+** vmovdqu %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** vmovdqu64 \(%rcx\), %zmm7
+** leaq \(%rdi,%rdx\), %rdi
+** vmovdqu64 64\(%rcx\), %zmm6
+** vmovdqu64 128\(%rcx\), %zmm5
+** vmovdqu64 192\(%rcx\), %zmm4
+** addq %rdx, %rcx
+**.L15:
+** vmovdqu64 -64\(%rcx\), %zmm3
+** vmovdqu64 -128\(%rcx\), %zmm2
+** subq \$256, %rsi
+** subq \$256, %rdi
+** vmovdqu64 -192\(%rcx\), %zmm1
+** subq \$256, %rcx
+** vmovdqu64 \(%rcx\), %zmm0
+** vmovdqu64 %zmm3, 192\(%rdi\)
+** vmovdqu64 %zmm2, 128\(%rdi\)
+** vmovdqu64 %zmm1, 64\(%rdi\)
+** vmovdqu64 %zmm0, \(%rdi\)
+** cmpq \$256, %rsi
+** ja .L15
+** vmovdqu64 %zmm7, \(%rax\)
+** vmovdqu64 %zmm6, 64\(%rax\)
+** vmovdqu64 %zmm5, 128\(%rax\)
+** vmovdqu64 %zmm4, 192\(%rax\)
+** vzeroupper
+**.L2:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L12:
+** vmovdqu64 \(%rsi\), %zmm3
+** vmovdqu64 64\(%rsi\), %zmm2
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm3, \(%rdi\)
+** vmovdqu64 %zmm2, 64\(%rdi\)
+** vmovdqu64 %zmm1, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movq \(%rsi\), %rdi
+** movq -8\(%rsi,%rdx\), %rcx
+** movq %rdi, \(%rax\)
+** movq %rcx, -8\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** movl \(%rsi\), %edi
+** movl -4\(%rsi,%rdx\), %ecx
+** movl %edi, \(%rax\)
+** movl %ecx, -4\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L9:
+** movzwl \(%rsi\), %edi
+** movzwl -2\(%rsi,%rdx\), %ecx
+** movw %di, \(%rax\)
+** movw %cx, -2\(%rax,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_zmm
+#include "builtin-memmove-2a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-2d.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-2d.c
new file mode 100644
index 0000000..c27edfe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-2d.c
@@ -0,0 +1,195 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mgeneral-regs-only -march=x86-64 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_gpr:
+**.LFB0:
+** .cfi_startproc
+** movq %rdi, %rax
+** cmpq \$8, %rdx
+** jb .L3
+** cmpq \$16, %rdx
+** jbe .L19
+** subq \$32, %rsp
+** .cfi_def_cfa_offset 40
+** cmpq \$64, %rdx
+** jbe .L20
+** movq %rsi, %rcx
+** movq %rdx, %rsi
+** cmpq %rdi, %rcx
+** jb .L10
+** je .L2
+** movq %rbx, \(%rsp\)
+** movq %rbp, 8\(%rsp\)
+** movq %r14, 16\(%rsp\)
+** movq %r15, 24\(%rsp\)
+** .cfi_offset 3, -40
+** .cfi_offset 6, -32
+** .cfi_offset 14, -24
+** .cfi_offset 15, -16
+** movq -8\(%rcx,%rdx\), %r15
+** movq -16\(%rcx,%rdx\), %r14
+** movq -24\(%rcx,%rdx\), %rbp
+** movq -32\(%rcx,%rdx\), %r11
+**.L11:
+** movq 8\(%rcx\), %r10
+** movq 16\(%rcx\), %r9
+** subq \$32, %rsi
+** addq \$32, %rdi
+** movq 24\(%rcx\), %r8
+** movq \(%rcx\), %rbx
+** addq \$32, %rcx
+** movq %r10, -24\(%rdi\)
+** movq %rbx, -32\(%rdi\)
+** movq %r9, -16\(%rdi\)
+** movq %r8, -8\(%rdi\)
+** cmpq \$32, %rsi
+** ja .L11
+** movq %r15, -8\(%rax,%rdx\)
+** movq %r14, -16\(%rax,%rdx\)
+** movq %rbp, -24\(%rax,%rdx\)
+** movq %r11, -32\(%rax,%rdx\)
+** movq \(%rsp\), %rbx
+** .cfi_restore 3
+** movq 8\(%rsp\), %rbp
+** .cfi_restore 6
+** movq 16\(%rsp\), %r14
+** .cfi_restore 14
+** movq 24\(%rsp\), %r15
+** .cfi_restore 15
+** jmp .L2
+** .p2align 4,,10
+** .p2align 3
+**.L3:
+** .cfi_def_cfa_offset 8
+** cmpq \$4, %rdx
+** jb .L21
+** movl \(%rsi\), %edi
+** movl -4\(%rsi,%rdx\), %ecx
+** movl %edi, \(%rax\)
+** movl %ecx, -4\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L21:
+** cmpq \$1, %rdx
+** ja .L6
+** jb .L16
+** movzbl \(%rsi\), %edx
+** movb %dl, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L19:
+** movq \(%rsi\), %rdi
+** movq -8\(%rsi,%rdx\), %rcx
+** movq %rdi, \(%rax\)
+** movq %rcx, -8\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L20:
+** .cfi_def_cfa_offset 40
+** cmpq \$32, %rdx
+** jb .L9
+** movq %rbx, \(%rsp\)
+** movq %r14, 16\(%rsp\)
+** .cfi_offset 3, -40
+** .cfi_offset 14, -24
+** movq \(%rsi\), %rbx
+** movq 8\(%rsi\), %r14
+** movq 16\(%rsi\), %r11
+** movq 24\(%rsi\), %r10
+** movq -8\(%rsi,%rdx\), %r9
+** movq -16\(%rsi,%rdx\), %r8
+** movq -24\(%rsi,%rdx\), %rdi
+** movq -32\(%rsi,%rdx\), %rcx
+** movq %rbx, \(%rax\)
+** movq %r14, 8\(%rax\)
+** movq %r11, 16\(%rax\)
+** movq %r10, 24\(%rax\)
+** movq %r9, -8\(%rax,%rdx\)
+** movq %r8, -16\(%rax,%rdx\)
+** movq %rdi, -24\(%rax,%rdx\)
+** movq %rcx, -32\(%rax,%rdx\)
+** movq \(%rsp\), %rbx
+** .cfi_restore 3
+** movq 16\(%rsp\), %r14
+** .cfi_restore 14
+**.L2:
+** addq \$32, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movzwl \(%rsi\), %edi
+** movzwl -2\(%rsi,%rdx\), %ecx
+** movw %di, \(%rax\)
+** movw %cx, -2\(%rax,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L16:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L9:
+** .cfi_def_cfa_offset 40
+** movq \(%rsi\), %r9
+** movq 8\(%rsi\), %r8
+** movq -8\(%rsi,%rdx\), %rdi
+** movq -16\(%rsi,%rdx\), %rcx
+** movq %r9, \(%rax\)
+** movq %r8, 8\(%rax\)
+** movq %rdi, -8\(%rax,%rdx\)
+** movq %rcx, -16\(%rax,%rdx\)
+** jmp .L2
+** .p2align 4,,10
+** .p2align 3
+**.L10:
+** movq %rbx, \(%rsp\)
+** leaq \(%rdi,%rdx\), %rdi
+** movq %r14, 16\(%rsp\)
+** movq %r15, 24\(%rsp\)
+** .cfi_offset 3, -40
+** .cfi_offset 14, -24
+** .cfi_offset 15, -16
+** movq \(%rcx\), %r14
+** movq 8\(%rcx\), %r15
+** movq 16\(%rcx\), %r10
+** movq 24\(%rcx\), %r11
+** addq %rdx, %rcx
+**.L12:
+** movq -16\(%rcx\), %r9
+** movq -24\(%rcx\), %r8
+** subq \$32, %rsi
+** subq \$32, %rdi
+** movq -32\(%rcx\), %rdx
+** movq -8\(%rcx\), %rbx
+** subq \$32, %rcx
+** movq %r9, 16\(%rdi\)
+** movq %rbx, 24\(%rdi\)
+** movq %r8, 8\(%rdi\)
+** movq %rdx, \(%rdi\)
+** cmpq \$32, %rsi
+** ja .L12
+** movq %r14, \(%rax\)
+** movq \(%rsp\), %rbx
+** .cfi_restore 3
+** movq %r15, 8\(%rax\)
+** movq 16\(%rsp\), %r14
+** .cfi_restore 14
+** movq %r10, 16\(%rax\)
+** movq 24\(%rsp\), %r15
+** .cfi_restore 15
+** movq %r11, 24\(%rax\)
+** jmp .L2
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_gpr
+#include "builtin-memmove-2a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-3a.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-3a.c
new file mode 100644
index 0000000..83cb8e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-3a.c
@@ -0,0 +1,133 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_xmm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$16, %rdx
+** ja .L13
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$32, %rdx
+** jbe .L14
+** cmpq \$128, %rdx
+** ja .L5
+** cmpq \$64, %rdx
+** jnb .L15
+** movdqu \(%rsi\), %xmm3
+** movdqu 16\(%rsi\), %xmm2
+** movdqu -16\(%rsi,%rdx\), %xmm1
+** movdqu -32\(%rsi,%rdx\), %xmm0
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, -16\(%rdi,%rdx\)
+** movups %xmm0, -32\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L14:
+** movdqu \(%rsi\), %xmm1
+** movdqu -16\(%rsi,%rdx\), %xmm0
+** movups %xmm1, \(%rdi\)
+** movups %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L7
+** je .L1
+** movdqu -16\(%rax,%rdx\), %xmm7
+** movdqu -32\(%rax,%rdx\), %xmm6
+** movdqu -48\(%rax,%rdx\), %xmm5
+** movdqu -64\(%rax,%rdx\), %xmm4
+**.L8:
+** movdqu \(%rax\), %xmm3
+** subq \$64, %rsi
+** addq \$64, %rcx
+** addq \$64, %rax
+** movdqu -48\(%rax\), %xmm2
+** movdqu -32\(%rax\), %xmm1
+** movdqu -16\(%rax\), %xmm0
+** movups %xmm3, -64\(%rcx\)
+** movups %xmm2, -48\(%rcx\)
+** movups %xmm1, -32\(%rcx\)
+** movups %xmm0, -16\(%rcx\)
+** cmpq \$64, %rsi
+** ja .L8
+** movups %xmm7, -16\(%rdi,%rdx\)
+** movups %xmm6, -32\(%rdi,%rdx\)
+** movups %xmm5, -48\(%rdi,%rdx\)
+** movups %xmm4, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movdqu \(%rax\), %xmm3
+** movdqu 16\(%rax\), %xmm2
+** leaq \(%rdi,%rdx\), %rcx
+** movdqu 32\(%rax\), %xmm1
+** movdqu 48\(%rax\), %xmm0
+** addq %rdx, %rax
+**.L9:
+** movdqu -16\(%rax\), %xmm7
+** movdqu -32\(%rax\), %xmm6
+** subq \$64, %rsi
+** subq \$64, %rcx
+** movdqu -48\(%rax\), %xmm5
+** movdqu -64\(%rax\), %xmm4
+** subq \$64, %rax
+** movups %xmm7, 48\(%rcx\)
+** movups %xmm6, 32\(%rcx\)
+** movups %xmm5, 16\(%rcx\)
+** movups %xmm4, \(%rcx\)
+** cmpq \$64, %rsi
+** ja .L9
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, 32\(%rdi\)
+** movups %xmm0, 48\(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L15:
+** movdqu \(%rsi\), %xmm7
+** movdqu 16\(%rsi\), %xmm6
+** movdqu 32\(%rsi\), %xmm5
+** movdqu 48\(%rsi\), %xmm4
+** movdqu -16\(%rsi,%rdx\), %xmm3
+** movdqu -32\(%rsi,%rdx\), %xmm2
+** movdqu -48\(%rsi,%rdx\), %xmm1
+** movdqu -64\(%rsi,%rdx\), %xmm0
+** movups %xmm7, \(%rdi\)
+** movups %xmm6, 16\(%rdi\)
+** movups %xmm5, 32\(%rdi\)
+** movups %xmm4, 48\(%rdi\)
+** movups %xmm3, -16\(%rdi,%rdx\)
+** movups %xmm2, -32\(%rdi,%rdx\)
+** movups %xmm1, -48\(%rdi,%rdx\)
+** movups %xmm0, -64\(%rdi,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+#ifndef gcc_memmove
+#define gcc_memmove gcc_memmove_xmm
+#endif
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n > 16)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-3b.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-3b.c
new file mode 100644
index 0000000..43fae5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-3b.c
@@ -0,0 +1,140 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx512f -march=x86-64-v3 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_ymm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$16, %rdx
+** ja .L16
+**.L14:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L16:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$32, %rdx
+** jb .L6
+** cmpq \$64, %rdx
+** ja .L5
+** vmovdqu \(%rsi\), %ymm1
+** vmovdqu -32\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm1, \(%rdi\)
+** vmovdqu %ymm0, -32\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** vmovdqu \(%rsi\), %xmm1
+** vmovdqu -16\(%rsi,%rdx\), %xmm0
+** vmovdqu %xmm1, \(%rdi\)
+** vmovdqu %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** cmpq \$256, %rdx
+** jbe .L17
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L9
+** je .L14
+** vmovdqu -32\(%rax,%rdx\), %ymm7
+** vmovdqu -64\(%rax,%rdx\), %ymm6
+** vmovdqu -96\(%rax,%rdx\), %ymm5
+** vmovdqu -128\(%rax,%rdx\), %ymm4
+**.L10:
+** vmovdqu \(%rax\), %ymm3
+** addq \$-128, %rsi
+** subq \$-128, %rcx
+** subq \$-128, %rax
+** vmovdqu -96\(%rax\), %ymm2
+** vmovdqu -64\(%rax\), %ymm1
+** vmovdqu -32\(%rax\), %ymm0
+** vmovdqu %ymm3, -128\(%rcx\)
+** vmovdqu %ymm2, -96\(%rcx\)
+** vmovdqu %ymm1, -64\(%rcx\)
+** vmovdqu %ymm0, -32\(%rcx\)
+** cmpq \$128, %rsi
+** ja .L10
+** vmovdqu %ymm7, -32\(%rdi,%rdx\)
+** vmovdqu %ymm6, -64\(%rdi,%rdx\)
+** vmovdqu %ymm5, -96\(%rdi,%rdx\)
+** vmovdqu %ymm4, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L17:
+** cmpq \$128, %rdx
+** jb .L8
+** vmovdqu \(%rsi\), %ymm7
+** vmovdqu 32\(%rsi\), %ymm6
+** vmovdqu 64\(%rsi\), %ymm5
+** vmovdqu 96\(%rsi\), %ymm4
+** vmovdqu -32\(%rsi,%rdx\), %ymm3
+** vmovdqu -64\(%rsi,%rdx\), %ymm2
+** vmovdqu -96\(%rsi,%rdx\), %ymm1
+** vmovdqu -128\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm7, \(%rdi\)
+** vmovdqu %ymm6, 32\(%rdi\)
+** vmovdqu %ymm5, 64\(%rdi\)
+** vmovdqu %ymm4, 96\(%rdi\)
+** vmovdqu %ymm3, -32\(%rdi,%rdx\)
+** vmovdqu %ymm2, -64\(%rdi,%rdx\)
+** vmovdqu %ymm1, -96\(%rdi,%rdx\)
+** vmovdqu %ymm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** vmovdqu \(%rsi\), %ymm3
+** vmovdqu 32\(%rsi\), %ymm2
+** vmovdqu -32\(%rsi,%rdx\), %ymm1
+** vmovdqu -64\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm3, \(%rdi\)
+** vmovdqu %ymm2, 32\(%rdi\)
+** vmovdqu %ymm1, -32\(%rdi,%rdx\)
+** vmovdqu %ymm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L9:
+** vmovdqu \(%rax\), %ymm3
+** vmovdqu 32\(%rax\), %ymm2
+** leaq \(%rdi,%rdx\), %rcx
+** vmovdqu 64\(%rax\), %ymm1
+** vmovdqu 96\(%rax\), %ymm0
+** addq %rdx, %rax
+**.L11:
+** vmovdqu -32\(%rax\), %ymm7
+** vmovdqu -64\(%rax\), %ymm6
+** addq \$-128, %rsi
+** addq \$-128, %rcx
+** vmovdqu -96\(%rax\), %ymm5
+** vmovdqu -128\(%rax\), %ymm4
+** addq \$-128, %rax
+** vmovdqu %ymm7, 96\(%rcx\)
+** vmovdqu %ymm6, 64\(%rcx\)
+** vmovdqu %ymm5, 32\(%rcx\)
+** vmovdqu %ymm4, \(%rcx\)
+** cmpq \$128, %rsi
+** ja .L11
+** vmovdqu %ymm3, \(%rdi\)
+** vmovdqu %ymm2, 32\(%rdi\)
+** vmovdqu %ymm1, 64\(%rdi\)
+** vmovdqu %ymm0, 96\(%rdi\)
+** vzeroupper
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_ymm
+#include "builtin-memmove-3a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-3c.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-3c.c
new file mode 100644
index 0000000..11ccb69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-3c.c
@@ -0,0 +1,151 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mmove-max=512 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_zmm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$16, %rdx
+** ja .L18
+**.L16:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L18:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$64, %rdx
+** jnb .L19
+** cmpq \$32, %rdx
+** jb .L15
+** vmovdqu \(%rsi\), %ymm1
+** vmovdqu -32\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm1, \(%rdi\)
+** vmovdqu %ymm0, -32\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L19:
+** cmpq \$128, %rdx
+** ja .L5
+** vmovdqu64 \(%rsi\), %zmm1
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm1, \(%rdi\)
+** vmovdqu64 %zmm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** cmpq \$512, %rdx
+** jbe .L20
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L10
+** je .L16
+** vmovdqu64 -64\(%rax,%rdx\), %zmm7
+** vmovdqu64 -128\(%rax,%rdx\), %zmm6
+** vmovdqu64 -192\(%rax,%rdx\), %zmm5
+** vmovdqu64 -256\(%rax,%rdx\), %zmm4
+**.L11:
+** vmovdqu64 \(%rax\), %zmm3
+** addq \$256, %rax
+** vmovdqu64 -192\(%rax\), %zmm2
+** subq \$256, %rsi
+** vmovdqu64 -128\(%rax\), %zmm1
+** vmovdqu64 -64\(%rax\), %zmm0
+** addq \$256, %rcx
+** vmovdqu64 %zmm3, -256\(%rcx\)
+** vmovdqu64 %zmm2, -192\(%rcx\)
+** vmovdqu64 %zmm1, -128\(%rcx\)
+** vmovdqu64 %zmm0, -64\(%rcx\)
+** cmpq \$256, %rsi
+** ja .L11
+** vmovdqu64 %zmm7, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm6, -128\(%rdi,%rdx\)
+** vmovdqu64 %zmm5, -192\(%rdi,%rdx\)
+** vmovdqu64 %zmm4, -256\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L15:
+** vmovdqu \(%rsi\), %xmm1
+** vmovdqu -16\(%rsi,%rdx\), %xmm0
+** vmovdqu %xmm1, \(%rdi\)
+** vmovdqu %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L20:
+** cmpq \$256, %rdx
+** jb .L9
+** vmovdqu64 \(%rsi\), %zmm7
+** vmovdqu64 64\(%rsi\), %zmm6
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm3
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm2
+** vmovdqu64 128\(%rsi\), %zmm5
+** vmovdqu64 192\(%rsi\), %zmm4
+** vmovdqu64 -192\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -256\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm7, \(%rdi\)
+** vmovdqu64 %zmm6, 64\(%rdi\)
+** vmovdqu64 %zmm5, 128\(%rdi\)
+** vmovdqu64 %zmm4, 192\(%rdi\)
+** vmovdqu64 %zmm3, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm2, -128\(%rdi,%rdx\)
+** vmovdqu64 %zmm1, -192\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -256\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L9:
+** vmovdqu64 \(%rsi\), %zmm3
+** vmovdqu64 64\(%rsi\), %zmm2
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm3, \(%rdi\)
+** vmovdqu64 %zmm2, 64\(%rdi\)
+** vmovdqu64 %zmm1, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L10:
+** vmovdqu64 \(%rax\), %zmm3
+** leaq \(%rdi,%rdx\), %rcx
+** vmovdqu64 64\(%rax\), %zmm2
+** vmovdqu64 128\(%rax\), %zmm1
+** vmovdqu64 192\(%rax\), %zmm0
+** addq %rdx, %rax
+**.L12:
+** vmovdqu64 -64\(%rax\), %zmm7
+** subq \$256, %rax
+** vmovdqu64 128\(%rax\), %zmm6
+** subq \$256, %rsi
+** vmovdqu64 64\(%rax\), %zmm5
+** vmovdqu64 \(%rax\), %zmm4
+** subq \$256, %rcx
+** vmovdqu64 %zmm7, 192\(%rcx\)
+** vmovdqu64 %zmm6, 128\(%rcx\)
+** vmovdqu64 %zmm5, 64\(%rcx\)
+** vmovdqu64 %zmm4, \(%rcx\)
+** cmpq \$256, %rsi
+** ja .L12
+** vmovdqu64 %zmm3, \(%rdi\)
+** vmovdqu64 %zmm2, 64\(%rdi\)
+** vmovdqu64 %zmm1, 128\(%rdi\)
+** vmovdqu64 %zmm0, 192\(%rdi\)
+** vzeroupper
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_zmm
+#include "builtin-memmove-3a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-4a.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-4a.c
new file mode 100644
index 0000000..c437a53
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-4a.c
@@ -0,0 +1,123 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_xmm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$32, %rdx
+** ja .L13
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$128, %rdx
+** jbe .L14
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L7
+** je .L1
+** movdqu -16\(%rax,%rdx\), %xmm7
+** movdqu -32\(%rax,%rdx\), %xmm6
+** movdqu -48\(%rax,%rdx\), %xmm5
+** movdqu -64\(%rax,%rdx\), %xmm4
+**.L8:
+** movdqu \(%rax\), %xmm3
+** subq \$64, %rsi
+** addq \$64, %rcx
+** addq \$64, %rax
+** movdqu -48\(%rax\), %xmm2
+** movdqu -32\(%rax\), %xmm1
+** movdqu -16\(%rax\), %xmm0
+** movups %xmm3, -64\(%rcx\)
+** movups %xmm2, -48\(%rcx\)
+** movups %xmm1, -32\(%rcx\)
+** movups %xmm0, -16\(%rcx\)
+** cmpq \$64, %rsi
+** ja .L8
+** movups %xmm7, -16\(%rdi,%rdx\)
+** movups %xmm6, -32\(%rdi,%rdx\)
+** movups %xmm5, -48\(%rdi,%rdx\)
+** movups %xmm4, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L14:
+** cmpq \$64, %rdx
+** jb .L6
+** movdqu \(%rsi\), %xmm7
+** movdqu 16\(%rsi\), %xmm6
+** movdqu 32\(%rsi\), %xmm5
+** movdqu 48\(%rsi\), %xmm4
+** movdqu -16\(%rsi,%rdx\), %xmm3
+** movdqu -32\(%rsi,%rdx\), %xmm2
+** movdqu -48\(%rsi,%rdx\), %xmm1
+** movdqu -64\(%rsi,%rdx\), %xmm0
+** movups %xmm7, \(%rdi\)
+** movups %xmm6, 16\(%rdi\)
+** movups %xmm5, 32\(%rdi\)
+** movups %xmm4, 48\(%rdi\)
+** movups %xmm3, -16\(%rdi,%rdx\)
+** movups %xmm2, -32\(%rdi,%rdx\)
+** movups %xmm1, -48\(%rdi,%rdx\)
+** movups %xmm0, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movdqu \(%rsi\), %xmm3
+** movdqu 16\(%rsi\), %xmm2
+** movdqu -16\(%rsi,%rdx\), %xmm1
+** movdqu -32\(%rsi,%rdx\), %xmm0
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, -16\(%rdi,%rdx\)
+** movups %xmm0, -32\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movdqu \(%rax\), %xmm3
+** movdqu 16\(%rax\), %xmm2
+** leaq \(%rdi,%rdx\), %rcx
+** movdqu 32\(%rax\), %xmm1
+** movdqu 48\(%rax\), %xmm0
+** addq %rdx, %rax
+**.L9:
+** movdqu -16\(%rax\), %xmm7
+** movdqu -32\(%rax\), %xmm6
+** subq \$64, %rsi
+** subq \$64, %rcx
+** movdqu -48\(%rax\), %xmm5
+** movdqu -64\(%rax\), %xmm4
+** subq \$64, %rax
+** movups %xmm7, 48\(%rcx\)
+** movups %xmm6, 32\(%rcx\)
+** movups %xmm5, 16\(%rcx\)
+** movups %xmm4, \(%rcx\)
+** cmpq \$64, %rsi
+** ja .L9
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, 32\(%rdi\)
+** movups %xmm0, 48\(%rdi\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+#ifndef gcc_memmove
+#define gcc_memmove gcc_memmove_xmm
+#endif
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n > 32)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-4b.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-4b.c
new file mode 100644
index 0000000..4b65fca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-4b.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx512f -march=x86-64-v3 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_ymm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$32, %rdx
+** ja .L14
+**.L12:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L14:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$64, %rdx
+** jbe .L15
+** cmpq \$256, %rdx
+** ja .L5
+** cmpq \$128, %rdx
+** jnb .L16
+** vmovdqu \(%rsi\), %ymm3
+** vmovdqu 32\(%rsi\), %ymm2
+** vmovdqu -32\(%rsi,%rdx\), %ymm1
+** vmovdqu -64\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm3, \(%rdi\)
+** vmovdqu %ymm2, 32\(%rdi\)
+** vmovdqu %ymm1, -32\(%rdi,%rdx\)
+** vmovdqu %ymm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L15:
+** vmovdqu \(%rsi\), %ymm1
+** vmovdqu -32\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm1, \(%rdi\)
+** vmovdqu %ymm0, -32\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L7
+** je .L12
+** vmovdqu -32\(%rax,%rdx\), %ymm7
+** vmovdqu -64\(%rax,%rdx\), %ymm6
+** vmovdqu -96\(%rax,%rdx\), %ymm5
+** vmovdqu -128\(%rax,%rdx\), %ymm4
+**.L8:
+** vmovdqu \(%rax\), %ymm3
+** addq \$-128, %rsi
+** subq \$-128, %rcx
+** subq \$-128, %rax
+** vmovdqu -96\(%rax\), %ymm2
+** vmovdqu -64\(%rax\), %ymm1
+** vmovdqu -32\(%rax\), %ymm0
+** vmovdqu %ymm3, -128\(%rcx\)
+** vmovdqu %ymm2, -96\(%rcx\)
+** vmovdqu %ymm1, -64\(%rcx\)
+** vmovdqu %ymm0, -32\(%rcx\)
+** cmpq \$128, %rsi
+** ja .L8
+** vmovdqu %ymm7, -32\(%rdi,%rdx\)
+** vmovdqu %ymm6, -64\(%rdi,%rdx\)
+** vmovdqu %ymm5, -96\(%rdi,%rdx\)
+** vmovdqu %ymm4, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** vmovdqu \(%rax\), %ymm3
+** vmovdqu 32\(%rax\), %ymm2
+** leaq \(%rdi,%rdx\), %rcx
+** vmovdqu 64\(%rax\), %ymm1
+** vmovdqu 96\(%rax\), %ymm0
+** addq %rdx, %rax
+**.L9:
+** vmovdqu -32\(%rax\), %ymm7
+** vmovdqu -64\(%rax\), %ymm6
+** addq \$-128, %rsi
+** addq \$-128, %rcx
+** vmovdqu -96\(%rax\), %ymm5
+** vmovdqu -128\(%rax\), %ymm4
+** addq \$-128, %rax
+** vmovdqu %ymm7, 96\(%rcx\)
+** vmovdqu %ymm6, 64\(%rcx\)
+** vmovdqu %ymm5, 32\(%rcx\)
+** vmovdqu %ymm4, \(%rcx\)
+** cmpq \$128, %rsi
+** ja .L9
+** vmovdqu %ymm3, \(%rdi\)
+** vmovdqu %ymm2, 32\(%rdi\)
+** vmovdqu %ymm1, 64\(%rdi\)
+** vmovdqu %ymm0, 96\(%rdi\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L16:
+** vmovdqu \(%rsi\), %ymm7
+** vmovdqu 32\(%rsi\), %ymm6
+** vmovdqu 64\(%rsi\), %ymm5
+** vmovdqu 96\(%rsi\), %ymm4
+** vmovdqu -32\(%rsi,%rdx\), %ymm3
+** vmovdqu -64\(%rsi,%rdx\), %ymm2
+** vmovdqu -96\(%rsi,%rdx\), %ymm1
+** vmovdqu -128\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm7, \(%rdi\)
+** vmovdqu %ymm6, 32\(%rdi\)
+** vmovdqu %ymm5, 64\(%rdi\)
+** vmovdqu %ymm4, 96\(%rdi\)
+** vmovdqu %ymm3, -32\(%rdi,%rdx\)
+** vmovdqu %ymm2, -64\(%rdi,%rdx\)
+** vmovdqu %ymm1, -96\(%rdi,%rdx\)
+** vmovdqu %ymm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_ymm
+#include "builtin-memmove-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-4c.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-4c.c
new file mode 100644
index 0000000..fea3e49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-4c.c
@@ -0,0 +1,141 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mmove-max=512 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_zmm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$32, %rdx
+** ja .L16
+**.L14:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L16:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$64, %rdx
+** jb .L6
+** cmpq \$128, %rdx
+** ja .L5
+** vmovdqu64 \(%rsi\), %zmm1
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm1, \(%rdi\)
+** vmovdqu64 %zmm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** vmovdqu \(%rsi\), %ymm1
+** vmovdqu -32\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm1, \(%rdi\)
+** vmovdqu %ymm0, -32\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** cmpq \$512, %rdx
+** jbe .L17
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L9
+** je .L14
+** vmovdqu64 -64\(%rax,%rdx\), %zmm7
+** vmovdqu64 -128\(%rax,%rdx\), %zmm6
+** vmovdqu64 -192\(%rax,%rdx\), %zmm5
+** vmovdqu64 -256\(%rax,%rdx\), %zmm4
+**.L10:
+** vmovdqu64 \(%rax\), %zmm3
+** addq \$256, %rax
+** vmovdqu64 -192\(%rax\), %zmm2
+** subq \$256, %rsi
+** vmovdqu64 -128\(%rax\), %zmm1
+** vmovdqu64 -64\(%rax\), %zmm0
+** addq \$256, %rcx
+** vmovdqu64 %zmm3, -256\(%rcx\)
+** vmovdqu64 %zmm2, -192\(%rcx\)
+** vmovdqu64 %zmm1, -128\(%rcx\)
+** vmovdqu64 %zmm0, -64\(%rcx\)
+** cmpq \$256, %rsi
+** ja .L10
+** vmovdqu64 %zmm7, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm6, -128\(%rdi,%rdx\)
+** vmovdqu64 %zmm5, -192\(%rdi,%rdx\)
+** vmovdqu64 %zmm4, -256\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L17:
+** cmpq \$256, %rdx
+** jb .L8
+** vmovdqu64 \(%rsi\), %zmm7
+** vmovdqu64 64\(%rsi\), %zmm6
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm3
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm2
+** vmovdqu64 128\(%rsi\), %zmm5
+** vmovdqu64 192\(%rsi\), %zmm4
+** vmovdqu64 -192\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -256\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm7, \(%rdi\)
+** vmovdqu64 %zmm6, 64\(%rdi\)
+** vmovdqu64 %zmm5, 128\(%rdi\)
+** vmovdqu64 %zmm4, 192\(%rdi\)
+** vmovdqu64 %zmm3, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm2, -128\(%rdi,%rdx\)
+** vmovdqu64 %zmm1, -192\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -256\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** vmovdqu64 \(%rsi\), %zmm3
+** vmovdqu64 64\(%rsi\), %zmm2
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm3, \(%rdi\)
+** vmovdqu64 %zmm2, 64\(%rdi\)
+** vmovdqu64 %zmm1, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L9:
+** vmovdqu64 \(%rax\), %zmm3
+** leaq \(%rdi,%rdx\), %rcx
+** vmovdqu64 64\(%rax\), %zmm2
+** vmovdqu64 128\(%rax\), %zmm1
+** vmovdqu64 192\(%rax\), %zmm0
+** addq %rdx, %rax
+**.L11:
+** vmovdqu64 -64\(%rax\), %zmm7
+** subq \$256, %rax
+** vmovdqu64 128\(%rax\), %zmm6
+** subq \$256, %rsi
+** vmovdqu64 64\(%rax\), %zmm5
+** vmovdqu64 \(%rax\), %zmm4
+** subq \$256, %rcx
+** vmovdqu64 %zmm7, 192\(%rcx\)
+** vmovdqu64 %zmm6, 128\(%rcx\)
+** vmovdqu64 %zmm5, 64\(%rcx\)
+** vmovdqu64 %zmm4, \(%rcx\)
+** cmpq \$256, %rsi
+** ja .L11
+** vmovdqu64 %zmm3, \(%rdi\)
+** vmovdqu64 %zmm2, 64\(%rdi\)
+** vmovdqu64 %zmm1, 128\(%rdi\)
+** vmovdqu64 %zmm0, 192\(%rdi\)
+** vzeroupper
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_zmm
+#include "builtin-memmove-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-5a.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-5a.c
new file mode 100644
index 0000000..c86defb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-5a.c
@@ -0,0 +1,109 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_xmm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$67, %rdx
+** ja .L12
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L12:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$128, %rdx
+** jbe .L13
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L6
+** je .L1
+** movdqu -16\(%rax,%rdx\), %xmm7
+** movdqu -32\(%rax,%rdx\), %xmm6
+** movdqu -48\(%rax,%rdx\), %xmm5
+** movdqu -64\(%rax,%rdx\), %xmm4
+**.L7:
+** movdqu \(%rax\), %xmm3
+** subq \$64, %rsi
+** addq \$64, %rcx
+** addq \$64, %rax
+** movdqu -48\(%rax\), %xmm2
+** movdqu -32\(%rax\), %xmm1
+** movdqu -16\(%rax\), %xmm0
+** movups %xmm3, -64\(%rcx\)
+** movups %xmm2, -48\(%rcx\)
+** movups %xmm1, -32\(%rcx\)
+** movups %xmm0, -16\(%rcx\)
+** cmpq \$64, %rsi
+** ja .L7
+** movups %xmm7, -16\(%rdi,%rdx\)
+** movups %xmm6, -32\(%rdi,%rdx\)
+** movups %xmm5, -48\(%rdi,%rdx\)
+** movups %xmm4, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** movdqu \(%rsi\), %xmm7
+** movdqu 16\(%rsi\), %xmm6
+** movdqu 32\(%rsi\), %xmm5
+** movdqu 48\(%rsi\), %xmm4
+** movdqu -16\(%rsi,%rdx\), %xmm3
+** movdqu -32\(%rsi,%rdx\), %xmm2
+** movdqu -48\(%rsi,%rdx\), %xmm1
+** movdqu -64\(%rsi,%rdx\), %xmm0
+** movups %xmm7, \(%rdi\)
+** movups %xmm6, 16\(%rdi\)
+** movups %xmm5, 32\(%rdi\)
+** movups %xmm4, 48\(%rdi\)
+** movups %xmm3, -16\(%rdi,%rdx\)
+** movups %xmm2, -32\(%rdi,%rdx\)
+** movups %xmm1, -48\(%rdi,%rdx\)
+** movups %xmm0, -64\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movdqu \(%rax\), %xmm3
+** movdqu 16\(%rax\), %xmm2
+** leaq \(%rdi,%rdx\), %rcx
+** movdqu 32\(%rax\), %xmm1
+** movdqu 48\(%rax\), %xmm0
+** addq %rdx, %rax
+**.L8:
+** movdqu -16\(%rax\), %xmm7
+** movdqu -32\(%rax\), %xmm6
+** subq \$64, %rsi
+** subq \$64, %rcx
+** movdqu -48\(%rax\), %xmm5
+** movdqu -64\(%rax\), %xmm4
+** subq \$64, %rax
+** movups %xmm7, 48\(%rcx\)
+** movups %xmm6, 32\(%rcx\)
+** movups %xmm5, 16\(%rcx\)
+** movups %xmm4, \(%rcx\)
+** cmpq \$64, %rsi
+** ja .L8
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, 32\(%rdi\)
+** movups %xmm0, 48\(%rdi\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+#ifndef gcc_memmove
+#define gcc_memmove gcc_memmove_xmm
+#endif
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n > 67)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-5b.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-5b.c
new file mode 100644
index 0000000..e5fc156
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-5b.c
@@ -0,0 +1,120 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx512f -march=x86-64-v3 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_ymm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$67, %rdx
+** ja .L14
+**.L12:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L14:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$256, %rdx
+** jbe .L15
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L7
+** je .L12
+** vmovdqu -32\(%rax,%rdx\), %ymm7
+** vmovdqu -64\(%rax,%rdx\), %ymm6
+** vmovdqu -96\(%rax,%rdx\), %ymm5
+** vmovdqu -128\(%rax,%rdx\), %ymm4
+**.L8:
+** vmovdqu \(%rax\), %ymm3
+** addq \$-128, %rsi
+** subq \$-128, %rcx
+** subq \$-128, %rax
+** vmovdqu -96\(%rax\), %ymm2
+** vmovdqu -64\(%rax\), %ymm1
+** vmovdqu -32\(%rax\), %ymm0
+** vmovdqu %ymm3, -128\(%rcx\)
+** vmovdqu %ymm2, -96\(%rcx\)
+** vmovdqu %ymm1, -64\(%rcx\)
+** vmovdqu %ymm0, -32\(%rcx\)
+** cmpq \$128, %rsi
+** ja .L8
+** vmovdqu %ymm7, -32\(%rdi,%rdx\)
+** vmovdqu %ymm6, -64\(%rdi,%rdx\)
+** vmovdqu %ymm5, -96\(%rdi,%rdx\)
+** vmovdqu %ymm4, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L15:
+** cmpq \$128, %rdx
+** jb .L6
+** vmovdqu \(%rsi\), %ymm7
+** vmovdqu 32\(%rsi\), %ymm6
+** vmovdqu 64\(%rsi\), %ymm5
+** vmovdqu 96\(%rsi\), %ymm4
+** vmovdqu -32\(%rsi,%rdx\), %ymm3
+** vmovdqu -64\(%rsi,%rdx\), %ymm2
+** vmovdqu -96\(%rsi,%rdx\), %ymm1
+** vmovdqu -128\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm7, \(%rdi\)
+** vmovdqu %ymm6, 32\(%rdi\)
+** vmovdqu %ymm5, 64\(%rdi\)
+** vmovdqu %ymm4, 96\(%rdi\)
+** vmovdqu %ymm3, -32\(%rdi,%rdx\)
+** vmovdqu %ymm2, -64\(%rdi,%rdx\)
+** vmovdqu %ymm1, -96\(%rdi,%rdx\)
+** vmovdqu %ymm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** vmovdqu \(%rsi\), %ymm3
+** vmovdqu 32\(%rsi\), %ymm2
+** vmovdqu -32\(%rsi,%rdx\), %ymm1
+** vmovdqu -64\(%rsi,%rdx\), %ymm0
+** vmovdqu %ymm3, \(%rdi\)
+** vmovdqu %ymm2, 32\(%rdi\)
+** vmovdqu %ymm1, -32\(%rdi,%rdx\)
+** vmovdqu %ymm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** vmovdqu \(%rax\), %ymm3
+** vmovdqu 32\(%rax\), %ymm2
+** leaq \(%rdi,%rdx\), %rcx
+** vmovdqu 64\(%rax\), %ymm1
+** vmovdqu 96\(%rax\), %ymm0
+** addq %rdx, %rax
+**.L9:
+** vmovdqu -32\(%rax\), %ymm7
+** vmovdqu -64\(%rax\), %ymm6
+** addq \$-128, %rsi
+** addq \$-128, %rcx
+** vmovdqu -96\(%rax\), %ymm5
+** vmovdqu -128\(%rax\), %ymm4
+** addq \$-128, %rax
+** vmovdqu %ymm7, 96\(%rcx\)
+** vmovdqu %ymm6, 64\(%rcx\)
+** vmovdqu %ymm5, 32\(%rcx\)
+** vmovdqu %ymm4, \(%rcx\)
+** cmpq \$128, %rsi
+** ja .L9
+** vmovdqu %ymm3, \(%rdi\)
+** vmovdqu %ymm2, 32\(%rdi\)
+** vmovdqu %ymm1, 64\(%rdi\)
+** vmovdqu %ymm0, 96\(%rdi\)
+** vzeroupper
+** ret
+** .cfi_endproc
+**.LFE0:
+**...
+*/
+
+#define gcc_memmove gcc_memmove_ymm
+#include "builtin-memmove-5a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-5c.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-5c.c
new file mode 100644
index 0000000..a8443f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-5c.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mmove-max=512 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove_zmm:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$67, %rdx
+** ja .L14
+**.L12:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L14:
+** movq %rdi, %rcx
+** movq %rsi, %rax
+** cmpq \$128, %rdx
+** jbe .L15
+** cmpq \$512, %rdx
+** ja .L5
+** cmpq \$256, %rdx
+** jnb .L16
+** vmovdqu64 \(%rsi\), %zmm3
+** vmovdqu64 64\(%rsi\), %zmm2
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm3, \(%rdi\)
+** vmovdqu64 %zmm2, 64\(%rdi\)
+** vmovdqu64 %zmm1, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -128\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L15:
+** vmovdqu64 \(%rsi\), %zmm1
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm1, \(%rdi\)
+** vmovdqu64 %zmm0, -64\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movq %rdx, %rsi
+** cmpq %rdi, %rax
+** jb .L7
+** je .L12
+** vmovdqu64 -64\(%rax,%rdx\), %zmm7
+** vmovdqu64 -128\(%rax,%rdx\), %zmm6
+** vmovdqu64 -192\(%rax,%rdx\), %zmm5
+** vmovdqu64 -256\(%rax,%rdx\), %zmm4
+**.L8:
+** vmovdqu64 \(%rax\), %zmm3
+** addq \$256, %rax
+** vmovdqu64 -192\(%rax\), %zmm2
+** subq \$256, %rsi
+** vmovdqu64 -128\(%rax\), %zmm1
+** vmovdqu64 -64\(%rax\), %zmm0
+** addq \$256, %rcx
+** vmovdqu64 %zmm3, -256\(%rcx\)
+** vmovdqu64 %zmm2, -192\(%rcx\)
+** vmovdqu64 %zmm1, -128\(%rcx\)
+** vmovdqu64 %zmm0, -64\(%rcx\)
+** cmpq \$256, %rsi
+** ja .L8
+** vmovdqu64 %zmm7, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm6, -128\(%rdi,%rdx\)
+** vmovdqu64 %zmm5, -192\(%rdi,%rdx\)
+** vmovdqu64 %zmm4, -256\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** vmovdqu64 \(%rax\), %zmm3
+** leaq \(%rdi,%rdx\), %rcx
+** vmovdqu64 64\(%rax\), %zmm2
+** vmovdqu64 128\(%rax\), %zmm1
+** vmovdqu64 192\(%rax\), %zmm0
+** addq %rdx, %rax
+**.L9:
+** vmovdqu64 -64\(%rax\), %zmm7
+** subq \$256, %rax
+** vmovdqu64 128\(%rax\), %zmm6
+** subq \$256, %rsi
+** vmovdqu64 64\(%rax\), %zmm5
+** vmovdqu64 \(%rax\), %zmm4
+** subq \$256, %rcx
+** vmovdqu64 %zmm7, 192\(%rcx\)
+** vmovdqu64 %zmm6, 128\(%rcx\)
+** vmovdqu64 %zmm5, 64\(%rcx\)
+** vmovdqu64 %zmm4, \(%rcx\)
+** cmpq \$256, %rsi
+** ja .L9
+** vmovdqu64 %zmm3, \(%rdi\)
+** vmovdqu64 %zmm2, 64\(%rdi\)
+** vmovdqu64 %zmm1, 128\(%rdi\)
+** vmovdqu64 %zmm0, 192\(%rdi\)
+** vzeroupper
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L16:
+** vmovdqu64 \(%rsi\), %zmm7
+** vmovdqu64 64\(%rsi\), %zmm6
+** vmovdqu64 -64\(%rsi,%rdx\), %zmm3
+** vmovdqu64 -128\(%rsi,%rdx\), %zmm2
+** vmovdqu64 128\(%rsi\), %zmm5
+** vmovdqu64 192\(%rsi\), %zmm4
+** vmovdqu64 -192\(%rsi,%rdx\), %zmm1
+** vmovdqu64 -256\(%rsi,%rdx\), %zmm0
+** vmovdqu64 %zmm7, \(%rdi\)
+** vmovdqu64 %zmm6, 64\(%rdi\)
+** vmovdqu64 %zmm5, 128\(%rdi\)
+** vmovdqu64 %zmm4, 192\(%rdi\)
+** vmovdqu64 %zmm3, -64\(%rdi,%rdx\)
+** vmovdqu64 %zmm2, -128\(%rdi,%rdx\)
+** vmovdqu64 %zmm1, -192\(%rdi,%rdx\)
+** vmovdqu64 %zmm0, -256\(%rdi,%rdx\)
+** vzeroupper
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define gcc_memmove gcc_memmove_zmm
+#include "builtin-memmove-5a.c"
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-6.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-6.c
new file mode 100644
index 0000000..6d15916
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-6.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$7, %rdx
+** jbe .L8
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** cmpl \$4, %edx
+** jnb .L9
+** cmpl \$1, %edx
+** ja .L5
+** jb .L1
+** movzbl \(%rsi\), %eax
+** movb %al, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L9:
+** movl %edx, %edx
+** movl \(%rsi\), %ecx
+** movl -4\(%rsi,%rdx\), %eax
+** movl %ecx, \(%rdi\)
+** movl %eax, -4\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movl %edx, %edx
+** movzwl \(%rsi\), %ecx
+** movzwl -2\(%rsi,%rdx\), %eax
+** movw %cx, \(%rdi\)
+** movw %ax, -2\(%rdi,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n < 8)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-7.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-7.c
new file mode 100644
index 0000000..4118b13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-7.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$3, %rdx
+** jbe .L7
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** cmpl \$2, %edx
+** jnb .L8
+** cmpl \$1, %edx
+** jb .L1
+** movzbl \(%rsi\), %eax
+** movb %al, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** movl %edx, %edx
+** movzwl \(%rsi\), %ecx
+** movzwl -2\(%rsi,%rdx\), %eax
+** movw %cx, \(%rdi\)
+** movw %ax, -2\(%rdi,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n < 4)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-8.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-8.c
new file mode 100644
index 0000000..aa57a10
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-8.c
@@ -0,0 +1,90 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$33, %rdx
+** jbe .L12
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L12:
+** cmpl \$16, %edx
+** jnb .L13
+** cmpl \$8, %edx
+** jnb .L6
+** cmpl \$4, %edx
+** jnb .L7
+** cmpl \$1, %edx
+** ja .L8
+** jb .L1
+** movzbl \(%rsi\), %eax
+** movb %al, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L13:
+** cmpl \$32, %edx
+** ja .L5
+** movl %edx, %edx
+** movdqu \(%rsi\), %xmm1
+** movdqu -16\(%rsi,%rdx\), %xmm0
+** movups %xmm1, \(%rdi\)
+** movups %xmm0, -16\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movl %edx, %edx
+** movdqu \(%rsi\), %xmm3
+** movdqu 16\(%rsi\), %xmm2
+** addq %rdx, %rsi
+** movdqu -16\(%rsi\), %xmm1
+** movdqu -32\(%rsi\), %xmm0
+** movups %xmm3, \(%rdi\)
+** movups %xmm2, 16\(%rdi\)
+** movups %xmm1, -16\(%rdi,%rdx\)
+** movups %xmm0, -32\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movl %edx, %edx
+** movq \(%rsi\), %rcx
+** movq -8\(%rsi,%rdx\), %rax
+** movq %rcx, \(%rdi\)
+** movq %rax, -8\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L7:
+** movl %edx, %edx
+** movl \(%rsi\), %ecx
+** movl -4\(%rsi,%rdx\), %eax
+** movl %ecx, \(%rdi\)
+** movl %eax, -4\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L8:
+** movl %edx, %edx
+** movzwl \(%rsi\), %ecx
+** movzwl -2\(%rsi,%rdx\), %eax
+** movw %cx, \(%rdi\)
+** movw %ax, -2\(%rdi,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n < 34)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-memmove-9.c b/gcc/testsuite/gcc.target/i386/builtin-memmove-9.c
new file mode 100644
index 0000000..f84565e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-memmove-9.c
@@ -0,0 +1,63 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -minline-all-stringops" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target { lp64 } } {^\t?\.} } } */
+
+/*
+**gcc_memmove:
+**.LFB0:
+** .cfi_startproc
+** cmpq \$15, %rdx
+** jbe .L9
+**.L1:
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L9:
+** cmpl \$8, %edx
+** jnb .L10
+** cmpl \$4, %edx
+** jnb .L5
+** cmpl \$1, %edx
+** ja .L6
+** jb .L1
+** movzbl \(%rsi\), %eax
+** movb %al, \(%rdi\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L10:
+** movl %edx, %edx
+** movq \(%rsi\), %rcx
+** movq -8\(%rsi,%rdx\), %rax
+** movq %rcx, \(%rdi\)
+** movq %rax, -8\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L5:
+** movl %edx, %edx
+** movl \(%rsi\), %ecx
+** movl -4\(%rsi,%rdx\), %eax
+** movl %ecx, \(%rdi\)
+** movl %eax, -4\(%rdi,%rdx\)
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L6:
+** movl %edx, %edx
+** movzwl \(%rsi\), %ecx
+** movzwl -2\(%rsi,%rdx\), %eax
+** movw %cx, \(%rdi\)
+** movw %ax, -2\(%rdi,%rdx\)
+** ret
+** .cfi_endproc
+**...
+*/
+
+void
+gcc_memmove (void *a, void *b, __SIZE_TYPE__ n)
+{
+ if (n < 16)
+ __builtin_memmove (a, b, n);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr122518.c b/gcc/testsuite/gcc.target/i386/pr122518.c
new file mode 100644
index 0000000..2791889
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr122518.c
@@ -0,0 +1,15 @@
+/* PR target/122518 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+inline unsigned min (unsigned a, unsigned b)
+{
+ return (a < b) ? a : b;
+}
+
+unsigned uminsub (unsigned a, unsigned b)
+{
+ return min (a - b, a);
+}
+
+/* { dg-final { scan-assembler-not "cmp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr122534.c b/gcc/testsuite/gcc.target/i386/pr122534.c
new file mode 100644
index 0000000..b1988fb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr122534.c
@@ -0,0 +1,15 @@
+/* PR target/122534 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int test (unsigned long p[6], int index)
+{
+ __SIZE_TYPE__ i;
+
+ for (i = 0; i < 6; i++)
+ if (p[i] & (1UL << index))
+ return i;
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "and" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/and-large-immediate-opt.c b/gcc/testsuite/gcc.target/loongarch/and-large-immediate-opt.c
new file mode 100644
index 0000000..921bef6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/and-large-immediate-opt.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-O3" } */
+/* { dg-final { scan-assembler-not "\tlu12i.w" } } */
+/* { dg-final { scan-assembler-not "\tori" } } */
+/* { dg-final { scan-assembler-not "\tlu52i.d" } } */
+/* { dg-final { scan-assembler-not "\tand" } } */
+/* { dg-final { scan-assembler "\tbstrpick.d" } } */
+/* { dg-final { scan-assembler "\tbstrins.d" } } */
+
+long
+test (long a)
+{
+ return a & 0x3fffffffefffffff;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/extendsidi2-combine.c b/gcc/testsuite/gcc.target/loongarch/extendsidi2-combine.c
new file mode 100644
index 0000000..0c3613c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/extendsidi2-combine.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-O3 -fno-strict-aliasing" } */
+
+int
+test (double a)
+{
+ int z;
+
+ *((double *)&z) = a;
+ return z;
+}
+
+/* { dg-final { scan-assembler-not "slli\\.w" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/imm-load.c b/gcc/testsuite/gcc.target/loongarch/imm-load.c
index 33291fe..a125840 100644
--- a/gcc/testsuite/gcc.target/loongarch/imm-load.c
+++ b/gcc/testsuite/gcc.target/loongarch/imm-load.c
@@ -7,5 +7,5 @@ test (void)
{
return 0x1234567890abcdef;
}
-/* { dg-final { scan-rtl-dump-times "scanning new insn with uid" 6 "split1" } } */
+/* { dg-final { scan-rtl-dump-times "scanning new insn with uid" 4 "split1" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-xvpermi_q-opt.c b/gcc/testsuite/gcc.target/loongarch/lasx-xvpermi_q-opt.c
new file mode 100644
index 0000000..16fb9df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/lasx-xvpermi_q-opt.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mlasx -ftree-vectorize" } */
+
+#include <lasxintrin.h>
+
+#define TEST_FUNC(imm) \
+ __m256i \
+ test_##imm (__m256i op0, __m256i op1) \
+ { \
+ return __lasx_xvpermi_q (op0, op1, imm); \
+ }
+
+TEST_FUNC (0x00)
+/* { dg-final { scan-assembler-not "test_0x00:.*\txvld.*xvld.*-test_0x00"} } */
+/* { dg-final { scan-assembler-times "test_0x00:.*\txvpermi\\.d.*-test_0x00" 1 } } */
+
+TEST_FUNC (0x01)
+/* { dg-final { scan-assembler-not "test_0x01:.*\txvld.*xvld.*-test_0x01"} } */
+/* { dg-final { scan-assembler-times "test_0x01:.*\txvpermi\\.d.*-test_0x01" 1 } } */
+
+TEST_FUNC (0x10)
+/* { dg-final { scan-assembler-not "test_0x10:.*\txvld.*xvld.*-test_0x10"} } */
+/* { dg-final { scan-assembler-not "test_0x10:.*\txvpermi.*-test_0x10"} } */
+
+TEST_FUNC (0x11)
+/* { dg-final { scan-assembler-not "test_0x11:.*\txvld.*xvld.*-test_0x11"} } */
+/* { dg-final { scan-assembler-times "test_0x11:.*\txvpermi\\.d.*-test_0x11" 1 } } */
+
+TEST_FUNC (0x22)
+/* { dg-final { scan-assembler-not "test_0x22:.*\txvld.*xvld.*-test_0x22"} } */
+/* { dg-final { scan-assembler-times "test_0x22:.*\txvpermi\\.d.*-test_0x22" 1 } } */
+
+TEST_FUNC (0x23)
+/* { dg-final { scan-assembler-not "test_0x23:.*\txvld.*xvld.*-test_0x23"} } */
+/* { dg-final { scan-assembler-times "test_0x23:.*\txvpermi\\.d.*-test_0x23" 1 } } */
+
+TEST_FUNC (0x32)
+/* { dg-final { scan-assembler-not "test_0x32:.*\txvld.*xvld.*-test_0x32"} } */
+/* { dg-final { scan-assembler-not "test_0x32:.*\txvpermi.*-test_0x32"} } */
+
+TEST_FUNC (0x33)
+/* { dg-final { scan-assembler-not "test_0x33:.*\txvld.*xvld.*-test_0x33"} } */
+/* { dg-final { scan-assembler-times "test_0x33:.*\txvpermi\\.d.*-test_0x33" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c b/gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c
new file mode 100644
index 0000000..9b3a5cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { scan-assembler-not "bstrpick" } } */
+/* { dg-final { scan-assembler "ld\\.wu" } } */
+
+struct st
+{
+ char const *name;
+};
+struct fst
+{
+ struct st *groups;
+};
+
+struct fst *pfunc (int);
+
+const char *
+test (int pc, unsigned group)
+{
+ struct fst *pci = pfunc (pc);
+
+ return pci->groups[group].name;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c b/gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c
new file mode 100644
index 0000000..d6a6577
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-O3 -mno-lsx" } */
+/* { dg-final { scan-assembler-not "stptr\.d" } } */
+/* { dg-final { scan-assembler-not "fld\.d" } } */
+/* { dg-final { scan-assembler-not "fst\.d" } } */
+/* { dg-final { scan-assembler-not "ldptr\.d" } } */
+/* { dg-final { scan-assembler "movgr2fr\.d" } } */
+/* { dg-final { scan-assembler "movfr2gr\.d" } } */
+
+typedef double vec __attribute__ ((vector_size(16)));
+
+vec
+foo (vec x, double a)
+{
+ x[0] -= a;
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/mulh_wu.c b/gcc/testsuite/gcc.target/loongarch/mulh_wu.c
new file mode 100644
index 0000000..53fc518
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/mulh_wu.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-O3 -mabi=lp64d" } */
+/* { dg-final { scan-assembler "\tmulh.wu" } } */
+/* { dg-final { scan-assembler-not "\tlu32i.d" } } */
+
+unsigned int
+test (unsigned int *a)
+{
+ return *a / 60;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/spill-less.c b/gcc/testsuite/gcc.target/loongarch/spill-less.c
new file mode 100644
index 0000000..77eb9b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/spill-less.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-O3 -fno-strict-aliasing" } */
+
+double
+convert (long long in)
+{
+ double f;
+ *((long long *)&f) = in;
+ return f;
+}
+
+/* { dg-final { scan-assembler-not "st\\.d" } } */
+/* { dg-final { scan-assembler-not "fld\\.d" } } */
+/* { dg-final { scan-assembler "movgr2fr\\.d" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/vec_pack_unpack_256.c b/gcc/testsuite/gcc.target/loongarch/vec_pack_unpack_256.c
index 506b7bd..5b2fd9b 100644
--- a/gcc/testsuite/gcc.target/loongarch/vec_pack_unpack_256.c
+++ b/gcc/testsuite/gcc.target/loongarch/vec_pack_unpack_256.c
@@ -55,7 +55,8 @@ test_vec_unpacks_float_hi_lo_v8si (void)
}
/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8si:.*\tvext2xv\\.d\\.w.*-test_vec_unpacks_hi_lo_v8si" } } */
-/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8si:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v8si" } } */
+/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8si:.*\txvpermi\\.d.*-test_vec_unpacks_hi_lo_v8si" } } */
+/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v8si:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v8si" } } */
void
test_vec_unpacks_hi_lo_v8si (void)
{
@@ -64,7 +65,8 @@ test_vec_unpacks_hi_lo_v8si (void)
}
/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v16hi:.*\tvext2xv\\.w\\.h.*-test_vec_unpacks_hi_lo_v16hi" } } */
-/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v16hi:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v16hi" } } */
+/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v16hi:.*\txvpermi\\.d.*-test_vec_unpacks_hi_lo_v16hi" } } */
+/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v16hi:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v16hi" } } */
void
test_vec_unpacks_hi_lo_v16hi (void)
{
@@ -73,7 +75,8 @@ test_vec_unpacks_hi_lo_v16hi (void)
}
/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v32qi:.*\tvext2xv\\.h\\.b.*-test_vec_unpacks_hi_lo_v32qi" } } */
-/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v32qi:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v32qi" } } */
+/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v32qi:.*\txvpermi\\.d.*-test_vec_unpacks_hi_lo_v32qi" } } */
+/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v32qi:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v32qi" } } */
void
test_vec_unpacks_hi_lo_v32qi (void)
{
@@ -91,7 +94,8 @@ test_vec_unpacks_hi_lo_v8sf (void)
}
/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v8si:.*\tvext2xv\\.du\\.wu.*-test_vec_unpacku_hi_lo_v8si" } } */
-/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v8si:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v8si" } } */
+/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v8si:.*\txvpermi\\.d.*-test_vec_unpacku_hi_lo_v8si" } } */
+/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v8si:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v8si" } } */
void
test_vec_unpacku_hi_lo_v8si (void)
{
@@ -100,7 +104,8 @@ test_vec_unpacku_hi_lo_v8si (void)
}
/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v16hi:.*\tvext2xv\\.wu\\.hu.*-test_vec_unpacku_hi_lo_v16hi" } } */
-/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v16hi:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v16hi" } } */
+/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v16hi:.*\txvpermi\\.d.*-test_vec_unpacku_hi_lo_v16hi" } } */
+/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v16hi:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v16hi" } } */
void
test_vec_unpacku_hi_lo_v16hi (void)
{
@@ -109,7 +114,8 @@ test_vec_unpacku_hi_lo_v16hi (void)
}
/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v32qi:.*\tvext2xv\\.hu\\.bu.*-test_vec_unpacku_hi_lo_v32qi" } } */
-/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v32qi:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v32qi" } } */
+/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v32qi:.*\txvpermi\\.d.*-test_vec_unpacku_hi_lo_v32qi" } } */
+/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v32qi:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v32qi" } } */
void
test_vec_unpacku_hi_lo_v32qi (void)
{
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-builtin.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-builtin.c
index 64ff870..3f34a43 100644
--- a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-builtin.c
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-builtin.c
@@ -3301,7 +3301,7 @@ __lasx_vext2xv_du_bu (v32i8 _1)
v32i8
__lasx_xvpermi_q (v32i8 _1, v32i8 _2)
{
- return __builtin_lasx_xvpermi_q (_1, _2, 1);
+ return __builtin_lasx_xvpermi_q (_1, _2, 0x20);
}
v4i64
__lasx_xvpermi_d (v4i64 _1)
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256-result.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256-result.c
new file mode 100644
index 0000000..e876c4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256-result.c
@@ -0,0 +1,68 @@
+/* { dg-options "-mabi=lp64d -O2 -mlasx -w -fno-strict-aliasing" } */
+
+#include "../simd_correctness_check.h"
+#include <lasxintrin.h>
+
+int
+main ()
+{
+ __m128i __m128i_op0, __m128i_op1, __m128i_op2, __m128i_out, __m128i_result;
+ __m128 __m128_op0, __m128_op1, __m128_op2, __m128_out, __m128_result;
+ __m128d __m128d_op0, __m128d_op1, __m128d_op2, __m128d_out, __m128d_result;
+
+ __m256i __m256i_op0, __m256i_op1, __m256i_op2, __m256i_out, __m256i_result;
+ __m256 __m256_op0, __m256_op1, __m256_op2, __m256_out, __m256_result;
+ __m256d __m256d_op0, __m256d_op1, __m256d_op2, __m256d_out, __m256d_result;
+
+ //__m128_op0={1,2,3,4},__m128_op1={5,6,7,8};
+ *((int *)&__m128_op0[3]) = 0x40800000;
+ *((int *)&__m128_op0[2]) = 0x40400000;
+ *((int *)&__m128_op0[1]) = 0x40000000;
+ *((int *)&__m128_op0[0]) = 0x3f800000;
+ *((int *)&__m128_op1[3]) = 0x41000000;
+ *((int *)&__m128_op1[2]) = 0x40e00000;
+ *((int *)&__m128_op1[1]) = 0x40c00000;
+ *((int *)&__m128_op1[0]) = 0x40a00000;
+ *((int *)&__m256_result[7]) = 0x41000000;
+ *((int *)&__m256_result[6]) = 0x40e00000;
+ *((int *)&__m256_result[5]) = 0x40c00000;
+ *((int *)&__m256_result[4]) = 0x40a00000;
+ *((int *)&__m256_result[3]) = 0x40800000;
+ *((int *)&__m256_result[2]) = 0x40400000;
+ *((int *)&__m256_result[1]) = 0x40000000;
+ *((int *)&__m256_result[0]) = 0x3f800000;
+ __m256_out = __lasx_concat_128_s (__m128_op0, __m128_op1);
+ ASSERTEQ_32 (__LINE__, __m256_result, __m256_out);
+ __m256_out = __lasx_cast_128_s (__m128_op0);
+ ASSERTEQ_32 (__LINE__, __m256_out, __m128_op0);
+
+ //__m128i_op0={1,2},__m128i_op1={3,4};
+ *((unsigned long *)&__m128i_op0[1]) = 0x2;
+ *((unsigned long *)&__m128i_op0[0]) = 0x1;
+ *((unsigned long *)&__m128i_op1[1]) = 0x4;
+ *((unsigned long *)&__m128i_op1[0]) = 0x3;
+ *((unsigned long *)&__m256i_result[3]) = 0x4;
+ *((unsigned long *)&__m256i_result[2]) = 0x3;
+ *((unsigned long *)&__m256i_result[1]) = 0x2;
+ *((unsigned long *)&__m256i_result[0]) = 0x1;
+ __m256i_out = __lasx_concat_128 (__m128i_op0, __m128i_op1);
+ ASSERTEQ_64 (__LINE__, __m256i_result, __m256i_out);
+ __m256i_out = __lasx_cast_128 (__m128i_op0);
+ ASSERTEQ_64 (__LINE__, __m256i_out, __m128i_op0);
+
+ //__m128d_op0={1,2},__m128i_op1={3,4};
+ *((unsigned long *)&__m128d_op0[1]) = 0x4000000000000000;
+ *((unsigned long *)&__m128d_op0[0]) = 0x3ff0000000000000;
+ *((unsigned long *)&__m128d_op1[1]) = 0x4010000000000000;
+ *((unsigned long *)&__m128d_op1[0]) = 0x4008000000000000;
+ *((unsigned long *)&__m256d_result[3]) = 0x4010000000000000;
+ *((unsigned long *)&__m256d_result[2]) = 0x4008000000000000;
+ *((unsigned long *)&__m256d_result[1]) = 0x4000000000000000;
+ *((unsigned long *)&__m256d_result[0]) = 0x3ff0000000000000;
+ __m256d_out = __lasx_concat_128_d (__m128d_op0, __m128d_op1);
+ ASSERTEQ_64 (__LINE__, __m256d_result, __m256d_out);
+ __m256d_out = __lasx_cast_128_d (__m128d_op0);
+ ASSERTEQ_64 (__LINE__, __m256d_out, __m128d_op0);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256.c
new file mode 100644
index 0000000..5d8cbb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-concat-128-256.c
@@ -0,0 +1,92 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-mabi=lp64d -O2 -mlasx" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <lasxintrin.h>
+
+/*
+**foo1:
+** vinsgr2vr.d (\$vr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,1
+** vinsgr2vr.d (\$vr[0-9]+),\$r8,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x02
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256
+foo1 (__m128 x, __m128 y)
+{
+ return __builtin_lasx_concat_128_s (x, y);
+}
+
+/*
+**foo2:
+** vinsgr2vr.d (\$vr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,1
+** vinsgr2vr.d (\$vr[0-9]+),\$r8,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x02
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256d
+foo2 (__m128d x, __m128d y)
+{
+ return __builtin_lasx_concat_128_d (x, y);
+}
+
+/*
+**foo3:
+** vinsgr2vr.d (\$vr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,1
+** vinsgr2vr.d (\$vr[0-9]+),\$r8,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x02
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256i
+foo3 (__m128i x, __m128i y)
+{
+ return __builtin_lasx_concat_128 (x, y);
+}
+
+/*
+**foo4:
+** vinsgr2vr.d (\$vr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,1
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256
+foo4 (__m128 x)
+{
+ return __builtin_lasx_cast_128_s (x);
+}
+
+/*
+**foo5:
+** vinsgr2vr.d (\$vr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,1
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256d
+foo5 (__m128d x)
+{
+ return __builtin_lasx_cast_128_d (x);
+}
+
+/*
+**foo6:
+** vinsgr2vr.d (\$vr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,1
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256i
+foo6 (__m128i x)
+{
+ return __builtin_lasx_cast_128 (x);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128-result.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128-result.c
new file mode 100644
index 0000000..61064d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128-result.c
@@ -0,0 +1,69 @@
+/* { dg-options "-mabi=lp64d -O2 -mlasx -w -fno-strict-aliasing" } */
+
+#include "../simd_correctness_check.h"
+#include <lasxintrin.h>
+
+extern void abort (void);
+int
+main ()
+{
+ __m128i __m128i_result0, __m128i_result1, __m128i_out, __m128i_result;
+ __m128 __m128_result0, __m128_result1, __m128_out, __m128_result;
+ __m128d __m128d_result0, __m128d_result1, __m128d_out, __m128d_result;
+
+ __m256i __m256i_op0, __m256i_op1, __m256i_op2, __m256i_out, __m256i_result;
+ __m256 __m256_op0, __m256_op1, __m256_op2, __m256_out, __m256_result;
+ __m256d __m256d_op0, __m256d_op1, __m256d_op2, __m256d_out, __m256d_result;
+
+ //__m256_op0 = {1,2,3,4,5,6,7,8};
+ *((int *)&__m256_op0[7]) = 0x41000000;
+ *((int *)&__m256_op0[6]) = 0x40e00000;
+ *((int *)&__m256_op0[5]) = 0x40c00000;
+ *((int *)&__m256_op0[4]) = 0x40a00000;
+ *((int *)&__m256_op0[3]) = 0x40800000;
+ *((int *)&__m256_op0[2]) = 0x40400000;
+ *((int *)&__m256_op0[1]) = 0x40000000;
+ *((int *)&__m256_op0[0]) = 0x3f800000;
+ *((int *)&__m128_result1[3]) = 0x41000000;
+ *((int *)&__m128_result1[2]) = 0x40e00000;
+ *((int *)&__m128_result1[1]) = 0x40c00000;
+ *((int *)&__m128_result1[0]) = 0x40a00000;
+ *((int *)&__m128_result0[3]) = 0x40800000;
+ *((int *)&__m128_result0[2]) = 0x40400000;
+ *((int *)&__m128_result0[1]) = 0x40000000;
+ *((int *)&__m128_result0[0]) = 0x3f800000;
+ __m128_out = __lasx_extract_128_lo_s (__m256_op0);
+ ASSERTEQ_32 (__LINE__, __m128_result0, __m128_out);
+ __m128_out = __lasx_extract_128_hi_s (__m256_op0);
+ ASSERTEQ_32 (__LINE__, __m128_result1, __m128_out);
+
+ //__m256i_op0 = {1,2,3,4};
+ *((unsigned long *)&__m256i_op0[3]) = 0x4;
+ *((unsigned long *)&__m256i_op0[2]) = 0x3;
+ *((unsigned long *)&__m256i_op0[1]) = 0x2;
+ *((unsigned long *)&__m256i_op0[0]) = 0x1;
+ *((unsigned long *)&__m128i_result0[1]) = 0x2;
+ *((unsigned long *)&__m128i_result0[0]) = 0x1;
+ *((unsigned long *)&__m128i_result1[1]) = 0x4;
+ *((unsigned long *)&__m128i_result1[0]) = 0x3;
+ __m128i_out = __lasx_extract_128_lo (__m256i_op0);
+ ASSERTEQ_64 (__LINE__, __m128i_result0, __m128i_out);
+ __m128i_out = __lasx_extract_128_hi (__m256i_op0);
+ ASSERTEQ_64 (__LINE__, __m128i_result1, __m128i_out);
+
+ //__m256d_op0 = {1,2,3,4};
+ *((unsigned long *)&__m256d_op0[3]) = 0x4010000000000000;
+ *((unsigned long *)&__m256d_op0[2]) = 0x4008000000000000;
+ *((unsigned long *)&__m256d_op0[1]) = 0x4000000000000000;
+ *((unsigned long *)&__m256d_op0[0]) = 0x3ff0000000000000;
+ *((unsigned long *)&__m128d_result0[1]) = 0x4000000000000000;
+ *((unsigned long *)&__m128d_result0[0]) = 0x3ff0000000000000;
+ *((unsigned long *)&__m128d_result1[1]) = 0x4010000000000000;
+ *((unsigned long *)&__m128d_result1[0]) = 0x4008000000000000;
+ __m128d_out = __lasx_extract_128_lo_d (__m256d_op0);
+ ASSERTEQ_64 (__LINE__, __m128d_result0, __m128d_out);
+ __m128d_out = __lasx_extract_128_hi_d (__m256d_op0);
+ ASSERTEQ_64 (__LINE__, __m128d_result1, __m128d_out);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128.c
new file mode 100644
index 0000000..d2219ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract-256-128.c
@@ -0,0 +1,86 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-mabi=lp64d -O2 -mlasx" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <lasxintrin.h>
+
+/*
+**foo1_lo:
+** vld (\$vr[0-9]+),\$r4,0
+** vpickve2gr.du \$r4,(\$vr[0-9]+),0
+** vpickve2gr.du \$r5,(\$vr[0-9]+),1
+** jr \$r1
+*/
+__m128
+foo1_lo (__m256 x)
+{
+ return __lasx_extract_128_lo_s (x);
+}
+
+/*
+**foo1_hi:
+** xvld (\$xr[0-9]+),\$r4,0
+** xvpermi.d (\$xr[0-9]+),(\$xr[0-9]+),0xe
+** vpickve2gr.du \$r4,(\$vr[0-9]+),0
+** vpickve2gr.du \$r5,(\$vr[0-9]+),1
+** jr \$r1
+*/
+__m128
+foo1_hi (__m256 x)
+{
+ return __lasx_extract_128_hi_s (x);
+}
+
+/*
+**foo2_lo:
+** vld (\$vr[0-9]+),\$r4,0
+** vpickve2gr.du \$r4,(\$vr[0-9]+),0
+** vpickve2gr.du \$r5,(\$vr[0-9]+),1
+** jr \$r1
+*/
+__m128d
+foo2_lo (__m256d x)
+{
+ return __lasx_extract_128_lo_d (x);
+}
+
+/*
+**foo2_hi:
+** xvld (\$xr[0-9]+),\$r4,0
+** xvpermi.d (\$xr[0-9]+),(\$xr[0-9]+),0xe
+** vpickve2gr.du \$r4,(\$vr[0-9]+),0
+** vpickve2gr.du \$r5,(\$vr[0-9]+),1
+** jr \$r1
+*/
+__m128d
+foo2_hi (__m256d x)
+{
+ return __lasx_extract_128_hi_d (x);
+}
+
+/*
+**foo3_lo:
+** vld (\$vr[0-9]+),\$r4,0
+** vpickve2gr.du \$r4,(\$vr[0-9]+),0
+** vpickve2gr.du \$r5,(\$vr[0-9]+),1
+** jr \$r1
+*/
+__m128i
+foo3_lo (__m256i x)
+{
+ return __lasx_extract_128_lo (x);
+}
+
+/*
+**foo3_hi:
+** xvld (\$xr[0-9]+),\$r4,0
+** xvpermi.d (\$xr[0-9]+),(\$xr[0-9]+),0xe
+** vpickve2gr.du \$r4,(\$vr[0-9]+),0
+** vpickve2gr.du \$r5,(\$vr[0-9]+),1
+** jr \$r1
+*/
+__m128i
+foo3_hi (__m256i x)
+{
+ return __lasx_extract_128_hi (x);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256-result.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256-result.c
new file mode 100644
index 0000000..ce5abf9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256-result.c
@@ -0,0 +1,97 @@
+/* { dg-options "-mabi=lp64d -O2 -mlasx -w -fno-strict-aliasing" } */
+
+#include "../simd_correctness_check.h"
+#include <lasxintrin.h>
+
+extern void abort (void);
+int
+main ()
+{
+ __m128i __m128i_op0, __m128i_op1, __m128i_out;
+ __m128 __m128_op0, __m128_op1, __m128_out;
+ __m128d __m128d_op0, __m128d_op1, __m128d_out;
+
+ __m256i __m256i_op0, __m256i_result0, __m256i_result1, __m256i_out;
+ __m256 __m256_op0, __m256_result0, __m256_result1, __m256_out;
+ __m256d __m256d_op0, __m256d_result0, __m256d_result1, __m256d_out;
+
+ //__m256_op0 = {1,2,3,4,5,6,7,8}, __m128_op0 ={9,9,9,9};
+ *((int *)&__m256_op0[7]) = 0x41000000;
+ *((int *)&__m256_op0[6]) = 0x40e00000;
+ *((int *)&__m256_op0[5]) = 0x40c00000;
+ *((int *)&__m256_op0[4]) = 0x40a00000;
+ *((int *)&__m256_op0[3]) = 0x40800000;
+ *((int *)&__m256_op0[2]) = 0x40400000;
+ *((int *)&__m256_op0[1]) = 0x40000000;
+ *((int *)&__m256_op0[0]) = 0x3f800000;
+ *((int *)&__m128_op0[3]) = 0x41100000;
+ *((int *)&__m128_op0[2]) = 0x41100000;
+ *((int *)&__m128_op0[1]) = 0x41100000;
+ *((int *)&__m128_op0[0]) = 0x41100000;
+ *((int *)&__m256_result0[7]) = 0x41000000;
+ *((int *)&__m256_result0[6]) = 0x40e00000;
+ *((int *)&__m256_result0[5]) = 0x40c00000;
+ *((int *)&__m256_result0[4]) = 0x40a00000;
+ *((int *)&__m256_result0[3]) = 0x41100000;
+ *((int *)&__m256_result0[2]) = 0x41100000;
+ *((int *)&__m256_result0[1]) = 0x41100000;
+ *((int *)&__m256_result0[0]) = 0x41100000;
+ *((int *)&__m256_result1[7]) = 0x41100000;
+ *((int *)&__m256_result1[6]) = 0x41100000;
+ *((int *)&__m256_result1[5]) = 0x41100000;
+ *((int *)&__m256_result1[4]) = 0x41100000;
+ *((int *)&__m256_result1[3]) = 0x40800000;
+ *((int *)&__m256_result1[2]) = 0x40400000;
+ *((int *)&__m256_result1[1]) = 0x40000000;
+ *((int *)&__m256_result1[0]) = 0x3f800000;
+ __m256_out = __lasx_insert_128_lo_s (__m256_op0, __m128_op0);
+ ASSERTEQ_32 (__LINE__, __m256_result0, __m256_out);
+ __m256_out = __lasx_insert_128_hi_s (__m256_op0, __m128_op0);
+ ASSERTEQ_32 (__LINE__, __m256_result1, __m256_out);
+
+ //__m256i_op0 ={1,2,3,4},__m128i_op0={5,6},__m128i_op1={7,8};
+ *((unsigned long *)&__m256i_op0[3]) = 0x4;
+ *((unsigned long *)&__m256i_op0[2]) = 0x3;
+ *((unsigned long *)&__m256i_op0[1]) = 0x2;
+ *((unsigned long *)&__m256i_op0[0]) = 0x1;
+ *((unsigned long *)&__m128i_op0[1]) = 0x6;
+ *((unsigned long *)&__m128i_op0[0]) = 0x5;
+ *((unsigned long *)&__m128i_op1[1]) = 0x8;
+ *((unsigned long *)&__m128i_op1[0]) = 0x7;
+ *((unsigned long *)&__m256i_result0[3]) = 0x4;
+ *((unsigned long *)&__m256i_result0[2]) = 0x3;
+ *((unsigned long *)&__m256i_result0[1]) = 0x6;
+ *((unsigned long *)&__m256i_result0[0]) = 0x5;
+ *((unsigned long *)&__m256i_result1[3]) = 0x8;
+ *((unsigned long *)&__m256i_result1[2]) = 0x7;
+ *((unsigned long *)&__m256i_result1[1]) = 0x2;
+ *((unsigned long *)&__m256i_result1[0]) = 0x1;
+ __m256i_out = __lasx_insert_128_lo (__m256i_op0, __m128i_op0);
+ ASSERTEQ_64 (__LINE__, __m256i_result0, __m256i_out);
+ __m256i_out = __lasx_insert_128_hi (__m256i_op0, __m128i_op1);
+ ASSERTEQ_64 (__LINE__, __m256i_result1, __m256i_out);
+
+ //__m256d_op0 ={1,2,3,4},__m128d_op0={5,6},__m128d_op1={7,8};
+ *((unsigned long *)&__m256d_op0[3]) = 0x4010000000000000;
+ *((unsigned long *)&__m256d_op0[2]) = 0x4008000000000000;
+ *((unsigned long *)&__m256d_op0[1]) = 0x4000000000000000;
+ *((unsigned long *)&__m256d_op0[0]) = 0x3ff0000000000000;
+ *((unsigned long *)&__m128d_op0[1]) = 0x4018000000000000;
+ *((unsigned long *)&__m128d_op0[0]) = 0x4014000000000000;
+ *((unsigned long *)&__m128d_op1[1]) = 0x4020000000000000;
+ *((unsigned long *)&__m128d_op1[0]) = 0x401c000000000000;
+ *((unsigned long *)&__m256d_result0[3]) = 0x4010000000000000;
+ *((unsigned long *)&__m256d_result0[2]) = 0x4008000000000000;
+ *((unsigned long *)&__m256d_result0[1]) = 0x4018000000000000;
+ *((unsigned long *)&__m256d_result0[0]) = 0x4014000000000000;
+ *((unsigned long *)&__m256d_result1[3]) = 0x4020000000000000;
+ *((unsigned long *)&__m256d_result1[2]) = 0x401c000000000000;
+ *((unsigned long *)&__m256d_result1[1]) = 0x4000000000000000;
+ *((unsigned long *)&__m256d_result1[0]) = 0x3ff0000000000000;
+ __m256d_out = __lasx_insert_128_lo_d (__m256d_op0, __m128d_op0);
+ ASSERTEQ_64 (__LINE__, __m256d_result0, __m256d_out);
+ __m256d_out = __lasx_insert_128_hi_d (__m256d_op0, __m128d_op1);
+ ASSERTEQ_64 (__LINE__, __m256d_result1, __m256d_out);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256.c
new file mode 100644
index 0000000..326c855
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-insert-128-256.c
@@ -0,0 +1,95 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-mabi=lp64d -O2 -mlasx" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <lasxintrin.h>
+
+/*
+**foo1:
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,0
+** xvld (\$xr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x30
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256
+foo1 (__m256 x, __m128 y)
+{
+ return __builtin_lasx_insert_128_lo_s (x, y);
+}
+
+/*
+**foo2:
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,0
+** xvld (\$xr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x02
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256
+foo2 (__m256 x, __m128 y)
+{
+ return __builtin_lasx_insert_128_hi_s (x, y);
+}
+
+/*
+**foo3:
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,0
+** xvld (\$xr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x30
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256d
+foo3 (__m256d x, __m128d y)
+{
+ return __builtin_lasx_insert_128_lo_d (x, y);
+}
+
+/*
+**foo4:
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,0
+** xvld (\$xr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x02
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256d
+foo4 (__m256d x, __m128d y)
+{
+ return __builtin_lasx_insert_128_hi_d (x, y);
+}
+
+/*
+**foo5:
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,0
+** xvld (\$xr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x30
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256i
+foo5 (__m256i x, __m128i y)
+{
+ return __builtin_lasx_insert_128_lo (x, y);
+}
+
+/*
+**foo6:
+** vinsgr2vr.d (\$vr[0-9]+),\$r6,0
+** xvld (\$xr[0-9]+),\$r5,0
+** vinsgr2vr.d (\$vr[0-9]+),\$r7,1
+** xvpermi.q (\$xr[0-9]+),(\$xr[0-9]+),0x02
+** xvst (\$xr[0-9]+),\$r4,0
+** jr \$r1
+*/
+__m256i
+foo6 (__m256i x, __m128i y)
+{
+ return __builtin_lasx_insert_128_hi (x, y);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/rlwimi-2.c b/gcc/testsuite/gcc.target/powerpc/rlwimi-2.c
index bafa371..afbde0e 100644
--- a/gcc/testsuite/gcc.target/powerpc/rlwimi-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/rlwimi-2.c
@@ -6,7 +6,7 @@
/* { dg-final { scan-assembler-times {(?n)^\s+blr} 6750 } } */
/* { dg-final { scan-assembler-times {(?n)^\s+mr} 643 { target ilp32 } } } */
/* { dg-final { scan-assembler-times {(?n)^\s+mr} 11 { target lp64 } } } */
-/* { dg-final { scan-assembler-times {(?n)^\s+rldicl} 7790 { target lp64 } } } */
+/* { dg-final { scan-assembler-times {(?n)^\s+rldicl} 6754 { target lp64 } } } */
/* { dg-final { scan-assembler-times {(?n)^\s+rlwimi} 1692 { target ilp32 } } } */
/* { dg-final { scan-assembler-times {(?n)^\s+rlwimi} 1666 { target lp64 } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-1.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-1.c
new file mode 100644
index 0000000..4cea38e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Su2e_1f {
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ float f;
+};
+struct Su2e_1f echo_Su2e_1f(int i, float f, struct Su2e_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-2.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-2.c
new file mode 100644
index 0000000..e7271e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Su2e_2f {
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ float f;
+ float g;
+};
+struct Su2e_2f echo_Su2e_2f(int i, float f, struct Su2e_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-3.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-3.c
new file mode 100644
index 0000000..9743d4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-3.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smu2e_1f {
+ union {
+ struct {
+ } e1, e2;
+ } u1;
+ struct {
+ float f;
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ } ue;
+ union {
+ struct {
+ } e1, e2;
+ } u2;
+};
+struct Smu2e_1f echo_Smu2e_1f(int i, float f, struct Smu2e_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-4.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-4.c
new file mode 100644
index 0000000..081ea68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct+union-4.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smu2e_2f {
+ union {
+ struct {
+ } e1, e2;
+ } u1;
+ struct {
+ float f;
+ float g;
+ union {
+ struct {
+ } e1, e2;
+ } u;
+ } ue;
+ union {
+ struct {
+ } e1, e2;
+ } u2;
+};
+struct Smu2e_2f echo_Smu2e_2f(int i, float f, struct Smu2e_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-1.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-1.c
new file mode 100644
index 0000000..a0a4866
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Se_1f {
+ struct {
+ } e1;
+ float f;
+};
+struct Se_1f echo_Se_1f(int i, float f, struct Se_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-10.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-10.c
new file mode 100644
index 0000000..de8ad02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-10.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S1ae_2f {
+ struct {
+ } e1[1];
+ float f;
+ float g;
+};
+struct S1ae_2f echo_S1ae_2f(int i, float f, struct S1ae_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-11.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-11.c
new file mode 100644
index 0000000..c99bb22
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-11.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm1ae_1f {
+ struct {
+ } e1[1];
+ struct {
+ float f;
+ struct {
+ } e[1];
+ } fe;
+ struct {
+ } e2[1];
+};
+struct Sm1ae_1f echo_Sm1ae_1f(int i, float f, struct Sm1ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-12.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-12.c
new file mode 100644
index 0000000..065ff02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-12.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm1ae_2f {
+ struct {
+ } e1[1];
+ struct {
+ float f;
+ float g;
+ struct {
+ } e[1];
+ } fe;
+ struct {
+ } e2[1];
+};
+struct Sm1ae_2f echo_Sm1ae_2f(int i, float f, struct Sm1ae_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-2.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-2.c
new file mode 100644
index 0000000..93210fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Se_2f {
+ struct {
+ } e1;
+ float f;
+ float g;
+};
+struct Se_2f echo_Se_2f(int i, float f, struct Se_2f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-3.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-3.c
new file mode 100644
index 0000000..b8c3362
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sme_1f {
+ struct {
+ } e1;
+ struct {
+ float f;
+ struct {
+ } e;
+ } fe;
+ struct {
+ } e2;
+};
+struct Sme_1f echo_Sme_1f(int i, float f, struct Sme_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-4.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-4.c
new file mode 100644
index 0000000..0ce36d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-4.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sme_2f {
+ struct {
+ } e1;
+ struct {
+ float f;
+ float g;
+ struct {
+ } e;
+ } fe;
+ struct {
+ } e2;
+};
+struct Sme_2f echo_Sme_2f(int i, float f, struct Sme_2f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-5.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-5.c
new file mode 100644
index 0000000..0ae1e41
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-5.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S0ae_1f {
+ struct {
+ } e1[0];
+ float f;
+};
+struct S0ae_1f echo_S0ae_1f(int i, float f, struct S0ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-6.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-6.c
new file mode 100644
index 0000000..d3d0b65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-6.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S0ae_2f {
+ struct {
+ } e1[0];
+ float f;
+ float g;
+};
+struct S0ae_2f echo_S0ae_2f(int i, float f, struct S0ae_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-7.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-7.c
new file mode 100644
index 0000000..9eae13d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-7.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm0ae_1f {
+ struct {
+ } e1[0];
+ struct {
+ float f;
+ struct {
+ } e[0];
+ } fe;
+ struct {
+ } e2[0];
+};
+struct Sm0ae_1f echo_Sm0ae_1f(int i, float f, struct Sm0ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-8.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-8.c
new file mode 100644
index 0000000..e7c81f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-8.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Sm0ae_2f {
+ struct {
+ } e1[0];
+ struct {
+ float f;
+ float g;
+ struct {
+ } e[0];
+ } fe;
+ struct {
+ } e2[0];
+};
+struct Sm0ae_2f echo_Sm0ae_2f(int i, float f, struct Sm0ae_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-struct-9.c b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-9.c
new file mode 100644
index 0000000..55c4be4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-struct-9.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S1ae_1f {
+ struct {
+ } e1[1];
+ float f;
+};
+struct S1ae_1f echo_S1ae_1f(int i, float f, struct S1ae_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-union-1.c b/gcc/testsuite/gcc.target/riscv/abi/empty-union-1.c
new file mode 100644
index 0000000..17beb0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-union-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Seu_1f {
+ union {
+ } e1;
+ float f;
+};
+struct Seu_1f echo_Seu_1f(int i, float f, struct Seu_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-union-2.c b/gcc/testsuite/gcc.target/riscv/abi/empty-union-2.c
new file mode 100644
index 0000000..c583186
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-union-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct S2eu_2f {
+ union {
+ } e1;
+ float f;
+ float g;
+};
+struct S2eu_2f echo_S2eu_2f(int i, float f, struct S2eu_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-union-3.c b/gcc/testsuite/gcc.target/riscv/abi/empty-union-3.c
new file mode 100644
index 0000000..e9e189b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-union-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smeu_1f {
+ union {
+ } e1;
+ struct {
+ float f;
+ union {
+ } e;
+ } fe;
+ union {
+ } e2;
+};
+struct Smeu_1f echo_Smeu_1f(int i, float f, struct Smeu_1f s) {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/abi/empty-union-4.c b/gcc/testsuite/gcc.target/riscv/abi/empty-union-4.c
new file mode 100644
index 0000000..91c2d89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/abi/empty-union-4.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64g -mabi=lp64d -fdump-rtl-expand" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct Smeu_2f {
+ union {
+ } e1;
+ struct {
+ float f;
+ float g;
+ union {
+ } e;
+ } fe;
+ union {
+ } e2;
+};
+struct Smeu_2f echo_Smeu_2f(int i, float f, struct Smeu_2f s) /* { dg-warning "ABI for flattened empty union and zero length array changed in GCC 16" } */ {
+ return s;
+}
+
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa1 \[ s \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ .*\)[[:space:]]+\(reg.*:SF \d+ fa2 \[ s\+4 \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa0\)[[:space:]]+\(reg.*:SF \d+ \[ <retval> \]\)\)} "expand" } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg.*:SF \d+ fa1\)[[:space:]]+\(reg.*:SF \d+ \[ <retval>\+4 \]\)\)} "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr52345.c b/gcc/testsuite/gcc.target/riscv/pr52345.c
new file mode 100644
index 0000000..90feb91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr52345.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv64gcbv_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-O2 -march=rv32gcbv_zicond -mabi=ilp32" { target { rv32 } } } */
+
+int f(int a, int b)
+{
+ int c = a != 0;
+ int d = (c!=0|b!=0);
+ return d;
+}
+
+int h (int a, int b)
+{
+ int c = (a!=0|b);
+ int d = c==0;
+ return d;
+}
+
+/* { dg-final { scan-assembler-times {\tor} 2 } } */
+/* { dg-final { scan-assembler-times {\tsnez} 1 } } */
+/* { dg-final { scan-assembler-times {\tseqz} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr67731.c b/gcc/testsuite/gcc.target/riscv/pr67731.c
new file mode 100644
index 0000000..6f254fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr67731.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv64gcbv -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-O2 -march=rv32gcbv -mabi=ilp32" { target { rv32 } } } */
+
+typedef struct
+{
+ _Bool a : 1;
+ _Bool b : 1;
+ _Bool c : 1;
+ _Bool d : 1;
+ unsigned int e : 4;
+} S;
+
+_Bool test_00 (S* s)
+{
+ return s->b | s->c;
+}
+
+_Bool test_01 (S* s)
+{
+ return s->b | s->c | s->d;
+}
+/* { dg-final { scan-assembler-times {\tlw\ta0,0\(a0\).*?\n\tandi\ta0,a0,\d+.*?\n\tsnez\ta0,a0.*?\n\tret} 2 } } */
+/* { dg-final { scan-assembler-not {\tor} } } */
+/* { dg-final { scan-assembler-not {\tbexti} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/riscv.exp b/gcc/testsuite/gcc.target/riscv/riscv.exp
index b5e7618..dd8443d 100644
--- a/gcc/testsuite/gcc.target/riscv/riscv.exp
+++ b/gcc/testsuite/gcc.target/riscv/riscv.exp
@@ -42,6 +42,8 @@ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/sched1-spills/*.{\[cS\],
"" $DEFAULT_CFLAGS
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/xandes/*.\[cS\]]] \
"" $DEFAULT_CFLAGS
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/abi/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
# Saturation alu
foreach opt {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122321.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122321.c
new file mode 100644
index 0000000..0e34bc1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122321.c
@@ -0,0 +1,150 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -w -O0" { target rv64 } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -w -O0" { target rv32 } } */
+
+
+typedef int a;
+typedef signed char b;
+typedef char c;
+typedef short d;
+typedef unsigned short e;
+typedef a f;
+typedef unsigned g;
+typedef long h;
+h j, k, l, m, n, o;
+int p, q, r, s;
+short t;
+volatile a u;
+a v[];
+char w, x;
+a *y, *z;
+a **aa;
+__attribute__((always_inline)) b __attribute__((vector_size(16)))
+ab(f __attribute__((vector_size(8 * sizeof(f)))), d ac,
+ d __attribute__((vector_size(2 * sizeof(d)))), d) {
+ return __builtin_shufflevector(
+ (b __attribute__((vector_size(16)))) __builtin_convertvector(
+ (d __attribute__((vector_size(16 *sizeof(d))))){
+ ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
+ c __attribute__((vector_size(16)))) |
+ __builtin_convertvector(
+ (d __attribute__((vector_size(16 *sizeof(d))))){
+ ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
+ c __attribute__((vector_size(16)))),
+ __builtin_convertvector(
+ (d __attribute__((vector_size(16 *sizeof(d))))){
+ ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
+ b __attribute__((vector_size(16)))),
+ 3, 21, 0, 2, 2, 7, 1, 8, 4, 0, 8, 0, 8, 9, 5, 6);
+}
+__attribute__((always_inline)) g
+ad(d ae, h __attribute__((vector_size(32 * sizeof(h))))) {
+ g f = 6318;
+ return (8 ? ae / 786856318u : 0) & ae;
+}
+a(af)(a, int);
+void(ag)(long);
+char(ah)(char, char);
+char(ai)(char);
+short(aj)(short, short);
+int ak(long, int *, int *, char, int);
+void al(signed, a *, int *, long);
+char am(int *, short, short);
+void an(int *, long, int);
+void ao(int, int *, a *);
+a ap() {
+ int *aq, *ar, *as;
+ short at;
+ char au, av, aw = 2;
+ long ax, ay, az = j;
+ int ba, i;
+ g __attribute__((vector_size(16 * sizeof(g)))) bb = {80};
+ b __attribute__((vector_size(4))) bc = {6};
+ int bd[1];
+ char *be = &w;
+ int bf, bg = q;
+ a **bh[] = {
+ &y, &z, &z, &y, &y, &y, &y, &y, &z, &z, &y, &z, &y, &y, &y, &y, &z, &y,
+ &z, &y, &y, &y, &z, &z, &z, &y, &z, &z, &z, &y, &z, &z, &y, &z, &z, &y,
+ &z, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y, &y, 0, &z, 0,
+ &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z, &y, &z, &z, &y,
+ 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y, &y, 0,
+ &z, 0, &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z, &y, &z,
+ &z, &y, 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y,
+ &y, 0, &z, 0, &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z,
+ &y, &z, &z, &y, 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z,
+ &z, &y, &y, 0, &z, 0, &z, 0, &y, &z, &z, 0, 0, &z, 0, &z, &z, &z,
+ &y, &z, &z, &y, &z, &z, &y, 0, &z, 0, 0, &z, &z};
+ for (; i; i++)
+ bd[i] = p;
+ h __attribute__((vector_size(32 * sizeof(h))))
+ bi = {2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681,
+ 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681,
+ 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681},
+ bj = __builtin_convertvector(
+ (c __attribute__((vector_size(32)))){
+ aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw,
+ aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw},
+ h __attribute__((vector_size(32 * sizeof(h))))),
+ bk = __builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 4, 8, 7, 9, 1, 10, 4, 7, 0, 4, 3, 5, 6, 7,
+ 6, 2, 2, 20, 6, 4, 7, 7, 9, 7, 4, 9, 8, 6, 1, 0,
+ 6, 9),
+ h __attribute__((vector_size(32 * sizeof(h)))));
+ bb = __builtin_convertvector(
+ ab(__builtin_shufflevector(
+ __builtin_shufflevector(
+ __builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 1, 31, 8, 2, 3, 7, 4, 0, 7,
+ 3, 4, 6, 7, 1, 9, 3, 8, 7, 1, 8, 5,
+ 3, 9, 9, 0, 3, 2, 8, 5, 2, 5, 3),
+ f __attribute__((vector_size(32 * sizeof(f))))),
+ (f __attribute__((vector_size(32 * sizeof(f))))){
+ 800761418310502961587690471176286910032020044212442466872080013589354162852207417903424527024812447907811618435019152886919380169872910001752451018659493155196043018716516518746289614523948734758456011127254301274351182132760058399143431214610613191313926994549901191890929084305862034120561651877003645},
+ 32, 44),
+ (f __attribute__((vector_size(2 * sizeof(f))))){o}, 1, 0, 3, 0, 2,
+ 1, 3, 3),
+ ad(__builtin_clzg((g)aw, (f)bb[9]),
+ (h __attribute__((vector_size(32 * sizeof(h))))){
+ bi[0] ?: bk[0], bi[1] ? 1 : bk[1], bi[2] ? 2 : bk[2],
+ bi[3] ? 3 : bk[3], bi[4] ? 4 : bk[4], bi[5] ? 5 : bk[5],
+ bi[6] ? 6 : bk[6], bi[7] ? 7 : bk[7], bi[8] ? 8 : bk[8],
+ bi[9] ? 9 : bk[9], bi[0] ? 10 : bk[0], bi[1] ? 1 : bk[1],
+ bi[2] ? 2 : bk[2], bi[3] ? 3 : bk[3], bi[4] ? 4 : bk[4],
+ bi[5] ? 5 : bk[5], bi[6] ? 6 : bk[6], bi[7] ? 7 : bk[7],
+ bi[8] ? 8 : bk[8], bi[9] ? 9 : bk[9], bi[0] ? 20 : bk[0],
+ bi[1] ? 1 : bk[1], bi[2] ? 2 : bk[2], bi[3] ? 3 : bk[3],
+ bi[4] ? bj[4] : 4, bi[5] ?: 5, bi[6] ?: 6,
+ bi[7] ? 0 : 7, bi[8] ?: 8, bi[9] ? 0 : 9,
+ bi[0] ? 0 : 30, bi[1] ?: 1}),
+ (d __attribute__((vector_size(2 * sizeof(d)))))
+ __builtin_shufflevector(
+ __builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 2, 7, 21, 6),
+ e __attribute__((vector_size(4 * sizeof(e))))),
+ __builtin_convertvector(
+ (c __attribute__((vector_size(4)))){aw, aw},
+ e __attribute__((vector_size(4 * sizeof(e))))),
+ 5, 1) +
+ (__builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 4, 5),
+ e __attribute__((vector_size(2 * sizeof(e))))) <=
+ __builtin_convertvector(
+ (c __attribute__((vector_size(2)))){aw},
+ e __attribute__((vector_size(2 * sizeof(e)))))),
+ n ? bb[5] << n : aw),
+ g __attribute__((vector_size(16 * sizeof(g)))));
+ ag(aw & t);
+ at = aj(aw, v[1]);
+ au = ah(at, aw);
+ ba = af((1 == ax != aw) <= aw <= au, aw);
+ ao(0, &bd[0], &r);
+ o = ay;
+ an(aq, aw, k);
+ av = am(ar, l, k);
+ *be = ai(*be);
+ al(x, as, &bd[0], aw);
+ bg = ak(u, &s, &bf, aw, aw);
+ as = *aa;
+ return m;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr119115.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr119115.c
index ac8a70e..524201c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr119115.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr119115.c
@@ -1,7 +1,7 @@
/* { dg-do run } */
/* { dg-require-effective-target rv64 } */
/* { dg-require-effective-target rvv_zvl256b_ok } */
-/* { dg-additional-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -fsigned-char -fwrapv -mrvv-vector-bits=zvl" } */
+/* { dg-additional-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -fsigned-char -fwrapv -mrvv-vector-bits=zvl -std=gnu99" } */
short a[4][14][14];
void
diff --git a/gcc/testsuite/gcc.target/sh/pr67731.c b/gcc/testsuite/gcc.target/sh/pr67731.c
new file mode 100644
index 0000000..43c1657
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr67731.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -m4 -ml" } */
+
+typedef struct
+{
+ _Bool a : 1;
+ _Bool b : 1;
+ _Bool c : 1;
+ _Bool d : 1;
+ unsigned int e : 4;
+} S;
+
+_Bool test_00 (S* s)
+{
+ return s->b | s->c;
+}
+
+_Bool test_01 (S* s)
+{
+ return s->b | s->c | s->d;
+}
+
+/* { dg-final { scan-assembler-times {\ttst} 2 } } */
+/* { dg-final { scan-assembler-times {\tnegc} 2 } } */
+/* { dg-final { scan-assembler-not {\tor} } } */
diff --git a/gcc/testsuite/gcc.target/sparc/cbcond-1.c b/gcc/testsuite/gcc.target/sparc/cbcond-1.c
index 74fe475..742ab1d 100644
--- a/gcc/testsuite/gcc.target/sparc/cbcond-1.c
+++ b/gcc/testsuite/gcc.target/sparc/cbcond-1.c
@@ -34,5 +34,5 @@ void cbcondle (int a)
/* { dg-final { scan-assembler "cwbe\t%" { target ilp32 } } } */
/* { dg-final { scan-assembler "cwbne\t%" { target ilp32 } } } */
-/* { dg-final { scan-assembler "cwbl\t%" } } */
-/* { dg-final { scan-assembler "cwble\t%" } } */
+/* { dg-final { scan-assembler "cwbl|cwbge\t%" } } */
+/* { dg-final { scan-assembler "cwble|cwbg\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/cbcond-2.c b/gcc/testsuite/gcc.target/sparc/cbcond-2.c
index da6c617..c55f9e9 100644
--- a/gcc/testsuite/gcc.target/sparc/cbcond-2.c
+++ b/gcc/testsuite/gcc.target/sparc/cbcond-2.c
@@ -35,5 +35,5 @@ void cbcondle (long a)
/* { dg-final { scan-assembler "cxbe\t%" } } */
/* { dg-final { scan-assembler "cxbne\t%" } } */
-/* { dg-final { scan-assembler "cxbl\t%" } } */
-/* { dg-final { scan-assembler "cxble\t%" } } */
+/* { dg-final { scan-assembler "cxbl|cxbge\t%" } } */
+/* { dg-final { scan-assembler "cxble|cxbg\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/overflow-3.c b/gcc/testsuite/gcc.target/sparc/overflow-3.c
index 52d6ab2..ce52de0 100644
--- a/gcc/testsuite/gcc.target/sparc/overflow-3.c
+++ b/gcc/testsuite/gcc.target/sparc/overflow-3.c
@@ -38,6 +38,6 @@ bool my_neg_overflow (int32_t a, int32_t *res)
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
-/* { dg-final { scan-assembler-times "bvs" 3 } } */
+/* { dg-final { scan-assembler-times "bvs|bvc" 3 } } */
/* { dg-final { scan-assembler-not "cmp\t%" } } */
/* { dg-final { scan-assembler-not "save\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/overflow-4.c b/gcc/testsuite/gcc.target/sparc/overflow-4.c
index c6121b9..2b62edf 100644
--- a/gcc/testsuite/gcc.target/sparc/overflow-4.c
+++ b/gcc/testsuite/gcc.target/sparc/overflow-4.c
@@ -38,7 +38,7 @@ bool my_neg_overflow (int64_t a, int64_t *res)
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
/* { dg-final { scan-assembler-times "movlu\t%" 1 } } */
-/* { dg-final { scan-assembler-times "blu" 2 } } */
-/* { dg-final { scan-assembler-times "bvs" 3 } } */
+/* { dg-final { scan-assembler-times "blu|bgeu" 2 } } */
+/* { dg-final { scan-assembler-times "bvs|bvc" 3 } } */
/* { dg-final { scan-assembler-not "cmp\t%" } } */
/* { dg-final { scan-assembler-not "save\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/overflow-5.c b/gcc/testsuite/gcc.target/sparc/overflow-5.c
index f00283f..0459a65 100644
--- a/gcc/testsuite/gcc.target/sparc/overflow-5.c
+++ b/gcc/testsuite/gcc.target/sparc/overflow-5.c
@@ -38,6 +38,6 @@ bool my_neg_overflow (int64_t a, int64_t *res)
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
/* { dg-final { scan-assembler-times "addxc\t%" 3 } } */
-/* { dg-final { scan-assembler-times "bvs" 3 } } */
+/* { dg-final { scan-assembler-times "bvs|bvc" 3 } } */
/* { dg-final { scan-assembler-not "cmp\t%" } } */
/* { dg-final { scan-assembler-not "save\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/small-struct-1.c b/gcc/testsuite/gcc.target/sparc/small-struct-1.c
index 4897288..1ceccd5 100644
--- a/gcc/testsuite/gcc.target/sparc/small-struct-1.c
+++ b/gcc/testsuite/gcc.target/sparc/small-struct-1.c
@@ -42,5 +42,5 @@ double get2x (struct vec2x v)
return v.x + v.y;
}
-/* { dg-final { scan-assembler-not "ldx" } } */
-/* { dg-final { scan-assembler-not "stx" } } */
+/* { dg-final { scan-assembler-not "ldx" { target *-*-solaris* } } } */
+/* { dg-final { scan-assembler-not "stx" { target *-*-solaris* } } } */
diff --git a/gcc/testsuite/gfortran.dg/pr122513-2.f90 b/gcc/testsuite/gfortran.dg/pr122513-2.f90
new file mode 100644
index 0000000..3f6c5c4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr122513-2.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+
+! PR fortran/122513
+
+! The error is not really new but seems to be untested
+! before. The example is from the mentioned PR.
+
+program test
+ implicit none
+ integer :: i
+ do concurrent (i=1:2) default (none) local(i) ! { dg-error "Index variable 'i' at .1. cannot be specified in a locality-spec" }
+ block
+ integer, dimension(2,3), parameter :: &
+ ii = reshape((/ 1,2,3,4,5,6 /), (/2, 3/))
+ print*,ii(i,:)
+ end block
+ end do
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pr122513.f90 b/gcc/testsuite/gfortran.dg/pr122513.f90
new file mode 100644
index 0000000..9e12ab1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr122513.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! PR122513 do concurrent default (none) fails on parameter arrays
+program test
+ implicit none
+ integer :: i
+ do concurrent (i=1:2) default (none)
+ block
+ integer, dimension(2,3), parameter :: &
+ ii = reshape((/ 1,2,3,4,5,6 /), (/2, 3/))
+ print*,ii(i,:)
+ end block
+ end do
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pure_result.f90 b/gcc/testsuite/gfortran.dg/pure_result.f90
new file mode 100644
index 0000000..a4d30aa
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pure_result.f90
@@ -0,0 +1,49 @@
+! { dg-do compile }
+! PR fortran/78640 - constraints on pure function results
+!
+! F2018:C1585, F2023:C1594:
+! "The function result of a pure function shall not be both polymorphic and
+! allocatable, or have a polymorphic allocatable ultimate component."
+
+program pr78640
+ implicit none
+
+ type foo_t
+ end type
+
+ type bar_t
+ integer, allocatable :: dummy
+ class(*), allocatable :: c
+ end type bar_t
+
+contains
+
+ pure function f() result(foo) ! { dg-error "is polymorphic allocatable" }
+ class(foo_t), allocatable :: foo
+ foo = foo_t()
+ end function
+
+ pure function f2() ! { dg-error "is polymorphic allocatable" }
+ class(foo_t), allocatable :: f2
+ f2 = foo_t()
+ end function
+
+ pure function g() result(foo) ! { dg-error "is polymorphic allocatable" }
+ class(*), allocatable :: foo
+ foo = foo_t()
+ end function
+
+ pure function g2() ! { dg-error "is polymorphic allocatable" }
+ class(*), allocatable :: g2
+ g2 = foo_t()
+ end function
+
+ pure function h() result(bar) ! { dg-error "polymorphic allocatable component" }
+ type(bar_t) :: bar
+ end function
+
+ pure function h2() ! { dg-error "polymorphic allocatable component" }
+ type(bar_t) :: h2
+ end function
+
+end
diff --git a/gcc/testsuite/gm2.dg/spell/iso/fail/badimport2.mod b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport2.mod
new file mode 100644
index 0000000..63fd338
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport2.mod
@@ -0,0 +1,12 @@
+
+(* { dg-do compile } *)
+(* { dg-options "-g -c" } *)
+
+MODULE badimport2 ;
+
+FROM StrIO IMPORT Writestring ;
+ (* { dg-error "error: In program module 'badimport2': unknown symbol 'Writestring', did you mean WriteString?" "Writestring" { target *-*-* } 7 } *)
+
+BEGIN
+
+END badimport2.
diff --git a/gcc/testsuite/gm2.dg/spell/iso/fail/badimport3.mod b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport3.mod
new file mode 100644
index 0000000..ab82cd5
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport3.mod
@@ -0,0 +1,17 @@
+
+(* { dg-do compile } *)
+(* { dg-options "-g -c" } *)
+
+MODULE badimport3 ;
+
+CONST
+ Foo = 42 ;
+
+MODULE inner ;
+IMPORT foo ;
+ (* { dg-error "error: In inner module 'inner': unknown symbol 'foo', did you mean Foo?" "foo" { target *-*-* } 11 } *)
+END inner ;
+
+
+BEGIN
+END badimport3.
diff --git a/gcc/testsuite/gm2.dg/spell/iso/fail/badimport4.mod b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport4.mod
new file mode 100644
index 0000000..1b310d7
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport4.mod
@@ -0,0 +1,17 @@
+
+(* { dg-do compile } *)
+(* { dg-options "-g -c" } *)
+
+MODULE badimport4 ;
+
+CONST
+ Foo = 42 ;
+
+MODULE inner ;
+IMPORT foo ;
+ (* { dg-error "error: In inner module 'inner': unknown symbol 'foo', did you mean Foo?" "foo" { target *-*-* } 11 } *)
+END inner ;
+
+
+BEGIN
+END badimport4.
diff --git a/gcc/testsuite/gnat.dg/generic_inst15.adb b/gcc/testsuite/gnat.dg/generic_inst15.adb
new file mode 100644
index 0000000..e1abf04
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst15.adb
@@ -0,0 +1,27 @@
+-- { dg-do compile }
+
+with Ada.Command_Line; use Ada.Command_Line;
+with Ada.Directories; use Ada.Directories;
+with Ada.Text_IO; use Ada.Text_IO;
+
+with Generic_Inst15_Pkg;
+with Generic_Inst15_Pkg.G;
+
+procedure Generic_Inst15 is
+
+ procedure Print_Word
+ (Word : in out Generic_Inst15_Pkg.Word_Type;
+ Continue : out Boolean)
+ is
+ begin
+ Ada.Text_IO.Put_Line(Generic_Inst15_Pkg.Get_Word(Word));
+ Continue := True;
+ end;
+
+ package Word_Lister is new Generic_Inst15_Pkg.G
+ (Order => Generic_Inst15_Pkg.Word_Order'Val (Positive'Value (Argument(1))),
+ Process => Print_Word);
+
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst15_pkg-g.ads b/gcc/testsuite/gnat.dg/generic_inst15_pkg-g.ads
new file mode 100644
index 0000000..371f2fe
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst15_pkg-g.ads
@@ -0,0 +1,8 @@
+generic
+ Order : Word_Order;
+ with procedure Process
+ (Word : in out Word_Type;
+ Continue : out Boolean);
+package Generic_Inst15_Pkg.G is
+ procedure Translate (Code : in Book_Code_Type) is null;
+end Generic_Inst15_Pkg.G;
diff --git a/gcc/testsuite/gnat.dg/generic_inst15_pkg.ads b/gcc/testsuite/gnat.dg/generic_inst15_pkg.ads
new file mode 100644
index 0000000..d83af45
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst15_pkg.ads
@@ -0,0 +1,37 @@
+private with Ada.Containers.Indefinite_Vectors;
+private with Ada.Strings.Unbounded;
+
+package Generic_Inst15_Pkg is
+ type Word_Order is
+ (wo_Alpha,
+ wo_Position,
+ wo_Frequency_Alpha,
+ wo_Frequency_Position);
+
+ subtype Book_Code_Type is String (1 .. 24);
+
+ type Word_Type is private;
+ type Word_Status is (ws_Single, ws_Multi, ws_Not_All, ws_Unknown);
+ type Translation_Index is new Natural range 1 .. 10;
+
+ function Get_Word (Self : in Word_Type) return String;
+
+ type Book_Type is private;
+
+private
+
+ package Translation_List is new Ada.Containers.Indefinite_Vectors (
+ Index_Type => Translation_Index,
+ Element_Type => String,
+ "=" => "=");
+
+ type Word_Type is record
+ Is_All : Boolean := False;
+ Translations : Translation_List.Vector;
+ end record;
+
+ type Book_Type is record
+ Line : Positive := 1;
+ Index : Positive := 1;
+ end record;
+end Generic_Inst15_Pkg;
diff --git a/gcc/testsuite/gnat.dg/specs/abstract1.ads b/gcc/testsuite/gnat.dg/specs/abstract1.ads
new file mode 100644
index 0000000..4674424
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/abstract1.ads
@@ -0,0 +1,9 @@
+-- { dg-do compile }
+
+package Abstract1 is
+
+ type T is abstract tagged null record;
+
+ type S is abstract new T; -- { dg-error "allowed only for record extension" }
+
+end Abstract1;
diff --git a/gcc/testsuite/gnat.dg/specs/unknown_discr1.ads b/gcc/testsuite/gnat.dg/specs/unknown_discr1.ads
new file mode 100644
index 0000000..d1c85e1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/unknown_discr1.ads
@@ -0,0 +1,23 @@
+-- { dg-do compile }
+
+with Unknown_Discr1_Pkg; use Unknown_Discr1_Pkg;
+with Unknown_Discr1_Pkg.Child;
+with Unknown_Discr1_Pkg.Inst;
+
+package Unknown_Discr1 is
+
+ A : Tagged_Type (0); -- { dg-error "type has unknown discriminants" }
+
+ B : Child.Derived_1 (1); -- { dg-error "type has unknown discriminants" }
+
+ C : Child.Derived_2 (2); -- { dg-error "type has unknown discriminants" }
+
+ D : Child.Nested.Derived_3 (3); -- { dg-error "type has unknown discriminants" }
+
+ E : Inst.Derived_1 (1); -- { dg-error "type has unknown discriminants" }
+
+ F : Inst.Derived_2 (2); -- { dg-error "type has unknown discriminants" }
+
+ G : Inst.Nested.Derived_3 (3); -- { dg-error "type has unknown discriminants" }
+
+end Unknown_Discr1;
diff --git a/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-child.ads b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-child.ads
new file mode 100644
index 0000000..681efbc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-child.ads
@@ -0,0 +1,17 @@
+package Unknown_Discr1_Pkg.Child is
+
+ type Derived_1 is new Tagged_Type with null record;
+
+ type Derived_2 is new Derived_1 with null record;
+
+ package Nested is
+
+ type Derived_3 is new Tagged_Type with private;
+
+ private
+
+ type Derived_3 is new Tagged_Type with null record;
+
+ end Nested;
+
+end Unknown_Discr1_Pkg.Child;
diff --git a/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-g.ads b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-g.ads
new file mode 100644
index 0000000..1570405
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-g.ads
@@ -0,0 +1,21 @@
+generic
+
+ type Base (<>) is new Tagged_Type with private;
+
+package Unknown_Discr1_Pkg.G is
+
+ type Derived_1 is new Base with null record;
+
+ type Derived_2 is new Derived_1 with null record;
+
+ package Nested is
+
+ type Derived_3 is new Tagged_Type with private;
+
+ private
+
+ type Derived_3 is new Tagged_Type with null record;
+
+ end Nested;
+
+end Unknown_Discr1_Pkg.G;
diff --git a/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-inst.ads b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-inst.ads
new file mode 100644
index 0000000..5dfe119
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg-inst.ads
@@ -0,0 +1,3 @@
+with Unknown_Discr1_Pkg.G;
+
+package Unknown_Discr1_Pkg.Inst is new Unknown_Discr1_Pkg.G (Tagged_Type);
diff --git a/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg.ads b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg.ads
new file mode 100644
index 0000000..d769b4d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/unknown_discr1_pkg.ads
@@ -0,0 +1,9 @@
+package Unknown_Discr1_Pkg is
+
+ type Tagged_Type (<>) is tagged limited private;
+
+private
+
+ type Tagged_Type (Kind : Integer) is tagged limited null record;
+
+end Unknown_Discr1_Pkg;
diff --git a/gcc/testsuite/gnat.dg/use_type4.adb b/gcc/testsuite/gnat.dg/use_type4.adb
new file mode 100644
index 0000000..5ceb288
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/use_type4.adb
@@ -0,0 +1,29 @@
+-- { dg-do compile }
+
+procedure Use_Type4 is
+
+ package P1 is
+ type T is new Integer;
+ function "and" (L, R : in Integer) return T;
+ end P1;
+
+ package body P1 is
+ function "and" (L, R : in Integer) return T is
+ begin
+ return T (L * R);
+ end "and";
+ end P1;
+
+ use type P1.T;
+
+ package Renaming renames P1;
+
+ package P2 is
+ use Renaming;
+ end P2;
+
+ G : P1.T := Integer'(1) and Integer'(2);
+
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/vect19.adb b/gcc/testsuite/gnat.dg/vect19.adb
new file mode 100644
index 0000000..af6f7e6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect19.adb
@@ -0,0 +1,17 @@
+-- { dg-do compile { target i?86-*-* x86_64-*-* } }
+-- { dg-options "-O3 -msse2 -gnatn -fno-tree-slp-vectorize -fdump-tree-vect-details" }
+
+package body Vect19 is
+
+ function NSum (X : Arr; N : Positive) return Arr is
+ Ret : Arr := X;
+ begin
+ for I in 1 .. N loop
+ Ret := Sum (Ret, X);
+ end loop;
+ return Ret;
+ end;
+
+end Vect19;
+
+-- { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } }
diff --git a/gcc/testsuite/gnat.dg/vect19.ads b/gcc/testsuite/gnat.dg/vect19.ads
new file mode 100644
index 0000000..475f8d4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect19.ads
@@ -0,0 +1,7 @@
+with Vect19_Pkg; use Vect19_Pkg;
+
+package Vect19 is
+
+ function NSum (X : Arr; N : Positive) return Arr;
+
+end Vect19;
diff --git a/gcc/testsuite/gnat.dg/vect19_pkg.adb b/gcc/testsuite/gnat.dg/vect19_pkg.adb
new file mode 100644
index 0000000..4c3b999
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect19_pkg.adb
@@ -0,0 +1,12 @@
+package body Vect19_Pkg is
+
+ function Sum (X : Arr; Y : Arr) return Arr is
+ Result : Arr;
+ begin
+ for I in X'Range loop
+ Result(I) := X(I) + Y(I);
+ end loop;
+ return Result;
+ end;
+
+end Vect19_Pkg;
diff --git a/gcc/testsuite/gnat.dg/vect19_pkg.ads b/gcc/testsuite/gnat.dg/vect19_pkg.ads
new file mode 100644
index 0000000..accd8af
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect19_pkg.ads
@@ -0,0 +1,9 @@
+package Vect19_Pkg is
+
+ type Arr is array (1 .. 4) of Float;
+ for Arr'Alignment use 16;
+
+ function Sum (X : Arr; Y : Arr) return Arr;
+ pragma Inline (Sum);
+
+end Vect19_Pkg;
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 50cdc2a..576a69c 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -7578,7 +7578,9 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
if ((double_reduc || neutral_op)
&& !nunits_out.is_constant ()
&& (SLP_TREE_LANES (slp_node) != 1 && !reduc_chain)
- && !operand_equal_p (neutral_op, vect_phi_initial_value (reduc_def_phi))
+ && (!neutral_op
+ || !operand_equal_p (neutral_op,
+ vect_phi_initial_value (reduc_def_phi)))
&& !direct_internal_fn_supported_p (IFN_VEC_SHL_INSERT,
vectype_out, OPTIMIZE_FOR_SPEED))
{