aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog219
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/sem_aggr.adb10
-rw-r--r--gcc/analyzer/ChangeLog17
-rw-r--r--gcc/analyzer/checker-event.h3
-rw-r--r--gcc/analyzer/checker-path.cc12
-rw-r--r--gcc/analyzer/diagnostic-manager.cc20
-rw-r--r--gcc/auto-profile.cc244
-rw-r--r--gcc/cgraph.cc9
-rw-r--r--gcc/cobol/ChangeLog100
-rw-r--r--gcc/cobol/cbldiag.h17
-rw-r--r--gcc/cobol/cdf-copy.cc3
-rw-r--r--gcc/cobol/cdf.y18
-rw-r--r--gcc/cobol/cobol-system.h6
-rw-r--r--gcc/cobol/except.cc2
-rw-r--r--gcc/cobol/genapi.cc164
-rw-r--r--gcc/cobol/gengen.cc95
-rw-r--r--gcc/cobol/gengen.h5
-rw-r--r--gcc/cobol/genmath.cc12
-rw-r--r--gcc/cobol/genutil.cc2
-rw-r--r--gcc/cobol/lexio.cc6
-rw-r--r--gcc/cobol/parse.y96
-rw-r--r--gcc/cobol/parse_ante.h7
-rw-r--r--gcc/cobol/parse_util.h2
-rw-r--r--gcc/cobol/scan.l9
-rw-r--r--gcc/cobol/scan_ante.h27
-rw-r--r--gcc/cobol/scan_post.h2
-rw-r--r--gcc/cobol/show_parse.h49
-rw-r--r--gcc/cobol/symbols.cc6
-rw-r--r--gcc/cobol/symbols.h8
-rw-r--r--gcc/cobol/util.cc37
-rw-r--r--gcc/cobol/util.h10
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64-simd.md38
-rw-r--r--gcc/config/aarch64/aarch64.cc22
-rw-r--r--gcc/config/aarch64/iterators.md48
-rw-r--r--gcc/config/i386/i386-expand.cc31
-rw-r--r--gcc/config/i386/i386-protos.h7
-rw-r--r--gcc/config/i386/i386.cc318
-rw-r--r--gcc/config/i386/i386.h4
-rw-r--r--gcc/config/i386/i386.md37
-rw-r--r--gcc/config/or1k/or1k.cc57
-rw-r--r--gcc/config/or1k/or1k.md57
-rw-r--r--gcc/config/or1k/predicates.md4
-rw-r--r--gcc/config/riscv/riscv-cores.def1
-rw-r--r--gcc/config/riscv/riscv-v.cc4
-rw-r--r--gcc/config/riscv/riscv.cc78
-rw-r--r--gcc/config/riscv/riscv.h2
-rw-r--r--gcc/config/riscv/sync.md11
-rw-r--r--gcc/config/riscv/vector-iterators.md4
-rw-r--r--gcc/cp/ChangeLog66
-rw-r--r--gcc/cp/coroutines.cc342
-rw-r--r--gcc/cp/cp-trait.def2
-rw-r--r--gcc/cp/module.cc177
-rw-r--r--gcc/dfp.cc79
-rw-r--r--gcc/diagnostic.h10
-rw-r--r--gcc/doc/extend.texi4
-rw-r--r--gcc/doc/gcov.texi2
-rw-r--r--gcc/doc/install.texi3
-rw-r--r--gcc/emit-rtl.cc9
-rw-r--r--gcc/fortran/ChangeLog15
-rw-r--r--gcc/fortran/check.cc61
-rw-r--r--gcc/fortran/intrinsic.texi24
-rw-r--r--gcc/fortran/trans-array.cc12
-rw-r--r--gcc/function.cc2
-rw-r--r--gcc/gimple-crc-optimization.cc9
-rw-r--r--gcc/m2/ChangeLog22
-rw-r--r--gcc/m2/gm2-compiler/M2GCCDeclare.mod94
-rw-r--r--gcc/m2/gm2-compiler/M2MetaError.mod37
-rw-r--r--gcc/m2/gm2-compiler/P2SymBuild.mod31
-rw-r--r--gcc/omp-offload.cc3
-rw-r--r--gcc/prime-paths.cc50
-rw-r--r--gcc/real.cc21
-rw-r--r--gcc/rtl.h3
-rw-r--r--gcc/rtlanal.cc36
-rw-r--r--gcc/testsuite/ChangeLog212
-rw-r--r--gcc/testsuite/g++.dg/coroutines/assume.C40
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr115908.C (renamed from gcc/testsuite/g++.dg/coroutines/pr115908.C)9
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-00-nothing-throws.C5
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C (renamed from gcc/testsuite/g++.dg/coroutines/torture/pr95615-02.C)0
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C (renamed from gcc/testsuite/g++.dg/coroutines/torture/pr95615-03.C)0
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C (renamed from gcc/testsuite/g++.dg/coroutines/torture/pr95615-01.C)0
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C (renamed from gcc/testsuite/g++.dg/coroutines/torture/pr95615-04.C)0
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C (renamed from gcc/testsuite/g++.dg/coroutines/torture/pr95615-05.C)0
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C7
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-07-body-throws.C7
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C8
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C10
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc196
-rw-r--r--gcc/testsuite/g++.dg/coroutines/unevaluated.C25
-rw-r--r--gcc/testsuite/g++.dg/modules/warn-spec-3_a.C20
-rw-r--r--gcc/testsuite/g++.dg/modules/warn-spec-3_b.C7
-rw-r--r--gcc/testsuite/g++.dg/modules/warn-spec-3_c.C12
-rw-r--r--gcc/testsuite/g++.target/i386/shrink_wrap_separate.C25
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr120677.c31
-rw-r--r--gcc/testsuite/gcc.dg/dfp/bitint-10.c49
-rw-r--r--gcc/testsuite/gcc.dg/dfp/bitint-9.c29
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr120631.c25
-rw-r--r--gcc/testsuite/gcc.dg/pr119039-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/pr119039-2.c60
-rw-r--r--gcc/testsuite/gcc.dg/pr120661-1.c51
-rw-r--r--gcc/testsuite/gcc.dg/pr120661-2.c39
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr120654.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/afdo-vpt-earlyinline.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr113027-1.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr113027-2.c268
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr113027-3.c268
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr113027-4.c268
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr113027-5.c268
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr113027-6.c267
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr113027-7.c267
-rw-r--r--gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/cold-attribute-4.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/interrupt-16.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/memset-pr120708-1.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/memset-pr120708-2.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr120427-1.c28
-rw-r--r--gcc/testsuite/gcc.target/i386/pr120427-2.c28
-rw-r--r--gcc/testsuite/gcc.target/i386/pr120427-3.c45
-rw-r--r--gcc/testsuite/gcc.target/i386/pr120427-4.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr120689.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/shrink_wrap_separate_check_lea.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/stack-clash-protection.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h48
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h392
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/zalrsc.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c16
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c2
-rw-r--r--gcc/testsuite/gfortran.dg/guality/arg1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/save_alloc_character_1.f9023
-rw-r--r--gcc/testsuite/gfortran.dg/stat_3.f9046
-rw-r--r--gcc/testsuite/gm2/pim/fail/badmodvar.mod7
-rw-r--r--gcc/testsuite/gm2/pim/fail/cyclictypes.mod13
-rw-r--r--gcc/testsuite/gm2/pim/fail/cyclictypes2.mod9
-rw-r--r--gcc/testsuite/gm2/pim/fail/cyclictypes4.mod13
-rw-r--r--gcc/testsuite/gnat.dg/specs/aggr8.ads14
-rw-r--r--gcc/tree-cfg.cc20
-rw-r--r--gcc/value-range.cc121
-rw-r--r--gcc/value-range.h2
-rw-r--r--gcc/vr-values.cc291
-rw-r--r--include/longlong.h14
-rw-r--r--libcpp/ChangeLog5
-rw-r--r--libcpp/include/line-map.h4
-rw-r--r--libcpp/line-map.cc11
-rw-r--r--libgfortran/ChangeLog21
-rw-r--r--libgfortran/intrinsics/stat.c274
-rw-r--r--libgomp/ChangeLog21
-rw-r--r--libgomp/libgomp.texi181
-rw-r--r--libgomp/target.c13
-rw-r--r--libgomp/testsuite/libgomp.c++/declare_target-2.C25
235 files changed, 6686 insertions, 1274 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dc7b430..e4c9846 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,222 @@
+2025-06-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/120689
+ * function.cc (assign_parm_setup_block): Align parm to at least
+ word alignment even on !STRICT_ALIGNMENT targets, as long as
+ BITS_PER_WORD is not larger than MAX_SUPPORTED_STACK_ALIGNMENT.
+
+2025-06-19 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/120427
+ * config/i386/i386.md (*mov<mode>_and): Changed to
+ define_insn_and_split. Split it to "mov $0,mem" if not -Oz.
+ (*mov<mode>_or): Changed to define_insn_and_split. Split it
+ to "mov $-1,mem" if not -Oz.
+ (peephole2): Don't transform "mov $-1,reg" to "push $-1; pop reg"
+ for -Oz since it will be transformed to "or $-1,reg".
+
+2025-06-19 Georg-Johann Lay <avr@gjlay.de>
+
+ PR other/115893
+ * doc/install.texi (Prerequisites): Note that Texinfo older
+ than v7.1 may throw incorrect build warnings, cf.
+ https://lists.nongnu.org/archive/html/help-texinfo/2023-11/msg00004.html
+
+2025-06-19 Dongyan Chen <chendongyan@isrc.iscas.ac.cn>
+
+ * config/riscv/riscv-cores.def (RISCV_TUNE): Add "generic" tune.
+ * config/riscv/riscv.cc: Add generic_tune_info.
+ * config/riscv/riscv.h (RISCV_TUNE_STRING_DEFAULT): Change default tune.
+
+2025-06-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120631
+ * dfp.cc (decimal_real_to_integer): Use result multiplication not just
+ when precision > 128 and dn.exponent > 19, but when precision > 64
+ and dn.exponent > 0.
+
+2025-06-19 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/riscv.cc (riscv_legitimize_move): Use
+ riscv_2x_xlen_mode_p.
+ (riscv_binary_cost): Ditto.
+ (riscv_hard_regno_mode_ok): Ditto.
+
+2025-06-19 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/riscv.cc (riscv_cost_model): Add cost model for
+ zilsd.
+
+2025-06-19 Lili Cui <lili.cui@intel.com>
+
+ PR target/120697
+ * config/i386/i386.cc (ix86_expand_prologue):
+ Remove 3 assertions and associated code.
+
+2025-06-18 Dimitar Dimitrov <dimitar@dinux.eu>
+ Richard Sandiford <richard.sandiford@arm.com>
+ Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR target/119966
+ * emit-rtl.cc (validate_subreg): Call simplify_subreg_regno
+ instead of checking info.representable_p..
+ * rtl.h (simplify_subreg_regno): Add new argument
+ allow_stack_regs.
+ * rtlanal.cc (simplify_subreg_regno): Do not reject
+ stack-related registers if allow_stack_regs is true.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ * value-range.cc (irange::intersect_bitmask): Always update the
+ stored mask to reflect the current calculated mask.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/119039
+ * value-range.cc (irange::contains_p): Call wide_int version of
+ contains_p for singleton ranges.
+ (irange::intersect): If either range is a singleton, use
+ contains_p.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/119039
+ * vr-values.cc (simplify_using_ranges::legacy_fold_cond): Remove.
+ (simplify_using_ranges::simplify_switch_using_ranges): Adjust.
+
+2025-06-18 Richard Biener <rguenther@suse.de>
+
+ * tree-cfg.cc (dump_function_to_file): Use flags, not dump_flags.
+
+2025-06-18 Jan Beulich <jbeulich@suse.com>
+
+ * doc/gcov.texi: Drop blank after @anchor.
+
+2025-06-18 Jan Beulich <jbeulich@suse.com>
+
+ * doc/extend.texi: Fill first argument of @xref{}.
+
+2025-06-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120631
+ * real.cc (decimal_from_integer): Add digits argument, if larger than
+ 256, use XALLOCAVEC allocated buffer.
+ (real_from_integer): Pass val_in's precision divided by 3 to
+ decimal_from_integer.
+ * dfp.cc (decimal_real_to_integer): For precision > 128 if finite
+ and exponent is large, decrease exponent and multiply resulting
+ wide_int by powers of 10^19.
+
+2025-06-18 Pan Li <pan2.li@intel.com>
+
+ * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add
+ new case SMIN.
+ (expand_vx_binary_vec_vec_dup): Ditto.
+ * config/riscv/riscv.cc (riscv_rtx_costs): Ditto.
+ * config/riscv/vector-iterators.md: Add new op smin.
+
+2025-06-18 Lili Cui <lili.cui@intel.com>
+ Michael Matz <matz@suse.de>
+
+ * config/i386/i386-protos.h (ix86_get_separate_components):
+ New function.
+ (ix86_components_for_bb): Likewise.
+ (ix86_disqualify_components): Likewise.
+ (ix86_emit_prologue_components): Likewise.
+ (ix86_emit_epilogue_components): Likewise.
+ (ix86_set_handled_components): Likewise.
+ * config/i386/i386.cc (save_regs_using_push_pop):
+ Split from ix86_compute_frame_layout.
+ (ix86_compute_frame_layout):
+ Use save_regs_using_push_pop.
+ (pro_epilogue_adjust_stack):
+ Use gen_pro_epilogue_adjust_stack_add_nocc.
+ (ix86_expand_prologue): Add some assertions and adjust
+ the stack frame at the beginning of the prolog for shrink
+ wrapping separate.
+ (ix86_emit_save_regs_using_mov):
+ Skip registers that are wrapped separately.
+ (ix86_emit_restore_regs_using_mov): Likewise.
+ (ix86_expand_epilogue): Add some assertions and set
+ restore_regs_via_mov to true for shrink wrapping separate.
+ (ix86_get_separate_components): New function.
+ (ix86_components_for_bb): Likewise.
+ (ix86_disqualify_components): Likewise.
+ (ix86_emit_prologue_components): Likewise.
+ (ix86_emit_epilogue_components): Likewise.
+ (ix86_set_handled_components): Likewise.
+ (TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS): Define.
+ (TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB): Likewise.
+ (TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS): Likewise.
+ (TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS): Likewise.
+ (TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS): Likewise.
+ (TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS): Likewise.
+ * config/i386/i386.h (struct machine_function):Add
+ reg_is_wrapped_separately array for register wrapping
+ information.
+ * config/i386/i386.md
+ (@pro_epilogue_adjust_stack_add_nocc<mode>): New.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/120661
+ * value-range.cc (irange::snap): New.
+ (irange::snap_subranges): New.
+ (irange::set_range_from_bitmask): Call snap_subranges.
+ * value-range.h (snap, snap_subranges): New prototypes.
+
+2025-06-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * auto-profile.cc (afdo_indirect_call): Compute speculative edge
+ probability.
+ (add_scale): Break out from ...
+ (scale_bbs): Break out from ...
+ (afdo_adjust_guessed_profile): ... here; use componet array instead of
+ current_component hash_map; handle components with only 0 profile;
+ be more agressive on finding scales along the boundary.
+
+2025-06-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * cgraph.cc (cgraph_node::apply_scale): Special case scaling
+ to profile_count::zero ().
+ (cgraph_node::verify_node): Add extra compatibility check.
+
+2025-06-17 Umesh Kalappa <ukalappa.mips@gmail.com>
+
+ * config/riscv/sync.md (lrsc_atomic_exchange<mode>): Use scratch
+ register for loop control rather than lr output.
+
+2025-06-17 Jason Merrill <jason@redhat.com>
+
+ * diagnostic.h (diagnostic_option_classifier): Friend
+ diagnostic_context.
+ (diagnostic_context::get_classification_history): New.
+
+2025-06-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/120677
+ * gimple-crc-optimization.cc (crc_optimization::optimize_crc_loop):
+ Insert before gsi_after_labels instead of gsi_start_bb. Use
+ gimple_bb (output_crc) instead of output_crc->bb. Formatting fix.
+
+2025-06-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/113027
+ * config/aarch64/aarch64-protos.h (aarch64_decompose_vec_struct_index):
+ Declare.
+ * config/aarch64/aarch64.cc (aarch64_decompose_vec_struct_index): New
+ function.
+ * config/aarch64/iterators.md (VEL, Vel): Add Advanced SIMD
+ structure modes.
+ * config/aarch64/aarch64-simd.md (vec_set<VSTRUCT_QD:mode>)
+ (vec_extract<VSTRUCT_QD:mode>): New patterns.
+
+2025-06-17 Tobias Burnus <tburnus@baylibre.com>
+
+ * omp-offload.cc (omp_discover_declare_target_tgt_fn_r): Also
+ walk external functions that are declare inline (and have a
+ DECL_SAVED_TREE).
+
2025-06-16 Spencer Abson <spencer.abson@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_sve_valid_pred_p):
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index aaa22e3..48356de 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250617
+20250620
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index f51e899..2cc7357 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2025-06-17 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/120665
+ * sem_aggr.adb (Resolve_Container_Aggregate): Use robust guards.
+
2025-06-12 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Variable>: Generate
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index f4fa1ad..1bcb4b9 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -4054,8 +4054,8 @@ package body Sem_Aggr is
if Present (Add_Unnamed_Subp)
and then No (New_Indexed_Subp)
- and then Present (Etype (Add_Unnamed_Subp))
- and then Etype (Add_Unnamed_Subp) /= Any_Type
+ and then Present (Entity (Add_Unnamed_Subp))
+ and then Entity (Add_Unnamed_Subp) /= Any_Id
then
declare
Elmt_Type : constant Entity_Id :=
@@ -4101,7 +4101,8 @@ package body Sem_Aggr is
end;
elsif Present (Add_Named_Subp)
- and then Etype (Add_Named_Subp) /= Any_Type
+ and then Present (Entity (Add_Named_Subp))
+ and then Entity (Add_Named_Subp) /= Any_Id
then
declare
-- Retrieves types of container, key, and element from the
@@ -4155,7 +4156,8 @@ package body Sem_Aggr is
end;
elsif Present (Assign_Indexed_Subp)
- and then Etype (Assign_Indexed_Subp) /= Any_Type
+ and then Present (Entity (Assign_Indexed_Subp))
+ and then Entity (Assign_Indexed_Subp) /= Any_Id
then
-- Indexed Aggregate. Positional or indexed component
-- can be present, but not both. Choices must be static
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 1fbba5d..cc86675 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,20 @@
+2025-06-18 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-event.h (checker_event::get_kind): New accessor.
+ (checker_event::m_kind): Make private.
+ * checker-path.cc (checker_path::maybe_log): Use accessor for
+ checker_event::m_kind.
+ (checker_path::add_event): Likewise.
+ (checker_path::debug): Likewise.
+ (checker_path::cfg_edge_pair_at_p): Likewise.
+ (checker_path::inject_any_inlined_call_events): Likewise.
+ * diagnostic-manager.cc
+ (diagnostic_manager::prune_for_sm_diagnostic): Likewise.
+ (diagnostic_manager::prune_for_sm_diagnostic): Likewise.
+ (diagnostic_manager::consolidate_conditions): Likewise.
+ (diagnostic_manager::consolidate_unwind_events): Likewise.
+ (diagnostic_manager::finish_pruning): Likewise.
+
2025-05-06 David Malcolm <dmalcolm@redhat.com>
* checker-event.cc (checker_event::checker_event): Update
diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h
index 2f26b8d..e29173a 100644
--- a/gcc/analyzer/checker-event.h
+++ b/gcc/analyzer/checker-event.h
@@ -116,6 +116,7 @@ public:
sarif_object &thread_flow_loc_obj) const override;
/* Additional functionality. */
+ enum event_kind get_kind () const { return m_kind; }
tree get_fndecl () const { return m_effective_fndecl; }
int get_original_stack_depth () const { return m_original_depth; }
@@ -142,7 +143,7 @@ protected:
checker_event (enum event_kind kind,
const event_loc_info &loc_info);
- public:
+ private:
const enum event_kind m_kind;
protected:
location_t m_loc;
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 9bde6f2..45593e0 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -89,7 +89,7 @@ checker_path::maybe_log (logger *logger, const char *desc) const
{
logger->start_log_line ();
logger->log_partial ("%s[%i]: %s ", desc, i,
- event_kind_to_string (m_events[i]->m_kind));
+ event_kind_to_string (m_events[i]->get_kind ()));
m_events[i]->dump (logger->get_printer ());
logger->end_log_line ();
}
@@ -103,7 +103,7 @@ checker_path::add_event (std::unique_ptr<checker_event> event)
m_logger->start_log_line ();
m_logger->log_partial ("added event[%i]: %s ",
m_events.length (),
- event_kind_to_string (event.get ()->m_kind));
+ event_kind_to_string (event.get ()->get_kind ()));
event.get ()->dump (m_logger->get_printer ());
m_logger->end_log_line ();
}
@@ -123,7 +123,7 @@ checker_path::debug () const
fprintf (stderr,
"[%i]: %s \"%s\"\n",
i,
- event_kind_to_string (m_events[i]->m_kind),
+ event_kind_to_string (m_events[i]->get_kind ()),
event_desc.get ());
}
}
@@ -167,8 +167,8 @@ checker_path::cfg_edge_pair_at_p (unsigned idx) const
{
if (m_events.length () < idx + 1)
return false;
- return (m_events[idx]->m_kind == event_kind::start_cfg_edge
- && m_events[idx + 1]->m_kind == event_kind::end_cfg_edge);
+ return (m_events[idx]->get_kind () == event_kind::start_cfg_edge
+ && m_events[idx + 1]->get_kind () == event_kind::end_cfg_edge);
}
/* Consider a call from "outer" to "middle" which calls "inner",
@@ -254,7 +254,7 @@ checker_path::inject_any_inlined_call_events (logger *logger)
{
logger->start_log_line ();
logger->log_partial ("event[%i]: %s ", ev_idx,
- event_kind_to_string (curr_event->m_kind));
+ event_kind_to_string (curr_event->get_kind ()));
curr_event->dump (logger->get_printer ());
logger->end_log_line ();
for (inlining_iterator iter (curr_event->get_location ());
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index e5d1a25..6867dd2 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -2599,19 +2599,19 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
{
label_text sval_desc = sval->get_desc ();
log ("considering event %i (%s), with sval: %qs, state: %qs",
- idx, event_kind_to_string (base_event->m_kind),
+ idx, event_kind_to_string (base_event->get_kind ()),
sval_desc.get (), state->get_name ());
}
else
log ("considering event %i (%s), with global state: %qs",
- idx, event_kind_to_string (base_event->m_kind),
+ idx, event_kind_to_string (base_event->get_kind ()),
state->get_name ());
}
else
log ("considering event %i", idx);
}
- switch (base_event->m_kind)
+ switch (base_event->get_kind ())
{
default:
gcc_unreachable ();
@@ -2718,7 +2718,7 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
log ("filtering events %i and %i: CFG edge", idx, idx + 1);
path->delete_event (idx);
/* Also delete the corresponding event_kind::end_cfg_edge. */
- gcc_assert (path->get_checker_event (idx)->m_kind
+ gcc_assert (path->get_checker_event (idx)->get_kind ()
== event_kind::end_cfg_edge);
path->delete_event (idx);
}
@@ -3109,7 +3109,7 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const
continue;
/* Are we looking for a run of all TRUE edges, or all FALSE edges? */
- gcc_assert (old_start_ev->m_kind == event_kind::start_cfg_edge);
+ gcc_assert (old_start_ev->get_kind () == event_kind::start_cfg_edge);
const start_cfg_edge_event *old_start_cfg_ev
= (const start_cfg_edge_event *)old_start_ev;
const cfg_superedge& first_cfg_sedge
@@ -3132,7 +3132,7 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const
{
const checker_event *iter_ev
= path->get_checker_event (next_idx);
- gcc_assert (iter_ev->m_kind == event_kind::start_cfg_edge);
+ gcc_assert (iter_ev->get_kind () == event_kind::start_cfg_edge);
const start_cfg_edge_event *iter_cfg_ev
= (const start_cfg_edge_event *)iter_ev;
const cfg_superedge& iter_cfg_sedge
@@ -3190,11 +3190,13 @@ diagnostic_manager::consolidate_unwind_events (checker_path *path) const
start_idx++)
{
/* Find a run of consecutive unwind_event instances. */
- if (path->get_checker_event (start_idx)->m_kind != event_kind::unwind)
+ if (path->get_checker_event (start_idx)->get_kind ()
+ != event_kind::unwind)
continue;
int iter_idx = start_idx + 1;
while (iter_idx < (int)path->num_events ())
- if (path->get_checker_event (iter_idx)->m_kind == event_kind::unwind)
+ if (path->get_checker_event (iter_idx)->get_kind ()
+ == event_kind::unwind)
++iter_idx;
else
break;
@@ -3232,7 +3234,7 @@ diagnostic_manager::finish_pruning (checker_path *path) const
while (idx >= 0 && idx < (signed)path->num_events ())
{
checker_event *base_event = path->get_checker_event (idx);
- if (base_event->m_kind == event_kind::function_entry)
+ if (base_event->get_kind () == event_kind::function_entry)
{
log ("filtering event %i:"
" function entry for purely intraprocedural path", idx);
diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
index 8918d1e..3272cbe 100644
--- a/gcc/auto-profile.cc
+++ b/gcc/auto-profile.cc
@@ -1076,10 +1076,10 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map,
fprintf (dump_file, "\n");
}
- /* FIXME: Count should be initialized. */
struct cgraph_edge *new_edge
- = indirect_edge->make_speculative (direct_call,
- profile_count::uninitialized ());
+ = indirect_edge->make_speculative
+ (direct_call,
+ gimple_bb (stmt)->count.apply_scale (99, 100));
cgraph_edge::redirect_call_stmt_to_callee (new_edge);
gimple_remove_histogram_value (cfun, stmt, hist);
inline_call (new_edge, true, NULL, NULL, false);
@@ -1549,6 +1549,60 @@ cmp (const void *a, const void *b)
return 0;
}
+/* Add scale ORIG/ANNOTATED to SCALES. */
+
+static void
+add_scale (vec <sreal> *scales, profile_count annotated, profile_count orig)
+{
+ if (dump_file)
+ {
+ orig.dump (dump_file);
+ fprintf (dump_file, " should be ");
+ annotated.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ if (orig.nonzero_p ())
+ {
+ sreal scale
+ = annotated.guessed_local ()
+ .to_sreal_scale (orig);
+ if (dump_file)
+ fprintf (dump_file, " adding scale %.16f\n",
+ scale.to_double ());
+ scales->safe_push (scale);
+ }
+}
+
+/* Scale counts of all basic blocks in BBS by SCALE and convert them to
+ IPA quality. */
+
+static void
+scale_bbs (const vec <basic_block> &bbs, sreal scale)
+{
+ if (dump_file)
+ fprintf (dump_file, " Scaling by %.16f\n", scale.to_double ());
+ for (basic_block b : bbs)
+ if (!(b->count == profile_count::zero ())
+ && b->count.initialized_p ())
+ {
+ profile_count o = b->count;
+ b->count = b->count.force_guessed () * scale;
+
+ /* If we scaled to 0, make it auto-fdo since that is treated
+ less agressively. */
+ if (!b->count.nonzero_p () && o.nonzero_p ())
+ b->count = profile_count::zero ().afdo ();
+ if (dump_file)
+ {
+ fprintf (dump_file, " bb %i count updated ", b->index);
+ o.dump (dump_file);
+ fprintf (dump_file, " -> ");
+ b->count.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ }
+}
+
/* In case given basic block was fully optimized out, AutoFDO
will have no data about it. In this case try to preserve static profile.
Identify connected components (in undirected form of CFG) which has
@@ -1558,26 +1612,33 @@ cmp (const void *a, const void *b)
void
afdo_adjust_guessed_profile (bb_set *annotated_bb)
{
- auto_sbitmap visited (last_basic_block_for_fn (cfun));
/* Basic blocks of connected component currently processed. */
- auto_vec <basic_block, 20> bbs (n_basic_blocks_for_fn (cfun) + 1);
+ auto_vec <basic_block, 20> bbs (n_basic_blocks_for_fn (cfun));
/* Scale factors found. */
- auto_vec <sreal, 20> scales (n_basic_blocks_for_fn (cfun) + 1);
- auto_vec <basic_block, 20> stack (n_basic_blocks_for_fn (cfun) + 1);
-
- bitmap_clear (visited);
+ auto_vec <sreal, 20> scales;
+ auto_vec <basic_block, 20> stack (n_basic_blocks_for_fn (cfun));
basic_block seed_bb;
- FOR_BB_BETWEEN (seed_bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
- EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
- if (!is_bb_annotated (seed_bb, *annotated_bb)
- && bitmap_set_bit (visited, seed_bb->index))
+ unsigned int component_id = 1;
+
+ /* Map from basic block to its component.
+ 0 is used for univisited BBs,
+ 1 means that BB is annotated,
+ >=2 is an id of the component BB belongs to. */
+ auto_vec <unsigned int, 20> component;
+ component.safe_grow (last_basic_block_for_fn (cfun));
+ FOR_ALL_BB_FN (seed_bb, cfun)
+ component[seed_bb->index]
+ = is_bb_annotated (seed_bb, *annotated_bb) ? 1 : 0;
+ FOR_ALL_BB_FN (seed_bb, cfun)
+ if (!component[seed_bb->index])
{
- hash_set <basic_block> current_component;
-
stack.quick_push (seed_bb);
+ component_id++;
bbs.truncate (0);
scales.truncate (0);
+ component[seed_bb->index] = component_id;
+ profile_count max_count = profile_count::zero ();
/* Identify connected component starting in BB. */
if (dump_file)
@@ -1588,19 +1649,33 @@ afdo_adjust_guessed_profile (bb_set *annotated_bb)
basic_block b = stack.pop ();
bbs.quick_push (b);
- current_component.add (b);
+ max_count = max_count.max (b->count);
for (edge e: b->preds)
- if (!is_bb_annotated (e->src, *annotated_bb)
- && bitmap_set_bit (visited, e->src->index))
- stack.quick_push (e->src);
+ if (!component[e->src->index])
+ {
+ stack.quick_push (e->src);
+ component[e->src->index] = component_id;
+ }
for (edge e: b->succs)
- if (!is_bb_annotated (e->dest, *annotated_bb)
- && bitmap_set_bit (visited, e->dest->index))
- stack.quick_push (e->dest);
+ if (!component[e->dest->index])
+ {
+ stack.quick_push (e->dest);
+ component[e->dest->index] = component_id;
+ }
}
while (!stack.is_empty ());
+ /* If all blocks in components has 0 count, we do not need
+ to scale, only we must convert to IPA quality. */
+ if (!max_count.nonzero_p ())
+ {
+ if (dump_file)
+ fprintf (dump_file, " All counts are 0; scale = 1\n");
+ scale_bbs (bbs, 1);
+ continue;
+ }
+
/* Now visit the component and try to figure out its desired
frequency. */
for (basic_block b : bbs)
@@ -1653,84 +1728,83 @@ afdo_adjust_guessed_profile (bb_set *annotated_bb)
}
else
{
- gcc_checking_assert (current_component.contains (e->src));
current_component_count += e->count ();
+ gcc_checking_assert (component[e->src->index] == component_id);
}
if (boundary && current_component_count.initialized_p ())
{
- profile_count in_count = b->count - current_component_count;
if (dump_file)
- {
- fprintf (dump_file, " bb %i in count ", b->index);
- in_count.dump (dump_file);
- fprintf (dump_file, " should be ");
- annotated_count.dump (dump_file);
- fprintf (dump_file, "\n");
- }
- if (in_count.nonzero_p ())
- {
- sreal scale
- = annotated_count.guessed_local ()
- .to_sreal_scale (in_count);
- if (dump_file)
- fprintf (dump_file, " adding scale %.16f\n",
- scale.to_double ());
- scales.safe_push (scale);
- }
+ fprintf (dump_file, " bb %i in count ", b->index);
+ add_scale (&scales,
+ annotated_count,
+ b->count - current_component_count);
}
for (edge e: b->succs)
if (AFDO_EINFO (e)->is_annotated ())
{
- profile_count out_count = e->count ();
- profile_count annotated_count = AFDO_EINFO (e)->get_count ();
if (dump_file)
- {
- fprintf (dump_file, " edge %i->%i count ",
- b->index, e->dest->index);
- out_count.dump (dump_file);
- fprintf (dump_file, " should be ");
- annotated_count.dump (dump_file);
- fprintf (dump_file, "\n");
- }
- if (out_count.nonzero_p ())
- {
- sreal scale
- = annotated_count.guessed_local ()
- .to_sreal_scale (out_count);
- if (dump_file)
- fprintf (dump_file, " adding scale %.16f\n",
- scale.to_double ());
- scales.safe_push (scale);
- }
+ fprintf (dump_file, " edge %i->%i count ",
+ b->index, e->dest->index);
+ add_scale (&scales, AFDO_EINFO (e)->get_count (), e->count ());
+ }
+ else if (is_bb_annotated (e->dest, *annotated_bb))
+ {
+ profile_count annotated_count = e->dest->count;
+ profile_count out_count = profile_count::zero ();
+ bool ok = true;
+ for (edge e2: e->dest->preds)
+ if (AFDO_EINFO (e2)->is_annotated ())
+ annotated_count -= AFDO_EINFO (e2)->get_count ();
+ else if (component[e->src->index] == component_id)
+ out_count += e->count ();
+ else if (e->probability.nonzero_p ())
+ {
+ ok = false;
+ break;
+ }
+ if (!ok)
+ continue;
+ if (dump_file)
+ fprintf (dump_file,
+ " edge %i->%i has annotated sucessor; count ",
+ b->index, e->dest->index);
+ add_scale (&scales, annotated_count, e->count ());
}
}
+
+ /* If we failed to find annotated entry or exit edge,
+ look for exit edges and scale profile so the dest
+ BB get all flow it needs. This is inprecise because
+ the edge is not annotated and thus BB has more than
+ one such predecessor. */
+ if (!scales.length ())
+ for (basic_block b : bbs)
+ if (b->count.nonzero_p ())
+ for (edge e: b->succs)
+ if (is_bb_annotated (e->dest, *annotated_bb))
+ {
+ profile_count annotated_count = e->dest->count;
+ for (edge e2: e->dest->preds)
+ if (AFDO_EINFO (e2)->is_annotated ())
+ annotated_count -= AFDO_EINFO (e2)->get_count ();
+ if (dump_file)
+ fprintf (dump_file,
+ " edge %i->%i has annotated sucessor;"
+ " upper bound count ",
+ b->index, e->dest->index);
+ add_scale (&scales, annotated_count, e->count ());
+ }
if (!scales.length ())
- continue;
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ " Can not determine count from the boundary; giving up");
+ continue;
+ }
+ gcc_checking_assert (scales.length ());
scales.qsort (cmp);
- sreal scale = scales[scales.length () / 2];
- if (dump_file)
- fprintf (dump_file, " Scaling by %.16f\n", scale.to_double ());
- for (basic_block b : bbs)
- if (!(b->count == profile_count::zero ())
- && b->count.initialized_p ())
- {
- profile_count o = b->count;
- b->count = b->count.force_guessed () * scale;
-
- /* If we scaled to 0, make it auto-fdo since that is treated
- less agressively. */
- if (!b->count.nonzero_p () && o.nonzero_p ())
- b->count = profile_count::zero ().afdo ();
- if (dump_file)
- {
- fprintf (dump_file, " bb %i count updated ", b->index);
- o.dump (dump_file);
- fprintf (dump_file, " -> ");
- b->count.dump (dump_file);
- fprintf (dump_file, "\n");
- }
- }
+ scale_bbs (bbs, scales[scales.length () / 2]);
}
}
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 93353cb..2441c9e 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -250,7 +250,7 @@ cgraph_node::make_profile_global0 (profile_quality quality)
void
cgraph_node::apply_scale (profile_count num, profile_count den)
{
- if (num == den)
+ if (num == den && !(num == profile_count::zero ()))
return;
for (cgraph_edge *e = callees; e; e = e->next_callee)
@@ -3763,6 +3763,13 @@ cgraph_node::verify_node (void)
count.debug ();
error_found = true;
}
+ if (inlined_to && !e->count.compatible_p (inlined_to->count))
+ {
+ error ("edge count is not compatible with inlined to function count");
+ e->count.debug ();
+ count.debug ();
+ error_found = true;
+ }
if (!e->indirect_unknown_callee
|| !e->indirect_info)
{
diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog
index bb8d631..3ff4700 100644
--- a/gcc/cobol/ChangeLog
+++ b/gcc/cobol/ChangeLog
@@ -1,3 +1,103 @@
+2025-06-18 James K. Lowden <jklowden@cobolworx.com>
+
+ PR cobol/120621
+ * cbldiag.h (yyerror): Add diagnostic attributes.
+ (yywarn): Same.
+ (error_msg): Same.
+ (yyerrorvl): Same.
+ (cbl_unimplementedw): Same.
+ (cbl_unimplemented): Same.
+ (cbl_unimplemented_at): Same.
+ * cdf-copy.cc (copybook_elem_t::open_file): Supply string argument.
+ * cdf.y: Use %<%>.
+ * cobol-system.h (if): Check GCC_VERSION.
+ (ATTRIBUTE_GCOBOL_DIAG): Define.
+ * except.cc (cbl_enabled_exception_t::dump): Remove extra %s.
+ * genapi.cc (get_class_condition_string): Use acceptable message.
+ (get_bytes_needed): Same.
+ (move_tree): Same.
+ (get_string_from): Same.
+ (internal_perform_through): Same.
+ (tree_type_from_field_type): Same.
+ (is_valuable): Same.
+ (parser_logop): Same.
+ (parser_relop): Same.
+ (parser_relop_long): Same.
+ (parser_if): Same.
+ (parser_setop): Same.
+ (parser_perform_conditional): Same.
+ (parser_file_add): Same.
+ (parser_file_open): Same.
+ (parser_file_close): Same.
+ (parser_file_read): Same.
+ (parser_file_write): Same.
+ (inspect_replacing): Same.
+ (parser_sort): Same.
+ (parser_file_sort): Same.
+ (parser_file_merge): Same.
+ (create_and_call): Same.
+ (parser_bitop): Same.
+ (parser_bitwise_op): Same.
+ (hijack_for_development): Same.
+ (mh_source_is_literalN): Same.
+ (mh_dest_is_float): Same.
+ (parser_symbol_add): Same.
+ * gengen.cc (show_type): Use acceptable message.
+ (gg_find_field_in_struct): Same.
+ (gg_declare_variable): Same.
+ (gg_printf): Same.
+ (gg_fprintf): Same.
+ (gg_tack_on_function_parameters): Same.
+ (gg_define_function): Same.
+ (gg_get_function_decl): Same.
+ (gg_finalize_function): Same.
+ (gg_call_expr): Same.
+ (gg_call): Same.
+ (gg_insert_into_assembler): Define new function.
+ (gg_insert_into_assemblerf): Use gg_insert_into_assembler().
+ * gengen.h (gg_insert_into_assembler): Simpler function declaration.
+ (gg_insert_into_assemblerf): Declare new function.
+ * genmath.cc (parser_op): Use acceptable message.
+ * genutil.cc (get_binary_value): Use acceptable message.
+ * lexio.cc (parse_replacing_pair): Correct diagnostic arguments.
+ (preprocess_filter_add): Same.
+ (cdftext::open_input): Same.
+ * parse.y: Use acceptable messages.
+ * parse_ante.h (struct evaluate_elem_t): Use %<%>.
+ (is_callable): Same.
+ * parse_util.h (intrinsic_invalid_parameter): Use %qs.
+ * scan.l: Use dialect_error().
+ * scan_ante.h (numstr_of): Use %qs.
+ (scanner_token): Quote COBOL tokens in messages.
+ (scanner_parsing): Correct diagnostic message.
+ (scanner_parsing_toggle): Quote COBOL tokens in messages.
+ (scanner_parsing_pop): Same.
+ (typed_name): Use %qs.
+ * scan_post.h (prelex): Quote COBOL tokens in message.
+ * show_parse.h (CHECK_FIELD): Use acceptable message format.
+ (CHECK_LABEL): Same.
+ * symbols.cc (symbol_field_same_as): Remove extra spaces.
+ (cbl_alphabet_t::assign): Use %<%>.
+ (cbl_field_t::internalize): Quote library name in message.
+ * symbols.h (struct os_locale_t): Constify codeset.
+ (class temporaries_t): Add copy constructor.
+ (struct cbl_alphabet_t): Use acceptable message.
+ * util.cc (symbol_type_str): Use cbl_internal_error.
+ (cbl_field_type_str): Same.
+ (is_elementary): Same.
+ (cbl_field_t::report_invalid_initial_value): Use %qs.
+ (class unique_stack): Avoid %m.
+ (ydferror): Declare function with attributes.
+ (error_msg): Same.
+ (cobol_fileline_set): Use %<%>.
+ (os_locale_t): Remove use of xstrdup.
+ (cobol_parse_files): Quote C names in message.
+ (dialect_error): Use %<%>.
+ * util.h (cbl_message): Add attributes.
+ (cbl_internal_error): Same.
+ (cbl_err): Same.
+ (cbl_errx): Same.
+
2025-06-16 James K. Lowden <jklowden@cobolworx.com>
PR cobol/120621
diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h
index 6b371eb..548b0f2 100644
--- a/gcc/cobol/cbldiag.h
+++ b/gcc/cobol/cbldiag.h
@@ -45,8 +45,8 @@ const char * cobol_filename();
* These are user-facing messages. They go through the gcc
* diagnostic framework and use text that can be localized.
*/
-void yyerror( const char fmt[], ... );
-bool yywarn( const char fmt[], ... );
+void yyerror( const char fmt[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2);
+bool yywarn( const char fmt[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2);
/* Location type. Borrowed from parse.h as generated by Bison. */
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
@@ -79,18 +79,21 @@ struct YDFLTYPE
#endif
// an error at a location, called from the parser for semantic errors
-void error_msg( const YYLTYPE& loc, const char gmsgid[], ... );
+void error_msg( const YYLTYPE& loc, const char gmsgid[], ... )
+ ATTRIBUTE_GCOBOL_DIAG(2, 3);
void dialect_error( const YYLTYPE& loc, const char term[], const char dialect[] );
// for CDF and other warnings that refer back to an earlier line
// (not in diagnostic framework yet)
-void yyerrorvl( int line, const char *filename, const char fmt[], ... );
+void yyerrorvl( int line, const char *filename, const char fmt[], ... )
+ ATTRIBUTE_PRINTF_3;
-void cbl_unimplementedw(const char *gmsgid, ...); // warning
-void cbl_unimplemented(const char *gmsgid, ...); // error
-void cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... );
+void cbl_unimplementedw(const char *gmsgid, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); // warning
+void cbl_unimplemented(const char *gmsgid, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); // error
+void cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... )
+ ATTRIBUTE_GCOBOL_DIAG(2, 3);
/*
* dbgmsg produce messages not intended for the user. They cannot be localized
diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc
index f45c466..11be9b8 100644
--- a/gcc/cobol/cdf-copy.cc
+++ b/gcc/cobol/cdf-copy.cc
@@ -304,7 +304,8 @@ copybook_elem_t::open_file( const char directory[], bool literally ) {
dbgmsg("found copybook file %s", filename);
this->source.name = xstrdup(filename);
if( ! cobol_filename(this->source.name, inode_of(fd)) ) {
- error_msg(source.loc, "recursive copybook: '%s' includes itself", this->source);
+ error_msg(source.loc, "recursive copybook: '%s' includes itself",
+ this->source.name);
(void)! close(fd);
fd = -1;
}
diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y
index 7e7d226..3344271 100644
--- a/gcc/cobol/cdf.y
+++ b/gcc/cobol/cdf.y
@@ -263,7 +263,7 @@ top: partials { YYACCEPT; }
YYACCEPT;
}
| copy error {
- error_msg(@error, "COPY directive must end in a '.'");
+ error_msg(@error, "COPY directive must end in a %<.%>");
YYABORT;
}
| completes { YYACCEPT; }
@@ -365,13 +365,15 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override
| CDF_DEFINE FEATURE as ON {
auto feature = cbl_gcobol_feature_t($2);
if( ! cobol_gcobol_feature_set(feature, true) ) {
- error_msg(@FEATURE, ">>DEFINE %EBCDIC-MODE is invalid within program body");
+ error_msg(@FEATURE,
+ "%<>>DEFINE %%EBCDIC-MODE%> is invalid within program body");
}
}
| CDF_DEFINE FEATURE as OFF {
auto feature = cbl_gcobol_feature_t($2);
if( ! cobol_gcobol_feature_set(feature, false) ) {
- error_msg(@FEATURE, ">>DEFINE %EBCDIC-MODE is invalid within program body");
+ error_msg(@FEATURE,
+ "%<>>DEFINE %%EBCDIC-MODE%> is invalid within program body");
}
}
;
@@ -430,7 +432,7 @@ filenames: filename {
auto inserted = $$->insert(symbol_index(symbol_elem_of($2)));
if( ! inserted.second ) {
error_msg(@2, "%s: No file-name shall be specified more than "
- " once for one exception condition", $filename->name);
+ "once for one exception condition", $filename->name);
}
}
;
@@ -517,7 +519,7 @@ cdf_relexpr: cdf_relexpr '<' cdf_expr { $$ = $1(@1) < $3(@3); }
const char *msg = $1.string?
"incommensurate comparison is FALSE: '%s' = %ld" :
"incommensurate comparison is FALSE: %ld = '%s'" ;
- error_msg(@1, msg);
+ error_msg(@1, "%s", msg);
}
}
| cdf_relexpr NE cdf_expr
@@ -531,7 +533,7 @@ cdf_relexpr: cdf_relexpr '<' cdf_expr { $$ = $1(@1) < $3(@3); }
const char *msg = $1.string?
"incommensurate comparison is FALSE: '%s' = %ld" :
"incommensurate comparison is FALSE: %ld = '%s'" ;
- error_msg(@1, msg);
+ error_msg(@1, "%s", msg);
}
}
| cdf_relexpr GE cdf_expr { $$ = $1(@1) >= $3(@3); }
@@ -567,7 +569,7 @@ cdf_factor: NAME {
| NUMSTR {
auto value = integer_literal($NUMSTR);
if( !value.second ) {
- error_msg(@1, "CDF error: parsed %s as %ld",
+ error_msg(@1, "CDF error: parsed %qs as %lld",
$NUMSTR, value.first);
YYERROR;
}
@@ -593,7 +595,7 @@ copybook_name: COPY name_one[src]
copybook.library(@lib, $lib.string);
if( -1 == copybook.open(@src, $src.string) ) {
error_msg(@src, "could not open copybook file "
- "for '%s' in '%'s'", $src.string, $lib.string);
+ "for %<%s%> in %<%s%>", $src.string, $lib.string);
YYABORT;
}
}
diff --git a/gcc/cobol/cobol-system.h b/gcc/cobol/cobol-system.h
index ff95835..828f4f5 100644
--- a/gcc/cobol/cobol-system.h
+++ b/gcc/cobol/cobol-system.h
@@ -60,4 +60,10 @@
// The following "local" #include is part of the GCC core code
#include "system.h"
+#if (CHECKING_P && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION
+#define ATTRIBUTE_GCOBOL_DIAG(m, n) __attribute__ ((__format__ (__gcc_tdiag__, m, n))) ATTRIBUTE_NONNULL(m)
+#else
+#define ATTRIBUTE_GCOBOL_DIAG(m, n) ATTRIBUTE_NONNULL(m)
+#endif
+
#endif
diff --git a/gcc/cobol/except.cc b/gcc/cobol/except.cc
index e50fa61..3e073e2 100644
--- a/gcc/cobol/except.cc
+++ b/gcc/cobol/except.cc
@@ -77,7 +77,7 @@ ec_level( ec_type_t ec ) {
void
cbl_enabled_exception_t::dump( int i ) const {
- cbl_message(2, "cbl_enabled_exception_t: %2d {%s, %s, %s, %zu}",
+ cbl_message(2, "cbl_enabled_exception_t: %2d {%s, %s, %zu}",
i,
location? "location" : " none",
ec_type_str(ec),
diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index f2a5d0e..0ea41f1 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -571,7 +571,7 @@ get_class_condition_string(cbl_field_t *var)
{
if( strlen(ach) > sizeof(ach) - 1000 )
{
- cbl_internal_error("Nice try, but you can't fire me. I quit!");
+ cbl_internal_error("Nice try, but you cannot fire me.");
}
// We are working with unquoted strings that contain the values 1 through
@@ -1756,7 +1756,7 @@ get_bytes_needed(cbl_field_t *field)
}
default:
- cbl_internal_error("%s(): Knows not the variable type %s for %s",
+ cbl_internal_error("%s: Knows not the variable type %s for %s",
__func__,
cbl_field_type_str(field->type),
field->name );
@@ -2445,10 +2445,10 @@ move_tree( cbl_field_t *dest,
if( !moved )
{
- dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ );
- cbl_internal_error( "I don't know how to MOVE an alphabetical string to %s(%s) \n",
- cbl_field_type_str(dest->type),
- dest->name
+ dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ );
+ cbl_internal_error( "I don%'t know how to MOVE an alphabetical string to %s(%s)",
+ cbl_field_type_str(dest->type),
+ dest->name
);
return;
}
@@ -2514,7 +2514,7 @@ get_string_from(cbl_field_t *field)
default:
cbl_internal_error(
- "%s(): field->type %s must be literal or alphanumeric",
+ "%s: %<field->type%> %s must be literal or alphanumeric",
__func__, cbl_field_type_str(field->type));
break;
}
@@ -3449,7 +3449,7 @@ internal_perform_through( cbl_label_t *proc_1,
pseudo_return_push(proc2, return_addr);
// Create the code that will launch the first procedure
- gg_insert_into_assembler("%s PERFORM %s THROUGH %s",
+ gg_insert_into_assemblerf("%s PERFORM %s THROUGH %s",
ASM_COMMENT_START, proc_1->name, proc_2->name);
if( !suppress_nexting )
@@ -6026,7 +6026,7 @@ tree_type_from_field_type(cbl_field_t *field, size_t &nbytes)
break;
default:
- cbl_internal_error( "%s(): Invalid field type %s:",
+ cbl_internal_error( "%s: Invalid field type %s:",
__func__,
cbl_field_type_str(field->type));
break;
@@ -6082,7 +6082,7 @@ is_valuable( cbl_field_type_t type ) {
case FldPointer:
return true;
}
- cbl_internal_error( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type );
+ cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type );
return false;
}
@@ -7228,20 +7228,20 @@ parser_logop( struct cbl_field_t *tgt,
if( tgt->type != FldConditional )
{
- cbl_internal_error("parser_logop() was called with variable %s on line %d"
- ", which is not a FldConditional\n",
+ cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d"
+ ", which is not a FldConditional",
tgt->name, cobol_location().first_line);
}
if( a && a->type != FldConditional )
{
- cbl_internal_error("parser_logop() was called with variable %s on line %d"
- ", which is not a FldConditional\n",
+ cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d"
+ ", which is not a FldConditional",
a->name, cobol_location().first_line);
}
if( b && b->type != FldConditional )
{
- cbl_internal_error("parser_logop() was called with variable %s on line %d"
- ", which is not a FldConditional\n",
+ cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d"
+ ", which is not a FldConditional",
b->name, cobol_location().first_line);
}
@@ -7347,9 +7347,9 @@ parser_relop( cbl_field_t *tgt,
if( tgt->type != FldConditional )
{
- cbl_internal_error("parser_relop() was called with variable %s, "
- "which is not a FldConditional\n",
- tgt->name);
+ cbl_internal_error("%<parser_relop%> was called with variable %qs, "
+ "which is not a FldConditional",
+ tgt->name);
}
static tree comp_res = gg_define_variable(INT, "..pr_comp_res", vs_file_static);
@@ -7411,8 +7411,8 @@ parser_relop_long(cbl_field_t *tgt,
if( tgt->type != FldConditional )
{
- cbl_internal_error("parser_relop() was called with variable %s, "
- "which is not a FldConditional\n",
+ cbl_internal_error("%<parser_relop()%> was called with variable %s, "
+ "which is not a FldConditional",
tgt->name);
}
@@ -7457,8 +7457,8 @@ parser_if( struct cbl_field_t *conditional )
if( conditional->type != FldConditional )
{
- cbl_internal_error("parser_if() was called with variable %s, "
- "which is not a FldConditional\n",
+ cbl_internal_error("%<parser_if()%> was called with variable %s, "
+ "which is not a FldConditional",
conditional->name);
}
@@ -7708,20 +7708,19 @@ parser_setop( struct cbl_field_t *tgt,
integer_zero_node));
break;
default:
- dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ );
- cbl_internal_error(
- "###### candidate %s has unimplemented CVT_type %d(%s)\n",
- candidate->name,
- candidate->type,
- cbl_field_type_str(candidate->type));
+ dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ );
+ cbl_internal_error("candidate %s has unimplemented %<CVT_type%> %d(%s)",
+ candidate->name,
+ candidate->type,
+ cbl_field_type_str(candidate->type));
gcc_unreachable();
break;
}
break;
default:
- dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ );
- cbl_internal_error("###### unknown setop_t code %d\n", op);
+ dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ );
+ cbl_internal_error("unknown %<setop_t%> code %d", op);
gcc_unreachable();
break;
}
@@ -7917,7 +7916,7 @@ parser_perform_conditional( struct cbl_perform_tgt_t *tgt )
if( !(i < MAXIMUM_UNTILS) )
{
- cbl_internal_error("%s:%d: %u exceeds MAXIMUM_UNTILS of %d, line %d",
+ cbl_internal_error("%s:%d: %u exceeds %<MAXIMUM_UNTILS%> of %d, line %d",
__func__, __LINE__,
i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER);
}
@@ -9151,7 +9150,7 @@ parser_file_add(struct cbl_file_t *file)
if( !file )
{
- cbl_internal_error("%s(): called with NULL *file", __func__);
+ cbl_internal_error("%s: called with NULL *file", __func__);
gcc_assert(file);
}
@@ -9276,7 +9275,7 @@ parser_file_add(struct cbl_file_t *file)
if(file->access == file_inaccessible_e)
{
cbl_internal_error(
- "%s:%d file %s access mode is 'file_inaccessible_e' in %s",
+ "%s:%d file %s access mode is %<file_inaccessible_e%> in %s",
current_filename.back().c_str(),
CURRENT_LINE_NUMBER,
file->name,
@@ -9350,12 +9349,13 @@ parser_file_open( struct cbl_file_t *file, int mode_char )
if( !file )
{
- cbl_internal_error("parser_file_open called with NULL *file");
+ cbl_internal_error("%<parser_file_open%> called with NULL *file");
}
if( !file->var_decl_node )
{
- cbl_internal_error("parser_file_open for %s called with NULL var_decl_node", file->name);
+ cbl_internal_error("%<parser_file_open%> for %s called with NULL "
+ "%<var_decl_node%>", file->name);
}
if( mode_char == 'a' && (file->access != file_access_seq_e) )
@@ -9429,12 +9429,13 @@ parser_file_close( struct cbl_file_t *file, file_close_how_t how )
if( !file )
{
- cbl_internal_error("parser_file_close called with NULL *file");
+ cbl_internal_error("%<parser_file_close%> called with NULL *file");
}
if( !file->var_decl_node )
{
- cbl_internal_error("parser_file_close for %s called with NULL file->var_decl_node", file->name);
+ cbl_internal_error("%<parser_file_close%> for %s called with "
+ "NULL %<file->var_decl_node%>", file->name);
}
TRACE1
@@ -9498,27 +9499,29 @@ parser_file_read( struct cbl_file_t *file,
if( !file )
{
- cbl_internal_error("parser_file_read called with NULL *file");
+ cbl_internal_error("%<parser_file_read%> called with NULL *file");
}
if( !file->var_decl_node )
{
- cbl_internal_error("parser_file_read for %s called with NULL file->var_decl_node", file->name);
+ cbl_internal_error("%<parser_file_read%> for %s called with "
+ "NULL %<file->var_decl_node%>", file->name);
}
if( !file )
{
- cbl_internal_error("parser_file_read called with NULL *field");
+ cbl_internal_error("%<parser_file_read%> called with NULL *field");
}
if( !file->var_decl_node )
{
- cbl_internal_error("parser_file_read for %s called with NULL field->var_decl_node", file->name);
+ cbl_internal_error("%<parser_file_read%> for %s called with "
+ "NULL %<field->var_decl_node%>", file->name);
}
if( file->access == file_access_seq_e && where >= 0)
{
- cbl_internal_error("%s:%d file %s is RELATIVE/SEQUENTIAL, but 'where' >= 0",
+ cbl_internal_error("%s:%d file %s is RELATIVE/SEQUENTIAL, but %<where >= 0%>",
current_filename.back().c_str(),
CURRENT_LINE_NUMBER,
file->name);
@@ -9527,7 +9530,7 @@ parser_file_read( struct cbl_file_t *file,
if( file->access == file_access_rnd_e && where < 0)
{
- cbl_internal_error("%s:%d file %s is RELATIVE/RANDOM, but 'where' < 0",
+ cbl_internal_error("%s:%d file %s is RELATIVE/RANDOM, but %<where < 0%>",
current_filename.back().c_str(),
CURRENT_LINE_NUMBER,
file->name);
@@ -9615,23 +9618,23 @@ parser_file_write( cbl_file_t *file,
if( !file )
{
- cbl_internal_error("%s(): called with NULL *file", __func__);
+ cbl_internal_error("%s: called with NULL *file", __func__);
}
if( !file->var_decl_node )
{
- cbl_internal_error("%s(): for %s called with NULL file->var_decl_node",
+ cbl_internal_error("%s: for %s called with NULL %<file->var_decl_node%>",
__func__, file->name);
}
if( !file )
{
- cbl_internal_error("%s(): called with NULL *field", __func__);
+ cbl_internal_error("%s: called with NULL *field", __func__);
}
if( !file->var_decl_node )
{
- cbl_internal_error( "%s(): for %s called with NULL field->var_decl_node",
+ cbl_internal_error( "%s: for %s called with NULL %<field->var_decl_node%>",
__func__,
file->name);
}
@@ -10292,9 +10295,9 @@ inspect_replacing(int backward,
}
}
- //fprintf(stderr, "%s(): %ld %ld\n", __func__, int_index, n_integers);
+ //fprintf(stderr, "%s: %ld %ld\n", __func__, int_index, n_integers);
gcc_assert(int_index == n_integers);
- //fprintf(stderr, "%s(): %ld %ld\n", __func__, pcbl_index, n_resolveds);
+ //fprintf(stderr, "%s: %ld %ld\n", __func__, pcbl_index, n_resolveds);
gcc_assert(pcbl_index == n_resolveds);
// We have built up an array of integers, and an array of cbl_refer_t.
@@ -11477,7 +11480,7 @@ parser_sort(cbl_refer_t tableref,
gcc_assert(table->var_decl_node);
if( !is_table(table) )
{
- cbl_internal_error( "%s(): asked to sort %s, but it's not a table",
+ cbl_internal_error( "%s: asked to sort %s, which is not a table",
__func__,
tableref.field->name);
}
@@ -11605,7 +11608,7 @@ parser_file_sort( cbl_file_t *workfile,
else
{
// Having both or neither violates SORT syntax
- cbl_internal_error("%s(): syntax error -- both (or neither) USING "
+ cbl_internal_error("%s: syntax error: both (or neither) USING "
"and input-proc are specified",
__func__);
}
@@ -11735,7 +11738,7 @@ parser_file_sort( cbl_file_t *workfile,
}
else
{
- cbl_internal_error("%s(): syntax error -- both (or neither) GIVING "
+ cbl_internal_error("%s: syntax error: both (or neither) GIVING "
"and output-proc are specified", __func__);
}
}
@@ -12147,7 +12150,7 @@ parser_file_merge( cbl_file_t *workfile,
}
else
{
- cbl_internal_error("%s(): syntax error -- both (or neither) "
+ cbl_internal_error("%s: syntax error: both (or neither) "
"files and output-proc are specified", __func__);
}
}
@@ -12798,7 +12801,7 @@ create_and_call(size_t narg,
else
{
cbl_internal_error(
- "%s(): What in the name of Nero's fiddle are we doing here?",
+ "%s: What in the name of Nero are we doing here?",
__func__);
}
}
@@ -13038,7 +13041,7 @@ parser_bitop( struct cbl_field_t *tgt, // tgt has to be a FldConditional
if(tgt && tgt->type != FldConditional)
{
fprintf(stderr,
- "%s(): The target %s has to be a FldConditional, not %s\n",
+ "%s: The target %s has to be a FldConditional, not %s\n",
__func__,
tgt->name,
cbl_field_type_str(tgt->type));
@@ -13075,7 +13078,7 @@ parser_bitop( struct cbl_field_t *tgt, // tgt has to be a FldConditional
case bit_or_op:
case bit_xor_op:
fprintf(stderr,
- "%s(): The %s operation is not valid\n",
+ "%s: The %s operation is not valid\n",
__func__,
ops[op]);
gcc_unreachable();
@@ -13122,7 +13125,7 @@ parser_bitwise_op(struct cbl_field_t *tgt,
if( tgt && !is_valuable(tgt->type) && tgt->type != FldLiteralN)
{
fprintf(stderr,
- "%s(): The target %s has to be is_valuable, not %s\n",
+ "%s: The target %s has to be is_valuable, not %s\n",
__func__,
tgt->name,
cbl_field_type_str(tgt->type));
@@ -13136,7 +13139,7 @@ parser_bitwise_op(struct cbl_field_t *tgt,
case bit_on_op:
case bit_off_op:
fprintf(stderr,
- "%s(): The %s operation is not valid\n",
+ "%s: The %s operation is not valid\n",
__func__,
ops[op]);
gcc_unreachable();
@@ -13749,7 +13752,7 @@ hijack_for_development(const char *funcname)
// Assume that funcname is lowercase with no hyphens
enter_program_common(funcname, funcname);
parser_display_literal("You have been hijacked by a program named \"dubner\"");
- gg_insert_into_assembler("%s HIJACKED DUBNER CODE START", ASM_COMMENT_START);
+ gg_insert_into_assemblerf("%s HIJACKED DUBNER CODE START", ASM_COMMENT_START);
for(int i=0; i<10; i++)
{
@@ -13762,7 +13765,7 @@ hijack_for_development(const char *funcname)
NULL_TREE);
}
- gg_insert_into_assembler("%s HIJACKED DUBNER CODE END", ASM_COMMENT_START);
+ gg_insert_into_assemblerf("%s HIJACKED DUBNER CODE END", ASM_COMMENT_START);
gg_return(0);
}
@@ -14083,8 +14086,8 @@ mh_source_is_literalN(cbl_refer_t &destref,
default:
cbl_internal_error(
- "In parser_move(%s to %s), the move of FldLiteralN to %s "
- "hasn't been implemented",
+ "In %<parser_move(%s to %s)%>, the move of FldLiteralN to %s "
+ "is unimplemented",
sourceref.field->name,
destref.field->name,
cbl_field_type_str(destref.field->type));
@@ -14319,8 +14322,8 @@ mh_dest_is_float( cbl_refer_t &destref,
}
default:
- cbl_internal_error("In mh_dest_is_float(%s to %s), the "
- "move of %s to %s hasn't been implemented",
+ cbl_internal_error("In %<mh_dest_is_float%>(%s to %s), the "
+ "move of %s to %s is unimplemented",
sourceref.field->name,
destref.field->name,
cbl_field_type_str(sourceref.field->type),
@@ -16349,7 +16352,7 @@ parser_symbol_add(struct cbl_field_t *new_var )
{
do
{
- fprintf(stderr, "( %d ) %s():", CURRENT_LINE_NUMBER, __func__);
+ fprintf(stderr, "( %d ) %s:", CURRENT_LINE_NUMBER, __func__);
}
while(0);
@@ -16487,7 +16490,7 @@ parser_symbol_add(struct cbl_field_t *new_var )
// Make sure we have a new variable to work with.
if( !new_var )
{
- cbl_internal_error("parser_symbol_add() was called with a NULL new_var\n");
+ cbl_internal_error("%<parser_symbol_add()%> was called with a NULL %<new_var%>");
}
TRACE1
@@ -16515,7 +16518,7 @@ parser_symbol_add(struct cbl_field_t *new_var )
if( is_table(new_var) && new_var->data.capacity == 0)
{
cbl_internal_error(
- "%s(): %2.2d %s is a table, but it improperly has a capacity of zero",
+ "%s: %d %s is a table, but it improperly has a capacity of zero",
__func__,
new_var->level,
new_var->name);
@@ -16555,23 +16558,20 @@ parser_symbol_add(struct cbl_field_t *new_var )
if( ancestor == new_var )
{
- cbl_internal_error("parser_symbol_add(): %s is its own ancestor",
- new_var->name);
+ cbl_internal_error("%s: %s is its own ancestor", __func__, new_var->name);
}
if( !ancestor && (new_var->level > LEVEL01 && new_var->level <= LEVEL49 ) )
{
- cbl_internal_error("parser_symbol_add(): %2.2d %s has null ancestor",
- new_var->level,
- new_var->name);
+ cbl_internal_error("%s: %d %qs has NULL ancestor", __func__,
+ new_var->level, new_var->name);
}
// new_var's var_decl_node should be NULL at this point
if( new_var->var_decl_node )
{
- cbl_internal_error( "parser_symbol_add( %s ) improperly has a non-null "
- "var_decl_node\n",
- new_var->name);
+ cbl_internal_error( "%s(%s) improperly has a non-null "
+ "%<var_decl_node%>", __func__, new_var->name);
}
switch( new_var->type )
@@ -16765,7 +16765,7 @@ parser_symbol_add(struct cbl_field_t *new_var )
&& new_var->type != FldLiteralN
&& new_var->type != FldLiteralA )
{
- cbl_internal_error( "%s(): %2.2d %s<%s> improperly has a data.capacity of zero",
+ cbl_internal_error( "%s: %d %s<%s> improperly has a data.capacity of zero",
__func__,
new_var->level,
new_var->name,
@@ -16832,12 +16832,10 @@ parser_symbol_add(struct cbl_field_t *new_var )
if( !bytes_to_allocate )
{
- fprintf(stderr,
- "bytes_to_allocate is zero for %s (symbol number "
- HOST_SIZE_T_PRINT_DEC ")\n",
- new_var->name,
- (fmt_size_t)new_var->our_index);
- gcc_assert(bytes_to_allocate);
+ cbl_internal_error( "%<bytes_to_allocate%> is zero for %s (symbol number "
+ HOST_SIZE_T_PRINT_DEC ")",
+ new_var->name,
+ (fmt_size_t)new_var->our_index);
}
if( new_var->type == FldIndex && new_var->level == 0 )
diff --git a/gcc/cobol/gengen.cc b/gcc/cobol/gengen.cc
index a5f143c..1098225 100644
--- a/gcc/cobol/gengen.cc
+++ b/gcc/cobol/gengen.cc
@@ -360,7 +360,7 @@ show_type(tree type)
{
if( !type )
{
- cbl_internal_error("The given type is not NULL, and that's just not fair");
+ cbl_internal_error("The given type is not NULL, and that is just not fair");
}
if( DECL_P(type) )
@@ -369,7 +369,7 @@ show_type(tree type)
}
if( !TYPE_P(type) )
{
- cbl_internal_error("The given type is not a DECL or a TYPE");
+ cbl_internal_error("The given type is not a declaration or a TYPE");
}
static char ach[1024];
@@ -520,8 +520,7 @@ gg_find_field_in_struct(const tree base, const char *field_name)
if( !field_decl )
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### Somebody asked for the field %s.%s, which doesn't exist",
+ yywarn("Somebody asked for the field %s.%s, which does not exist",
IDENTIFIER_POINTER(DECL_NAME(base)),
field_name);
gcc_unreachable();
@@ -933,7 +932,7 @@ gg_declare_variable(tree type_decl,
// causes the storage to be allocated.
// It is routine to let the compiler assign names to stack variables. The
- // assembly code doesn't use names for variables on the stack; they are
+ // assembly code does not use names for variables on the stack; they are
// referenced by offsets to the base pointer. But static variables have to
// have names, and there are places in my code generation -- Lord only knows
// why -- where I didn't give the variables explicit names. We remedy that
@@ -2161,8 +2160,7 @@ gg_printf(const char *format_string, ...)
{
if(nargs >= ARG_LIMIT)
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### You *must* be joking!");
+ yywarn("You *must* be joking");
gcc_unreachable();
}
@@ -2170,10 +2168,8 @@ gg_printf(const char *format_string, ...)
{
// Warning: This test is not completely reliable, because a garbage
// byte could have a valid TREE_CODE. But it does help.
- yywarn("You nitwit!");
- yywarn("You forgot to put a NULL_TREE at the end of a "
- "gg_printf() again!");
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
+ yywarn("You forgot to put a %<NULL_TREE%> at the end of a "
+ "%<gg_printf()%> again");
gcc_unreachable();
}
@@ -2219,8 +2215,7 @@ gg_fprintf(tree fd, int nargs, const char *format_string, ...)
{
if(argc >= ARG_LIMIT)
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### You *must* be joking!");
+ yywarn("You *must* be joking");
gcc_unreachable();
}
@@ -2601,10 +2596,8 @@ gg_tack_on_function_parameters(tree function_decl, ...)
{
// Warning: This test is not completely reliable, because a garbage
// byte could have a valid TREE_CODE. But it does help.
- yywarn("You nitwit!");
- yywarn("You forgot to put a NULL_TREE at the end of a "
- "gg_define_function() again!");
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
+ yywarn("You forgot to put a %<NULL_TREE%> at the end of a "
+ "%<gg_define_function()%> again");
gcc_unreachable();
}
@@ -2615,8 +2608,7 @@ gg_tack_on_function_parameters(tree function_decl, ...)
nparams += 1;
if(nparams > ARG_LIMIT)
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### %d parameters? Really? Are you insane?",ARG_LIMIT+1);
+ yywarn("%d parameters? Really? Are you insane?",ARG_LIMIT+1);
gcc_unreachable();
}
}
@@ -2657,10 +2649,8 @@ gg_define_function(tree return_type, const char *funcname, ...)
{
// Warning: This test is not completely reliable, because a garbage
// byte could have a valid TREE_CODE. But it does help.
- yywarn("You nitwit!");
- yywarn("You forgot to put a NULL_TREE at the end of a "
- "gg_define_function() again!");
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
+ yywarn("You forgot to put a %<NULL_TREE%> at the end of a "
+ "%<gg_define_function()%> again");
gcc_unreachable();
}
@@ -2671,9 +2661,7 @@ gg_define_function(tree return_type, const char *funcname, ...)
nparams += 1;
if(nparams > ARG_LIMIT)
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### %d parameters? Really? Are you insane?",
- ARG_LIMIT+1);
+ yywarn("%d parameters? Really? Are you insane?", ARG_LIMIT+1);
gcc_unreachable();
}
}
@@ -2785,10 +2773,8 @@ gg_get_function_decl(tree return_type, const char *funcname, ...)
{
// Warning: This test is not completely reliable, because a garbage
// byte could have a valid TREE_CODE. But it does help.
- yywarn("You nitwit!");
- yywarn("You forgot to put a NULL_TREE at the end of a "
- "gg_define_function() again!");
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
+ yywarn("You forgot to put a %<NULL_TREE%> at the end of a "
+ "%<gg_define_function()%> again");
gcc_unreachable();
}
@@ -2799,8 +2785,7 @@ gg_get_function_decl(tree return_type, const char *funcname, ...)
nparams += 1;
if(nparams > ARG_LIMIT)
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### %d parameters? Really? Are you insane?",
+ yywarn("%d parameters? Really? Are you insane?",
ARG_LIMIT+1);
gcc_unreachable();
}
@@ -2909,7 +2894,7 @@ gg_finalize_function()
/* Register this function with cgraph just far enough to get it
added to our parent's nested function list. Handy, since the
- C front end doesn't have such a list. */
+ C front end does not have such a list. */
static cgraph_node *node = cgraph_node::get_create (current_function->function_decl);
gcc_assert(node);
@@ -2925,7 +2910,7 @@ gg_finalize_function()
if( gg_trans_unit.function_stack.back().context_count )
{
- cbl_internal_error("Residual context count!");
+ cbl_internal_error("Residual context count");
}
gg_trans_unit.function_stack.pop_back();
@@ -3070,8 +3055,7 @@ gg_call_expr(tree return_type, const char *function_name, ...)
{
if(nargs >= ARG_LIMIT)
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### You *must* be joking!");
+ yywarn("You *must* be joking");
gcc_unreachable();
}
@@ -3127,8 +3111,7 @@ gg_call(tree return_type, const char *function_name, ...)
{
if(nargs >= ARG_LIMIT)
{
- yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ );
- yywarn("###### You *must* be joking!");
+ yywarn("You *must* be joking");
gcc_unreachable();
}
@@ -3425,7 +3408,27 @@ gg_trans_unit_var_decl(const char *var_name)
}
void
-gg_insert_into_assembler(const char *format, ...)
+gg_insert_into_assembler(const char ach[])
+ {
+ if( !optimize )
+ {
+ // Create the required generic tag
+ tree asm_expr = build5_loc( location_from_lineno(),
+ ASM_EXPR,
+ VOID,
+ build_string(strlen(ach), ach),
+ NULL_TREE,
+ NULL_TREE,
+ NULL_TREE,
+ NULL_TREE);
+
+ // And insert it as a statement
+ gg_append_statement(asm_expr);
+ }
+ }
+
+void
+gg_insert_into_assemblerf(const char *format, ...)
{
// Temporarily defeat all ASM_EXPR for optimized code per PR119214
// The correct solution using LABEL_DECL is forthcoming
@@ -3444,18 +3447,6 @@ gg_insert_into_assembler(const char *format, ...)
vsnprintf(ach, sizeof(ach), format, ap);
va_end(ap);
- // Create the required generic tag
- tree asm_expr = build5_loc( location_from_lineno(),
- ASM_EXPR,
- VOID,
- build_string(strlen(ach), ach),
- NULL_TREE,
- NULL_TREE,
- NULL_TREE,
- NULL_TREE);
- //SET_EXPR_LOCATION (asm_expr, UNKNOWN_LOCATION);
-
- // And insert it as a statement
- gg_append_statement(asm_expr);
+ gg_insert_into_assembler(ach);
}
}
diff --git a/gcc/cobol/gengen.h b/gcc/cobol/gengen.h
index 8c1bc8d..15c2a6b 100644
--- a/gcc/cobol/gengen.h
+++ b/gcc/cobol/gengen.h
@@ -539,6 +539,9 @@ extern tree gg_trans_unit_var_decl(const char *var_name);
tree gg_open(tree char_star_A, tree int_B);
tree gg_close(tree int_A);
tree gg_get_indirect_reference(tree pointer, tree offset);
-void gg_insert_into_assembler(const char *format, ...);
+
+void gg_insert_into_assembler(const char ach[]);
+void gg_insert_into_assemblerf(const char *format, ...) ATTRIBUTE_PRINTF_1;
+
void gg_modify_function_type(tree function_decl, tree return_type);
#endif
diff --git a/gcc/cobol/genmath.cc b/gcc/cobol/genmath.cc
index bf3885b..0a1c12d 100644
--- a/gcc/cobol/genmath.cc
+++ b/gcc/cobol/genmath.cc
@@ -1383,12 +1383,12 @@ parser_op( struct cbl_refer_t cref,
break;
}
default:
- cbl_internal_error( "parser_op() doesn't know how to "
- "evaluate \"%s = %s %c %s\"\n",
- cref.field->name,
- aref.field->name,
- op,
- bref.field->name);
+ cbl_internal_error( "%<parser_op()%> doesn%'t know how to "
+ "evaluate %<%s = %s %c %s%>",
+ cref.field->name,
+ aref.field->name,
+ op,
+ bref.field->name);
break;
}
}
diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc
index 8ec7a78..1d921a3 100644
--- a/gcc/cobol/genutil.cc
+++ b/gcc/cobol/genutil.cc
@@ -737,7 +737,7 @@ get_binary_value( tree value,
{
if( SCALAR_FLOAT_TYPE_P(value) )
{
- cbl_internal_error("Can't get float value from %s", field->name);
+ cbl_internal_error("cannot get %<float%> value from %s", field->name);
}
else
{
diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc
index 888cce1..754a948 100644
--- a/gcc/cobol/lexio.cc
+++ b/gcc/cobol/lexio.cc
@@ -745,7 +745,7 @@ parse_replacing_pair( const char *stmt, const char *estmt ) {
}
}
if( pair.stmt.p ) {
- yywarn("CDF syntax error '%*s'", (int)pair.stmt.size(), pair.stmt.p);
+ yywarn("CDF syntax error '%.*s'", (int)pair.stmt.size(), pair.stmt.p);
}
else {
// This eliminated a compiler warning about "format-overflow"
@@ -1413,7 +1413,7 @@ preprocess_filter_add( const char input[] ) {
auto filename = find_filter(filter.c_str());
if( !filename ) {
- yywarn("preprocessor '%s/%s' not found", getcwd(NULL, 0), filter);
+ yywarn("preprocessor '%s/%s' not found", getcwd(NULL, 0), filter.c_str());
return false;
}
preprocessor_filters.push_back( std::make_pair(xstrdup(filename), options) );
@@ -1546,7 +1546,7 @@ int
cdftext::open_input( const char filename[] ) {
int fd = open(filename, O_RDONLY);
if( fd == -1 ) {
- dbgmsg( "could not open '%s': %m", filename );
+ dbgmsg( "could not open '%s': %s", filename, xstrerror(errno) );
}
verbose_file_reader = NULL != getenv("GCOBOL_TEMPDIR");
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index 3afa20f..99295e8 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -1482,7 +1482,7 @@ program_id: PROGRAM_ID dot namestr[name] program_as program_attrs[attr] dot
const char *name = string_of($name);
parser_enter_program( name, false, &main_error );
if( main_error ) {
- error_msg(@name, "PROGRAM-ID 'main' is invalid with -main option");
+ error_msg(@name, "PROGRAM-ID 'main' is invalid with %<-main%> option");
YYERROR;
}
@@ -1518,7 +1518,8 @@ function_id: FUNCTION '.' NAME program_as program_attrs[attr] '.'
int main_error = 0;
parser_enter_program( $NAME, true, &main_error );
if( main_error ) {
- error_msg(@NAME, "FUNCTION-ID 'main' is invalid with -main option");
+ error_msg(@NAME, "FUNCTION-ID %<main%> is invalid "
+ "with %<-main%> option");
YYERROR;
}
if( symbols_begin() == symbols_end() ) {
@@ -1589,7 +1590,7 @@ opt_binary: FLOAT_BINARY default_kw is HIGH_ORDER_LEFT
{
cbl_unimplementedw("HIGH-ORDER-LEFT was ignored");
if( ! current.option_binary(cbl_options_t::high_order_left_e) ) {
- error_msg(@3, "unable to set HIGH_ORDER_LEFT");
+ error_msg(@3, "unable to set %<HIGH_ORDER_LEFT%>");
}
}
| FLOAT_BINARY default_kw is HIGH_ORDER_RIGHT[opt]
@@ -2520,7 +2521,7 @@ dev_mnemonic: device_name is NAME
{
auto p = cmd_or_env_special_of($device);
if( !p ) {
- error_msg(@device, "%s is not a device name");
+ error_msg(@device, "%s is not a device name", $device);
YYERROR;
}
@@ -2646,7 +2647,7 @@ alphabet_seq: alphabet_lit[low]
alphabet_etc: alphabet_lit
{
if( $1.len > 1 ) {
- error_msg(@1, "'%c' can be only a single letter", $1.data);
+ error_msg(@1, "%qs can be only a single letter", $1.data);
YYERROR;
}
$$ = (unsigned char)$1.data[0];
@@ -2912,7 +2913,7 @@ fd_clause: record_desc
f->varying_size.explicitly = f->varies();
if( f->varying_size.max != 0 ) {
if( !(f->varying_size.min <= f->varying_size.max) ) {
- error_msg(@1, "%zu must be <= %zu",
+ error_msg(@1, "%zu must be less than or equal to %zu",
f->varying_size.min, f->varying_size.max);
YYERROR;
}
@@ -2988,7 +2989,7 @@ rec_contains: NUMSTR[min] {
}
$$.max = n;
if( !($$.min < $$.max) ) {
- error_msg(@max, "FROM (%xz) must be less than TO (%zu)",
+ error_msg(@max, "FROM (%zu) must be less than TO (%zu)",
$$.min, $$.max);
YYERROR;
}
@@ -3184,7 +3185,7 @@ field: cdf
}
initial = string_of(field.data.value_of());
if( !initial ) {
- error_msg(@1, xstrerror(errno));
+ error_msg(@1, "could not convert value to string");
YYERROR;
}
char decimal = symbol_decimal_point();
@@ -3638,7 +3639,7 @@ data_descr1: level_name
}
if( field_index($thru) <= field_index($orig) ) {
error_msg(@orig, "cannot RENAME %s %s THRU %s %s "
- "because they're in the wrong order",
+ "because they are in the wrong order",
$orig->level_str(), name_of($orig),
$thru->level_str(), name_of($thru));
YYERROR;
@@ -3680,7 +3681,7 @@ data_descr1: level_name
case FldNumericEdited:
if( $field->has_attr(signable_e) ) {
error_msg(@2, "%s has 'S' in PICTURE, cannot be BLANK WHEN ZERO",
- $field->name, cbl_field_type_str($field->type) );
+ $field->name );
}
break;
default:
@@ -3891,9 +3892,8 @@ data_clauses: data_clause
auto redefined = symbol_redefines(field);
if( redefined && redefined->type == FldPointer ) {
if( yydebug ) {
- yywarn("expanding %s size from %u bytes to "
- HOST_WIDE_INT_PRINT " "
- "because it redefines %s with USAGE POINTER",
+ yywarn("expanding %s size from %u bytes to %wd "
+ "because it redefines %s with %<USAGE POINTER%>",
field->name, field->size(),
int_size_in_bytes(ptr_type_node),
redefined->name);
@@ -3986,7 +3986,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft]
field->data.capacity = type_capacity(field->type, $4);
field->data.digits = $4;
if( long(field->data.digits) != $4 ) {
- error_msg(@2, "indicated size would be %ld bytes, "
+ error_msg(@2, "indicated size would be %d bytes, "
"maximum data item size is %u",
$4, UINT32_MAX);
}
@@ -4056,7 +4056,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft]
(dialect_gnu() || dialect_mf()) )
{ // PIC X COMP-X or COMP-9
if( ! field->has_attr(all_x_e) ) {
- error_msg(@2, "COMP PICTURE requires all X's or all 9's");
+ error_msg(@2, "COMP PICTURE requires all X%'s or all 9%'s");
YYERROR;
}
} else {
@@ -4091,7 +4091,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft]
}
ERROR_IF_CAPACITY(@PIC, field);
if( !is_numeric_edited($picture) ) {
- error_msg(@picture, numed_message);
+ error_msg(@picture, "%s", numed_message);
YYERROR;
}
field->data.picture = $picture;
@@ -4170,7 +4170,7 @@ alphanum_part: ALNUM[picture] count
$$.nbyte += count; // AX9(3) has count 5
}
if( count < 0 ) {
- error_msg(@2, "PICTURE count '(%d)' is negative", count );
+ error_msg(@2, "PICTURE count %<(%d)%> is negative", count );
YYERROR;
}
}
@@ -4189,7 +4189,7 @@ nine: %empty { $$ = 0; }
{
$$ = $1;
if( $$ == 0 ) {
- error_msg(@1, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)");
+ error_msg(@1, "%<(0)%> invalid in PICTURE (ISO 2023 13.18.40.3)");
}
}
;
@@ -4203,14 +4203,14 @@ count: %empty { $$ = 0; }
REAL_VALUE_TYPE rn = numstr2i($NUMSTR.string, $NUMSTR.radix);
$$ = real_to_integer (&rn);
if( $$ == 0 ) {
- error_msg(@2, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)");
+ error_msg(@2, "%<0%> invalid in PICTURE (ISO 2023 13.18.40.3)");
}
}
| '(' NAME ')'
{
auto value = cdf_value($NAME);
if( ! (value && value->is_numeric()) ) {
- error_msg(@NAME, "PICTURE '(%s)' requires a CONSTANT value", $NAME );
+ error_msg(@NAME, "PICTURE %qs requires a CONSTANT value", $NAME );
YYERROR;
}
int nmsg = 0;
@@ -4223,13 +4223,13 @@ count: %empty { $$ = 0; }
if( !real_identical (TREE_REAL_CST_PTR (field->data.value_of()),
&vi) ) {
nmsg++;
- error_msg(@NAME, "invalid PICTURE count '(%s)'",
+ error_msg(@NAME, "invalid PICTURE count %<(%s)%>",
field->data.initial );
}
}
$$ = value->as_number();
if( $$ <= 0 && !nmsg) {
- error_msg(@NAME, "invalid PICTURE count '(%s)'", $NAME );
+ error_msg(@NAME, "invalid PICTURE count %<(%s)%>", $NAME );
}
}
;
@@ -4974,12 +4974,11 @@ statements: statement { $$ = $1; }
statement: error {
if( current.declarative_section_name() ) {
- error_msg(@1, "missing END DECLARATIVES or SECTION name",
- nparse_error);
+ error_msg(@1, "missing END DECLARATIVES or SECTION name");
YYABORT;
}
if( max_errors_exceeded(nparse_error) ) {
- error_msg(@1, "max errors %d reached", nparse_error);
+ error_msg(@1, "max errors %zu reached", nparse_error);
YYABORT;
}
}
@@ -5692,7 +5691,8 @@ end_program: end_program1[end] '.'
gcc_unreachable();
}
if( !matches ) {
- error_msg(@end, "END %s %s' does not match IDENTIFICATION DIVISION '%s'",
+ error_msg(@end, "END %s %s does not match "
+ "%<IDENTIFICATION DIVISION %s%>",
token_name, name, prog->name);
YYERROR;
}
@@ -5723,9 +5723,9 @@ end_program: end_program1[end] '.'
token_name = "FUNCTION";
break;
default:
- cbl_internal_error( "END token invalid");
+ cbl_internal_error( "%<END%> token invalid");
}
- error_msg(@end, "END %s requires NAME before '.'", token_name);
+ error_msg(@end, "%<END%> %s requires %<NAME%> before %<.%>", token_name);
YYERROR;
}
;
@@ -6776,7 +6776,7 @@ move: MOVE scalar TO move_tgts[tgts]
{
statement_begin(@1, MOVE);
if( $scalar->field->type == FldIndex ) {
- error_msg(@1, "'%s' cannot be MOVEd because it's an INDEX",
+ error_msg(@1, "%qs cannot be MOVEd because it is an %<INDEX%>",
name_of($scalar->field) );
YYERROR;
}
@@ -7168,20 +7168,20 @@ section_kw: SECTION
{
if( $1 ) {
if( *$1 == '-' ) {
- error_msg(@1, "SECTION segment %<%s%> is negative", $1);
+ error_msg(@1, "SECTION segment %qs is negative", $1);
} else {
if( dialect_ibm() ) {
int sectno;
sscanf($1, "%d", &sectno);
if( ! (0 <= sectno && sectno <= 99) ) {
- error_msg(@1, "SECTION segment %<%s%> must be 0-99", $1);
+ error_msg(@1, "SECTION segment %qs must be 0-99", $1);
} else {
if(false) { // stand-in for warning, someday.
- yywarn("SECTION segment %<%s%> was ignored", $1);
+ yywarn("SECTION segment %qs was ignored", $1);
}
}
} else {
- cbl_unimplemented("SECTION segment %<%s%> is not ISO syntax", $1);
+ cbl_unimplemented("SECTION segment %qs is not ISO syntax", $1);
}
}
}
@@ -7932,7 +7932,7 @@ raise: RAISE EXCEPTION NAME
"EXCEPTION CONDITION: %s", $NAME);
YYERROR;
}
- cbl_unimplemented("RAISE <EXCEPTION OBJECT>");
+ cbl_unimplemented("RAISE %<EXCEPTION OBJECT%>");
YYERROR;
}
;
@@ -8009,7 +8009,7 @@ read_body: NAME read_next read_into read_key
YYERROR;
}
if( $read_key->field && $read_next < 0 ) {
- error_msg(@1, "cannot read NEXT with KEY", $$->name);
+ error_msg(@1, "cannot read NEXT with KEY %qs", $$->name);
YYERROR;
}
@@ -8803,7 +8803,7 @@ search_term: scalar[key] '=' search_expr[sarg]
}
if( dimensions($key->field) < $key->nsubscript() ) {
error_msg(@1, "too many subscripts: "
- "%zu for table of %zu dimensions",
+ "%u for table of %zu dimensions",
$key->nsubscript(), dimensions($key->field) );
YYERROR;
}
@@ -9137,7 +9137,7 @@ inspect: INSPECT backward inspected TALLYING tallies
if( is_literal(match) && is_literal(replace) ) {
if( !$match->all && !$replace_oper->all) {
if( match->data.capacity != replace->data.capacity ) {
- error_msg(@match, "'%s', size %u NOT EQUAL '%s', size %u",
+ error_msg(@match, "%qs, size %u NOT EQUAL %qs, size %u",
nice_name_of(match), match->data.capacity,
nice_name_of(replace), replace->data.capacity);
YYERROR;
@@ -10212,8 +10212,8 @@ intrinsic: function_udf
args.data());
if( p != NULL ) {
auto loc = symbol_field_location(field_index(p->field));
- error_msg(loc, "FUNCTION %s has "
- "inconsistent parameter type %zu ('%s')",
+ error_msg(loc, "FUNCTION %qs has "
+ "inconsistent parameter type %zu (%qs)",
keyword_str($1), p - args.data(), name_of(p->field) );
YYERROR;
}
@@ -10290,7 +10290,7 @@ intrinsic: function_udf
location_set(@1);
$$ = new_alphanumeric("FIND-STRING");
/* auto r1 = new_reference(new_literal(strlen($r1), $r1, quoted_e)); */
- cbl_unimplemented("FIND_STRING");
+ cbl_unimplemented("%<FIND_STRING%>");
/* if( ! intrinsic_call_4($$, FIND_STRING, r1, $r2) ) YYERROR; */
}
@@ -10757,7 +10757,7 @@ numval_locale: %empty {
$$.arg2 = cbl_refer_t::empty();
}
| LOCALE NAME { $$.is_locale = true; $$.arg2 = NULL;
- cbl_unimplemented("NUMVAL_C LOCALE"); YYERROR;
+ cbl_unimplemented("%<NUMVAL_C LOCALE%>"); YYERROR;
}
| varg { $$.is_locale = false; $$.arg2 = $1; }
;
@@ -11541,7 +11541,7 @@ relop_invert(relop_t op) {
case ge_op: return lt_op;
case gt_op: return le_op;
}
- cbl_errx( "%s:%d: invalid relop_t %d", __func__, __LINE__, op);
+ cbl_internal_error("%s:%d: invalid %<relop_t%> %d", __func__, __LINE__, op);
return relop_t(0); // not reached
}
@@ -11834,7 +11834,7 @@ current_t::udf_args_valid( const cbl_label_t *L,
auto tgt = cbl_field_of(symbol_at(udf.linkage_fields.at(i).isym));
if( ! valid_move(tgt, arg.field) ) {
auto loc = symbol_field_location(field_index(arg.field));
- error_msg(loc, "FUNCTION %s arg %zu, '%s' cannot be passed to %s, type %s",
+ error_msg(loc, "FUNCTION %s argument %zu, '%s' cannot be passed to %s, type %s",
L->name, i, arg.field->pretty_name(),
tgt->pretty_name(), 3 + cbl_field_type_str(tgt->type) );
return false;
@@ -12032,7 +12032,7 @@ struct stringify_src_t : public cbl_string_src_t {
protected:
static void dump_input( const cbl_refer_t& refer ) {
- yywarn( "%s:\t%s", __func__, field_str(refer.field) );
+ yywarn( "%s: %s", __func__, field_str(refer.field) );
}
};
@@ -12341,7 +12341,7 @@ numstr2i( const char input[], radix_t radix ) {
case boolean_e:
for( const char *p = input; *p != '\0'; p++ ) {
if( ssize_t(8 * sizeof(integer) - 1) < p - input ) {
- yywarn("'%s' was accepted as %d", input, integer);
+ yywarn("'%s' was accepted as %zu", input, integer);
break;
}
switch(*p) {
@@ -12351,7 +12351,7 @@ numstr2i( const char input[], radix_t radix ) {
integer |= ((*p) == '0' ? 0 : 1);
break;
default:
- yywarn("'%s' was accepted as %d", input, integer);
+ yywarn("'%s' was accepted as %zu", input, integer);
break;
}
}
@@ -12359,7 +12359,7 @@ numstr2i( const char input[], radix_t radix ) {
return output;
}
if( erc == -1 ) {
- yywarn("'%s' was accepted as %lld", input, output);
+ yywarn("'%s' was accepted as %wd", input, integer);
}
return output;
}
@@ -12982,7 +12982,7 @@ literal_attr( const char prefix[] ) {
}
// must be [BN]X
- cbl_internal_error("'%s': invalid literal prefix", prefix);
+ cbl_internal_error("invalid literal prefix: %qs", prefix);
gcc_unreachable();
return none_e;
}
diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h
index ffb4c98..8194614 100644
--- a/gcc/cobol/parse_ante.h
+++ b/gcc/cobol/parse_ante.h
@@ -335,7 +335,7 @@ struct evaluate_elem_t {
label.line = yylineno;
if( -1 == snprintf(label.name, sizeof(label.name),
"%.*s_%d", (int)sizeof(label.name)-6, skel, yylineno) ) {
- yyerror("could not create unique label '%s_%d' because it is too long",
+ yyerror("could not create unique label %<%s_%d%> because it is too long",
skel, yylineno);
}
}
@@ -2116,7 +2116,7 @@ static class current_t {
if( ! dialect_ibm() ) {
error_msg(loc,
"Per ISO a program with DECLARATIVES must begin with a SECTION, "
- "requires -dialect ibm");
+ "requires %<-dialect ibm%>");
}
}
}
@@ -2558,7 +2558,8 @@ is_callable( const cbl_field_t *field ) {
case FldPointer:
return true;
}
- cbl_internal_error( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, field->type );
+ cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d",
+ __func__, __LINE__, field->type );
return false;
}
diff --git a/gcc/cobol/parse_util.h b/gcc/cobol/parse_util.h
index 11b86a3..006cea7 100644
--- a/gcc/cobol/parse_util.h
+++ b/gcc/cobol/parse_util.h
@@ -348,7 +348,7 @@ intrinsic_invalid_parameter( int token,
return token == descr.token;
} );
if( p == function_descrs_end ) {
- cbl_internal_error( "%s: intrinsic function %s not found",
+ cbl_internal_error( "%s: intrinsic function %qs not found",
__func__, keyword_str(token) );
}
diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l
index 52a0b94..9b586e9 100644
--- a/gcc/cobol/scan.l
+++ b/gcc/cobol/scan.l
@@ -982,7 +982,7 @@ USE({SPC}FOR)? { return USE; }
BINARY-LONG { return bcomputable(FldNumericBin5, 4); }
BINARY-DOUBLE { return bcomputable(FldNumericBin5, 8); }
BINARY-LONG-LONG { if( ! dialect_mf() ) {
- error_msg(yylloc, "%s requires -dialect mf", yytext);
+ dialect_error(yylloc, yytext, "mf");
}
return bcomputable(FldNumericBin5, 8);
}
@@ -993,7 +993,7 @@ USE({SPC}FOR)? { return USE; }
FLOAT-BINARY-32 { return ucomputable(FldFloat, 4); }
FLOAT-BINARY-64 { return ucomputable(FldFloat, 8); }
FLOAT-BINARY-128 { return ucomputable(FldFloat, 16); }
- FLOAT-DECIMAL-(16|34) { not_implemented("USAGE type: FLOAT_DECIMAL");
+ FLOAT-DECIMAL-(16|34) { not_implemented("USAGE type: %<FLOAT_DECIMAL%>");
return FLOAT_DECIMAL; // causes syntax error
}
/* 21) The representation and length of a data item described with USAGE
@@ -1019,7 +1019,7 @@ USE({SPC}FOR)? { return USE; }
POINTER { yylval.field_attr = none_e; return POINTER; }
PROCEDURE-POINTER { if( dialect_gcc() ) {
- error_msg(yylloc, "%s requires -dialect ibm or mf", yytext);
+ dialect_error(yylloc, yytext, "ibm or mf");
}
yylval.field_attr = prog_ptr_e;
return POINTER; // return it anyway
@@ -2482,10 +2482,9 @@ BASIS { yy_push_state(basis); return BASIS; }
<<EOF>> {
if( YY_START == quoted1 || YY_START == quoted2 ) {
- error_msg(yylloc, "syntax error: unterminated string '%s'",
+ error_msg(yylloc, "syntax error: unterminated string %<%s%>",
tmpstring);
return NO_CONDITION;
- cbl_internal_error("");
}
yypop_buffer_state();
diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index 21e89e4..037c929 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -159,11 +159,11 @@ numstr_of( const char string[], radix_t radix = decimal_e ) {
// exponent is implementor-defined." (We allow 9999.)
nx = std::count_if(p, eoinput, fisdigit);
if( 4 < nx ) {
- error_msg(yylloc, "exponent %s more than 4 digits", ++p);
+ error_msg(yylloc, "exponent %qs more than 4 digits", ++p);
return NO_CONDITION;
}
if( eoinput != std::find(p, eoinput, symbol_decimal_point()) ) {
- error_msg(yylloc, "exponent includes decimal point", ++p);
+ error_msg(yylloc, "exponent %qs includes decimal point", ++p);
return NO_CONDITION;
}
@@ -187,7 +187,7 @@ numstr_of( const char string[], radix_t radix = decimal_e ) {
}
}
if( 1 < std::count(input, eoinput, symbol_decimal_point()) ) {
- error_msg(yylloc, "invalid numeric literal", ++p);
+ error_msg(yylloc, "invalid numeric literal %qs", ++p);
return NO_CONDITION;
}
@@ -295,7 +295,7 @@ static class parsing_status_t : public std::stack<cdf_status_t> {
void splat() const {
int i=0;
for( const auto& status : c ) {
- yywarn( "%4d\t%s", ++i, status.str() );
+ yywarn( "%d %s", ++i, status.str() );
}
}
} parsing;
@@ -305,7 +305,7 @@ void field_done() { orig_picture[0] = '\0'; parsing.need_level(true); }
static int scanner_token() {
if( parsing.empty() ) {
- error_msg(yylloc, ">>ELSE or >>END-IF without >>IF");
+ error_msg(yylloc, "%<>>ELSE%> or %<>>END-IF%> without %<>>IF%>");
return NO_CONDITION;
}
return parsing.top().token;
@@ -317,33 +317,32 @@ bool scanner_normal() { return parsing.normal(); }
void scanner_parsing( int token, bool tf ) {
parsing.push( cdf_status_t(token, tf) );
if( yydebug ) {
- yywarn("%10s: parsing now %5s, depth %lu",
- keyword_str(token), boolalpha(parsing.on()),
- gb4(parsing.size()));
+ yywarn("%s: parsing now %s, depth %zu",
+ keyword_str(token), boolalpha(parsing.on()), parsing.size());
parsing.splat();
}
}
void scanner_parsing_toggle() {
if( parsing.empty() ) {
- error_msg(yylloc, ">>ELSE without >>IF");
+ error_msg(yylloc, "%<>>ELSE%> without %<>>IF%>");
return;
}
parsing.top().toggle();
if( yydebug ) {
- yywarn("%10s: parsing now %5s",
+ yywarn("%s: parsing now %s",
keyword_str(CDF_ELSE), boolalpha(parsing.on()));
}
}
void scanner_parsing_pop() {
if( parsing.empty() ) {
- error_msg(yylloc, ">>END-IF without >>IF");
+ error_msg(yylloc, "%<>>END-IF%> without %<>>IF%>");
return;
}
parsing.pop();
if( yydebug ) {
- yywarn("%10s: parsing now %5s, depth %lu",
+ yywarn("%s: parsing now %s, depth %zu",
keyword_str(CDF_END_IF), boolalpha(parsing.on()),
- gb4(parsing.size()));
+ parsing.size());
parsing.splat();
}
}
@@ -792,7 +791,7 @@ typed_name( const char name[] ) {
return cbl_field_of(e)->level == 88? NAME88 : CLASS_NAME;
break;
default:
- yywarn("%s:%d: invalid symbol type %s for symbol \"%s\"",
+ yywarn("%s:%d: invalid symbol type %s for symbol %qs",
__func__, __LINE__, cbl_field_type_str(type), name);
return NAME;
}
diff --git a/gcc/cobol/scan_post.h b/gcc/cobol/scan_post.h
index 385ea67..a273da9 100644
--- a/gcc/cobol/scan_post.h
+++ b/gcc/cobol/scan_post.h
@@ -297,7 +297,7 @@ prelex() {
token = LEVEL;
break;
case YDF_NUMBER:
- if( yy_flex_debug ) yywarn("final token is YDF_NUMBER");
+ if( yy_flex_debug ) yywarn("final token is %<YDF_NUMBER%>");
yylval.number = ydflval.number;
token = LEVEL;
break;
diff --git a/gcc/cobol/show_parse.h b/gcc/cobol/show_parse.h
index d417af3..db24807 100644
--- a/gcc/cobol/show_parse.h
+++ b/gcc/cobol/show_parse.h
@@ -424,30 +424,31 @@ extern bool cursor_at_sol;
// Use CHECK_FIELD when a should be non-null, and a->var_decl_node also should
// by non-null:
-#define CHECK_FIELD(a) \
- do{ \
- if(!a) \
- { \
- yywarn("%s(): parameter " #a " is NULL", __func__); \
- gcc_unreachable(); \
- } \
- if( !a->var_decl_node && a->type != FldConditional && a->type != FldLiteralA) \
- { \
- yywarn("%s() parameter " #a " is variable %s<%s> with NULL var_decl_node", \
- __func__, \
- a->name, \
- cbl_field_type_str(a->type) ); \
- gcc_unreachable(); \
- } \
- }while(0);
-
-#define CHECK_LABEL(a) \
- do{ \
- if(!a) \
- { \
- yywarn("%s(): parameter " #a " is NULL", __func__); \
- gcc_unreachable(); \
- } \
+#define CHECK_FIELD(a) \
+ do { \
+ if(!a) \
+ { \
+ yywarn("%s: parameter %<" #a "%> is NULL", __func__); \
+ gcc_unreachable(); \
+ } \
+ if( !a->var_decl_node && a->type != FldConditional && a->type != FldLiteralA) \
+ { \
+ yywarn("%s: parameter %<" #a "%> is variable " \
+ "%s<%s> with NULL %<var_decl_node%>", \
+ __func__, \
+ a->name, \
+ cbl_field_type_str(a->type) ); \
+ gcc_unreachable(); \
+ } \
+ } while(0);
+
+#define CHECK_LABEL(a) \
+ do{ \
+ if(!a) \
+ { \
+ yywarn("%s: parameter %<" #a "%> is NULL", __func__); \
+ gcc_unreachable(); \
+ } \
}while(0);
#ifdef INCORPORATE_ANALYZER
diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
index d75ca29..089c9c1 100644
--- a/gcc/cobol/symbols.cc
+++ b/gcc/cobol/symbols.cc
@@ -2836,7 +2836,7 @@ seek_parent( const symbol_elem_t *e, size_t level ) {
struct symbol_elem_t *
symbol_field_same_as( cbl_field_t *tgt, const cbl_field_t *src ) {
if( target_in_src(tgt, src) ) {
- ERROR_FIELD(tgt, "%s %s may not reference itself as part of %s %s",
+ ERROR_FIELD(tgt, "%s %s may not reference itself as part of %s %s",
tgt->level_str(), tgt->name, src->level_str(), src->name);
return NULL;
}
@@ -3088,7 +3088,7 @@ cbl_alphabet_t::assign( const YYLTYPE& loc, unsigned char ch, unsigned char high
return true;
}
auto taken = alphabet[ch];
- error_msg(loc, "ALPHABET %s, character '%c' (X'%x') "
+ error_msg(loc, "ALPHABET %s, character %<%c%> (X%'%x%') "
"in position %d already defined at position %d",
name,
ISPRINT(ch)? ch : '?', ch,
@@ -3493,7 +3493,7 @@ cbl_field_t::internalize() {
static const size_t noconv = size_t(-1);
if (cd == (iconv_t)-1) {
- yywarn("failed iconv_open tocode = '%s' fromcode = %s", tocode, fromcode);
+ yywarn("failed %<iconv_open%> tocode = %<%s%> fromcode = %s", tocode, fromcode);
}
bool using_assumed = fromcode == os_locale.assumed;
diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
index 84a984e..c09fbcc 100644
--- a/gcc/cobol/symbols.h
+++ b/gcc/cobol/symbols.h
@@ -131,13 +131,13 @@ is_numeric( cbl_field_type_t type ) {
case FldIndex:
return true;
}
- yywarn( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type );
+ cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type );
return false;
}
struct os_locale_t {
char assumed[16];
- char *codeset;
+ const char *codeset;
};
const char * cbl_field_attr_str( cbl_field_attr_t attr );
@@ -1216,6 +1216,8 @@ class temporaries_t {
literal_an() : is_quoted(false), value("???") {}
literal_an( const char value[], bool is_quoted )
: is_quoted(is_quoted), value(value) {}
+ literal_an( const literal_an& that )
+ : is_quoted(that.is_quoted), value(that.value) {}
literal_an& operator=( const literal_an& that ) {
is_quoted = that.is_quoted;
value = that.value;
@@ -1495,7 +1497,7 @@ struct cbl_alphabet_t {
}
void dump() const {
- yywarn("'%s': %s, '%c' to '%c' (low 0x%02x, high 0x%02x)",
+ yywarn("%qs: %s, %<%c%> to %<%c%> (low 0x%x, high 0x%x)",
name, encoding_str(encoding),
low_index, last_index, low_index, high_index);
if( encoding == custom_encoding_e ) {
diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc
index b6c9280..d8423e0 100644
--- a/gcc/cobol/util.cc
+++ b/gcc/cobol/util.cc
@@ -130,7 +130,7 @@ symbol_type_str( enum symbol_type_t type )
case SymDataSection:
return "SymDataSection";
}
- dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type);
+ cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type);
return "???";
}
@@ -179,7 +179,7 @@ cbl_field_type_str( enum cbl_field_type_t type )
case FldBlob:
return "FldBlob";
}
- dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type);
+ cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type);
return "???";
}
@@ -479,7 +479,7 @@ is_elementary( enum cbl_field_type_t type )
case FldFloat:
return true; // takes up space
}
- dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type);
+ cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type);
return false;
}
@@ -902,8 +902,8 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const {
return TOUPPER(ch) == 'E';
} );
if( !has_exponent && data.precision() < pend - p ) {
- error_msg(loc, "%s cannot represent VALUE '%s' exactly (max .%zu)",
- name, data.initial, pend - p);
+ error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%zu)",
+ name, data.initial, '.', pend - p);
}
}
}
@@ -1805,7 +1805,7 @@ class unique_stack : public std::stack<input_file_t>
(fmt_size_t)(c.size() - --n), v.lineno, no_wd(wd, v.name) );
}
} else {
- dbgmsg("unable to get current working directory: %m");
+ dbgmsg("unable to get current working directory: %s", xstrerror(errno));
}
free(wd);
}
@@ -1953,6 +1953,8 @@ verify_format( const char gmsgid[] ) {
static const diagnostic_option_id option_zero;
size_t parse_error_inc();
+void ydferror( const char gmsgid[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2);
+
void
ydferror( const char gmsgid[], ... ) {
verify_format(gmsgid);
@@ -2029,6 +2031,9 @@ void error_msg( const YYLTYPE& loc, const char gmsgid[], ... ) {
ERROR_MSG_BODY
}
+void error_msg( const YDFLTYPE& loc, const char gmsgid[], ... )
+ ATTRIBUTE_GCOBOL_DIAG(2, 3);
+
void error_msg( const YDFLTYPE& loc, const char gmsgid[], ... ) {
ERROR_MSG_BODY
}
@@ -2119,7 +2124,7 @@ cobol_fileline_set( const char line[] ) {
dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg );
return line;
}
- error_msg(yylloc, "invalid #line directive: %s", line );
+ error_msg(yylloc, "invalid %<#line%> directive: %s", line );
return line;
}
@@ -2129,7 +2134,7 @@ cobol_fileline_set( const char line[] ) {
int fileline;
if( 1 != sscanf(line_str, "%d", &fileline) )
- yywarn("could not parse line number %s from #line directive", line_str);
+ yywarn("could not parse line number %s from %<#line%> directive", line_str);
input_file_t input_file( filename, ino_t(0), fileline ); // constructor sets inode
@@ -2216,19 +2221,9 @@ cobol_set_debugging( bool flex, bool yacc, bool parser )
yy_flex_debug = flex? 1 : 0;
ydfdebug = yydebug = yacc? 1 : 0;
f_trace_debug = parser? 1 : 0;
-
- char *ind = getenv("INDICATOR_COLUMN");
- if( ind ) {
- int col;
- if( 1 != sscanf(ind, "%d", &col) ) {
- yywarn("ignored non-integer value for INDICATOR_COLUMN=%s", ind);
- }
- cobol_set_indicator_column(col);
- }
}
-os_locale_t os_locale = { "UTF-8", xstrdup("C.UTF-8") };
-
+os_locale_t os_locale = { "UTF-8", "C.UTF-8" };
void
cobol_parse_files (int nfile, const char **files)
@@ -2239,7 +2234,7 @@ cobol_parse_files (int nfile, const char **files)
} else {
char *codeset = nl_langinfo(CODESET);
if( ! codeset ) {
- yywarn("nl_langinfo failed after setlocale succeeded");
+ yywarn("%<nl_langinfo%> failed after %<setlocale()%> succeeded");
} else {
os_locale.codeset = codeset;
}
@@ -2351,7 +2346,7 @@ dbgmsg(const char *msg, ...) {
void
dialect_error( const YYLTYPE& loc, const char term[], const char dialect[] ) {
- error_msg(loc, "%s is not ISO syntax, requires -dialect %s",
+ error_msg(loc, "%s is not ISO syntax, requires %<-dialect %s%>",
term, dialect);
}
diff --git a/gcc/cobol/util.h b/gcc/cobol/util.h
index 54d3930..9388b50 100644
--- a/gcc/cobol/util.h
+++ b/gcc/cobol/util.h
@@ -31,11 +31,13 @@
#ifndef _UTIL_H_
#define _UTIL_H_
-void cbl_message(int fd, const char *format_string, ...);
-void cbl_internal_error(const char *format_string, ...);
+void cbl_message(int fd, const char *format_string, ...)
+ ATTRIBUTE_PRINTF_2;
+void cbl_internal_error(const char *format_string, ...)
+ ATTRIBUTE_GCOBOL_DIAG(1, 2);
-void cbl_err(const char *format_string, ...);
-void cbl_errx(const char *format_string, ...);
+void cbl_err(const char *format_string, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2);
+void cbl_errx(const char *format_string, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2);
bool fisdigit(int c);
bool fisspace(int c);
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 40088db..31f2f5b 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1039,6 +1039,7 @@ bool aarch64_maybe_expand_sve_subreg_move (rtx, rtx);
rtx aarch64_replace_reg_mode (rtx, machine_mode);
void aarch64_split_sve_subreg_move (rtx, rtx, rtx);
void aarch64_expand_prologue (void);
+void aarch64_decompose_vec_struct_index (machine_mode, rtx *, rtx *, bool);
void aarch64_expand_vector_init (rtx, rtx);
void aarch64_sve_expand_vector_init_subvector (rtx, rtx);
void aarch64_sve_expand_vector_init (rtx, rtx);
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 6e30dc4..e771def 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1628,6 +1628,24 @@
}
)
+(define_expand "vec_set<mode>"
+ [(match_operand:VSTRUCT_QD 0 "register_operand")
+ (match_operand:<VEL> 1 "aarch64_simd_nonimmediate_operand")
+ (match_operand:SI 2 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ aarch64_decompose_vec_struct_index (<VSTRUCT_ELT>mode, &operands[0],
+ &operands[2], true);
+ /* For tuples of 64-bit modes, <vstruct_elt> is the 64-bit scalar mode.
+ Allow gen_vec_set<vstruct_elt> to cope with those cases too. */
+ auto gen_vec_setdi ATTRIBUTE_UNUSED = [](rtx x0, rtx x1, rtx)
+ {
+ return gen_move_insn (x0, x1);
+ };
+ auto gen_vec_setdf ATTRIBUTE_UNUSED = gen_vec_setdi;
+ emit_insn (gen_vec_set<vstruct_elt> (operands[0], operands[1], operands[2]));
+ DONE;
+})
(define_insn "aarch64_mla<mode><vczle><vczbe>"
[(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
@@ -8883,6 +8901,26 @@
DONE;
})
+(define_expand "vec_extract<mode><Vel>"
+ [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand")
+ (match_operand:VSTRUCT_QD 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ aarch64_decompose_vec_struct_index (<VSTRUCT_ELT>mode, &operands[1],
+ &operands[2], false);
+ /* For tuples of 64-bit modes, <vstruct_elt> is the 64-bit scalar mode.
+ Allow gen_vec_extract<vstruct_elt><Vel> to cope with those cases too. */
+ auto gen_vec_extractdidi ATTRIBUTE_UNUSED = [](rtx x0, rtx x1, rtx)
+ {
+ return gen_move_insn (x0, x1);
+ };
+ auto gen_vec_extractdfdf ATTRIBUTE_UNUSED = gen_vec_extractdidi;
+ emit_insn (gen_vec_extract<vstruct_elt><Vel> (operands[0], operands[1],
+ operands[2]));
+ DONE;
+})
+
;; Extract a 64-bit vector from one half of a 128-bit vector.
(define_expand "vec_extract<mode><Vhalf>"
[(match_operand:<VHALF> 0 "register_operand")
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 5540946..af8415c 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -24721,6 +24721,28 @@ seq_cost_ignoring_scalar_moves (const rtx_insn *seq, bool speed)
return cost;
}
+/* *VECTOR is an Advanced SIMD structure mode and *INDEX is a constant index
+ into it. Narrow *VECTOR and *INDEX so that they reference a single vector
+ of mode SUBVEC_MODE. IS_DEST is true if *VECTOR is a destination operand,
+ false if it is a source operand. */
+
+void
+aarch64_decompose_vec_struct_index (machine_mode subvec_mode,
+ rtx *vector, rtx *index, bool is_dest)
+{
+ auto elts_per_vector = GET_MODE_NUNITS (subvec_mode).to_constant ();
+ auto subvec = UINTVAL (*index) / elts_per_vector;
+ auto subelt = UINTVAL (*index) % elts_per_vector;
+ auto subvec_byte = subvec * GET_MODE_SIZE (subvec_mode);
+ if (is_dest)
+ *vector = simplify_gen_subreg (subvec_mode, *vector, GET_MODE (*vector),
+ subvec_byte);
+ else
+ *vector = force_subreg (subvec_mode, *vector, GET_MODE (*vector),
+ subvec_byte);
+ *index = gen_int_mode (subelt, SImode);
+}
+
/* Expand a vector initialization sequence, such that TARGET is
initialized to contain VALS. */
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 2700392..a8957681 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1705,6 +1705,30 @@
(SI "SI") (HI "HI")
(QI "QI")
(V4BF "BF") (V8BF "BF")
+ (V2x8QI "QI") (V2x4HI "HI")
+ (V2x2SI "SI") (V2x1DI "DI")
+ (V2x4HF "HF") (V2x2SF "SF")
+ (V2x1DF "DF") (V2x4BF "BF")
+ (V3x8QI "QI") (V3x4HI "HI")
+ (V3x2SI "SI") (V3x1DI "DI")
+ (V3x4HF "HF") (V3x2SF "SF")
+ (V3x1DF "DF") (V3x4BF "BF")
+ (V4x8QI "QI") (V4x4HI "HI")
+ (V4x2SI "SI") (V4x1DI "DI")
+ (V4x4HF "HF") (V4x2SF "SF")
+ (V4x1DF "DF") (V4x4BF "BF")
+ (V2x16QI "QI") (V2x8HI "HI")
+ (V2x4SI "SI") (V2x2DI "DI")
+ (V2x8HF "HF") (V2x4SF "SF")
+ (V2x2DF "DF") (V2x8BF "BF")
+ (V3x16QI "QI") (V3x8HI "HI")
+ (V3x4SI "SI") (V3x2DI "DI")
+ (V3x8HF "HF") (V3x4SF "SF")
+ (V3x2DF "DF") (V3x8BF "BF")
+ (V4x16QI "QI") (V4x8HI "HI")
+ (V4x4SI "SI") (V4x2DI "DI")
+ (V4x8HF "HF") (V4x4SF "SF")
+ (V4x2DF "DF") (V4x8BF "BF")
(VNx16QI "QI") (VNx8QI "QI") (VNx4QI "QI") (VNx2QI "QI")
(VNx8HI "HI") (VNx4HI "HI") (VNx2HI "HI")
(VNx8HF "HF") (VNx4HF "HF") (VNx2HF "HF")
@@ -1726,6 +1750,30 @@
(DF "df") (SI "si")
(HI "hi") (QI "qi")
(V4BF "bf") (V8BF "bf")
+ (V2x8QI "qi") (V2x4HI "hi")
+ (V2x2SI "si") (V2x1DI "di")
+ (V2x4HF "hf") (V2x2SF "sf")
+ (V2x1DF "df") (V2x4BF "bf")
+ (V3x8QI "qi") (V3x4HI "hi")
+ (V3x2SI "si") (V3x1DI "di")
+ (V3x4HF "hf") (V3x2SF "sf")
+ (V3x1DF "df") (V3x4BF "bf")
+ (V4x8QI "qi") (V4x4HI "hi")
+ (V4x2SI "si") (V4x1DI "di")
+ (V4x4HF "hf") (V4x2SF "sf")
+ (V4x1DF "df") (V4x4BF "bf")
+ (V2x16QI "qi") (V2x8HI "hi")
+ (V2x4SI "si") (V2x2DI "di")
+ (V2x8HF "hf") (V2x4SF "sf")
+ (V2x2DF "df") (V2x8BF "bf")
+ (V3x16QI "qi") (V3x8HI "hi")
+ (V3x4SI "si") (V3x2DI "di")
+ (V3x8HF "hf") (V3x4SF "sf")
+ (V3x2DF "df") (V3x8BF "bf")
+ (V4x16QI "qi") (V4x8HI "hi")
+ (V4x4SI "si") (V4x2DI "di")
+ (V4x8HF "hf") (V4x4SF "sf")
+ (V4x2DF "df") (V4x8BF "bf")
(VNx16QI "qi") (VNx8QI "qi") (VNx4QI "qi") (VNx2QI "qi")
(VNx8HI "hi") (VNx4HI "hi") (VNx2HI "hi")
(VNx8HF "hf") (VNx4HF "hf") (VNx2HF "hf")
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 4946f87..423fc63 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -9351,7 +9351,6 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
bool need_zero_guard = false;
bool noalign;
machine_mode move_mode = VOIDmode;
- machine_mode wider_mode;
int unroll_factor = 1;
/* TODO: Once value ranges are available, fill in proper data. */
unsigned HOST_WIDE_INT min_size = 0;
@@ -9427,6 +9426,7 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
unroll_factor = 1;
move_mode = word_mode;
+ int nunits;
switch (alg)
{
case libcall:
@@ -9447,27 +9447,14 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
case vector_loop:
need_zero_guard = true;
unroll_factor = 4;
- /* Find the widest supported mode. */
- move_mode = word_mode;
- while (GET_MODE_WIDER_MODE (move_mode).exists (&wider_mode)
- && optab_handler (mov_optab, wider_mode) != CODE_FOR_nothing)
- move_mode = wider_mode;
-
- if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (move_mode) > 128)
- move_mode = TImode;
- if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (move_mode) > 256)
- move_mode = OImode;
-
- /* Find the corresponding vector mode with the same size as MOVE_MODE.
- MOVE_MODE is an integer mode at the moment (SI, DI, TI, etc.). */
- if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode))
- {
- int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode);
- if (!mode_for_vector (word_mode, nunits).exists (&move_mode)
- || optab_handler (mov_optab, move_mode) == CODE_FOR_nothing)
- move_mode = word_mode;
- }
- gcc_assert (optab_handler (mov_optab, move_mode) != CODE_FOR_nothing);
+ /* Get the vector mode to move MOVE_MAX bytes. */
+ nunits = MOVE_MAX / GET_MODE_SIZE (word_mode);
+ if (nunits > 1)
+ {
+ move_mode = mode_for_vector (word_mode, nunits).require ();
+ gcc_assert (optab_handler (mov_optab, move_mode)
+ != CODE_FOR_nothing);
+ }
break;
case rep_prefix_8_byte:
move_mode = DImode;
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 10863ab..86194b3 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -437,6 +437,13 @@ extern rtl_opt_pass *make_pass_align_tight_loops (gcc::context *);
extern bool ix86_has_no_direct_extern_access;
extern bool ix86_rpad_gate ();
+extern sbitmap ix86_get_separate_components (void);
+extern sbitmap ix86_components_for_bb (basic_block);
+extern void ix86_disqualify_components (sbitmap, edge, sbitmap, bool);
+extern void ix86_emit_prologue_components (sbitmap);
+extern void ix86_emit_epilogue_components (sbitmap);
+extern void ix86_set_handled_components (sbitmap);
+
/* In i386-expand.cc. */
bool ix86_check_builtin_isa_match (unsigned int, HOST_WIDE_INT*,
HOST_WIDE_INT*);
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 20ee360..7785329 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -6905,6 +6905,26 @@ ix86_pro_and_epilogue_can_use_push2pop2 (int nregs)
&& (nregs + aligned) >= 3;
}
+/* Check if push/pop should be used to save/restore registers. */
+static bool
+save_regs_using_push_pop (HOST_WIDE_INT to_allocate)
+{
+ return ((!to_allocate && cfun->machine->frame.nregs <= 1)
+ || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
+ /* If static stack checking is enabled and done with probes,
+ the registers need to be saved before allocating the frame. */
+ || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
+ /* If stack clash probing needs a loop, then it needs a
+ scratch register. But the returned register is only guaranteed
+ to be safe to use after register saves are complete. So if
+ stack clash protections are enabled and the allocated frame is
+ larger than the probe interval, then use pushes to save
+ callee saved registers. */
+ || (flag_stack_clash_protection
+ && !ix86_target_stack_probe ()
+ && to_allocate > get_probe_interval ()));
+}
+
/* Fill structure ix86_frame about frame of currently computed function. */
static void
@@ -7189,20 +7209,7 @@ ix86_compute_frame_layout (void)
/* Size prologue needs to allocate. */
to_allocate = offset - frame->sse_reg_save_offset;
- if ((!to_allocate && frame->nregs <= 1)
- || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
- /* If static stack checking is enabled and done with probes,
- the registers need to be saved before allocating the frame. */
- || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
- /* If stack clash probing needs a loop, then it needs a
- scratch register. But the returned register is only guaranteed
- to be safe to use after register saves are complete. So if
- stack clash protections are enabled and the allocated frame is
- larger than the probe interval, then use pushes to save
- callee saved registers. */
- || (flag_stack_clash_protection
- && !ix86_target_stack_probe ()
- && to_allocate > get_probe_interval ()))
+ if (save_regs_using_push_pop (to_allocate))
frame->save_regs_using_mov = false;
if (ix86_using_red_zone ()
@@ -7660,7 +7667,9 @@ ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
{
- ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
+ /* Skip registers, already processed by shrink wrap separate. */
+ if (!cfun->machine->reg_is_wrapped_separately[regno])
+ ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
cfa_offset -= UNITS_PER_WORD;
}
}
@@ -7753,8 +7762,15 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
add_frame_related_expr = true;
}
- insn = emit_insn (gen_pro_epilogue_adjust_stack_add
- (Pmode, dest, src, addend));
+ /* Shrink wrap separate may insert prologue between TEST and JMP. In order
+ not to affect EFlags, emit add without reg clobbering. */
+ if (crtl->shrink_wrapped_separate)
+ insn = emit_insn (gen_pro_epilogue_adjust_stack_add_nocc
+ (Pmode, dest, src, addend));
+ else
+ insn = emit_insn (gen_pro_epilogue_adjust_stack_add
+ (Pmode, dest, src, addend));
+
if (style >= 0)
ix86_add_queued_cfa_restore_notes (insn);
@@ -9219,11 +9235,22 @@ ix86_expand_prologue (void)
doing this if we have to probe the stack; at least on x86_64 the
stack probe can turn into a call that clobbers a red zone location. */
else if (ix86_using_red_zone ()
- && (! TARGET_STACK_PROBE
- || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
+ && (! TARGET_STACK_PROBE
+ || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
{
+ HOST_WIDE_INT allocate_offset;
+ if (crtl->shrink_wrapped_separate)
+ {
+ allocate_offset = m->fs.sp_offset - frame.stack_pointer_offset;
+
+ /* Adjust the total offset at the beginning of the function. */
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (allocate_offset), -1,
+ m->fs.cfa_reg == stack_pointer_rtx);
+ m->fs.sp_offset = cfun->machine->frame.stack_pointer_offset;
+ }
+
ix86_emit_save_regs_using_mov (frame.reg_save_offset);
- cfun->machine->red_zone_used = true;
int_registers_saved = true;
}
}
@@ -9416,6 +9443,8 @@ ix86_expand_prologue (void)
}
else
{
+ gcc_assert (!crtl->shrink_wrapped_separate);
+
rtx eax = gen_rtx_REG (Pmode, AX_REG);
rtx r10 = NULL;
const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
@@ -9801,30 +9830,35 @@ ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
{
- rtx reg = gen_rtx_REG (word_mode, regno);
- rtx mem;
- rtx_insn *insn;
- mem = choose_baseaddr (cfa_offset, NULL);
- mem = gen_frame_mem (word_mode, mem);
- insn = emit_move_insn (reg, mem);
-
- if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg))
+ /* Skip registers, already processed by shrink wrap separate. */
+ if (!cfun->machine->reg_is_wrapped_separately[regno])
{
- /* Previously we'd represented the CFA as an expression
- like *(%ebp - 8). We've just popped that value from
- the stack, which means we need to reset the CFA to
- the drap register. This will remain until we restore
- the stack pointer. */
- add_reg_note (insn, REG_CFA_DEF_CFA, reg);
- RTX_FRAME_RELATED_P (insn) = 1;
+ rtx reg = gen_rtx_REG (word_mode, regno);
+ rtx mem;
+ rtx_insn *insn;
- /* This means that the DRAP register is valid for addressing. */
- m->fs.drap_valid = true;
- }
- else
- ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
+ mem = choose_baseaddr (cfa_offset, NULL);
+ mem = gen_frame_mem (word_mode, mem);
+ insn = emit_move_insn (reg, mem);
+ if (m->fs.cfa_reg == crtl->drap_reg
+ && regno == REGNO (crtl->drap_reg))
+ {
+ /* Previously we'd represented the CFA as an expression
+ like *(%ebp - 8). We've just popped that value from
+ the stack, which means we need to reset the CFA to
+ the drap register. This will remain until we restore
+ the stack pointer. */
+ add_reg_note (insn, REG_CFA_DEF_CFA, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ /* DRAP register is valid for addressing. */
+ m->fs.drap_valid = true;
+ }
+ else
+ ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
+ }
cfa_offset -= UNITS_PER_WORD;
}
}
@@ -10103,10 +10137,11 @@ ix86_expand_epilogue (int style)
less work than reloading sp and popping the register. */
else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1)
restore_regs_via_mov = true;
- else if (TARGET_EPILOGUE_USING_MOVE
- && cfun->machine->use_fast_prologue_epilogue
- && (frame.nregs > 1
- || m->fs.sp_offset != reg_save_offset))
+ else if (crtl->shrink_wrapped_separate
+ || (TARGET_EPILOGUE_USING_MOVE
+ && cfun->machine->use_fast_prologue_epilogue
+ && (frame.nregs > 1
+ || m->fs.sp_offset != reg_save_offset)))
restore_regs_via_mov = true;
else if (frame_pointer_needed
&& !frame.nregs
@@ -10120,6 +10155,9 @@ ix86_expand_epilogue (int style)
else
restore_regs_via_mov = false;
+ if (crtl->shrink_wrapped_separate)
+ gcc_assert (restore_regs_via_mov);
+
if (restore_regs_via_mov || frame.nsseregs)
{
/* Ensure that the entire register save area is addressable via
@@ -10172,6 +10210,7 @@ ix86_expand_epilogue (int style)
gcc_assert (m->fs.sp_offset == UNITS_PER_WORD);
gcc_assert (!crtl->drap_reg);
gcc_assert (!frame.nregs);
+ gcc_assert (!crtl->shrink_wrapped_separate);
}
else if (restore_regs_via_mov)
{
@@ -10186,6 +10225,8 @@ ix86_expand_epilogue (int style)
rtx sa = EH_RETURN_STACKADJ_RTX;
rtx_insn *insn;
+ gcc_assert (!crtl->shrink_wrapped_separate);
+
/* Stack realignment doesn't work with eh_return. */
if (crtl->stack_realign_needed)
sorry ("Stack realignment not supported with "
@@ -28076,6 +28117,195 @@ ix86_cannot_copy_insn_p (rtx_insn *insn)
#undef TARGET_DOCUMENTATION_NAME
#define TARGET_DOCUMENTATION_NAME "x86"
+/* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */
+sbitmap
+ix86_get_separate_components (void)
+{
+ HOST_WIDE_INT offset, to_allocate;
+ sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
+ bitmap_clear (components);
+ struct machine_function *m = cfun->machine;
+
+ offset = m->frame.stack_pointer_offset;
+ to_allocate = offset - m->frame.sse_reg_save_offset;
+
+ /* Shrink wrap separate uses MOV, which means APX PPX cannot be used.
+ Experiments show that APX PPX can speed up the prologue. If the function
+ does not exit early during actual execution, then using APX PPX is faster.
+ If the function always exits early during actual execution, then shrink
+ wrap separate reduces the number of MOV (PUSH/POP) instructions actually
+ executed, thus speeding up execution.
+ foo:
+ movl $1, %eax
+ testq %rdi, %rdi
+ jne.L60
+ ret ---> early return.
+ .L60:
+ subq $88, %rsp ---> belong to prologue.
+ xorl %eax, %eax
+ movq %rbx, 40 (%rsp) ---> belong to prologue.
+ movq 8 (%rdi), %rbx
+ movq %rbp, 48 (%rsp) ---> belong to prologue.
+ movq %rdi, %rbp
+ testq %rbx, %rbx
+ jne.L61
+ movq 40 (%rsp), %rbx
+ movq 48 (%rsp), %rbp
+ addq $88, %rsp
+ ret
+ .L61:
+ movq %r12, 56 (%rsp) ---> belong to prologue.
+ movq %r13, 64 (%rsp) ---> belong to prologue.
+ movq %r14, 72 (%rsp) ---> belong to prologue.
+ ... ...
+
+ Disable shrink wrap separate when PPX is enabled. */
+ if ((TARGET_APX_PPX && !crtl->calls_eh_return)
+ || cfun->machine->func_type != TYPE_NORMAL
+ || TARGET_SEH
+ || crtl->stack_realign_needed
+ || m->call_ms2sysv)
+ return components;
+
+ /* Since shrink wrapping separate uses MOV instead of PUSH/POP.
+ Disable shrink wrap separate when MOV is prohibited. */
+ if (save_regs_using_push_pop (to_allocate))
+ return components;
+
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
+ {
+ /* Skip registers with large offsets, where a pseudo may be needed. */
+ if (IN_RANGE (offset, -0x8000, 0x7fff))
+ bitmap_set_bit (components, regno);
+ offset += UNITS_PER_WORD;
+ }
+
+ /* Don't mess with the following registers. */
+ if (frame_pointer_needed)
+ bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM);
+
+ if (crtl->drap_reg)
+ bitmap_clear_bit (components, REGNO (crtl->drap_reg));
+
+ if (pic_offset_table_rtx)
+ bitmap_clear_bit (components, REAL_PIC_OFFSET_TABLE_REGNUM);
+
+ return components;
+}
+
+/* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */
+sbitmap
+ix86_components_for_bb (basic_block bb)
+{
+ bitmap in = DF_LIVE_IN (bb);
+ bitmap gen = &DF_LIVE_BB_INFO (bb)->gen;
+ bitmap kill = &DF_LIVE_BB_INFO (bb)->kill;
+
+ sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
+ bitmap_clear (components);
+
+ function_abi_aggregator callee_abis;
+ rtx_insn *insn;
+ FOR_BB_INSNS (bb, insn)
+ if (CALL_P (insn))
+ callee_abis.note_callee_abi (insn_callee_abi (insn));
+ HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
+
+ /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (!fixed_regs[regno]
+ && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
+ || bitmap_bit_p (in, regno)
+ || bitmap_bit_p (gen, regno)
+ || bitmap_bit_p (kill, regno)))
+ bitmap_set_bit (components, regno);
+
+ return components;
+}
+
+/* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */
+void
+ix86_disqualify_components (sbitmap, edge, sbitmap, bool)
+{
+ /* Nothing to do for x86. */
+}
+
+/* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */
+void
+ix86_emit_prologue_components (sbitmap components)
+{
+ HOST_WIDE_INT cfa_offset;
+ struct machine_function *m = cfun->machine;
+
+ cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
+ - m->frame.stack_pointer_offset;
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
+ {
+ if (bitmap_bit_p (components, regno))
+ ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
+ cfa_offset -= UNITS_PER_WORD;
+ }
+}
+
+/* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */
+void
+ix86_emit_epilogue_components (sbitmap components)
+{
+ HOST_WIDE_INT cfa_offset;
+ struct machine_function *m = cfun->machine;
+ cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
+ - m->frame.stack_pointer_offset;
+
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
+ {
+ if (bitmap_bit_p (components, regno))
+ {
+ rtx reg = gen_rtx_REG (word_mode, regno);
+ rtx mem;
+ rtx_insn *insn;
+
+ mem = choose_baseaddr (cfa_offset, NULL);
+ mem = gen_frame_mem (word_mode, mem);
+ insn = emit_move_insn (reg, mem);
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_CFA_RESTORE, reg);
+ }
+ cfa_offset -= UNITS_PER_WORD;
+ }
+}
+
+/* Implement TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS. */
+void
+ix86_set_handled_components (sbitmap components)
+{
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (bitmap_bit_p (components, regno))
+ {
+ cfun->machine->reg_is_wrapped_separately[regno] = true;
+ cfun->machine->use_fast_prologue_epilogue = true;
+ cfun->machine->frame.save_regs_using_mov = true;
+ }
+}
+
+#undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
+#define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS ix86_get_separate_components
+#undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
+#define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB ix86_components_for_bb
+#undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
+#define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS ix86_disqualify_components
+#undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
+#define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
+ ix86_emit_prologue_components
+#undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
+#define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
+ ix86_emit_epilogue_components
+#undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
+#define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS ix86_set_handled_components
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-i386.h"
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index d32d9ad..7c16eac 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2821,6 +2821,10 @@ struct GTY(()) machine_function {
/* Cached initial frame layout for the current function. */
struct ix86_frame frame;
+ /* The components already handled by separate shrink-wrapping, which should
+ not be considered by the prologue and epilogue. */
+ bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER];
+
/* For -fsplit-stack support: A stack local which holds a pointer to
the stack arguments for a function with a variable number of
arguments. This is set at the start of the function and is used
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 99f3824..423ef48 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2438,22 +2438,32 @@
(set_attr "mode" "SI")
(set_attr "length_immediate" "0")])
-(define_insn "*mov<mode>_and"
+;; Generate shorter "and $0,mem" for -Oz. Split it to "mov $0,mem"
+;; otherwise.
+(define_insn_and_split "*mov<mode>_and"
[(set (match_operand:SWI248 0 "memory_operand" "=m")
(match_operand:SWI248 1 "const0_operand"))
(clobber (reg:CC FLAGS_REG))]
"reload_completed"
"and{<imodesuffix>}\t{%1, %0|%0, %1}"
+ "&& !(optimize_insn_for_size_p () && optimize_size > 1)"
+ [(set (match_dup 0) (match_dup 1))]
+ ""
[(set_attr "type" "alu1")
(set_attr "mode" "<MODE>")
(set_attr "length_immediate" "1")])
-(define_insn "*mov<mode>_or"
+;; Generate shorter "or $-1,mem" for -Oz. Split it to "mov $-1,mem"
+;; otherwise.
+(define_insn_and_split "*mov<mode>_or"
[(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
(match_operand:SWI248 1 "constm1_operand"))
(clobber (reg:CC FLAGS_REG))]
"reload_completed"
"or{<imodesuffix>}\t{%1, %0|%0, %1}"
+ "&& !(optimize_insn_for_size_p () && optimize_size > 1)"
+ [(set (match_dup 0) (match_dup 1))]
+ ""
[(set_attr "type" "alu1")
(set_attr "mode" "<MODE>")
(set_attr "length_immediate" "1")])
@@ -2958,6 +2968,7 @@
(match_operand:SWI248 1 "const_int_operand"))]
"optimize_insn_for_size_p () && optimize_size > 1
&& operands[1] != const0_rtx
+ && operands[1] != constm1_rtx
&& IN_RANGE (INTVAL (operands[1]), -128, 127)
&& !ix86_red_zone_used
&& REGNO (operands[0]) != SP_REG"
@@ -27452,6 +27463,28 @@
(const_string "*")))
(set_attr "mode" "<MODE>")])
+(define_insn "@pro_epilogue_adjust_stack_add_nocc<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (plus:P (match_operand:P 1 "register_operand" "r")
+ (match_operand:P 2 "<nonmemory_operand>" "l<i>")))
+ (clobber (mem:BLK (scratch)))]
+ ""
+{
+ if (operands[2] == CONST0_RTX (<MODE>mode))
+ return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
+ else
+ {
+ operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
+ return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
+ }
+}
+ [(set (attr "length_immediate")
+ (cond [(eq_attr "type" "imov")
+ (const_string "0")
+ ]
+ (const_string "*")))
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(minus:P (match_operand:P 1 "register_operand" "0")
diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc
index f1c92c6..868df67 100644
--- a/gcc/config/or1k/or1k.cc
+++ b/gcc/config/or1k/or1k.cc
@@ -1654,6 +1654,63 @@ or1k_rtx_costs (rtx x, machine_mode mode, int outer_code, int /* opno */,
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS or1k_rtx_costs
+static bool
+or1k_is_cmov_insn (rtx_insn *seq)
+{
+ rtx_insn *curr_insn = seq;
+ rtx set = NULL_RTX;
+
+ /* The pattern may start with a simple set with register operands. Skip
+ through any of those. */
+ while (curr_insn)
+ {
+ set = single_set (curr_insn);
+ if (!set
+ || !REG_P (SET_DEST (set)))
+ return false;
+
+ /* If it's not a simple reg or immediate break. */
+ if (REG_P (SET_SRC (set)) || CONST_INT_P (SET_SRC (set)))
+ curr_insn = NEXT_INSN (curr_insn);
+ else
+ break;
+ }
+
+ if (!curr_insn)
+ return false;
+
+ /* The next instruction should be a compare. OpenRISC has many operators used
+ for comparison so skip and confirm the next is IF_THEN_ELSE. */
+ curr_insn = NEXT_INSN (curr_insn);
+ if (!curr_insn)
+ return false;
+
+ /* And the last instruction should be an IF_THEN_ELSE. */
+ set = single_set (curr_insn);
+ if (!set
+ || !REG_P (SET_DEST (set))
+ || GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
+ return false;
+
+ return !NEXT_INSN (curr_insn);
+}
+
+/* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We detect if the conversion
+ resulted in a l.cmov instruction and if so we consider it more profitable than
+ branch instructions. */
+
+static bool
+or1k_noce_conversion_profitable_p (rtx_insn *seq,
+ struct noce_if_info *if_info)
+{
+ if (TARGET_CMOV)
+ return or1k_is_cmov_insn (seq);
+
+ return default_noce_conversion_profitable_p (seq, if_info);
+}
+
+#undef TARGET_NOCE_CONVERSION_PROFITABLE_P
+#define TARGET_NOCE_CONVERSION_PROFITABLE_P or1k_noce_conversion_profitable_p
/* A subroutine of the atomic operation splitters. Jump to LABEL if
COND is true. Mark the jump as unlikely to be taken. */
diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md
index 627e400..bf71253 100644
--- a/gcc/config/or1k/or1k.md
+++ b/gcc/config/or1k/or1k.md
@@ -515,6 +515,31 @@
(ne:SI (reg:BI SR_F_REGNUM) (const_int 0)))]
"")
+;; Allowing "extending" the BImode SR_F to a general register
+;; avoids 'convert_mode_scalar' from trying to do subregging
+;; which we don't have support for.
+;; We require signed and unsigned extend instructions because
+;; signed comparisons require signed extention, but for SR_F
+;; it doesn't matter.
+
+(define_expand "zero_extendbisi2_sr_f"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:BI 1 "sr_f_reg_operand" "")))]
+ ""
+{
+ emit_insn(gen_sne_sr_f (operands[0]));
+ DONE;
+})
+
+(define_expand "extendbisi2_sr_f"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (sign_extend:SI (match_operand:BI 1 "sr_f_reg_operand" "")))]
+ ""
+{
+ emit_insn(gen_sne_sr_f (operands[0]));
+ DONE;
+})
+
(define_insn_and_split "*scc"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "equality_comparison_operator"
@@ -584,7 +609,7 @@
;; Branch instructions
;; -------------------------------------------------------------------------
-(define_expand "cbranchsi4"
+(define_insn_and_split "cbranchsi4"
[(set (pc)
(if_then_else
(match_operator 0 "comparison_operator"
@@ -593,13 +618,27 @@
(label_ref (match_operand 3 "" ""))
(pc)))]
""
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
+ rtx label;
+
+ /* Generate *scc */
or1k_expand_compare (operands);
+ /* Generate *cbranch */
+ label = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
+ emit_jump_insn (gen_rtx_SET (pc_rtx,
+ gen_rtx_IF_THEN_ELSE (VOIDmode,
+ operands[0],
+ label,
+ pc_rtx)));
+ DONE;
})
;; Support FP branching
-(define_expand "cbranch<F:mode>4"
+(define_insn_and_split "cbranch<F:mode>4"
[(set (pc)
(if_then_else
(match_operator 0 "fp_comparison_operator"
@@ -608,8 +647,22 @@
(label_ref (match_operand 3 "" ""))
(pc)))]
"TARGET_HARD_FLOAT"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
+ rtx label;
+
+ /* Generate *scc */
or1k_expand_compare (operands);
+ /* Generate *cbranch */
+ label = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
+ emit_jump_insn (gen_rtx_SET (pc_rtx,
+ gen_rtx_IF_THEN_ELSE (VOIDmode,
+ operands[0],
+ label,
+ pc_rtx)));
+ DONE;
})
(define_insn "*cbranch"
diff --git a/gcc/config/or1k/predicates.md b/gcc/config/or1k/predicates.md
index 144f4d7..7ccfd09 100644
--- a/gcc/config/or1k/predicates.md
+++ b/gcc/config/or1k/predicates.md
@@ -60,6 +60,10 @@
(and (match_operand 0 "register_operand")
(match_test "TARGET_ROR"))))
+(define_predicate "sr_f_reg_operand"
+ (and (match_operand 0 "register_operand")
+ (match_test "REGNO (op) == SR_F_REGNUM")))
+
(define_predicate "call_insn_operand"
(ior (and (match_code "symbol_ref")
(match_test "!TARGET_CMODEL_LARGE"))
diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index cff7c77..2096c00 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -33,6 +33,7 @@
#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO)
#endif
+RISCV_TUNE("generic", generic, generic_tune_info)
RISCV_TUNE("rocket", generic, rocket_tune_info)
RISCV_TUNE("sifive-3-series", generic, rocket_tune_info)
RISCV_TUNE("sifive-5-series", generic, rocket_tune_info)
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 0115949..ac690df 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -5539,6 +5539,8 @@ expand_vx_binary_vec_dup_vec (rtx op_0, rtx op_1, rtx op_2,
case MULT:
case SMAX:
case UMAX:
+ case SMIN:
+ case UMIN:
icode = code_for_pred_scalar (code, mode);
break;
case MINUS:
@@ -5575,6 +5577,8 @@ expand_vx_binary_vec_vec_dup (rtx op_0, rtx op_1, rtx op_2,
case UMOD:
case SMAX:
case UMAX:
+ case SMIN:
+ case UMIN:
icode = code_for_pred_scalar (code, mode);
break;
default:
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 74462cc..3c1bb74 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -450,6 +450,29 @@ static const struct cpu_vector_cost generic_vector_cost = {
&rvv_regmove_vector_cost, /* regmove */
};
+/* Costs to use when optimizing for generic. */
+static const struct riscv_tune_param generic_tune_info = {
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
+ {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
+ {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
+ 1, /* issue_rate */
+ 4, /* branch_cost */
+ 5, /* memory_cost */
+ 8, /* fmv_cost */
+ true, /* slow_unaligned_access */
+ false, /* vector_unaligned_access */
+ false, /* use_divmod_expansion */
+ false, /* overlap_op_by_pieces */
+ false, /* speculative_sched_vsetvl */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
+ NULL, /* vector cost */
+ NULL, /* function_align */
+ NULL, /* jump_align */
+ NULL, /* loop_align */
+};
+
/* Costs to use when optimizing for rocket. */
static const struct riscv_tune_param rocket_tune_info = {
{COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
@@ -814,6 +837,16 @@ void riscv_frame_info::reset(void)
arg_pointer_offset = 0;
}
+/* Check if the mode is twice the size of the XLEN mode. */
+
+static bool
+riscv_2x_xlen_mode_p (machine_mode mode)
+{
+ poly_int64 mode_size = GET_MODE_SIZE (mode);
+ return mode_size.is_constant ()
+ && (mode_size.to_constant () == UNITS_PER_WORD * 2);
+}
+
/* Implement TARGET_MIN_ARITHMETIC_PRECISION. */
static unsigned int
@@ -3778,10 +3811,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
return true;
}
- if (TARGET_ZILSD
- && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2))
- && ((REG_P (dest) && MEM_P (src))
- || (MEM_P (dest) && REG_P (src)))
+ if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode)
+ && ((REG_P (dest) && MEM_P (src)) || (MEM_P (dest) && REG_P (src)))
&& can_create_pseudo_p ())
{
rtx reg = REG_P (dest) ? dest : src;
@@ -3868,7 +3899,7 @@ static int
riscv_binary_cost (rtx x, int single_insns, int double_insns)
{
if (!riscv_v_ext_mode_p (GET_MODE (x))
- && GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2)
+ && riscv_2x_xlen_mode_p (GET_MODE (x)))
return COSTS_N_INSNS (double_insns);
return COSTS_N_INSNS (single_insns);
}
@@ -3980,6 +4011,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
case MULT:
case SMAX:
case UMAX:
+ case SMIN:
+ case UMIN:
{
rtx op;
rtx op_0 = XEXP (x, 0);
@@ -4022,10 +4055,41 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (1);
return true;
}
+
+ /* Register move for XLEN * 2. */
+ if (TARGET_ZILSD
+ && register_operand (SET_SRC (x), GET_MODE (SET_SRC (x)))
+ && riscv_2x_xlen_mode_p (mode))
+ {
+ /* We still need two instruction for move with ZILSD,
+ but let minus one cost to let subreg split don't.
+ TODO: Add riscv_tune_param for this. */
+ *total = COSTS_N_INSNS (2) - 1;
+ return true;
+ }
+
+ /* Load for XLEN * 2. */
+ if (TARGET_ZILSD && MEM_P (SET_SRC (x))
+ && riscv_2x_xlen_mode_p (mode))
+ {
+ /* TODO: Add riscv_tune_param for this. */
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
riscv_rtx_costs (SET_SRC (x), mode, SET, opno, total, speed);
return true;
}
+ /* Store for XLEN * 2. */
+ if (TARGET_ZILSD && MEM_P (SET_DEST (x)) && REG_P (SET_SRC (x))
+ && riscv_2x_xlen_mode_p (mode))
+ {
+ /* TODO: Add riscv_tune_param for this. */
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
/* Otherwise return FALSE indicating we should recurse into both the
SET_DEST and SET_SRC combining the cost of both. */
return false;
@@ -9973,9 +10037,7 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
return false;
/* Zilsd require load/store with even-odd reg pair. */
- if (TARGET_ZILSD
- && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2))
- && ((regno % 2) != 0))
+ if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode) && ((regno % 2) != 0))
return false;
if (!GP_REG_P (regno + nregs - 1))
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 2759a4c..45fa521 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see
#endif
#ifndef RISCV_TUNE_STRING_DEFAULT
-#define RISCV_TUNE_STRING_DEFAULT "rocket"
+#define RISCV_TUNE_STRING_DEFAULT "generic"
#endif
extern const char *riscv_expand_arch (int argc, const char **argv);
diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
index 726800a..a75ea68 100644
--- a/gcc/config/riscv/sync.md
+++ b/gcc/config/riscv/sync.md
@@ -405,18 +405,17 @@
(match_operand:SI 3 "const_int_operand")] ;; model
UNSPEC_SYNC_EXCHANGE))
(set (match_dup 1)
- (match_operand:GPR 2 "register_operand" "0"))
+ (match_operand:GPR 2 "reg_or_0_operand" "rJ"))
(clobber (match_scratch:GPR 4 "=&r"))] ;; tmp_1
"!TARGET_ZAAMO && TARGET_ZALRSC"
{
return "1:\;"
- "lr.<amo>%I3\t%4, %1\;"
- "sc.<amo>%J3\t%0, %0, %1\;"
- "bnez\t%0, 1b\;"
- "mv\t%0, %4";
+ "lr.<amo>%I3\t%0, %1\;"
+ "sc.<amo>%J3\t%4, %z2, %1\;"
+ "bnez\t%4, 1b\";
}
[(set_attr "type" "atomic")
- (set (attr "length") (const_int 16))])
+ (set (attr "length") (const_int 12))])
(define_expand "atomic_exchange<mode>"
[(match_operand:SHORT 0 "register_operand") ;; old value at mem
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 1e048c1..44ae79c 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -4042,11 +4042,11 @@
])
(define_code_iterator any_int_binop_no_shift_v_vdup [
- plus minus and ior xor mult div udiv mod umod smax umax
+ plus minus and ior xor mult div udiv mod umod smax umax smin umin
])
(define_code_iterator any_int_binop_no_shift_vdup_v [
- plus minus and ior xor mult smax umax
+ plus minus and ior xor mult smax umax smin umin
])
(define_code_iterator any_int_unop [neg not])
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index aea11c9..4a86326 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,69 @@
+2025-06-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/115908
+ PR c++/118074
+ PR c++/95615
+ * coroutines.cc (coro_frame_refcount_id): New.
+ (coro_init_identifiers): Initialise coro_frame_refcount_id.
+ (build_actor_fn): Set up initial_await_resume_called. Handle
+ decrementing of the frame reference count. Return directly to
+ the caller if that is non-zero.
+ (cp_coroutine_transform::wrap_original_function_body): Use a
+ conditional eh-only cleanup around the initial await expression
+ to release the body use on exception before initial await
+ resume.
+ (cp_coroutine_transform::build_ramp_function): Wrap the called
+ body in a cleanup that releases a use of the frame when we
+ return to the ramp. Implement frame, promise and argument copy
+ destruction via conditional cleanups when the frame use count
+ is zero.
+
+2025-06-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ * coroutines.cc (struct coroutine_info): Update comments.
+ (struct coro_aw_data): Remove self_handle and add in
+ information to create the handle in lowering.
+ (expand_one_await_expression): Build a temporary coroutine
+ handle.
+ (build_actor_fn): Remove reference to the frame copy of the
+ coroutine handle.
+ (cp_coroutine_transform::wrap_original_function_body): Remove
+ reference to the frame copy of the coroutine handle.
+
+2025-06-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ * coroutines.cc (analyze_expression_awaits): Elide assume
+ attributes containing await expressions, since these have
+ side effects. Emit a diagnostic that this has been done.
+
+2025-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/120678
+ * cp-trait.def (IS_TRIVIALLY_DESTRUCTIBLE): Fix nargs.
+
+2025-06-17 Jason Merrill <jason@redhat.com>
+
+ * module.cc (module_state::write_diagnostic_classification): New.
+ (module_state::write_begin): Call it.
+ (module_state::read_diagnostic_classification): New.
+ (module_state::read_initial): Call it.
+ (dk_string, dump_dc_change): New.
+
+2025-06-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ * coroutines.cc (finish_co_await_expr): Do not allow in an
+ unevaluated context.
+ (finish_co_yield_expr): Likewise.
+
+2025-06-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/120273
+ * coroutines.cc
+ (cp_coroutine_transform::wrap_original_function_body): Use
+ function start and end locations when synthesizing code.
+ (cp_coroutine_transform::cp_coroutine_transform): Set the
+ function end location.
+
2025-06-16 Jason Merrill <jason@redhat.com>
* constraint.cc (failed_completions_map): New.
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 17d0ee9..52cc186 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -191,8 +191,87 @@ static bool coro_promise_type_found_p (tree, location_t);
just syntactic sugar for a co_await).
We defer the analysis and transformation until template expansion is
- complete so that we have complete types at that time. */
+ complete so that we have complete types at that time.
+ ---------------------------------------------------------------------------
+
+ Coroutine state, and responsibility for its release.
+
+ As noted above, a coroutine has some state that persists across suspensions.
+
+ The state has two components:
+ * State that is specified by the standard and persists for the entire
+ life of the coroutine.
+ * Local state that is constructed/destructed as scopes in the original
+ function body are entered/exited. The destruction of local state is
+ always the responsibility of the body code.
+
+ The persistent state (and the overall storage for the state) must be
+ managed in two places:
+ * The ramp function (which allocates and builds this - and can, in some
+ cases, be responsible for destroying it)
+ * The re-written function body which can destroy it when that body
+ completes its final suspend - or when the handle.destroy () is called.
+
+ In all cases the ramp holds responsibility for constructing the standard-
+ mandated persistent state.
+
+ There are four ways in which the ramp might be re-entered after starting
+ the function body:
+ A The body could suspend (one might expect that to be the 'normal' case
+ for most coroutines).
+ B The body might complete either synchronously or via continuations.
+ C An exception might be thrown during the setup of the initial await
+ expression, before the initial awaiter resumes.
+ D An exception might be processed by promise.unhandled_exception () and
+ that, in turn, might re-throw it (or throw something else). In this
+ case, the coroutine is considered suspended at the final suspension
+ point.
+
+ Until the ramp return value has been constructed, the ramp is considered
+ to have a use of the state.
+
+ To manage these interacting conditions we allocate a reference counter
+ for the frame state. This is initialised to 1 by the ramp as part of its
+ startup (note that failures/exceptions in the startup code are handled
+ locally to the ramp).
+
+ When the body returns (either normally, or by exception) the ramp releases
+ its use.
+
+ Once the rewritten coroutine body is started, the body is considered to
+ have a use of the frame. This use (potentially) needs to be released if
+ an exception is thrown from the body. We implement this using an eh-only
+ cleanup around the initial await and function body. If we have the case
+ D above, then we do not release the use.
+
+ In case:
+
+ A, typically the ramp would be re-entered with the body holding a use,
+ and therefore the ramp should not destroy the state.
+
+ B, both the body and ramp will have released their uses, and the ramp
+ should destroy the state.
+
+ C, we must arrange for the body to release its use, because we require
+ the ramp to cleanup in this circumstance.
+
+ D is an outlier, since the responsibility for destruction of the state
+ now rests with the user's code (via a handle.destroy() call).
+
+ NOTE: In the case that the body has never suspended before such an
+ exception occurs, the only reasonable way for the user code to obtain the
+ necessary handle is if unhandled_exception() throws the handle or some
+ object that contains the handle. That is outside of the designs here -
+ if the user code might need this corner-case, then such provision will
+ have to be made.
+
+ In the ramp, we implement destruction for the persistent frame state by
+ means of cleanups. These are run conditionally when the reference count
+ is 0 signalling that both the body and the ramp have completed.
+
+ In the body, once we pass the final suspend, then we test the use and
+ delete the state if the use is 0. */
/* The state that we collect during parsing (and template expansion) for
a coroutine. */
@@ -206,11 +285,10 @@ struct GTY((for_user)) coroutine_info
tree traits_type; /* The cached traits type for this function. */
tree handle_type; /* The cached coroutine handle for this function. */
tree self_h_proxy; /* A handle instance that is used as the proxy for the
- one that will eventually be allocated in the coroutine
- frame. */
+ one that will eventually be built in lowering. */
tree promise_proxy; /* Likewise, a proxy promise instance. */
- tree from_address; /* handle_type from_address function. */
- tree return_void; /* The expression for p.return_void() if it exists. */
+ tree from_address; /* handle_type from_address() function. */
+ tree return_void; /* The expression for p.return_void(), if it exists. */
location_t first_coro_keyword; /* The location of the keyword that made this
function into a coroutine. */
@@ -348,6 +426,7 @@ static GTY(()) tree coro_resume_index_id;
static GTY(()) tree coro_self_handle_id;
static GTY(()) tree coro_actor_continue_id;
static GTY(()) tree coro_frame_i_a_r_c_id;
+static GTY(()) tree coro_frame_refcount_id;
/* Create the identifiers used by the coroutines library interfaces and
the implementation frame state. */
@@ -385,6 +464,7 @@ coro_init_identifiers ()
coro_resume_index_id = get_identifier ("_Coro_resume_index");
coro_self_handle_id = get_identifier ("_Coro_self_handle");
coro_actor_continue_id = get_identifier ("_Coro_actor_continue");
+ coro_frame_refcount_id = get_identifier ("_Coro_frame_refcount");
}
/* Trees we only need to set up once. */
@@ -1467,6 +1547,12 @@ finish_co_await_expr (location_t kw, tree expr)
if (!expr || error_operand_p (expr))
return error_mark_node;
+ if (cp_unevaluated_operand)
+ {
+ error_at (kw, "%qs cannot be used in an unevaluated context","co_await");
+ return error_mark_node;
+ }
+
if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
"co_await"))
return error_mark_node;
@@ -1547,6 +1633,12 @@ finish_co_yield_expr (location_t kw, tree expr)
if (!expr || error_operand_p (expr))
return error_mark_node;
+ if (cp_unevaluated_operand)
+ {
+ error_at (kw, "%qs cannot be used in an unevaluated context","co_yield");
+ return error_mark_node;
+ }
+
/* Check the general requirements and simple syntax errors. */
if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
"co_yield"))
@@ -1970,12 +2062,13 @@ struct coro_aw_data
tree coro_fp; /* Frame pointer var. */
tree resume_idx; /* This is the index var in the frame. */
tree i_a_r_c; /* initial suspend await_resume() was called if true. */
- tree self_h; /* This is a handle to the current coro (frame var). */
tree cleanup; /* This is where to go once we complete local destroy. */
tree cororet; /* This is where to go if we suspend. */
tree corocont; /* This is where to go if we continue. */
tree dispatch; /* This is where we go if we restart the dispatch. */
tree conthand; /* This is the handle for a continuation. */
+ tree handle_type; /* Handle type for this coroutine... */
+ tree hfa_m; /* ... and handle.from_address() for this. */
unsigned index; /* This is our current resume index. */
};
@@ -2093,6 +2186,18 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d)
tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend(). */
tree susp_type = TREE_TYPE (suspend);
+ tree susp_call = suspend;
+ if (TREE_CODE (suspend) == TARGET_EXPR)
+ susp_call = TARGET_EXPR_INITIAL (suspend);
+ gcc_checking_assert (TREE_CODE (susp_call) == CALL_EXPR);
+ tree dummy_ch = build_dummy_object (data->handle_type);
+ r = fold_convert (build_pointer_type (void_type_node), data->coro_fp);
+ vec<tree, va_gc> *args = make_tree_vector_single (r);
+ tree hfa = cp_fold_rvalue (
+ build_new_method_call (dummy_ch, data->hfa_m, &args, NULL_TREE,
+ LOOKUP_NORMAL, NULL, tf_warning_or_error));
+ release_tree_vector (args);
+ CALL_EXPR_ARG (susp_call, call_expr_nargs (susp_call) - 1) = hfa;
bool is_cont = false;
/* NOTE: final suspend can't resume; the "resume" label in that case
@@ -2574,21 +2679,16 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
/* Now we start building the rewritten function body. */
add_stmt (build_stmt (loc, LABEL_EXPR, actor_begin_label));
- /* actor's coroutine 'self handle'. */
- tree ash = coro_build_frame_access_expr (actor_frame, coro_self_handle_id,
- false, tf_warning_or_error);
- /* So construct the self-handle from the frame address. */
- tree hfa_m = get_coroutine_from_address (orig);
- /* Should have been set earlier by coro_promise_type_found_p. */
- gcc_assert (hfa_m);
-
- tree r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
- vec<tree, va_gc> *args = make_tree_vector_single (r);
- tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
- NULL, tf_warning_or_error);
- r = cp_build_init_expr (ash, hfa);
- finish_expr_stmt (r);
- release_tree_vector (args);
+ tree i_a_r_c = NULL_TREE;
+ if (flag_exceptions)
+ {
+ i_a_r_c
+ = coro_build_frame_access_expr (actor_frame, coro_frame_i_a_r_c_id,
+ false, tf_warning_or_error);
+ tree m = cp_build_modify_expr (loc, i_a_r_c, NOP_EXPR,
+ boolean_false_node, tf_warning_or_error);
+ finish_expr_stmt (m);
+ }
/* Now we know the real promise, and enough about the frame layout to
decide where to put things. */
@@ -2603,7 +2703,28 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
/* Add in our function body with the co_returns rewritten to final form. */
add_stmt (fnbody);
- /* Now do the tail of the function; first cleanups. */
+ /* We are done with the frame, but if the ramp still has a hold on it
+ we should not cleanup. So decrement the refcount and then return to
+ the ramp if it is > 0. */
+ tree coro_frame_refcount
+ = coro_build_frame_access_expr (actor_frame, coro_frame_refcount_id,
+ false, tf_warning_or_error);
+ tree released = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node,
+ coro_frame_refcount,
+ build_int_cst (short_unsigned_type_node, 1));
+ tree r = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, released,
+ tf_warning_or_error);
+ finish_expr_stmt (r);
+ tree cond = build2_loc (loc, NE_EXPR, short_unsigned_type_node,
+ coro_frame_refcount,
+ build_int_cst (short_unsigned_type_node, 0));
+ tree ramp_cu_if = begin_if_stmt ();
+ finish_if_stmt_cond (cond, ramp_cu_if);
+ finish_return_stmt (NULL_TREE);
+ finish_then_clause (ramp_cu_if);
+ finish_if_stmt (ramp_cu_if);
+
+ /* Otherwise, do the tail of the function; first cleanups. */
r = build_stmt (loc, LABEL_EXPR, del_promise_label);
add_stmt (r);
@@ -2672,16 +2793,19 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
add_stmt (r);
+ /* How to construct the handle for this coroutine from the frame address. */
+ tree hfa_m = get_coroutine_from_address (orig);
+ /* Should have been set earlier by coro_promise_type_found_p. */
+ gcc_assert (hfa_m);
+ tree handle_type = TREE_TYPE (get_coroutine_self_handle_proxy (orig));
+
/* We've now rewritten the tree and added the initial and final
co_awaits. Now pass over the tree and expand the co_awaits. */
- tree i_a_r_c = NULL_TREE;
- if (flag_exceptions)
- i_a_r_c = coro_build_frame_access_expr (actor_frame, coro_frame_i_a_r_c_id,
- false, tf_warning_or_error);
coro_aw_data data = {actor, actor_fp, resume_idx_var, i_a_r_c,
- ash, del_promise_label, ret_label,
- continue_label, restart_dispatch_label, continuation, 2};
+ del_promise_label, ret_label,
+ continue_label, restart_dispatch_label, continuation,
+ handle_type, hfa_m, 2};
cp_walk_tree (&actor_body, await_statement_expander, &data, NULL);
BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body);
@@ -3467,6 +3591,19 @@ analyze_expression_awaits (tree *stmt, int *do_subtree, void *d)
}
*do_subtree = 0;
}
+ else if (!fn && CALL_EXPR_IFN (*stmt) == IFN_ASSUME)
+ {
+ tree expr = CALL_EXPR_ARG (*stmt, 0);
+ if (TREE_SIDE_EFFECTS (expr))
+ {
+ location_t loc_e = cp_expr_location (expr);
+ location_t loc_s = cp_expr_location (*stmt);
+ location_t loc_n = make_location (loc_e, loc_s, loc_s);
+ warning_at (loc_n, OPT_Wattributes,"assumption ignored"
+ " because it contains an await-expression");
+ *stmt = build_empty_stmt (loc_n);
+ }
+ }
}
break;
case CO_YIELD_EXPR:
@@ -4399,16 +4536,6 @@ cp_coroutine_transform::wrap_original_function_body ()
var_list = promise;
add_decl_expr (promise);
- /* We need a handle to this coroutine, which is passed to every
- await_suspend(). This was created on demand when parsing we now link it
- into our scope. */
- var = get_coroutine_self_handle_proxy (orig_fn_decl);
- DECL_CONTEXT (var) = orig_fn_decl;
- DECL_SOURCE_LOCATION (var) = loc;
- DECL_CHAIN (var) = var_list;
- var_list = var;
- add_decl_expr (var);
-
/* If we have function parms, then these will be copied to the coroutine
frame as per [dcl.fct.def.coroutine] / 13.
Here, we create a local (proxy) variable for each parm, since the original
@@ -4452,6 +4579,14 @@ cp_coroutine_transform::wrap_original_function_body ()
var_list = resume_idx_var;
add_decl_expr (resume_idx_var);
+ tree coro_frame_refcount
+ = coro_build_artificial_var (loc, coro_frame_refcount_id,
+ short_unsigned_type_node, orig_fn_decl,
+ NULL_TREE);
+ DECL_CHAIN (coro_frame_refcount) = var_list;
+ var_list = coro_frame_refcount;
+ add_decl_expr (coro_frame_refcount);
+
/* If the coroutine has a frame that needs to be freed, this will be set by
the ramp. */
var = coro_build_artificial_var (loc, coro_frame_needs_free_id,
@@ -4460,6 +4595,15 @@ cp_coroutine_transform::wrap_original_function_body ()
var_list = var;
add_decl_expr (var);
+ /* We consider that the body has a use of the frame once we start to process
+ the initial suspend expression. (the use might be relinquished if we
+ encounter an exception before the body is finished). */
+ tree body_use
+ = build2_loc (loc, PLUS_EXPR, short_unsigned_type_node, coro_frame_refcount,
+ build_int_cst (short_unsigned_type_node, 1));
+ body_use = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, body_use,
+ tf_warning_or_error);
+ finish_expr_stmt (body_use);
if (flag_exceptions)
{
/* Build promise.unhandled_exception(); */
@@ -4480,10 +4624,28 @@ cp_coroutine_transform::wrap_original_function_body ()
tree tcb = build_stmt (loc, TRY_BLOCK, NULL_TREE, NULL_TREE);
add_stmt (tcb);
TRY_STMTS (tcb) = push_stmt_list ();
+ /* We need a new scope to handle the cleanup for the ramp use that is
+ needed for exceptions. */
+ tree except_scope = begin_compound_stmt (0);
+ current_binding_level->artificial = 1;
+ tree release
+ = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node,
+ coro_frame_refcount, build_int_cst (short_unsigned_type_node, 1));
+ release = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR,
+ release, tf_warning_or_error);
+ /* Once we pass the initial await resume, the cleanup rules on exception
+ change so that the responsibility lies with the caller. */
+ release = build3 (COND_EXPR, void_type_node, i_a_r_c,
+ build_empty_stmt (loc), release);
+ push_cleanup (NULL_TREE, release, /*ehonly*/true);
/* Add the initial await to the start of the user-authored function. */
finish_expr_stmt (initial_await);
+ /* End the scope that handles the remove of frame-use on exception. */
+ finish_compound_stmt (except_scope);
+
/* Append the original function body. */
add_stmt (coroutine_body);
+
if (return_void)
add_stmt (return_void);
TRY_STMTS (tcb) = pop_stmt_list (TRY_STMTS (tcb));
@@ -4928,31 +5090,18 @@ cp_coroutine_transform::build_ramp_function ()
just set it true. */
TREE_USED (frame_needs_free) = true;
- tree iarc_x = NULL_TREE;
- tree coro_before_return = NULL_TREE;
- if (flag_exceptions)
- {
- coro_before_return
- = coro_build_and_push_artificial_var (loc, "_Coro_before_return",
- boolean_type_node, orig_fn_decl,
- boolean_true_node);
- iarc_x
- = coro_build_and_push_artificial_var_with_dve (loc,
- coro_frame_i_a_r_c_id,
- boolean_type_node,
- orig_fn_decl,
- boolean_false_node,
- deref_fp);
- tree frame_cleanup = push_stmt_list ();
- tree do_fr_cleanup
- = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x);
- do_fr_cleanup = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node,
- coro_before_return, do_fr_cleanup);
- r = build3 (COND_EXPR, void_type_node, do_fr_cleanup,
- delete_frame_call, void_node);
- finish_expr_stmt (r);
- push_cleanup (coro_fp, pop_stmt_list (frame_cleanup), /*eh_only*/true);
- }
+ tree coro_frame_refcount
+ = coro_build_and_push_artificial_var_with_dve (loc, coro_frame_refcount_id,
+ short_unsigned_type_node,
+ orig_fn_decl, NULL_TREE,
+ deref_fp);
+ /* Cleanup if both the ramp and the body have finished. */
+ tree cond
+ = build2_loc (loc, EQ_EXPR, short_unsigned_type_node, coro_frame_refcount,
+ build_int_cst (short_unsigned_type_node, 0));
+ r = build3 (COND_EXPR, void_type_node, cond, delete_frame_call,
+ build_empty_stmt (loc));
+ push_cleanup (coro_fp, r, /*eh_only*/false);
/* Put the resumer and destroyer functions in. */
@@ -5027,24 +5176,20 @@ cp_coroutine_transform::build_ramp_function ()
/* Arrange for parm copies to be cleaned up when an exception is
thrown before initial await resume. */
- if (flag_exceptions && !parm.trivial_dtor)
+ if (!parm.trivial_dtor)
{
parm.fr_copy_dtor
= cxx_maybe_build_cleanup (fld_idx, tf_warning_or_error);
if (parm.fr_copy_dtor && parm.fr_copy_dtor != error_mark_node)
{
param_dtor_list.safe_push (parm.field_id);
- tree param_cleanup = push_stmt_list ();
- tree do_cleanup
- = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x);
- do_cleanup
- = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node,
- coro_before_return, do_cleanup);
- r = build3_loc (loc, COND_EXPR, void_type_node, do_cleanup,
- parm.fr_copy_dtor, void_node);
- finish_expr_stmt (r);
- push_cleanup (fld_idx, pop_stmt_list (param_cleanup),
- /*eh_only*/true);
+ cond
+ = build2_loc (loc, EQ_EXPR, short_unsigned_type_node,
+ coro_frame_refcount,
+ build_int_cst (short_unsigned_type_node, 0));
+ r = build3_loc (loc, COND_EXPR, void_type_node, cond,
+ parm.fr_copy_dtor, build_empty_stmt (loc));
+ push_cleanup (fld_idx, r, /*eh_only*/false);
}
}
}
@@ -5089,22 +5234,16 @@ cp_coroutine_transform::build_ramp_function ()
finish_expr_stmt (r);
}
- if (flag_exceptions)
+ tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error);
+ /* If the promise is live, then run its dtor if that's available. */
+ if (promise_dtor && promise_dtor != error_mark_node)
{
- tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error);
- /* If the promise is live, then run its dtor if that's available. */
- if (promise_dtor && promise_dtor != error_mark_node)
- {
- tree promise_cleanup = push_stmt_list ();
- tree do_cleanup
- = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x);
- do_cleanup = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node,
- coro_before_return, do_cleanup);
- r = build3 (COND_EXPR, void_type_node, do_cleanup,
- promise_dtor, void_node);
- finish_expr_stmt (r);
- push_cleanup (p, pop_stmt_list (promise_cleanup), /*eh_only*/true);
- }
+ cond = build2_loc (loc, EQ_EXPR, short_unsigned_type_node,
+ coro_frame_refcount,
+ build_int_cst (short_unsigned_type_node, 0));
+ r = build3 (COND_EXPR, void_type_node, cond, promise_dtor,
+ build_empty_stmt (loc));
+ push_cleanup (p, r, /*eh_only*/false);
}
tree get_ro
@@ -5169,16 +5308,22 @@ cp_coroutine_transform::build_ramp_function ()
push_cleanup (coro_gro, coro_gro_cleanup, /*eh_only*/false);
}
- /* Start the coroutine body. */
- r = build_call_expr_loc (fn_start, resumer, 1, coro_fp);
+ /* Start the coroutine body, we now have a use of the frame... */
+ r = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR,
+ build_int_cst (short_unsigned_type_node, 1),
+ tf_warning_or_error);
finish_expr_stmt (r);
+ /* ... but when we finish we want to release that, and we want to do that
+ before any of the other cleanups run. */
+ tree released
+ = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node, coro_frame_refcount,
+ build_int_cst (short_unsigned_type_node, 1));
+ released = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, released,
+ tf_warning_or_error);
+ push_cleanup (NULL_TREE, released, /*eh_only*/false);
- if (flag_exceptions)
- {
- r = cp_build_modify_expr (input_location, coro_before_return, NOP_EXPR,
- boolean_false_node, tf_warning_or_error);
- finish_expr_stmt (r);
- }
+ r = build_call_expr_loc (fn_start, resumer, 1, coro_fp);
+ finish_expr_stmt (r);
/* The ramp is done, we just need the return statement, which we build from
the return object we constructed before we called the actor. */
@@ -5260,7 +5405,6 @@ cp_coroutine_transform::~cp_coroutine_transform ()
bool _Coro_frame_needs_free; free the coro frame mem if set.
bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3
short _Coro_resume_index;
- handle_type _Coro_self_handle;
parameter copies (were required).
local variables saved (including awaitables)
(maybe) trailing space.
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 9c7380d..2e3b4ca 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -100,7 +100,7 @@ DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
-DEFTRAIT_EXPR (IS_TRIVIALLY_DESTRUCTIBLE, "__is_trivially_destructible", -1)
+DEFTRAIT_EXPR (IS_TRIVIALLY_DESTRUCTIBLE, "__is_trivially_destructible", 1)
DEFTRAIT_EXPR (IS_UNBOUNDED_ARRAY, "__is_unbounded_array", 1)
DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
DEFTRAIT_EXPR (IS_VIRTUAL_BASE_OF, "__builtin_is_virtual_base_of", 2)
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ad2acaf..c99988d 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -3879,6 +3879,10 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state {
void write_macro_maps (elf_out *to, range_t &, unsigned *crc_ptr);
bool read_macro_maps (line_map_uint_t);
+ void write_diagnostic_classification (elf_out *, diagnostic_context *,
+ unsigned *);
+ bool read_diagnostic_classification (diagnostic_context *);
+
private:
void write_define (bytes_out &, const cpp_macro *);
cpp_macro *read_define (bytes_in &, cpp_reader *) const;
@@ -18167,6 +18171,168 @@ module_state::write_ordinary_maps (elf_out *to, range_t &info,
dump.outdent ();
}
+/* Return the prefix to use for dumping a #pragma diagnostic change to DK. */
+
+static const char *
+dk_string (diagnostic_t dk)
+{
+ gcc_assert (dk > DK_UNSPECIFIED && dk < DK_LAST_DIAGNOSTIC_KIND);
+ if (dk == DK_IGNORED)
+ /* diagnostic.def has an empty string for ignored. */
+ return "ignored: ";
+ else
+ return get_diagnostic_kind_text (dk);
+}
+
+/* Dump one #pragma GCC diagnostic entry. */
+
+static bool
+dump_dc_change (unsigned index, unsigned opt, diagnostic_t dk)
+{
+ if (dk == DK_POP)
+ return dump (" Index %u: pop from %d", index, opt);
+ else
+ return dump (" Index %u: %s%s", index, dk_string (dk),
+ cl_options[opt].opt_text);
+}
+
+/* Write out any #pragma GCC diagnostic info to the .dgc section. */
+
+void
+module_state::write_diagnostic_classification (elf_out *to,
+ diagnostic_context *dc,
+ unsigned *crc_p)
+{
+ auto &changes = dc->get_classification_history ();
+
+ bytes_out sec (to);
+ if (sec.streaming_p ())
+ {
+ sec.begin ();
+ dump () && dump ("Writing diagnostic change locations");
+ dump.indent ();
+ }
+
+ unsigned len = changes.length ();
+
+ /* We don't want to write out any entries that came from one of our imports.
+ But then we need to adjust the total, and change DK_POP targets to match
+ the index in our actual output. So remember how many lines we had skipped
+ at each step, where -1 means this line itself is skipped. */
+ int skips = 0;
+ auto_vec<int> skips_at (len);
+ skips_at.safe_grow (len);
+
+ for (unsigned i = 0; i < len; ++i)
+ {
+ const auto &c = changes[i];
+ skips_at[i] = skips;
+ if (linemap_location_from_module_p (line_table, c.location))
+ {
+ ++skips;
+ skips_at[i] = -1;
+ continue;
+ }
+ }
+
+ if (sec.streaming_p ())
+ {
+ sec.u (len - skips);
+ dump () && dump ("Diagnostic changes: %u", len - skips);
+ }
+
+ for (unsigned i = 0; i < len; ++i)
+ {
+ if (skips_at[i] == -1)
+ continue;
+
+ const auto &c = changes[i];
+ write_location (sec, c.location);
+ if (sec.streaming_p ())
+ {
+ unsigned opt = c.option;
+ if (c.kind == DK_POP)
+ opt -= skips_at[opt];
+ sec.u (opt);
+ sec.u (c.kind);
+ dump () && dump_dc_change (i - skips_at[i], opt, c.kind);
+ }
+ }
+
+ if (sec.streaming_p ())
+ {
+ sec.end (to, to->name (MOD_SNAME_PFX ".dgc"), crc_p);
+ dump.outdent ();
+ }
+}
+
+/* Read any #pragma GCC diagnostic info from the .dgc section. */
+
+bool
+module_state::read_diagnostic_classification (diagnostic_context *dc)
+{
+ bytes_in sec;
+
+ if (!sec.begin (loc, from (), MOD_SNAME_PFX ".dgc"))
+ return false;
+
+ dump () && dump ("Reading diagnostic change locations");
+ dump.indent ();
+
+ unsigned len = sec.u ();
+ dump () && dump ("Diagnostic changes: %u", len);
+
+ auto &changes = dc->get_classification_history ();
+ int offset = changes.length ();
+ changes.reserve (len + 1);
+ for (unsigned i = 0; i < len; ++i)
+ {
+ location_t loc = read_location (sec);
+ int opt = sec.u ();
+ diagnostic_t kind = (diagnostic_t) sec.u ();
+ if (kind == DK_POP)
+ /* For a pop, opt is the 'changes' index to return to. */
+ opt += offset;
+ changes.quick_push ({ loc, opt, kind });
+ dump () && dump_dc_change (changes.length () - 1, opt, kind);
+ }
+
+ /* Did the import pop all its diagnostic changes? */
+ bool last_was_reset = (len == 0);
+ if (len)
+ for (int i = changes.length () - 1; ; --i)
+ {
+ gcc_checking_assert (i >= offset);
+
+ const auto &c = changes[i];
+ if (c.kind != DK_POP)
+ break;
+ else if (c.option == offset)
+ {
+ last_was_reset = true;
+ break;
+ }
+ else
+ /* As in update_effective_level_from_pragmas, the loop will decrement
+ i so we actually jump to c.option - 1. */
+ i = c.option;
+ }
+ if (!last_was_reset)
+ {
+ /* It didn't, so add a pop at its last location to avoid affecting later
+ imports. */
+ location_t last_loc = ordinary_locs.first + ordinary_locs.second - 1;
+ changes.quick_push ({ last_loc, offset, DK_POP });
+ dump () && dump (" Adding final pop from index %d", offset);
+ }
+
+ dump.outdent ();
+ if (!sec.end (from ()))
+ return false;
+
+ return true;
+}
+
void
module_state::write_macro_maps (elf_out *to, range_t &info, unsigned *crc_p)
{
@@ -19853,6 +20019,8 @@ module_state::write_begin (elf_out *to, cpp_reader *reader,
}
ool->qsort (ool_cmp);
+ write_diagnostic_classification (nullptr, global_dc, nullptr);
+
vec<cpp_hashnode *> *macros = nullptr;
if (is_header ())
macros = prepare_macros (reader);
@@ -19998,7 +20166,10 @@ module_state::write_begin (elf_out *to, cpp_reader *reader,
/* Write the line maps. */
if (config.ordinary_locs)
- write_ordinary_maps (to, map_info, bool (config.num_partitions), &crc);
+ {
+ write_ordinary_maps (to, map_info, bool (config.num_partitions), &crc);
+ write_diagnostic_classification (to, global_dc, &crc);
+ }
if (config.macro_locs)
write_macro_maps (to, map_info, &crc);
@@ -20071,6 +20242,10 @@ module_state::read_initial (cpp_reader *reader)
else if (!read_ordinary_maps (config.ordinary_locs, config.loc_range_bits))
ok = false;
+ if (ok && have_locs && config.ordinary_locs
+ && !read_diagnostic_classification (global_dc))
+ ok = false;
+
/* Allocate the REMAP vector. */
slurp->alloc_remap (config.num_imports);
diff --git a/gcc/dfp.cc b/gcc/dfp.cc
index 5c2bf1a..74e9642 100644
--- a/gcc/dfp.cc
+++ b/gcc/dfp.cc
@@ -619,11 +619,21 @@ decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
decNumber dn, dn2, dn3;
REAL_VALUE_TYPE to;
char string[256];
+ int scale = 0;
decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0;
set.round = DEC_ROUND_DOWN;
decimal128ToNumber ((const decimal128 *) r->sig, &dn);
+ if (precision > 64 && decNumberIsFinite (&dn) && dn.exponent > 0)
+ {
+ /* libdecNumber doesn't really handle too large integers.
+ So when precision is large and exponent as well, trim the
+ exponent and adjust the resulting wide_int by multiplying
+ it multiple times with powers of ten. */
+ scale = dn.exponent;
+ dn.exponent = 0;
+ }
decNumberToIntegralValue (&dn2, &dn, &set);
decNumberZero (&dn3);
@@ -633,7 +643,74 @@ decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
function. */
decNumberToString (&dn, string);
real_from_string (&to, string);
- return real_to_integer (&to, fail, precision);
+ bool failp = false;
+ wide_int w = real_to_integer (&to, &failp, precision);
+ if (failp)
+ *fail = true;
+ if (scale && !failp)
+ {
+ bool isneg = wi::neg_p (w);
+ if (isneg)
+ w = -w;
+ enum wi::overflow_type ovf = wi::OVF_NONE;
+ unsigned HOST_WIDE_INT pow10s[] = {
+ HOST_WIDE_INT_UC (10),
+ HOST_WIDE_INT_UC (100),
+ HOST_WIDE_INT_UC (1000),
+ HOST_WIDE_INT_UC (10000),
+ HOST_WIDE_INT_UC (100000),
+ HOST_WIDE_INT_UC (1000000),
+ HOST_WIDE_INT_UC (10000000),
+ HOST_WIDE_INT_UC (100000000),
+ HOST_WIDE_INT_UC (1000000000),
+ HOST_WIDE_INT_UC (10000000000),
+ HOST_WIDE_INT_UC (100000000000),
+ HOST_WIDE_INT_UC (1000000000000),
+ HOST_WIDE_INT_UC (10000000000000),
+ HOST_WIDE_INT_UC (100000000000000),
+ HOST_WIDE_INT_UC (1000000000000000),
+ HOST_WIDE_INT_UC (10000000000000000),
+ HOST_WIDE_INT_UC (100000000000000000),
+ HOST_WIDE_INT_UC (1000000000000000000),
+ HOST_WIDE_INT_UC (10000000000000000000),
+ };
+ int s = scale % 19;
+ if (s)
+ {
+ wide_int wm = wi::uhwi (pow10s[s - 1], w.get_precision ());
+ w = wi::umul (w, wm, &ovf);
+ if (ovf)
+ scale = 0;
+ }
+ scale /= 19;
+ wide_int wm = wi::uhwi (pow10s[18], w.get_precision ());
+ while (scale)
+ {
+ if (scale & 1)
+ {
+ w = wi::umul (w, wm, &ovf);
+ if (ovf)
+ break;
+ }
+ scale >>= 1;
+ if (!scale)
+ break;
+ wm = wi::umul (wm, wm, &ovf);
+ if (ovf)
+ break;
+ }
+ if (ovf)
+ {
+ *fail = true;
+ if (isneg)
+ return wi::set_bit_in_zero (precision - 1, precision);
+ else
+ return ~wi::set_bit_in_zero (precision - 1, precision);
+ }
+ if (isneg)
+ w = -w;
+ }
+ return w;
}
/* Perform the decimal floating point operation described by CODE.
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index cdd6f26..b6cab0d 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -307,6 +307,9 @@ private:
diagnostic. */
vec<diagnostic_classification_change_t> m_classification_history;
+ /* For diagnostic_context::get_classification_history, declared later. */
+ friend class diagnostic_context;
+
/* For pragma push/pop. */
vec<int> m_push_list;
};
@@ -830,6 +833,13 @@ public:
m_abort_on_error = val;
}
+ /* Accessor for use in serialization, e.g. by C++ modules. */
+ auto &
+ get_classification_history ()
+ {
+ return m_option_classifier.m_classification_history;
+ }
+
private:
void error_recursion () ATTRIBUTE_NORETURN;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index e4f3cc2..69c6512 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -10668,7 +10668,7 @@ and @samp{[[omp::sequence(...)]]} in C and C++,
GCC needs to be invoked with the @option{-fopenmp} option.
This option also arranges for automatic linking of the OpenMP
runtime library.
-@xref{,,,libgomp,GNU Offloading and Multi Processing Runtime Library}.
+@xref{Top,,,libgomp,GNU Offloading and Multi Processing Runtime Library}.
@xref{OpenMP and OpenACC Options}, for additional options useful with
@option{-fopenmp}.
@@ -10690,7 +10690,7 @@ To enable the processing of OpenACC directives @samp{#pragma acc}
in C and C++, GCC needs to be invoked with the @option{-fopenacc} option.
This option also arranges for automatic linking of the OpenACC runtime
library.
-@xref{,,,libgomp,GNU Offloading and Multi Processing Runtime Library}.
+@xref{Top,,,libgomp,GNU Offloading and Multi Processing Runtime Library}.
@xref{OpenMP and OpenACC Options}, for additional options useful with
@option{-fopenacc}.
diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index 8bf87a2..ecf147a 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -1077,7 +1077,7 @@ condition 1 not covered (true)
-: 12:@}
@end smallexample
-@anchor {gcov prime paths example}
+@anchor{gcov prime paths example}
When you compile with @option{--coverage -fpath-coverage} and use the
option @option{-e} your output looks like this:
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 34e35a2..80ee2cd 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -631,6 +631,9 @@ building the documentation without error, but you may still want to
install a newer release to get the best appearance and usability of
the generated manuals.
+Also note that Texinfo older than version 7.1 may throw incorrect build
+warnings, though the generated documentation is correct.
+
@item @TeX{} (any working version)
Necessary for running @command{texi2dvi} and @command{texi2pdf}, which
diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index e640329..f4fc92b 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -975,8 +975,9 @@ validate_subreg (machine_mode omode, machine_mode imode,
/* Verify that the offset is representable. */
- /* For hard registers, we already have most of these rules collected in
- subreg_offset_representable_p. */
+ /* Ensure that subregs of hard registers can be folded. In other words,
+ the hardware register must be valid in the subreg's outer mode,
+ and consequently the subreg can be replaced with a hardware register. */
if (reg && REG_P (reg) && HARD_REGISTER_P (reg))
{
unsigned int regno = REGNO (reg);
@@ -987,7 +988,9 @@ validate_subreg (machine_mode omode, machine_mode imode,
else if (!REG_CAN_CHANGE_MODE_P (regno, imode, omode))
return false;
- return subreg_offset_representable_p (regno, imode, offset, omode);
+ /* Pass true to allow_stack_regs because targets like x86
+ expect to be able to take subregs of the stack pointer. */
+ return simplify_subreg_regno (regno, imode, offset, omode, true) >= 0;
}
/* Do not allow normal SUBREG with stricter alignment than the inner MEM.
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index fb84921..9a5ffb9 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,18 @@
+2025-06-19 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/120713
+ * trans-array.cc (gfc_trans_deferred_array): Statically
+ initialize deferred length variable for SAVEd character arrays.
+
+2025-06-18 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/82480
+ * check.cc (gfc_check_fstat): Extend checks to INTENT(OUT) arguments.
+ (gfc_check_fstat_sub): Likewise.
+ (gfc_check_stat): Likewise.
+ (gfc_check_stat_sub): Likewise.
+ * intrinsic.texi: Adjust documentation.
+
2025-06-16 Harald Anlauf <anlauf@gmx.de>
PR fortran/51961
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index c8904df..838d523 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -6507,7 +6507,7 @@ gfc_check_fseek_sub (gfc_expr *unit, gfc_expr *offset, gfc_expr *whence, gfc_exp
bool
-gfc_check_fstat (gfc_expr *unit, gfc_expr *array)
+gfc_check_fstat (gfc_expr *unit, gfc_expr *values)
{
if (!type_check (unit, 0, BT_INTEGER))
return false;
@@ -6515,11 +6515,17 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array)
if (!scalar_check (unit, 0))
return false;
- if (!type_check (array, 1, BT_INTEGER)
+ if (!type_check (values, 1, BT_INTEGER)
|| !kind_value_check (unit, 0, gfc_default_integer_kind))
return false;
- if (!array_check (array, 1))
+ if (!array_check (values, 1))
+ return false;
+
+ if (!variable_check (values, 1, false))
+ return false;
+
+ if (!array_size_check (values, 1, 13))
return false;
return true;
@@ -6527,19 +6533,9 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array)
bool
-gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status)
+gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *values, gfc_expr *status)
{
- if (!type_check (unit, 0, BT_INTEGER))
- return false;
-
- if (!scalar_check (unit, 0))
- return false;
-
- if (!type_check (array, 1, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
- return false;
-
- if (!array_check (array, 1))
+ if (!gfc_check_fstat (unit, values))
return false;
if (status == NULL)
@@ -6552,6 +6548,9 @@ gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status)
if (!scalar_check (status, 2))
return false;
+ if (!variable_check (status, 2, false))
+ return false;
+
return true;
}
@@ -6589,18 +6588,24 @@ gfc_check_ftell_sub (gfc_expr *unit, gfc_expr *offset)
bool
-gfc_check_stat (gfc_expr *name, gfc_expr *array)
+gfc_check_stat (gfc_expr *name, gfc_expr *values)
{
if (!type_check (name, 0, BT_CHARACTER))
return false;
if (!kind_value_check (name, 0, gfc_default_character_kind))
return false;
- if (!type_check (array, 1, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
+ if (!type_check (values, 1, BT_INTEGER)
+ || !kind_value_check (values, 1, gfc_default_integer_kind))
return false;
- if (!array_check (array, 1))
+ if (!array_check (values, 1))
+ return false;
+
+ if (!variable_check (values, 1, false))
+ return false;
+
+ if (!array_size_check (values, 1, 13))
return false;
return true;
@@ -6608,30 +6613,24 @@ gfc_check_stat (gfc_expr *name, gfc_expr *array)
bool
-gfc_check_stat_sub (gfc_expr *name, gfc_expr *array, gfc_expr *status)
+gfc_check_stat_sub (gfc_expr *name, gfc_expr *values, gfc_expr *status)
{
- if (!type_check (name, 0, BT_CHARACTER))
- return false;
- if (!kind_value_check (name, 0, gfc_default_character_kind))
- return false;
-
- if (!type_check (array, 1, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
- return false;
-
- if (!array_check (array, 1))
+ if (!gfc_check_stat (name, values))
return false;
if (status == NULL)
return true;
if (!type_check (status, 2, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
+ || !kind_value_check (status, 2, gfc_default_integer_kind))
return false;
if (!scalar_check (status, 2))
return false;
+ if (!variable_check (status, 2, false))
+ return false;
+
return true;
}
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 5831995..3103da3 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -7001,9 +7001,11 @@ Subroutine, function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{UNIT} @tab An open I/O unit number of type @code{INTEGER}.
-@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
-@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}. Returns 0
-on success and a system specific error code otherwise.
+@item @var{VALUES} @tab The type shall be @code{INTEGER, DIMENSION(13)}
+of the default kind.
+@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER}
+of the default kind.
+Returns 0 on success and a system specific error code otherwise.
@end multitable
@item @emph{Example}:
@@ -10306,8 +10308,10 @@ Subroutine, function
@multitable @columnfractions .15 .70
@item @var{NAME} @tab The type shall be @code{CHARACTER} of the default
kind, a valid path within the file system.
-@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
-@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}.
+@item @var{VALUES} @tab The type shall be @code{INTEGER, DIMENSION(13)}
+of the default kind.
+@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER}
+of the default kind.
Returns 0 on success and a system specific error code otherwise.
@end multitable
@@ -14391,6 +14395,8 @@ The elements that are obtained and stored in the array @code{VALUES}:
Not all these elements are relevant on all systems.
If an element is not relevant, it is returned as 0.
+If the value of an element would overflow the range of default integer,
+a -1 is returned instead.
This intrinsic is provided in both subroutine and function forms; however,
only one form can be used in any given program unit.
@@ -14402,9 +14408,11 @@ Subroutine, function
@multitable @columnfractions .15 .70
@item @var{NAME} @tab The type shall be @code{CHARACTER}, of the
default kind and a valid path within the file system.
-@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
-@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}. Returns 0
-on success and a system specific error code otherwise.
+@item @var{VALUES} @tab The type shall be @code{INTEGER, DIMENSION(13)}
+of the default kind.
+@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER}
+of the default kind.
+Returns 0 on success and a system specific error code otherwise.
@end multitable
@item @emph{Example}:
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 9606131..3d27443 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -12067,8 +12067,16 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
&& !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
{
if (sym->ts.deferred && !sym->ts.u.cl->length && !sym->attr.dummy)
- gfc_add_modify (&init, sym->ts.u.cl->backend_decl,
- build_zero_cst (TREE_TYPE (sym->ts.u.cl->backend_decl)));
+ {
+ tree len_expr = sym->ts.u.cl->backend_decl;
+ tree init_val = build_zero_cst (TREE_TYPE (len_expr));
+ if (VAR_P (len_expr)
+ && sym->attr.save
+ && !DECL_INITIAL (len_expr))
+ DECL_INITIAL (len_expr) = init_val;
+ else
+ gfc_add_modify (&init, len_expr, init_val);
+ }
gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
gfc_trans_vla_type_sizes (sym, &init);
diff --git a/gcc/function.cc b/gcc/function.cc
index a5b245a..a3a74b4 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -2937,7 +2937,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
if (stack_parm == 0)
{
HOST_WIDE_INT parm_align
- = (STRICT_ALIGNMENT
+ = ((STRICT_ALIGNMENT || BITS_PER_WORD <= MAX_SUPPORTED_STACK_ALIGNMENT)
? MAX (DECL_ALIGN (parm), BITS_PER_WORD) : DECL_ALIGN (parm));
SET_DECL_ALIGN (parm, parm_align);
diff --git a/gcc/gimple-crc-optimization.cc b/gcc/gimple-crc-optimization.cc
index a98cbe6..1751be9 100644
--- a/gcc/gimple-crc-optimization.cc
+++ b/gcc/gimple-crc-optimization.cc
@@ -1261,15 +1261,12 @@ crc_optimization::optimize_crc_loop (gphi *output_crc)
loc = EXPR_LOCATION (phi_result);
/* Add IFN call and write the return value in the phi_result. */
- gcall *call
- = gimple_build_call_internal (ifn, 3,
- m_crc_arg,
- m_data_arg,
- polynomial_arg);
+ gcall *call = gimple_build_call_internal (ifn, 3, m_crc_arg, m_data_arg,
+ polynomial_arg);
gimple_call_set_lhs (call, phi_result);
gimple_set_location (call, loc);
- gimple_stmt_iterator si = gsi_start_bb (output_crc->bb);
+ gimple_stmt_iterator si = gsi_after_labels (gimple_bb (output_crc));
gsi_insert_before (&si, call, GSI_SAME_STMT);
/* Remove phi statement, which was holding CRC result. */
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog
index 1037f5c..e5c4264 100644
--- a/gcc/m2/ChangeLog
+++ b/gcc/m2/ChangeLog
@@ -1,3 +1,25 @@
+2025-06-17 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/120673
+ * gm2-compiler/M2GCCDeclare.mod (ErrorDepList): New
+ global variable set containing every errant dependency symbol.
+ (mystop): Remove.
+ (EmitCircularDependancyError): Replace with ...
+ (EmitCircularDependencyError): ... this.
+ (AssertAllTypesDeclared): Rewrite.
+ (DoVariableDeclaration): Ditto.
+ (TypeDependentsDeclared): New procedure function.
+ (PrepareGCCVarDeclaration): Ditto.
+ (DeclareVariable): Remove assert.
+ (DeclareLocalVariable): Ditto.
+ (Constructor): Initialize ErrorDepList.
+ * gm2-compiler/M2MetaError.mod (doErrorScopeProc): Rewrite
+ and ensure that a symbol with a module scope does not lookup
+ from a definition module.
+ * gm2-compiler/P2SymBuild.mod (BuildType): Rewrite so that
+ a synonym type is created using the token refering to the name
+ on the lhs.
+
2025-06-12 Gaius Mulley <gaiusmod2@gmail.com>
PR modula2/119650
diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
index b12add6..be80695 100644
--- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod
+++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
@@ -251,6 +251,7 @@ TYPE
VAR
FreeGroup,
GlobalGroup : Group ; (* The global group of all sets. *)
+ ErrorDepList, (* The set of symbols with dependency errors. *)
VisitedList,
ChainedList : Set ;
HaveInitDefaultTypes: BOOLEAN ; (* Have we initialized them yet? *)
@@ -261,9 +262,6 @@ VAR
enumDeps : BOOLEAN ;
-PROCEDURE mystop ; BEGIN END mystop ;
-
-
(* *************************************************** *)
(*
PrintNum -
@@ -1315,14 +1313,26 @@ END CanBeDeclaredPartiallyViaPartialDependants ;
(*
- EmitCircularDependancyError - issue a dependancy error.
+ EmitCircularDependencyError - issue a dependency error.
*)
-PROCEDURE EmitCircularDependancyError (sym: CARDINAL) ;
+PROCEDURE EmitCircularDependencyError (sym: CARDINAL) ;
BEGIN
- MetaError1('circular dependancy error found when trying to resolve {%1Uad}',
- sym)
-END EmitCircularDependancyError ;
+ (* Ensure we only issue one dependency message per symbol for this
+ error classification. *)
+ IF NOT IsElementInSet (ErrorDepList, sym)
+ THEN
+ IncludeElementIntoSet (ErrorDepList, sym) ;
+ IF IsVar (sym) OR IsParameter (sym)
+ THEN
+ MetaError1 ('circular dependency error found when trying to resolve {%1Had}',
+ sym)
+ ELSE
+ MetaError1 ('circular dependency error found when trying to resolve {%1Dad}',
+ sym)
+ END
+ END
+END EmitCircularDependencyError ;
TYPE
@@ -1529,17 +1539,17 @@ BEGIN
IF ForeachTryDeclare (todolist,
circulartodo,
NotAllDependantsFullyDeclared,
- EmitCircularDependancyError)
+ EmitCircularDependencyError)
THEN
ELSIF ForeachTryDeclare (partiallydeclared,
circularpartial,
NotAllDependantsPartiallyDeclared,
- EmitCircularDependancyError)
+ EmitCircularDependencyError)
THEN
ELSIF ForeachTryDeclare (niltypedarrays,
circularniltyped,
NotAllDependantsPartiallyDeclared,
- EmitCircularDependancyError)
+ EmitCircularDependencyError)
THEN
END
END ;
@@ -2855,13 +2865,8 @@ BEGIN
n := 1 ;
Var := GetNth(scope, n) ;
WHILE Var#NulSym DO
- IF NOT AllDependantsFullyDeclared(GetSType(Var))
- THEN
- mystop
- END ;
- IF NOT AllDependantsFullyDeclared(GetSType(Var))
+ IF NOT TypeDependentsDeclared (Var, TRUE)
THEN
- EmitCircularDependancyError(GetSType(Var)) ;
failed := TRUE
END ;
INC(n) ;
@@ -3411,15 +3416,55 @@ PROCEDURE DoVariableDeclaration (var: CARDINAL; name: ADDRESS;
isImported, isExported,
isTemporary, isGlobal: BOOLEAN;
scope: tree) ;
+BEGIN
+ IF NOT (IsComponent (var) OR IsVarHeap (var))
+ THEN
+ IF TypeDependentsDeclared (var, TRUE)
+ THEN
+ PrepareGCCVarDeclaration (var, name, isImported, isExported,
+ isTemporary, isGlobal, scope)
+ END
+ END
+END DoVariableDeclaration ;
+
+
+(*
+ TypeDependentsDeclared - return TRUE if all type dependents of variable
+ have been declared.
+*)
+
+PROCEDURE TypeDependentsDeclared (variable: CARDINAL; errorMessage: BOOLEAN) : BOOLEAN ;
+VAR
+ type: CARDINAL ;
+BEGIN
+ type := GetSType (variable) ;
+ IF AllDependantsFullyDeclared (type)
+ THEN
+ RETURN TRUE
+ ELSE
+ IF errorMessage
+ THEN
+ EmitCircularDependencyError (variable) ;
+ ForeachElementInSetDo (GlobalGroup^.ToDoList, EmitCircularDependencyError)
+ END
+ END ;
+ RETURN FALSE
+END TypeDependentsDeclared ;
+
+
+(*
+ PrepareGCCVarDeclaration -
+*)
+
+PROCEDURE PrepareGCCVarDeclaration (var: CARDINAL; name: ADDRESS;
+ isImported, isExported,
+ isTemporary, isGlobal: BOOLEAN;
+ scope: tree) ;
VAR
type : tree ;
varType : CARDINAL ;
location: location_t ;
BEGIN
- IF IsComponent (var) OR IsVarHeap (var)
- THEN
- RETURN
- END ;
IF GetMode (var) = LeftValue
THEN
(*
@@ -3457,7 +3502,7 @@ BEGIN
isGlobal, scope, NIL)) ;
WatchRemoveList (var, todolist) ;
WatchIncludeList (var, fullydeclared)
-END DoVariableDeclaration ;
+END PrepareGCCVarDeclaration ;
(*
@@ -3493,7 +3538,6 @@ BEGIN
THEN
scope := FindContext (ModSym) ;
decl := FindOuterModule (variable) ;
- Assert (AllDependantsFullyDeclared (GetSType (variable))) ;
PushBinding (ModSym) ;
DoVariableDeclaration (variable,
KeyToCharStar (GetFullSymName (variable)),
@@ -3521,7 +3565,6 @@ BEGIN
THEN
scope := FindContext (mainModule) ;
decl := FindOuterModule (variable) ;
- Assert (AllDependantsFullyDeclared (GetSType (variable))) ;
PushBinding (mainModule) ;
DoVariableDeclaration (variable,
KeyToCharStar (GetFullSymName (variable)),
@@ -3618,7 +3661,6 @@ END DeclareImportedVariablesWholeProgram ;
PROCEDURE DeclareLocalVariable (var: CARDINAL) ;
BEGIN
- Assert (AllDependantsFullyDeclared (var)) ;
DoVariableDeclaration (var,
KeyToCharStar (GetFullSymName (var)),
FALSE, (* local variables cannot be imported *)
@@ -3662,7 +3704,6 @@ BEGIN
scope := Mod2Gcc (GetProcedureScope (sym)) ;
Var := GetNth (sym, i) ;
WHILE Var # NulSym DO
- Assert (AllDependantsFullyDeclared (GetSType (Var))) ;
DoVariableDeclaration (Var,
KeyToCharStar (GetFullSymName (Var)),
FALSE, (* inner module variables cannot be imported *)
@@ -6658,6 +6699,7 @@ END InitDeclarations ;
BEGIN
FreeGroup := NIL ;
GlobalGroup := InitGroup () ;
+ ErrorDepList := InitSet (1) ;
ChainedList := InitSet(1) ;
WatchList := InitSet(1) ;
VisitedList := NIL ;
diff --git a/gcc/m2/gm2-compiler/M2MetaError.mod b/gcc/m2/gm2-compiler/M2MetaError.mod
index 22bc77f..3aa7543 100644
--- a/gcc/m2/gm2-compiler/M2MetaError.mod
+++ b/gcc/m2/gm2-compiler/M2MetaError.mod
@@ -1437,35 +1437,22 @@ BEGIN
doError (eb, GetDeclaredDef (sym))
ELSE
M2Error.EnterErrorScope (GetErrorScope (scope)) ;
- IF IsProcedure (scope)
+ IF IsVar (sym) OR IsParameter (sym)
THEN
- IF IsVar (sym) OR IsParameter (sym)
- THEN
- doError (eb, GetVarParamTok (sym))
- ELSE
- doError (eb, GetDeclaredDef (sym))
- END
+ doError (eb, GetVarParamTok (sym))
+ ELSIF IsProcedure (scope)
+ THEN
+ doError (eb, GetDeclaredDef (sym))
+ ELSIF IsModule (scope)
+ THEN
+ doError (eb, GetDeclaredMod (sym))
ELSE
- IF IsModule (scope)
+ Assert (IsDefImp (scope)) ;
+ IF GetDeclaredDefinition (sym) = UnknownTokenNo
THEN
- IF IsInnerModule (scope)
- THEN
- doError (eb, GetDeclaredDef (sym))
- ELSE
- doError (eb, GetDeclaredDef (sym))
- END
+ doError (eb, GetDeclaredMod (sym))
ELSE
- Assert (IsDefImp (scope)) ;
- (* if this fails then we need to skip to the outer scope.
- REPEAT
- OuterModule := GetScope(OuterModule)
- UNTIL GetScope(OuterModule)=NulSym ; *)
- IF GetDeclaredDefinition (sym) = UnknownTokenNo
- THEN
- doError (eb, GetDeclaredMod (sym))
- ELSE
- doError (eb, GetDeclaredDef (sym))
- END
+ doError (eb, GetDeclaredDef (sym))
END
END
END ;
diff --git a/gcc/m2/gm2-compiler/P2SymBuild.mod b/gcc/m2/gm2-compiler/P2SymBuild.mod
index 8f3b499..5c82ec8 100644
--- a/gcc/m2/gm2-compiler/P2SymBuild.mod
+++ b/gcc/m2/gm2-compiler/P2SymBuild.mod
@@ -1225,7 +1225,8 @@ VAR
Sym,
Type : CARDINAL ;
name : Name ;
- tokno : CARDINAL ;
+ nametokno,
+ typetokno: CARDINAL ;
BEGIN
(*
Two cases
@@ -1234,8 +1235,8 @@ BEGIN
- when type with a name that is different to Name. In which case
we create a new type.
*)
- PopTtok(Type, tokno) ;
- PopT(name) ;
+ PopTtok (Type, typetokno) ;
+ PopTtok (name, nametokno) ;
IF Debugging
THEN
n1 := GetSymName(GetCurrentModule()) ;
@@ -1264,11 +1265,11 @@ BEGIN
*)
(* WriteString('Blank name type') ; WriteLn ; *)
- PushTFtok(Type, name, tokno) ;
+ PushTFtok(Type, name, typetokno) ;
Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
ELSIF IsError(Type)
THEN
- PushTFtok(Type, name, tokno) ;
+ PushTFtok(Type, name, typetokno) ;
Annotate("%1s(%1d)|%2n|%3d||error type|error type name|token no")
ELSIF GetSymName(Type)=name
THEN
@@ -1276,7 +1277,7 @@ BEGIN
IF isunknown OR
(NOT IsDeclaredIn(GetCurrentScope(), Type))
THEN
- Sym := MakeType(tokno, name) ;
+ Sym := MakeType (typetokno, name) ;
IF NOT IsError(Sym)
THEN
IF Sym=Type
@@ -1295,19 +1296,23 @@ BEGIN
CheckForEnumerationInCurrentModule(Type)
END
END ;
- PushTFtok(Sym, name, tokno) ;
+ PushTFtok(Sym, name, typetokno) ;
Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
ELSE
- PushTFtok(Type, name, tokno) ;
+ PushTFtok(Type, name, typetokno) ;
Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
END
ELSE
(* example TYPE a = CARDINAL *)
- Sym := MakeType(tokno, name) ;
- PutType(Sym, Type) ;
- CheckForExportedImplementation(Sym) ; (* May be an exported hidden type *)
- PushTFtok(Sym, name, tokno) ;
- Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
+ Sym := MakeType (nametokno, name) ;
+ PutType (Sym, Type) ;
+ CheckForExportedImplementation (Sym) ; (* May be an exported hidden type *)
+ PushTFtok (Sym, name, nametokno) ;
+ Annotate ("%1s(%1d)|%2n|%3d||type|type name|token no") ;
+ IF Debugging
+ THEN
+ MetaErrorT1 (nametokno, 'type pos {%1Wa}', Sym)
+ END
END
END BuildType ;
diff --git a/gcc/omp-offload.cc b/gcc/omp-offload.cc
index da2b54b..d88edb2 100644
--- a/gcc/omp-offload.cc
+++ b/gcc/omp-offload.cc
@@ -261,7 +261,8 @@ omp_discover_declare_target_tgt_fn_r (tree *tp, int *walk_subtrees, void *data)
DECL_ATTRIBUTES (decl)))
return NULL_TREE;
- if (!DECL_EXTERNAL (decl) && DECL_SAVED_TREE (decl))
+ if (DECL_SAVED_TREE (decl)
+ && (!DECL_EXTERNAL (decl) || DECL_DECLARED_INLINE_P (decl)))
((vec<tree> *) data)->safe_push (decl);
DECL_ATTRIBUTES (decl) = tree_cons (id, NULL_TREE,
DECL_ATTRIBUTES (decl));
diff --git a/gcc/prime-paths.cc b/gcc/prime-paths.cc
index 838343c..5b626ce 100644
--- a/gcc/prime-paths.cc
+++ b/gcc/prime-paths.cc
@@ -91,6 +91,8 @@ struct auto_sbitmap_vector
/* A silly RAII wrpaper for automatically releasing a vec<vec<int>>. */
struct auto_vec_vec : vec<vec<int>>
{
+ auto_vec_vec () = default;
+ auto_vec_vec (vec<vec<int>> v) : vec<vec<int>>(v) {}
~auto_vec_vec () { release_vec_vec (*this); }
};
@@ -635,7 +637,7 @@ trie::insert_with_suffix (array_slice<const int> path)
vec<vec<int>>
trie::paths () const
{
- vec<int> path {};
+ auto_vec<int> path {};
vec<vec<int>> all {};
auto iter = paths (path);
while (iter.next ())
@@ -1658,8 +1660,8 @@ test_split_components ()
int nscc = graphds_scc (cfg, NULL);
auto_graph ccfg (disconnect_sccs (cfg));
- vec<vec<int>> entries {};
- vec<vec<int>> exits {};
+ auto_vec_vec entries {};
+ auto_vec_vec exits {};
entries.safe_grow_cleared (nscc);
exits.safe_grow_cleared (nscc);
@@ -1707,7 +1709,7 @@ test_split_components ()
because other graph inconsistencies are easier to detect. */
/* Count and check singleton components. */
- vec<int> scc_size {};
+ auto_vec<int> scc_size {};
scc_size.safe_grow_cleared (nscc);
for (int i = 0; i != cfg->n_vertices; ++i)
scc_size[cfg->vertices[i].component]++;
@@ -1722,14 +1724,14 @@ test_split_components ()
/* Manually unroll the loop finding the simple paths starting at the
vertices in the SCCs. In this case there is only the one SCC. */
trie ccfg_paths;
- simple_paths (ccfg, ccfg_paths, 2);
- simple_paths (ccfg, ccfg_paths, 4);
- simple_paths (ccfg, ccfg_paths, 5);
- simple_paths (ccfg, ccfg_paths, 6);
- simple_paths (ccfg, ccfg_paths, 7);
- simple_paths (ccfg, ccfg_paths, 9);
+ auto_vec_vec (simple_paths (ccfg, ccfg_paths, 2));
+ auto_vec_vec (simple_paths (ccfg, ccfg_paths, 4));
+ auto_vec_vec (simple_paths (ccfg, ccfg_paths, 5));
+ auto_vec_vec (simple_paths (ccfg, ccfg_paths, 6));
+ auto_vec_vec (simple_paths (ccfg, ccfg_paths, 7));
+ auto_vec_vec (simple_paths (ccfg, ccfg_paths, 9));
/* Then in+out of trie. */
- vec<vec<int>> xscc_internal_pp = ccfg_paths.paths ();
+ auto_vec_vec xscc_internal_pp = ccfg_paths.paths ();
trie scc_internal_pp;
for (auto &p : xscc_internal_pp)
scc_internal_pp.insert_with_suffix (p);
@@ -1782,7 +1784,7 @@ test_scc_internal_prime_paths ()
add_edge (scc, 9, 7);
add_edge (scc, 7, 2);
- vec<vec<int>> paths = prime_paths (scc, 100);
+ auto_vec_vec paths = prime_paths (scc, 100);
const int p01[] = { 5, 7, 2, 4, 6, 9 };
const int p02[] = { 4, 6, 9, 7, 2, 4 };
const int p03[] = { 2, 4, 6, 9, 7, 2 };
@@ -1806,7 +1808,6 @@ test_scc_internal_prime_paths ()
ASSERT_TRUE (any_equal_p (p09, paths));
ASSERT_TRUE (any_equal_p (p10, paths));
ASSERT_TRUE (any_equal_p (p11, paths));
- release_vec_vec (paths);
}
/* Test the entry/exit path helpers for the strongly connected component in
@@ -1825,13 +1826,13 @@ test_scc_entry_exit_paths ()
add_edge (scc, 7, 2);
trie scc_internal_trie;
- simple_paths (scc, scc_internal_trie, 2);
- simple_paths (scc, scc_internal_trie, 4);
- simple_paths (scc, scc_internal_trie, 5);
- simple_paths (scc, scc_internal_trie, 6);
- simple_paths (scc, scc_internal_trie, 7);
- simple_paths (scc, scc_internal_trie, 9);
- vec<vec<int>> scc_prime_paths = scc_internal_trie.paths ();
+ auto_vec_vec (simple_paths (scc, scc_internal_trie, 2));
+ auto_vec_vec (simple_paths (scc, scc_internal_trie, 4));
+ auto_vec_vec (simple_paths (scc, scc_internal_trie, 5));
+ auto_vec_vec (simple_paths (scc, scc_internal_trie, 6));
+ auto_vec_vec (simple_paths (scc, scc_internal_trie, 7));
+ auto_vec_vec (simple_paths (scc, scc_internal_trie, 9));
+ auto_vec_vec scc_prime_paths = scc_internal_trie.paths ();
trie entry_exits {};
scc_entry_exit_paths (scc_prime_paths, 2, 2, entry_exits);
@@ -1867,8 +1868,6 @@ test_scc_entry_exit_paths ()
ASSERT_EQ (count (entries), 2);
ASSERT_TRUE (contains (entries, p07));
ASSERT_TRUE (contains (entries, p08));
-
- release_vec_vec (scc_prime_paths);
}
static void
@@ -1893,7 +1892,7 @@ test_complete_prime_paths ()
for (graph_edge *e = cfg->vertices[i].succ; e; e = e->succ_next)
bitmap_set_bit (edges[e->src], e->dest);
- vec<trie> ccfg_paths {};
+ auto_vec<trie> ccfg_paths {};
ccfg_paths.safe_grow_cleared (6);
ccfg_paths[0].insert (array_slice <const int> (ccfg_single + 0, 1));
ccfg_paths[1].insert (array_slice <const int> (ccfg_single + 1, 1));
@@ -1997,7 +1996,7 @@ test_entry_prime_paths ()
exit_prime_paths.insert (ep03);
exit_prime_paths.insert (ep04);
- vec<int> sccs = binary_search_scc_map ();
+ auto_vec<int> sccs = binary_search_scc_map ();
trie epp = scc_entry_prime_paths (cfg, scc_entry_paths,
complete_prime_paths,
@@ -2022,14 +2021,13 @@ test_singleton_path ()
auto_graph cfg (new_graph (3));
add_edge (cfg, 0, 2);
add_edge (cfg, 2, 1);
- vec<vec<int>> paths = prime_paths (cfg, 100);
+ auto_vec_vec paths = prime_paths (cfg, 100);
ASSERT_EQ (paths.length (), 1);
ASSERT_EQ (paths[0].length (), 3);
ASSERT_EQ (paths[0][0], 0);
ASSERT_EQ (paths[0][1], 2);
ASSERT_EQ (paths[0][2], 1);
- release_vec_vec (paths);
}
void
diff --git a/gcc/real.cc b/gcc/real.cc
index 95a9332..1f987d4 100644
--- a/gcc/real.cc
+++ b/gcc/real.cc
@@ -101,7 +101,7 @@ static int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *);
-static void decimal_from_integer (REAL_VALUE_TYPE *);
+static void decimal_from_integer (REAL_VALUE_TYPE *, int);
static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
size_t);
@@ -2309,7 +2309,9 @@ real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
}
if (fmt.decimal_p ())
- decimal_from_integer (r);
+ /* We need at most one decimal digits for each 3 bits of input
+ precision. */
+ decimal_from_integer (r, val_in.get_precision () / 3);
if (fmt)
real_convert (r, fmt, r);
}
@@ -2364,12 +2366,21 @@ decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
/* Convert a real with an integral value to decimal float. */
static void
-decimal_from_integer (REAL_VALUE_TYPE *r)
+decimal_from_integer (REAL_VALUE_TYPE *r, int digits)
{
char str[256];
- decimal_integer_string (str, r, sizeof (str) - 1);
- decimal_real_from_string (r, str);
+ if (digits <= 256)
+ {
+ decimal_integer_string (str, r, sizeof (str) - 1);
+ decimal_real_from_string (r, str);
+ }
+ else
+ {
+ char *s = XALLOCAVEC (char, digits);
+ decimal_integer_string (s, r, digits - 1);
+ decimal_real_from_string (r, s);
+ }
}
/* Returns 10**2**N. */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 8a74021..5bd0bd4 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2506,7 +2506,8 @@ extern bool subreg_offset_representable_p (unsigned int, machine_mode,
poly_uint64, machine_mode);
extern unsigned int subreg_regno (const_rtx);
extern int simplify_subreg_regno (unsigned int, machine_mode,
- poly_uint64, machine_mode);
+ poly_uint64, machine_mode,
+ bool allow_stack_regs = false);
extern int lowpart_subreg_regno (unsigned int, machine_mode,
machine_mode);
extern unsigned int subreg_nregs (const_rtx);
diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc
index 239d669..87332ff 100644
--- a/gcc/rtlanal.cc
+++ b/gcc/rtlanal.cc
@@ -4245,11 +4245,16 @@ subreg_offset_representable_p (unsigned int xregno, machine_mode xmode,
can be simplified. Return -1 if the subreg can't be simplified.
- XREGNO is a hard register number. */
+ XREGNO is a hard register number. ALLOW_STACK_REGS is true if
+ we should allow subregs of stack_pointer_rtx, frame_pointer_rtx.
+ and arg_pointer_rtx (which are normally expected to be the unique
+ way of referring to their respective registers). */
+
int
simplify_subreg_regno (unsigned int xregno, machine_mode xmode,
- poly_uint64 offset, machine_mode ymode)
+ poly_uint64 offset, machine_mode ymode,
+ bool allow_stack_regs)
{
struct subreg_info info;
unsigned int yregno;
@@ -4260,20 +4265,23 @@ simplify_subreg_regno (unsigned int xregno, machine_mode xmode,
&& !REG_CAN_CHANGE_MODE_P (xregno, xmode, ymode))
return -1;
- /* We shouldn't simplify stack-related registers. */
- if ((!reload_completed || frame_pointer_needed)
- && xregno == FRAME_POINTER_REGNUM)
- return -1;
+ if (!allow_stack_regs)
+ {
+ /* We shouldn't simplify stack-related registers. */
+ if ((!reload_completed || frame_pointer_needed)
+ && xregno == FRAME_POINTER_REGNUM)
+ return -1;
- if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- && xregno == ARG_POINTER_REGNUM)
- return -1;
+ if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ && xregno == ARG_POINTER_REGNUM)
+ return -1;
- if (xregno == STACK_POINTER_REGNUM
- /* We should convert hard stack register in LRA if it is
- possible. */
- && ! lra_in_progress)
- return -1;
+ if (xregno == STACK_POINTER_REGNUM
+ /* We should convert hard stack register in LRA if it is
+ possible. */
+ && ! lra_in_progress)
+ return -1;
+ }
/* Try to get the register offset. */
subreg_get_info (xregno, xmode, offset, ymode, &info);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0a1bf3d..32e3a59 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,215 @@
+2025-06-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/120689
+ * gcc.target/i386/pr120689.c: New test.
+
+2025-06-19 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/120713
+ * gfortran.dg/save_alloc_character_1.f90: New test.
+
+2025-06-19 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/120427
+ * gcc.target/i386/cold-attribute-4.c: Compile with -Oz.
+ * gcc.target/i386/pr120427-1.c: New test.
+ * gcc.target/i386/pr120427-2.c: Likewise.
+ * gcc.target/i386/pr120427-3.c: Likewise.
+ * gcc.target/i386/pr120427-4.c: Likewise.
+
+2025-06-19 Dongyan Chen <chendongyan@isrc.iscas.ac.cn>
+
+ * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c: New test.
+
+2025-06-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120631
+ * gcc.dg/dfp/bitint-10.c: New test.
+ * gcc.dg/dfp/pr120631.c: New test.
+
+2025-06-19 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.target/riscv/zilsd-code-gen-split-subreg-1.c: New test.
+ * gcc.target/riscv/zilsd-code-gen-split-subreg-2.c: New test.
+
+2025-06-19 Lili Cui <lili.cui@intel.com>
+
+ PR target/120697
+ * gcc.target/i386/stack-clash-protection.c: New test.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/pr119039-1.c: Add space in search criteria.
+
+2025-06-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/115908
+ PR c++/118074
+ PR c++/95615
+ * g++.dg/coroutines/pr115908.C: Move to...
+ * g++.dg/coroutines/torture/pr115908.C: ...here.
+ * g++.dg/coroutines/torture/pr95615-02.C: Move to...
+ * g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C: ...here.
+ * g++.dg/coroutines/torture/pr95615-03.C: Move to...
+ * g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C: ...here.
+ * g++.dg/coroutines/torture/pr95615-01.C: Move to...
+ * g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C: ...here.
+ * g++.dg/coroutines/torture/pr95615-04.C: Move to...
+ * g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C: ...here.
+ * g++.dg/coroutines/torture/pr95615-05.C: Move to...
+ * g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C: ...here.
+ * g++.dg/coroutines/torture/pr95615.inc: Add more cases and ensure that the
+ code completes properly when no exceptions are thrown.
+ * g++.dg/coroutines/torture/pr95615-00-nothing-throws.C: New test.
+ * g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C: New test.
+ * g++.dg/coroutines/torture/pr95615-07-body-throws.C: New test.
+ * g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C: New test.
+ * g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C: New test.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/119039
+ * gcc.dg/pr119039-2.c: New.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/119039
+ * gcc.dg/pr119039-1.c: New.
+ * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust thread counts.
+
+2025-06-18 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/82480
+ * gfortran.dg/stat_3.f90: New test.
+
+2025-06-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120631
+ * gcc.dg/dfp/bitint-9.c: New test.
+
+2025-06-18 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c: Add asm check
+ for vmin.vx combine.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c: Ditto.
+
+2025-06-18 Pan Li <pan2.li@intel.com>
+
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c: Add asm check.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h: Add test
+ helper macros.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h: Add test
+ data for run test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c: New test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c: New test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c: New test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c: New test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c: New test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c: New test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c: New test.
+ * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c: New test.
+
+2025-06-18 Lili Cui <lili.cui@intel.com>
+ Michael Matz <matz@suse.de>
+
+ * gcc.target/x86_64/abi/callabi/leaf-2.c: Adjust the test.
+ * gcc.target/i386/interrupt-16.c: Likewise.
+ * gfortran.dg/guality/arg1.f90: Likewise.
+ * gcc.target/i386/avx10_2-comibf-1.c: Likewise.
+ * g++.target/i386/shrink_wrap_separate.C: New test.
+ * gcc.target/i386/shrink_wrap_separate_check_lea.c: Likewise.
+
+2025-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/120661
+ * gcc.dg/pr120661-1.c: New.
+ * gcc.dg/pr120661-2.c: New.
+
+2025-06-17 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/aggr8.ads: New test.
+
+2025-06-17 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/120673
+ * gm2/pim/fail/badmodvar.mod: New test.
+ * gm2/pim/fail/cyclictypes.mod: New test.
+ * gm2/pim/fail/cyclictypes2.mod: New test.
+ * gm2/pim/fail/cyclictypes4.mod: New test.
+
+2025-06-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * gcc.dg/tree-prof/afdo-vpt-earlyinline.c: New test.
+
+2025-06-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ * g++.dg/coroutines/assume.C: New test.
+
+2025-06-17 Umesh Kalappa <ukalappa.mips@gmail.com>
+
+ * gcc.target/riscv/zalrsc.c: New test.
+
+2025-06-17 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/modules/warn-spec-3_a.C: New test.
+ * g++.dg/modules/warn-spec-3_b.C: New test.
+ * g++.dg/modules/warn-spec-3_c.C: New test.
+
+2025-06-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/120677
+ * gcc.c-torture/execute/pr120677.c: New test.
+
+2025-06-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/113027
+ * gcc.target/aarch64/pr113027-1.c: New test.
+ * gcc.target/aarch64/pr113027-2.c: Likewise.
+ * gcc.target/aarch64/pr113027-3.c: Likewise.
+ * gcc.target/aarch64/pr113027-4.c: Likewise.
+ * gcc.target/aarch64/pr113027-5.c: Likewise.
+ * gcc.target/aarch64/pr113027-6.c: Likewise.
+ * gcc.target/aarch64/pr113027-7.c: Likewise.
+
+2025-06-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ * g++.dg/coroutines/unevaluated.C: New test.
+
+2025-06-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/120273
+ * g++.dg/coroutines/pr120273.C: New test.
+
+2025-06-17 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.target/riscv/jump-table-large-code-model.c: Adding
+ -fno-pie.
+ * gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c: Ditto.
+ * gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c: Ditto.
+
2025-06-16 Spencer Abson <spencer.abson@arm.com>
* gcc.target/aarch64/sve/pack_fcvt_signed_1.c: Disable the aarch64 vector
diff --git a/gcc/testsuite/g++.dg/coroutines/assume.C b/gcc/testsuite/g++.dg/coroutines/assume.C
new file mode 100644
index 0000000..d007386
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/assume.C
@@ -0,0 +1,40 @@
+// { dg-additional-options "-fsyntax-only -Wattributes" }
+
+#include <coroutine>
+
+struct awaitable {
+ awaitable (int n) : delay{n} {}
+
+ constexpr bool await_ready () const noexcept { return false; }
+ auto await_suspend (std::coroutine_handle<> h) const {
+ __builtin_abort ();
+ return false;
+ }
+ int await_resume() const noexcept {
+ return delay;
+ }
+
+ int delay;
+};
+
+struct Task {
+ struct promise_type {
+ promise_type() = default;
+ Task get_return_object() { return {}; }
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_always final_suspend() noexcept { return {}; }
+ void unhandled_exception() {}
+ void return_void () {}
+ awaitable yield_value (int v) { return {v}; }
+ };
+};
+
+int h () { return 5; }
+
+Task foo() noexcept {
+ int x = 5;
+ [[assume (x == 5)]];
+ [[assume (co_await awaitable{10})]]; // { dg-warning {assumption ignored because it contains an await-expression} }
+ [[assume ((h(),co_await awaitable{11}))]]; // { dg-warning {assumption ignored because it contains an await-expression} }
+ co_return;
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr115908.C b/gcc/testsuite/g++.dg/coroutines/torture/pr115908.C
index a40cece..ff562ef 100644
--- a/gcc/testsuite/g++.dg/coroutines/pr115908.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr115908.C
@@ -3,13 +3,8 @@
// With the changes to deal with CWG2563 (and PR119916) we now use the
// referenced promise in the return expression. It is quite reasonable
// for a body implementation to complete before control is returned to
-// the ramp - and in that case we would be creating the ramp return object
-// from an already-deleted promise object.
-// This is recognised to be a poor situation and resolution via a core
-// issue is planned.
-
-// In this test we explicitly trigger the circumstance mentioned above.
-// { dg-xfail-run-if "" { *-*-* } }
+// the ramp - so we need to ensure that the promise lifetime is extended
+// in that case, tested here.
#include <coroutine>
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-00-nothing-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-00-nothing-throws.C
new file mode 100644
index 0000000..07558f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-00-nothing-throws.C
@@ -0,0 +1,5 @@
+// { dg-do run }
+// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } }
+
+// Check that this completes correctly if nothing throws.
+#include "pr95615.inc"
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C
index 504c8b9..504c8b9 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C
index 90b6395..90b6395 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C
index baae030..baae030 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C
index 1b7f89f..1b7f89f 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C
index 1d302c8..1d302c8 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C
new file mode 100644
index 0000000..e57b471
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C
@@ -0,0 +1,7 @@
+// { dg-do run }
+// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } }
+
+#define INITIAL_AWAIT_RESUME_THROWS 1
+// This should reach unhandled_exception
+#define SHOULD_CALL_UNHANDLED_EXCEPTION 1
+#include "pr95615.inc"
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-07-body-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-07-body-throws.C
new file mode 100644
index 0000000..fb10599
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-07-body-throws.C
@@ -0,0 +1,7 @@
+// { dg-do run }
+// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } }
+
+#define BODY_THROWS 1
+// This should reach unhandled_exception
+#define SHOULD_CALL_UNHANDLED_EXCEPTION 1
+#include "pr95615.inc"
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C
new file mode 100644
index 0000000..6dc47bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C
@@ -0,0 +1,8 @@
+// { dg-do run }
+// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } }
+
+#define INITIAL_SUSPEND_THROWS 1
+// It should be irrelevant that unhandled_exception might throw, so we should
+// not call it.
+#define UNHANDLED_EXCEPTION_THROWS 1
+#include "pr95615.inc"
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C
new file mode 100644
index 0000000..838b2ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C
@@ -0,0 +1,10 @@
+// { dg-do run }
+// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } }
+
+#define BODY_THROWS 1
+// This should reach unhandled_exception...
+#define SHOULD_CALL_UNHANDLED_EXCEPTION 1
+// ... which will throw
+#define UNHANDLED_EXCEPTION_THROWS 1
+// and we should cleanup by calling destroy.
+#include "pr95615.inc"
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc b/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc
index b6f78fb..ab6731d 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc
@@ -1,127 +1,209 @@
-#if __has_include(<coroutine>)
#include <coroutine>
-#else
-#include <experimental/coroutine>
-namespace std {
- using namespace std::experimental;
-}
-#endif
-#include <cassert>
+#include <exception>
#include <cstdio>
#include <cstdlib>
-bool frame_live = false;
-bool promise_live = false;
-
-struct X {};
+#ifndef OUTPUT
+# define PRINT(X)
+# define PRINTF(...)
+#else
+//#include <iostream>
+# define PRINT(X) puts(X)
+//# define PRINT(X) std::cout << (X) << std::endl
+# define PRINTF(...) printf(__VA_ARGS__)
+#endif
+int frame_live = 0;
+int promise_live = 0;
int Y_live = 0;
int task_live = 0;
+int unhandled_exception_called = 0;
+
+struct X {};
struct Y
{
- Y () { std::puts("Y ()"); Y_live++; }
- Y (const Y&) { std::puts("Y (const Y&)"); Y_live++; }
- ~Y () { std::puts("~Y ()"); Y_live--; }
+ Y () {
+ PRINT("Y ()");
+ Y_live++;
+ }
+ Y (const Y&) {
+ PRINT("Y (const Y&)");
+ Y_live++;
+ }
+ ~Y () {
+ PRINT("~Y ()");
+ --Y_live;
+ }
};
struct task {
+ struct promise_type;
+ using coro_handle = std::coroutine_handle<promise_type>;
+ struct Z {
+ std::exception_ptr eptr;
+ coro_handle h;
+ };
struct promise_type {
void* operator new(size_t sz) {
- std::puts("operator new()");
- frame_live = true;
+ PRINT("operator new()");
+ frame_live++;
return ::operator new(sz);
}
- void operator delete(void* p, size_t sz) {
- std::puts("operator delete");
- frame_live = false;
- return ::operator delete(p, sz);
+ static void operator delete(void* p, size_t sz) {
+ PRINT("operator delete");
+ --frame_live;
+ ::operator delete(p, sz);
}
promise_type() {
- std::puts("promise_type()");
-#if PROMISE_CTOR_THROWS
+ PRINT("promise_type()");
+#ifdef PROMISE_CTOR_THROWS
throw X{};
#endif
promise_live = true;
}
~promise_type() {
- std::puts("~promise_type()");
- promise_live = false;
+ PRINT("~promise_type()");
+ --promise_live;
}
struct awaiter {
bool await_ready() {
-#if INITIAL_AWAIT_READY_THROWS
+ PRINT("initial await_ready()");
+#ifdef INITIAL_AWAIT_READY_THROWS
throw X{};
#endif
+// If we are testing the suspend infra, then suspend, otherwise continue
+// so that we can test later paths (effectively, suspend_never).
+#ifdef INITIAL_AWAIT_SUSPEND_THROWS
return false;
+#else
+ return true;
+#endif
}
void await_suspend(std::coroutine_handle<>) {
-#if INITIAL_AWAIT_SUSPEND_THROWS
+#ifdef INITIAL_AWAIT_SUSPEND_THROWS
throw X{};
#endif
}
void await_resume() {
-#if INITIAL_AWAIT_RESUME_THROWS
-// this would be caught by unhandled_exception () which is tested
-// elsewhere.
+ PRINT("initial await_resume()");
+#ifdef INITIAL_AWAIT_RESUME_THROWS
+// This should be caught by unhandled_exception ()
throw X{};
#endif
}
};
awaiter initial_suspend() {
-#if INITIAL_SUSPEND_THROWS
+ PRINT("initial_suspend()");
+#ifdef INITIAL_SUSPEND_THROWS
throw X{};
#endif
return {};
}
task get_return_object() {
- std::puts("get_return_object()");
-#if GET_RETURN_OBJECT_THROWS
+ PRINT("get_return_object()");
+#ifdef GET_RETURN_OBJECT_THROWS
throw X{};
#endif
return task{};
}
- std::suspend_never final_suspend() noexcept { return {}; }
- void return_void() noexcept {}
- void unhandled_exception() noexcept {
- std::puts("unhandled_exception()");
+ std::suspend_never final_suspend() noexcept {
+ PRINT("final_suspend()");
+ return {};
+ }
+ void return_void() {
+ PRINT("return_void()");
+ }
+ void unhandled_exception() {
+ PRINT("unhandled_exception()");
+ unhandled_exception_called++;
+#ifdef UNHANDLED_EXCEPTION_THROWS
+ Z z{std::current_exception(),coro_handle::from_promise(*this)};
+ throw z;
+ //throw coro_handle::from_promise(*this);
+#endif
}
};
+
+ task() noexcept {
+ PRINT("task()");
+ task_live++;
+ }
+ task(task&& t) noexcept {
+ PRINT("task(task&&)");
+ task_live++;
+ }
+ ~task() noexcept {
+ PRINT("~task()");
+ task_live--;
+ }
- task() { std::puts("task()"); task_live++; }
- ~task() { std::puts("~task()"); task_live--; }
- task(task&&) { std::puts("task(task&&)"); task_live++; }
};
task f(Y Val __attribute__((__unused__))) {
- co_return;
+ PRINT("f()");
+#ifdef BODY_THROWS
+ throw X{};
+#endif
+ co_return;
}
int main() {
- bool failed = false;
- Y Val;
- try {
- f(Val);
- } catch (X) {
- std::puts("caught X");
- if (task_live)
- std::puts("task live"), failed = true;
- if (promise_live)
- std::puts("promise live"), failed = true;
- if (frame_live)
- std::puts("frame live"), failed = true;
- }
-
+ bool failed = false;
+ Y Val;
+ try {
+ PRINT("try-block-s");
+ task tsk = f(Val);
+ PRINT("try-block-e");
+ } catch (X) {
+ PRINT("caught X");
+ } catch (task::Z& z) {
+ PRINTF("caught Z : %d\n",(bool)z.eptr);
+ if (z.h.done())
+ {
+ PRINT("done, cleaning up");
+ z.h.destroy ();
+ }
+ else
+ PRINT("not done?");
+ } catch (std::coroutine_handle<task::promise_type>& h) {
+ PRINT("caught handle");
+ if (h.done())
+ {
+ PRINT("done, cleaning up");
+ h.destroy ();
+ }
+ else
+ PRINT("not done?");
+ }
+
+ if (task_live)
+ failed = true, __builtin_printf("task still live\n") ;
+ if (promise_live)
+ failed = true, __builtin_printf("promise still live\n");
+ if (frame_live)
+ failed = true, __builtin_printf("frame still live : %d\n", frame_live);
if (Y_live != 1)
- std::printf("Y live %d\n", Y_live), failed = true;
+ failed = true, __builtin_printf("Y live count : %d\n", Y_live);
+#ifdef SHOULD_CALL_UNHANDLED_EXCEPTION
+ if (unhandled_exception_called != 1)
+ failed = true, __builtin_printf("unhandled exception : %d\n", unhandled_exception_called);
+#else
+ if (unhandled_exception_called != 0)
+ failed = true, __builtin_printf("unhandled exception : %d\n", unhandled_exception_called);
+#endif
+
+ __builtin_printf("checking result : %s \n",(failed?"bad":"good"));
+
+ fflush(stdout);
if (failed)
- abort() ;
+ __builtin_abort();
}
diff --git a/gcc/testsuite/g++.dg/coroutines/unevaluated.C b/gcc/testsuite/g++.dg/coroutines/unevaluated.C
new file mode 100644
index 0000000..63dae38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/unevaluated.C
@@ -0,0 +1,25 @@
+// { dg-additional-options "-fsyntax-only" }
+#include <typeinfo>
+#include <coroutine>
+
+struct Task {
+ struct promise_type {
+ promise_type() = default;
+ Task get_return_object() { return {}; }
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_always final_suspend() noexcept { return {}; }
+ void unhandled_exception() {}
+ void return_void () {}
+ std::suspend_never yield_value (int) { return {}; }
+ };
+};
+
+// We do not permit co_await, co_yield outside a function, and so uses in
+// noexcept or requirements are covered by that.
+Task foo() {
+ /* This one will currently fail - see PR68604. */
+ const std::type_info& ti1 = typeid (co_await std::suspend_never{}); // { dg-error {'co_await' cannot be used in an unevaluated context} "" { xfail *-*-* } }
+ std::size_t x = sizeof (co_yield (19)); // { dg-error {'co_yield' cannot be used in an unevaluated context} }
+ decltype (co_await std::suspend_never{}) A; // { dg-error {'co_await' cannot be used in an unevaluated context} }
+ co_return;
+}
diff --git a/gcc/testsuite/g++.dg/modules/warn-spec-3_a.C b/gcc/testsuite/g++.dg/modules/warn-spec-3_a.C
new file mode 100644
index 0000000..2e50303
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/warn-spec-3_a.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -fmodules }
+// { dg-module-cmi M }
+
+module;
+
+#include <initializer_list>
+
+export module M;
+
+#pragma GCC diagnostic ignored "-Winit-list-lifetime"
+
+template <class T>
+struct myspan {
+ const T* p; unsigned s;
+ myspan (std::initializer_list<T> il)
+ : p (il.begin()), s (il.size()) { }
+};
+
+export void f(myspan<int>);
diff --git a/gcc/testsuite/g++.dg/modules/warn-spec-3_b.C b/gcc/testsuite/g++.dg/modules/warn-spec-3_b.C
new file mode 100644
index 0000000..0a614f7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/warn-spec-3_b.C
@@ -0,0 +1,7 @@
+// { dg-additional-options "-fmodules -fdump-lang-module" }
+
+// Test that we don't re-export the changes from M.
+// { dg-final { scan-lang-dump {Diagnostic changes: 0} module } }
+
+export module N;
+import M;
diff --git a/gcc/testsuite/g++.dg/modules/warn-spec-3_c.C b/gcc/testsuite/g++.dg/modules/warn-spec-3_c.C
new file mode 100644
index 0000000..2e466c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/warn-spec-3_c.C
@@ -0,0 +1,12 @@
+// { dg-additional-options "-fmodules -fdump-lang-module" }
+
+// Test that we clean up the unpopped change in M.
+// { dg-final { scan-lang-dump {Adding final pop} module } }
+
+import N;
+import M;
+
+int main()
+{
+ f({24,42});
+}
diff --git a/gcc/testsuite/g++.target/i386/shrink_wrap_separate.C b/gcc/testsuite/g++.target/i386/shrink_wrap_separate.C
new file mode 100644
index 0000000..294dccd
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/shrink_wrap_separate.C
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */
+typedef struct a b;
+typedef double c;
+struct a {
+ b *d;
+ b *e;
+};
+struct f {
+ c g;
+};
+inline bool h(c i, b *m) {
+ b *j = m->e;
+ for (; m->e; j = j->d)
+ if (h(i, j))
+ return 0;
+ return m;
+}
+bool k() {
+ f *l;
+ b *n;
+ return h(l->g, n);
+}
+/* { dg-final { scan-rtl-dump "The components we wrap separately are \\\[sep 3 4\\\]" "pro_and_epilogue" { target { ia32 } } } } */
+/* { dg-final { scan-rtl-dump "The components we wrap separately are \\\[sep 40 41 42 43\\\]" "pro_and_epilogue" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr120677.c b/gcc/testsuite/gcc.c-torture/execute/pr120677.c
new file mode 100644
index 0000000..3cff04e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr120677.c
@@ -0,0 +1,31 @@
+/* PR tree-optimization/120677 */
+/* { dg-do run { target int32plus } } */
+
+unsigned a;
+int b, e;
+
+int
+foo (int d)
+{
+ switch (d)
+ {
+ case 0:
+ case 2:
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+int
+main ()
+{
+ for (b = 8; b; b--)
+ if (a & 1)
+ a = a >> 1 ^ 20000000;
+ else
+ a >>= 1;
+ e = foo (0);
+ if (e || a)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/bitint-10.c b/gcc/testsuite/gcc.dg/dfp/bitint-10.c
new file mode 100644
index 0000000..b48f0ea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/bitint-10.c
@@ -0,0 +1,49 @@
+/* PR middle-end/120631 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-O2" } */
+
+#if __BITINT_MAXWIDTH__ >= 128
+_Decimal128 a = 123456789135792468012345678900000000000.0dl;
+_BitInt(128) b = 123456789135792468012345678900000000000wb;
+_Decimal64 c = 12345678913579000000000000000000000000.0dd;
+_BitInt(127) d = 12345678913579000000000000000000000000wb;
+#endif
+#if __BITINT_MAXWIDTH__ >= 256
+_Decimal128 m = 1234567891357924680123456789000000000000000000000000000000000000000000000000.0dl;
+_BitInt(256) n = 1234567891357924680123456789000000000000000000000000000000000000000000000000wb;
+_Decimal64 o = 1234567891357900000000000000000000000000000000000000000000000000000000000000.0dd;
+_BitInt(255) p = 1234567891357900000000000000000000000000000000000000000000000000000000000000wb;
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 128
+ if (a != b || (_BitInt(128)) a != b || c != d || (_BitInt(127)) c != d)
+ __builtin_abort ();
+ _Decimal128 e = 123456789135792468012345678900000000000.0dl;
+ _BitInt(128) f = 123456789135792468012345678900000000000wb;
+ _Decimal128 g = 123456789135792468012345678900000000000wb;
+ _BitInt(128) h = 123456789135792468012345678900000000000.0dl;
+ _Decimal64 i = 12345678913579000000000000000000000000.0dd;
+ _BitInt(128) j = 12345678913579000000000000000000000000wb;
+ _Decimal64 k = 12345678913579000000000000000000000000wb;
+ _BitInt(128) l = 12345678913579000000000000000000000000.0dd;
+ if (e != g || f != h || i != k || j != l)
+ __builtin_abort ();
+#endif
+#if __BITINT_MAXWIDTH__ >= 256
+ if (m != n || (_BitInt(256)) m != n || o != p || (_BitInt(255)) o != p)
+ __builtin_abort ();
+ _Decimal128 q = 1234567891357924680123456789000000000000000000000000000000000000000000000000.0dl;
+ _BitInt(256) r = 1234567891357924680123456789000000000000000000000000000000000000000000000000wb;
+ _Decimal128 s = 1234567891357924680123456789000000000000000000000000000000000000000000000000wb;
+ _BitInt(256) t = 1234567891357924680123456789000000000000000000000000000000000000000000000000.0dl;
+ _Decimal64 u = 1234567891357900000000000000000000000000000000000000000000000000000000000000.0dd;
+ _BitInt(255) v = 1234567891357900000000000000000000000000000000000000000000000000000000000000wb;
+ _Decimal64 w = 1234567891357900000000000000000000000000000000000000000000000000000000000000wb;
+ _BitInt(255) x = 1234567891357900000000000000000000000000000000000000000000000000000000000000.0dd;
+ if (q != s || r != t || u != w || v != x)
+ __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/bitint-9.c b/gcc/testsuite/gcc.dg/dfp/bitint-9.c
new file mode 100644
index 0000000..72155a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/bitint-9.c
@@ -0,0 +1,29 @@
+/* PR middle-end/120631 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-O2" } */
+
+#if __BITINT_MAXWIDTH__ >= 2048
+_Decimal128 a = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dl;
+_BitInt(2048) b = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb;
+_Decimal64 c = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dd;
+_BitInt(1536) d = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb;
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 2048
+ if (a != b || (_BitInt(2048)) a != b || c != d || (_BitInt(1536)) c != d)
+ __builtin_abort ();
+ _Decimal128 e = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dl;
+ _BitInt(2048) f = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb;
+ _Decimal128 g = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb;
+ _BitInt(2048) h = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dl;
+ _Decimal64 i = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dd;
+ _BitInt(1536) j = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb;
+ _Decimal64 k = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb;
+ _BitInt(1536) l = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dd;
+ if (e != g || f != h || i != k || j != l)
+ __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/pr120631.c b/gcc/testsuite/gcc.dg/dfp/pr120631.c
new file mode 100644
index 0000000..2085ff7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/pr120631.c
@@ -0,0 +1,25 @@
+/* PR middle-end/120631 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+_Decimal64 a = 1234567891357900000.0dd;
+long long b = 1234567891357900000LL;
+_Decimal32 c = 1234567000000000000.0df;
+long long d = 1234567000000000000LL;
+
+int
+main ()
+{
+ if (a != b || (long long) a != b || c != d || (long long) c != d)
+ __builtin_abort ();
+ _Decimal64 e = 1234567891357900000.0dd;
+ long long f = 1234567891357900000LL;
+ _Decimal64 g = 1234567891357900000LL;
+ long long h = 1234567891357900000.0dd;
+ _Decimal32 i = 1234567000000000000.0df;
+ long long j = 1234567000000000000LL;
+ _Decimal32 k = 1234567000000000000LL;
+ long long l = 1234567000000000000.0df;
+ if (e != g || f != h || i != k || j != l)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/pr119039-1.c b/gcc/testsuite/gcc.dg/pr119039-1.c
new file mode 100644
index 0000000..f91d5eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119039-1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void foo (void);
+extern void bar (void);
+extern void baz (void);
+
+/* Tests the ability to remove cases that are subranges. */
+
+void
+test (int i)
+{
+ if (i < 0 || i > 45)
+ return;
+ if (i >= 7 && i <= 8)
+ return;
+
+ switch (i)
+ {
+ case 1:
+ bar ();
+ break;
+ case 7 ... 8:
+ foo ();
+ case 14:
+ baz ();
+ break;
+ default:
+ break;
+ }
+}
+/* { dg-final { scan-tree-dump-not "foo " "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr119039-2.c b/gcc/testsuite/gcc.dg/pr119039-2.c
new file mode 100644
index 0000000..634b400
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119039-2.c
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void good (void);
+extern void bad (void);
+
+/* Switch simplification should remove 'case 2:' because 'i' will always
+ * have its 0th bit set (odd). */
+
+void bitmask_elimination_1(int i)
+{
+ i = i | 1;
+
+ switch (i)
+ {
+ case 1:
+ good ();
+ break;
+
+ // This case should be removed;
+ case 2:
+ bad ();
+ break;
+
+ case 3:
+ good ();
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Switch simplification should remove 'case 20-28:' because 'i' will always
+ * be a multiple of 16. */
+void bitmask_elimination_2 (int i)
+{
+ int masked_val = i & 0xF0; // This zeroes out the lower 4 bits of 'i'
+
+ switch (masked_val)
+ {
+ case 0:
+ good (); // Reachable.
+ break;
+
+ // This entire cased should be removed;
+ case 20 ... 28:
+ bad ();
+ break;
+
+ case 32:
+ good (); // Reachable.
+ break;
+
+ default:
+ good ();
+ break;
+ }
+}
+/* { dg-final { scan-tree-dump-not "bad" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr120661-1.c b/gcc/testsuite/gcc.dg/pr120661-1.c
new file mode 100644
index 0000000..abf9210
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr120661-1.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -Os" } */
+
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+int e, a, b;
+int f(int b, ...) {
+ va_list args;
+ __builtin_c23_va_start(args, b);
+ unsigned c = 1;
+ for (int d; d < b; ++d)
+ c = c ^ 1;
+ return c;
+}
+static int fn3(int l, int i, int n) {
+ int j;
+ goto k;
+r:
+ j = (f(e) + 1641730381) * l + 1189664732 * n + 1064 * i - 1545337304;
+ if (903562339 * j + n >= 0)
+ goto m;
+ goto ac;
+k:
+ if (0)
+ goto ad;
+ goto t;
+ad:
+ if (b)
+ goto s;
+ goto r;
+m:
+ goto ad;
+t:
+ j = l;
+ l = 800794 * j;
+ goto ad;
+s:
+ b = 2 * b + 1;
+ if (a + (long)j)
+ goto t;
+ i = n;
+ goto s;
+ac:
+}
+int main() {
+ if (a)
+ if (fn3(-1, 1, -1))
+ fn3(1, 0, 3);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr120661-2.c b/gcc/testsuite/gcc.dg/pr120661-2.c
new file mode 100644
index 0000000..05d976d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr120661-2.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -O2" } */
+
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+int a, c, d;
+int e(int b, ...) {
+ va_list args;
+ __builtin_c23_va_start(args, b);
+
+ int r = 0;
+ for (int i = 0; i < b; i++) {
+ int v = __builtin_va_arg(args, int);
+ r += v;
+ }
+ __builtin_va_end (args);
+ return r;
+}
+int f() { e(0); }
+int main() {
+ int h = 0, g = 0;
+ goto l;
+i:
+ if (f() * h)
+ goto k;
+j:
+ h = h - 2;
+k:
+ d = 1200000000 * h + 10;
+ g = (long)g + -1000000000 * d + 1;
+ if (a * h >= 0) {
+ if (g + (c - (long)1) >= 0)
+ goto i;
+ return 0;
+ }
+l:
+ goto j;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr120654.c b/gcc/testsuite/gcc.dg/torture/pr120654.c
new file mode 100644
index 0000000..3819b78
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120654.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+int a, c, e, f, h, j;
+long g, k;
+void *malloc(long);
+void free(void *);
+int b(int m) {
+ if (m || a)
+ return 1;
+ return 0.0f;
+}
+int d(int m, int p2) { return b(m) + m + (1 + p2 + p2); }
+int i() {
+ long l[] = {2, 9, 7, 8, g, g, 9, 0, 2, g};
+ e = l[c] << 6;
+}
+void n() {
+ long o;
+ int *p = malloc(sizeof(int));
+ k = 1 % j;
+ for (; i() + f + h; o++)
+ if (p[d(j + 6, (int)k + 1992695866) + h + f + j + (int)k - 1 + o])
+ free(p);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/afdo-vpt-earlyinline.c b/gcc/testsuite/gcc.dg/tree-prof/afdo-vpt-earlyinline.c
new file mode 100644
index 0000000..3b51ea9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/afdo-vpt-earlyinline.c
@@ -0,0 +1,32 @@
+/* { dg-options "-O2 -fdump-ipa-afdo-details -fdump-tree-einline-details" } */
+/* { dg-require-profiling "-fauto-profile" } */
+
+volatile int array[1000];
+int reta (int i)
+{
+ return array[i];
+}
+struct wrapptr
+{
+ int (*ret)(int);
+};
+int test (struct wrapptr *p)
+{
+ int s = 0;
+ for (int pos = 0; pos < 1000; pos++)
+ s+p->ret(pos);
+ if (s)
+ __builtin_printf ("sum error\n");
+}
+int main()
+{
+ struct wrapptr p={reta};
+ for (int i = 0; i < 10000; i++)
+ test(&p);
+ return 0;
+}
+/* { dg-final-use-autofdo { scan-tree-dump "Inlining test" "einline"} } */
+/* { dg-final-use-autofdo { scan-ipa-dump "Checking indirect call -> direct call reta" "afdo"} } */
+/* { dg-final-use-autofdo { scan-ipa-dump "looks good" "afdo"} } */
+/* If we inlined reta->test->main, it will contian array[pos]. */
+/* { dg-final-use-autofdo { scan-ipa-dump "array.pos_" "afdo"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c
index 59891f2..1c2cfa4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c
@@ -11,8 +11,8 @@
to change decisions in switch expansion which in turn can expose new
jump threading opportunities. Skip the later tests on aarch64. */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */
-/* { dg-final { scan-tree-dump "Jumps threaded: 10" "thread2" { target { ! aarch64*-*-* } } } } */
-/* { dg-final { scan-tree-dump "Jumps threaded: 17" "thread2" { target { aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { ! aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { aarch64*-*-* } } } } */
enum STATE {
S0=0,
diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-1.c b/gcc/testsuite/gcc.target/aarch64/pr113027-1.c
new file mode 100644
index 0000000..6d9a51f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr113027-1.c
@@ -0,0 +1,27 @@
+/* { dg-options "-O2" } */
+
+#include <arm_neon.h>
+
+float64x2x2_t
+f1 (float64x2x2_t x)
+{
+ x.val[0][1] += 1.0;
+ return x;
+}
+
+float64x2x3_t
+f2 (float64x2x3_t x)
+{
+ x.val[0][0] = x.val[1][1] + x.val[2][0];
+ return x;
+}
+
+float64x2x4_t
+f3 (float64x2x4_t x)
+{
+ x.val[0][0] = x.val[1][1] + x.val[2][0] - x.val[3][1];
+ return x;
+}
+
+/* { dg-final { scan-assembler-not {\tmov\t} } } */
+/* { dg-final { scan-assembler-not {\[sp,} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-2.c b/gcc/testsuite/gcc.target/aarch64/pr113027-2.c
new file mode 100644
index 0000000..ec756ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr113027-2.c
@@ -0,0 +1,268 @@
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */
+
+#include <arm_neon.h>
+
+#define TEST(TYPE, A, B, C, D) \
+ TYPE \
+ test_##TYPE (TYPE a) \
+ { \
+ a.val[A][B] = a.val[C][D]; \
+ return a; \
+ }
+
+/*
+** test_bfloat16x4x2_t:
+** ins v1\.h\[3\], v0\.h\[2\]
+** ret
+*/
+TEST (bfloat16x4x2_t, 1, 3, 0, 2)
+
+/*
+** test_float16x4x2_t:
+** ins v1\.h\[1\], v0\.h\[3\]
+** ret
+*/
+TEST (float16x4x2_t, 1, 1, 0, 3)
+
+/*
+** test_float32x2x2_t:
+** ins v1\.s\[0\], v0\.s\[1\]
+** ret
+*/
+TEST (float32x2x2_t, 1, 0, 0, 1)
+
+/*
+** test_float64x1x2_t:
+** fmov d1, d0
+** ret
+*/
+TEST (float64x1x2_t, 1, 0, 0, 0)
+
+/*
+** test_int8x8x2_t:
+** ins v0\.b\[5\], v1\.b\[7\]
+** ret
+*/
+TEST (int8x8x2_t, 0, 5, 1, 7)
+
+/*
+** test_int16x4x2_t:
+** ins v0\.h\[2\], v1\.h\[2\]
+** ret
+*/
+TEST (int16x4x2_t, 0, 2, 1, 2)
+
+/*
+** test_int32x2x2_t:
+** ins v0\.s\[0\], v1\.s\[1\]
+** ret
+*/
+TEST (int32x2x2_t, 0, 0, 1, 1)
+
+/*
+** test_int64x1x2_t:
+** fmov d0, d1
+** ret
+*/
+TEST (int64x1x2_t, 0, 0, 1, 0)
+
+/*
+** test_uint8x8x2_t:
+** ins v1\.b\[6\], v0\.b\[3\]
+** ret
+*/
+TEST (uint8x8x2_t, 1, 6, 0, 3)
+
+/*
+** test_uint16x4x2_t:
+** ins v1\.h\[2\], v1\.h\[0\]
+** ret
+*/
+TEST (uint16x4x2_t, 1, 2, 1, 0)
+
+/*
+** test_uint32x2x2_t:
+** ins v1\.s\[0\], v1\.s\[1\]
+** ret
+*/
+TEST (uint32x2x2_t, 1, 0, 1, 1)
+
+/*
+** test_uint64x1x2_t:
+** fmov d1, d0
+** ret
+*/
+TEST (uint64x1x2_t, 1, 0, 0, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x4x3_t:
+** ins v2\.h\[3\], v0\.h\[2\]
+** ret
+*/
+TEST (bfloat16x4x3_t, 2, 3, 0, 2)
+
+/*
+** test_float16x4x3_t:
+** ins v0\.h\[1\], v1\.h\[3\]
+** ret
+*/
+TEST (float16x4x3_t, 0, 1, 1, 3)
+
+/*
+** test_float32x2x3_t:
+** ins v1\.s\[0\], v2\.s\[1\]
+** ret
+*/
+TEST (float32x2x3_t, 1, 0, 2, 1)
+
+/*
+** test_float64x1x3_t:
+** fmov d1, d2
+** ret
+*/
+TEST (float64x1x3_t, 1, 0, 2, 0)
+
+/*
+** test_int8x8x3_t:
+** ins v0\.b\[5\], v2\.b\[6\]
+** ret
+*/
+TEST (int8x8x3_t, 0, 5, 2, 6)
+
+/*
+** test_int16x4x3_t:
+** ins v2\.h\[2\], v1\.h\[1\]
+** ret
+*/
+TEST (int16x4x3_t, 2, 2, 1, 1)
+
+/*
+** test_int32x2x3_t:
+** ins v1\.s\[0\], v1\.s\[1\]
+** ret
+*/
+TEST (int32x2x3_t, 1, 0, 1, 1)
+
+/*
+** test_int64x1x3_t:
+** fmov d2, d1
+** ret
+*/
+TEST (int64x1x3_t, 2, 0, 1, 0)
+
+/*
+** test_uint8x8x3_t:
+** ins v1\.b\[6\], v2\.b\[7\]
+** ret
+*/
+TEST (uint8x8x3_t, 1, 6, 2, 7)
+
+/*
+** test_uint16x4x3_t:
+** ins v2\.h\[2\], v1\.h\[3\]
+** ret
+*/
+TEST (uint16x4x3_t, 2, 2, 1, 3)
+
+/*
+** test_uint32x2x3_t:
+** ins v2\.s\[0\], v0\.s\[1\]
+** ret
+*/
+TEST (uint32x2x3_t, 2, 0, 0, 1)
+
+/*
+** test_uint64x1x3_t:
+** fmov d1, d2
+** ret
+*/
+TEST (uint64x1x3_t, 1, 0, 2, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x4x4_t:
+** ins v2\.h\[3\], v3\.h\[2\]
+** ret
+*/
+TEST (bfloat16x4x4_t, 2, 3, 3, 2)
+
+/*
+** test_float16x4x4_t:
+** ins v0\.h\[2\], v3\.h\[1\]
+** ret
+*/
+TEST (float16x4x4_t, 0, 2, 3, 1)
+
+/*
+** test_float32x2x4_t:
+** ins v3\.s\[0\], v2\.s\[1\]
+** ret
+*/
+TEST (float32x2x4_t, 3, 0, 2, 1)
+
+/*
+** test_float64x1x4_t:
+** fmov d1, d3
+** ret
+*/
+TEST (float64x1x4_t, 1, 0, 3, 0)
+
+/*
+** test_int8x8x4_t:
+** ins v0\.b\[4\], v3\.b\[7\]
+** ret
+*/
+TEST (int8x8x4_t, 0, 4, 3, 7)
+
+/*
+** test_int16x4x4_t:
+** ins v3\.h\[3\], v1\.h\[1\]
+** ret
+*/
+TEST (int16x4x4_t, 3, 3, 1, 1)
+
+/*
+** test_int32x2x4_t:
+** ins v1\.s\[0\], v3\.s\[1\]
+** ret
+*/
+TEST (int32x2x4_t, 1, 0, 3, 1)
+
+/*
+** test_int64x1x4_t:
+** fmov d3, d1
+** ret
+*/
+TEST (int64x1x4_t, 3, 0, 1, 0)
+
+/*
+** test_uint8x8x4_t:
+** ins v3\.b\[6\], v2\.b\[4\]
+** ret
+*/
+TEST (uint8x8x4_t, 3, 6, 2, 4)
+
+/*
+** test_uint16x4x4_t:
+** ins v3\.h\[1\], v1\.h\[3\]
+** ret
+*/
+TEST (uint16x4x4_t, 3, 1, 1, 3)
+
+/*
+** test_uint32x2x4_t:
+** ins v0\.s\[0\], v3\.s\[1\]
+** ret
+*/
+TEST (uint32x2x4_t, 0, 0, 3, 1)
+
+/*
+** test_uint64x1x4_t:
+** fmov d1, d3
+** ret
+*/
+TEST (uint64x1x4_t, 1, 0, 3, 0)
diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-3.c b/gcc/testsuite/gcc.target/aarch64/pr113027-3.c
new file mode 100644
index 0000000..561e672
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr113027-3.c
@@ -0,0 +1,268 @@
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */
+
+#include <arm_neon.h>
+
+#define TEST(TYPE, A, B, C, D) \
+ TYPE \
+ test_##TYPE (TYPE a) \
+ { \
+ a.val[A][B] = a.val[C][D]; \
+ return a; \
+ }
+
+/*
+** test_bfloat16x8x2_t:
+** ins v1\.h\[6\], v0\.h\[5\]
+** ret
+*/
+TEST (bfloat16x8x2_t, 1, 6, 0, 5)
+
+/*
+** test_float16x8x2_t:
+** ins v1\.h\[2\], v0\.h\[7\]
+** ret
+*/
+TEST (float16x8x2_t, 1, 2, 0, 7)
+
+/*
+** test_float32x4x2_t:
+** ins v1\.s\[3\], v0\.s\[1\]
+** ret
+*/
+TEST (float32x4x2_t, 1, 3, 0, 1)
+
+/*
+** test_float64x2x2_t:
+** ins v1\.d\[0\], v0\.d\[0\]
+** ret
+*/
+TEST (float64x2x2_t, 1, 0, 0, 0)
+
+/*
+** test_int8x16x2_t:
+** ins v0\.b\[15\], v1\.b\[13\]
+** ret
+*/
+TEST (int8x16x2_t, 0, 15, 1, 13)
+
+/*
+** test_int16x8x2_t:
+** ins v0\.h\[2\], v1\.h\[7\]
+** ret
+*/
+TEST (int16x8x2_t, 0, 2, 1, 7)
+
+/*
+** test_int32x4x2_t:
+** ins v0\.s\[3\], v1\.s\[1\]
+** ret
+*/
+TEST (int32x4x2_t, 0, 3, 1, 1)
+
+/*
+** test_int64x2x2_t:
+** ins v0\.d\[0\], v1\.d\[1\]
+** ret
+*/
+TEST (int64x2x2_t, 0, 0, 1, 1)
+
+/*
+** test_uint8x16x2_t:
+** ins v1\.b\[13\], v0\.b\[11\]
+** ret
+*/
+TEST (uint8x16x2_t, 1, 13, 0, 11)
+
+/*
+** test_uint16x8x2_t:
+** ins v1\.h\[6\], v1\.h\[3\]
+** ret
+*/
+TEST (uint16x8x2_t, 1, 6, 1, 3)
+
+/*
+** test_uint32x4x2_t:
+** ins v1\.s\[3\], v1\.s\[1\]
+** ret
+*/
+TEST (uint32x4x2_t, 1, 3, 1, 1)
+
+/*
+** test_uint64x2x2_t:
+** ins v1\.d\[0\], v1\.d\[1\]
+** ret
+*/
+TEST (uint64x2x2_t, 1, 0, 1, 1)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x8x3_t:
+** ins v2\.h\[3\], v0\.h\[7\]
+** ret
+*/
+TEST (bfloat16x8x3_t, 2, 3, 0, 7)
+
+/*
+** test_float16x8x3_t:
+** ins v0\.h\[4\], v1\.h\[6\]
+** ret
+*/
+TEST (float16x8x3_t, 0, 4, 1, 6)
+
+/*
+** test_float32x4x3_t:
+** ins v1\.s\[2\], v2\.s\[1\]
+** ret
+*/
+TEST (float32x4x3_t, 1, 2, 2, 1)
+
+/*
+** test_float64x2x3_t:
+** ins v1\.d\[0\], v2\.d\[1\]
+** ret
+*/
+TEST (float64x2x3_t, 1, 0, 2, 1)
+
+/*
+** test_int8x16x3_t:
+** ins v0\.b\[9\], v2\.b\[14\]
+** ret
+*/
+TEST (int8x16x3_t, 0, 9, 2, 14)
+
+/*
+** test_int16x8x3_t:
+** ins v2\.h\[6\], v1\.h\[3\]
+** ret
+*/
+TEST (int16x8x3_t, 2, 6, 1, 3)
+
+/*
+** test_int32x4x3_t:
+** ins v1\.s\[3\], v1\.s\[1\]
+** ret
+*/
+TEST (int32x4x3_t, 1, 3, 1, 1)
+
+/*
+** test_int64x2x3_t:
+** ins v2\.d\[1\], v1\.d\[0\]
+** ret
+*/
+TEST (int64x2x3_t, 2, 1, 1, 0)
+
+/*
+** test_uint8x16x3_t:
+** ins v1\.b\[10\], v2\.b\[8\]
+** ret
+*/
+TEST (uint8x16x3_t, 1, 10, 2, 8)
+
+/*
+** test_uint16x8x3_t:
+** ins v2\.h\[5\], v1\.h\[2\]
+** ret
+*/
+TEST (uint16x8x3_t, 2, 5, 1, 2)
+
+/*
+** test_uint32x4x3_t:
+** ins v2\.s\[3\], v0\.s\[1\]
+** ret
+*/
+TEST (uint32x4x3_t, 2, 3, 0, 1)
+
+/*
+** test_uint64x2x3_t:
+** ins v1\.d\[0\], v2\.d\[1\]
+** ret
+*/
+TEST (uint64x2x3_t, 1, 0, 2, 1)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x8x4_t:
+** ins v2\.h\[5\], v3\.h\[6\]
+** ret
+*/
+TEST (bfloat16x8x4_t, 2, 5, 3, 6)
+
+/*
+** test_float16x8x4_t:
+** ins v0\.h\[3\], v3\.h\[5\]
+** ret
+*/
+TEST (float16x8x4_t, 0, 3, 3, 5)
+
+/*
+** test_float32x4x4_t:
+** ins v3\.s\[2\], v2\.s\[1\]
+** ret
+*/
+TEST (float32x4x4_t, 3, 2, 2, 1)
+
+/*
+** test_float64x2x4_t:
+** ins v1\.d\[1\], v3\.d\[0\]
+** ret
+*/
+TEST (float64x2x4_t, 1, 1, 3, 0)
+
+/*
+** test_int8x16x4_t:
+** ins v0\.b\[14\], v3\.b\[10\]
+** ret
+*/
+TEST (int8x16x4_t, 0, 14, 3, 10)
+
+/*
+** test_int16x8x4_t:
+** ins v3\.h\[4\], v1\.h\[6\]
+** ret
+*/
+TEST (int16x8x4_t, 3, 4, 1, 6)
+
+/*
+** test_int32x4x4_t:
+** ins v1\.s\[3\], v3\.s\[1\]
+** ret
+*/
+TEST (int32x4x4_t, 1, 3, 3, 1)
+
+/*
+** test_int64x2x4_t:
+** ins v3\.d\[0\], v2\.d\[0\]
+** ret
+*/
+TEST (int64x2x4_t, 3, 0, 2, 0)
+
+/*
+** test_uint8x16x4_t:
+** ins v3\.b\[13\], v2\.b\[6\]
+** ret
+*/
+TEST (uint8x16x4_t, 3, 13, 2, 6)
+
+/*
+** test_uint16x8x4_t:
+** ins v3\.h\[2\], v1\.h\[7\]
+** ret
+*/
+TEST (uint16x8x4_t, 3, 2, 1, 7)
+
+/*
+** test_uint32x4x4_t:
+** ins v0\.s\[3\], v3\.s\[2\]
+** ret
+*/
+TEST (uint32x4x4_t, 0, 3, 3, 2)
+
+/*
+** test_uint64x2x4_t:
+** ins v1\.d\[0\], v3\.d\[1\]
+** ret
+*/
+TEST (uint64x2x4_t, 1, 0, 3, 1)
diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-4.c b/gcc/testsuite/gcc.target/aarch64/pr113027-4.c
new file mode 100644
index 0000000..67f45df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr113027-4.c
@@ -0,0 +1,268 @@
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */
+
+#include <arm_neon.h>
+
+#define TEST(TYPE, A, B) \
+ TYPE \
+ test_##TYPE (TYPE a, TYPE *ptr) \
+ { \
+ a.val[A][B] = ptr->val[0][0]; \
+ return a; \
+ }
+
+/*
+** test_bfloat16x4x2_t:
+** ld1 \{v1\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x4x2_t, 1, 3)
+
+/*
+** test_float16x4x2_t:
+** ld1 \{v1\.h\}\[1\], \[x0\]
+** ret
+*/
+TEST (float16x4x2_t, 1, 1)
+
+/*
+** test_float32x2x2_t:
+** ld1 \{v1\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (float32x2x2_t, 1, 0)
+
+/*
+** test_float64x1x2_t:
+** ldr d1, \[x0\]
+** ret
+*/
+TEST (float64x1x2_t, 1, 0)
+
+/*
+** test_int8x8x2_t:
+** ld1 \{v0\.b\}\[5\], \[x0\]
+** ret
+*/
+TEST (int8x8x2_t, 0, 5)
+
+/*
+** test_int16x4x2_t:
+** ld1 \{v0\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (int16x4x2_t, 0, 2)
+
+/*
+** test_int32x2x2_t:
+** ld1 \{v0\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (int32x2x2_t, 0, 0)
+
+/*
+** test_int64x1x2_t:
+** ldr d0, \[x0\]
+** ret
+*/
+TEST (int64x1x2_t, 0, 0)
+
+/*
+** test_uint8x8x2_t:
+** ld1 \{v1\.b\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint8x8x2_t, 1, 6)
+
+/*
+** test_uint16x4x2_t:
+** ld1 \{v1\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (uint16x4x2_t, 1, 2)
+
+/*
+** test_uint32x2x2_t:
+** ld1 \{v1\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (uint32x2x2_t, 1, 0)
+
+/*
+** test_uint64x1x2_t:
+** ldr d1, \[x0\]
+** ret
+*/
+TEST (uint64x1x2_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x4x3_t:
+** ld1 \{v2\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x4x3_t, 2, 3)
+
+/*
+** test_float16x4x3_t:
+** ld1 \{v0\.h\}\[1\], \[x0\]
+** ret
+*/
+TEST (float16x4x3_t, 0, 1)
+
+/*
+** test_float32x2x3_t:
+** ld1 \{v1\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (float32x2x3_t, 1, 0)
+
+/*
+** test_float64x1x3_t:
+** ldr d1, \[x0\]
+** ret
+*/
+TEST (float64x1x3_t, 1, 0)
+
+/*
+** test_int8x8x3_t:
+** ld1 \{v0\.b\}\[5\], \[x0\]
+** ret
+*/
+TEST (int8x8x3_t, 0, 5)
+
+/*
+** test_int16x4x3_t:
+** ld1 \{v2\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (int16x4x3_t, 2, 2)
+
+/*
+** test_int32x2x3_t:
+** ld1 \{v1\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (int32x2x3_t, 1, 0)
+
+/*
+** test_int64x1x3_t:
+** ldr d2, \[x0\]
+** ret
+*/
+TEST (int64x1x3_t, 2, 0)
+
+/*
+** test_uint8x8x3_t:
+** ld1 \{v1\.b\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint8x8x3_t, 1, 6)
+
+/*
+** test_uint16x4x3_t:
+** ld1 \{v2\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (uint16x4x3_t, 2, 2)
+
+/*
+** test_uint32x2x3_t:
+** ld1 \{v2\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (uint32x2x3_t, 2, 0)
+
+/*
+** test_uint64x1x3_t:
+** ldr d1, \[x0\]
+** ret
+*/
+TEST (uint64x1x3_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x4x4_t:
+** ld1 \{v2\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x4x4_t, 2, 3)
+
+/*
+** test_float16x4x4_t:
+** ld1 \{v0\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (float16x4x4_t, 0, 2)
+
+/*
+** test_float32x2x4_t:
+** ld1 \{v3\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (float32x2x4_t, 3, 0)
+
+/*
+** test_float64x1x4_t:
+** ldr d1, \[x0\]
+** ret
+*/
+TEST (float64x1x4_t, 1, 0)
+
+/*
+** test_int8x8x4_t:
+** ld1 \{v0\.b\}\[4\], \[x0\]
+** ret
+*/
+TEST (int8x8x4_t, 0, 4)
+
+/*
+** test_int16x4x4_t:
+** ld1 \{v3\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (int16x4x4_t, 3, 3)
+
+/*
+** test_int32x2x4_t:
+** ld1 \{v1\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (int32x2x4_t, 1, 0)
+
+/*
+** test_int64x1x4_t:
+** ldr d3, \[x0\]
+** ret
+*/
+TEST (int64x1x4_t, 3, 0)
+
+/*
+** test_uint8x8x4_t:
+** ld1 \{v3\.b\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint8x8x4_t, 3, 6)
+
+/*
+** test_uint16x4x4_t:
+** ld1 \{v3\.h\}\[1\], \[x0\]
+** ret
+*/
+TEST (uint16x4x4_t, 3, 1)
+
+/*
+** test_uint32x2x4_t:
+** ld1 \{v0\.s\}\[0\], \[x0\]
+** ret
+*/
+TEST (uint32x2x4_t, 0, 0)
+
+/*
+** test_uint64x1x4_t:
+** ldr d1, \[x0\]
+** ret
+*/
+TEST (uint64x1x4_t, 1, 0)
diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-5.c b/gcc/testsuite/gcc.target/aarch64/pr113027-5.c
new file mode 100644
index 0000000..5695eca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr113027-5.c
@@ -0,0 +1,268 @@
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */
+
+#include <arm_neon.h>
+
+#define TEST(TYPE, A, B) \
+ TYPE \
+ test_##TYPE (TYPE a, TYPE *ptr) \
+ { \
+ a.val[A][B] = ptr->val[0][0]; \
+ return a; \
+ }
+
+/*
+** test_bfloat16x8x2_t:
+** ld1 \{v1\.h\}\[6\], \[x0\]
+** ret
+*/
+TEST (bfloat16x8x2_t, 1, 6)
+
+/*
+** test_float16x8x2_t:
+** ld1 \{v1\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (float16x8x2_t, 1, 2)
+
+/*
+** test_float32x4x2_t:
+** ld1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (float32x4x2_t, 1, 3)
+
+/*
+** test_float64x2x2_t:
+** ld1 \{v1\.d\}\[0\], \[x0\]
+** ret
+*/
+TEST (float64x2x2_t, 1, 0)
+
+/*
+** test_int8x16x2_t:
+** ld1 \{v0\.b\}\[15\], \[x0\]
+** ret
+*/
+TEST (int8x16x2_t, 0, 15)
+
+/*
+** test_int16x8x2_t:
+** ld1 \{v0\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (int16x8x2_t, 0, 2)
+
+/*
+** test_int32x4x2_t:
+** ld1 \{v0\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (int32x4x2_t, 0, 3)
+
+/*
+** test_int64x2x2_t:
+** ld1 \{v0\.d\}\[0\], \[x0\]
+** ret
+*/
+TEST (int64x2x2_t, 0, 0)
+
+/*
+** test_uint8x16x2_t:
+** ld1 \{v1\.b\}\[13\], \[x0\]
+** ret
+*/
+TEST (uint8x16x2_t, 1, 13)
+
+/*
+** test_uint16x8x2_t:
+** ld1 \{v1\.h\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint16x8x2_t, 1, 6)
+
+/*
+** test_uint32x4x2_t:
+** ld1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (uint32x4x2_t, 1, 3)
+
+/*
+** test_uint64x2x2_t:
+** ld1 \{v1\.d\}\[0\], \[x0\]
+** ret
+*/
+TEST (uint64x2x2_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x8x3_t:
+** ld1 \{v2\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x8x3_t, 2, 3)
+
+/*
+** test_float16x8x3_t:
+** ld1 \{v0\.h\}\[4\], \[x0\]
+** ret
+*/
+TEST (float16x8x3_t, 0, 4)
+
+/*
+** test_float32x4x3_t:
+** ld1 \{v1\.s\}\[2\], \[x0\]
+** ret
+*/
+TEST (float32x4x3_t, 1, 2)
+
+/*
+** test_float64x2x3_t:
+** ld1 \{v1\.d\}\[0\], \[x0\]
+** ret
+*/
+TEST (float64x2x3_t, 1, 0)
+
+/*
+** test_int8x16x3_t:
+** ld1 \{v0\.b\}\[9\], \[x0\]
+** ret
+*/
+TEST (int8x16x3_t, 0, 9)
+
+/*
+** test_int16x8x3_t:
+** ld1 \{v2\.h\}\[6\], \[x0\]
+** ret
+*/
+TEST (int16x8x3_t, 2, 6)
+
+/*
+** test_int32x4x3_t:
+** ld1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (int32x4x3_t, 1, 3)
+
+/*
+** test_int64x2x3_t:
+** ld1 \{v2\.d\}\[1\], \[x0\]
+** ret
+*/
+TEST (int64x2x3_t, 2, 1)
+
+/*
+** test_uint8x16x3_t:
+** ld1 \{v1\.b\}\[10\], \[x0\]
+** ret
+*/
+TEST (uint8x16x3_t, 1, 10)
+
+/*
+** test_uint16x8x3_t:
+** ld1 \{v2\.h\}\[5\], \[x0\]
+** ret
+*/
+TEST (uint16x8x3_t, 2, 5)
+
+/*
+** test_uint32x4x3_t:
+** ld1 \{v2\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (uint32x4x3_t, 2, 3)
+
+/*
+** test_uint64x2x3_t:
+** ld1 \{v1\.d\}\[0\], \[x0\]
+** ret
+*/
+TEST (uint64x2x3_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x8x4_t:
+** ld1 \{v2\.h\}\[5\], \[x0\]
+** ret
+*/
+TEST (bfloat16x8x4_t, 2, 5)
+
+/*
+** test_float16x8x4_t:
+** ld1 \{v0\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (float16x8x4_t, 0, 3)
+
+/*
+** test_float32x4x4_t:
+** ld1 \{v3\.s\}\[2\], \[x0\]
+** ret
+*/
+TEST (float32x4x4_t, 3, 2)
+
+/*
+** test_float64x2x4_t:
+** ld1 \{v1\.d\}\[1\], \[x0\]
+** ret
+*/
+TEST (float64x2x4_t, 1, 1)
+
+/*
+** test_int8x16x4_t:
+** ld1 \{v0\.b\}\[14\], \[x0\]
+** ret
+*/
+TEST (int8x16x4_t, 0, 14)
+
+/*
+** test_int16x8x4_t:
+** ld1 \{v3\.h\}\[4\], \[x0\]
+** ret
+*/
+TEST (int16x8x4_t, 3, 4)
+
+/*
+** test_int32x4x4_t:
+** ld1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (int32x4x4_t, 1, 3)
+
+/*
+** test_int64x2x4_t:
+** ld1 \{v3\.d\}\[0\], \[x0\]
+** ret
+*/
+TEST (int64x2x4_t, 3, 0)
+
+/*
+** test_uint8x16x4_t:
+** ld1 \{v3\.b\}\[13\], \[x0\]
+** ret
+*/
+TEST (uint8x16x4_t, 3, 13)
+
+/*
+** test_uint16x8x4_t:
+** ld1 \{v3\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (uint16x8x4_t, 3, 2)
+
+/*
+** test_uint32x4x4_t:
+** ld1 \{v0\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (uint32x4x4_t, 0, 3)
+
+/*
+** test_uint64x2x4_t:
+** ld1 \{v1\.d\}\[0\], \[x0\]
+** ret
+*/
+TEST (uint64x2x4_t, 1, 0)
diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-6.c b/gcc/testsuite/gcc.target/aarch64/pr113027-6.c
new file mode 100644
index 0000000..12d3a38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr113027-6.c
@@ -0,0 +1,267 @@
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */
+
+#include <arm_neon.h>
+
+#define TEST(TYPE, A, B) \
+ void \
+ test_##TYPE (TYPE a, TYPE *ptr) \
+ { \
+ ptr->val[0][0] = a.val[A][B]; \
+ }
+
+/*
+** test_bfloat16x4x2_t:
+** st1 \{v1\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x4x2_t, 1, 3)
+
+/*
+** test_float16x4x2_t:
+** st1 \{v1\.h\}\[1\], \[x0\]
+** ret
+*/
+TEST (float16x4x2_t, 1, 1)
+
+/*
+** test_float32x2x2_t:
+** str s1, \[x0\]
+** ret
+*/
+TEST (float32x2x2_t, 1, 0)
+
+/*
+** test_float64x1x2_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (float64x1x2_t, 1, 0)
+
+/*
+** test_int8x8x2_t:
+** st1 \{v0\.b\}\[5\], \[x0\]
+** ret
+*/
+TEST (int8x8x2_t, 0, 5)
+
+/*
+** test_int16x4x2_t:
+** st1 \{v0\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (int16x4x2_t, 0, 2)
+
+/*
+** test_int32x2x2_t:
+** str s0, \[x0\]
+** ret
+*/
+TEST (int32x2x2_t, 0, 0)
+
+/*
+** test_int64x1x2_t:
+** str d0, \[x0\]
+** ret
+*/
+TEST (int64x1x2_t, 0, 0)
+
+/*
+** test_uint8x8x2_t:
+** st1 \{v1\.b\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint8x8x2_t, 1, 6)
+
+/*
+** test_uint16x4x2_t:
+** st1 \{v1\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (uint16x4x2_t, 1, 2)
+
+/*
+** test_uint32x2x2_t:
+** str s1, \[x0\]
+** ret
+*/
+TEST (uint32x2x2_t, 1, 0)
+
+/*
+** test_uint64x1x2_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (uint64x1x2_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x4x3_t:
+** st1 \{v2\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x4x3_t, 2, 3)
+
+/*
+** test_float16x4x3_t:
+** st1 \{v0\.h\}\[1\], \[x0\]
+** ret
+*/
+TEST (float16x4x3_t, 0, 1)
+
+/*
+** test_float32x2x3_t:
+** str s1, \[x0\]
+** ret
+*/
+TEST (float32x2x3_t, 1, 0)
+
+/*
+** test_float64x1x3_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (float64x1x3_t, 1, 0)
+
+/*
+** test_int8x8x3_t:
+** st1 \{v0\.b\}\[5\], \[x0\]
+** ret
+*/
+TEST (int8x8x3_t, 0, 5)
+
+/*
+** test_int16x4x3_t:
+** st1 \{v2\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (int16x4x3_t, 2, 2)
+
+/*
+** test_int32x2x3_t:
+** str s1, \[x0\]
+** ret
+*/
+TEST (int32x2x3_t, 1, 0)
+
+/*
+** test_int64x1x3_t:
+** str d2, \[x0\]
+** ret
+*/
+TEST (int64x1x3_t, 2, 0)
+
+/*
+** test_uint8x8x3_t:
+** st1 \{v1\.b\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint8x8x3_t, 1, 6)
+
+/*
+** test_uint16x4x3_t:
+** st1 \{v2\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (uint16x4x3_t, 2, 2)
+
+/*
+** test_uint32x2x3_t:
+** str s2, \[x0\]
+** ret
+*/
+TEST (uint32x2x3_t, 2, 0)
+
+/*
+** test_uint64x1x3_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (uint64x1x3_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x4x4_t:
+** st1 \{v2\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x4x4_t, 2, 3)
+
+/*
+** test_float16x4x4_t:
+** st1 \{v0\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (float16x4x4_t, 0, 2)
+
+/*
+** test_float32x2x4_t:
+** str s3, \[x0\]
+** ret
+*/
+TEST (float32x2x4_t, 3, 0)
+
+/*
+** test_float64x1x4_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (float64x1x4_t, 1, 0)
+
+/*
+** test_int8x8x4_t:
+** st1 \{v0\.b\}\[4\], \[x0\]
+** ret
+*/
+TEST (int8x8x4_t, 0, 4)
+
+/*
+** test_int16x4x4_t:
+** st1 \{v3\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (int16x4x4_t, 3, 3)
+
+/*
+** test_int32x2x4_t:
+** str s1, \[x0\]
+** ret
+*/
+TEST (int32x2x4_t, 1, 0)
+
+/*
+** test_int64x1x4_t:
+** str d3, \[x0\]
+** ret
+*/
+TEST (int64x1x4_t, 3, 0)
+
+/*
+** test_uint8x8x4_t:
+** st1 \{v3\.b\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint8x8x4_t, 3, 6)
+
+/*
+** test_uint16x4x4_t:
+** st1 \{v3\.h\}\[1\], \[x0\]
+** ret
+*/
+TEST (uint16x4x4_t, 3, 1)
+
+/*
+** test_uint32x2x4_t:
+** str s0, \[x0\]
+** ret
+*/
+TEST (uint32x2x4_t, 0, 0)
+
+/*
+** test_uint64x1x4_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (uint64x1x4_t, 1, 0)
diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-7.c b/gcc/testsuite/gcc.target/aarch64/pr113027-7.c
new file mode 100644
index 0000000..b3ae1a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr113027-7.c
@@ -0,0 +1,267 @@
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */
+
+#include <arm_neon.h>
+
+#define TEST(TYPE, A, B) \
+ void \
+ test_##TYPE (TYPE a, TYPE *ptr) \
+ { \
+ ptr->val[0][0] = a.val[A][B]; \
+ }
+
+/*
+** test_bfloat16x8x2_t:
+** st1 \{v1\.h\}\[6\], \[x0\]
+** ret
+*/
+TEST (bfloat16x8x2_t, 1, 6)
+
+/*
+** test_float16x8x2_t:
+** st1 \{v1\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (float16x8x2_t, 1, 2)
+
+/*
+** test_float32x4x2_t:
+** st1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (float32x4x2_t, 1, 3)
+
+/*
+** test_float64x2x2_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (float64x2x2_t, 1, 0)
+
+/*
+** test_int8x16x2_t:
+** st1 \{v0\.b\}\[15\], \[x0\]
+** ret
+*/
+TEST (int8x16x2_t, 0, 15)
+
+/*
+** test_int16x8x2_t:
+** st1 \{v0\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (int16x8x2_t, 0, 2)
+
+/*
+** test_int32x4x2_t:
+** st1 \{v0\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (int32x4x2_t, 0, 3)
+
+/*
+** test_int64x2x2_t:
+** str d0, \[x0\]
+** ret
+*/
+TEST (int64x2x2_t, 0, 0)
+
+/*
+** test_uint8x16x2_t:
+** st1 \{v1\.b\}\[13\], \[x0\]
+** ret
+*/
+TEST (uint8x16x2_t, 1, 13)
+
+/*
+** test_uint16x8x2_t:
+** st1 \{v1\.h\}\[6\], \[x0\]
+** ret
+*/
+TEST (uint16x8x2_t, 1, 6)
+
+/*
+** test_uint32x4x2_t:
+** st1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (uint32x4x2_t, 1, 3)
+
+/*
+** test_uint64x2x2_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (uint64x2x2_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x8x3_t:
+** st1 \{v2\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (bfloat16x8x3_t, 2, 3)
+
+/*
+** test_float16x8x3_t:
+** st1 \{v0\.h\}\[4\], \[x0\]
+** ret
+*/
+TEST (float16x8x3_t, 0, 4)
+
+/*
+** test_float32x4x3_t:
+** st1 \{v1\.s\}\[2\], \[x0\]
+** ret
+*/
+TEST (float32x4x3_t, 1, 2)
+
+/*
+** test_float64x2x3_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (float64x2x3_t, 1, 0)
+
+/*
+** test_int8x16x3_t:
+** st1 \{v0\.b\}\[9\], \[x0\]
+** ret
+*/
+TEST (int8x16x3_t, 0, 9)
+
+/*
+** test_int16x8x3_t:
+** st1 \{v2\.h\}\[6\], \[x0\]
+** ret
+*/
+TEST (int16x8x3_t, 2, 6)
+
+/*
+** test_int32x4x3_t:
+** st1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (int32x4x3_t, 1, 3)
+
+/*
+** test_int64x2x3_t:
+** st1 \{v2\.d\}\[1\], \[x0\]
+** ret
+*/
+TEST (int64x2x3_t, 2, 1)
+
+/*
+** test_uint8x16x3_t:
+** st1 \{v1\.b\}\[10\], \[x0\]
+** ret
+*/
+TEST (uint8x16x3_t, 1, 10)
+
+/*
+** test_uint16x8x3_t:
+** st1 \{v2\.h\}\[5\], \[x0\]
+** ret
+*/
+TEST (uint16x8x3_t, 2, 5)
+
+/*
+** test_uint32x4x3_t:
+** st1 \{v2\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (uint32x4x3_t, 2, 3)
+
+/*
+** test_uint64x2x3_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (uint64x2x3_t, 1, 0)
+
+//--------------------------------------------------------------
+
+/*
+** test_bfloat16x8x4_t:
+** st1 \{v2\.h\}\[5\], \[x0\]
+** ret
+*/
+TEST (bfloat16x8x4_t, 2, 5)
+
+/*
+** test_float16x8x4_t:
+** st1 \{v0\.h\}\[3\], \[x0\]
+** ret
+*/
+TEST (float16x8x4_t, 0, 3)
+
+/*
+** test_float32x4x4_t:
+** st1 \{v3\.s\}\[2\], \[x0\]
+** ret
+*/
+TEST (float32x4x4_t, 3, 2)
+
+/*
+** test_float64x2x4_t:
+** st1 \{v1\.d\}\[1\], \[x0\]
+** ret
+*/
+TEST (float64x2x4_t, 1, 1)
+
+/*
+** test_int8x16x4_t:
+** st1 \{v0\.b\}\[14\], \[x0\]
+** ret
+*/
+TEST (int8x16x4_t, 0, 14)
+
+/*
+** test_int16x8x4_t:
+** st1 \{v3\.h\}\[4\], \[x0\]
+** ret
+*/
+TEST (int16x8x4_t, 3, 4)
+
+/*
+** test_int32x4x4_t:
+** st1 \{v1\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (int32x4x4_t, 1, 3)
+
+/*
+** test_int64x2x4_t:
+** str d3, \[x0\]
+** ret
+*/
+TEST (int64x2x4_t, 3, 0)
+
+/*
+** test_uint8x16x4_t:
+** st1 \{v3\.b\}\[13\], \[x0\]
+** ret
+*/
+TEST (uint8x16x4_t, 3, 13)
+
+/*
+** test_uint16x8x4_t:
+** st1 \{v3\.h\}\[2\], \[x0\]
+** ret
+*/
+TEST (uint16x8x4_t, 3, 2)
+
+/*
+** test_uint32x4x4_t:
+** st1 \{v0\.s\}\[3\], \[x0\]
+** ret
+*/
+TEST (uint32x4x4_t, 0, 3)
+
+/*
+** test_uint64x2x4_t:
+** str d1, \[x0\]
+** ret
+*/
+TEST (uint64x2x4_t, 1, 0)
diff --git a/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c b/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c
index 3862f1e..532a9a0 100644
--- a/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-march=x86-64-v3 -mavx10.2 -O2 -fno-trapping-math" } */
+/* { dg-options "-march=x86-64-v3 -mavx10.2 -O2 -fno-trapping-math -fno-shrink-wrap" } */
/* { dg-final { scan-assembler-times "vcomisbf16\[ \\t\]+\[^{}\n\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 6 } } */
/* { dg-final { scan-assembler-times {j[a-z]+\s} 6 } } */
diff --git a/gcc/testsuite/gcc.target/i386/cold-attribute-4.c b/gcc/testsuite/gcc.target/i386/cold-attribute-4.c
index 37a41e9..e0808c5 100644
--- a/gcc/testsuite/gcc.target/i386/cold-attribute-4.c
+++ b/gcc/testsuite/gcc.target/i386/cold-attribute-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-Oz" } */
#include <string.h>
int
diff --git a/gcc/testsuite/gcc.target/i386/interrupt-16.c b/gcc/testsuite/gcc.target/i386/interrupt-16.c
index cb45ba5..ca4441b 100644
--- a/gcc/testsuite/gcc.target/i386/interrupt-16.c
+++ b/gcc/testsuite/gcc.target/i386/interrupt-16.c
@@ -18,5 +18,5 @@ foo (int i)
/* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)bp" } } */
/* { dg-final { scan-assembler-not "(push|pop)l\[\\t \]*%edi" { target ia32 } } } */
/* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%r\[0-9\]+" { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "pushq\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "(pushq.*%rdi|subq.*\\\$8,.*%rsp)" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "(popq.*%rdi|addq.*\\\$8,.*%rsp)" 1 { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c
new file mode 100644
index 0000000..d4fe2adc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
+/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */
+/* { dg-final { scan-assembler-not "movdqa" } } */
+
+char a[2048];
+char b[2048];
+void t (void)
+{
+ __builtin_memcpy (a, b, 2048);
+}
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c
new file mode 100644
index 0000000..9a6fcfd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
+/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */
+/* { dg-final { scan-assembler-not "movdqa" } } */
+
+char *a;
+char *b;
+void t (void)
+{
+ __builtin_memcpy (a, b, 2048);
+}
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c
new file mode 100644
index 0000000..010ac24
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
+/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */
+/* { dg-final { scan-assembler-not "movdqa" } } */
+
+char a[2048];
+char b[2048];
+void t (void)
+{
+ __builtin_memcpy (a, b, 2048);
+}
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c
new file mode 100644
index 0000000..87a58ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
+/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */
+/* { dg-final { scan-assembler-not "movdqa" } } */
+
+char a[2048];
+char b[2048];
+void t (void)
+{
+ __builtin_memcpy (a, b, 2048);
+}
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c
new file mode 100644
index 0000000..19e0600
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=128 -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */
+
+#define SIZE (16 + 1) * 16
+
+char dest[SIZE];
+char src[SIZE];
+
+void
+foo (void)
+{
+ __builtin_memcpy (dest, src, SIZE);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqa\[ \t]\+\[^\n\r]*%xmm\[0-9\]\+" 10 } } */
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c
new file mode 100644
index 0000000..17b101f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=256 -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */
+
+#define SIZE (16 + 1) * 32
+
+char dest[SIZE];
+char src[SIZE];
+
+void
+foo (void)
+{
+ __builtin_memcpy (dest, src, SIZE);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqa\[ \t]\+\[^\n\r]*%ymm\[0-9\]\+" 10 } } */
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c
index 6ac80c9..b298673 100644
--- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c
+++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c
@@ -1,6 +1,5 @@
/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
-/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mmemcpy-strategy=vector_loop:-1:align" } */
/* { dg-final { scan-assembler-times "movdqa" 8 } } */
char a[2048];
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c
index c103896..18e260b 100644
--- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c
+++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c
@@ -1,6 +1,5 @@
/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
-/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */
/* { dg-final { scan-assembler-times "movdqa" 8 } } */
char a[2048];
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c
index 93f428a..cec8c90 100644
--- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c
+++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c
@@ -1,6 +1,5 @@
/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
-/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */
/* { dg-final { scan-assembler-times "movdqa" 8 } } */
char a[2048];
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c
index ab23540..314eb3d 100644
--- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c
+++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c
@@ -1,7 +1,6 @@
/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
-/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */
-/* { dg-final { scan-assembler-times "movdqa" 4} } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */
+/* { dg-final { scan-assembler-times "movdqa" 4 } } */
char *a;
char *b;
diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c b/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c
new file mode 100644
index 0000000..fba0588
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=128 -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */
+
+void
+foo (char *dest)
+{
+ __builtin_memset (dest, 0, 254);
+}
+
+/* { dg-final { scan-assembler "vmovdqu\[ \t]\+%xmm\[0-9\]+, \\(\[^\n\r]*\\)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c b/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c
new file mode 100644
index 0000000..d9a3e7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=256 -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */
+
+void
+foo (char *dest)
+{
+ __builtin_memset (dest, 0, 254);
+}
+
+/* { dg-final { scan-assembler "vmovdqu\[ \t]\+%ymm\[0-9\]+, \\(\[^\n\r]*\\)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c
index d6fdc98..5bb30a8 100644
--- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c
+++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c
@@ -1,6 +1,5 @@
/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
-/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */
/* { dg-final { scan-assembler-times "movdqa" 4 } } */
char a[2048];
diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c
index bce8be0..6e31070 100644
--- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c
+++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c
@@ -1,6 +1,5 @@
/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */
-/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */
+/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mstringop-strategy=vector_loop" } */
/* { dg-final { scan-assembler-times "movdqa" 4} } */
char *a;
diff --git a/gcc/testsuite/gcc.target/i386/pr120427-1.c b/gcc/testsuite/gcc.target/i386/pr120427-1.c
new file mode 100644
index 0000000..7f1690e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr120427-1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=sapphirerapids" } */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]+\\\$0, \[0-9\]*\\(" } } */
+
+struct __pthread_mutex_s
+{
+ int __lock;
+ unsigned int __count;
+ int __owner;
+ unsigned int __nusers;
+ int __kind;
+ short __spins;
+ short __elision;
+ void *p[2];
+};
+typedef union
+{
+ struct __pthread_mutex_s __data;
+ char __size[40];
+ long int __align;
+} pthread_mutex_t;
+typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t;
+void
+foo (__rtld_lock_recursive_t *lock, int i)
+{
+ lock[i] = (__rtld_lock_recursive_t) {{ { 0, 0, 0, 0, 1,
+ 0, 0, { ((void *)0) , ((void *)0) } } }};
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr120427-2.c b/gcc/testsuite/gcc.target/i386/pr120427-2.c
new file mode 100644
index 0000000..a380c12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr120427-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=sapphirerapids" } */
+/* { dg-final { scan-assembler-not "or\[lq\]?\[\\t \]+\\\$-1, \[0-9\]*\\(" } } */
+
+struct __pthread_mutex_s
+{
+ int __lock;
+ unsigned int __count;
+ int __owner;
+ unsigned int __nusers;
+ int __kind;
+ short __spins;
+ short __elision;
+ void *p[2];
+};
+typedef union
+{
+ struct __pthread_mutex_s __data;
+ char __size[40];
+ long int __align;
+} pthread_mutex_t;
+typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t;
+void
+foo (__rtld_lock_recursive_t *lock, int i)
+{
+ lock[i] = (__rtld_lock_recursive_t) {{ { -1, -1, -1, -1, 1,
+ -1, -1, { ((void *)-1) , ((void *)-1) } } }};
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr120427-3.c b/gcc/testsuite/gcc.target/i386/pr120427-3.c
new file mode 100644
index 0000000..951cb1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr120427-3.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+typedef UDItype __attribute__ ((__may_alias__)) bar_t;
+
+static inline __attribute__((__always_inline__)) SItype
+bar (const bar_t **p, SItype prec)
+{
+ bar_t mslimb = 0;
+ SItype i = 20;
+ SItype n = ((USItype) prec) % 4;
+ if (n)
+ {
+ prec -= n;
+ if (prec == 0)
+ return 1;
+ mslimb = (*p)[i];
+ }
+ while (mslimb == 0)
+ {
+ prec -= 4;
+ if (prec == 0)
+ return 1;
+ --i;
+ mslimb = (*p)[i];
+ }
+ return prec;
+}
+UDItype
+foo (const bar_t *i, SItype iprec)
+{
+ iprec = bar (&i, iprec);
+ USItype aiprec = iprec < 0 ? -iprec : iprec;
+ bar_t msb = *i;
+ UDItype mantissa = 0;
+ if (aiprec % 4)
+ msb &= ((bar_t) 1 << aiprec) - 1;
+ if (aiprec >= 54)
+ mantissa = (UDItype) msb << 32;
+
+ return (mantissa ^ (UDItype) 0x20000000000000);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr120427-4.c b/gcc/testsuite/gcc.target/i386/pr120427-4.c
new file mode 100644
index 0000000..2b453b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr120427-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include "cold-attribute-4.c"
+
+/* { dg-final { scan-assembler "movl" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr120689.c b/gcc/testsuite/gcc.target/i386/pr120689.c
new file mode 100644
index 0000000..cd10cdb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr120689.c
@@ -0,0 +1,17 @@
+/* PR target/120689 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -mtune=generic -fno-stack-protector -masm=att" } */
+/* { dg-final { scan-assembler-not "\t\(movzbl\|shrl\|salq\|orq\)\t" } } */
+
+struct S { char a, b, c; };
+
+[[gnu::noipa]]
+void foo (struct S x, struct S y, struct S z)
+{
+}
+
+void
+bar (struct S x, struct S y, struct S z)
+{
+ [[gnu::musttail]] return foo (x, y, z);
+}
diff --git a/gcc/testsuite/gcc.target/i386/shrink_wrap_separate_check_lea.c b/gcc/testsuite/gcc.target/i386/shrink_wrap_separate_check_lea.c
new file mode 100644
index 0000000..0f2449f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/shrink_wrap_separate_check_lea.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */
+
+/* Avoid inserting sub between test-je-jle to change EFlags, lea should be used here
+ xorl %eax, %eax
+ testl %edi, %edi
+ je .L11
+ sub $16, %rsp ------> leaq -16(%rsp), %rsp
+ movq %r13, 8(%rsp)
+ movl $1, %r13d
+ jle .L4
+*/
+int foo (int num)
+{
+ if (!num)
+ return 0;
+
+ register int r13 __asm ("r13") = 1;
+
+ for ( int i = 0; i < num; i++)
+ {
+ register int r12 __asm ("r12") = 1;
+ asm volatile ("" : "+r" (r12), "+r" (r13));
+ }
+
+ return 1;
+}
+/* { dg-final { scan-rtl-dump "The components we wrap separately are \\\[sep 40\\\]" "pro_and_epilogue" } } */
+/* { dg-final { scan-assembler "leaq.*(%rsp)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/stack-clash-protection.c b/gcc/testsuite/gcc.target/i386/stack-clash-protection.c
new file mode 100644
index 0000000..5be28cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stack-clash-protection.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection" } */
+
+int flag;
+void open();
+int getChar();
+typedef enum { QUOTE } CharType;
+typedef enum { UNQ } State;
+CharType getCharType();
+void expand() {
+ open();
+ if (flag)
+ return;
+ int ch = getChar();
+ State nextState = getCharType();
+ if (nextState)
+ while (ch)
+ ;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c
index e18a672..c86d77c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */
/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c
index 5feec25..f6524cb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */
/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c
index 2474684..f1e8627 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */
/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c
index 6f062831..9b0cbd2 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */
/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c
index e06829d..bcfd514 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c
index 05fb829..b9a6a28 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c
index 4681f36..abb5e5e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c
index 9b4404f..50065d0 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */
/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */
+/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c
index 6726e23..fb1154c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c
index 8cf7ba9..d4baa4b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c
index 51514e8..18c1a78 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c
index 12d11ba..5ce3c88 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c
index ec1b7d9..c03560a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c
index 40ef107..70fc262 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c
index abf04d1..a368c96 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c
index 400fc3c..581da35 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c
index 2031985..2965924 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c
index 462793f..e7815e9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c
index 65498e3..063a7a1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c
index 908df5e..0efb60c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c
@@ -17,3 +17,4 @@ TEST_BINARY_VX_SIGNED_0(T)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c
index e6d5014..0620953 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c
index 4560862..0aca5b9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c
index 189d554..4dd8f1a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c
index 6a1905e..1508ff3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c
@@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c
index 5d684e6..199f8a7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c
index 6c086d2..392f4fe 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c
index 0abae20..d22c387 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c
index d2955b8..9a832a2 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c
index bee4171..b621643 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c
index 376f1c6..741a749 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c
index 034f50d..70375b1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c
index cfb1ad1..b1c22b3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c
@@ -15,6 +15,7 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +26,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c
index c42c58e..f15fec5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler-not {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c
index a6d1ad0..8d21c47 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c
index ea9c526..0660000 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c
index d1212ea..ce33461 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler-not {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c
index 4793fdf..399045b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c
index daf2501..f3a2fcb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c
index b4fc5c1..d83acaa 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c
index ceb6e37..b629bc9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c
index 30e38f7..3c9afdd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler-not {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c
index f0b6bcd..b80a6b3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c
index ef168ac..15bfe60 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler-not {vadd.vx} } } */
/* { dg-final { scan-assembler-not {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler-not {vdiv.vx} } } */
/* { dg-final { scan-assembler-not {vrem.vx} } } */
/* { dg-final { scan-assembler-not {vmax.vx} } } */
+/* { dg-final { scan-assembler-not {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c
index 9977ff3..4d529fe 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c
@@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler-not {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdiv.vx} } } */
/* { dg-final { scan-assembler {vrem.vx} } } */
/* { dg-final { scan-assembler {vmax.vx} } } */
+/* { dg-final { scan-assembler {vmin.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c
index aee9f12..93e2bf2 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c
index df48fc4..52336ba 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c
index 166cc7d..91be71d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler-not {vadd.vx} } } */
/* { dg-final { scan-assembler-not {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY)
/* { dg-final { scan-assembler-not {vdivu.vx} } } */
/* { dg-final { scan-assembler-not {vremu.vx} } } */
/* { dg-final { scan-assembler-not {vmaxu.vx} } } */
+/* { dg-final { scan-assembler-not {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c
index f19cbdc..4afc04d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c
@@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
+DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vadd.vx} } } */
/* { dg-final { scan-assembler {vsub.vx} } } */
@@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8)
/* { dg-final { scan-assembler {vdivu.vx} } } */
/* { dg-final { scan-assembler {vremu.vx} } } */
/* { dg-final { scan-assembler {vmaxu.vx} } } */
+/* { dg-final { scan-assembler {vminu.vx} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h
index 7bc3049..f47586b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h
@@ -167,6 +167,46 @@ DEF_MAX_1(uint64_t)
#define MAX_FUNC_1(T) test_##T##_max_1
#define MAX_FUNC_1_WARP(T) MAX_FUNC_1(T)
+#define DEF_MIN_0(T) \
+static inline T \
+test_##T##_min_0 (T a, T b) \
+{ \
+ return a > b ? b : a; \
+}
+
+#define DEF_MIN_1(T) \
+static inline T \
+test_##T##_min_1 (T a, T b) \
+{ \
+ return a >= b ? b : a; \
+}
+
+DEF_MIN_0(int8_t)
+DEF_MIN_0(int16_t)
+DEF_MIN_0(int32_t)
+DEF_MIN_0(int64_t)
+
+DEF_MIN_1(int8_t)
+DEF_MIN_1(int16_t)
+DEF_MIN_1(int32_t)
+DEF_MIN_1(int64_t)
+
+DEF_MIN_0(uint8_t)
+DEF_MIN_0(uint16_t)
+DEF_MIN_0(uint32_t)
+DEF_MIN_0(uint64_t)
+
+DEF_MIN_1(uint8_t)
+DEF_MIN_1(uint16_t)
+DEF_MIN_1(uint32_t)
+DEF_MIN_1(uint64_t)
+
+#define MIN_FUNC_0(T) test_##T##_min_0
+#define MIN_FUNC_0_WARP(T) MIN_FUNC_0(T)
+
+#define MIN_FUNC_1(T) test_##T##_min_1
+#define MIN_FUNC_1_WARP(T) MIN_FUNC_1(T)
+
#define DEF_VX_BINARY_CASE_2(T, FUNC, NAME) \
void \
test_vx_binary_##NAME##_##FUNC##_##T##_case_2 (T * restrict out, \
@@ -241,7 +281,9 @@ test_vx_binary_##NAME##_##FUNC##_##T##_case_3 (T * restrict out, \
DEF_VX_BINARY_CASE_0_WRAP(T, /, div) \
DEF_VX_BINARY_CASE_0_WRAP(T, %, rem) \
DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_0_WARP(T), max) \
- DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max)
+ DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max) \
+ DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_0_WARP(T), min) \
+ DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_1_WARP(T), min)
#define TEST_BINARY_VX_UNSIGNED_0(T) \
DEF_VX_BINARY_CASE_0_WRAP(T, +, add) \
@@ -253,6 +295,8 @@ test_vx_binary_##NAME##_##FUNC##_##T##_case_3 (T * restrict out, \
DEF_VX_BINARY_CASE_0_WRAP(T, /, div) \
DEF_VX_BINARY_CASE_0_WRAP(T, %, rem) \
DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_0_WARP(T), max) \
- DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max)
+ DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max) \
+ DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_0_WARP(T), min) \
+ DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_1_WARP(T), min)
#endif
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h
index 41654ec3..9666301 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h
@@ -3730,4 +3730,396 @@ uint64_t TEST_BINARY_DATA(uint64_t, max)[][3][N] =
},
};
+int8_t TEST_BINARY_DATA(int8_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { 127 },
+ {
+ 127, 127, 127, 127,
+ -1, -1, -1, -1,
+ -128, -128, -128, -128,
+ -2, -2, -2, -2,
+ },
+ {
+ 127, 127, 127, 127,
+ -1, -1, -1, -1,
+ -128, -128, -128, -128,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { -128 },
+ {
+ -128, -128, -128, -128,
+ 1, 1, 1, 1,
+ 127, 127, 127, 127,
+ 2, 2, 2, 2,
+ },
+ {
+ -128, -128, -128, -128,
+ -128, -128, -128, -128,
+ -128, -128, -128, -128,
+ -128, -128, -128, -128,
+ },
+ },
+};
+
+int16_t TEST_BINARY_DATA(int16_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { 32767 },
+ {
+ 32767, 32767, 32767, 32767,
+ -1, -1, -1, -1,
+ -32768, -32768, -32768, -32768,
+ -2, -2, -2, -2,
+ },
+ {
+ 32767, 32767, 32767, 32767,
+ -1, -1, -1, -1,
+ -32768, -32768, -32768, -32768,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { -32768 },
+ {
+ -32768, -32768, -32768, -32768,
+ 1, 1, 1, 1,
+ 32767, 32767, 32767, 32767,
+ 2, 2, 2, 2,
+ },
+ {
+ -32768, -32768, -32768, -32768,
+ -32768, -32768, -32768, -32768,
+ -32768, -32768, -32768, -32768,
+ -32768, -32768, -32768, -32768,
+ },
+ },
+};
+
+int32_t TEST_BINARY_DATA(int32_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { 2147483647 },
+ {
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ -1, -1, -1, -1,
+ -2147483648, -2147483648, -2147483648, -2147483648,
+ -2, -2, -2, -2,
+ },
+ {
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ -1, -1, -1, -1,
+ -2147483648, -2147483648, -2147483648, -2147483648,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { -2147483648 },
+ {
+ -2147483648, -2147483648, -2147483648, -2147483648,
+ 1, 1, 1, 1,
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ 2, 2, 2, 2,
+ },
+ {
+ -2147483648, -2147483648, -2147483648, -2147483648,
+ -2147483648, -2147483648, -2147483648, -2147483648,
+ -2147483648, -2147483648, -2147483648, -2147483648,
+ -2147483648, -2147483648, -2147483648, -2147483648,
+ },
+ },
+};
+
+int64_t TEST_BINARY_DATA(int64_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ -1, -1, -1, -1,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { 9223372036854775807ll },
+ {
+ 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll,
+ -1, -1, -1, -1,
+ -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull,
+ -2, -2, -2, -2,
+ },
+ {
+ 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll,
+ -1, -1, -1, -1,
+ -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull,
+ -2, -2, -2, -2,
+ },
+ },
+ {
+ { -9223372036854775808ull },
+ {
+ -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull,
+ 1, 1, 1, 1,
+ 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll,
+ 2, 2, 2, 2,
+ },
+ {
+ -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull,
+ -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull,
+ -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull,
+ -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull,
+ },
+ },
+};
+
+uint8_t TEST_BINARY_DATA(uint8_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ 0, 0, 0, 0,
+ 4, 4, 4, 4,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ },
+ },
+ {
+ { 127 },
+ {
+ 127, 127, 127, 127,
+ 128, 128, 128, 128,
+ 255, 255, 255, 255,
+ 1, 1, 1, 1,
+ },
+ {
+ 127, 127, 127, 127,
+ 127, 127, 127, 127,
+ 127, 127, 127, 127,
+ 1, 1, 1, 1,
+ },
+ },
+ {
+ { 254 },
+ {
+ 128, 128, 128, 128,
+ 255, 255, 255, 255,
+ 127, 127, 127, 127,
+ 2, 2, 2, 2,
+ },
+ {
+ 128, 128, 128, 128,
+ 254, 254, 254, 254,
+ 127, 127, 127, 127,
+ 2, 2, 2, 2,
+ },
+ },
+};
+
+uint16_t TEST_BINARY_DATA(uint16_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ 0, 0, 0, 0,
+ 4, 4, 4, 4,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ },
+ },
+ {
+ { 32767 },
+ {
+ 32767, 32767, 32767, 32767,
+ 32768, 32768, 32768, 32768,
+ 65535, 65535, 65535, 65535,
+ 1, 1, 1, 1,
+ },
+ {
+ 32767, 32767, 32767, 32767,
+ 32767, 32767, 32767, 32767,
+ 32767, 32767, 32767, 32767,
+ 1, 1, 1, 1,
+ },
+ },
+ {
+ { 65534 },
+ {
+ 32768, 32768, 32768, 32768,
+ 65535, 65535, 65535, 65535,
+ 32767, 32767, 32767, 32767,
+ 2, 2, 2, 2,
+ },
+ {
+ 32768, 32768, 32768, 32768,
+ 65534, 65534, 65534, 65534,
+ 32767, 32767, 32767, 32767,
+ 2, 2, 2, 2,
+ },
+ },
+};
+
+uint32_t TEST_BINARY_DATA(uint32_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ 0, 0, 0, 0,
+ 4, 4, 4, 4,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ },
+ },
+ {
+ { 2147483647 },
+ {
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ 2147483648, 2147483648, 2147483648, 2147483648,
+ 4294967295, 4294967295, 4294967295, 4294967295,
+ 1, 1, 1, 1,
+ },
+ {
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ 1, 1, 1, 1,
+ },
+ },
+ {
+ { 4294967294 },
+ {
+ 2147483648, 2147483648, 2147483648, 2147483648,
+ 4294967295, 4294967295, 4294967295, 4294967295,
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ 2, 2, 2, 2,
+ },
+ {
+ 2147483648, 2147483648, 2147483648, 2147483648,
+ 4294967294, 4294967294, 4294967294, 4294967294,
+ 2147483647, 2147483647, 2147483647, 2147483647,
+ 2, 2, 2, 2,
+ },
+ },
+};
+
+uint64_t TEST_BINARY_DATA(uint64_t, min)[][3][N] =
+{
+ {
+ { 0 },
+ {
+ 2, 2, 2, 2,
+ 1, 1, 1, 1,
+ 0, 0, 0, 0,
+ 4, 4, 4, 4,
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ },
+ },
+ {
+ { 9223372036854775807ull },
+ {
+ 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull,
+ 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull,
+ 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull,
+ 1, 1, 1, 1,
+ },
+ {
+ 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull,
+ 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull,
+ 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull,
+ 1, 1, 1, 1,
+ },
+ },
+ {
+ { 18446744073709551614ull },
+ {
+ 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull,
+ 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull,
+ 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull,
+ 2, 2, 2, 2,
+ },
+ {
+ 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull,
+ 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull,
+ 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull,
+ 2, 2, 2, 2,
+ },
+ },
+};
+
#endif
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c
new file mode 100644
index 0000000..180c82bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int16_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c
new file mode 100644
index 0000000..980b63c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int32_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c
new file mode 100644
index 0000000..26fae23
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int64_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c
new file mode 100644
index 0000000..c5c14a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int8_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c
new file mode 100644
index 0000000..5295bb8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint16_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c
new file mode 100644
index 0000000..1e09610
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint32_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c
new file mode 100644
index 0000000..ed757e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint64_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c
new file mode 100644
index 0000000..dd4b93a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint8_t
+#define NAME min
+#define FUNC MIN_FUNC_0_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c
new file mode 100644
index 0000000..bfdabeb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int16_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c
new file mode 100644
index 0000000..af34049
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int32_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c
new file mode 100644
index 0000000..013bd83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int64_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c
new file mode 100644
index 0000000..0f4fd2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T int8_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c
new file mode 100644
index 0000000..5e450d85
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint16_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c
new file mode 100644
index 0000000..45bfd12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint32_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c
new file mode 100644
index 0000000..46f0031
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint64_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c
new file mode 100644
index 0000000..971404b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c
@@ -0,0 +1,17 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */
+
+#include "vx_binary.h"
+#include "vx_binary_data.h"
+
+#define T uint8_t
+#define NAME min
+#define FUNC MIN_FUNC_1_WARP(T)
+#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME)
+
+DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME)
+
+#define TEST_RUN(T, NAME, out, in, x, n) \
+ RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n)
+
+#include "vx_binary_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c
index cd3e961..9bade06 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -fno-tree-vectorize" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -fno-tree-vectorize -mtune=rocket" } */
#include "riscv_vector.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c
index d7f6d18..321eb3b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */
#include "riscv_vector.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c
index 1354c5e..29dcfef 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */
#include "riscv_vector.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c
index 6366dd9..8b6299e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */
#include "riscv_vector.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c
index bbff028..3b836f9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */
#include "riscv_vector.h"
diff --git a/gcc/testsuite/gcc.target/riscv/zalrsc.c b/gcc/testsuite/gcc.target/riscv/zalrsc.c
new file mode 100644
index 0000000..19a26bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zalrsc.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64imfd_zalrsc -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } {"-O0"} } */
+
+/* lr.w/sc.w */
+int *i;
+int lr_sc(int v)
+{
+ return __atomic_exchange_4(i, v, __ATOMIC_RELAXED);
+}
+
+/* { dg-final { scan-assembler-times {\mlr.w} 1 } } */
+/* { dg-final { scan-assembler-times {\msc.w} 1 } } */
+/* { dg-final { scan-assembler-not {"mv\t"} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c
new file mode 100644
index 0000000..1ad1b77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mtune=generic" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mtune=generic" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" "-O3" } } */
+
+#define N 10000
+
+int primitiveSemantics_compare_reg_reg_return_reg_reg_00(int *a, int min_v)
+{
+ int last = 0;
+
+ for (int i = 0; i < N; i++)
+ {
+ if (a[i] < min_v)
+ last = a[i];
+ }
+ return last;
+}
+
+/* { dg-final { scan-assembler-times {\mczero\.nez\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mczero\.eqz\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c
new file mode 100644
index 0000000..3602626
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zilsd -mabi=ilp32" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long long y;
+long long foo(long long x)
+{
+ return y + x;
+}
+
+/* { dg-final { scan-assembler-times "ld\t" 1 } } */
+/* { dg-final { scan-assembler-not "lw\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c
new file mode 100644
index 0000000..3adcd21
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zilsd -mabi=ilp32" } */
+
+long long y;
+long long foo(long long x)
+{
+ return y >> x;
+}
+/* TODO: We should not split that 64 bit load into two 32 bit load if we have
+ zilsd, but we split that during the expand time, so it's hard to fix via cost
+ model turning, we could either fix that for expander, or...combine those two
+ 32 bit load back later. */
+/* { dg-final { scan-assembler-times "ld\t" 1 { xfail riscv*-*-* } } } */
+
+/* Os and Oz will use libcall, so the 64 bit load won't be split. */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Oz" } } */
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c
index 5f3d3e1..46fc464 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c
+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-vectorize -mabi=sysv" } */
+/* { dg-options "-O2 -fno-tree-vectorize -mabi=sysv -fno-shrink-wrap-separate" } */
extern int glb1, gbl2, gbl3;
diff --git a/gcc/testsuite/gfortran.dg/guality/arg1.f90 b/gcc/testsuite/gfortran.dg/guality/arg1.f90
index 332a4ed..775b7bb 100644
--- a/gcc/testsuite/gfortran.dg/guality/arg1.f90
+++ b/gcc/testsuite/gfortran.dg/guality/arg1.f90
@@ -1,5 +1,5 @@
! { dg-do run }
-! { dg-options "-g" }
+! { dg-options "-fno-shrink-wrap -g" }
integer :: a(10), b(12)
call sub (a, 10)
call sub (b, 12)
diff --git a/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90 b/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90
new file mode 100644
index 0000000..e26919f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90
@@ -0,0 +1,23 @@
+! { dg-do run }
+!
+! PR fortran/120713
+! Check that the length variable of SAVEd allocatable character arrays are
+! not initialized at function entry.
+
+program p
+ implicit none
+ call s(1)
+ call s(2)
+contains
+ subroutine s(i)
+ integer, intent(in) :: i
+ character(len=:), allocatable, save :: a(:)
+ integer :: j
+ if (i == 1) then
+ allocate(a, source= [ ('x' // achar(ichar('0') + j), j=1,7) ])
+ else
+ if (len(a) /= 2) error stop 1
+ if (any(a /= ['x1','x2','x3','x4','x5','x6','x7'])) error stop 2
+ end if
+ end subroutine s
+end program p
diff --git a/gcc/testsuite/gfortran.dg/stat_3.f90 b/gcc/testsuite/gfortran.dg/stat_3.f90
new file mode 100644
index 0000000..93ec183
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/stat_3.f90
@@ -0,0 +1,46 @@
+! { dg-do compile }
+! PR fortran/82480 - checking of arguments to STAT/LSTAT/FSTAT
+
+subroutine sub1 ()
+ integer, parameter :: ik = kind(1)
+ integer(ik) :: buff12(12)
+ integer(ik) :: buff13(13)
+ integer(ik) :: unit = 10
+ integer(ik) :: ierr
+ character(len=64) :: name = "/etc/passwd"
+ ierr = stat (name, values= buff12) ! { dg-error "too small" }
+ ierr = stat (name, values= buff13)
+ ierr = lstat (name, values= buff12) ! { dg-error "too small" }
+ ierr = lstat (name, values= buff13)
+ ierr = fstat (unit, values= buff12) ! { dg-error "too small" }
+ ierr = fstat (unit, values= buff13)
+ ierr = stat (name, values=(buff13)) ! { dg-error "must be a variable" }
+ ierr = lstat (name, values=(buff13)) ! { dg-error "must be a variable" }
+ ierr = fstat (unit, values=(buff13)) ! { dg-error "must be a variable" }
+end
+
+subroutine sub2 ()
+ integer, parameter :: ik = kind(1)
+ integer(ik) :: buff12(12)
+ integer(ik), target :: buff13(13) = 0
+ integer(ik) :: unit = 10
+ integer(ik), target :: ierr = 0
+ character(len=64) :: name = "/etc/passwd"
+ integer(ik),pointer :: pbuf(:) => buff13
+ integer(ik),pointer :: perr => ierr
+ call stat (name, status=ierr, values= buff12) ! { dg-error "too small" }
+ call stat (name, status=ierr, values= buff13)
+ call lstat (name, status=ierr, values= buff12) ! { dg-error "too small" }
+ call lstat (name, status=ierr, values= buff13)
+ call fstat (unit, status=ierr, values= buff12) ! { dg-error "too small" }
+ call fstat (unit, status=ierr, values= buff13)
+ call stat (name, status=ierr, values=(buff13)) ! { dg-error "must be a variable" }
+ call lstat (name, status=ierr, values=(buff13)) ! { dg-error "must be a variable" }
+ call fstat (unit, status=ierr, values=(buff13)) ! { dg-error "must be a variable" }
+ call stat (name, status=(ierr),values=buff13) ! { dg-error "must be a variable" }
+ call lstat (name, status=(ierr),values=buff13) ! { dg-error "must be a variable" }
+ call fstat (unit, status=(ierr),values=buff13) ! { dg-error "must be a variable" }
+ call stat (name, status=perr, values= pbuf)
+ call lstat (name, status=perr, values= pbuf)
+ call fstat (unit, status=perr, values= pbuf)
+end
diff --git a/gcc/testsuite/gm2/pim/fail/badmodvar.mod b/gcc/testsuite/gm2/pim/fail/badmodvar.mod
new file mode 100644
index 0000000..dd90920
--- /dev/null
+++ b/gcc/testsuite/gm2/pim/fail/badmodvar.mod
@@ -0,0 +1,7 @@
+MODULE badmodvar ;
+
+VAR
+ x: y ;
+BEGIN
+
+END badmodvar.
diff --git a/gcc/testsuite/gm2/pim/fail/cyclictypes.mod b/gcc/testsuite/gm2/pim/fail/cyclictypes.mod
new file mode 100644
index 0000000..f2adb49
--- /dev/null
+++ b/gcc/testsuite/gm2/pim/fail/cyclictypes.mod
@@ -0,0 +1,13 @@
+MODULE cyclictypes ;
+
+TYPE
+ A = B;
+ B = A;
+
+PROCEDURE foo ;
+VAR
+ bar: A ;
+END foo ;
+
+
+END cyclictypes.
diff --git a/gcc/testsuite/gm2/pim/fail/cyclictypes2.mod b/gcc/testsuite/gm2/pim/fail/cyclictypes2.mod
new file mode 100644
index 0000000..a5630c8
--- /dev/null
+++ b/gcc/testsuite/gm2/pim/fail/cyclictypes2.mod
@@ -0,0 +1,9 @@
+MODULE cyclictypes2 ;
+
+TYPE
+ A = B;
+ B = A;
+
+VAR
+ bar: A ;
+END cyclictypes2.
diff --git a/gcc/testsuite/gm2/pim/fail/cyclictypes4.mod b/gcc/testsuite/gm2/pim/fail/cyclictypes4.mod
new file mode 100644
index 0000000..69f061b
--- /dev/null
+++ b/gcc/testsuite/gm2/pim/fail/cyclictypes4.mod
@@ -0,0 +1,13 @@
+MODULE cyclictypes4 ;
+
+TYPE
+ A = B ;
+ B = C ;
+ C = D ;
+ D = A ;
+
+VAR
+ v: A ;
+BEGIN
+
+END cyclictypes4.
diff --git a/gcc/testsuite/gnat.dg/specs/aggr8.ads b/gcc/testsuite/gnat.dg/specs/aggr8.ads
new file mode 100644
index 0000000..3847c4e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/aggr8.ads
@@ -0,0 +1,14 @@
+-- PR ada/120665
+-- { dg-do compile }
+-- { dg-options "-gnat2022" }
+
+package Aggr8 is
+
+ type T is null record
+ with Aggregate => (Empty => Empty, Add_Named => Add_Named);
+
+ function Empty return T is ([]); -- { dg-warning "empty|infinite" }
+
+ procedure Add_Named (this : in out T; k : Integer; v : Integer) is null;
+
+end Aggr8;
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 1c5427e..72763fd 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -8339,7 +8339,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
fprintf (file, ", ");
tree name = get_attribute_name (chain);
- print_generic_expr (file, name, dump_flags);
+ print_generic_expr (file, name, flags);
if (TREE_VALUE (chain) != NULL_TREE)
{
fprintf (file, " (");
@@ -8350,13 +8350,13 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
"omp declare variant base"))
{
tree a = TREE_VALUE (chain);
- print_generic_expr (file, TREE_PURPOSE (a), dump_flags);
+ print_generic_expr (file, TREE_PURPOSE (a), flags);
fprintf (file, " match ");
print_omp_context_selector (file, TREE_VALUE (a),
- dump_flags);
+ flags);
}
else
- print_generic_expr (file, TREE_VALUE (chain), dump_flags);
+ print_generic_expr (file, TREE_VALUE (chain), flags);
fprintf (file, ")");
}
}
@@ -8378,7 +8378,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
}
print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)),
- dump_flags | TDF_SLIM);
+ flags | TDF_SLIM);
fprintf (file, " __GIMPLE (%s",
(fun->curr_properties & PROP_ssa) ? "ssa"
: (fun->curr_properties & PROP_cfg) ? "cfg"
@@ -8391,7 +8391,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
fprintf (file, ",%s(%" PRIu64 ")",
profile_quality_as_string (bb->count.quality ()),
bb->count.value ());
- if (dump_flags & TDF_UID)
+ if (flags & TDF_UID)
fprintf (file, ")\n%sD_%u (", function_name (fun),
DECL_UID (fndecl));
else
@@ -8400,8 +8400,8 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
}
else
{
- print_generic_expr (file, TREE_TYPE (fntype), dump_flags);
- if (dump_flags & TDF_UID)
+ print_generic_expr (file, TREE_TYPE (fntype), flags);
+ if (flags & TDF_UID)
fprintf (file, " %sD.%u %s(", function_name (fun), DECL_UID (fndecl),
tmclone ? "[tm-clone] " : "");
else
@@ -8412,9 +8412,9 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
arg = DECL_ARGUMENTS (fndecl);
while (arg)
{
- print_generic_expr (file, TREE_TYPE (arg), dump_flags);
+ print_generic_expr (file, TREE_TYPE (arg), flags);
fprintf (file, " ");
- print_generic_expr (file, arg, dump_flags);
+ print_generic_expr (file, arg, flags);
if (DECL_CHAIN (arg))
fprintf (file, ", ");
arg = DECL_CHAIN (arg);
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index e2d75f5..0f0770a 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1628,10 +1628,8 @@ irange::contains_p (const wide_int &cst) const
if (undefined_p ())
return false;
- // See if we can exclude CST based on the known 0 bits.
- if (!m_bitmask.unknown_p ()
- && cst != 0
- && wi::bit_and (m_bitmask.get_nonzero_bits (), cst) == 0)
+ // Check is the known bits in bitmask exclude CST.
+ if (!m_bitmask.member_p (cst))
return false;
signop sign = TYPE_SIGN (type ());
@@ -1899,12 +1897,17 @@ irange::irange_contains_p (const irange &r) const
gcc_checking_assert (!undefined_p () && !varying_p ());
gcc_checking_assert (!r.undefined_p () && !varying_p ());
+ // Check singletons directly which will include any bitmasks.
+ wide_int rl;
+ if (r.singleton_p (rl))
+ return contains_p (rl);
+
// In order for THIS to fully contain R, all of the pairs within R must
// be fully contained by the pairs in this object.
signop sign = TYPE_SIGN (m_type);
unsigned ri = 0;
unsigned i = 0;
- wide_int rl = r.m_base[0];
+ rl = r.m_base[0];
wide_int ru = r.m_base[1];
wide_int l = m_base[0];
wide_int u = m_base[1];
@@ -1973,6 +1976,16 @@ irange::intersect (const vrange &v)
return res;
}
+ // If either range is a singleton and the other range does not contain
+ // it, the result is undefined.
+ wide_int val;
+ if ((singleton_p (val) && !r.contains_p (val))
+ || (r.singleton_p (val) && !contains_p (val)))
+ {
+ set_undefined ();
+ return true;
+ }
+
// If R fully contains this, then intersection will change nothing.
if (r.irange_contains_p (*this))
return intersect_bitmask (r);
@@ -2254,6 +2267,94 @@ irange::invert ()
verify_range ();
}
+// This routine will take the bounds [LB, UB], and apply the bitmask to those
+// values such that both bounds satisfy the bitmask. TRUE is returned
+// if either bound changes, and they are retuirned as [NEW_LB, NEW_UB].
+// if NEW_UB < NEW_LB, then the entire bound is to be removed as none of
+// the values are valid.
+// ie, [4, 14] MASK 0xFFFE VALUE 0x1
+// means all values must be odd, the new bounds returned will be [5, 13].
+// ie, [4, 4] MASK 0xFFFE VALUE 0x1
+// would return [1, 0] and as the LB < UB, the entire subrange is invalid
+// and should be removed.
+
+bool
+irange::snap (const wide_int &lb, const wide_int &ub,
+ wide_int &new_lb, wide_int &new_ub)
+{
+ uint z = wi::ctz (m_bitmask.mask ());
+ if (z == 0)
+ return false;
+ const wide_int &wild_mask = m_bitmask.mask ();
+
+ const wide_int step = (wi::one (TYPE_PRECISION (type ())) << z);
+ const wide_int match_mask = step - 1;
+ const wide_int value = m_bitmask.value () & match_mask;
+
+ wide_int rem_lb = lb & match_mask;
+
+ wi::overflow_type ov_sub;
+ wide_int diff = wi::sub(value, rem_lb, UNSIGNED, &ov_sub);
+ wide_int offset = diff & match_mask;
+
+ wi::overflow_type ov1;
+ new_lb = wi::add (lb, offset, UNSIGNED, &ov1);
+
+ wide_int rem_ub = ub & match_mask;
+ wide_int offset_ub = (rem_ub - value) & match_mask;
+
+ wi::overflow_type ov2;
+ new_ub = wi::sub (ub, offset_ub, UNSIGNED, &ov2);
+
+ // Overflow or inverted range = invalid
+ if (ov1 != wi::OVF_NONE || ov2 != wi::OVF_NONE
+ || wi::lt_p (new_ub, new_lb, TYPE_SIGN (type ())))
+ {
+ new_lb = wi::one (lb.get_precision ());
+ new_ub = wi::zero (ub.get_precision ());
+ return true;
+ }
+ return (new_lb != lb) || (new_ub != ub);
+}
+
+// This method loops through the subranges in THIS, and adjusts any bounds
+// to satisfy the contraints of the BITMASK. If a subrange is invalid,
+// it is removed. TRUE is returned if there were any changes.
+
+bool
+irange::snap_subranges ()
+{
+ bool changed = false;
+ int_range_max invalid;
+ unsigned x;
+ wide_int lb, ub;
+ for (x = 0; x < m_num_ranges; x++)
+ {
+ if (snap (lower_bound (x), upper_bound (x), lb, ub))
+ {
+ changed = true;
+ // This subrange is to be completely removed.
+ if (wi::lt_p (ub, lb, TYPE_SIGN (type ())))
+ {
+ int_range<1> tmp (type (), lower_bound (x), upper_bound (x));
+ invalid.union_ (tmp);
+ continue;
+ }
+ if (lower_bound (x) != lb)
+ m_base[x * 2] = lb;
+ if (upper_bound (x) != ub)
+ m_base[x * 2 + 1] = ub;
+ }
+ }
+ // Remove any subranges which are no invalid.
+ if (!invalid.undefined_p ())
+ {
+ invalid.invert ();
+ intersect (invalid);
+ }
+ return changed;
+}
+
// If the mask can be trivially converted to a range, do so.
// Otherwise attempt to remove the lower bits from the range.
// Return true if the range changed in any way.
@@ -2353,6 +2454,9 @@ irange::set_range_from_bitmask ()
// Make sure we call intersect, so do it first.
changed = intersect (mask_range) | changed;
+ // Npw make sure each subrange endpoint matches the bitmask.
+ changed |= snap_subranges ();
+
return changed;
}
@@ -2444,15 +2548,14 @@ irange::intersect_bitmask (const irange &r)
irange_bitmask bm = get_bitmask ();
irange_bitmask save = bm;
bm.intersect (r.get_bitmask ());
- if (save == bm)
- return false;
-
+ // Use ths opportunity to make sure mask reflects always reflects the
+ // best mask we have.
m_bitmask = bm;
// Updating m_bitmask may still yield a semantic bitmask (as
// returned by get_bitmask) which is functionally equivalent to what
// we originally had. In which case, there's still no change.
- if (save == get_bitmask ())
+ if (save == bm || save == get_bitmask ())
return false;
if (!set_range_from_bitmask ())
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 74cdf29..c32c507 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -344,6 +344,8 @@ private:
bool intersect_bitmask (const irange &r);
bool union_bitmask (const irange &r);
bool set_range_from_bitmask ();
+ bool snap_subranges ();
+ bool snap (const wide_int &, const wide_int &, wide_int &, wide_int &);
bool intersect (const wide_int& lb, const wide_int& ub);
bool union_append (const irange &r);
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 4c78759..ff11656 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -513,85 +513,6 @@ simplify_using_ranges::legacy_fold_cond (gcond *stmt, edge *taken_edge_p)
}
}
-/* Searches the case label vector VEC for the ranges of CASE_LABELs that are
- used in range VR. The indices are placed in MIN_IDX1, MAX_IDX, MIN_IDX2 and
- MAX_IDX2. If the ranges of CASE_LABELs are empty then MAX_IDX1 < MIN_IDX1.
- Returns true if the default label is not needed. */
-
-static bool
-find_case_label_ranges (gswitch *stmt, const irange *vr,
- size_t *min_idx1, size_t *max_idx1,
- size_t *min_idx2, size_t *max_idx2)
-{
- size_t i, j, k, l;
- unsigned int n = gimple_switch_num_labels (stmt);
- bool take_default;
- tree case_low, case_high;
- tree min, max;
- value_range_kind kind = get_legacy_range (*vr, min, max);
-
- gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
-
- take_default = !find_case_label_range (stmt, min, max, &i, &j);
-
- /* Set second range to empty. */
- *min_idx2 = 1;
- *max_idx2 = 0;
-
- if (kind == VR_RANGE)
- {
- *min_idx1 = i;
- *max_idx1 = j;
- return !take_default;
- }
-
- /* Set first range to all case labels. */
- *min_idx1 = 1;
- *max_idx1 = n - 1;
-
- if (i > j)
- return false;
-
- /* Make sure all the values of case labels [i , j] are contained in
- range [MIN, MAX]. */
- case_low = CASE_LOW (gimple_switch_label (stmt, i));
- case_high = CASE_HIGH (gimple_switch_label (stmt, j));
- if (tree_int_cst_compare (case_low, min) < 0)
- i += 1;
- if (case_high != NULL_TREE
- && tree_int_cst_compare (max, case_high) < 0)
- j -= 1;
-
- if (i > j)
- return false;
-
- /* If the range spans case labels [i, j], the corresponding anti-range spans
- the labels [1, i - 1] and [j + 1, n - 1]. */
- k = j + 1;
- l = n - 1;
- if (k > l)
- {
- k = 1;
- l = 0;
- }
-
- j = i - 1;
- i = 1;
- if (i > j)
- {
- i = k;
- j = l;
- k = 1;
- l = 0;
- }
-
- *min_idx1 = i;
- *max_idx1 = j;
- *min_idx2 = k;
- *max_idx2 = l;
- return false;
-}
-
/* Simplify boolean operations if the source is known
to be already a boolean. */
bool
@@ -1023,6 +944,10 @@ range_fits_type_p (const irange *vr,
widest_int tem;
signop src_sgn;
+ /* Now we can only handle ranges with constant bounds. */
+ if (vr->undefined_p () || vr->varying_p ())
+ return false;
+
/* We can only handle integral and pointer types. */
src_type = vr->type ();
if (!INTEGRAL_TYPE_P (src_type)
@@ -1031,17 +956,13 @@ range_fits_type_p (const irange *vr,
/* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED,
and so is an identity transform. */
- src_precision = TYPE_PRECISION (vr->type ());
+ src_precision = TYPE_PRECISION (src_type);
src_sgn = TYPE_SIGN (src_type);
if ((src_precision < dest_precision
&& !(dest_sgn == UNSIGNED && src_sgn == SIGNED))
|| (src_precision == dest_precision && src_sgn == dest_sgn))
return true;
- /* Now we can only handle ranges with constant bounds. */
- if (vr->undefined_p () || vr->varying_p ())
- return false;
-
wide_int vrmin = vr->lower_bound ();
wide_int vrmax = vr->upper_bound ();
@@ -1374,157 +1295,99 @@ bool
simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
{
tree op = gimple_switch_index (stmt);
- int_range_max vr;
- bool take_default;
+ tree type = TREE_TYPE (op);
+ int_range_max op_range (type);
+ int_range_max default_range (type);
+ auto_vec<unsigned> cases;
+ cases.truncate (0);
edge e;
- edge_iterator ei;
- size_t i = 0, j = 0, n, n2;
- tree vec2;
switch_update su;
- size_t k = 1, l = 0;
-
- if (TREE_CODE (op) == SSA_NAME)
- {
- if (!query->range_of_expr (vr, op, stmt)
- || vr.varying_p () || vr.undefined_p ())
- return false;
- /* Find case label for min/max of the value range. */
- take_default = !find_case_label_ranges (stmt, &vr, &i, &j, &k, &l);
- }
- else if (TREE_CODE (op) == INTEGER_CST)
- {
- take_default = !find_case_label_index (stmt, 1, op, &i);
- if (take_default)
- {
- i = 1;
- j = 0;
- }
- else
- {
- j = i;
- }
- }
- else
+ // Abort if we don't have a useful range for the switch index.
+ if (!query->range_of_expr (op_range, op, stmt)
+ || op_range.varying_p () || op_range.undefined_p ())
return false;
- n = gimple_switch_num_labels (stmt);
+ // Default range starts with full known range of op.
+ default_range = op_range;
+ edge default_edge = gimple_switch_default_edge (cfun, stmt);
- /* We can truncate the case label ranges that partially overlap with OP's
- value range. */
- size_t min_idx = 1, max_idx = 0;
- tree min, max;
- value_range_kind kind = get_legacy_range (vr, min, max);
- if (!vr.undefined_p ())
- find_case_label_range (stmt, min, max, &min_idx, &max_idx);
- if (min_idx <= max_idx)
+ unsigned x, lim = gimple_switch_num_labels (stmt);
+ for (x = 1; x < lim; x++)
{
- tree min_label = gimple_switch_label (stmt, min_idx);
- tree max_label = gimple_switch_label (stmt, max_idx);
+ e = gimple_switch_edge (cfun, stmt, x);
+ tree label = gimple_switch_label (stmt, x);
+
+ // If this edge is the same as the default edge, do nothing else.
+ if (e == default_edge)
+ continue;
+ // Ada sometimes has mismatched labels and index. Just bail.
+ if (TREE_TYPE (CASE_LOW (label)) != type)
+ return false;
- /* Avoid changing the type of the case labels when truncating. */
- tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
- tree vr_min = fold_convert (case_label_type, min);
- tree vr_max = fold_convert (case_label_type, max);
+ wide_int low = wi::to_wide (CASE_LOW (label));
+ wide_int high;
+ // Singleton cases have no CASE_HIGH.
+ tree tree_high = CASE_HIGH (label);
+ if (tree_high)
+ high = wi::to_wide (tree_high);
+ else
+ high = low;
- if (kind == VR_RANGE)
+ // If the case range is fully contained in op_range, leave the
+ // case as it is, otherwise adjust the labels.
+ int_range_max case_range (type, low, high);
+ if (case_range.intersect (op_range))
{
- /* If OP's value range is [2,8] and the low label range is
- 0 ... 3, truncate the label's range to 2 .. 3. */
- if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
- && CASE_HIGH (min_label) != NULL_TREE
- && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
- CASE_LOW (min_label) = vr_min;
-
- /* If OP's value range is [2,8] and the high label range is
- 7 ... 10, truncate the label's range to 7 .. 8. */
- if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
- && CASE_HIGH (max_label) != NULL_TREE
- && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
- CASE_HIGH (max_label) = vr_max;
- }
- else if (kind == VR_ANTI_RANGE)
- {
- tree one_cst = build_one_cst (case_label_type);
-
- if (min_label == max_label)
- {
- /* If OP's value range is ~[7,8] and the label's range is
- 7 ... 10, truncate the label's range to 9 ... 10. */
- if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) == 0
- && CASE_HIGH (min_label) != NULL_TREE
- && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) > 0)
- CASE_LOW (min_label)
- = int_const_binop (PLUS_EXPR, vr_max, one_cst);
-
- /* If OP's value range is ~[7,8] and the label's range is
- 5 ... 8, truncate the label's range to 5 ... 6. */
- if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
- && CASE_HIGH (min_label) != NULL_TREE
- && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) == 0)
- CASE_HIGH (min_label)
- = int_const_binop (MINUS_EXPR, vr_min, one_cst);
- }
+ // If none of the label is in op_range, skip this label.
+ if (case_range.undefined_p ())
+ continue;
+
+ // Part of the label is in op_range, but not all of it. CASE_RANGE
+ // contains the part that is. Adjust the case range to
+ // the new min/max.
+ if (case_range.lower_bound () != low)
+ CASE_LOW (label) = wide_int_to_tree (type,
+ case_range.lower_bound ());
+ if (case_range.singleton_p ())
+ CASE_HIGH (label) = NULL_TREE;
else
- {
- /* If OP's value range is ~[2,8] and the low label range is
- 0 ... 3, truncate the label's range to 0 ... 1. */
- if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
- && CASE_HIGH (min_label) != NULL_TREE
- && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
- CASE_HIGH (min_label)
- = int_const_binop (MINUS_EXPR, vr_min, one_cst);
-
- /* If OP's value range is ~[2,8] and the high label range is
- 7 ... 10, truncate the label's range to 9 ... 10. */
- if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
- && CASE_HIGH (max_label) != NULL_TREE
- && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
- CASE_LOW (max_label)
- = int_const_binop (PLUS_EXPR, vr_max, one_cst);
- }
+ if (case_range.upper_bound () != high)
+ CASE_HIGH (label) = wide_int_to_tree (type,
+ case_range.upper_bound ());
}
-
- /* Canonicalize singleton case ranges. */
- if (tree_int_cst_equal (CASE_LOW (min_label), CASE_HIGH (min_label)))
- CASE_HIGH (min_label) = NULL_TREE;
- if (tree_int_cst_equal (CASE_LOW (max_label), CASE_HIGH (max_label)))
- CASE_HIGH (max_label) = NULL_TREE;
+ // Add case label to the keep list.
+ cases.safe_push (x);
+ // Remove case_range from needing to be handled by the default.
+ case_range.invert ();
+ default_range.intersect (case_range);
}
- /* We can also eliminate case labels that lie completely outside OP's value
- range. */
-
- /* Bail out if this is just all edges taken. */
- if (i == 1
- && j == n - 1
- && take_default)
+ // An undefined DEFAULT range means the current default case is not needed.
+ unsigned idx = default_range.undefined_p () ? 0 : 1;
+ unsigned vec_size = cases.length () + idx;
+ if (vec_size == lim)
return false;
- /* Build a new vector of taken case labels. */
- vec2 = make_tree_vec (j - i + 1 + l - k + 1 + (int)take_default);
- n2 = 0;
-
- /* Add the default edge, if necessary. */
- if (take_default)
- TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt);
-
- for (; i <= j; ++i, ++n2)
- TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i);
-
- for (; k <= l; ++k, ++n2)
- TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, k);
+ tree vec2 = make_tree_vec (vec_size);
+ // Add default label if there is one.
+ if (idx)
+ {
+ TREE_VEC_ELT (vec2, 0) = gimple_switch_default_label (stmt);
+ e = gimple_switch_edge (cfun, stmt, 0);
+ e->aux = (void *)-1;
+ }
- /* Mark needed edges. */
- for (i = 0; i < n2; ++i)
+ for (x = 0; x < cases.length (); x++)
{
- e = find_edge (gimple_bb (stmt),
- label_to_block (cfun,
- CASE_LABEL (TREE_VEC_ELT (vec2, i))));
- e->aux = (void *)-1;
+ unsigned swi = cases[x];
+ TREE_VEC_ELT (vec2, idx++) = gimple_switch_label (stmt, swi);
+ e = gimple_switch_edge (cfun, stmt, swi);
+ e->aux = (void *)-1;
}
/* Queue not needed edges for later removal. */
+ edge_iterator ei;
FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
{
if (e->aux == (void *)-1)
diff --git a/include/longlong.h b/include/longlong.h
index 40f9424..5ae250f 100644
--- a/include/longlong.h
+++ b/include/longlong.h
@@ -1065,6 +1065,20 @@ extern UDItype __umulsidi3 (USItype, USItype);
#endif
#if defined(__riscv)
+
+#ifdef __riscv_zbb
+#if W_TYPE_SIZE == 32
+#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X))
+#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X))
+#define COUNT_LEADING_ZEROS_0 32
+#endif /* W_TYPE_SIZE == 32 */
+#if W_TYPE_SIZE == 64
+#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clzll (X))
+#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctzll (X))
+#define COUNT_LEADING_ZEROS_0 64
+#endif /* W_TYPE_SIZE == 64 */
+#endif /* __riscv_zbb */
+
#ifdef __riscv_mul
#define __umulsidi3(u,v) ((UDWtype)(UWtype)(u) * (UWtype)(v))
#define __muluw3(a, b) ((UWtype)(a) * (UWtype)(b))
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 8c10718..3c5bae1 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,8 @@
+2025-06-17 Jason Merrill <jason@redhat.com>
+
+ * line-map.cc (linemap_location_from_module_p): Add.
+ * include/line-map.h: Declare it.
+
2025-06-11 David Malcolm <dmalcolm@redhat.com>
PR other/116792
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 83ebbde..21a59af 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -1111,6 +1111,10 @@ extern location_t linemap_module_loc
extern void linemap_module_reparent
(line_maps *, location_t loc, location_t new_parent);
+/* TRUE iff the location comes from a module import. */
+extern bool linemap_location_from_module_p
+ (const line_maps *, location_t);
+
/* Restore the linemap state such that the map at LWM-1 continues.
Return start location of the new map. */
extern location_t linemap_module_restore
diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc
index 284af57..33701b5 100644
--- a/libcpp/line-map.cc
+++ b/libcpp/line-map.cc
@@ -767,6 +767,17 @@ linemap_module_restore (line_maps *set, line_map_uint_t lwm)
return 0;
}
+/* TRUE iff the location comes from a module import. */
+
+bool
+linemap_location_from_module_p (const line_maps *set, location_t loc)
+{
+ const line_map_ordinary *map = linemap_ordinary_map_lookup (set, loc);
+ while (map && map->reason != LC_MODULE)
+ map = linemap_included_from_linemap (set, map);
+ return !!map;
+}
+
/* Returns TRUE if the line table set tracks token locations across
macro expansion, FALSE otherwise. */
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index f0f1597..057b850 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,24 @@
+2025-06-18 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/82480
+ * intrinsics/stat.c (stat_i4_sub_0): Fix argument names. Rename
+ SARRAY to VALUES also in error message. When array VALUES is
+ KIND=4, get only stat components that do not overflow INT32_MAX,
+ otherwise set the corresponding VALUES elements to -1.
+ (stat_i4_sub): Fix argument names.
+ (lstat_i4_sub): Likewise.
+ (stat_i8_sub_0): Likewise.
+ (stat_i8_sub): Likewise.
+ (lstat_i8_sub): Likewise.
+ (stat_i4): Likewise.
+ (stat_i8): Likewise.
+ (lstat_i4): Likewise.
+ (lstat_i8): Likewise.
+ (fstat_i4_sub): Likewise.
+ (fstat_i8_sub): Likewise.
+ (fstat_i4): Likewise.
+ (fstat_i8): Likewise.
+
2025-06-11 François-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR libfortran/116400
diff --git a/libgfortran/intrinsics/stat.c b/libgfortran/intrinsics/stat.c
index 8d32f22..63a57cd 100644
--- a/libgfortran/intrinsics/stat.c
+++ b/libgfortran/intrinsics/stat.c
@@ -35,22 +35,22 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifdef HAVE_STAT
-/* SUBROUTINE STAT(FILE, SARRAY, STATUS)
+/* SUBROUTINE STAT(NAME, VALUES, STATUS)
CHARACTER(len=*), INTENT(IN) :: FILE
- INTEGER, INTENT(OUT), :: SARRAY(13)
+ INTEGER, INTENT(OUT), :: VALUES(13)
INTEGER, INTENT(OUT), OPTIONAL :: STATUS
- FUNCTION STAT(FILE, SARRAY)
+ FUNCTION STAT(NAME, VALUES)
INTEGER STAT
CHARACTER(len=*), INTENT(IN) :: FILE
- INTEGER, INTENT(OUT), :: SARRAY(13) */
+ INTEGER, INTENT(OUT), :: VALUES(13) */
/*extern void stat_i4_sub_0 (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
gfc_charlen_type, int);
internal_proto(stat_i4_sub_0);*/
static void
-stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
+stat_i4_sub_0 (char *name, gfc_array_i4 *values, GFC_INTEGER_4 *status,
gfc_charlen_type name_len, int is_lstat __attribute__ ((unused)))
{
int val;
@@ -58,12 +58,12 @@ stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
struct stat sb;
/* If the rank of the array is not 1, abort. */
- if (GFC_DESCRIPTOR_RANK (sarray) != 1)
- runtime_error ("Array rank of SARRAY is not 1.");
+ if (GFC_DESCRIPTOR_RANK (values) != 1)
+ runtime_error ("Array rank of VALUES is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
- runtime_error ("Array size of SARRAY is too small.");
+ if (GFC_DESCRIPTOR_EXTENT(values,0) < 13)
+ runtime_error ("Array size of VALUES is too small.");
/* Make a null terminated copy of the string. */
str = fc_strdup (name, name_len);
@@ -80,57 +80,70 @@ stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
if (val == 0)
{
- index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
+ index_type stride = GFC_DESCRIPTOR_STRIDE(values,0);
+
+ /* Return -1 for any value overflowing INT32_MAX. */
+ for (int i = 0; i < 13; i++)
+ values->base_addr[i * stride] = -1;
/* Device ID */
- sarray->base_addr[0 * stride] = sb.st_dev;
+ if (sb.st_dev <= INT32_MAX)
+ values->base_addr[0 * stride] = sb.st_dev;
/* Inode number */
- sarray->base_addr[1 * stride] = sb.st_ino;
+ if (sb.st_ino <= INT32_MAX)
+ values->base_addr[1 * stride] = sb.st_ino;
/* File mode */
- sarray->base_addr[2 * stride] = sb.st_mode;
+ if (sb.st_mode <= INT32_MAX)
+ values->base_addr[2 * stride] = sb.st_mode;
/* Number of (hard) links */
- sarray->base_addr[3 * stride] = sb.st_nlink;
+ if (sb.st_nlink <= INT32_MAX)
+ values->base_addr[3 * stride] = sb.st_nlink;
/* Owner's uid */
- sarray->base_addr[4 * stride] = sb.st_uid;
+ if (sb.st_uid <= INT32_MAX)
+ values->base_addr[4 * stride] = sb.st_uid;
/* Owner's gid */
- sarray->base_addr[5 * stride] = sb.st_gid;
+ if (sb.st_gid <= INT32_MAX)
+ values->base_addr[5 * stride] = sb.st_gid;
/* ID of device containing directory entry for file (0 if not available) */
#if HAVE_STRUCT_STAT_ST_RDEV
- sarray->base_addr[6 * stride] = sb.st_rdev;
+ if (sb.st_rdev <= INT32_MAX)
+ values->base_addr[6 * stride] = sb.st_rdev;
#else
- sarray->base_addr[6 * stride] = 0;
+ values->base_addr[6 * stride] = 0;
#endif
/* File size (bytes) */
- sarray->base_addr[7 * stride] = sb.st_size;
+ if (sb.st_size <= INT32_MAX)
+ values->base_addr[7 * stride] = sb.st_size;
/* Last access time */
- sarray->base_addr[8 * stride] = sb.st_atime;
+ if (sb.st_atime <= INT32_MAX)
+ values->base_addr[8 * stride] = sb.st_atime;
/* Last modification time */
- sarray->base_addr[9 * stride] = sb.st_mtime;
+ if (sb.st_mtime <= INT32_MAX)
+ values->base_addr[9 * stride] = sb.st_mtime;
/* Last file status change time */
- sarray->base_addr[10 * stride] = sb.st_ctime;
+ if (sb.st_ctime <= INT32_MAX)
+ values->base_addr[10 * stride] = sb.st_ctime;
/* Preferred I/O block size (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLKSIZE
- sarray->base_addr[11 * stride] = sb.st_blksize;
-#else
- sarray->base_addr[11 * stride] = -1;
+ if (sb.st_blksize <= INT32_MAX)
+ values->base_addr[11 * stride] = sb.st_blksize;
#endif
/* Number of blocks allocated (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLOCKS
- sarray->base_addr[12 * stride] = sb.st_blocks;
-#else
- sarray->base_addr[12 * stride] = -1;
+ if (sb.st_blocks <= INT32_MAX)
+ values->base_addr[12 * stride] = sb.st_blocks;
#endif
}
@@ -144,10 +157,10 @@ extern void stat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
iexport_proto(stat_i4_sub);
void
-stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
+stat_i4_sub (char *name, gfc_array_i4 *values, GFC_INTEGER_4 *status,
gfc_charlen_type name_len)
{
- stat_i4_sub_0 (name, sarray, status, name_len, 0);
+ stat_i4_sub_0 (name, values, status, name_len, 0);
}
iexport(stat_i4_sub);
@@ -157,17 +170,17 @@ extern void lstat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
iexport_proto(lstat_i4_sub);
void
-lstat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
+lstat_i4_sub (char *name, gfc_array_i4 *values, GFC_INTEGER_4 *status,
gfc_charlen_type name_len)
{
- stat_i4_sub_0 (name, sarray, status, name_len, 1);
+ stat_i4_sub_0 (name, values, status, name_len, 1);
}
iexport(lstat_i4_sub);
static void
-stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
+stat_i8_sub_0 (char *name, gfc_array_i8 *values, GFC_INTEGER_8 *status,
gfc_charlen_type name_len, int is_lstat __attribute__ ((unused)))
{
int val;
@@ -175,12 +188,12 @@ stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
struct stat sb;
/* If the rank of the array is not 1, abort. */
- if (GFC_DESCRIPTOR_RANK (sarray) != 1)
- runtime_error ("Array rank of SARRAY is not 1.");
+ if (GFC_DESCRIPTOR_RANK (values) != 1)
+ runtime_error ("Array rank of VALUES is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
- runtime_error ("Array size of SARRAY is too small.");
+ if (GFC_DESCRIPTOR_EXTENT(values,0) < 13)
+ runtime_error ("Array size of VALUES is too small.");
/* Make a null terminated copy of the string. */
str = fc_strdup (name, name_len);
@@ -197,57 +210,57 @@ stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
if (val == 0)
{
- index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
+ index_type stride = GFC_DESCRIPTOR_STRIDE(values,0);
/* Device ID */
- sarray->base_addr[0] = sb.st_dev;
+ values->base_addr[0] = sb.st_dev;
/* Inode number */
- sarray->base_addr[stride] = sb.st_ino;
+ values->base_addr[stride] = sb.st_ino;
/* File mode */
- sarray->base_addr[2 * stride] = sb.st_mode;
+ values->base_addr[2 * stride] = sb.st_mode;
/* Number of (hard) links */
- sarray->base_addr[3 * stride] = sb.st_nlink;
+ values->base_addr[3 * stride] = sb.st_nlink;
/* Owner's uid */
- sarray->base_addr[4 * stride] = sb.st_uid;
+ values->base_addr[4 * stride] = sb.st_uid;
/* Owner's gid */
- sarray->base_addr[5 * stride] = sb.st_gid;
+ values->base_addr[5 * stride] = sb.st_gid;
/* ID of device containing directory entry for file (0 if not available) */
#if HAVE_STRUCT_STAT_ST_RDEV
- sarray->base_addr[6 * stride] = sb.st_rdev;
+ values->base_addr[6 * stride] = sb.st_rdev;
#else
- sarray->base_addr[6 * stride] = 0;
+ values->base_addr[6 * stride] = 0;
#endif
/* File size (bytes) */
- sarray->base_addr[7 * stride] = sb.st_size;
+ values->base_addr[7 * stride] = sb.st_size;
/* Last access time */
- sarray->base_addr[8 * stride] = sb.st_atime;
+ values->base_addr[8 * stride] = sb.st_atime;
/* Last modification time */
- sarray->base_addr[9 * stride] = sb.st_mtime;
+ values->base_addr[9 * stride] = sb.st_mtime;
/* Last file status change time */
- sarray->base_addr[10 * stride] = sb.st_ctime;
+ values->base_addr[10 * stride] = sb.st_ctime;
/* Preferred I/O block size (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLKSIZE
- sarray->base_addr[11 * stride] = sb.st_blksize;
+ values->base_addr[11 * stride] = sb.st_blksize;
#else
- sarray->base_addr[11 * stride] = -1;
+ values->base_addr[11 * stride] = -1;
#endif
/* Number of blocks allocated (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLOCKS
- sarray->base_addr[12 * stride] = sb.st_blocks;
+ values->base_addr[12 * stride] = sb.st_blocks;
#else
- sarray->base_addr[12 * stride] = -1;
+ values->base_addr[12 * stride] = -1;
#endif
}
@@ -261,10 +274,10 @@ extern void stat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *,
iexport_proto(stat_i8_sub);
void
-stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
+stat_i8_sub (char *name, gfc_array_i8 *values, GFC_INTEGER_8 *status,
gfc_charlen_type name_len)
{
- stat_i8_sub_0 (name, sarray, status, name_len, 0);
+ stat_i8_sub_0 (name, values, status, name_len, 0);
}
iexport(stat_i8_sub);
@@ -275,10 +288,10 @@ extern void lstat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *,
iexport_proto(lstat_i8_sub);
void
-lstat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
+lstat_i8_sub (char *name, gfc_array_i8 *values, GFC_INTEGER_8 *status,
gfc_charlen_type name_len)
{
- stat_i8_sub_0 (name, sarray, status, name_len, 1);
+ stat_i8_sub_0 (name, values, status, name_len, 1);
}
iexport(lstat_i8_sub);
@@ -288,10 +301,10 @@ extern GFC_INTEGER_4 stat_i4 (char *, gfc_array_i4 *, gfc_charlen_type);
export_proto(stat_i4);
GFC_INTEGER_4
-stat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len)
+stat_i4 (char *name, gfc_array_i4 *values, gfc_charlen_type name_len)
{
GFC_INTEGER_4 val;
- stat_i4_sub (name, sarray, &val, name_len);
+ stat_i4_sub (name, values, &val, name_len);
return val;
}
@@ -299,32 +312,32 @@ extern GFC_INTEGER_8 stat_i8 (char *, gfc_array_i8 *, gfc_charlen_type);
export_proto(stat_i8);
GFC_INTEGER_8
-stat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len)
+stat_i8 (char *name, gfc_array_i8 *values, gfc_charlen_type name_len)
{
GFC_INTEGER_8 val;
- stat_i8_sub (name, sarray, &val, name_len);
+ stat_i8_sub (name, values, &val, name_len);
return val;
}
-/* SUBROUTINE LSTAT(FILE, SARRAY, STATUS)
+/* SUBROUTINE LSTAT(NAME, VALUES, STATUS)
CHARACTER(len=*), INTENT(IN) :: FILE
- INTEGER, INTENT(OUT), :: SARRAY(13)
+ INTEGER, INTENT(OUT), :: VALUES(13)
INTEGER, INTENT(OUT), OPTIONAL :: STATUS
- FUNCTION LSTAT(FILE, SARRAY)
+ FUNCTION LSTAT(NAME, VALUES)
INTEGER LSTAT
CHARACTER(len=*), INTENT(IN) :: FILE
- INTEGER, INTENT(OUT), :: SARRAY(13) */
+ INTEGER, INTENT(OUT), :: VALUES(13) */
extern GFC_INTEGER_4 lstat_i4 (char *, gfc_array_i4 *, gfc_charlen_type);
export_proto(lstat_i4);
GFC_INTEGER_4
-lstat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len)
+lstat_i4 (char *name, gfc_array_i4 *values, gfc_charlen_type name_len)
{
GFC_INTEGER_4 val;
- lstat_i4_sub (name, sarray, &val, name_len);
+ lstat_i4_sub (name, values, &val, name_len);
return val;
}
@@ -332,10 +345,10 @@ extern GFC_INTEGER_8 lstat_i8 (char *, gfc_array_i8 *, gfc_charlen_type);
export_proto(lstat_i8);
GFC_INTEGER_8
-lstat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len)
+lstat_i8 (char *name, gfc_array_i8 *values, gfc_charlen_type name_len)
{
GFC_INTEGER_8 val;
- lstat_i8_sub (name, sarray, &val, name_len);
+ lstat_i8_sub (name, values, &val, name_len);
return val;
}
@@ -344,32 +357,32 @@ lstat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len)
#ifdef HAVE_FSTAT
-/* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS)
+/* SUBROUTINE FSTAT(UNIT, VALUES, STATUS)
INTEGER, INTENT(IN) :: UNIT
- INTEGER, INTENT(OUT) :: SARRAY(13)
+ INTEGER, INTENT(OUT) :: VALUES(13)
INTEGER, INTENT(OUT), OPTIONAL :: STATUS
- FUNCTION FSTAT(UNIT, SARRAY)
+ FUNCTION FSTAT(UNIT, VALUES)
INTEGER FSTAT
INTEGER, INTENT(IN) :: UNIT
- INTEGER, INTENT(OUT) :: SARRAY(13) */
+ INTEGER, INTENT(OUT) :: VALUES(13) */
extern void fstat_i4_sub (GFC_INTEGER_4 *, gfc_array_i4 *, GFC_INTEGER_4 *);
iexport_proto(fstat_i4_sub);
void
-fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray, GFC_INTEGER_4 *status)
+fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *values, GFC_INTEGER_4 *status)
{
int val;
struct stat sb;
/* If the rank of the array is not 1, abort. */
- if (GFC_DESCRIPTOR_RANK (sarray) != 1)
- runtime_error ("Array rank of SARRAY is not 1.");
+ if (GFC_DESCRIPTOR_RANK (values) != 1)
+ runtime_error ("Array rank of VALUES is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
- runtime_error ("Array size of SARRAY is too small.");
+ if (GFC_DESCRIPTOR_EXTENT(values,0) < 13)
+ runtime_error ("Array size of VALUES is too small.");
/* Convert Fortran unit number to C file descriptor. */
val = unit_to_fd (*unit);
@@ -378,57 +391,70 @@ fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray, GFC_INTEGER_4 *status)
if (val == 0)
{
- index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
+ index_type stride = GFC_DESCRIPTOR_STRIDE(values,0);
+
+ /* Return -1 for any value overflowing INT32_MAX. */
+ for (int i = 0; i < 13; i++)
+ values->base_addr[i * stride] = -1;
/* Device ID */
- sarray->base_addr[0 * stride] = sb.st_dev;
+ if (sb.st_dev <= INT32_MAX)
+ values->base_addr[0 * stride] = sb.st_dev;
/* Inode number */
- sarray->base_addr[1 * stride] = sb.st_ino;
+ if (sb.st_ino <= INT32_MAX)
+ values->base_addr[1 * stride] = sb.st_ino;
/* File mode */
- sarray->base_addr[2 * stride] = sb.st_mode;
+ if (sb.st_mode <= INT32_MAX)
+ values->base_addr[2 * stride] = sb.st_mode;
/* Number of (hard) links */
- sarray->base_addr[3 * stride] = sb.st_nlink;
+ if (sb.st_nlink <= INT32_MAX)
+ values->base_addr[3 * stride] = sb.st_nlink;
/* Owner's uid */
- sarray->base_addr[4 * stride] = sb.st_uid;
+ if (sb.st_uid <= INT32_MAX)
+ values->base_addr[4 * stride] = sb.st_uid;
/* Owner's gid */
- sarray->base_addr[5 * stride] = sb.st_gid;
+ if (sb.st_gid <= INT32_MAX)
+ values->base_addr[5 * stride] = sb.st_gid;
/* ID of device containing directory entry for file (0 if not available) */
#if HAVE_STRUCT_STAT_ST_RDEV
- sarray->base_addr[6 * stride] = sb.st_rdev;
+ if (sb.st_rdev <= INT32_MAX)
+ values->base_addr[6 * stride] = sb.st_rdev;
#else
- sarray->base_addr[6 * stride] = 0;
+ values->base_addr[6 * stride] = 0;
#endif
/* File size (bytes) */
- sarray->base_addr[7 * stride] = sb.st_size;
+ if (sb.st_size <= INT32_MAX)
+ values->base_addr[7 * stride] = sb.st_size;
/* Last access time */
- sarray->base_addr[8 * stride] = sb.st_atime;
+ if (sb.st_atime <= INT32_MAX)
+ values->base_addr[8 * stride] = sb.st_atime;
/* Last modification time */
- sarray->base_addr[9 * stride] = sb.st_mtime;
+ if (sb.st_mtime <= INT32_MAX)
+ values->base_addr[9 * stride] = sb.st_mtime;
/* Last file status change time */
- sarray->base_addr[10 * stride] = sb.st_ctime;
+ if (sb.st_ctime <= INT32_MAX)
+ values->base_addr[10 * stride] = sb.st_ctime;
/* Preferred I/O block size (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLKSIZE
- sarray->base_addr[11 * stride] = sb.st_blksize;
-#else
- sarray->base_addr[11 * stride] = -1;
+ if (sb.st_blksize <= INT32_MAX)
+ values->base_addr[11 * stride] = sb.st_blksize;
#endif
/* Number of blocks allocated (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLOCKS
- sarray->base_addr[12 * stride] = sb.st_blocks;
-#else
- sarray->base_addr[12 * stride] = -1;
+ if (sb.st_blocks <= INT32_MAX)
+ values->base_addr[12 * stride] = sb.st_blocks;
#endif
}
@@ -441,18 +467,18 @@ extern void fstat_i8_sub (GFC_INTEGER_8 *, gfc_array_i8 *, GFC_INTEGER_8 *);
iexport_proto(fstat_i8_sub);
void
-fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray, GFC_INTEGER_8 *status)
+fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *values, GFC_INTEGER_8 *status)
{
int val;
struct stat sb;
/* If the rank of the array is not 1, abort. */
- if (GFC_DESCRIPTOR_RANK (sarray) != 1)
- runtime_error ("Array rank of SARRAY is not 1.");
+ if (GFC_DESCRIPTOR_RANK (values) != 1)
+ runtime_error ("Array rank of VALUES is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
- runtime_error ("Array size of SARRAY is too small.");
+ if (GFC_DESCRIPTOR_EXTENT(values,0) < 13)
+ runtime_error ("Array size of VALUES is too small.");
/* Convert Fortran unit number to C file descriptor. */
val = unit_to_fd ((int) *unit);
@@ -461,57 +487,57 @@ fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray, GFC_INTEGER_8 *status)
if (val == 0)
{
- index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
+ index_type stride = GFC_DESCRIPTOR_STRIDE(values,0);
/* Device ID */
- sarray->base_addr[0] = sb.st_dev;
+ values->base_addr[0] = sb.st_dev;
/* Inode number */
- sarray->base_addr[stride] = sb.st_ino;
+ values->base_addr[stride] = sb.st_ino;
/* File mode */
- sarray->base_addr[2 * stride] = sb.st_mode;
+ values->base_addr[2 * stride] = sb.st_mode;
/* Number of (hard) links */
- sarray->base_addr[3 * stride] = sb.st_nlink;
+ values->base_addr[3 * stride] = sb.st_nlink;
/* Owner's uid */
- sarray->base_addr[4 * stride] = sb.st_uid;
+ values->base_addr[4 * stride] = sb.st_uid;
/* Owner's gid */
- sarray->base_addr[5 * stride] = sb.st_gid;
+ values->base_addr[5 * stride] = sb.st_gid;
/* ID of device containing directory entry for file (0 if not available) */
#if HAVE_STRUCT_STAT_ST_RDEV
- sarray->base_addr[6 * stride] = sb.st_rdev;
+ values->base_addr[6 * stride] = sb.st_rdev;
#else
- sarray->base_addr[6 * stride] = 0;
+ values->base_addr[6 * stride] = 0;
#endif
/* File size (bytes) */
- sarray->base_addr[7 * stride] = sb.st_size;
+ values->base_addr[7 * stride] = sb.st_size;
/* Last access time */
- sarray->base_addr[8 * stride] = sb.st_atime;
+ values->base_addr[8 * stride] = sb.st_atime;
/* Last modification time */
- sarray->base_addr[9 * stride] = sb.st_mtime;
+ values->base_addr[9 * stride] = sb.st_mtime;
/* Last file status change time */
- sarray->base_addr[10 * stride] = sb.st_ctime;
+ values->base_addr[10 * stride] = sb.st_ctime;
/* Preferred I/O block size (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLKSIZE
- sarray->base_addr[11 * stride] = sb.st_blksize;
+ values->base_addr[11 * stride] = sb.st_blksize;
#else
- sarray->base_addr[11 * stride] = -1;
+ values->base_addr[11 * stride] = -1;
#endif
/* Number of blocks allocated (-1 if not available) */
#if HAVE_STRUCT_STAT_ST_BLOCKS
- sarray->base_addr[12 * stride] = sb.st_blocks;
+ values->base_addr[12 * stride] = sb.st_blocks;
#else
- sarray->base_addr[12 * stride] = -1;
+ values->base_addr[12 * stride] = -1;
#endif
}
@@ -524,10 +550,10 @@ extern GFC_INTEGER_4 fstat_i4 (GFC_INTEGER_4 *, gfc_array_i4 *);
export_proto(fstat_i4);
GFC_INTEGER_4
-fstat_i4 (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray)
+fstat_i4 (GFC_INTEGER_4 *unit, gfc_array_i4 *values)
{
GFC_INTEGER_4 val;
- fstat_i4_sub (unit, sarray, &val);
+ fstat_i4_sub (unit, values, &val);
return val;
}
@@ -535,10 +561,10 @@ extern GFC_INTEGER_8 fstat_i8 (GFC_INTEGER_8 *, gfc_array_i8 *);
export_proto(fstat_i8);
GFC_INTEGER_8
-fstat_i8 (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray)
+fstat_i8 (GFC_INTEGER_8 *unit, gfc_array_i8 *values)
{
GFC_INTEGER_8 val;
- fstat_i8_sub (unit, sarray, &val);
+ fstat_i8_sub (unit, values, &val);
return val;
}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index e21366c..5b206af 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,24 @@
+2025-06-19 Tobias Burnus <tburnus@baylibre.com>
+
+ * target.c (GOMP_REQUIRES_NAME_BUF_LEN): Define.
+ (GOMP_offload_register_ver, gomp_target_init): Use it for the
+ char buffer size.
+
+2025-06-19 Tobias Burnus <tburnus@baylibre.com>
+ waffl3x <waffl3x@baylibre.com>
+
+ * libgomp.texi (omp_init_allocator): Refer to 'Memory allocation'
+ for available memory spaces.
+ (OMP_ALLOCATOR): Move list of traits and predefined memspaces
+ and allocators to ...
+ (Memory allocation): ... here. Document omp(x)::allocator::*;
+ minor wording tweaks, be more explicit about memkind, pinned and
+ pool_size.
+
+2025-06-17 Tobias Burnus <tburnus@baylibre.com>
+
+ * testsuite/libgomp.c++/declare_target-2.C: New test.
+
2025-06-10 Tobias Burnus <tburnus@baylibre.com>
* testsuite/libgomp.c/declare-variant-4.h (gfx942): New variant function.
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 8374595..9f53f16 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -3453,7 +3453,7 @@ traits; if an allocator that fulfills the requirements cannot be created,
@code{omp_null_allocator} is returned.
The predefined memory spaces and available traits can be found at
-@ref{OMP_ALLOCATOR}, where the trait names have to be prefixed by
+@ref{Memory allocation}, where the trait names have to be prefixed by
@code{omp_atk_} (e.g. @code{omp_atk_pinned}) and the named trait values by
@code{omp_atv_} (e.g. @code{omp_atv_true}); additionally, @code{omp_atv_default}
may be used as trait value to specify that the default value should be used.
@@ -3476,7 +3476,7 @@ may be used as trait value to specify that the default value should be used.
@end multitable
@item @emph{See also}:
-@ref{OMP_ALLOCATOR}, @ref{Memory allocation}, @ref{omp_destroy_allocator}
+@ref{Memory allocation}, @ref{OMP_ALLOCATOR}, @ref{omp_destroy_allocator}
@item @emph{Reference}:
@uref{https://www.openmp.org, OpenMP specification v5.0}, Section 3.7.2
@@ -4057,63 +4057,15 @@ The value can either be a predefined allocator or a predefined memory space
or a predefined memory space followed by a colon and a comma-separated list
of memory trait and value pairs, separated by @code{=}.
+See @ref{Memory allocation} for a list of supported prefedined allocators,
+memory spaces, and traits.
+
Note: The corresponding device environment variables are currently not
supported. Therefore, the non-host @var{def-allocator-var} ICVs are always
initialized to @code{omp_default_mem_alloc}. However, on all devices,
the @code{omp_set_default_allocator} API routine can be used to change
value.
-@multitable @columnfractions .45 .45
-@headitem Predefined allocators @tab Associated predefined memory spaces
-@item omp_default_mem_alloc @tab omp_default_mem_space
-@item omp_large_cap_mem_alloc @tab omp_large_cap_mem_space
-@item omp_const_mem_alloc @tab omp_const_mem_space
-@item omp_high_bw_mem_alloc @tab omp_high_bw_mem_space
-@item omp_low_lat_mem_alloc @tab omp_low_lat_mem_space
-@item omp_cgroup_mem_alloc @tab omp_low_lat_mem_space (implementation defined)
-@item omp_pteam_mem_alloc @tab omp_low_lat_mem_space (implementation defined)
-@item omp_thread_mem_alloc @tab omp_low_lat_mem_space (implementation defined)
-@item ompx_gnu_pinned_mem_alloc @tab omp_default_mem_space (GNU extension)
-@end multitable
-
-The predefined allocators use the default values for the traits,
-as listed below. Except that the last three allocators have the
-@code{access} trait set to @code{cgroup}, @code{pteam}, and
-@code{thread}, respectively.
-
-@multitable @columnfractions .25 .40 .25
-@headitem Trait @tab Allowed values @tab Default value
-@item @code{sync_hint} @tab @code{contended}, @code{uncontended},
- @code{serialized}, @code{private}
- @tab @code{contended}
-@item @code{alignment} @tab Positive integer being a power of two
- @tab 1 byte
-@item @code{access} @tab @code{all}, @code{cgroup},
- @code{pteam}, @code{thread}
- @tab @code{all}
-@item @code{pool_size} @tab Positive integer
- @tab See @ref{Memory allocation}
-@item @code{fallback} @tab @code{default_mem_fb}, @code{null_fb},
- @code{abort_fb}, @code{allocator_fb}
- @tab See below
-@item @code{fb_data} @tab @emph{unsupported as it needs an allocator handle}
- @tab (none)
-@item @code{pinned} @tab @code{true}, @code{false}
- @tab See below
-@item @code{partition} @tab @code{environment}, @code{nearest},
- @code{blocked}, @code{interleaved}
- @tab @code{environment}
-@end multitable
-
-For the @code{fallback} trait, the default value is @code{null_fb} for the
-@code{omp_default_mem_alloc} allocator and any allocator that is associated
-with device memory; for all other allocators, it is @code{default_mem_fb}
-by default.
-
-For the @code{pinned} trait, the default value is @code{true} for
-predefined allocator @code{ompx_gnu_pinned_mem_alloc} (a GNU extension), and
-@code{false} for all others.
-
Examples:
@smallexample
OMP_ALLOCATOR=omp_high_bw_mem_alloc
@@ -5972,7 +5924,7 @@ This function copies device memory from one memory location to another
on the current device. It copies @var{bytes} bytes of data from the device
address, specified by @var{data_dev_src}, to the device address
@var{data_dev_dest}. The @code{_async} version performs the transfer
-asnychronously using the queue associated with @var{async_arg}.
+asynchronously using the queue associated with @var{async_arg}.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
@@ -6883,6 +6835,7 @@ on more architectures, GCC currently does not match any @code{arch} or
@tab See @code{-march=} in ``Nvidia PTX Options''
@end multitable
+
@node Memory allocation
@section Memory allocation
@@ -6917,11 +6870,94 @@ The description below applies to:
@code{_Alignof} and C++'s @code{alignof}.
@end itemize
-For the available predefined allocators and, as applicable, their associated
-predefined memory spaces and for the available traits and their default values,
-see @ref{OMP_ALLOCATOR}. Predefined allocators without an associated memory
-space use the @code{omp_default_mem_space} memory space. See additionally
-@ref{Offload-Target Specifics}.
+GCC supports the following predefined allocators and predefined memory spaces:
+
+@multitable @columnfractions .45 .45
+@headitem Predefined allocators @tab Associated predefined memory spaces
+@item omp_default_mem_alloc @tab omp_default_mem_space
+@item omp_large_cap_mem_alloc @tab omp_large_cap_mem_space
+@item omp_const_mem_alloc @tab omp_const_mem_space
+@item omp_high_bw_mem_alloc @tab omp_high_bw_mem_space
+@item omp_low_lat_mem_alloc @tab omp_low_lat_mem_space
+@item omp_cgroup_mem_alloc @tab omp_low_lat_mem_space (implementation defined)
+@item omp_pteam_mem_alloc @tab omp_low_lat_mem_space (implementation defined)
+@item omp_thread_mem_alloc @tab omp_low_lat_mem_space (implementation defined)
+@item ompx_gnu_pinned_mem_alloc @tab omp_default_mem_space (GNU extension)
+@end multitable
+
+Each predefined allocator, including @code{omp_null_allocator}, has a corresponding
+allocator class template that meet the C++ allocator completeness requirements.
+These are located in the @code{omp::allocator} namespace, and the
+@code{ompx::allocator} namespace for gnu extensions. This allows the
+allocator-aware C++ standard library containers to use OpenMP allocation routines;
+for instance:
+
+@smallexample
+std::vector<int, omp::allocator::cgroup_mem<int>> vec;
+@end smallexample
+
+The following allocator templates are supported:
+
+@multitable @columnfractions .45 .45
+@headitem Predefined allocators @tab Associated allocator template
+@item omp_null_allocator @tab omp::allocator::null_allocator
+@item omp_default_mem_alloc @tab omp::allocator::default_mem
+@item omp_large_cap_mem_alloc @tab omp::allocator::large_cap_mem
+@item omp_const_mem_alloc @tab omp::allocator::const_mem
+@item omp_high_bw_mem_alloc @tab omp::allocator::high_bw_mem
+@item omp_low_lat_mem_alloc @tab omp::allocator::low_lat_mem
+@item omp_cgroup_mem_alloc @tab omp::allocator::cgroup_mem
+@item omp_pteam_mem_alloc @tab omp::allocator::pteam_mem
+@item omp_thread_mem_alloc @tab omp::allocator::thread_mem
+@item ompx_gnu_pinned_mem_alloc @tab ompx::allocator::gnu_pinned_mem
+@end multitable
+
+The following traits are available when constructing a new allocator;
+if a trait is not specified or with the value @code{default}, the
+specified default value is used for that trait. The predefined
+allocators use the default values of each trait, except that the
+@code{omp_cgroup_mem_alloc}, @code{omp_pteam_mem_alloc}, and
+@code{omp_thread_mem_alloc} allocators have the @code{access} trait
+set to @code{cgroup}, @code{pteam}, and @code{thread}, respectively.
+For each trait, a named constant prefixed by @code{omp_atk_} exists;
+for each non-numeric value, a named constant prefixed by @code{omp_atv_}
+exists.
+
+@multitable @columnfractions .25 .40 .25
+@headitem Trait @tab Allowed values @tab Default value
+@item @code{sync_hint} @tab @code{contended}, @code{uncontended},
+ @code{serialized}, @code{private}
+ @tab @code{contended}
+@item @code{alignment} @tab Positive integer being a power of two
+ @tab 1 byte
+@item @code{access} @tab @code{all}, @code{cgroup},
+ @code{pteam}, @code{thread}
+ @tab @code{all}
+@item @code{pool_size} @tab Positive integer (bytes)
+ @tab See below.
+@item @code{fallback} @tab @code{default_mem_fb}, @code{null_fb},
+ @code{abort_fb}, @code{allocator_fb}
+ @tab See below
+@item @code{fb_data} @tab @emph{allocator handle}
+ @tab (none)
+@item @code{pinned} @tab @code{true}, @code{false}
+ @tab See below
+@item @code{partition} @tab @code{environment}, @code{nearest},
+ @code{blocked}, @code{interleaved}
+ @tab @code{environment}
+@end multitable
+
+For the @code{fallback} trait, the default value is @code{null_fb} for the
+@code{omp_default_mem_alloc} allocator and any allocator that is associated
+with device memory; for all other allocators, it is @code{default_mem_fb}
+by default.
+
+For the @code{pinned} trait, the default value is @code{true} for
+predefined allocator @code{ompx_gnu_pinned_mem_alloc} (a GNU extension), and
+@code{false} for all others.
+
+The following description applies to the initial device (the host) and largely
+also to non-host devices; for the latter, also see @ref{Offload-Target Specifics}.
For the memory spaces, the following applies:
@itemize
@@ -6936,14 +6972,16 @@ For the memory spaces, the following applies:
@end itemize
On Linux systems, where the @uref{https://github.com/memkind/memkind, memkind
-library} (@code{libmemkind.so.0}) is available at runtime, it is used when
-creating memory allocators requesting
+library} (@code{libmemkind.so.0}) is available at runtime and the respective
+memkind kind is supported, it is used when creating memory allocators requesting
@itemize
-@item the memory space @code{omp_high_bw_mem_space}
-@item the memory space @code{omp_large_cap_mem_space}
-@item the @code{partition} trait @code{interleaved}; note that for
- @code{omp_large_cap_mem_space} the allocation will not be interleaved
+@item the @code{partition} trait @code{interleaved} except when the memory space
+ is @code{omp_large_cap_mem_space} (uses @code{MEMKIND_HBW_INTERLEAVE})
+@item the memory space is @code{omp_high_bw_mem_space} (uses
+ @code{MEMKIND_HBW_PREFERRED})
+@item the memory space is @code{omp_large_cap_mem_space} (uses
+ @code{MEMKIND_DAX_KMEM_ALL} or, if not available, @code{MEMKIND_DAX_KMEM})
@end itemize
On Linux systems, where the @uref{https://github.com/numactl/numactl, numa
@@ -6969,10 +7007,15 @@ a @code{nearest} allocation.
Additional notes regarding the traits:
@itemize
@item The @code{pinned} trait is supported on Linux hosts, but is subject to
- the OS @code{ulimit}/@code{rlimit} locked memory settings.
+ the OS @code{ulimit}/@code{rlimit} locked memory settings. It currently
+ uses @code{mmap} and is therefore optimized for few allocations, including
+ large data. If the conditions for numa or memkind allocations are
+ fulfilled, those allocators are used instead.
@item The default for the @code{pool_size} trait is no pool and for every
(re)allocation the associated library routine is called, which might
- internally use a memory pool.
+ internally use a memory pool. Currently, the same applies when a
+ @code{pool_size} has been specified, except that once allocations exceed
+ the the pool size, the action of the @code{fallback} trait applies.
@item For the @code{partition} trait, the partition part size will be the same
as the requested size (i.e. @code{interleaved} or @code{blocked} has no
effect), except for @code{interleaved} when the memkind library is
@@ -6981,13 +7024,15 @@ Additional notes regarding the traits:
that allocated the memory; on Linux, this is in particular the case when
the memory placement policy is set to preferred.
@item The @code{access} trait has no effect such that memory is always
- accessible by all threads.
+ accessible by all threads. (Except on supported no-host devices.)
@item The @code{sync_hint} trait has no effect.
@end itemize
See also:
@ref{Offload-Target Specifics}
+
+
@c ---------------------------------------------------------------------
@c Offload-Target Specifics
@c ---------------------------------------------------------------------
diff --git a/libgomp/target.c b/libgomp/target.c
index a2a4a72..cda092b 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -2641,6 +2641,10 @@ gomp_unload_image_from_device (struct gomp_device_descr *devicep,
}
}
+#define GOMP_REQUIRES_NAME_BUF_LEN \
+ sizeof ("unified_address, unified_shared_memory, " \
+ "self_maps, reverse_offload")
+
static void
gomp_requires_to_name (char *buf, size_t size, int requires_mask)
{
@@ -2689,10 +2693,8 @@ GOMP_offload_register_ver (unsigned version, const void *host_table,
if (omp_req && omp_requires_mask && omp_requires_mask != omp_req)
{
- char buf1[sizeof ("unified_address, unified_shared_memory, "
- "self_maps, reverse_offload")];
- char buf2[sizeof ("unified_address, unified_shared_memory, "
- "self_maps, reverse_offload")];
+ char buf1[GOMP_REQUIRES_NAME_BUF_LEN];
+ char buf2[GOMP_REQUIRES_NAME_BUF_LEN];
gomp_requires_to_name (buf2, sizeof (buf2),
omp_req != GOMP_REQUIRES_TARGET_USED
? omp_req : omp_requires_mask);
@@ -5786,8 +5788,7 @@ gomp_target_init (void)
found = true;
if (found)
{
- char buf[sizeof ("unified_address, unified_shared_memory, "
- "reverse_offload")];
+ char buf[GOMP_REQUIRES_NAME_BUF_LEN];
gomp_requires_to_name (buf, sizeof (buf), omp_req);
char *name = (char *) malloc (cur_len + 1);
memcpy (name, cur, cur_len);
diff --git a/libgomp/testsuite/libgomp.c++/declare_target-2.C b/libgomp/testsuite/libgomp.c++/declare_target-2.C
new file mode 100644
index 0000000..ab94a55
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/declare_target-2.C
@@ -0,0 +1,25 @@
+// { dg-do link }
+
+// Actually not needed: -fipa-cp is default with -O2:
+// { dg-additional-options "-O2 -fipa-cp" }
+
+// The code failed because 'std::endl' becoḿes implicitly 'declare target'
+// but not the 'widen' function it calls. While the linker had no issues
+// (endl is never called, either because it is inlined or optimized away),
+// the IPA-CP (enabled by -O2 and higher) failed as the definition for
+// 'widen' did not exist on the offload side.
+
+#include <iostream>
+
+void func (int m)
+{
+ if (m < 0)
+ std::cout << "should not happen" << std::endl;
+}
+
+
+int main()
+{
+ #pragma omp target
+ func (1);
+}