[gcc r14-11575] RISC-V:Bugfix for vlmul_ext and vlmul_trunc with NULL return value[pr117286]
https://gcc.gnu.org/g:4bd63c709de82bfecde8cf99145974b349918d5d commit r14-11575-g4bd63c709de82bfecde8cf99145974b349918d5d Author: xuli Date: Mon Oct 28 04:41:09 2024 + RISC-V:Bugfix for vlmul_ext and vlmul_trunc with NULL return value[pr117286] This patch fixes following ICE: test.c: In function 'func': test.c:37:24: internal compiler error: Segmentation fault 37 | vfloat16mf2_t vc = __riscv_vlmul_trunc_v_f16m1_f16mf2(vb); |^~ The root cause is that vlmul_trunc has a null return value. gimple_call <__riscv_vlmul_trunc_v_f16m1_f16mf2, NULL, vb_13> ^^^ Passed the rv64gcv_zvfh regression test. Singed-off-by: Li Xu PR target/117286 gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc: Do not expand NULL return. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/pr117286.c: New test. Diff: --- gcc/config/riscv/riscv-vector-builtins-bases.cc| 4 gcc/testsuite/gcc.target/riscv/rvv/base/pr117286.c | 16 2 files changed, 20 insertions(+) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index b6f6e4ff37e7..3450c69979cd 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -1760,6 +1760,8 @@ public: rtx expand (function_expander &e) const override { +if (!e.target) + return NULL_RTX; tree arg = CALL_EXPR_ARG (e.exp, 0); rtx src = expand_normal (arg); emit_move_insn (gen_lowpart (e.vector_mode (), e.target), src); @@ -1774,6 +1776,8 @@ public: rtx expand (function_expander &e) const override { +if (!e.target) + return NULL_RTX; rtx src = expand_normal (CALL_EXPR_ARG (e.exp, 0)); emit_move_insn (e.target, gen_lowpart (GET_MODE (e.target), src)); return e.target; diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr117286.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr117286.c new file mode 100644 index ..dabb8ae0751d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr117286.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O1" } */ + +#include +_Float16 a[10]; +void func(){ + int placeholder0 = 10; + _Float16* ptr_a = a; + for (size_t vl; placeholder0 > 0; placeholder0 -= vl){ +vl = __riscv_vsetvl_e16m1(placeholder0); +vfloat16mf2_t va = __riscv_vle16_v_f16mf2(ptr_a, vl); +vfloat16m1_t vb = __riscv_vlmul_ext_v_f16mf2_f16m1(va); +vfloat16mf2_t vc = __riscv_vlmul_trunc_v_f16m1_f16mf2(vb); +ptr_a += vl; + } +}
[gcc r15-9343] aarch64: Add sve testcase for PR 116595 [PR116595]
https://gcc.gnu.org/g:76d902a68d8331fa3d06f3ba04d361795b17bb5a commit r15-9343-g76d902a68d8331fa3d06f3ba04d361795b17bb5a Author: Andrew Pinski Date: Wed Apr 9 12:47:53 2025 -0700 aarch64: Add sve testcase for PR 116595 [PR116595] This was fixed with r15-9329-gf183ae0ae891a471764876eb but only a RISC-V V testcase was added. So this adds an aarch64 SVE testcase too. Pushed as obvious after a quick test to make sure it passes. PR middle-end/116595 gcc/testsuite/ChangeLog: * g++.target/aarch64/sve/pr116595.C: New test. Signed-off-by: Andrew Pinski Diff: --- gcc/testsuite/g++.target/aarch64/sve/pr116595.C | 7 +++ 1 file changed, 7 insertions(+) diff --git a/gcc/testsuite/g++.target/aarch64/sve/pr116595.C b/gcc/testsuite/g++.target/aarch64/sve/pr116595.C new file mode 100644 index ..49874dd0db0f --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve/pr116595.C @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +#include + +void transpose4x4_ps() +{ +svfloat32x4_t _r = svfloat32x4_t(); +}
[gcc r15-9346] libquadmath: Fix up THREEp96 constant in expq
https://gcc.gnu.org/g:e081ced345c45581a4891361c08e50e07720239e commit r15-9346-ge081ced345c45581a4891361c08e50e07720239e Author: Jakub Jelinek Date: Wed Apr 9 22:01:30 2025 +0200 libquadmath: Fix up THREEp96 constant in expq Here is a cherry-pick from glibc [BZ #32411] fix. As mentioned by the reporter in a pull request against gcc-mirror, the THREEp96 constant in e_expl.c is incorrect, it is actually 0x3.p+94f128 rather than 0x3.p+96f128. The algorithm uses that to compute the t2 integer (tval2), by whose delta it adjusts the x+xl pair and then in the result uses the precomputed exp value for that entry. Using 0x3.p+94f128 rather than 0x3.p+96f128 results in tval2 sometimes being one smaller, sometimes one larger than the desired value, thus can mean the x+xl pair after adjustment will be larger in absolute value than it should be. DesWursters created a test program for this https://github.com/DesWurstes/comparefloats and his results were total: 113500 not_equal: 4322 earlier_score: 674 later_score: 3648 I've modified this so with https://sourceware.org/bugzilla/show_bug.cgi?id=32411#c3 so that it actually tests pseudo-random _Float128 values with range (-16384.,16384) with strong bias on values larger than 0.0002 in absolute value (so that tval1/tval2 aren't zero most of the time) and that gave total: 100 not_equal: 29861 earlier_score: 4606 later_score: 25255 So, in both cases, in most cases the change doesn't result in any differences, and in those rare cases where does, about 85% have smaller ulp than without the patch. Additionally I've tried https://sourceware.org/bugzilla/show_bug.cgi?id=32411#c4 and in 2 billion iterations it didn't find any case where x+xl after the adjustments without this change would be smaller in absolute value compared to x+xl after the adjustments with this change. 2025-04-09 Jakub Jelinek * math/expq.c (C): Fix up THREEp96 constant. Diff: --- libquadmath/math/expq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libquadmath/math/expq.c b/libquadmath/math/expq.c index 1aaad91c2446..171598824f12 100644 --- a/libquadmath/math/expq.c +++ b/libquadmath/math/expq.c @@ -74,7 +74,7 @@ static const __float128 C[] = { /* 3x2^96 */ #define THREEp96 C[2] - 59421121885698253195157962752.0Q, + 237684487542793012780631851008.0Q, /* 3x2^103 */ #define THREEp103 C[3]
[gcc r15-9348] pretty-print: Fix format specifier description
https://gcc.gnu.org/g:f7738c36710f8084e24cbb1d92acf3b6e5e83ea9 commit r15-9348-gf7738c36710f8084e24cbb1d92acf3b6e5e83ea9 Author: Jakub Jelinek Date: Wed Apr 9 22:07:33 2025 +0200 pretty-print: Fix format specifier description I've noticed we talk about %Ns even when that isn't supported and we actually only support %.Ns which the comment describes. 2025-04-09 Jakub Jelinek * pretty-print.cc (pretty_printer::format): Use %.Ns instead of %Ns in function comment. Diff: --- gcc/pretty-print.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc index 79c7bc2b6625..abd6c0b528f4 100644 --- a/gcc/pretty-print.cc +++ b/gcc/pretty-print.cc @@ -1640,7 +1640,7 @@ push_back_any_text (pp_token_list *tok_list, %@: diagnostic_event_id_ptr, for which event_id->known_p () must be true. %.*s: a substring the length of which is specified by an argument integer. - %Ns: likewise, but length specified as constant in the format string. + %.Ns: likewise, but length specified as constant in the format string. Flag 'q': quote formatted text (must come immediately after '%'). %Z: Requires two arguments - array of int, and len. Prints elements of the array.
[gcc r15-9347] modula2: FIx a comment typo
https://gcc.gnu.org/g:76b267b43cbf93163b1648c4430ab1102e24142e commit r15-9347-g76b267b43cbf93163b1648c4430ab1102e24142e Author: Jakub Jelinek Date: Wed Apr 9 22:03:50 2025 +0200 modula2: FIx a comment typo During make gcc.pot I've noticed among tons of other warnings (e.g. because can't appears in non-C/C++ style comment and so gettext considers it unterminated) a warning where the lack of " looked unintentional. 2025-04-09 Jakub Jelinek * gm2-compiler/M2MetaError.def: Fix comment typo, range" -> "range2". Diff: --- gcc/m2/gm2-compiler/M2MetaError.def | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/m2/gm2-compiler/M2MetaError.def b/gcc/m2/gm2-compiler/M2MetaError.def index 637a27d8f095..92c4ad2b8d8e 100644 --- a/gcc/m2/gm2-compiler/M2MetaError.def +++ b/gcc/m2/gm2-compiler/M2MetaError.def @@ -109,7 +109,8 @@ FROM NameKey IMPORT Name ; describe the symbol. If ordinary text is copied then it is not quoted. The color strings are: "filename", "quote", "error", "warning", "note", - "locus", "insert", "delete", "type", "range1", range2". + "locus", "insert", "delete", "type", "range1", + "range2". *) (*
[gcc r15-9344] Update gcc de.po
https://gcc.gnu.org/g:101ac9e5acbd9ff7216565492988be7b4f02587d commit r15-9344-g101ac9e5acbd9ff7216565492988be7b4f02587d Author: Joseph Myers Date: Wed Apr 9 20:06:02 2025 + Update gcc de.po * de.po: Update. Diff: --- gcc/po/de.po | 366 +-- 1 file changed, 129 insertions(+), 237 deletions(-) diff --git a/gcc/po/de.po b/gcc/po/de.po index 038c8b8252ad..c3a2c94a81b8 100644 --- a/gcc/po/de.po +++ b/gcc/po/de.po @@ -8,10 +8,10 @@ # Roland Illig , 2015, 2017-2025. msgid "" msgstr "" -"Project-Id-Version: gcc 15.1-b20250316\n" +"Project-Id-Version: gcc 15.1-b20250406\n" "Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n"; "POT-Creation-Date: 2025-04-04 20:42+\n" -"PO-Revision-Date: 2025-04-09 07:29+0200\n" +"PO-Revision-Date: 2025-04-09 20:06+0200\n" "Last-Translator: Roland Illig \n" "Language-Team: German \n" "Language: de\n" @@ -1309,13 +1309,12 @@ msgstr "Den WIP-Borrow-Prüfer verwenden." #: rust/lang.opt:217 #, no-c-format msgid "-frust-edition=[unwind|abort] Panic strategy to compile crate with" -msgstr "" +msgstr "-frust-edition=[unwind|abort] Panikstrategie, mit der Crate compiliert wird" #: rust/lang.opt:230 -#, fuzzy, no-c-format -#| msgid "Select the eBPF ISA version to target in code generation." +#, no-c-format msgid "Enable the overflow checks in code generation" -msgstr "Auswählen, für welche eBPF-ISA-Version der Zielcode generiert wird." +msgstr "Überlaufprüfungen bei der Codegenerierung einschalten" #: c-family/c.opt:71 #, no-c-format @@ -1819,10 +1818,8 @@ msgstr "Bei veralteten arithmetischen Umwandlungen von Operanden mit Aufzählung msgid "Warn about deprecated arithmetic conversions on operands where one is of enumeration type and the other is of a floating-point type." msgstr "Bei veralteten arithmetischen Umwandlungen von Operanden warnen, bei denen der eine von einem Aufzählungstyp ist und der andere eine Gleitkommazahl." -# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118979 #: c-family/c.opt:669 -#, fuzzy, no-c-format -#| msgid "Warn about deprecated space between and suffix in a user-defined literal operator." +#, no-c-format msgid "Warn about deprecated space between \"\" and suffix in a user-defined literal operator." msgstr "Warnen, wenn zwischen \"\" und dem Suffix in einem benutzerdefinierten Literaloperator ein Leerzeichen steht (veraltet)." @@ -8313,10 +8310,9 @@ msgid "Support USER_MSR built-in functions and code generation." msgstr "Eingebaute USER_MSR-Funktionen und Codeerzeugung unterstützen." #: config/i386/i386.opt:1368 -#, fuzzy, no-c-format -#| msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and AVX10.1-512 built-in functions and code generation." +#, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and AVX10.1-256 built-in functions and code generation." -msgstr "Eingebaute Funktionen und Codeerzeugung für MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 und AVX10.1-512 unterstützen." +msgstr "Eingebaute Funktionen und Codeerzeugung für MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 und AVX10.1-256 unterstützen." #: config/i386/i386.opt:1373 config/i386/i386.opt:1378 #, no-c-format @@ -8324,16 +8320,14 @@ msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and AVX10 msgstr "Eingebaute Funktionen und Codeerzeugung für MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 und AVX10.1-512 unterstützen." #: config/i386/i386.opt:1383 -#, fuzzy, no-c-format -#| msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512 and AVX10.2-512 built-in functions and code generation." +#, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512 and AVX10.2 built-in functions and code generation." -msgstr "Eingebaute Funktionen und Codeerzeugung für MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512 und AVX10.2-512 unterstützen." +msgstr "Eingebaute Funktionen und Codeerzeugung für MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512 und AVX10.2 unterstützen." #: config/i386/i386.opt:1388 -#, fuzzy, no-c-format -#| msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512, AVX10.2-512 and AMX-AVX512 built-in functions and code generation." +#, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512, AVX10.2 and AMX-AVX512 built-in functions and code generation." -msgstr "Eingebaute Funktionen und Codeerzeugung für MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512, AVX10.2-512 und AMX-AVX512 unterstützen." +msgstr "Eingebaute Funktionen und Codeerzeugung für MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1-512, AVX10.2 und AMX-AVX512 unterstützen." #: config/i386/i386.opt:1393 #, no-c-format @@ -8779,7 +8773,7 @@ msgstr
[gcc r15-9345] h8300: Fix up bit test and jump splitter [PR119664]
https://gcc.gnu.org/g:4203060a73e65e4fa3e091b060a973c3296b84e9 commit r15-9345-g4203060a73e65e4fa3e091b060a973c3296b84e9 Author: Jakub Jelinek Date: Wed Apr 9 22:00:35 2025 +0200 h8300: Fix up bit test and jump splitter [PR119664] r12-2601 has added this define_insn_and_split and corresponding (define_insn "" [(set (reg:CCZ CC_REG) (eq (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r") (const_int 1) (match_operand 1 "const_int_operand" "n")) (const_int 0)))] "INTVAL (operands[1]) < 16" "btst %Z1,%Y0" [(set_attr "length" "2")]) pattern into which the define_insn_and_split wants to splut in addition to a conditional jump. But as can be seen, the btst define_insn uses HSI mode iterator while define_insn_and_split QHSI, so for QImode it splits into something that can't be recognized. This was probably latent since r12-2601 and on the attached testcase is reproduceable starting with r15-1945 - a late combiner change. 2025-04-09 Jakub Jelinek PR target/119664 * config/h8300/jumpcall.md (bit test and jump define_insn_and_split): Use HSI iterator rather than QHSI. * gcc.dg/pr119664.c: New test. Diff: --- gcc/config/h8300/jumpcall.md| 8 gcc/testsuite/gcc.dg/pr119664.c | 15 +++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/gcc/config/h8300/jumpcall.md b/gcc/config/h8300/jumpcall.md index b59639992a36..4e634085130c 100644 --- a/gcc/config/h8300/jumpcall.md +++ b/gcc/config/h8300/jumpcall.md @@ -146,9 +146,9 @@ (define_insn_and_split "" [(set (pc) (if_then_else (match_operator 3 "eqne_operator" - [(zero_extract:QHSI (match_operand:QHSI 1 "register_operand" "r") - (const_int 1) - (match_operand 2 "const_int_operand" "n")) + [(zero_extract:HSI (match_operand:HSI 1 "register_operand" "r") + (const_int 1) + (match_operand 2 "const_int_operand" "n")) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] @@ -156,7 +156,7 @@ "#" "&& reload_completed" [(set (reg:CCZ CC_REG) - (eq (zero_extract:QHSI (match_dup 1) (const_int 1) (match_dup 2)) + (eq (zero_extract:HSI (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (pc) (if_then_else (match_op_dup 3 [(reg:CCZ CC_REG) (const_int 0)]) diff --git a/gcc/testsuite/gcc.dg/pr119664.c b/gcc/testsuite/gcc.dg/pr119664.c new file mode 100644 index ..23ffc30eb779 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119664.c @@ -0,0 +1,15 @@ +/* PR target/119664 */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +struct S { unsigned : 1, a : 1; } *s; +int foo (void); +void bar (void); + +int +baz (void) +{ + int a = s->a; + bar (); + return a && foo (); +}
[gcc r14-11561] [PATCH] RISC-V: Allow zero operand for DI variants of vssubu.vx
https://gcc.gnu.org/g:d0663c143071331bd3bff7e396bc0e761dd98939 commit r14-11561-gd0663c143071331bd3bff7e396bc0e761dd98939 Author: Bohan Lei Date: Wed Sep 18 07:20:23 2024 -0600 [PATCH] RISC-V: Allow zero operand for DI variants of vssubu.vx The RISC-V vector machine description relies on the helper function `sew64_scalar_helper` to emit actual insns for the DI variants of vssub.vx and vssubu.vx. This works with vssub.vx, but can cause problems with vssubu.vx with the scalar operand being constant zero, because `has_vi_variant_p` returns false, and the operand will be taken without being loaded into a reg. The attached testcases can cause an internal compiler error as a result. Allowing a constant zero operand in those insns seems to be a simple solution that only affects minimum existing code. gcc/ChangeLog: * config/riscv/vector.md: Allow zero operand for DI variants of vssubu.vx gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/vssubu-1.c: New test. * gcc.target/riscv/rvv/base/vssubu-2.c: New test. Diff: --- gcc/config/riscv/vector.md | 8 gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-1.c | 11 +++ gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-2.c | 11 +++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index adf9633e2cc5..0b2be136236f 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -4395,10 +4395,10 @@ (sat_int_minus_binop:VI_D (match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr") (vec_duplicate:VI_D - (match_operand: 4 "register_operand" " r, r, r, r"))) + (match_operand: 4 "reg_or_0_operand" " rJ, rJ, rJ, rJ"))) (match_operand:VI_D 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" - "v.vx\t%0,%3,%4%p1" + "v.vx\t%0,%3,%z4%p1" [(set_attr "type" "") (set_attr "mode" "")]) @@ -4417,10 +4417,10 @@ (match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr") (vec_duplicate:VI_D (sign_extend: - (match_operand: 4 "register_operand" " r, r, r, r" + (match_operand: 4 "reg_or_0_operand" " rJ, rJ, rJ, rJ" (match_operand:VI_D 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR && !TARGET_64BIT" - "v.vx\t%0,%3,%4%p1" + "v.vx\t%0,%3,%z4%p1" [(set_attr "type" "") (set_attr "mode" "")]) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-1.c new file mode 100644 index ..f19b42aed04c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gcv -mabi=lp64d" } */ + +#include + +vuint64m1_t test_vssubu_vx_u64m1(vuint64m1_t op1) +{ + return __riscv_vssubu_vx_u64m1(op1,0,0); +} + +/* { dg-final { scan-assembler-not {\tvssubu} } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-2.c new file mode 100644 index ..2f8c146a2efc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vssubu-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv32gcv -mabi=ilp32d" } */ + +#include "riscv_vector.h" + +vuint64m1_t test_vssubu_vx_u64m1(vuint64m1_t op1) +{ + return __riscv_vssubu_vx_u64m1(op1,0,0); +} + +/* { dg-final { scan-assembler-not {\tvssubu} } } */
[gcc r14-11564] [PATCH v4] [target/116592] RISC-V: Fix illegal operands "th.vsetvli zero, 0, e32, m8" for XTheadVector
https://gcc.gnu.org/g:4f41d8fa5a73e2703d417b0e44bce48aa35bfd91 commit r14-11564-g4f41d8fa5a73e2703d417b0e44bce48aa35bfd91 Author: Jin Ma Date: Sat Sep 7 10:29:02 2024 -0600 [PATCH v4] [target/116592] RISC-V: Fix illegal operands "th.vsetvli zero,0,e32,m8" for XTheadVector Since the THeadVector vsetvli does not support vl as an immediate, we need to convert 0 to zero when outputting asm. PR target/116592 gcc/ChangeLog: * config/riscv/thead.cc (th_asm_output_opcode): Change '0' to "zero" gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/xtheadvector/pr116592.c: New test. Diff: --- gcc/config/riscv/thead.cc | 4 +-- .../gcc.target/riscv/rvv/xtheadvector/pr116592.c | 38 ++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index 0be5e4aceb8b..725a1bcf2b24 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -906,11 +906,11 @@ th_asm_output_opcode (FILE *asm_out_file, const char *p) if (strstr (p, "zero,zero")) return "th.vsetvli\tzero,zero,e%0,%m1"; else - return "th.vsetvli\tzero,%0,e%1,%m2"; + return "th.vsetvli\tzero,%z0,e%1,%m2"; } else { - return "th.vsetvli\t%0,%1,e%2,%m3"; + return "th.vsetvli\t%z0,%z1,e%2,%m3"; } } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c new file mode 100644 index ..a7cd8c5bdb72 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c @@ -0,0 +1,38 @@ +/* { dg-do assemble } */ +/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2 -save-temps" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2 -save-temps" { target { rv64 } } } */ + +#include +#include + +static vfloat32m8_t atan2_ps(vfloat32m8_t a, vfloat32m8_t b, size_t vl) +{ + float tmpx[vl]; + float tmpy[vl]; + __riscv_vse32_v_f32m8(tmpx, a, vl); + __riscv_vse32_v_f32m8(tmpy, b, vl); + for (size_t i = 0; i < vl; i++) + { +tmpx[i] = atan2(tmpx[i], tmpy[i]); + } + return __riscv_vle32_v_f32m8(tmpx, vl); +} + +void my_atan2(const float *x, const float *y, float *out, int size) +{ + int n = size; + while (n > 0) + { +size_t vl = __riscv_vsetvl_e32m8(n); +vfloat32m8_t _x = __riscv_vle32_v_f32m8(x, vl); +vfloat32m8_t _y = __riscv_vle32_v_f32m8(y, vl); +vfloat32m8_t _out = atan2_ps(_x, _y, vl); +__riscv_vse32_v_f32m8(out, _out, vl); +n -= vl; +x += vl; +y += vl; +out += vl; + } +} + +/* { dg-final { scan-assembler-not {th\.vsetvli\s+zero,0} } } */
[gcc r14-11578] libstdc++: Fix constraint recursion in basic_const_iterator operator- [PR115046]
https://gcc.gnu.org/g:630bca9fa83236e108e9421549bdd5058133c3dd commit r14-11578-g630bca9fa83236e108e9421549bdd5058133c3dd Author: Patrick Palka Date: Wed Apr 9 17:48:05 2025 -0400 libstdc++: Fix constraint recursion in basic_const_iterator operator- [PR115046] It was proposed in PR112490 to also adjust basic_const_iterator's friend operator-(sent, iter) overload alongside the r15-7757-g4342c50ca84ae5 adjustments to its comparison operators, but we lacked a concrete testcase demonstrating fixable constraint recursion there. It turns out Hewill Kang's PR115046 is such a testcase! So this patch makes the same adjustments to that overload as well, fixing PR115046. The LWG 4218 P/R will need to get adjusted too. PR libstdc++/115046 PR libstdc++/112490 libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (basic_const_iterator::operator-): Replace non-dependent basic_const_iterator function parameter with a dependent one of type basic_const_iterator<_It2> where _It2 matches _It. * testsuite/std/ranges/adaptors/as_const/1.cc (test04): New test. Reviewed-by: Jonathan Wakely (cherry picked from commit d69f73c0334486f3c66937388f02008736809e87) Diff: --- libstdc++-v3/include/bits/stl_iterator.h | 4 ++-- libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc | 13 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 5e1fe30135ef..2162792782eb 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -2917,10 +2917,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(noexcept(_M_current - __y)) { return _M_current - __y; } -template<__detail::__not_a_const_iterator _Sent> +template<__detail::__not_a_const_iterator _Sent, same_as<_It> _It2> requires sized_sentinel_for<_Sent, _It> friend constexpr difference_type - operator-(const _Sent& __x, const basic_const_iterator& __y) + operator-(const _Sent& __x, const basic_const_iterator<_It2>& __y) noexcept(noexcept(__x - __y._M_current)) { return __x - __y._M_current; } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc index 3f1f8eb17726..5ccf47d4d300 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc @@ -69,10 +69,23 @@ test03() auto r2 = views::as_const(views::all(v)); } +void +test04() +{ + // PR libstdc++/115046 - meta-recursion with join_view and as_const_view + int x[3] = {1,2,3}; + auto v = x +| views::chunk(3) +| views::transform(views::as_const) +| views::join; + VERIFY( ranges::equal(v, x) ); +} + int main() { static_assert(test01()); static_assert(test02()); test03(); + test04(); }
[gcc/devel/rust/master] Make loop label truly optional
https://gcc.gnu.org/g:f77aeb99dde12544ea7c29004e88d46a8d5aa7b2 commit f77aeb99dde12544ea7c29004e88d46a8d5aa7b2 Author: Pierre-Emmanuel Patry Date: Tue Apr 1 15:57:47 2025 +0200 Make loop label truly optional A loop label error state was in use to represent missing loop label but this may be easily forgotten and the optional nature of the label was misrepresented. gcc/rust/ChangeLog: * ast/rust-ast-builder.cc (Builder::block): Call with a nullopt instead of an error loop label. (WhileLetLoopExpr::as_string): Use getter function and adapt to newtype. * ast/rust-ast.cc (WhileLoopExpr::as_string): Likewise. (LoopExpr::as_string): Likewise. (BreakExpr::as_string): Likewise. (ForLoopExpr::as_string): Likewise. * ast/rust-expr.h (class BlockExpr): Make loop label optional. (class BreakExpr): Likewise. * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Use nullopt. * expand/rust-derive-debug.cc (DeriveDebug::stub_debug_fn): Likewise. * expand/rust-derive-default.cc (DeriveDefault::default_fn): Likewise. * expand/rust-derive-eq.cc: Likewise. * parse/rust-parse-impl.h (Parser::parse_block_expr): Use optional for arguments. (Parser::parse_loop_expr): Likewise. (Parser::parse_while_loop_expr): Likewise. (Parser::parse_while_let_loop_expr): Likewise. (Parser::parse_for_loop_expr): Likewise. (Parser::parse_labelled_loop_expr): Likewise. (Parser::parse_loop_label): Return an optional. * parse/rust-parse.h: Update function prototype and use nullopt for default values. Signed-off-by: Pierre-Emmanuel Patry Diff: --- gcc/rust/ast/rust-ast-builder.cc | 6 +-- gcc/rust/ast/rust-ast.cc | 10 ++--- gcc/rust/ast/rust-expr.h | 35 --- gcc/rust/expand/rust-derive-clone.cc | 3 +- gcc/rust/expand/rust-derive-debug.cc | 3 +- gcc/rust/expand/rust-derive-default.cc | 3 +- gcc/rust/expand/rust-derive-eq.cc | 3 +- gcc/rust/parse/rust-parse-impl.h | 80 +- gcc/rust/parse/rust-parse.h| 12 ++--- 9 files changed, 77 insertions(+), 78 deletions(-) diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 2e3685f2b198..437ba1b56ea0 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -335,9 +335,9 @@ std::unique_ptr Builder::block (std::vector> &&stmts, std::unique_ptr &&tail_expr) const { - return std::unique_ptr ( -new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {}, - LoopLabel::error (), loc, loc)); + return std::unique_ptr (new BlockExpr (std::move (stmts), + std::move (tail_expr), {}, + {}, tl::nullopt, loc, loc)); } std::unique_ptr diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 43f1ee2f5266..2d286cdf3d70 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -2095,7 +2095,7 @@ WhileLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else -str += loop_label.as_string (); +str += get_loop_label ().as_string (); str += "\n Conditional expr: " + condition->as_string (); @@ -2115,7 +2115,7 @@ WhileLetLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else -str += loop_label.as_string (); +str += get_loop_label ().as_string (); str += "\n Match arm patterns: "; if (match_arm_patterns.empty ()) @@ -2146,7 +2146,7 @@ LoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else -str += loop_label.as_string (); +str += get_loop_label ().as_string (); str += "\n Loop block: " + loop_block->as_string (); @@ -2183,7 +2183,7 @@ BreakExpr::as_string () const std::string str ("break "); if (has_label ()) -str += label.as_string () + " "; +str += get_label ().as_string () + " "; if (has_break_expr ()) str += break_expr->as_string (); @@ -2545,7 +2545,7 @@ ForLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else -str += loop_label.as_string (); +str += get_loop_label ().as_string (); str += "\n Pattern: " + pattern->as_string (); diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index cff09fe17d7b..3ce78c643c73 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -2590,7 +2590,7 @@ class BlockExpr : public ExprWithBlock std::vector inner_attrs; std::vector > statements; std::unique_ptr expr; - LoopLabel label; + tl::optional label; location_t start_locus; location_t end_locus; bool marked_for_strip =
[gcc r15-9339] [RISC-V] Fix more fallout from combine.c changes
https://gcc.gnu.org/g:4645d092969face6aa1da4c919924697185f9cf9 commit r15-9339-g4645d092969face6aa1da4c919924697185f9cf9 Author: Jeff Law Date: Wed Apr 9 08:33:17 2025 -0600 [RISC-V] Fix more fallout from combine.c changes Trivial fallout from the recent combine work. We end up with a srai rather than an xor in some of the saturation sequences. Both variants look equally performant, so I'm just adjusting the expected test output. gcc/testsuite * gcc.target/riscv/sat/sat_s_sub-1-i64.c: Update expected output. * gcc.target/riscv/sat/sat_s_sub-2-i64.c: Likewise. * gcc.target/riscv/sat/sat_s_sub-3-i64.c: Likewise. * gcc.target/riscv/sat/sat_s_sub-4-i64.c: Likewise. Diff: --- gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c | 2 +- gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c | 2 +- gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c | 2 +- gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c index c0d643d710f4..929de162d574 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c @@ -15,7 +15,7 @@ ** li\s+[atx][0-9]+,\s*-1 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 ** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ ** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c index 470e6b7391be..a5401983e7d9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c @@ -15,7 +15,7 @@ ** li\s+[atx][0-9]+,\s*-1 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 ** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ ** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c index bb947751fdad..e3fe6c78ca6a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c @@ -15,7 +15,7 @@ ** li\s+[atx][0-9]+,\s*-1 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 ** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ ** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c index cc598ebc0d23..f42ffea5f9f6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c @@ -15,7 +15,7 @@ ** li\s+[atx][0-9]+,\s*-1 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 ** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ ** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 ** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
[gcc r15-9350] c++: ICE with nested default targ lambdas [PR119574]
https://gcc.gnu.org/g:f3862ab07943d1fc6e6a0416657ae4b7d1f3941d commit r15-9350-gf3862ab07943d1fc6e6a0416657ae4b7d1f3941d Author: Patrick Palka Date: Wed Apr 9 17:47:34 2025 -0400 c++: ICE with nested default targ lambdas [PR119574] Here we substitute into the inner lambda twice, first during default argument substitution for the outer template parameters, then during that for the inner template parameters. For the second testcase (which is easier to follow/debug), the first substitution into the inner lambda is with the template arguments {0, NULL_TREE}, which we defer because it's an incremental substitution. For the second and final substitution we have the template arguments {1, NULL_TREE}, which we try combining via add_extra_args and ICE on the checking assert because TREE_STATIC isn't set on the deferred arguments but the template arguments are considered dependent. The template arguments aren't dependent however -- they're just incomplete because when we deferred them we were in the middle of deduction, and we consider a NULL_TREE template argument as dependent. If we remove this checking assert, we go on to correctly merge the template arguments into {{0, NULL_TREE}, {1, NULL_TREE}}. So this patch just removes this imprecise assert. PR c++/119574 gcc/cp/ChangeLog: * pt.cc (add_extra_args): Remove checking assert. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ13.C: New test. * g++.dg/cpp2a/lambda-targ13a.C: New test. * g++.dg/cpp2a/lambda-targ13b.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/pt.cc| 1 - gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C | 7 +++ gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C | 8 gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C | 8 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 0e120c4040ed..63c2ec0c59b3 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -13752,7 +13752,6 @@ add_extra_args (tree extra, tree args, tsubst_flags_t complain, tree in_decl) gcc_assert (!TREE_PURPOSE (extra)); extra = TREE_VALUE (extra); } - gcc_checking_assert (TREE_STATIC (extra) == uses_template_parms (extra)); if (TREE_STATIC (extra)) /* This is a partial substitution into e.g. a requires-expr or lambda-expr inside a default template argument; we expect 'extra' to be a full set diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C new file mode 100644 index ..8fd0a311e056 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C @@ -0,0 +1,7 @@ +// PR c++/119574 +// { dg-do compile { target c++20 } } + +template () {})> +void f(F op = {}) { op(); } + +int main() { f(); } diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C new file mode 100644 index ..8aaefd93356c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C @@ -0,0 +1,8 @@ +// PR c++/119574 +// A version of lambda-targ13.C with extra template parameters. +// { dg-do compile { target c++20 } } + +template () {})> +void f(F op = {}) { op(); } + +int main() { f(); } diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C new file mode 100644 index ..7f541c75bd71 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C @@ -0,0 +1,8 @@ +// PR c++/119574 +// A version of lambda-targ13.C where the inner lambda returns non-void. +// { dg-do compile { target c++20 } } + +template () { return G(); })> +constexpr int f(F op = {}) { return op(); } + +static_assert(f() == 42);
[gcc r15-9351] libstdc++: Fix constraint recursion in basic_const_iterator operator- [PR115046]
https://gcc.gnu.org/g:d69f73c0334486f3c66937388f02008736809e87 commit r15-9351-gd69f73c0334486f3c66937388f02008736809e87 Author: Patrick Palka Date: Wed Apr 9 17:48:05 2025 -0400 libstdc++: Fix constraint recursion in basic_const_iterator operator- [PR115046] It was proposed in PR112490 to also adjust basic_const_iterator's friend operator-(sent, iter) overload alongside the r15-7757-g4342c50ca84ae5 adjustments to its comparison operators, but we lacked a concrete testcase demonstrating fixable constraint recursion there. It turns out Hewill Kang's PR115046 is such a testcase! So this patch makes the same adjustments to that overload as well, fixing PR115046. The LWG 4218 P/R will need to get adjusted too. PR libstdc++/115046 PR libstdc++/112490 libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (basic_const_iterator::operator-): Replace non-dependent basic_const_iterator function parameter with a dependent one of type basic_const_iterator<_It2> where _It2 matches _It. * testsuite/std/ranges/adaptors/as_const/1.cc (test04): New test. Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/bits/stl_iterator.h | 4 ++-- libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc | 13 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 33732b1a4287..9203a66b2ff0 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -2933,10 +2933,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(noexcept(_M_current - __y)) { return _M_current - __y; } -template<__detail::__not_a_const_iterator _Sent> +template<__detail::__not_a_const_iterator _Sent, same_as<_It> _It2> requires sized_sentinel_for<_Sent, _It> friend constexpr difference_type - operator-(const _Sent& __x, const basic_const_iterator& __y) + operator-(const _Sent& __x, const basic_const_iterator<_It2>& __y) noexcept(noexcept(__x - __y._M_current)) { return __x - __y._M_current; } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc index 3f1f8eb17726..5ccf47d4d300 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc @@ -69,10 +69,23 @@ test03() auto r2 = views::as_const(views::all(v)); } +void +test04() +{ + // PR libstdc++/115046 - meta-recursion with join_view and as_const_view + int x[3] = {1,2,3}; + auto v = x +| views::chunk(3) +| views::transform(views::as_const) +| views::join; + VERIFY( ranges::equal(v, x) ); +} + int main() { static_assert(test01()); static_assert(test02()); test03(); + test04(); }
[gcc r15-9342] d: Fix forward referenced enums missing type names in debug info [PR118309]
https://gcc.gnu.org/g:cee353c2653d274768a67677c8ea37fd23422b3c commit r15-9342-gcee353c2653d274768a67677c8ea37fd23422b3c Author: Iain Buclaw Date: Wed Apr 9 20:02:02 2025 +0200 d: Fix forward referenced enums missing type names in debug info [PR118309] Calling `rest_of_type_compilation' as the D types were built meant that debug info was being emitted before all forward references were resolved, resulting in DW_AT_name's to be missing. Instead, defer outputting type debug information until all modules have been parsed and generated in `d_finish_compilation'. PR d/118309 gcc/d/ChangeLog: * modules.cc: Include debug.h (d_finish_compilation): Call debug_hooks->type_decl on all TYPE_DECLs. * types.cc: Remove toplev.h include. (finish_aggregate_type): Don't call rest_of_type_compilation or rest_of_decl_compilation on type. (TypeVisitor::visit (TypeEnum *)): Likewise. gcc/testsuite/ChangeLog: * gdc.dg/debug/dwarf2/pr118309.d: New test. Diff: --- gcc/d/modules.cc | 9 +++ gcc/d/types.cc | 15 ++-- gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d | 36 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index 813d94bc5c4e..14e4a4850431 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "cgraph.h" #include "stor-layout.h" +#include "debug.h" #include "toplev.h" #include "target.h" #include "common/common-target.h" @@ -927,6 +928,14 @@ d_finish_compilation (tree *vec, int len) /* Complete all generated thunks. */ symtab->process_same_body_aliases (); + /* Output debug information for all type declarations in this unit. */ + for (int i = 0; i < len; i++) +{ + tree decl = vec[i]; + if (TREE_CODE (decl) == TYPE_DECL) + debug_hooks->type_decl (decl, false); +} + /* Process all file scopes in this compilation, and the external_scope, through wrapup_global_declarations. */ for (int i = 0; i < len; i++) diff --git a/gcc/d/types.cc b/gcc/d/types.cc index ea62bc9d05e1..e43fa88a5d4c 100644 --- a/gcc/d/types.cc +++ b/gcc/d/types.cc @@ -33,7 +33,6 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "tm.h" #include "function.h" -#include "toplev.h" #include "target.h" #include "stringpool.h" #include "stor-layout.h" @@ -709,13 +708,8 @@ finish_aggregate_type (unsigned structsize, unsigned alignsize, tree type) TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type); } - /* Finish debugging output for this type. */ - rest_of_type_compilation (type, TYPE_FILE_SCOPE_P (type)); + /* Complete any other forward-referenced fields of this aggregate type. */ finish_incomplete_fields (type); - - /* Finish processing of TYPE_DECL. */ - rest_of_decl_compilation (TYPE_NAME (type), - DECL_FILE_SCOPE_P (TYPE_NAME (type)), 0); } /* Returns true if the class or struct type TYPE has already been layed out by @@ -1185,13 +1179,8 @@ public: layout_type (t->ctype); - /* Finish debugging output for this type. */ - rest_of_type_compilation (t->ctype, TYPE_FILE_SCOPE_P (t->ctype)); + /* Complete forward-referenced fields of this enum type. */ finish_incomplete_fields (t->ctype); - - /* Finish processing of TYPE_DECL. */ - rest_of_decl_compilation (TYPE_NAME (t->ctype), - DECL_FILE_SCOPE_P (TYPE_NAME (t->ctype)), 0); } } diff --git a/gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d b/gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d new file mode 100644 index ..50e42164eef1 --- /dev/null +++ b/gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d @@ -0,0 +1,36 @@ +// { dg-do compile } +// { dg-options "-fno-druntime -gdwarf-4 -dA -fno-merge-debug-strings" } +// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_enumeration_type" 1 } } +// { dg-final { scan-assembler-times " DW_AT_enum_class" 1 } } +// { dg-final { scan-assembler-times "\"E..\"\[^\n\]*DW_AT_name" 1 } } +// { dg-final { scan-assembler-times "\"E1..\"\[^\n\]*DW_AT_name" 1 } } +// { dg-final { scan-assembler-times "\"C1..\"\[^\n\]*DW_AT_name" 1 } } +// { dg-final { scan-assembler-times "\"C2..\"\[^\n\]*DW_AT_name" 1 } } +// { dg-final { scan-assembler-times "\"C3..\"\[^\n\]*DW_AT_name" 1 } } +// { dg-final { scan-assembler-times "\"C4..\"\[^\n\]*DW_AT_name" 1 } } +// { dg-final { scan-assembler-times "\"S1..\"\[^\n\]*DW_AT_name" 1 } } + +module expression; +extern (C++): +class C1 +{ +bool bfn() { return true; } +} +class C2 : C1 +{ +C4 cfn() { return null; } +} +class C3 : C2 +{ +S1.E s; +} +class C4 : C3 +{ +S1 s; +} +struct S1 +{
[gcc r14-11547] [RISC-V][PR target/116308] Fix generation of initial RTL for atomics
https://gcc.gnu.org/g:f3ac41f84249d10a1685c73d67e5d071902fcc4c commit r14-11547-gf3ac41f84249d10a1685c73d67e5d071902fcc4c Author: Jeff Law Date: Sat Jan 18 13:44:33 2025 -0700 [RISC-V][PR target/116308] Fix generation of initial RTL for atomics While this wasn't originally marked as a regression, it almost certainly is given that older versions of GCC would have used libatomic and would not have ICE'd on this code. Basically this is another case where we directly used simplify_gen_subreg when we should have used gen_lowpart. When I fixed a similar bug a while back I noted the code in question as needing another looksie. I think at that time my brain saw the mixed modes (SI & QI) and locked up. But the QI stuff is just the shift count, not some deeper issue. So fixing is trivial. We just replace the simplify_gen_subreg with a gen_lowpart and get on with our lives. Tested on rv64 and rv32 in my tester. Waiting on pre-commit testing for final verdict. PR target/116308 gcc/ * config/riscv/riscv.cc (riscv_lshift_subword): Use gen_lowpart rather than simplify_gen_subreg. gcc/testsuite/ * gcc.target/riscv/pr116308.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 4 +--- gcc/testsuite/gcc.target/riscv/pr116308.c | 9 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 2841787d93e7..a6a3b2745c53 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -10428,9 +10428,7 @@ riscv_lshift_subword (machine_mode mode, rtx value, rtx shift, rtx *shifted_value) { rtx value_reg = gen_reg_rtx (SImode); - emit_move_insn (value_reg, simplify_gen_subreg (SImode, value, - mode, 0)); - + emit_move_insn (value_reg, gen_lowpart (SImode, value)); emit_move_insn (*shifted_value, gen_rtx_ASHIFT (SImode, value_reg, gen_lowpart (QImode, shift))); } diff --git a/gcc/testsuite/gcc.target/riscv/pr116308.c b/gcc/testsuite/gcc.target/riscv/pr116308.c new file mode 100644 index ..241df14bd922 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr116308.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -march=rv64gc -mabi=lp64d" { target rv64 } } */ +/* { dg-options "-Ofast -march=rv32gc -mabi=ilp32" { target rv32 } } */ + +_Float16 test__Float16_post_inc() +{ +_Atomic _Float16 n; +return n++; +}
[gcc r14-11568] RISC-V: Delete duplicate '#define RISCV_DWARF_VLENB'
https://gcc.gnu.org/g:28fe2b087baea05759aa7386fb8c3862aecf51ef commit r14-11568-g28fe2b087baea05759aa7386fb8c3862aecf51ef Author: Jin Ma Date: Thu Aug 8 07:49:51 2024 -0600 RISC-V: Delete duplicate '#define RISCV_DWARF_VLENB' gcc/ChangeLog: * config/riscv/riscv.h (RISCV_DWARF_VLENB): Delete. Diff: --- gcc/config/riscv/riscv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 7797e67317a6..8a9fec787e48 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -1211,8 +1211,6 @@ extern void riscv_remove_unneeded_save_restore_calls (void); #define REGMODE_NATURAL_SIZE(MODE) riscv_regmode_natural_size (MODE) -#define RISCV_DWARF_VLENB (4096 + 0xc22) - #define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 1 /* VLENB */) #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) \
[gcc r15-9334] rtl-optimization/119689 - compare-debug failure with LRA
https://gcc.gnu.org/g:07de7717a22b1503760e9b79dfbe22a0f428 commit r15-9334-g07de7717a22b1503760e9b79dfbe22a0f428 Author: Richard Biener Date: Wed Apr 9 14:36:19 2025 +0200 rtl-optimization/119689 - compare-debug failure with LRA The previous change to fix LRA rematerialization broke compare-debug for i586 bootstrap. Fixed by using prev_nonnote_nondebug_insn instead of prev_nonnote_insn. PR rtl-optimization/119689 PR rtl-optimization/115568 * lra-remat.cc (create_cands): Use prev_nonnote_nondebug_insn to check whether insn2 is directly before insn. * g++.target/i386/pr119689.C: New testcase. Diff: --- gcc/lra-remat.cc | 2 +- gcc/testsuite/g++.target/i386/pr119689.C | 44 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/gcc/lra-remat.cc b/gcc/lra-remat.cc index 2f3afffcf5be..5f823193aa73 100644 --- a/gcc/lra-remat.cc +++ b/gcc/lra-remat.cc @@ -460,7 +460,7 @@ create_cands (void) && dst_regno >= FIRST_PSEUDO_REGISTER && reg_renumber[dst_regno] < 0 && BLOCK_FOR_INSN (insn2) == BLOCK_FOR_INSN (insn) - && insn2 == prev_nonnote_insn (insn)) + && insn2 == prev_nonnote_nondebug_insn (insn)) { create_cand (insn2, regno_potential_cand[src_regno].nop, dst_regno, insn); diff --git a/gcc/testsuite/g++.target/i386/pr119689.C b/gcc/testsuite/g++.target/i386/pr119689.C new file mode 100644 index ..cdc6d2dade53 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr119689.C @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-O2 -fcompare-debug" } +// { dg-additional-options "-march=i586 -mtune=generic" { target ia32 } } +// { dg-additional-options "-fPIC" { target { fpic } } } + +enum gimple_code { GIMPLE_ASSIGN, GIMPLE_RETURN }; +bool is_gimple_call(); +int m_sig, m_exp, sreal_new_exp; +struct sreal { + sreal(long long sig) { +long long __trans_tmp_6 = sig >= 0 ? sig : -(unsigned long long)sig; +sig = __trans_tmp_6 <<= sreal_new_exp -= m_exp = __trans_tmp_6; +m_sig = sig; + } + void operator/(sreal); +}; +struct ipa_predicate { + ipa_predicate(bool = true); + void operator&=(ipa_predicate); + void operator&(ipa_predicate); +}; +void add_condition(); +gimple_code eliminated_by_inlining_prob_code; +static int eliminated_by_inlining_prob() { + switch (eliminated_by_inlining_prob_code) { + case GIMPLE_RETURN: +return 2; + case GIMPLE_ASSIGN: +return 1; + } + return 0; +} +void fp_expression_p() { + ipa_predicate bb_predicate; + for (;;) { +int prob = eliminated_by_inlining_prob(); +ipa_predicate sra_predicate; +sra_predicate &= add_condition; +if (is_gimple_call()) + sreal(prob) / 2; +if (prob != 2) + bb_predicate & sra_predicate; + } +}
[gcc r14-11551] RISC-V: Fix vsetvl compatibility predicate [PR118154].
https://gcc.gnu.org/g:6f549f865d02f897f682dddf56f392a22c01df6c commit r14-11551-g6f549f865d02f897f682dddf56f392a22c01df6c Author: Robin Dapp Date: Thu Jan 9 20:45:10 2025 +0100 RISC-V: Fix vsetvl compatibility predicate [PR118154]. In PR118154 we emit strided stores but the first of those does not always have the proper VTYPE. That's because we erroneously delete a necessary vsetvl. In order to determine whether to elide (1) Expr[7]: VALID (insn 116, bb 17) Demand fields: demand_ratio_and_ge_sew demand_avl SEW=8, VLMUL=mf2, RATIO=16, MAX_SEW=64 TAIL_POLICY=agnostic, MASK_POLICY=agnostic AVL=(reg:DI 0 zero) when e.g. (2) Expr[3]: VALID (insn 360, bb 15) Demand fields: demand_sew_lmul demand_avl SEW=64, VLMUL=m1, RATIO=64, MAX_SEW=64 TAIL_POLICY=agnostic, MASK_POLICY=agnostic AVL=(reg:DI 0 zero) VL=(reg:DI 13 a3 [345]) is already available, we use sew_ge_and_prev_sew_le_next_max_sew_and_next_ratio_valid_for_prev_sew_p. (1) requires RATIO = SEW/LMUL = 16 and an SEW >= 8. (2) has ratio = 64, though, so we cannot directly elide (1). This patch uses ratio_eq_p instead of next_ratio_valid_for_prev_sew_p. PR target/118154 gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (MAX_LMUL): New define. (pre_vsetvl::earliest_fuse_vsetvl_info): Use. (pre_vsetvl::pre_global_vsetvl_info): New predicate with equal ratio. * config/riscv/riscv-vsetvl.def: Use. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr118154-1.c: New test. * gcc.target/riscv/rvv/autovec/pr118154-2.c: New test. Diff: --- gcc/config/riscv/riscv-vsetvl.cc | 14 +++--- gcc/config/riscv/riscv-vsetvl.def | 4 +-- .../gcc.target/riscv/rvv/autovec/pr118154-1.c | 23 .../gcc.target/riscv/rvv/autovec/pr118154-2.c | 31 ++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 62f48f0f077f..96cd82756cf8 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -222,6 +222,8 @@ enum emit_type EMIT_AFTER, }; +static const int MAX_LMUL = 8; + /* dump helper functions */ static const char * vlmul_to_str (vlmul_type vlmul) @@ -1439,14 +1441,13 @@ private: inline bool prev_ratio_valid_for_next_sew_p (const vsetvl_info &prev, const vsetvl_info &next) { -return prev.get_ratio () >= (next.get_sew () / 8); +return prev.get_ratio () >= (next.get_sew () / MAX_LMUL); } inline bool next_ratio_valid_for_prev_sew_p (const vsetvl_info &prev, const vsetvl_info &next) { -return next.get_ratio () >= (prev.get_sew () / 8); +return next.get_ratio () >= (prev.get_sew () / MAX_LMUL); } - inline bool sew_ge_and_ratio_eq_p (const vsetvl_info &prev, const vsetvl_info &next) { @@ -1464,6 +1465,13 @@ private: return sew_ge_p (prev, next) && prev_sew_le_next_max_sew_p (prev, next) && next_ratio_valid_for_prev_sew_p (prev, next); } + inline bool + sew_ge_and_prev_sew_le_next_max_sew_and_ratio_eq_p ( +const vsetvl_info &prev, const vsetvl_info &next) + { +return sew_ge_p (prev, next) && prev_sew_le_next_max_sew_p (prev, next) + && ratio_eq_p (prev, next); + } inline bool sew_le_and_next_sew_le_prev_max_sew_p (const vsetvl_info &prev, const vsetvl_info &next) { diff --git a/gcc/config/riscv/riscv-vsetvl.def b/gcc/config/riscv/riscv-vsetvl.def index 8f624f5cf264..cde238a1b8bf 100644 --- a/gcc/config/riscv/riscv-vsetvl.def +++ b/gcc/config/riscv/riscv-vsetvl.def @@ -53,8 +53,8 @@ DEF_SEW_LMUL_RULE (sew_lmul, ge_sew, sew_lmul, sew_ge_and_prev_sew_le_next_max_sew_p, nop) DEF_SEW_LMUL_RULE ( sew_lmul, ratio_and_ge_sew, sew_lmul, - sew_ge_and_prev_sew_le_next_max_sew_and_next_ratio_valid_for_prev_sew_p, - sew_ge_and_prev_sew_le_next_max_sew_and_next_ratio_valid_for_prev_sew_p, nop) + sew_ge_and_prev_sew_le_next_max_sew_and_ratio_eq_p, + sew_ge_and_prev_sew_le_next_max_sew_and_ratio_eq_p, nop) DEF_SEW_LMUL_RULE (ratio_only, sew_lmul, sew_lmul, ratio_eq_p, always_false, use_next_sew_lmul) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr118154-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr118154-1.c new file mode 100644 index ..55386568a5f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr118154-1.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-require-effective-target riscv_v_ok } */ +/*
[gcc r14-11548] [PR target/118357] RISC-V: Disable fusing vsetvl instructions by VSETVL_VTYPE_CHANGE_ONLY for XThead
https://gcc.gnu.org/g:e4586ae318436d63aa91c2d417f068987c77e442 commit r14-11548-ge4586ae318436d63aa91c2d417f068987c77e442 Author: Jin Ma Date: Sat Jan 18 07:43:17 2025 -0700 [PR target/118357] RISC-V: Disable fusing vsetvl instructions by VSETVL_VTYPE_CHANGE_ONLY for XTheadVector. In RVV 1.0, the instruction "vsetvlizero,zero,*" indicates that the available vector length (avl) does not change. However, in XTheadVector, this same instruction signifies that the avl should take the maximum value. Consequently, when fusing vsetvl instructions, the optimization labeled "VSETVL_VTYPE_CHANGE_ONLY" is disabled for XTheadVector. PR target/118357 gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc: Function change_vtype_only_p always returns false for XTheadVector. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/xtheadvector/pr118357.c: New test. Diff: --- gcc/config/riscv/riscv-vsetvl.cc | 3 ++- gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c | 13 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 48ce757a6ee5..62f48f0f077f 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -900,7 +900,8 @@ public: bool valid_p () const { return m_state == state_type::VALID; } bool unknown_p () const { return m_state == state_type::UNKNOWN; } bool empty_p () const { return m_state == state_type::EMPTY; } - bool change_vtype_only_p () const { return m_change_vtype_only; } + bool change_vtype_only_p () const { return m_change_vtype_only +&& !TARGET_XTHEADVECTOR; } void set_valid () { m_state = state_type::VALID; } void set_unknown () { m_state = state_type::UNKNOWN; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c new file mode 100644 index ..aebb0e3088ab --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-options "-march=rv64gc_xtheadvector -mabi=lp64d -O2" } */ + +#include + +vfloat16m4_t foo (float *ptr, size_t vl) +{ + vfloat32m8_t _p = __riscv_vle32_v_f32m8 (ptr, vl); + vfloat16m4_t _half = __riscv_vfncvt_f_f_w_f16m4 (_p, vl); + return _half; +} + +/* { dg-final { scan-assembler-not {th.vsetvli\tzero,zero} } }*/
[gcc r14-11556] RISC-V: Add assert for insn operand out of range access [PR117878][NFC]
https://gcc.gnu.org/g:acb636a9c3ac18e7234e37c99bd6e9200b80b9bd commit r14-11556-gacb636a9c3ac18e7234e37c99bd6e9200b80b9bd Author: Pan Li Date: Wed Dec 4 13:53:52 2024 +0800 RISC-V: Add assert for insn operand out of range access [PR117878][NFC] According to the the initial analysis of PR117878, the ice comes from the out-of-range operand access for recog_data.operand[]. Thus, add one assert here to expose this explicitly. PR target/117878 gcc/ChangeLog: * config/riscv/riscv-v.cc (vlmax_avl_type_p): Add assert for out of range access. (nonvlmax_avl_type_p): Ditto. Signed-off-by: Pan Li Diff: --- gcc/config/riscv/riscv-v.cc | 6 ++ 1 file changed, 6 insertions(+) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 33df1518d4a9..d95fb893c82a 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -4966,6 +4966,9 @@ vlmax_avl_type_p (rtx_insn *rinsn) int index = get_attr_avl_type_idx (rinsn); if (index == INVALID_ATTRIBUTE) return false; + + gcc_assert (index < recog_data.n_operands); + rtx avl_type = recog_data.operand[index]; return INTVAL (avl_type) == VLMAX; } @@ -5014,6 +5017,9 @@ nonvlmax_avl_type_p (rtx_insn *rinsn) int index = get_attr_avl_type_idx (rinsn); if (index == INVALID_ATTRIBUTE) return false; + + gcc_assert (index < recog_data.n_operands); + rtx avl_type = recog_data.operand[index]; return INTVAL (avl_type) == NONVLMAX; }
[gcc r15-9340] Fortran: fix issue with impure elemental subroutine and interface [PR119656]
https://gcc.gnu.org/g:334545194d9023fb9b2f72ee0dcde8af94930f25 commit r15-9340-g334545194d9023fb9b2f72ee0dcde8af94930f25 Author: Harald Anlauf Date: Tue Apr 8 22:30:15 2025 +0200 Fortran: fix issue with impure elemental subroutine and interface [PR119656] PR fortran/119656 gcc/fortran/ChangeLog: * interface.cc (gfc_compare_actual_formal): Fix front-end memleak when searching for matching interfaces. * trans-expr.cc (gfc_conv_procedure_call): If there is a formal dummy corresponding to an absent argument, use its type, and only fall back to inferred type otherwise. gcc/testsuite/ChangeLog: * gfortran.dg/optional_absent_13.f90: New test. Diff: --- gcc/fortran/interface.cc | 6 ++- gcc/fortran/trans-expr.cc| 18 ++--- gcc/testsuite/gfortran.dg/optional_absent_13.f90 | 48 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc index 6258a41cb596..c702239d64da 100644 --- a/gcc/fortran/interface.cc +++ b/gcc/fortran/interface.cc @@ -3382,7 +3382,11 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, return false; } else - a->associated_dummy = get_nonintrinsic_dummy_arg (f); + { + if (a->associated_dummy) + free (a->associated_dummy); + a->associated_dummy = get_nonintrinsic_dummy_arg (f); + } if (a->expr == NULL) { diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 6ece39b218d0..62dd38d6f9d0 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6925,10 +6925,18 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, { /* Pass a NULL pointer for an absent arg. */ parmse.expr = null_pointer_node; + + /* Is it an absent character dummy? */ + bool absent_char = false; gfc_dummy_arg * const dummy_arg = arg->associated_dummy; - if (dummy_arg - && gfc_dummy_arg_get_typespec (*dummy_arg).type -== BT_CHARACTER) + + /* Fall back to inferred type only if no formal. */ + if (fsym) + absent_char = (fsym->ts.type == BT_CHARACTER); + else if (dummy_arg) + absent_char = (gfc_dummy_arg_get_typespec (*dummy_arg).type + == BT_CHARACTER); + if (absent_char) parmse.string_length = build_int_cst (gfc_charlen_type_node, 0); } @@ -6954,9 +6962,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, || !CLASS_DATA (fsym)->attr.allocatable)); gfc_init_se (&parmse, NULL); parmse.expr = null_pointer_node; - if (arg->associated_dummy - && gfc_dummy_arg_get_typespec (*arg->associated_dummy).type -== BT_CHARACTER) + if (fsym->ts.type == BT_CHARACTER) parmse.string_length = build_int_cst (gfc_charlen_type_node, 0); } else if (fsym && fsym->ts.type == BT_CLASS diff --git a/gcc/testsuite/gfortran.dg/optional_absent_13.f90 b/gcc/testsuite/gfortran.dg/optional_absent_13.f90 new file mode 100644 index ..9c2039bfb3f6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/optional_absent_13.f90 @@ -0,0 +1,48 @@ +! { dg-do run } +! PR fortran/119656 - wrong code with impure elemental subroutine and interface +! +! Derived from testcase at: +! https://fortran-lang.discourse.group/t/ +! problem-with-impure-elemental-subroutine-in-interface-with-gfortran/9545 + +module m2 + implicit none + interface foo + module procedure foo_mat + module procedure foo_df + module procedure foo_cmat + end interface foo +contains + + subroutine foo_mat(x, nacf, label) +real, intent(in) :: x(:,:) +integer, intent(in) :: nacf +character(len=*), intent(in), optional :: label + end subroutine foo_mat + + impure elemental subroutine foo_df(nacf, outu, xstr) +integer , intent(in) :: nacf +integer , intent(in), optional :: outu +character(len=*), intent(in), optional :: xstr +if (present(xstr)) then + if (len (xstr) /= 2) then + print *,"nacf, len(xstr) =", nacf, len(xstr) + stop nacf + end if +end if + end subroutine foo_df + + subroutine foo_cmat(x, nacf, label) +complex, intent(in) :: x(:,:) +integer, intent(in) :: nacf +character(len=*), intent(in), optional :: label + end subroutine foo_cmat + +end module m2 + +program main + use m2, only:
[gcc r14-11571] RISC-V: Reject 'd' extension with ILP32E ABI
https://gcc.gnu.org/g:eaf423763c780795ea7ae914d390ac07e149871e commit r14-11571-geaf423763c780795ea7ae914d390ac07e149871e Author: Patrick O'Neill Date: Tue Jul 30 14:28:23 2024 -0700 RISC-V: Reject 'd' extension with ILP32E ABI Also add a testcase for -mabi=lp64d where 'd' is required. gcc/ChangeLog: PR target/116111 * config/riscv/riscv.cc (riscv_option_override): Add error. gcc/testsuite/ChangeLog: * gcc.target/riscv/arch-41.c: New test. * gcc.target/riscv/pr116111.c: New test. Signed-off-by: Patrick O'Neill Diff: --- gcc/config/riscv/riscv.cc | 5 + gcc/testsuite/gcc.target/riscv/arch-41.c | 7 +++ gcc/testsuite/gcc.target/riscv/pr116111.c | 7 +++ 3 files changed, 19 insertions(+) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 16ed2d91663e..9591bdf2c0cb 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -9373,6 +9373,11 @@ riscv_option_override (void) error ("rv64e requires lp64e ABI"); } + /* ILP32E does not support the 'd' extension. */ + if (riscv_abi == ABI_ILP32E && UNITS_PER_FP_REG > 4) +error ("ILP32E ABI does not support the %qc extension", + UNITS_PER_FP_REG > 8 ? 'Q' : 'D'); + /* Zfinx require abi ilp32, ilp32e, lp64 or lp64e. */ if (TARGET_ZFINX && riscv_abi != ABI_ILP32 && riscv_abi != ABI_LP64 diff --git a/gcc/testsuite/gcc.target/riscv/arch-41.c b/gcc/testsuite/gcc.target/riscv/arch-41.c new file mode 100644 index ..699eeb20a587 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-41.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i -mabi=lp64d" } */ +int +foo () +{} + +/* { dg-error "requested ABI requires '-march' to subsume the 'D' extension" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr116111.c b/gcc/testsuite/gcc.target/riscv/pr116111.c new file mode 100644 index ..5c824be2e93e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr116111.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32ed -mabi=ilp32e" } */ +int +foo () +{} + +/* { dg-error "ILP32E ABI does not support the 'D' extension" "" { target *-*-* } 0 } */
[gcc r14-11562] riscv: Fix duplicate assmbler label in @tlsdesc insn
https://gcc.gnu.org/g:5615fea2fce63d49d67691f102601868147c2bbc commit r14-11562-g5615fea2fce63d49d67691f102601868147c2bbc Author: Andreas Schwab Date: Thu Sep 12 13:55:09 2024 +0200 riscv: Fix duplicate assmbler label in @tlsdesc insn Use %= instead of maintaining a sequence number manually, so that it doesn't result in a duplicate assembler label when the insn is duplicated. PR target/116693 * config/riscv/riscv.cc (riscv_legitimize_tls_address): Don't pass seqno to gen_tlsdesc and remove it. * config/riscv/riscv.md (@tlsdesc): Remove operand 1. Use %= instead of %1 in template. Diff: --- gcc/config/riscv/riscv.cc | 4 +--- gcc/config/riscv/riscv.md | 15 +++ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index a58c33a0aa28..3e3a29d30443 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2250,14 +2250,12 @@ riscv_legitimize_tls_address (rtx loc) case TLS_MODEL_GLOBAL_DYNAMIC: if (TARGET_TLSDESC) { - static unsigned seqno; tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST); dest = gen_reg_rtx (Pmode); - emit_insn (gen_tlsdesc (Pmode, loc, GEN_INT (seqno))); + emit_insn (gen_tlsdesc (Pmode, loc)); emit_insn (gen_add3_insn (dest, a0, tp)); - seqno++; } else { diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index c4380a06693e..f65d54ceda49 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2045,17 +2045,16 @@ (define_insn "@tlsdesc" [(set (reg:P A0_REGNUM) - (unspec:P - [(match_operand:P 0 "symbolic_operand" "") -(match_operand:P 1 "const_int_operand")] - UNSPEC_TLSDESC)) + (unspec:P + [(match_operand:P 0 "symbolic_operand" "")] + UNSPEC_TLSDESC)) (clobber (reg:P T0_REGNUM))] "TARGET_TLSDESC" { -return ".LT%1: auipc\ta0,%%tlsdesc_hi(%0)\;" - "\tt0,%%tlsdesc_load_lo(.LT%1)(a0)\;" - "addi\ta0,a0,%%tlsdesc_add_lo(.LT%1)\;" - "jalr\tt0,t0,%%tlsdesc_call(.LT%1)"; +return ".LT%=: auipc\ta0,%%tlsdesc_hi(%0)\;" + "\tt0,%%tlsdesc_load_lo(.LT%=)(a0)\;" + "addi\ta0,a0,%%tlsdesc_add_lo(.LT%=)\;" + "jalr\tt0,t0,%%tlsdesc_call(.LT%=)"; } [(set_attr "type" "multi") (set_attr "length" "16")
[gcc r14-11572] RISC-V: Error early with V and no M extension.
https://gcc.gnu.org/g:b7d975945025d1e4e9237c90b46bf4f660289d22 commit r14-11572-gb7d975945025d1e4e9237c90b46bf4f660289d22 Author: Robin Dapp Date: Wed Jul 24 09:08:00 2024 +0200 RISC-V: Error early with V and no M extension. For calculating the value of a poly_int at runtime we use a multiplication instruction that requires the M extension. Instead of just asserting and ICEing this patch emits an early error at option-parsing time. gcc/ChangeLog: PR target/116036 * config/riscv/riscv.cc (riscv_override_options_internal): Error with TARGET_VECTOR && !TARGET_MUL. gcc/testsuite/ChangeLog: * gcc.target/riscv/arch-31.c: Add m to arch string and expect it. * gcc.target/riscv/arch-32.c: Ditto. * gcc.target/riscv/predef-14.c: Ditto. * gcc.target/riscv/predef-15.c: Ditto. * gcc.target/riscv/predef-16.c: Ditto. * gcc.target/riscv/predef-26.c: Ditto. * gcc.target/riscv/predef-27.c: Ditto. * gcc.target/riscv/predef-32.c: Ditto. * gcc.target/riscv/predef-33.c: Ditto. * gcc.target/riscv/rvv/autovec/pr111486.c: Add m to arch string. * gcc.target/riscv/compare-debug-1.c: Ditto. * gcc.target/riscv/compare-debug-2.c: Ditto. * gcc.target/riscv/rvv/base/pr116036.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 5 + gcc/testsuite/gcc.target/riscv/arch-31.c | 2 +- gcc/testsuite/gcc.target/riscv/arch-32.c | 2 +- gcc/testsuite/gcc.target/riscv/compare-debug-1.c | 2 +- gcc/testsuite/gcc.target/riscv/compare-debug-2.c | 2 +- gcc/testsuite/gcc.target/riscv/predef-14.c| 6 +++--- gcc/testsuite/gcc.target/riscv/predef-15.c| 4 ++-- gcc/testsuite/gcc.target/riscv/predef-16.c| 4 ++-- gcc/testsuite/gcc.target/riscv/predef-26.c| 6 +- gcc/testsuite/gcc.target/riscv/predef-27.c| 6 +- gcc/testsuite/gcc.target/riscv/predef-32.c| 6 +- gcc/testsuite/gcc.target/riscv/predef-33.c| 6 +- gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111486.c | 2 +- gcc/testsuite/gcc.target/riscv/rvv/base/pr116036.c| 11 +++ 14 files changed, 48 insertions(+), 16 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 9591bdf2c0cb..f4a3b96745b6 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -9257,6 +9257,11 @@ riscv_override_options_internal (struct gcc_options *opts) else if (!TARGET_MUL_OPTS_P (opts) && TARGET_DIV_OPTS_P (opts)) error ("%<-mdiv%> requires %<-march%> to subsume the % extension"); + /* We might use a multiplication to calculate the scalable vector length at + runtime. Therefore, require the M extension. */ + if (TARGET_VECTOR && !TARGET_MUL) +sorry ("GCC's current % implementation requires the % extension"); + /* Likewise floating-point division and square root. */ if ((TARGET_HARD_FLOAT_OPTS_P (opts) || TARGET_ZFINX_OPTS_P (opts)) && ((target_flags_explicit & MASK_FDIV) == 0)) diff --git a/gcc/testsuite/gcc.target/riscv/arch-31.c b/gcc/testsuite/gcc.target/riscv/arch-31.c index 5180753b9057..9b867c5ecd20 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-31.c +++ b/gcc/testsuite/gcc.target/riscv/arch-31.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32i_zvfbfmin -mabi=ilp32f" } */ +/* { dg-options "-march=rv32im_zvfbfmin -mabi=ilp32f" } */ int foo() { } diff --git a/gcc/testsuite/gcc.target/riscv/arch-32.c b/gcc/testsuite/gcc.target/riscv/arch-32.c index 496168325129..49a3db794892 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-32.c +++ b/gcc/testsuite/gcc.target/riscv/arch-32.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64iv_zvfbfmin -mabi=lp64d" } */ +/* { dg-options "-march=rv64imv_zvfbfmin -mabi=lp64d" } */ int foo() { } diff --git a/gcc/testsuite/gcc.target/riscv/compare-debug-1.c b/gcc/testsuite/gcc.target/riscv/compare-debug-1.c index d65bb287b9a7..c22e967f03d0 100644 --- a/gcc/testsuite/gcc.target/riscv/compare-debug-1.c +++ b/gcc/testsuite/gcc.target/riscv/compare-debug-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fno-tree-ch --param=max-completely-peel-times=0 -march=rv64iv -mabi=lp64d -fcompare-debug" } */ +/* { dg-options "-O -fno-tree-ch --param=max-completely-peel-times=0 -march=rv64imv -mabi=lp64d -fcompare-debug" } */ void diff --git a/gcc/testsuite/gcc.target/riscv/compare-debug-2.c b/gcc/testsuite/gcc.target/riscv/compare-debug-2.c index d87758475e46..be9bda17b59a 100644 --- a/gcc/testsuite/gcc.target/riscv/compare-debug-2.c +++ b/gcc/testsuite/gcc.target/riscv/compare-debug-2.c @@ -1,3 +1,3 @@ /* { dg-do compile } */ -/* { dg-options "-O -fno-tree-ch --param=max-completely-peel-times=0 -march=rv64i
[gcc r14-11570] RISC-V: Correct mode_idx attribute for viwalu wx variants [PR116149].
https://gcc.gnu.org/g:95ac2d8afb386ccd7277f4906e0aca88d53c835a commit r14-11570-g95ac2d8afb386ccd7277f4906e0aca88d53c835a Author: Robin Dapp Date: Wed Jul 31 16:54:03 2024 +0200 RISC-V: Correct mode_idx attribute for viwalu wx variants [PR116149]. In PR116149 we choose a wrong vector length which causes wrong values in a reduction. The problem happens in avlprop where we choose the number of units in the instruction's mode as vector length. For the non-scalar variants the respective operand has the correct non-widened mode. For the scalar variants, however, the same operand has a scalar mode which obviously only has one unit. This makes us choose VL = 1 leaving three elements undisturbed (so potentially -1). Those end up in the reduction causing the wrong result. This patch adjusts the mode_idx just for the scalar variants of the affected instruction patterns. gcc/ChangeLog: PR target/116149 * config/riscv/vector.md: Fix mode_idx attribute of scalar widen add/sub variants. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr116149.c: New test. Diff: --- gcc/config/riscv/vector.md| 2 ++ gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c | 18 ++ 2 files changed, 20 insertions(+) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index d0cc61bb3be6..913c09ffd856 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -4014,6 +4014,7 @@ "TARGET_VECTOR" "vwadd.wx\t%0,%3,%z4%p1" [(set_attr "type" "viwalu") + (set_attr "mode_idx" "3") (set_attr "mode" "")]) (define_insn "@pred_single_widen_sub_extended_scalar" @@ -4036,6 +4037,7 @@ "TARGET_VECTOR" "vwsub.wx\t%0,%3,%z4%p1" [(set_attr "type" "viwalu") + (set_attr "mode_idx" "3") (set_attr "mode" "")]) (define_insn "@pred_widen_mulsu" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c new file mode 100644 index ..4f5927b96fea --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=zvl" } */ + +long a; +short b[6]; +short c[20]; +int main() { + for (short d = 0; d < 20; d += 3) { +c[d] = 0; +for (int e = 0; e < 20; e += 2) + for (int f = 1; f < 20; f += 2) +a += (unsigned)b[f + e]; + } + if (a != 0) +__builtin_abort (); +} + +/* { dg-final { scan-assembler-times "vsetivli\tzero,1" 0 } } */
[gcc r14-11563] RISC-V: Fix vl_used_by_non_rvv_insn logic of vsetvl pass
https://gcc.gnu.org/g:94b774c5c1cd67608c31d593167996351e952cea commit r14-11563-g94b774c5c1cd67608c31d593167996351e952cea Author: garthlei Date: Wed Sep 11 17:09:37 2024 +0800 RISC-V: Fix vl_used_by_non_rvv_insn logic of vsetvl pass This patch fixes a bug in the current vsetvl pass. The current pass uses `m_vl` to determine whether the dest operand has been used by non-RVV instructions. However, `m_vl` may have been modified as a result of an `update_avl` call, and thus would be no longer the dest operand of the original instruction. This can lead to incorrect vsetvl eliminations, as is shown in the testcase. In this patch, we create a `dest_vl` variable for this scenerio. gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc: Use `dest_vl` for dest VL operand gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c: New test. Diff: --- gcc/config/riscv/riscv-vsetvl.cc| 16 +++- .../gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c | 17 + 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 96cd82756cf8..49702a5c6838 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -1004,6 +1004,9 @@ public: void parse_insn (insn_info *insn) { +/* The VL dest of the insn */ +rtx dest_vl = NULL_RTX; + m_insn = insn; m_bb = insn->bb (); /* Return if it is debug insn for the consistency with optimize == 0. */ @@ -1037,7 +1040,10 @@ public: if (m_avl) { if (vsetvl_insn_p (insn->rtl ()) || has_vlmax_avl ()) - m_vl = ::get_vl (insn->rtl ()); + { + m_vl = ::get_vl (insn->rtl ()); + dest_vl = m_vl; + } if (has_nonvlmax_reg_avl ()) m_avl_def = find_access (insn->uses (), REGNO (m_avl))->def (); @@ -1134,22 +1140,22 @@ public: } /* Determine if dest operand(vl) has been used by non-RVV instructions. */ -if (has_vl ()) +if (dest_vl) { const hash_set vl_uses - = get_all_real_uses (get_insn (), REGNO (get_vl ())); + = get_all_real_uses (get_insn (), REGNO (dest_vl)); for (use_info *use : vl_uses) { gcc_assert (use->insn ()->is_real ()); rtx_insn *rinsn = use->insn ()->rtl (); if (!has_vl_op (rinsn) - || count_regno_occurrences (rinsn, REGNO (get_vl ())) != 1) + || count_regno_occurrences (rinsn, REGNO (dest_vl)) != 1) { m_vl_used_by_non_rvv_insn = true; break; } rtx avl = ::get_avl (rinsn); - if (!avl || !REG_P (avl) || REGNO (get_vl ()) != REGNO (avl)) + if (!avl || !REG_P (avl) || REGNO (dest_vl) != REGNO (avl)) { m_vl_used_by_non_rvv_insn = true; break; diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c new file mode 100644 index ..3acbc739d4dd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv -mabi=ilp32d -O2 -fdump-rtl-vsetvl-details" } */ + +#include "riscv_vector.h" + +uint64_t a[2], b[2]; + +void +foo () +{ + size_t vl = __riscv_vsetvl_e64m1 (2); + vuint64m1_t vx = __riscv_vle64_v_u64m1 (a, vl); + vx = __riscv_vslide1down_vx_u64m1 (vx, 0xull, vl); + __riscv_vse64_v_u64m1 (b, vx, vl); +} + +/* { dg-final { scan-rtl-dump-not "Eliminate insn" "vsetvl" } } */
[gcc r14-11567] RISC-V: Fix factor in dwarf_poly_indeterminate_value [PR116305]
https://gcc.gnu.org/g:327c7c38123eec6264324acd98b4386363d05cb4 commit r14-11567-g327c7c38123eec6264324acd98b4386363d05cb4 Author: 曾治金 Date: Wed Aug 14 14:06:23 2024 +0800 RISC-V: Fix factor in dwarf_poly_indeterminate_value [PR116305] This patch is to fix the bug (BugId:116305) introduced by the commit bd93ef for risc-v target. The commit bd93ef changes the chunk_num from 1 to TARGET_MIN_VLEN/128 if TARGET_MIN_VLEN is larger than 128 in riscv_convert_vector_bits. So it changes the value of BYTES_PER_RISCV_VECTOR. For example, before merging the commit bd93ef and if TARGET_MIN_VLEN is 256, the value of BYTES_PER_RISCV_VECTOR should be [8, 8], but now [16, 16]. The value of riscv_bytes_per_vector_chunk and BYTES_PER_RISCV_VECTOR are no longer equal. Prologue will use BYTES_PER_RISCV_VECTOR.coeffs[1] to estimate the vlenb register value in riscv_legitimize_poly_move, and dwarf2cfi will also get the estimated vlenb register value in riscv_dwarf_poly_indeterminate_value to calculate the number of times to multiply the vlenb register value. So need to change the factor from riscv_bytes_per_vector_chunk to BYTES_PER_RISCV_VECTOR, otherwise we will get the incorrect dwarf information. The incorrect example as follow: ``` csrr t0,vlenb slli t1,t0,1 sub sp,sp,t1 .cfi_escape 0xf,0xb,0x72,0,0x92,0xa2,0x38,0,0x34,0x1e,0x23,0x50,0x22 ``` The sequence '0x92,0xa2,0x38,0' means the vlenb register, '0x34' means the literal 4, '0x1e' means the multiply operation. But in fact, the vlenb register value just need to multiply the literal 2. PR target/116305 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_dwarf_poly_indeterminate_value): Take BYTES_PER_RISCV_VECTOR for *factor instead of riscv_bytes_per_vector_chunk. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/scalable_vector_cfi.c: New test. Signed-off-by: Zhijin Zeng Diff: --- gcc/config/riscv/riscv.cc | 4 +-- .../riscv/rvv/base/scalable_vector_cfi.c | 32 ++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index bce84fe92321..3bc6a5e41ab8 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -10294,12 +10294,12 @@ static unsigned int riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor, int *offset) { - /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1. + /* Polynomial invariant 1 == (VLENB / BYTES_PER_RISCV_VECTOR) - 1. 1. TARGET_MIN_VLEN == 32, polynomial invariant 1 == (VLENB / 4) - 1. 2. TARGET_MIN_VLEN > 32, polynomial invariant 1 == (VLENB / 8) - 1. */ gcc_assert (i == 1); - *factor = riscv_bytes_per_vector_chunk; + *factor = BYTES_PER_RISCV_VECTOR.coeffs[1]; *offset = 1; return RISCV_DWARF_VLENB; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/scalable_vector_cfi.c b/gcc/testsuite/gcc.target/riscv/rvv/base/scalable_vector_cfi.c new file mode 100644 index ..184da10caf37 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/scalable_vector_cfi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-g -O3 -march=rv64gcv -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } {"-O2" "-O1" "-O0" "-Og" "-Oz" "-flto"} } */ +/* { dg-final { scan-assembler {cfi_escape .*0x92,0xa2,0x38,0,0x32,0x1e} } } */ + +#include "riscv_vector.h" + +#define PI_2 1.570796326795 + +extern void func(float *result); + +void test(const float *ys, const float *xs, float *result, size_t length) { +size_t gvl = __riscv_vsetvlmax_e32m2(); +vfloat32m2_t vpi2 = __riscv_vfmv_v_f_f32m2(PI_2, gvl); + +for(size_t i = 0; i < length;) { +gvl = __riscv_vsetvl_e32m2(length - i); +vfloat32m2_t y = __riscv_vle32_v_f32m2(ys, gvl); +vfloat32m2_t x = __riscv_vle32_v_f32m2(xs, gvl); +vbool16_t mask0 = __riscv_vmflt_vv_f32m2_b16(x, y, gvl); +vfloat32m2_t fixpi = __riscv_vfrsub_vf_f32m2_mu(mask0, vpi2, vpi2, 0, gvl); + +__riscv_vse32_v_f32m2(result, fixpi, gvl); + +func(result); + +i += gvl; +ys += gvl; +xs += gvl; +result += gvl; +} +}
[gcc r15-9328] Fortran: Fix some problems with the reduce intrinsic [PR119460]
https://gcc.gnu.org/g:ee65440cbd8042a5e5885e18bde70f8d530e4404 commit r15-9328-gee65440cbd8042a5e5885e18bde70f8d530e4404 Author: Paul Thomas Date: Wed Apr 9 09:50:04 2025 +0100 Fortran: Fix some problems with the reduce intrinsic [PR119460] 2025-04-09 Paul Thomas and Harald Anlauf gcc/fortran PR fortran/119460 * iresolve.cc (generate_reduce_op_wrapper): Increase the size of 'tname'. Change intent of 'a' and 'b' to intent_in. * trans-decl.cc (add_argument_checking): Do not test artificial formal symbols. * trans-expr.cc (gfc_conv_procedure_call): Remove reduce_scalar and the blocks triggered by it. * trans-intrinsic.cc (gfc_conv_intrinsic_function): Set the result of non-character, scalar reduce to be allocatable. gcc/testsuite/ PR fortran/119460 * gfortran.dg/reduce_2.f90: Add test to check that deferred len characters cannot slip through. * gfortran.dg/reduce_3.f90: New test * gfortran.dg/reduce_4.f90: New test libgfortran/ PR libfortran/119460 * intrinsics/reduce.c (reduce): Correct error message about mismatch between dim and the rank of array. Output the values of both. Correct the evaluation of the result stride and extent. (reduce_scalar): The front end treats the result as an allocatable so eliminate memcpy and free. Return the base-addr of the local descriptor. (reduce_c): Correct the type of the string lengths. (reduce_scalar_c): Correct the type of the string lengths.Test to see if 'res' is allocated. If not then return the base_addr of the local descriptor. Diff: --- gcc/fortran/iresolve.cc| 6 +-- gcc/fortran/trans-decl.cc | 2 +- gcc/fortran/trans-expr.cc | 24 --- gcc/fortran/trans-intrinsic.cc | 7 gcc/testsuite/gfortran.dg/reduce_2.f90 | 8 gcc/testsuite/gfortran.dg/reduce_3.f90 | 56 + gcc/testsuite/gfortran.dg/reduce_4.f90 | 48 + libgfortran/intrinsics/reduce.c| 77 -- 8 files changed, 168 insertions(+), 60 deletions(-) diff --git a/gcc/fortran/iresolve.cc b/gcc/fortran/iresolve.cc index 8189d7a1c6f6..858ffb1daebf 100644 --- a/gcc/fortran/iresolve.cc +++ b/gcc/fortran/iresolve.cc @@ -2417,7 +2417,7 @@ generate_reduce_op_wrapper (gfc_expr *op) gfc_symbol *operation = op->symtree->n.sym; gfc_symbol *wrapper, *a, *b, *c; gfc_symtree *st; - char tname[GFC_MAX_SYMBOL_LEN+1]; + char tname[2 * GFC_MAX_SYMBOL_LEN + 2]; char *name; gfc_namespace *ns; gfc_expr *e; @@ -2462,7 +2462,7 @@ generate_reduce_op_wrapper (gfc_expr *op) a->attr.flavor = FL_VARIABLE; a->attr.dummy = 1; a->attr.artificial = 1; - a->attr.intent = INTENT_INOUT; + a->attr.intent = INTENT_IN; wrapper->formal = gfc_get_formal_arglist (); wrapper->formal->sym = a; gfc_set_sym_referenced (a); @@ -2476,7 +2476,7 @@ generate_reduce_op_wrapper (gfc_expr *op) b->attr.dummy = 1; b->attr.optional= 1; b->attr.artificial = 1; - b->attr.intent = INTENT_INOUT; + b->attr.intent = INTENT_IN; wrapper->formal->next = gfc_get_formal_arglist (); wrapper->formal->next->sym = b; gfc_set_sym_referenced (b); diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 9087221dabbf..aea132ded13c 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -6546,7 +6546,7 @@ add_argument_checking (stmtblock_t *block, gfc_symbol *sym) message = _("Actual string length does not match the declared one" " for dummy argument '%s' (%ld/%ld)"); } - else if (fsym->as && fsym->as->rank != 0) + else if ((fsym->as && fsym->as->rank != 0) || fsym->attr.artificial) continue; else { diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 4b90b06fa0a0..6ece39b218d0 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6753,12 +6753,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, gfc_intrinsic_sym *isym = expr && expr->rank ? expr->value.function.isym : NULL; - /* In order that the library function for intrinsic REDUCE be type and kind - agnostic, the result is passed by reference. Allocatable components are - handled within the OPERATION wrapper. */ - bool reduce_scalar = expr && !expr->rank && expr->value.function.isym - && expr->value.function.isym->id == GFC_ISYM_REDUCE; - comp = gfc_get_proc_ptr_comp (expr); bool elemental_proc = (comp @@ -8596,16 +8590,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else if (ts.type == BT_CHA
[gcc r15-9263] libbacktrace: Use correct type in backtrace_atomic_store_int
https://gcc.gnu.org/g:895ea5bdc5e6485faa5fe88ead5a5d8d1f3dc5b9 commit r15-9263-g895ea5bdc5e6485faa5fe88ead5a5d8d1f3dc5b9 Author: Jonathan Wakely Date: Mon Apr 7 20:46:44 2025 +0100 libbacktrace: Use correct type in backtrace_atomic_store_int libbacktrace/ChangeLog: * atomic.c (backtrace_atomic_store_int): Use int for old value. Diff: --- libbacktrace/atomic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbacktrace/atomic.c b/libbacktrace/atomic.c index abf0d8d3e005..43bb88d6043c 100644 --- a/libbacktrace/atomic.c +++ b/libbacktrace/atomic.c @@ -103,7 +103,7 @@ backtrace_atomic_store_size_t (size_t *p, size_t v) void backtrace_atomic_store_int (int *p, int v) { - size_t old; + int old; old = *p; while (!__sync_bool_compare_and_swap (p, old, v))
[gcc/devel/rust/master] gccrs: fix ICE segfault with empty feature gate
https://gcc.gnu.org/g:3f2e8aef6f9e70da075261da80fa1400a2341634 commit 3f2e8aef6f9e70da075261da80fa1400a2341634 Author: Matty Kuhn Date: Fri Apr 4 18:09:41 2025 -0600 gccrs: fix ICE segfault with empty feature gate This patch fixes an issue where an empty feature gate would segfault, instead of reporting a syntax error to the user. gcc/rust/ChangeLog: * ast/rust-ast.h: (AST::Attribute): add empty_input function * checks/errors/rust-feature-gate.cc: (FeatureGate::visit): check for empty feature gate gcc/testsuite/ChangeLog: * rust/compile/feature.rs: add an invalid empty feature to produce an error Signed-off-by: Matty Kuhn Diff: --- gcc/rust/ast/rust-ast.h | 3 +++ gcc/rust/checks/errors/rust-feature-gate.cc | 7 +++ gcc/testsuite/rust/compile/feature.rs | 2 ++ 3 files changed, 12 insertions(+) diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 53bf1bc1c86c..71facfff2671 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -657,6 +657,9 @@ public: // Returns whether the attribute is considered an "empty" attribute. bool is_empty () const { return attr_input == nullptr && path.is_empty (); } + // Returns whether the attribute has no input + bool empty_input () const { return !attr_input; } + location_t get_locus () const { return locus; } AttrInput &get_attr_input () const { return *attr_input; } diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc b/gcc/rust/checks/errors/rust-feature-gate.cc index 5f07d22f1ac1..708dbb1d0a3f 100644 --- a/gcc/rust/checks/errors/rust-feature-gate.cc +++ b/gcc/rust/checks/errors/rust-feature-gate.cc @@ -40,6 +40,13 @@ FeatureGate::visit (AST::Crate &crate) { if (attr.get_path ().as_string () == "feature") { + // check for empty feature, such as `#![feature], this is an error + if (attr.empty_input ()) + { + rust_error_at (attr.get_locus (), ErrorCode::E0556, +"malformed % attribute input"); + continue; + } const auto &attr_input = attr.get_attr_input (); auto type = attr_input.get_attr_input_type (); if (type == AST::AttrInput::AttrInputType::TOKEN_TREE) diff --git a/gcc/testsuite/rust/compile/feature.rs b/gcc/testsuite/rust/compile/feature.rs index f743f9229b68..6f428f075a1b 100644 --- a/gcc/testsuite/rust/compile/feature.rs +++ b/gcc/testsuite/rust/compile/feature.rs @@ -2,5 +2,7 @@ #![feature(AA)] //{ dg-error "unknown feature .AA." } #![feature(iamcrabby)] // { dg-error "unknown feature .iamcrabby." } #![feature(nonexistent_gccrs_feature)] // { dg-error "unknown feature .nonexistent_gccrs_feature." } +// ErrorCode - E0556 +#![feature] // { dg-error "malformed .feature. attribute input" } fn main() {}
[gcc r14-11550] RISC-V: Fix code gen for reduction with length 0 [PR118182]
https://gcc.gnu.org/g:1eb6bf312839d0ff6f0f1a246f9b0b715d1c4b7a commit r14-11550-g1eb6bf312839d0ff6f0f1a246f9b0b715d1c4b7a Author: Kito Cheng Date: Mon Dec 23 23:23:44 2024 +0800 RISC-V: Fix code gen for reduction with length 0 [PR118182] `.MASK_LEN_FOLD_LEFT_PLUS`(or `mask_len_fold_left_plus_m`) is expecting the return value will be the start value even if the length is 0. However current code gen in RISC-V backend is not meet that semantic, it will result a random garbage value if length is 0. Let example by current code gen for MASK_LEN_FOLD_LEFT_PLUS with f64: # _148 = .MASK_LEN_FOLD_LEFT_PLUS (stmp__148.33_134, vect__70.32_138, { -1, ... }, loop_len_161, 0); vsetvli zero,a5,e64,m1,ta,ma vfmv.s.fv2,fa5 # insn 1 vfredosum.vsv1,v1,v2 # insn 2 vfmv.f.sfa5,v1 # insn 3 insn 1: - vfmv.s.f won't do anything if VL=0, which means v2 will contain garbage value. insn 2: - vfredosum.vs won't do anything if VL=0, and keep vd unchanged even TA. (v-spec say: `If vl=0, no operation is performed and the destination register is not updated.`) insn 3: - vfmv.f.s will move the value from v1 even VL=0, so this is safe. So how we fix that? we need two fix for that: 1. insn 1: need always execute with VL=1, so that we can guarantee it will always work as expect. 2. insn 2: Add new pattern to force `vd` use same reg as `vs1` (start value) for all reduction patterns, then we can guarantee vd[0] will contain the start value when vl=0 For 1, it's just a simple change to riscv_vector::expand_reduction, but for 2, we have to add _VL0_SAFE variant reduction to force `vd` use same reg as `vs1` (start value). Change since V3: - Rename _AV to _VL0_SAFE for readability. - Use non-VL0_SAFE version if VL is const or VLMAX. - Only force VL=1 for vfmv.s.f when VL is non-const and non-VLMAX. - Two more testcase. gcc/ChangeLog: PR target/118182 * config/riscv/autovec-opt.md (*widen_reduc_plus_scal_): Adjust argument for expand_reduction. (*widen_reduc_plus_scal_): Ditto. (*fold_left_widen_plus_): Ditto. (*mask_len_fold_left_widen_plus_): Ditto. (*cond_widen_reduc_plus_scal_): Ditto. (*cond_len_widen_reduc_plus_scal_): Ditto. (*cond_widen_reduc_plus_scal_): Ditto. * config/riscv/autovec.md (reduc_plus_scal_): Adjust argument for expand_reduction. (reduc_smax_scal_): Ditto. (reduc_umax_scal_): Ditto. (reduc_smin_scal_): Ditto. (reduc_umin_scal_): Ditto. (reduc_and_scal_): Ditto. (reduc_ior_scal_): Ditto. (reduc_xor_scal_): Ditto. (reduc_plus_scal_): Ditto. (reduc_smax_scal_): Ditto. (reduc_smin_scal_): Ditto. (reduc_fmax_scal_): Ditto. (reduc_fmin_scal_): Ditto. (fold_left_plus_): Ditto. (mask_len_fold_left_plus_): Ditto. * config/riscv/riscv-v.cc (expand_reduction): Add one more argument for reduction code for vl0-safe. * config/riscv/riscv-protos.h (expand_reduction): Ditto. * config/riscv/vector-iterators.md (unspec): Add _VL0_SAFE variant of reduction. (ANY_REDUC_VL0_SAFE): New. (ANY_WREDUC_VL0_SAFE): Ditto. (ANY_FREDUC_VL0_SAFE): Ditto. (ANY_FREDUC_SUM_VL0_SAFE): Ditto. (ANY_FWREDUC_SUM_VL0_SAFE): Ditto. (reduc_op): Add _VL0_SAFE variant of reduction. (order) Ditto. * config/riscv/vector.md (@pred_): New. gcc/testsuite/ChangeLog: PR target/118182 * gfortran.target/riscv/rvv/pr118182.f: New. * gcc.target/riscv/rvv/autovec/pr118182-1.c: New. * gcc.target/riscv/rvv/autovec/pr118182-2.c: New. Diff: --- gcc/config/riscv/autovec-opt.md| 10 +- gcc/config/riscv/autovec.md| 51 ++-- gcc/config/riscv/riscv-protos.h| 2 +- gcc/config/riscv/riscv-v.cc| 25 +++- gcc/config/riscv/vector-iterators.md | 59 + gcc/config/riscv/vector.md | 133 - .../gcc.target/riscv/rvv/autovec/pr118182-1.c | 28 + .../gcc.target/riscv/rvv/autovec/pr118182-2.c | 27 + gcc/testsuite/gfortran.target/riscv/rvv/pr118182.f | 63 ++ 9 files changed, 375 insertions(+), 23 deletions(-) diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index 645dc53d8680..267a37e5fbe6 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@
[gcc r14-11574] RISC-V: Bugfix for max_sew_overlap_and_next_ratio_valid_for_prev_sew_p[pr117483]
https://gcc.gnu.org/g:6cd78e383a98553482811f10318ff3da9a101d38 commit r14-11574-g6cd78e383a98553482811f10318ff3da9a101d38 Author: xuli Date: Tue Nov 12 02:31:28 2024 + RISC-V: Bugfix for max_sew_overlap_and_next_ratio_valid_for_prev_sew_p[pr117483] This patch fixs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117483 If prev and next satisfy the following rules, we should forbid the case (next.get_sew() < prev.get_sew() && (!next.get_ta() || !next.get_ma())) in the compatible function max_sew_overlap_and_next_ratio_valid_for_prev_sew_p. Otherwise, the tail elements of next will be polluted. DEF_SEW_LMUL_RULE (ge_sew, ratio_and_ge_sew, ratio_and_ge_sew, max_sew_overlap_and_next_ratio_valid_for_prev_sew_p, always_false, use_max_sew_and_lmul_with_next_ratio) Passed the rv64gcv full regression test. Signed-off-by: Li Xu PR target/117483 gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc: Fix bug. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr117483.c: New test. Diff: --- gcc/config/riscv/riscv-vsetvl.cc | 11 +-- gcc/testsuite/gcc.target/riscv/pr117483.c | 20 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 49702a5c6838..ffef579cd89c 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -1487,8 +1487,15 @@ private: max_sew_overlap_and_next_ratio_valid_for_prev_sew_p (const vsetvl_info &prev, const vsetvl_info &next) { -return next_ratio_valid_for_prev_sew_p (prev, next) - && max_sew_overlap_p (prev, next); +if (next_ratio_valid_for_prev_sew_p (prev, next) + && max_sew_overlap_p (prev, next)) + { + if (next.get_sew () < prev.get_sew () + && (!next.get_ta () || !next.get_ma ())) + return false; + return true; + } +return false; } inline bool sew_le_and_next_sew_le_prev_max_sew_and_ratio_eq_p (const vsetvl_info &prev, diff --git a/gcc/testsuite/gcc.target/riscv/pr117483.c b/gcc/testsuite/gcc.target/riscv/pr117483.c new file mode 100644 index ..3e00986d7e1e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr117483.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-fsigned-char -fno-strict-aliasing -fwrapv -march=rv64gcv_zvl256b -mabi=lp64d -O3" } */ + +char a, b, f; +short c, h; +int d[5]; +int e; +long *g; +short (*i)[4]; +int main() { + e = 906784; + char *j = &f; + short *k = &h; + for (short l = 0; l < 23; l += 740314495218734 - 29738) +for (unsigned char m = ~!g[l] - 255; m < 24; m += 3) { + a = k[m]; + b += j[1] ?: d[6]; + c ^= i[010][l]; +} +}
[gcc r14-11565] RISC-V: Fix subreg of VLS modes larger than a vector [PR116086].
https://gcc.gnu.org/g:e19a21f8edda3de1e460094e54239928bd289a31 commit r14-11565-ge19a21f8edda3de1e460094e54239928bd289a31 Author: Robin Dapp Date: Tue Aug 27 10:25:34 2024 +0200 RISC-V: Fix subreg of VLS modes larger than a vector [PR116086]. When the source mode is potentially larger than one vector (e.g. an LMUL2 mode for VLEN=128) we don't know which vector the subreg actually refers to. For zvl128b and LMUL=2 the subreg in (subreg:V2DI (reg:V4DI)) could actually be the a full (high) vector register of a two-register group (at VLEN=128) or the higher part of a single register (at VLEN>128). As the subreg is statically ambiguous we prevent such situations in can_change_mode_class. The culprit in PR116086 is _12 = BIT_FIELD_REF ; which can be expanded with a vector-vector extract (from V4DI to V2DI). This patch adds a VLS-mode vector-vector extract that handles "halving" cases like this one by sliding down the source vector, thus making sure the correct part is used. PR target/116086 gcc/ChangeLog: * config/riscv/autovec.md (vec_extract): Add vector-vector extract for VLS modes. * config/riscv/riscv.cc (riscv_can_change_mode_class): Forbid VLS modes larger than one vector. * config/riscv/vector-iterators.md: Add vector-vector extract iterators. gcc/testsuite/ChangeLog: * lib/target-supports.exp: Add effective target checks for zvl256b and zvl512b. * gcc.target/riscv/rvv/autovec/pr116086-2-run.c: New test. * gcc.target/riscv/rvv/autovec/pr116086-2.c: New test. * gcc.target/riscv/rvv/autovec/pr116086.c: New test. Diff: --- gcc/config/riscv/autovec.md| 35 gcc/config/riscv/riscv.cc | 11 ++ gcc/config/riscv/vector-iterators.md | 202 + .../gcc.target/riscv/rvv/autovec/pr116086-2-run.c | 6 + .../gcc.target/riscv/rvv/autovec/pr116086-2.c | 18 ++ .../gcc.target/riscv/rvv/autovec/pr116086.c| 76 gcc/testsuite/lib/target-supports.exp | 37 7 files changed, 385 insertions(+) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 9a3a4055a3a2..4b77e154ae70 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1463,6 +1463,41 @@ DONE; }) +;; - +;; [INT,FP] Extract a vector from a vector. +;; - +;; TODO: This can be extended to allow basically any extract mode. +;; For now this helps optimize VLS subregs like (subreg:V2DI (reg:V4DI) 16) +;; that would otherwise need to go via memory. + +(define_expand "vec_extract" + [(set (match_operand: 0 "nonimmediate_operand") + (vec_select: + (match_operand:VLS_HAS_HALF 1 "register_operand") + (parallel +[(match_operand 2 "immediate_operand")])))] + "TARGET_VECTOR" +{ + int sz = GET_MODE_NUNITS (mode).to_constant (); + int part = INTVAL (operands[2]); + + rtx start = GEN_INT (part * sz); + rtx tmp = operands[1]; + + if (part != 0) +{ + tmp = gen_reg_rtx (mode); + + rtx ops[] = {tmp, operands[1], start}; + riscv_vector::emit_vlmax_insn + (code_for_pred_slide (UNSPEC_VSLIDEDOWN, mode), +riscv_vector::BINARY_OP, ops); +} + + emit_move_insn (operands[0], gen_lowpart (mode, tmp)); + DONE; +}) + ;; - ;; [FP] Binary operations ;; - diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 3e3a29d30443..bce84fe92321 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -9886,6 +9886,17 @@ riscv_can_change_mode_class (machine_mode from, machine_mode to, if (reg_classes_intersect_p (V_REGS, rclass) && !ordered_p (GET_MODE_PRECISION (from), GET_MODE_PRECISION (to))) return false; + + /* Subregs of modes larger than one vector are ambiguous. + A V4DImode with rv64gcv_zvl128b could, for example, span two registers/one + register group of two at VLEN = 128 or one register at VLEN >= 256 and + we cannot, statically, determine which part of it to extract. + Therefore prevent that. */ + if (reg_classes_intersect_p (V_REGS, rclass) + && riscv_v_ext_vls_mode_p (from) + && !ordered_p (BITS_PER_RISCV_VECTOR, GET_MODE_PRECISION (from))) + return false; + return !reg_classes_intersect_p (FP_REGS, rclass); } diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index f6c0cb2fff65..8c908c1e1a56 100644 --- a/gcc/config/riscv/vector-iterato
[gcc r14-11569] [RISC-V][PR target/116240] Ensure object is a comparison before extracting arguments
https://gcc.gnu.org/g:86b0f63adb0815b40705051484dcb7ac640d commit r14-11569-g86b0f63adb0815b40705051484dcb7ac640d Author: Jeff Law Date: Thu Aug 8 07:42:26 2024 -0600 [RISC-V][PR target/116240] Ensure object is a comparison before extracting arguments This was supposed to go out the door yesterday, but I kept getting interrupted. The target bits for rtx costing can't assume the rtl they're given actually matches a target pattern. It's just kind of inherent in how the costing routines get called in various places. In this particular case we're trying to cost a conditional move: (set (dest) (if_then_else (cond) (true) (false)) On the RISC-V port the backend only allows actual conditionals for COND. So something like (eq (reg) (const_int 0)). In the costing code for if-then-else we did something like (XEXP (XEXP (cond, 0), 0))) Which fails miserably if COND is a terminal node like (reg) rather than (ne (reg) (const_int 0) So this patch tightens up the RTL scanning to ensure that we have a comparison before we start looking at the comparison's arguments. Run through my tester without incident, but I'll wait for the pre-commit tester to run through a cycle before pushing to the trunk. Jeff ps. We probably could support a naked REG for the condition and internally convert it to (ne (reg) (const_int 0)), but I don't think it likely happens with any regularity. PR target/116240 gcc/ * config/riscv/riscv.cc (riscv_rtx_costs): Ensure object is a comparison before looking at its arguments. gcc/testsuite * gcc.target/riscv/pr116240.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 6 -- gcc/testsuite/gcc.target/riscv/pr116240.c | 12 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 3bc6a5e41ab8..16ed2d91663e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3286,9 +3286,11 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1 || (GET_CODE (XEXP (x, 2)) == REG && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 2 - || (GET_CODE (XEXP (x, 1)) == REG + || (COMPARISON_P (XEXP (x, 0)) + && GET_CODE (XEXP (x, 1)) == REG && rtx_equal_p (XEXP (x, 1), XEXP (XEXP (x, 0), 0))) - || (GET_CODE (XEXP (x, 1)) == REG + || (COMPARISON_P (XEXP (x, 0)) + && GET_CODE (XEXP (x, 1)) == REG && rtx_equal_p (XEXP (x, 2), XEXP (XEXP (x, 0), 0) { *total = COSTS_N_INSNS (1); diff --git a/gcc/testsuite/gcc.target/riscv/pr116240.c b/gcc/testsuite/gcc.target/riscv/pr116240.c new file mode 100644 index ..7e3eaa2f5445 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr116240.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fwrapv -march=rv64imvxtheadcondmov_xventanacondops -mabi=lp64d" } */ + +int a, b; +void c() { + int e = a >= 2 ? b : a; + short d = e * 2; + if (d) +for (;;) + ; +} +
[gcc r14-11549] RISC-V: Move fortran testcase to gfortran.target
https://gcc.gnu.org/g:af3ebb414e2b88973d570e8878bc6262c0a1b3a9 commit r14-11549-gaf3ebb414e2b88973d570e8878bc6262c0a1b3a9 Author: Kito Cheng Date: Mon Dec 23 21:27:46 2024 +0800 RISC-V: Move fortran testcase to gfortran.target gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/fortran/pr111395.f90: Move this file to... * gfortran.target/riscv/rvv/pr111395.f90: ...here. * gcc.target/riscv/rvv/fortran/pr111566.f90: Move this file to... * gfortran.target/riscv/rvv/pr111566.f90: ...here. * gcc.target/riscv/rvv/rvv-fortran.exp: Move this file to... * gfortran.target/riscv/rvv/rvv.exp: ...here. Diff: --- .../riscv/rvv/fortran => gfortran.target/riscv/rvv}/pr111395.f90| 0 .../riscv/rvv/fortran => gfortran.target/riscv/rvv}/pr111566.f90| 0 .../riscv/rvv/rvv-fortran.exp => gfortran.target/riscv/rvv/rvv.exp} | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111395.f90 b/gcc/testsuite/gfortran.target/riscv/rvv/pr111395.f90 similarity index 100% rename from gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111395.f90 rename to gcc/testsuite/gfortran.target/riscv/rvv/pr111395.f90 diff --git a/gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111566.f90 b/gcc/testsuite/gfortran.target/riscv/rvv/pr111566.f90 similarity index 100% rename from gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111566.f90 rename to gcc/testsuite/gfortran.target/riscv/rvv/pr111566.f90 diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv-fortran.exp b/gcc/testsuite/gfortran.target/riscv/rvv/rvv.exp similarity index 93% rename from gcc/testsuite/gcc.target/riscv/rvv/rvv-fortran.exp rename to gcc/testsuite/gfortran.target/riscv/rvv/rvv.exp index a01c3d091700..d85f58336e14 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/rvv-fortran.exp +++ b/gcc/testsuite/gfortran.target/riscv/rvv/rvv.exp @@ -39,7 +39,7 @@ dg-init # Main loop. gfortran-dg-runtest [lsort \ - [glob -nocomplain $srcdir/$subdir/fortran/*.\[fF\]{,90,95,03,08} ] ] "" "" + [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" "" # All done. dg-finish
[gcc r14-11553] [PATCH] riscv: add mising masking in lrsc expander (PR118137)
https://gcc.gnu.org/g:46732eb89db2f5124f9433ef9460ff301ab7d737 commit r14-11553-g46732eb89db2f5124f9433ef9460ff301ab7d737 Author: Andreas Schwab Date: Tue Jan 7 12:23:37 2025 -0700 [PATCH] riscv: add mising masking in lrsc expander (PR118137) gcc: PR target/118137 * config/riscv/sync.md ("lrsc_atomic_exchange"): Apply mask to shifted value. gcc/testsuite: PR target/118137 * gcc.dg/atomic/pr118137.c: New. Diff: --- gcc/config/riscv/sync.md | 1 + gcc/testsuite/gcc.dg/atomic/pr118137.c | 29 + 2 files changed, 30 insertions(+) diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md index 6f0b5aae08dc..be31ddb97984 100644 --- a/gcc/config/riscv/sync.md +++ b/gcc/config/riscv/sync.md @@ -281,6 +281,7 @@ rtx shifted_value = gen_reg_rtx (SImode); riscv_lshift_subword (mode, value, shift, &shifted_value); + emit_move_insn (shifted_value, gen_rtx_AND (SImode, shifted_value, mask)); emit_insn (gen_subword_atomic_exchange_strong (old, aligned_mem, shifted_value, model, diff --git a/gcc/testsuite/gcc.dg/atomic/pr118137.c b/gcc/testsuite/gcc.dg/atomic/pr118137.c new file mode 100644 index ..7cdb2240aa36 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/pr118137.c @@ -0,0 +1,29 @@ +/* Test that subword atomic operations only affect the subword. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +void +foo (char *x) +{ + __sync_fetch_and_or (x, 0xff); +} + +void +bar (short *y) +{ + __atomic_fetch_or (y, 0x, 0); +} + + +int +main () +{ + char b[4] = {}; + foo(b); + + short h[2] = {}; + bar(h); + + if (b[1] || b[2] || b[3] || h[1]) +__builtin_abort(); +}
[gcc r14-11573] [committed] [RISC-V] Fix false-positive uninitialized variable
https://gcc.gnu.org/g:cdb987e977e03ba78a8a0e094967a5121e01f2ce commit r14-11573-gcdb987e977e03ba78a8a0e094967a5121e01f2ce Author: Jeff Law Date: Sun Jun 9 09:17:55 2024 -0600 [committed] [RISC-V] Fix false-positive uninitialized variable Andreas noted we were getting an uninit warning after the recent constant synthesis changes. Essentially there's no way for the uninit analysis code to know the first entry in the CODES array is a UNKNOWN which will set X before its first use. So trivial initialization with NULL_RTX is the obvious fix. Pushed to the trunk. gcc/ * config/riscv/riscv.cc (riscv_move_integer): Initialize "x". Diff: --- gcc/config/riscv/riscv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index f4a3b96745b6..fe9c8085551b 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2423,7 +2423,7 @@ riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value, struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS]; machine_mode mode; int i, num_ops; - rtx x; + rtx x = NULL_RTX; mode = GET_MODE (dest); /* We use the original mode for the riscv_build_integer call, because HImode
[gcc r14-11576] RISC-V: Fix vid const vector expander for non-npatterns size steps
https://gcc.gnu.org/g:6a66212916e70a9f27adf458b79c309c926dcf42 commit r14-11576-g6a66212916e70a9f27adf458b79c309c926dcf42 Author: Patrick O'Neill Date: Wed Aug 21 23:48:24 2024 -0700 RISC-V: Fix vid const vector expander for non-npatterns size steps Prior to this patch the expander would emit vectors like: { 0, 0, 5, 5, 10, 10, ...} as: { 0, 0, 2, 2, 4, 4, ...} This patch sets the step size to the requested value. gcc/ChangeLog: * config/riscv/riscv-v.cc (expand_const_vector): Fix STEP size in expander. Signed-off-by: Patrick O'Neill Diff: --- gcc/config/riscv/riscv-v.cc | 48 +++-- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index d95fb893c82a..fe51e2fe9b83 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1303,25 +1303,61 @@ expand_const_vector (rtx target, rtx src) /* Generate the variable-length vector following this rule: { a, a, a + step, a + step, a + step * 2, a + step * 2, ...} E.g. { 0, 0, 8, 8, 16, 16, ... } */ - /* We want to create a pattern where value[ix] = floor (ix / + + /* We want to create a pattern where value[idx] = floor (idx / NPATTERNS). As NPATTERNS is always a power of two we can -rewrite this as = ix & -NPATTERNS. */ +rewrite this as = idx & -NPATTERNS. */ /* Step 2: VID AND -NPATTERNS: { 0&-4, 1&-4, 2&-4, 3 &-4, 4 &-4, 5 &-4, 6 &-4, 7 &-4, ... } */ rtx imm = gen_int_mode (-builder.npatterns (), builder.inner_mode ()); - rtx tmp = gen_reg_rtx (builder.mode ()); - rtx and_ops[] = {tmp, vid, imm}; + rtx tmp1 = gen_reg_rtx (builder.mode ()); + rtx and_ops[] = {tmp1, vid, imm}; icode = code_for_pred_scalar (AND, builder.mode ()); emit_vlmax_insn (icode, BINARY_OP, and_ops); + + /* Step 3: Convert to step size 1. */ + rtx tmp2 = gen_reg_rtx (builder.mode ()); + /* log2 (npatterns) to get the shift amount to convert +Eg. { 0, 0, 0, 0, 4, 4, ... } +into { 0, 0, 0, 0, 1, 1, ... }. */ + HOST_WIDE_INT shift_amt = exact_log2 (builder.npatterns ()) ; + rtx shift = gen_int_mode (shift_amt, builder.inner_mode ()); + rtx shift_ops[] = {tmp2, tmp1, shift}; + icode = code_for_pred_scalar (ASHIFTRT, builder.mode ()); + emit_vlmax_insn (icode, BINARY_OP, shift_ops); + + /* Step 4: Multiply to step size n. */ + HOST_WIDE_INT step_size = + INTVAL (builder.elt (builder.npatterns ())) + - INTVAL (builder.elt (0)); + rtx tmp3 = gen_reg_rtx (builder.mode ()); + if (pow2p_hwi (step_size)) + { + /* Power of 2 can be handled with a left shift. */ + HOST_WIDE_INT shift = exact_log2 (step_size); + rtx shift_amount = gen_int_mode (shift, Pmode); + insn_code icode = code_for_pred_scalar (ASHIFT, mode); + rtx ops[] = {tmp3, tmp2, shift_amount}; + emit_vlmax_insn (icode, BINARY_OP, ops); + } + else + { + rtx mult_amt = gen_int_mode (step_size, builder.inner_mode ()); + insn_code icode = code_for_pred_scalar (MULT, builder.mode ()); + rtx ops[] = {tmp3, tmp2, mult_amt}; + emit_vlmax_insn (icode, BINARY_OP, ops); + } + + /* Step 5: Add starting value to all elements. */ HOST_WIDE_INT init_val = INTVAL (builder.elt (0)); if (init_val == 0) - emit_move_insn (target, tmp); + emit_move_insn (target, tmp3); else { rtx dup = gen_const_vector_dup (builder.mode (), init_val); - rtx add_ops[] = {target, tmp, dup}; + rtx add_ops[] = {target, tmp3, dup}; icode = code_for_pred (PLUS, builder.mode ()); emit_vlmax_insn (icode, BINARY_OP, add_ops); }
[gcc r15-9337] deref-before-check-pr113253.c: Fix bogus warnings on lp32
https://gcc.gnu.org/g:9ea6bdac02af61f360b5741bef978be02924252d commit r15-9337-g9ea6bdac02af61f360b5741bef978be02924252d Author: Jonathan Yong <10wa...@gmail.com> Date: Mon Apr 7 15:40:05 2025 + deref-before-check-pr113253.c: Fix bogus warnings on lp32 Warnings about pointer sizes cause the test to fail incorrectly. A dummy return value is also added to set_marker_internal for completeness to suppress a -Wreturn-type warning even though gcc does not issue it by default. Signed-off-by: Jonathan Yong <10wa...@gmail.com> gcc/testsuite/ChangeLog: PR analyzer/113253 * gcc.dg/analyzer/deref-before-check-pr113253.c: (ptrdiff_t): use stddef.h type. (uintptr_t): ditto. (EMACS_INT): ditto. (set_marker_internal): Add dummy 0 to suppress -Wreturn-type. Diff: --- gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr113253.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr113253.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr113253.c index d9015accd6ab..1890312cc1ab 100644 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr113253.c +++ b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr113253.c @@ -5,12 +5,12 @@ /* { dg-additional-options "-O2 -g" } */ -typedef long int ptrdiff_t; -typedef unsigned long int uintptr_t; -typedef long int EMACS_INT; +typedef __PTRDIFF_TYPE__ ptrdiff_t; +typedef __UINTPTR_TYPE__ uintptr_t; +typedef __PTRDIFF_TYPE__ EMACS_INT; enum { - EMACS_INT_WIDTH = 64, + EMACS_INT_WIDTH = sizeof(EMACS_INT) * 8, VALBITS = EMACS_INT_WIDTH - 3, }; typedef struct Lisp_X* Lisp_Word; @@ -151,4 +151,5 @@ set_marker_internal(Lisp_Object position, Lisp_Object buffer) struct buffer* b = live_buffer(buffer); if (NILP(position) || (MARKERP(position) && !XMARKER(position)->buffer) || !b) /* { dg-bogus "Wanalyzer-deref-before-check" } */ unchain_marker(); + return 0; }
[gcc r15-9333] d: Use CONSTRUCTOR_ZERO_PADDING_BITS in the D FE [PR117832]
https://gcc.gnu.org/g:3e3b665cc77791f2e088aeee124d8a9fb7f6eb41 commit r15-9333-g3e3b665cc77791f2e088aeee124d8a9fb7f6eb41 Author: Iain Buclaw Date: Wed Apr 9 14:49:14 2025 +0200 d: Use CONSTRUCTOR_ZERO_PADDING_BITS in the D FE [PR117832] Adds a new wrapper function for `build_constructor', and calls it instead to ensure that all CONSTRUCTOR nodes explicitly created by the front-end have CONSTRUCTOR_ZERO_PADDING_BITS set. Some places may not be necessary as it's guaranteed for there to be no padding in the type, such as D dynamic arrays. Other places this gets turned into a double-memset when optimizations are turned off, as the front-end already generates a memset call to zero out all padding on initializing a variable. The optimizer sees through this so will correctly clear all bits once, so this can be improved later as-needed. PR d/117832 gcc/d/ChangeLog: * d-tree.h (build_padded_constructor): New prototype. * d-codegen.cc (build_padded_constructor): New function. (d_array_value): Call it. (build_memset_call): Likewise. (build_struct_literal): Likewise. (underlying_complex_expr): Likewise. (build_array_from_val): Likewise. (build_array_from_exprs): Likewise. (d_build_call): Likewise. (get_frame_for_symbol): Likewise. * d-convert.cc (convert_for_rvalue): Likewise. (convert_for_assignment): Likewise. * decl.cc (class DeclVisitor): Likewise. * expr.cc (class ExprVisitor): Likewise. * modules.cc (layout_moduleinfo): Likewise. * typeinfo.cc (class TypeInfoVisitor): Likewise. Diff: --- gcc/d/d-codegen.cc | 32 +++- gcc/d/d-convert.cc | 4 ++-- gcc/d/d-tree.h | 1 + gcc/d/decl.cc | 2 +- gcc/d/expr.cc | 22 -- gcc/d/modules.cc | 4 ++-- gcc/d/typeinfo.cc | 8 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index ad71486e3ba8..1a7575aac22c 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -317,7 +317,7 @@ d_array_value (tree type, tree len, tree data) CONSTRUCTOR_APPEND_ELT (ce, len_field, len); CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data); - return build_constructor (type, ce); + return build_padded_constructor (type, ce); } /* Returns value representing the array length of expression EXP. @@ -898,7 +898,10 @@ build_memset_call (tree ptr, tree num) { tree cst = build_zero_cst (valtype); if (TREE_CODE (cst) == CONSTRUCTOR) - return build_memcpy_call (ptr, build_address (cst), num); + { + CONSTRUCTOR_ZERO_PADDING_BITS (cst) = 1; + return build_memcpy_call (ptr, build_address (cst), num); + } return modify_expr (build_deref (ptr), cst); } @@ -1205,7 +1208,7 @@ build_struct_literal (tree type, vec *init) { /* If the initializer was empty, use default zero initialization. */ if (vec_safe_is_empty (init)) -return build_constructor (type, NULL); +return build_padded_constructor (type, NULL); /* Struct literals can be seen for special enums representing `_Complex', make sure to reinterpret the literal as the correct type. */ @@ -1306,7 +1309,7 @@ build_struct_literal (tree type, vec *init) /* Ensure that we have consumed all values. */ gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type)); - tree ctor = build_constructor (type, ve); + tree ctor = build_padded_constructor (type, ve); if (constant_p) TREE_CONSTANT (ctor) = 1; @@ -1314,6 +1317,17 @@ build_struct_literal (tree type, vec *init) return ctor; } +/* Return a new zero padded CONSTRUCTOR node whose type is TYPE and values are + in the vec pointed to by VALS. */ + +tree +build_padded_constructor (tree type, vec *vals) +{ + tree ctor = build_constructor (type, vals); + CONSTRUCTOR_ZERO_PADDING_BITS (ctor) = 1; + return ctor; +} + /* Given the TYPE of an anonymous field inside T, return the FIELD_DECL for the field. If not found return NULL_TREE. Because anonymous types can nest, we must also search all @@ -1647,7 +1661,7 @@ underlying_complex_expr (tree type, tree expr) real_part (expr)); CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)), imaginary_part (expr)); - return build_constructor (type, ve); + return build_padded_constructor (type, ve); } /* Replace type in the reinterpret cast with a cast to the record type. */ @@ -1852,7 +1866,7 @@ build_array_from_val (Type *type, tree val) for (size_t i = 0; i < dims; i++) CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val); - return build_constructor (build_ctype (type), elms); + return build_padded_constructor (build_ctype (type), elms); } /*
[gcc r15-9335] riscv: Fix r15-9270 fallout on RISC-V
https://gcc.gnu.org/g:39deb26060ecf9c055489e96fa1d9c1d641ecefe commit r15-9335-g39deb26060ecf9c055489e96fa1d9c1d641ecefe Author: Jakub Jelinek Date: Wed Apr 9 15:43:48 2025 +0200 riscv: Fix r15-9270 fallout on RISC-V On Wed, Apr 09, 2025 at 02:38:01PM +0200, Mark Wielaard wrote: > Unfortunately this seems to have broken the riscv bootstrap: > https://builder.sourceware.org/buildbot/#/builders/337/builds/105 > > ../../gcc/gcc/config/riscv/riscv-vector-builtins.cc:4730:10: error: enumeration value ‘TCTX_OMP_MAP’ not handled in switch [-Werror=switch] > 4730 | switch (context) > | ^ > ../../gcc/gcc/config/riscv/riscv-vector-builtins.cc:4730:10: error: enumeration value ‘TCTX_OMP_MAP_IMP_REF’ not handled in switch [-Werror=switch] > ../../gcc/gcc/config/riscv/riscv-vector-builtins.cc:4730:10: error: enumeration value ‘TCTX_OMP_PRIVATE’ not handled in switch [-Werror=switch] > ../../gcc/gcc/config/riscv/riscv-vector-builtins.cc:4730:10: error: enumeration value ‘TCTX_OMP_FIRSTPRIVATE’ not handled in switch [-Werror=switch] > ../../gcc/gcc/config/riscv/riscv-vector-builtins.cc:4730:10: error: enumeration value ‘TCTX_OMP_DEVICE_ADDR’ not handled in switch [-Werror=switch] > cc1plus: all warnings being treated as errors Indeed, riscv-vector-builtins.cc IMHO needs pretty much the same changes as aarch64, just with s/SVE/RVV/g. I've also left out default: break; so that it is caught next time somebody adds further enumerators. 2025-04-09 Jakub Jelinek * config/riscv/riscv-vector-builtins.cc (verify_type_context): Diagnose RVV types for a given OpenMP context. Diff: --- gcc/config/riscv/riscv-vector-builtins.cc | 34 ++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index d2fe849c693e..61dcdabbb403 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -4724,7 +4724,11 @@ bool verify_type_context (location_t loc, type_context_kind context, const_tree type, bool silent_p) { - if (!sizeless_type_p (type)) + const_tree tmp = type; + if (omp_type_context (context) && POINTER_TYPE_P (type)) +tmp = strip_pointer_types (tmp); + + if (!sizeless_type_p (tmp)) return true; switch (context) @@ -4796,6 +4800,34 @@ verify_type_context (location_t loc, type_context_kind context, const_tree type, error_at (loc, "capture by copy of RVV type %qT", type); return false; + +case TCTX_OMP_MAP: + if (!silent_p) + error_at (loc, "RVV type %qT not allowed in % clause", type); + return false; + +case TCTX_OMP_MAP_IMP_REF: + if (!silent_p) + error ("cannot reference %qT object types in % region", type); + return false; + +case TCTX_OMP_PRIVATE: + if (!silent_p) + error_at (loc, "RVV type %qT not allowed in" + " % % clause", type); + return false; + +case TCTX_OMP_FIRSTPRIVATE: + if (!silent_p) + error_at (loc, "RVV type %qT not allowed in" + " % % clause", type); + return false; + +case TCTX_OMP_DEVICE_ADDR: + if (!silent_p) + error_at (loc, "RVV type %qT not allowed in" + " % device clauses", type); + return false; } gcc_unreachable ();
[gcc r14-11552] RISC-V: Disallow negative step for interleaving [PR117682]
https://gcc.gnu.org/g:08e381e8af3ec9beaa887824c41d4551b54e5063 commit r14-11552-g08e381e8af3ec9beaa887824c41d4551b54e5063 Author: Robin Dapp Date: Mon Jan 13 17:09:35 2025 -0700 RISC-V: Disallow negative step for interleaving [PR117682] Hi, in PR117682 we build an interleaving pattern { 1, 201, 209, 25, 161, 105, 113, 185, 65, 9, 17, 89, 225, 169, 177, 249, 129, 73, 81, 153, 33, 233, 241, 57, 193, 137, 145, 217, 97, 41, 49, 121 }; with negative step expecting wraparound semantics due to -fwrapv. For building interleaved patterns we have an optimization that does e.g. {1, 209, ...} = { 1, 0, 209, 0, ...} and {201, 25, ...} >> 8 = { 0, 201, 0, 25, ...} and IORs those. The optimization only works if the lowpart bits are zero. When overflowing e.g. with a negative step we cannot guarantee this. This patch makes us fall back to the generic merge handling for negative steps. I'm not 100% certain we're good even for positive steps. If the step or the vector length is large enough we'd still overflow and have non-zero lower bits. I haven't seen this happen during my testing, though and the patch doesn't make things worse, so... Regtested on rv64gcv_zvl512b. Let's see what the CI says. Regards Robin PR target/117682 gcc/ChangeLog: * config/riscv/riscv-v.cc (expand_const_vector): Fall back to merging if either step is negative. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr117682.c: New test. Diff: --- gcc/config/riscv/riscv-v.cc | 11 +-- gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117682.c | 15 +++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 1734761453d5..d40a34a6ffbc 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1408,13 +1408,20 @@ expand_const_vector (rtx target, rtx src) can be interpreted into: - EEW = 32, { 2, 4, ... } */ + EEW = 32, { 2, 4, ... }. + +This only works as long as the larger type does not overflow +as we can't guarantee a zero value for each second element +of the sequence with smaller EEW. +??? For now we assume that no overflow happens with positive +steps and forbid negative steps altogether. */ unsigned int new_smode_bitsize = builder.inner_bits_size () * 2; scalar_int_mode new_smode; machine_mode new_mode; poly_uint64 new_nunits = exact_div (GET_MODE_NUNITS (builder.mode ()), 2); - if (int_mode_for_size (new_smode_bitsize, 0).exists (&new_smode) + if (known_ge (step1, 0) && known_ge (step2, 0) + && int_mode_for_size (new_smode_bitsize, 0).exists (&new_smode) && get_vector_mode (new_smode, new_nunits).exists (&new_mode)) { rtx tmp = gen_reg_rtx (new_mode); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117682.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117682.c new file mode 100644 index ..bbbcfcce6262 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117682.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-require-effective-target riscv_v } */ +/* { dg-require-effective-target rvv_zvl256b_ok } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=zvl -fwrapv" } */ + +signed char a = 9; +int main() { + for (char e = 0; e < 20; e++) +for (char f = 0; f < 7; f++) + a *= 57; + + if (a != 41) +__builtin_abort (); +} +
[gcc r14-11554] [RISC-V][PR target/106544] Avoid ICEs due to bogus asms
https://gcc.gnu.org/g:6547906bdbdb3feb0d3bd96e09ceffcbc489349f commit r14-11554-g6547906bdbdb3feb0d3bd96e09ceffcbc489349f Author: Jeff Law Date: Mon Dec 30 13:51:55 2024 -0700 [RISC-V][PR target/106544] Avoid ICEs due to bogus asms This is a fix for a bug Andrew P filed a while back where essentially a poorly crafted asm statement could trigger a ICE during assembly output. Various cases will use INTVAL (op) without verifying the operand is a CONST_INT node first. The usual way to handle this is via output_operand_lossage, which this patch implements. I focused primarily on the CONST_INT cases, there could well be other problems in this space, if so they should get distinct bugs with testcases. Tested in my tester on rv32 and rv64. Waiting for pre-commit testing before moving forward. PR target/106544 gcc/ * config/riscv/riscv.cc (riscv_print_operand): Issue an error for invalid operands rather than invalidly accessing INTVAL of an object that is not a CONST_INT. Fix one error string for 'N'. gcc/testsuite * gcc.target/riscv/pr106544.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 151 +++--- gcc/testsuite/gcc.target/riscv/pr106544.c | 6 ++ 2 files changed, 104 insertions(+), 53 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index a6a3b2745c53..584c3d52c5e7 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6269,41 +6269,74 @@ riscv_print_operand (FILE *file, rtx op, int letter) fputs (GET_RTX_NAME (reverse_condition (code)), file); break; -case 'A': { - const enum memmodel model = memmodel_base (INTVAL (op)); - if (riscv_memmodel_needs_amo_acquire (model) - && riscv_memmodel_needs_amo_release (model)) - fputs (".aqrl", file); - else if (riscv_memmodel_needs_amo_acquire (model)) - fputs (".aq", file); - else if (riscv_memmodel_needs_amo_release (model)) - fputs (".rl", file); +case 'A': + if (!CONST_INT_P (op)) + output_operand_lossage ("invalid operand for '%%%c'", letter); + else + { + const enum memmodel model = memmodel_base (INTVAL (op)); + if (riscv_memmodel_needs_amo_acquire (model) + && riscv_memmodel_needs_amo_release (model)) + fputs (".aqrl", file); + else if (riscv_memmodel_needs_amo_acquire (model)) + fputs (".aq", file); + else if (riscv_memmodel_needs_amo_release (model)) + fputs (".rl", file); + } break; -} -case 'I': { - const enum memmodel model = memmodel_base (INTVAL (op)); - if (TARGET_ZTSO && model != MEMMODEL_SEQ_CST) - /* LR ops only have an annotation for SEQ_CST in the Ztso mapping. */ - break; - else if (model == MEMMODEL_SEQ_CST) - fputs (".aqrl", file); - else if (riscv_memmodel_needs_amo_acquire (model)) - fputs (".aq", file); +case 'I': + if (!CONST_INT_P (op)) + output_operand_lossage ("invalid operand for '%%%c'", letter); + else + { + const enum memmodel model = memmodel_base (INTVAL (op)); + if (TARGET_ZTSO && model != MEMMODEL_SEQ_CST) + /* LR ops only have an annotation for SEQ_CST in the Ztso mapping. */ + break; + else if (model == MEMMODEL_SEQ_CST) + fputs (".aqrl", file); + else if (riscv_memmodel_needs_amo_acquire (model)) + fputs (".aq", file); + } break; -} -case 'J': { - const enum memmodel model = memmodel_base (INTVAL (op)); - if (TARGET_ZTSO && model == MEMMODEL_SEQ_CST) - /* SC ops only have an annotation for SEQ_CST in the Ztso mapping. */ - fputs (".rl", file); - else if (TARGET_ZTSO) - break; - else if (riscv_memmodel_needs_amo_release (model)) - fputs (".rl", file); +case 'J': + if (!CONST_INT_P (op)) + output_operand_lossage ("invalid operand for '%%%c'", letter); + else + { + const enum memmodel model = memmodel_base (INTVAL (op)); + if (TARGET_ZTSO && model == MEMMODEL_SEQ_CST) + /* SC ops only have an annotation for SEQ_CST in the Ztso mapping. */ + fputs (".rl", file); + else if (TARGET_ZTSO) + break; + else if (riscv_memmodel_needs_amo_release (model)) + fputs (".rl", file); + } break; -} + +case 'L': + { + const char *ntl_hint = NULL; + switch (INTVAL (op)) + { + case 0: + ntl_hint = "ntl.all"; + break; + case 1: + ntl_hint = "ntl.pall"; + break; + case 2: + ntl_hint = "ntl.p1"; + break; + } + + if (ntl_hint) + asm_fprintf (file, "%s\n\t", ntl_hint);
[gcc r14-11559] [PATCH 1/2] RISC-V: Fix the outer_code when calculating the cost of SET expression.
https://gcc.gnu.org/g:80ab25142565e83477af7c3e57f0a4dcf51b9659 commit r14-11559-g80ab25142565e83477af7c3e57f0a4dcf51b9659 Author: Xianmiao Qu Date: Wed Sep 18 07:35:12 2024 -0600 [PATCH 1/2] RISC-V: Fix the outer_code when calculating the cost of SET expression. I think it is a typo. When calculating the 'SET_SRC (x)' cost, outer_code should be set to SET. gcc/ * config/riscv/riscv.cc (riscv_rtx_costs): Fix the outer_code when calculating the cost of SET expression. Diff: --- gcc/config/riscv/riscv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 584c3d52c5e7..a58c33a0aa28 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3209,7 +3209,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN if (outer_code == INSN && register_operand (SET_DEST (x), GET_MODE (SET_DEST (x { - riscv_rtx_costs (SET_SRC (x), mode, outer_code, opno, total, speed); + riscv_rtx_costs (SET_SRC (x), mode, SET, opno, total, speed); return true; }
[gcc r15-9338] testsuite/x86: Correctly escape asterisk in scan-assembler
https://gcc.gnu.org/g:3aca82bc3a3ab62f96bf6ebe9e38ccc78cc8dca8 commit r15-9338-g3aca82bc3a3ab62f96bf6ebe9e38ccc78cc8dca8 Author: Uros Bizjak Date: Wed Apr 9 16:21:18 2025 +0200 testsuite/x86: Correctly escape asterisk in scan-assembler Asterisk in []* regexp applies to bracket expression. When asterisk is a part of the word, then it needs to be escaped with \\. Also use []+ instead of []* to match elements in bracket expression one or more times. gcc/testsuite/ChangeLog: * gcc.target/i386/pr67215-1.c: Correctly escape asterisk in scan-assembler dirctive. * gcc.target/i386/pr67215-2.c: Ditto. Diff: --- gcc/testsuite/gcc.target/i386/pr67215-1.c | 10 +- gcc/testsuite/gcc.target/i386/pr67215-2.c | 10 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcc/testsuite/gcc.target/i386/pr67215-1.c b/gcc/testsuite/gcc.target/i386/pr67215-1.c index fd37f8e63db9..ab69550db7d5 100644 --- a/gcc/testsuite/gcc.target/i386/pr67215-1.c +++ b/gcc/testsuite/gcc.target/i386/pr67215-1.c @@ -13,8 +13,8 @@ foo (void) arr[i] = bar (128); } -/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT\\(" { target ia32 } } } */ -/* { dg-final { scan-assembler-not "mov(l|q)\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-not "movl\[ \t\]*.bar@GOT\\(" { target ia32 } } } */ -/* { dg-final { scan-assembler-not "call\[ \t\]*.bar@PLT" } } */ +/* { dg-final { scan-assembler "call\[ \t\]+\\*bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call\[ \t\]+\\*bar@GOT\\(" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "mov(l|q)\[ \t\]+bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "movl\[ \t\]+bar@GOT\\(" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]+\\*bar@PLT" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr67215-2.c b/gcc/testsuite/gcc.target/i386/pr67215-2.c index ebf2919078c4..9fd7469e2d09 100644 --- a/gcc/testsuite/gcc.target/i386/pr67215-2.c +++ b/gcc/testsuite/gcc.target/i386/pr67215-2.c @@ -13,8 +13,8 @@ foo (void) arr[i] = bar (128); } -/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT\\(" { target ia32 } } } */ -/* { dg-final { scan-assembler-not "mov(l|q)\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-not "movl\[ \t\]*.bar@GOT\\(" { target ia32 } } } */ -/* { dg-final { scan-assembler-not "call\[ \t\]*.bar@PLT" } } */ +/* { dg-final { scan-assembler "call\[ \t\]+\\*bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call\[ \t\]+\\*bar@GOT\\(" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "mov(l|q)\[ \t\]+bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "movl\[ \t\]+bar@GOT\\(" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]+\\*bar@PLT" } } */
[gcc r14-11560] [PATCH] RISC-V: Fix th.extu operands exceeding range on rv32.
https://gcc.gnu.org/g:5b3558944a7a03071744585ee8c55f30d51b5653 commit r14-11560-g5b3558944a7a03071744585ee8c55f30d51b5653 Author: Xianmiao Qu Date: Wed Sep 18 07:28:44 2024 -0600 [PATCH] RISC-V: Fix th.extu operands exceeding range on rv32. The Combine Pass may generate zero_extract instructions that are out of range. Drawing from other architectures like AArch64, we should impose restrictions on the "*th_extu4" pattern. gcc/ * config/riscv/thead.md (*th_extu4): Fix th.extu operands exceeding range on rv32. gcc/testsuite/ * gcc.target/riscv/xtheadbb-extu-4.c: New. Diff: --- gcc/config/riscv/thead.md| 4 +++- gcc/testsuite/gcc.target/riscv/xtheadbb-extu-4.c | 17 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 5c7d4beb1b66..245386a1 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -85,7 +85,9 @@ (zero_extract:GPR (match_operand:GPR 1 "register_operand" "r") (match_operand 2 "const_int_operand") (match_operand 3 "const_int_operand")))] - "TARGET_XTHEADBB" + "TARGET_XTHEADBB + && (UINTVAL (operands[2]) + UINTVAL (operands[3]) + <= GET_MODE_BITSIZE (mode))" { operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); return "th.extu\t%0,%1,%2,%3"; diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-4.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-4.c new file mode 100644 index ..41d3fc1f5b40 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-4.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { rv32 } } } */ +/* { dg-options "-march=rv32gc_xtheadbb" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Og" "-Oz" } } */ + +struct c { + int f : 25; +} d; + +int b; +extern unsigned int e[]; + +void g() +{ + d.f = e[2] >> (b << ~4194303 + 4194332) - 58096371; +} + +/* { dg-final { scan-assembler-not {th.extu\t[ax][0-9]+,[ax][0-9]+,37,13} } } */ \ No newline at end of file
[gcc r14-11557] RISC-V: Ensure vtype for full-register moves [PR117544].
https://gcc.gnu.org/g:164aededa828c5db6195a10f9d0f6a500f2cbef9 commit r14-11557-g164aededa828c5db6195a10f9d0f6a500f2cbef9 Author: Robin Dapp Date: Thu Nov 21 14:49:53 2024 +0100 RISC-V: Ensure vtype for full-register moves [PR117544]. As discussed in PR117544 the VTYPE register is not preserved across function calls. Even though vmv1r-like instructions operate independently of the actual vtype they still require a valid vtype. As we cannot guarantee that the vtype is valid we must make sure to emit a vsetvl between a function call and a vmv1r.v. This patch makes the necessary changes by splitting the full-reg-move insns into patterns that use the vtype register and adding vmov to the types of instructions requiring a vset. PR target/117544 gcc/ChangeLog: * config/riscv/vector.md (*mov_whole): Split. (*mov_fract): Ditto. (*mov): Ditto. (*mov_vls): Ditto. (*mov_reg_whole_vtype): New pattern with vtype use. (*mov_fract_vtype): Ditto. (*mov_vtype): Ditto. (*mov_vls_vtype): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/abi-call-args-4.c: Expect vsetvl. * gcc.target/riscv/rvv/base/pr117544.c: New test. Diff: --- gcc/config/riscv/vector.md | 91 -- .../gcc.target/riscv/rvv/base/abi-call-args-4.c| 1 + gcc/testsuite/gcc.target/riscv/rvv/base/pr117544.c | 14 3 files changed, 99 insertions(+), 7 deletions(-) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 0f5dfc8dc6c3..adf9633e2cc5 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -42,7 +42,8 @@ (cond [(eq_attr "type" "vlde,vste,vldm,vstm,vlds,vsts,\ vldux,vldox,vstux,vstox,vldff,\ vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,viminmax,\ - vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge,vimov,\ + vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge, + vmov,vimov,\ vsalu,vaalu,vsmul,vsshift,vnclip,\ vfalu,vfwalu,vfmul,vfdiv,vfwmul,vfmuladd,vfwmuladd,vfsqrt,vfrecp,\ vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,\ @@ -1135,21 +1136,58 @@ ;; which is not the pattern we want. ;; According the facts above, we make "*mov_whole" includes load/store/move for whole ;; vector modes according to '-march' and "*mov_fract" only include fractional vector modes. -(define_insn "*mov_whole" +(define_insn_and_split "*mov_whole" [(set (match_operand:V_WHOLE 0 "reg_or_mem_operand" "=vr, m,vr") (match_operand:V_WHOLE 1 "reg_or_mem_operand" " m,vr,vr"))] "TARGET_VECTOR && !TARGET_XTHEADVECTOR" "@ vl%m1re.v\t%0,%1 vs%m1r.v\t%1,%0 - vmv%m1r.v\t%0,%1" + #" + "&& !memory_operand (operands[0], mode) + && !memory_operand (operands[1], mode)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (use (reg:SI VTYPE_REGNUM))])] + "" [(set_attr "type" "vldr,vstr,vmov") (set_attr "mode" "")]) -(define_insn "*mov_fract" +;; Full-register moves like vmv1r.v require a valid vtype. +;; The ABI does not guarantee that the vtype is valid after a function +;; call so we need to make it dependent on the vtype and have +;; the vsetvl pass insert a vsetvl if necessary. +;; To facilitate optimization we keep the reg-reg move patterns "regular" +;; until split time and only then switch to a pattern like below that +;; uses the vtype register. +;; As the use of these patterns is limited (in the general context) +;; there is no need for helper functions and we can just create the RTX +;; directly. +(define_insn "*mov_reg_whole_vtype" + [(set (match_operand:V_WHOLE 0 "reg_or_mem_operand" "=vr") + (match_operand:V_WHOLE 1 "reg_or_mem_operand" " vr")) + (use (reg:SI VTYPE_REGNUM))] + "TARGET_VECTOR && !TARGET_XTHEADVECTOR" + "vmv%m1r.v\t%0,%1" + [(set_attr "type" "vmov") + (set_attr "mode" "")]) + +(define_insn_and_split "*mov_fract" [(set (match_operand:V_FRACT 0 "register_operand" "=vr") (match_operand:V_FRACT 1 "register_operand" " vr"))] "TARGET_VECTOR" + "#" + "&& 1" + [(parallel [(set (match_dup 0) (match_dup 1)) + (use (reg:SI VTYPE_REGNUM))])] + "" + [(set_attr "type" "vmov") + (set_attr "mode" "")]) + +(define_insn "*mov_fract_vtype" + [(set (match_operand:V_FRACT 0 "register_operand" "=vr") + (match_operand:V_FRACT 1 "register_operand" " vr")) + (use (reg:SI VTYPE_REGNUM))] + "TARGET_VECTOR" "vmv1r.v\t%0,%1" [(set_attr "type" "vmov") (set_attr "mode" "")]) @@ -1170,10 +1208,23 @@ DONE; }) -(define_insn "*mov" +(define_insn_and_split "*mov" [(set (match_operand:VB 0 "register_operand" "=vr") (match_operand:VB 1 "register_operand" " vr"))]
[gcc r14-11558] [PATCH v3] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on
https://gcc.gnu.org/g:37d13153635b78013a8d27d2be9da99d0f2a88a7 commit r14-11558-g37d13153635b78013a8d27d2be9da99d0f2a88a7 Author: Jin Ma Date: Wed Sep 18 08:56:23 2024 -0600 [PATCH v3] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32. gcc/ChangeLog: * config/riscv/riscv.md: Change "truncate" to unspec for the Zfa extension on rv32. gcc/testsuite/ChangeLog: * gcc.target/riscv/zfa-fmovh-fmovp-bug.c: New test. Diff: --- gcc/config/riscv/riscv.md| 16 +--- gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c | 9 + 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 455715ab2f72..c4380a06693e 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -56,6 +56,8 @@ UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET UNSPEC_COPYSIGN + UNSPEC_FMV_X_W + UNSPEC_FMVH_X_D UNSPEC_RINT UNSPEC_ROUND UNSPEC_FLOOR @@ -2343,8 +2345,9 @@ (define_insn "movsidf2_low_rv32" [(set (match_operand:SI 0 "register_operand" "= r") - (truncate:SI - (match_operand:DF 1 "register_operand" "zmvf")))] + (unspec:SI + [(match_operand:DF 1 "register_operand" "zmvf")] + UNSPEC_FMV_X_W))] "TARGET_HARD_FLOAT && !TARGET_64BIT && TARGET_ZFA" "fmv.x.w\t%0,%1" [(set_attr "move_type" "fmove") @@ -2353,11 +2356,10 @@ (define_insn "movsidf2_high_rv32" - [(set (match_operand:SI 0 "register_operand""= r") - (truncate:SI -(lshiftrt:DF -(match_operand:DF 1 "register_operand" "zmvf") -(const_int 32] + [(set (match_operand:SI 0 "register_operand" "= r") + (unspec:SI + [(match_operand:DF 1 "register_operand" "zmvf")] + UNSPEC_FMVH_X_D))] "TARGET_HARD_FLOAT && !TARGET_64BIT && TARGET_ZFA" "fmvh.x.d\t%0,%1" [(set_attr "move_type" "fmove") diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c new file mode 100644 index ..e00047b09e3a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c @@ -0,0 +1,9 @@ +/* Test that we do not have ice when compile */ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zfa -mabi=ilp32d -O2 -g" } */ + +unsigned int +foo (double a) { + unsigned int tt = *(unsigned long long *)&a & 0x; + return tt; +}
[gcc r14-11555] RISC-V: Fix compress shuffle pattern [PR117383].
https://gcc.gnu.org/g:ca6adeda373fc97ff57a79bc1a078f90776330cd commit r14-11555-gca6adeda373fc97ff57a79bc1a078f90776330cd Author: Robin Dapp Date: Wed Dec 11 20:48:30 2024 +0100 RISC-V: Fix compress shuffle pattern [PR117383]. This patch makes vcompress use the tail-undisturbed policy by default and also uses the proper VL. PR target/117383 gcc/ChangeLog: * config/riscv/riscv-protos.h (enum insn_type): Use TU policy. * config/riscv/riscv-v.cc (shuffle_compress_patterns): Set VL. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/binop/vcompress-avlprop-1.c: Expect tu. * gcc.target/riscv/rvv/autovec/pr117383.c: New test. Diff: --- gcc/config/riscv/riscv-protos.h| 4 +- gcc/config/riscv/riscv-v.cc| 3 +- .../riscv/rvv/autovec/binop/vcompress-avlprop-1.c | 2 +- .../gcc.target/riscv/rvv/autovec/pr117383.c| 48 ++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 4f0f744a354e..99277e4e7c24 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -484,9 +484,9 @@ enum insn_type : unsigned int /* For vcompress.vm */ COMPRESS_OP = __NORMAL_OP_TA2 | BINARY_OP_P, - /* has merge operand but use ta. */ + /* has merge operand but use tu. */ COMPRESS_OP_MERGE - = HAS_DEST_P | HAS_MERGE_P | TDEFAULT_POLICY_P | BINARY_OP_P, + = HAS_DEST_P | HAS_MERGE_P | TU_POLICY_P | BINARY_OP_P, /* For vslideup.up has merge operand but use ta. */ SLIDEUP_OP_MERGE = HAS_DEST_P | HAS_MASK_P | USE_ALL_TRUES_MASK_P diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index d40a34a6ffbc..33df1518d4a9 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -3385,7 +3385,8 @@ shuffle_compress_patterns (struct expand_vec_perm_d *d) insn_code icode = code_for_pred_compress (vmode); rtx ops[] = {d->target, merge, d->op0, mask}; - emit_vlmax_insn (icode, COMPRESS_OP_MERGE, ops); + emit_nonvlmax_insn (icode, COMPRESS_OP_MERGE, ops, + gen_int_mode (vlen, Pmode)); return true; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vcompress-avlprop-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vcompress-avlprop-1.c index 32d81beb881f..87a29a7da175 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vcompress-avlprop-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vcompress-avlprop-1.c @@ -10,7 +10,7 @@ struct s sss[MAX]; /* ** build_linked_list: ** ... -** vsetivli\s+zero,\s*8,\s*e64,\s*m1,\s*ta,\s*ma +** vsetivli\s+zero,\s*8,\s*e64,\s*m1,\s*tu,\s*ma ** ... ** vcompress\.vm\s+v[0-9]+,\s*v[0-9]+,\s*v0 ** ... diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117383.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117383.c new file mode 100644 index ..c01612f29028 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117383.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-require-effective-target "riscv_v_ok" } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-additional-options "-std=c99 -mrvv-vector-bits=zvl" } */ + +typedef signed char int8_t; +typedef int8_t vnx64i __attribute__ ((vector_size (64))); + +#define MASK_64 \ + 1, 2, 3, 5, 7, 9, 10, 11, 12, 14, 15, 17, 19, 21, 22, 23, 26, 28, 30, 31, \ +37, 38, 41, 46, 47, 53, 54, 55, 60, 61, 62, 63, 76, 77, 78, 79, 80, 81, \ +82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, \ +100, 101, 102, 103, 104, 105, 106, 107 + +void __attribute__ ((noipa)) +test_1 (int8_t *x, int8_t *y, int8_t *out) +{ + vnx64i v1 = *(vnx64i *) x; + vnx64i v2 = *(vnx64i *) y; + vnx64i v3 = __builtin_shufflevector (v1, v2, MASK_64); + *(vnx64i *) out = v3; +} + +int +main (void) +{ + int8_t x[64]; + int8_t y[64]; + int8_t out[64]; + + for (int i = 0; i < 64; i++) +{ + x[i] = -i; + y[i] = i; +} + + test_1 (x, y, out); + + int mask[] = {MASK_64}; +#pragma GCC novector + for (int i = 0; i < 64; i++) +{ + int idx = mask[i] < 64 ? mask[i] : mask[i] - 64; + int ref = mask[i] < 64 ? x[idx] : y[idx]; + if (ref != out[i]) +__builtin_abort (); +} +}
[gcc r14-11566] RISC-V: Add missing mode_idx for vrol and vror
https://gcc.gnu.org/g:d2f5d28415fe28881b4b8cadf6df85cf94ded233 commit r14-11566-gd2f5d28415fe28881b4b8cadf6df85cf94ded233 Author: Kito Cheng Date: Tue Aug 27 21:27:02 2024 +0800 RISC-V: Add missing mode_idx for vrol and vror We add pattern for vector rotate, but seems like we forgot adding mode_idx which used in AVL propgation (riscv-avlprop.cc). gcc/ChangeLog: * config/riscv/vector.md (mode_idx): Add vrol and vror. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/rotr.c: New. Diff: --- gcc/config/riscv/vector.md| 2 +- gcc/testsuite/gcc.target/riscv/rvv/autovec/rotr.c | 13 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 0b2be136236f..d0cc61bb3be6 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -744,7 +744,7 @@ vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,\ vfcvtitof,vfncvtitof,vfncvtftoi,vfncvtftof,vmalu,vmiota,vmidx,\ vimovxv,vfmovfv,vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,\ - vgather,vcompress,vmov,vnclip,vnshift") + vgather,vcompress,vmov,vnclip,vnshift,vandn,vcpop,vclz,vctz") (const_int 0) (eq_attr "type" "vimovvx,vfmovvf") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/rotr.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/rotr.c new file mode 100644 index ..055b28d1e787 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/rotr.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvbb -mabi=lp64d -fno-vect-cost-model -mrvv-vector-bits=zvl" } */ + +typedef int a; +void *b; +a c; +void d() { + a e = c, f =0; + short *g = b; + for (; f < e; f++) +*(g + f) = (255 & (*(g + f) >> 8)) | *(g + f) << 8; +} +
[gcc r15-9332] Revert "RISC-V: Refine the testcases for cond_widen_complicate-3"
https://gcc.gnu.org/g:24d1832e0d6edce4f6f717135fcec65d6939e199 commit r15-9332-g24d1832e0d6edce4f6f717135fcec65d6939e199 Author: Pan Li Date: Wed Apr 9 19:08:21 2025 +0800 Revert "RISC-V: Refine the testcases for cond_widen_complicate-3" This reverts commit f70f4b60debce4a223725781d1973c05d8d1dfa9. Diff: --- .../rvv/autovec/cond/cond_widen_complicate-3-f16.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3-f32.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3-i16.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3-i32.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3-i8.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3-u16.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3-u32.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3-u8.c | 9 -- .../rvv/autovec/cond/cond_widen_complicate-3.c | 36 ++ .../rvv/autovec/cond/cond_widen_complicate-3.h | 21 - 10 files changed, 36 insertions(+), 93 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-f16.c deleted file mode 100644 index e4ff3106b0e0.. --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-f16.c +++ /dev/null @@ -1,9 +0,0 @@ -/* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -mrvv-vector-bits=scalable -ffast-math" } */ - -#include "cond_widen_complicate-3.h" - -TEST_TYPE (float, _Float16) - -/* { dg-final { scan-assembler-times {\tvfwmul\.vv} 1 } } */ -/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-f32.c deleted file mode 100644 index 7d2b44827cdc.. --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-f32.c +++ /dev/null @@ -1,9 +0,0 @@ -/* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d -mrvv-vector-bits=scalable -ffast-math" } */ - -#include "cond_widen_complicate-3.h" - -TEST_TYPE (double, float) - -/* { dg-final { scan-assembler-times {\tvfwmul\.vv} 1 } } */ -/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i16.c deleted file mode 100644 index dc7e1da76b80.. --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i16.c +++ /dev/null @@ -1,9 +0,0 @@ -/* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d -mrvv-vector-bits=scalable" } */ - -#include "cond_widen_complicate-3.h" - -TEST_TYPE (int32_t, int16_t) - -/* { dg-final { scan-assembler-times {\tvwmul\.vv} 1 } } */ -/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i32.c deleted file mode 100644 index de1072f5673f.. --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i32.c +++ /dev/null @@ -1,9 +0,0 @@ -/* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d -mrvv-vector-bits=scalable" } */ - -#include "cond_widen_complicate-3.h" - -TEST_TYPE (int64_t, int32_t) - -/* { dg-final { scan-assembler-times {\tvwmul\.vv} 1 } } */ -/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i8.c deleted file mode 100644 index 8de5ef4db0fb.. --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-i8.c +++ /dev/null @@ -1,9 +0,0 @@ -/* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d -mrvv-vector-bits=scalable" } */ - -#include "cond_widen_complicate-3.h" - -TEST_TYPE (int16_t, int8_t) - -/* { dg-final { scan-assembler-times {\tvwmul\.vv} 1 } } */ -/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-u16.c deleted file mode 100644 index a4aafd203d7e.. --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_widen_complicate-3-u16.c +++ /dev/null @@ -1,9 +0,0 @@ -/* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d -mrvv-vector-bits=scalable" } */ - -#include "cond_widen_complicate-3.h" - -TEST_TYPE (uint32_t, uint16_t) - -/* { dg-final { scan-assembler-times {\tvwmulu\.vv} 1 } } */ -/* { dg-final { scan-assembler-not {\tv
[gcc r15-9336] [committed][RISC-V] Adjust expected output for rvv test
https://gcc.gnu.org/g:0f74d1e38a7dd1931ab110c2b64b633393393437 commit r15-9336-g0f74d1e38a7dd1931ab110c2b64b633393393437 Author: Jeff Law Date: Wed Apr 9 07:55:06 2025 -0600 [committed][RISC-V] Adjust expected output for rvv test The recent combine changes twiddled code generation ever so slightly on risc-v and is causing pr117722.c to fail. The relevant change is this sequence to perform an abs() across elements in a vector: > ! vwsubu.vv v1,v4,v3 > vsetvli zero,zero,e16,mf2,tu,ma > - vrsub.viv3,v1,0 > - vmax.vv v1,v1,v3 Turns into: > ! vwsubu.vv v1,v3,v4 > ! vwsubu.vv v5,v4,v3 > vsetvli zero,zero,e16,mf2,tu,ma > + vmax.vv v1,v1,v5 There's other trivial differences, but that highlights the key change in the abs sequence. The first sequence has lower register pressure since it synthesizes the negation using vrsub.vi. The second sequence is better from a data dependency standpoint as the two vwsubu instructions can execute in parallel on designs with > 1 vector ALU. I don't consider either sequence inherently better than the other. So I'm just adjusting the test to accept our new code. gcc/testsuite * gcc.target/riscv/rvv/autovec/pr117722.c: Adjust expected output. Diff: --- gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117722.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117722.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117722.c index 493dab056212..02670784feaf 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117722.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr117722.c @@ -18,6 +18,5 @@ int pixel_sad_n(unsigned char *pix1, unsigned char *pix2, int n) return sum; } -/* { dg-final { scan-assembler {vrsub\.v} } } */ /* { dg-final { scan-assembler {vmax\.v} } } */ -/* { dg-final { scan-assembler {vwsubu\.v} } } */ +/* { dg-final { scan-assembler-times {vwsubu\.v} 2 } } */
[gcc r15-9349] cobol: Proper comparison of alphanumeric to refmoded numeric-display [PR119682]
https://gcc.gnu.org/g:6704d95ec859d9e7480da130bff1e6b58fe37350 commit r15-9349-g6704d95ec859d9e7480da130bff1e6b58fe37350 Author: Bob Dubner Date: Wed Apr 9 16:23:53 2025 -0400 cobol: Proper comparison of alphanumeric to refmoded numeric-display [PR119682] gcc/cobol PR cobol/119682 * genapi.cc: (cobol_compare): Change the call to __gg__compare(). libgcobol PR cobol/119682 * common-defs.h: Define the REFER_T_REFMOD constant. * intrinsic.cc: (__gg__max): Change the calls to __gg__compare_2(), (__gg__min): Likewise, (__gg__ord_min): Likewise, (__gg__ord_max): Likewise. * libgcobol.cc: (__gg__compare_2): Change definition of calling parameters, eliminate separate flag bit for ALL and ADDRESS_OF, change comparison of alphanumeric to numeric when the numeric is a refmod. * libgcobol.h: Change declaration of __gg__compare_2. Diff: --- gcc/cobol/genapi.cc | 11 +++--- libgcobol/common-defs.h | 1 + libgcobol/intrinsic.cc | 94 ++--- libgcobol/libgcobol.cc | 51 +-- libgcobol/libgcobol.h | 6 ++-- 5 files changed, 77 insertions(+), 86 deletions(-) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index c91237bd8d2c..fdf76aad7b14 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -2028,10 +2028,12 @@ cobol_compare( tree return_int, { // None of our explicit comparisons up above worked, so we revert to the // general case: -int leftflags = (left_side_ref.all ? REFER_T_MOVE_ALL : 0) -+ (left_side_ref.addr_of ? REFER_T_ADDRESS_OF : 0); -int rightflags = (right_side_ref.all ? REFER_T_MOVE_ALL : 0) -+ (right_side_ref.addr_of ? REFER_T_ADDRESS_OF : 0); +int leftflags = (left_side_ref.all ? REFER_T_MOVE_ALL : 0) ++ (left_side_ref.addr_of ? REFER_T_ADDRESS_OF : 0) ++ (left_side_ref.refmod.from ? REFER_T_REFMOD : 0); +int rightflags = (right_side_ref.all ? REFER_T_MOVE_ALL : 0) ++ (right_side_ref.addr_of ? REFER_T_ADDRESS_OF : 0) ++ (right_side_ref.refmod.from ? REFER_T_REFMOD : 0); gg_assign( return_int, gg_call_expr( INT, "__gg__compare", @@ -2045,6 +2047,7 @@ cobol_compare( tree return_int, build_int_cst_type(INT, rightflags), integer_zero_node, NULL_TREE)); +compared = true; } // gg_printf(" result is %d\n", return_int, NULL_TREE); diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h index f9d9c56a0d8d..6bf32ef79cf0 100644 --- a/libgcobol/common-defs.h +++ b/libgcobol/common-defs.h @@ -70,6 +70,7 @@ #define REFER_T_ALL_FLAGS_MASK 0x0FF // We allow for seven subscripts #define REFER_T_MOVE_ALL 0x100 // This is the move_all flag #define REFER_T_ADDRESS_OF 0x200 // This is the address_of flag +#define REFER_T_REFMOD 0x400 // Indicates to library the refer was a refmod #define MIN_FIELD_BLOCK_SIZE (16) diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc index 4bce481b0c04..e0bd3339708e 100644 --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -1867,8 +1867,7 @@ __gg__max(cblc_field_t *dest, unsigned char *best_location ; size_t best_length ; intbest_attr ; -bool best_move_all ; -bool best_address_of ; +intbest_flags ; bool first_time = true; assert(ncount); @@ -1887,8 +1886,7 @@ __gg__max(cblc_field_t *dest, best_location = __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i]; best_length = __gg__treeplet_1s[i]; best_attr = __gg__treeplet_1f[i]->attr; - best_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); - best_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + best_flags = __gg__fourplet_flags[i]; } else { @@ -1896,31 +1894,27 @@ __gg__max(cblc_field_t *dest, unsigned char *candidate_location = __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i]; size_t candidate_length = __gg__treeplet_1s[i]; intcandidate_attr = __gg__treeplet_1f[i]->attr; - bool candidate_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); - bool candidate_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + intcandidate_flags = __gg__fourplet_flags[i]; int compare_result = __gg__compare_2( candidate_field, candidate_location,
[gcc r15-9327] bootstrap/119680 - fix cross-compiler build with --enable-host-shared
https://gcc.gnu.org/g:faff25435b0d23b2ac4deef5a9434c8cd098c0d2 commit r15-9327-gfaff25435b0d23b2ac4deef5a9434c8cd098c0d2 Author: Richard Biener Date: Tue Apr 8 14:57:05 2025 +0200 bootstrap/119680 - fix cross-compiler build with --enable-host-shared It seems that at least when cross-compiling at least collect2 pulls in objects from libbacktrace.a which is linked via LIBDEPS. But libbacktrace for the host is only built -fPIC with --enable-host-shared but not -fPIE with --enable-host-pie so this fails. The following teaches libbacktrace about --enable-host-pie and handles it similar to libcpp. PR bootstrap/119680 libbacktrace/ * configure.ac (--enable-host-pie): Handle by setting PIC_FLAG to -fPIE. * configure: Regenerate. Diff: --- libbacktrace/configure| 16 libbacktrace/configure.ac | 7 ++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libbacktrace/configure b/libbacktrace/configure index 0ecdd3ec0a3d..85be043009af 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -814,6 +814,7 @@ enable_largefile enable_cet enable_werror with_system_libunwind +enable_host_pie enable_host_shared ' ac_precious_vars='build_alias @@ -1464,6 +1465,7 @@ Optional Features: --disable-largefile omit support for large files --enable-cetenable Intel CET in target libraries [default=auto] --disable-werrordisable building with -Werror + --enable-host-pie build host code as PIE --enable-host-sharedbuild host code as shared libraries --enable-cetenable Intel CET in host libraries [default=auto] @@ -11634,7 +11636,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11637 "configure" +#line 11639 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11740,7 +11742,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11743 "configure" +#line 11745 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12518,12 +12520,18 @@ $as_echo "#define HAVE_GETIPINFO 1" >>confdefs.h fi fi +# Enable --enable-host-pie. +# Check whether --enable-host-pie was given. +if test "${enable_host_pie+set}" = set; then : + enableval=$enable_host_pie; PIC_FLAG=-fPIE +else + PIC_FLAG= +fi + # Enable --enable-host-shared. # Check whether --enable-host-shared was given. if test "${enable_host_shared+set}" = set; then : enableval=$enable_host_shared; PIC_FLAG=-fPIC -else - PIC_FLAG= fi diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 75b3a7536f1e..6549cdeacf4f 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -175,11 +175,16 @@ else fi fi +# Enable --enable-host-pie. +AC_ARG_ENABLE(host-pie, +[AS_HELP_STRING([--enable-host-pie], +[build host code as PIE])], +[PIC_FLAG=-fPIE], [PIC_FLAG=]) # Enable --enable-host-shared. AC_ARG_ENABLE(host-shared, [AS_HELP_STRING([--enable-host-shared], [build host code as shared libraries])], -[PIC_FLAG=-fPIC], [PIC_FLAG=]) +[PIC_FLAG=-fPIC]) AC_SUBST(PIC_FLAG) # Enable Intel CET on Intel CET enabled host if jit is enabled.
[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa-dce: delete dead debug insns
https://gcc.gnu.org/g:668fb8231327b7385492464ab879fe06f9859ca1 commit 668fb8231327b7385492464ab879fe06f9859ca1 Author: Ondřej Machota Date: Tue Apr 8 23:27:00 2025 +0200 rtl-ssa-dce: delete dead debug insns Diff: --- gcc/dce.cc | 138 - 1 file changed, 35 insertions(+), 103 deletions(-) diff --git a/gcc/dce.cc b/gcc/dce.cc index c0ca89980254..40b4cd991151 100644 --- a/gcc/dce.cc +++ b/gcc/dce.cc @@ -1421,42 +1421,24 @@ bool is_prelive(insn_info *insn) gcc_assert (insn->is_real()); auto rtl = insn->rtl(); - /* I guess that a lot of conditions bellow are captured by artificial uses - of bb head and end insns. */ for (def_info * def : insn->defs()) { /* The purpose of this pass is not to eliminate stores to memory... */ if (def->is_mem()) - // TODO : clobbered memory? return true; gcc_assert(def->is_reg()); -/* this ignores clobbers, which is probably fine */ /* gcc.c-torture/execute/2503-1.c - flags register is unused. Not all hard registers should be marked... */ + +/* this ignores clobbers, which is probably fine */ if (def->kind() != access_kind::SET) continue; -/* This might be messed up a bit */ -// if (def->regno() == FRAME_POINTER_REGNUM -// || def->regno() == STACK_POINTER_REGNUM) -// return true; - /* needed by gcc.c-torture/execute/pr51447.c */ if (HARD_REGISTER_NUM_P (def->regno()) && global_regs[def->regno()]) -// { std::cout << "marked global reg: " << def->regno() << " in " << insn->uid() << '\n'; - return true; -// } - -// if (!HARD_FRAME_POINTER_IS_FRAME_POINTER -// && def->regno() == HARD_FRAME_POINTER_REGNUM) -// return true; - -// if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM -// && fixed_regs[ARG_POINTER_REGNUM] -// && def->regno() == ARG_POINTER_REGNUM) -// return true; +return true; unsigned int picreg = PIC_OFFSET_TABLE_REGNUM; if (picreg != INVALID_REGNUM @@ -1469,20 +1451,24 @@ bool is_prelive(insn_info *insn) } static void -rtl_ssa_dce_mark_prelive_insn(insn_info *info, vec &worklist, +rtl_ssa_dce_mark_prelive_insn(insn_info *insn, auto_vec &worklist, std::unordered_set &marked) { if (dump_file) -fprintf(dump_file, "Insn %d is prelive\n", info->uid()); +fprintf(dump_file, "Insn %d marked as prelive\n", insn->uid()); - marked.emplace(info); - worklist.safe_push(info); + marked.emplace(insn); + for (use_info *use : insn->uses()) { +set_info* set = use->def(); +if (set) + worklist.safe_push(set); + } } -static auto_vec +static auto_vec rtl_ssa_dce_mark_prelive(std::unordered_set &marked) { - auto_vec worklist; + auto_vec worklist; for (insn_info * insn : crtl->ssa->all_insns()) { if (is_prelive(insn)) rtl_ssa_dce_mark_prelive_insn(insn, worklist, marked); @@ -1497,16 +1483,7 @@ rtl_ssa_dce_mark() std::unordered_set marked{}; /* Phi insn might have more that one phi node: gcc/gcc/testsuite/gcc.c-torture/execute/2224-1.c */ std::unordered_set marked_phi_nodes{}; - auto prelive_insns = rtl_ssa_dce_mark_prelive(marked); - /* Extract uses from prelive insns to worklist */ - auto_vec worklist{}; - for (insn_info * insn : prelive_insns) { -for (auto&& use : insn->uses()) { - set_info* set = use->def(); - if (set) -worklist.safe_push(set); -} - } + auto worklist = rtl_ssa_dce_mark_prelive(marked); while (!worklist.is_empty()) { set_info* set = worklist.pop(); @@ -1581,78 +1558,31 @@ rtl_ssa_dce_sweep(std::unordered_set marked) crtl->ssa->change_insns(changes); } -// WIP -static void -rtl_ssa_dce_transform_insns_to_debug() { - std::unordered_set is_debug; - // Should we use ssa when modifing insns? if yes, we want in-place replace - - /* chceme prochazet v post orderu, abychom nejdrive zpracovali zavislosti - a pak az definici nelze jen menit instrukce, protoze musime informaci - propagovat pres phi node */ - /* We check, whether all insns that use a definition from the current insn - are only debug insns */ - for (insn_info * insn : crtl->ssa->reverse_all_insns()) { -if (insn->is_debug_insn()) { // phi is never debug -// TODO : store info about this insn -is_debug.emplace(insn->uid()); -continue; -} +static void reset_debug_insn_uses(insn_info * insn) { + gcc_assert(insn->is_debug_insn()); -if (insn->is_phi()) { - // for each phi_info - for (def_info *def : insn->defs()) { -phi_info *pi = as_a (def); - - } -} + if (dump_file) +fprintf(dump_file, "Resetting debug insn: %d\n", insn->uid()); -rtx_insn * rtl = insn->rtl(); -rtx set; -if (!(MAY_HAVE_DEBUG_BIND_INSNS - && (set = single_set (rtl)) != NULL_RTX - && (!side_effects_p (SET_SRC (set)) - && asm_n
[gcc r15-9329] expr: Use constant_lower_bound classifying constructor els [PR116595].
https://gcc.gnu.org/g:f183ae0ae891a471764876eb1e69239904598bb4 commit r15-9329-gf183ae0ae891a471764876eb1e69239904598bb4 Author: Robin Dapp Date: Thu Apr 3 16:46:05 2025 +0200 expr: Use constant_lower_bound classifying constructor els [PR116595]. In categorize_ctor_elements_1 we do VECTOR_CST_NELTS (value).to_constant () but VALUE's type can be a VLA vector (since r15-5780-g17b520a10cdaab). This patch uses constant_lower_bound instead. PR middle-end/116595 gcc/ChangeLog: * expr.cc (categorize_ctor_elements_1): Use constant_lower_bound. gcc/testsuite/ChangeLog: * g++.target/riscv/rvv/autovec/pr116595.C: New test. Diff: --- gcc/expr.cc | 6 +++--- gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C | 10 ++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index 2147eedad7be..3815c565e2d8 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -7193,9 +7193,9 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, case VECTOR_CST: { - /* We can only construct constant-length vectors using - CONSTRUCTOR. */ - unsigned int nunits = VECTOR_CST_NELTS (value).to_constant (); + unsigned int nunits + = constant_lower_bound + (TYPE_VECTOR_SUBPARTS (TREE_TYPE (value))); for (unsigned int i = 0; i < nunits; ++i) { tree v = VECTOR_CST_ELT (value, i); diff --git a/gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C b/gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C new file mode 100644 index ..6d509d2cf74e --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv" } */ + +#include + +void +vsseg (float *a, vfloat32mf2_t b, vfloat32mf2_t c, unsigned long vl) +{ + vfloat32mf2x2_t foo = vfloat32mf2x2_t (); +}
[gcc r15-9330] testsuite: Add -mabi to pr116595.C
https://gcc.gnu.org/g:ac1044da4b3db6cba7aa5d9faa1f0622b10ff823 commit r15-9330-gac1044da4b3db6cba7aa5d9faa1f0622b10ff823 Author: Robin Dapp Date: Wed Apr 9 12:11:52 2025 +0200 testsuite: Add -mabi to pr116595.C As usual, I forgot to add -mabi=lp64d to the test case. This patch adds it. Going to push as obvious. gcc/testsuite/ChangeLog: * g++.target/riscv/rvv/autovec/pr116595.C: Add -mabi. Diff: --- gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C b/gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C index 6d509d2cf74e..37475493a214 100644 --- a/gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C +++ b/gcc/testsuite/g++.target/riscv/rvv/autovec/pr116595.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ #include
[gcc r15-9331] libcpp: Fix error recovery after use of __VA_ARGS__ as macro argument [PR118674]
https://gcc.gnu.org/g:6e77a83ffbe4253c306b5b3750cf4ee38e5ce071 commit r15-9331-g6e77a83ffbe4253c306b5b3750cf4ee38e5ce071 Author: Jakub Jelinek Date: Wed Apr 9 12:27:38 2025 +0200 libcpp: Fix error recovery after use of __VA_ARGS__ as macro argument [PR118674] The following testcase ICEs after emitting one pedwarn (about using __VA_ARGS__ in a place where it shouldn't be used) and one error. The error is emitted by _cpp_save_parameter where it sees the node has been used already earlier. But unlike the other _cpp_save_parameter caller which does goto out; if it returns false, this call with explicit __VA_ARGS__ doesn't and if it increments number of parameters etc. after the error, we then try to unsave it twice. The following patch fixes it by doing the goto out in that case too, the macro will then not be considered as variable arguments macro, but for error recovery I think that is fine. The other option would be before the other _cpp_save_parameter caller check if the node is pfile->spec_nodes.n__VA_ARGS__ and in that case also error and goto out, but that seems more expensive than this for the common case that the macro definition is correct. 2025-04-09 Jakub Jelinek PR preprocessor/118674 * macro.cc (parse_params) : If _cpp_save_parameter failed for __VA_ARGS__, goto out. * gcc.dg/cpp/pr118674.c: New test. Diff: --- gcc/testsuite/gcc.dg/cpp/pr118674.c | 5 + libcpp/macro.cc | 7 --- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.dg/cpp/pr118674.c b/gcc/testsuite/gcc.dg/cpp/pr118674.c new file mode 100644 index ..00ea438eeb2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr118674.c @@ -0,0 +1,5 @@ +/* PR preprocessor/118674 */ +/* { dg-do preprocess } */ +#define M(__VA_ARGS__, ...) +/* { dg-error "'__VA_ARGS__' can only appear in the expansion of a C99 variadic macro" "" { target *-*-* } .-1 } */ +/* { dg-error "duplicate macro parameter '__VA_ARGS__'" "" { target *-*-* } .-2 } */ diff --git a/libcpp/macro.cc b/libcpp/macro.cc index aa430e466408..be2571034718 100644 --- a/libcpp/macro.cc +++ b/libcpp/macro.cc @@ -3610,9 +3610,10 @@ parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *variadic_ptr) if (!prev_ident) { /* An ISO bare ellipsis. */ - _cpp_save_parameter (pfile, nparms, - pfile->spec_nodes.n__VA_ARGS__, - pfile->spec_nodes.n__VA_ARGS__); + if (!_cpp_save_parameter (pfile, nparms, + pfile->spec_nodes.n__VA_ARGS__, + pfile->spec_nodes.n__VA_ARGS__)) + goto out; nparms++; pfile->state.va_args_ok = 1; if (! CPP_OPTION (pfile, c99)