commit 820ff02b98af9dda4eb8094322347ab458de351e Author: Jakub Jelinek Date: Fri Jun 26 11:17:46 2026 +0200 Bump BASE-VER. 2026-06-26 Jakub Jelinek * BASE-VER: Set to 14.4.1. diff --git a/gcc/BASE-VER b/gcc/BASE-VER index 72f51351fcd..a74a70e5dba 100644 --- a/gcc/BASE-VER +++ b/gcc/BASE-VER @@ -1 +1 @@ -14.4.0 +14.4.1 commit 12b43606631c4029f0dda59205f559b07581b329 Author: GCC Administrator Date: Sat Jun 27 00:19:34 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 29656a8522b..4fff66f6b5d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260626 +20260627 commit 1a1a34217e5989d5e5d6e4c546b404108527a0c6 Author: Patrick Palka Date: Tue Feb 17 11:21:42 2026 -0500 c++: unifying LAMBDA_EXPR [PR122318] This patch makes the default case of unify accept LAMBDA_EXPR P/A pairs, which we can legitimately hit during alias CTAD guide overload resolution. We can also less legimitately hit this during partial specialization matching (likely IFNDR). I'm not totally sure if we want to handle them like any other non-deducible expression vs handling them separately (returning success iff they're ==). I couldn't come up with a testcase for which it mattered so I went the simpler route. PR c++/122318 PR c++/101670 gcc/cp/ChangeLog: * pt.cc (unify) : Accept LAMBDA_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ20.C: New test. * g++.dg/cpp2a/lambda-targ21.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 9fe46ba8eb3f2cf41744cf8490b025f0876b9c86) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 341b08ad3eb..3ba1fb944b3 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -25495,6 +25495,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, return unify_success (explain_p); gcc_assert (EXPR_P (parm) || TREE_CODE (parm) == CONSTRUCTOR + || TREE_CODE (parm) == LAMBDA_EXPR || TREE_CODE (parm) == TRAIT_EXPR); expr: /* We must be looking at an expression. This can happen with diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ20.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ20.C new file mode 100644 index 00000000000..4d444bbe112 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ20.C @@ -0,0 +1,14 @@ +// PR c++/122318 +// { dg-do compile { target c++20 } } + +template +struct A { + A() { } + A(T) { } +}; + +template +using AT = A; + +AT a; +AT b = a; diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ21.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ21.C new file mode 100644 index 00000000000..d417d6cc3e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ21.C @@ -0,0 +1,10 @@ +// PR c++/101670 +// { dg-do compile { target c++20 } } + +template +struct A; + +template +struct A { }; // Partial specialization unusable due to lambda uniqueness + +A<0> a; // { dg-error "incomplete" } commit c401ff8c4304eee1dc80adf0573a052a632214a3 Author: Patrick Palka Date: Thu Jun 5 11:07:25 2025 -0400 c++: substituting fn parm redeclared with dep alias tmpl [PR120224] Here we declare f twice, the second time around using a dependent alias template. Due to alias template transparency these are logically the same overload. But now the function type of f (produced from the first declaration) diverges from the type of its formal parameter (produced from the subsequent redefinition) in that substituting T=int succeeds for the function type but not for the formal parameter type. This eventually causes us to produce an undiagnosed error_mark_node in the AST of the function call, leading to failure of the sanity check check added in r14-6343-g0c018a74eb1aff. Before r14-6343 we would still go on to reject the testcase later at instantiation time, from regenerate_decl_from_template, making this a regression. To fix this, it seems we just need to propagate error_mark_node upon substitution failure into the type of a PARM_DECL. PR c++/120224 gcc/cp/ChangeLog: * pt.cc (tsubst_function_decl): Return error_mark_node if substituting into the formal parameter list failed. (tsubst_decl) : Return error_mark_node upon TREE_TYPE substitution failure, when in a SFINAE context. Return error_mark_node upon DECL_CHAIN substitution failure. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-80.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 51e93aadc94940e2da854cf1321a7ab1aebf8d1a) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 3ba1fb944b3..733ce975500 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -14719,6 +14719,8 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t)) parms = DECL_CHAIN (parms); parms = tsubst (parms, args, complain, t); + if (parms == error_mark_node) + return error_mark_node; for (tree parm = parms; parm; parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = r; if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t)) @@ -15294,6 +15296,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, /* We're dealing with a normal parameter. */ type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node && !(complain & tf_error)) + RETURN (error_mark_node); + type = type_decays_to (type); TREE_TYPE (r) = type; cp_apply_type_quals_to_decl (cp_type_quals (type), r); @@ -15331,8 +15336,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, /* If cp_unevaluated_operand is set, we're just looking for a single dummy parameter, so don't keep going. */ if (DECL_CHAIN (t) && !cp_unevaluated_operand) - DECL_CHAIN (r) = tsubst (DECL_CHAIN (t), args, - complain, DECL_CHAIN (t)); + { + tree chain = tsubst (DECL_CHAIN (t), args, + complain, DECL_CHAIN (t)); + if (chain == error_mark_node) + RETURN (error_mark_node); + DECL_CHAIN (r) = chain; + } /* FIRST_R contains the start of the chain we've built. */ r = first_r; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C new file mode 100644 index 00000000000..9c0eadc967c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C @@ -0,0 +1,21 @@ +// PR c++/120224 +// { dg-do compile { target c++11 } } + +template using void_t = void; + +template +void f(void*); // #1 + +template +void f(void_t*) { } // { dg-error "not a class" } defn of #1 + +template +void g(int, void*); // #2 + +template +void g(int, void_t*) { } // { dg-error "not a class" } defn of #2 + +int main() { + f(0); // { dg-error "no match" } + g(0, 0); // { dg-error "no match" } +} commit 9e6c046f0a27e1900455676c3f98126b7da62ff8 Author: Patrick Palka Date: Tue Feb 17 11:21:45 2026 -0500 c++: void(concept-id) evaluation [PR121822] Similar to r16-7056-g22f51c0f5e62a4, here the expression within the decltype void(Derived) is non-dependent enough that we instantiate/fold it immediately, during which however convert_to_void tries to evaluate the concept-id, which fails. When in an unevaluated context such as decltype I don't think convert_to_void should be evaluating concept-ids. PR c++/121822 gcc/cp/ChangeLog: * cvt.cc (convert_to_void): Don't evaluate a concept-id in an unevaluated context. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-decltype6.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 44a51e8c7037eacd4315df0e84bf51e6e4021088) diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc index dac210d1247..ebc079cfc8c 100644 --- a/gcc/cp/cvt.cc +++ b/gcc/cp/cvt.cc @@ -1200,7 +1200,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) /* Explicitly evaluate void-converted concept checks since their satisfaction may produce ill-formed programs. */ - if (concept_check_p (expr)) + if (concept_check_p (expr) && !cp_unevaluated_operand) expr = evaluate_concept_check (expr); if (VOID_TYPE_P (TREE_TYPE (expr))) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-decltype6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-decltype6.C new file mode 100644 index 00000000000..03ecc7b0a07 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-decltype6.C @@ -0,0 +1,16 @@ +// PR c++/121822 +// { dg-do compile { target c++20 } } + +template +using void_t = void; + +template +concept Derived = requires { typename T::derived_type; }; + +template +struct Wrapper; + +template +struct Wrapper))>> { }; + +Wrapper x; commit 040cf529e22c309c0f568823ba4fb1fab6de3d7e Author: Patrick Palka Date: Tue Apr 7 12:28:42 2026 -0400 c++: templated static local var has value-dep addr, cont [PR123529] has_value_dependent_address for a static local variable checks type dependence of its context, but that's too narrow and we need a more general dependence check that considers outer template arguments as well, so that in the testcase below we deem A::g()::i to have a value-dependent address (making f<&i>() a dependent call). PR c++/123529 PR c++/98930 gcc/cp/ChangeLog: * pt.cc (has_value_dependent_address): Correct context dependence check for a static local variable. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/nontype9.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 6084b750085ae0de11b65df76b9e590b795afc74) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 733ce975500..0685b21d55c 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -6982,7 +6982,8 @@ has_value_dependent_address (tree op) if (VAR_P (op) && TREE_STATIC (op) && TREE_CODE (ctx) == FUNCTION_DECL - && type_dependent_expression_p (ctx)) + && DECL_TEMPLATE_INFO (ctx) + && any_dependent_template_arguments_p (DECL_TI_ARGS (ctx))) return true; } diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype9.C b/gcc/testsuite/g++.dg/cpp1z/nontype9.C new file mode 100644 index 00000000000..6f4d927eff3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nontype9.C @@ -0,0 +1,16 @@ +// PR c++/123529 +// { dg-do compile { target c++17 } } + +template +void f(); + +template +struct A { + static void g() { + static int i; + f<&i>(); + } +}; + +template struct A; +template struct A; commit ccd150e0f45a8d7b622052b89b1d9b26d96d2476 Author: Patrick Palka Date: Tue Jul 1 13:43:09 2025 -0400 libstdc++: Use ranges::iter_move in ranges::unique [PR120789] PR libstdc++/120789 libstdc++-v3/ChangeLog: * include/bits/ranges_algo.h (__unique_fn::operator()): Use ranges::iter_move(iter) instead of std::move(*iter). * testsuite/25_algorithms/unique/120789.cc: New test. Reviewed-by: Tomasz Kamiński Reviewed-by: Jonathan Wakely (cherry picked from commit 6f69a68998f601cdb86c65113eb1feddfa9da31a) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 59374e3dbd0..f8168e6a7ff 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -1144,7 +1144,7 @@ namespace ranges if (!std::__invoke(__comp, std::__invoke(__proj, *__dest), std::__invoke(__proj, *__first))) - *++__dest = std::move(*__first); + *++__dest = ranges::iter_move(__first); return {++__dest, __first}; } diff --git a/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc new file mode 100644 index 00000000000..24b10713247 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc @@ -0,0 +1,36 @@ +// PR libstdc++/120789 - ranges::unique should use ranges::iter_move +// { dg-do compile { target c++20 } } + +#include + +struct A +{ + bool operator==(const A&) const; +}; + +struct B +{ + B(B&&) = delete; + B& operator=(const A&) const; + + operator A() const; + bool operator==(const B&) const; +}; + +struct I +{ + using value_type = A; + using difference_type = int; + B operator*() const; + I& operator++(); + I operator++(int); + bool operator==(const I&) const; + friend A iter_move(const I&); +}; + +void +test01() +{ + std::ranges::subrange r; + auto [begin, end] = std::ranges::unique(r); +} commit 1b7d2aefd5f3f9425c1611b0a5944460a7479fb1 Author: Patrick Palka Date: Tue Jul 1 13:43:12 2025 -0400 libstdc++: Use ranges::iter_move in ranges::remove_if [PR120789] PR libstdc++/120789 libstdc++-v3/ChangeLog: * include/bits/ranges_algo.h (__remove_if_fn::operator()): Use ranges::iter_move(iter) instead of std::move(*iter). * testsuite/25_algorithms/remove_if/120789.cc: New test. Reviewed-by: Tomasz Kamiński Reviewed-by: Jonathan Wakely (cherry picked from commit 17e9ae215f991f2f94fe480aee2404c508388b7c) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index f8168e6a7ff..7ce98926a75 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -990,7 +990,7 @@ namespace ranges for (; __first != __last; ++__first) if (!std::__invoke(__pred, std::__invoke(__proj, *__first))) { - *__result = std::move(*__first); + *__result = ranges::iter_move(__first); ++__result; } diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc b/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc new file mode 100644 index 00000000000..c1f4eeb9b4d --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc @@ -0,0 +1,36 @@ +// PR libstdc++/120789 - ranges::remove_if should use ranges::iter_move +// { dg-do compile { target c++20 } } + +#include + +struct A +{ + bool operator==(const A&) const; +}; + +struct B +{ + B(B&&) = delete; + B& operator=(const A&) const; + + operator A() const; + bool operator==(const B&) const; +}; + +struct I +{ + using value_type = A; + using difference_type = int; + B operator*() const; + I& operator++(); + I operator++(int); + bool operator==(const I&) const; + friend A iter_move(const I&); +}; + +void +test01() +{ + std::ranges::subrange r; + auto [begin, end] = std::ranges::remove_if(r, [](auto&&) { return true; }); +} commit f91ad823bc233fa9fef30c4792e429d13a9d7887 Author: GCC Administrator Date: Sun Jun 28 00:19:32 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4fff66f6b5d..e77e928a75e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260627 +20260628 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9ef7c77ae95..29c3524b81d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,44 @@ +2026-06-27 Patrick Palka + + Backported from master: + 2026-04-07 Patrick Palka + + PR c++/123529 + PR c++/98930 + * pt.cc (has_value_dependent_address): Correct context + dependence check for a static local variable. + +2026-06-27 Patrick Palka + + Backported from master: + 2026-02-17 Patrick Palka + + PR c++/121822 + * cvt.cc (convert_to_void): Don't evaluate a concept-id + in an unevaluated context. + +2026-06-27 Patrick Palka + + Backported from master: + 2025-06-05 Patrick Palka + + PR c++/120224 + * pt.cc (tsubst_function_decl): Return error_mark_node if + substituting into the formal parameter list failed. + (tsubst_decl) : Return error_mark_node + upon TREE_TYPE substitution failure, when in a SFINAE + context. Return error_mark_node upon DECL_CHAIN substitution + failure. + +2026-06-27 Patrick Palka + + Backported from master: + 2026-02-17 Patrick Palka + + PR c++/122318 + PR c++/101670 + * pt.cc (unify) : Accept LAMBDA_EXPR. + 2026-06-26 Release Manager * GCC 14.4.0 released. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a049ddc5355..15efc6faefa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,38 @@ +2026-06-27 Patrick Palka + + Backported from master: + 2026-04-07 Patrick Palka + + PR c++/123529 + PR c++/98930 + * g++.dg/cpp1z/nontype9.C: New test. + +2026-06-27 Patrick Palka + + Backported from master: + 2026-02-17 Patrick Palka + + PR c++/121822 + * g++.dg/cpp2a/concepts-decltype6.C: New test. + +2026-06-27 Patrick Palka + + Backported from master: + 2025-06-05 Patrick Palka + + PR c++/120224 + * g++.dg/cpp0x/alias-decl-80.C: New test. + +2026-06-27 Patrick Palka + + Backported from master: + 2026-02-17 Patrick Palka + + PR c++/122318 + PR c++/101670 + * g++.dg/cpp2a/lambda-targ20.C: New test. + * g++.dg/cpp2a/lambda-targ21.C: New test. + 2026-06-26 Release Manager * GCC 14.4.0 released. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 400f97a1f20..57d4cedcd1c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2026-06-27 Patrick Palka + + Backported from master: + 2025-07-01 Patrick Palka + + PR libstdc++/120789 + * include/bits/ranges_algo.h (__remove_if_fn::operator()): Use + ranges::iter_move(iter) instead of std::move(*iter). + * testsuite/25_algorithms/remove_if/120789.cc: New test. + +2026-06-27 Patrick Palka + + Backported from master: + 2025-07-01 Patrick Palka + + PR libstdc++/120789 + * include/bits/ranges_algo.h (__unique_fn::operator()): Use + ranges::iter_move(iter) instead of std::move(*iter). + * testsuite/25_algorithms/unique/120789.cc: New test. + 2026-06-26 Release Manager * GCC 14.4.0 released. commit 5f3e4237ca0b2f410a718b7cf2a3481cf7635a60 Author: Georg-Johann Lay Date: Sun Jun 28 12:08:04 2026 +0200 AVR: ad target/125752 - Simplify double -> 64-bit fixed conversions. When converting a fixed-point value to double, there is no need to use ldexp to adjust for FBIT of the result. Instead, FBIT can be added to the double exponent without any further ado. When the input is +/-0.0 then the outcome of adding FBIT to the exponent is a small number that __fix[uns]dfdi converts to 0. PR target/125752 libgcc/config/avr/libf7/ * libf7.c (d_to_ufx, d_to_sfx): Remove prototypes. (__fractdfda, __fractdfuda, __fractdfta, __fractdfuta) (__fractdfdq, __fractdfudq): Move implementation to... * libf7-asm.sx: ...here. (d_to_fx64): Remove. * libf7-common.mk (F7_ASM_PARTS): Add D2dq, D2udq, D2da, D2uda, D2ta, D2uta. (F7F_asm): Remove d_to_fx64. * t-libf7 (LIBF7_DF_CONV): Remove fractdfda, fractdfta, fractdfdq, fractdfuda, fractdfuta, fractdfudq. * f7-renames.h: Rebuild. (cherry picked from commit 997a7e79258e7209718c5366b6a1d3be31c76b8b) diff --git a/libgcc/config/avr/libf7/f7-renames.h b/libgcc/config/avr/libf7/f7-renames.h index ba4410ee7c3..92f47817b49 100644 --- a/libgcc/config/avr/libf7/f7-renames.h +++ b/libgcc/config/avr/libf7/f7-renames.h @@ -222,7 +222,6 @@ #define f7_sqrt16_floor_asm __f7_sqrt16_floor_asm #define f7_lshrdi3_asm __f7_lshrdi3_asm #define f7_ashldi3_asm __f7_ashldi3_asm -#define f7_d_to_fx64_asm __f7_d_to_fx64_asm #define f7_ufx64_to_d_asm __f7_ufx64_to_d_asm #define f7_sfx64_to_d_asm __f7_sfx64_to_d_asm #define f7_class_D_asm __f7_class_D_asm diff --git a/libgcc/config/avr/libf7/libf7-asm.sx b/libgcc/config/avr/libf7/libf7-asm.sx index 6f50e401e0a..6e4f3eef6ad 100644 --- a/libgcc/config/avr/libf7/libf7-asm.sx +++ b/libgcc/config/avr/libf7/libf7-asm.sx @@ -2465,48 +2465,56 @@ _DEFUN __fractdfusa _ENDF __fractdfusa #endif /* F7MOD_D2usa_ */ - -#ifdef F7MOD_D2fx_ -;;; Convert double R18 to a 64-bit fixed point value. -;;; R18 d_to_fx64 (double R18, int8_t fbit R16); -;;; |FBIT| accounts for the extra fbits compared to [u]int64_t. -;;; FBIT < 0 indicates a signed conversion. -;;; FBIT > 0 indicates an unsigned conversion. -DEFUN d_to_fx64 - do_prologue_saves 4, F7_SIZEOF - - ;; Y = FramePointer + 1 - adiw Y, 1 - - ;; FP + 1 = (f7_t) arg - wmov r16, Y - - ;; Convert double R18 to f7_t *R16. - XCALL F7_NAME (set_double_impl) - - ;; Prepare for *R24 = ldexp (*R24, R22). ldexp() accounts for the - ;; fractional bits of the fixed point value, i.e. we have to <<= FBIT. - wmov r24, r16 - ;; Zero-extend FBIT. - clr r23 - ;; R16 has been clobbered. Fetch it from where prologue_saves put it. - ldd r22, Y + F7_SIZEOF + 3 ; Saved R16 - tst r22 - brmi 1f - - ;; Positive FBIT indicates an unsigned conversion. - XCALL F7_NAME (Ildexp) - XCALL F7_NAME (get_u64) - rjmp 9f - -1: ;; Negative FBIT indicates a signed conversion. - neg r22 ; FBIT := |FBIT| - XCALL F7_NAME (Ildexp) - XCALL F7_NAME (get_s64) - -9: do_epilogue_restores 4, F7_SIZEOF -ENDF d_to_fx64 -#endif /* F7MOD_D2fx_ */ +#ifdef F7MOD_D2da_ +_DEFUN __fractdfda + ;; Multiply with 2^FBIT to get a DA result in r25:r18. + subi r24, dex_lo (-__DA_FBIT__) + sbci r25, dex_hi (-__DA_FBIT__) + XJMP __fixdfdi +_ENDF __fractdfda +#endif /* F7MOD_D2da_ */ + +#ifdef F7MOD_D2uda_ +_DEFUN __fractdfuda + ;; Multiply with 2^FBIT to get an UDA result in r25:r18. + subi r25, dex_hi (-__UDA_FBIT__) + XJMP __fixunsdfdi +_ENDF __fractdfuda +#endif /* F7MOD_D2uda_ */ + +#ifdef F7MOD_D2ta_ +_DEFUN __fractdfta + ;; Multiply with 2^FBIT to get a TA result in r25:r18. + subi r24, dex_lo (-__TA_FBIT__) + sbci r25, dex_hi (-__TA_FBIT__) + XJMP __fixdfdi +_ENDF __fractdfta +#endif /* F7MOD_D2ta_ */ + +#ifdef F7MOD_D2uta_ +_DEFUN __fractdfuta + ;; Multiply with 2^FBIT to get an UTA result in r25:r18. + subi r25, dex_hi (-__UTA_FBIT__) + XJMP __fixunsdfdi +_ENDF __fractdfuta +#endif /* F7MOD_D2uta_ */ + +#ifdef F7MOD_D2dq_ +_DEFUN __fractdfdq + ;; Multiply with 2^FBIT to get a DQ result in r25:r18. + subi r24, dex_lo (-__DQ_FBIT__) + sbci r25, dex_hi (-__DQ_FBIT__) + XJMP __fixdfdi +_ENDF __fractdfdq +#endif /* F7MOD_D2dq_ */ + +#ifdef F7MOD_D2udq_ +_DEFUN __fractdfudq + ;; Multiply with 2^FBIT to get an UDQ result in r25:r18. + subi r25, dex_hi (-__UDQ_FBIT__) + XJMP __fixunsdfdi +_ENDF __fractdfudq +#endif /* F7MOD_D2udq_ */ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/libgcc/config/avr/libf7/libf7-common.mk b/libgcc/config/avr/libf7/libf7-common.mk index 4c3091f4f43..3ebe101c9c1 100644 --- a/libgcc/config/avr/libf7/libf7-common.mk +++ b/libgcc/config/avr/libf7/libf7-common.mk @@ -34,9 +34,8 @@ F7_ASM_PARTS += ha2D uha2D sa2D usa2D da2D uda2D ta2D uta2D F7_ASM_PARTS += fx2D # Double -> fixed-point conversions -F7_ASM_PARTS += D2qq D2uqq D2hq D2uhq -F7_ASM_PARTS += D2ha D2uha D2sa D2usa -F7_ASM_PARTS += D2fx +F7_ASM_PARTS += D2qq D2uqq D2hq D2uhq D2dq D2udq +F7_ASM_PARTS += D2ha D2uha D2sa D2usa D2da D2uda D2ta D2uta # Integer -> double conversions F7_ASM_PARTS += D_floatsidf D_floatunsidf @@ -109,7 +108,7 @@ F7F_asm += set_u64 set_s64 addsub_mant_scaled mul_mant F7F_asm += to_integer to_unsigned clr_mant_lsbs F7F_asm += div sqrt_approx sqrt16_round sqrt16_floor F7F_asm += lshrdi3 ashldi3 -F7F_asm += d_to_fx64 ufx64_to_d sfx64_to_d +F7F_asm += ufx64_to_d sfx64_to_d F7F_asm += class_D F7F_asm += call_ddd call_xdd call_ddx diff --git a/libgcc/config/avr/libf7/libf7.c b/libgcc/config/avr/libf7/libf7.c index 9825625b900..4e3cc9fc634 100644 --- a/libgcc/config/avr/libf7/libf7.c +++ b/libgcc/config/avr/libf7/libf7.c @@ -140,58 +140,6 @@ f7_double_t __floatdidf (int64_t x) #endif // F7MOD_floatdidf_ -extern uint64_t d_to_ufx (f7_double_t, int8_t) F7ASM(f7_d_to_fx64_asm); -extern int64_t d_to_sfx (f7_double_t, int8_t) F7ASM(f7_d_to_fx64_asm); - -#ifdef F7MOD_fractdfda_ -F7_WEAK -int64_t __fractdfda (f7_double_t d) -{ - return d_to_sfx (d, -__DA_FBIT__); -} -#endif // F7MOD_fractdfda_ - -#ifdef F7MOD_fractdfuda_ -F7_WEAK -uint64_t __fractdfuda (f7_double_t d) -{ - return d_to_ufx (d, __UDA_FBIT__); -} -#endif // F7MOD_fractdfuda_ - -#ifdef F7MOD_fractdfta_ -F7_WEAK -int64_t __fractdfta (f7_double_t d) -{ - return d_to_sfx (d, -__TA_FBIT__); -} -#endif // F7MOD_fractdfta_ - -#ifdef F7MOD_fractdfuta_ -F7_WEAK -uint64_t __fractdfuta (f7_double_t d) -{ - return d_to_ufx (d, __UTA_FBIT__); -} -#endif // F7MOD_fractdfuta_ - -#ifdef F7MOD_fractdfdq_ -F7_WEAK -int64_t __fractdfdq (f7_double_t d) -{ - return d_to_sfx (d, -__DQ_FBIT__); -} -#endif // F7MOD_fractdfdq_ - -#ifdef F7MOD_fractdfudq_ -F7_WEAK -uint64_t __fractdfudq (f7_double_t d) -{ - return d_to_ufx (d, __UDQ_FBIT__); -} -#endif // F7MOD_fractdfudq_ - - #ifdef F7MOD_init_ f7_t* f7_init_impl (uint64_t mant, uint8_t flags, f7_t *cc, int16_t expo) { diff --git a/libgcc/config/avr/libf7/t-libf7 b/libgcc/config/avr/libf7/t-libf7 index 5e589b08282..f17e67e8523 100644 --- a/libgcc/config/avr/libf7/t-libf7 +++ b/libgcc/config/avr/libf7/t-libf7 @@ -9,8 +9,6 @@ F7_PREFIX = __f7_ include $(libf7)/libf7-common.mk LIBF7_DF_CONV += floatundidf floatdidf # floatunsidf floatsidf -LIBF7_DF_CONV += fractdfda fractdfta fractdfdq -LIBF7_DF_CONV += fractdfuda fractdfuta fractdfudq # Wrappers like f7_lt_impl for f7_lt etc. because the latter is inline. LIBF7_DF_CMP += lt le gt ge ne eq unord commit 388850589abb1a80f87acf5c67a6d350a7d08294 Author: GCC Administrator Date: Mon Jun 29 00:19:31 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e77e928a75e..1d91ae1491c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260628 +20260629 diff --git a/libgcc/config/avr/libf7/ChangeLog b/libgcc/config/avr/libf7/ChangeLog index 14804651907..97e300ba002 100644 --- a/libgcc/config/avr/libf7/ChangeLog +++ b/libgcc/config/avr/libf7/ChangeLog @@ -1,3 +1,21 @@ +2026-06-28 Georg-Johann Lay + + Backported from master: + 2026-06-28 Georg-Johann Lay + + PR target/125752 + * libf7.c (d_to_ufx, d_to_sfx): Remove prototypes. + (__fractdfda, __fractdfuda, __fractdfta, __fractdfuta) + (__fractdfdq, __fractdfudq): Move implementation to... + * libf7-asm.sx: ...here. + (d_to_fx64): Remove. + * libf7-common.mk (F7_ASM_PARTS): Add D2dq, D2udq, D2da, + D2uda, D2ta, D2uta. + (F7F_asm): Remove d_to_fx64. + * t-libf7 (LIBF7_DF_CONV): Remove fractdfda, fractdfta, + fractdfdq, fractdfuda, fractdfuta, fractdfudq. + * f7-renames.h: Rebuild. + 2026-06-26 Release Manager * GCC 14.4.0 released. commit 2050bc6ba84815a8e6a9c6d9c6e04cd04c4ce66f Author: Jakub Jelinek Date: Sat Jun 6 09:50:35 2026 +0200 i386: Fix up predicates on _pmulhrsw3, smulhrs3 expanders [PR125611] The following testcase ICEs since r6-6060-gacf93f1edc9 aka PR68991 fix. THe problem is that the commit has changed the predicates on *_pmulhrsw3 pattern from nonimmediate_operand to vector_operand but kept the old predicates on the corresponding expanders. With TARGET_AVX that makes no difference (so I've left the _pmulhrsw3_mask expander as is, that is only TARGET_AVX512BW && TARGET_AVX512VL), but without it if there is unaligned memory the expander can just expand it as memory without forcing into REG while the pattern will not match. 2026-06-06 Jakub Jelinek PR target/125611 * config/i386/sse.md (_pmulhrsw3, smulhrs3): Use vector_operand instead of nonimmediate_operand. * gcc.target/i386/ssse3-pr125611.c: New test. Reviewed-by: Uros Bizjak (cherry picked from commit 793da440da5c84090af9e864b824157db02cdc82) diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 00d411755d5..e2c4e6c8f69 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -21832,9 +21832,9 @@ (lshiftrt: (mult: (sign_extend: - (match_operand:PMULHRSW 1 "nonimmediate_operand")) + (match_operand:PMULHRSW 1 "vector_operand")) (sign_extend: - (match_operand:PMULHRSW 2 "nonimmediate_operand"))) + (match_operand:PMULHRSW 2 "vector_operand"))) (const_int 14)) (match_dup 3)) (const_int 1))))] @@ -21852,9 +21852,9 @@ (lshiftrt: (mult: (sign_extend: - (match_operand:VI2_AVX2_AVX512BW 1 "nonimmediate_operand")) + (match_operand:VI2_AVX2_AVX512BW 1 "vector_operand")) (sign_extend: - (match_operand:VI2_AVX2_AVX512BW 2 "nonimmediate_operand"))) + (match_operand:VI2_AVX2_AVX512BW 2 "vector_operand"))) (const_int 14)) (match_dup 3)) (const_int 1))))] diff --git a/gcc/testsuite/gcc.target/i386/ssse3-pr125611.c b/gcc/testsuite/gcc.target/i386/ssse3-pr125611.c new file mode 100644 index 00000000000..7205edc4c52 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssse3-pr125611.c @@ -0,0 +1,12 @@ +/* PR target/125611 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mssse3 -mno-sse4.1" } */ + +typedef __attribute__((__vector_size__(16))) short V; +struct __attribute__((__packed__)) { V v[4]; } *u; + +void +foo (void) +{ + u->v[2] &= __builtin_ia32_pmulhrsw128 (u->v[0], u->v[1]); +} commit 9f3f376a5c6baa7e3d627d6e98e538622e6d53dd Author: Jakub Jelinek Date: Sat Jun 27 21:33:00 2026 +0200 s390: Fix up *brx_stage1_ [PR125992] The following testcase is miscompiled since r16-3301 but the problem is much older. The *brx_stage1_ define_insn_and_split pattern doesn't describe that it clobbers CC_REGNUM, but splits (before reload) into something which does clobber CC_REGNUM unconditionally. Since r16-3301 on this testcase the late_combine1 pass figures it can extend the lifetime of CC_REGNUM across such an instruction, but when it is in split1 pass split into something that does clobber CC_REGNUM, the value from earlier comparison till later use is not preserved anymore. The following patch fixes it by adding clobber for CC_REGNUM even to the *brx_stage1_ pattern, so that df/late_combine etc. know that it is CC_REGNUM is clobbered by it. I had to put the clobber before the match_scratch clobber, otherwise there is endless loop trying to split this insn in split1 pass, the insn it is split into matches the pattern again and is split again etc. forever. Even with this patch combine can match this insn, we have code to add the missing clobbers if the register isn't live across it. 2026-06-27 Jakub Jelinek PR target/125992 * config/s390/s390.md (*brx_stage1_): Add CC_REGNUM clobber. * gcc.target/s390/pr125992.c: New test. Reviewed-by: Stefan Schulze Frielinghaus (cherry picked from commit 13529401b15fe82c0b1d44b0b0a8bf5d2d72a1b3) diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index c364880af0a..2e24836d40a 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -9678,6 +9678,7 @@ (pc))) (set (match_operand:GPR 4 "nonimmediate_operand" "") (plus:GPR (match_dup 1) (match_dup 2))) + (clobber (reg:CC CC_REGNUM)) (clobber (match_scratch:GPR 5 ""))] "" "#" diff --git a/gcc/testsuite/gcc.target/s390/pr125992.c b/gcc/testsuite/gcc.target/s390/pr125992.c new file mode 100644 index 00000000000..a7d4b799ebe --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr125992.c @@ -0,0 +1,41 @@ +/* PR target/125992 */ +/* { dg-do run { target s390_useable_hw } } */ +/* { dg-options "-O2 -march=z13" } */ + +long a, b, c, d[4]; + +[[gnu::noipa]] long +foo () +{ + return d[c++]; +} + +[[gnu::noipa]] void +bar () +{ + long e = 0; + for (;;) + { + e += a; + a = foo (); + if (b + a > e) + return; + if (a == 0) + break; + if (a > 0) + b += a; + } +} + +int +main () +{ + a = 16; + b = -64; + c = 0; + d[0] = 64; + d[1] = 128; + bar (); + if (b != 0) + __builtin_abort (); +} commit 9bc6561c40525b34439958df84eca8c6d54a54fc Author: Alex Coplan Date: Thu Jun 18 15:05:07 2026 +0100 aarch64: Fix unsharing in svset_impl::fold [PR125818] svset_impl::fold lowers svset intrinsics into a copy of the entire tuple and then a subsequent update of the given tuple member to the new vector value, e.g.: D.14149 = svset2_f32 (a, 0, v); gets lowered into: D.14149 = a; D.14149.__val[0] = v; . Because both stmts use the lhs of the original call stmt, the code unshares the expressions. As svset_impl::fold notes: /* [...] The fold routines expect the replacement statement to have the same lhs as the original call, so return the copy statement rather than the field update. */ ultimately gsi_replace asserts that: gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt) i.e. requiring pointer equality, but the copy stmt we build is: gassign *copy = gimple_build_assign (unshare_expr (f.lhs), rhs_tuple); and notably the unshare_expr means that the pointer equality test above fails. For VAR_DECLs (as above) it happens to work, since those aren't unshared. mostly_copy_tree_r (called from unshare_expr) has: /* Stop at types, decls, constants like copy_tree_r. */ else if (TREE_CODE_CLASS (code) == tcc_type || TREE_CODE_CLASS (code) == tcc_declaration || TREE_CODE_CLASS (code) == tcc_constant) *walk_subtrees = 0; but for MEM_EXPRs (as with the tescase in the PR) we *do* actually unshare them, and thus trip the assert in gsi_replace (or since r17-1237-g4fb2541debcca1, ICE in completely_unused, but the root cause is the same). We want the stmt returned from svset_impl::fold (copy) to have a pointer-identical lhs as the original stmt, so this patch just changes which use of f.lhs is unshared. We keep copy's use as per the original stmt, and unshare the use in the update stmt instead. gcc/ChangeLog: PR target/125818 * config/aarch64/aarch64-sve-builtins-base.cc (svset_impl::fold): Fix unsharing to ensure the returned stmt has the exact same lhs as the original. gcc/testsuite/ChangeLog: PR target/125818 * gcc.target/aarch64/torture/pr125818.c: New test. (cherry picked from commit f6aac7ffab9f80d55b58beafc87da3379a70672a) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc index 1984e182586..9eff2787f43 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc @@ -2476,12 +2476,12 @@ public: The fold routines expect the replacement statement to have the same lhs as the original call, so return the copy statement rather than the field update. */ - gassign *copy = gimple_build_assign (unshare_expr (f.lhs), rhs_tuple); + gassign *copy = gimple_build_assign (f.lhs, rhs_tuple); /* Get a reference to the individual vector. */ tree field = tuple_type_field (TREE_TYPE (f.lhs)); tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field), - f.lhs, field, NULL_TREE); + unshare_expr (f.lhs), field, NULL_TREE); tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector), lhs_array, index, NULL_TREE, NULL_TREE); gassign *update = gimple_build_assign (lhs_vector, rhs_vector); diff --git a/gcc/testsuite/gcc.target/aarch64/torture/pr125818.c b/gcc/testsuite/gcc.target/aarch64/torture/pr125818.c new file mode 100644 index 00000000000..875092000df --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/torture/pr125818.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+sve" } */ +#include +void f(svfloat32x2_t *tp, const svfloat32x2_t *tuple, const svfloat32_t *vp) { + *tp = svset2_f32(*tuple, 0, *vp); +} commit 210be58a7c4e4760ec2301bb9f7cffa982ee315a Author: GCC Administrator Date: Tue Jun 30 00:20:02 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fa39d74cf6..3af80e852b2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2026-06-29 Alex Coplan + + Backported from master: + 2026-06-23 Alex Coplan + + PR target/125818 + * config/aarch64/aarch64-sve-builtins-base.cc (svset_impl::fold): Fix + unsharing to ensure the returned stmt has the exact same lhs as the + original. + +2026-06-29 Jakub Jelinek + + Backported from master: + 2026-06-27 Jakub Jelinek + + PR target/125992 + * config/s390/s390.md (*brx_stage1_): Add CC_REGNUM clobber. + +2026-06-29 Jakub Jelinek + + Backported from master: + 2026-06-06 Jakub Jelinek + + PR target/125611 + * config/i386/sse.md (_pmulhrsw3, smulhrs3): + Use vector_operand instead of nonimmediate_operand. + 2026-06-26 Release Manager * GCC 14.4.0 released. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 1d91ae1491c..264735f723d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260629 +20260630 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 15efc6faefa..584e139e0b8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,27 @@ +2026-06-29 Alex Coplan + + Backported from master: + 2026-06-23 Alex Coplan + + PR target/125818 + * gcc.target/aarch64/torture/pr125818.c: New test. + +2026-06-29 Jakub Jelinek + + Backported from master: + 2026-06-27 Jakub Jelinek + + PR target/125992 + * gcc.target/s390/pr125992.c: New test. + +2026-06-29 Jakub Jelinek + + Backported from master: + 2026-06-06 Jakub Jelinek + + PR target/125611 + * gcc.target/i386/ssse3-pr125611.c: New test. + 2026-06-27 Patrick Palka Backported from master: commit 8428a582e5f3a72ed28af3affed30239c74cbd80 Author: Kyrylo Tkachov Date: Mon Apr 20 00:56:01 2026 -0700 aarch64: PR124908 Fix ICE in svld1rq fold with -msve-vector-bits=128 svld1rq is a replicated-quadword load: it loads 16 bytes and replicates them to fill the SVE register. When -msve-vector-bits=128 the instruction can be folded to a normal load. The GIMPLE fold for svld1rq transforms the intrinsic into a 128-bit memory load followed by a VEC_PERM_EXPR that replicates the loaded value. When VL == 128, the VEC_PERM_EXPR becomes an identity permutation. The checking assertion that validates the permutation (can_vec_perm_const_p) fails for this degenerate case because the vec_perm_const hook does not recognise the cross-mode identity permutation (e.g. V16QI -> VNx16QI). Fix by detecting when the SVE vector has the same number of elements as the 128-bit quadword (known_eq (lhs_len, source_nelts)) and emitting a VIEW_CONVERT_EXPR instead of a VEC_PERM_EXPR. Bootstrapped and tested on aarch64-none-linux-gnu. Signed-off-by: Kyrylo Tkachov gcc/ChangeLog: PR target/124908 * config/aarch64/aarch64-sve-builtins-base.cc (svld1rq_impl::fold): When the SVE vector length equals the quadword width, emit VIEW_CONVERT_EXPR instead of VEC_PERM_EXPR. gcc/testsuite/ChangeLog: PR target/124908 * gcc.target/aarch64/sve/acle/general/ld1rq_2.c: New test. (cherry picked from commit b8ac2356c691f76c19246c4c7b94c23015b8b8aa) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc index 9eff2787f43..71a69765ea1 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc @@ -1590,6 +1590,20 @@ public: gimple_seq_add_stmt_without_update (&stmts, mem_ref_stmt); int source_nelts = TYPE_VECTOR_SUBPARTS (access_type).to_constant (); + + /* When the SVE vector has the same number of elements as the + 128-bit quadword (i.e. VL == 128), the load fills the entire + register and no replication is needed. Just convert the + loaded value from the Advanced SIMD type to the SVE type. */ + if (known_eq (lhs_len, (unsigned int) source_nelts)) + { + gimple *g + = gimple_build_assign (lhs, build1 (VIEW_CONVERT_EXPR, + lhs_type, mem_ref_lhs)); + gimple_seq_add_stmt_without_update (&stmts, g); + gsi_replace_with_seq_vops (f.gsi, stmts); + return g; + } vec_perm_builder sel (lhs_len, source_nelts, 1); for (int i = 0; i < source_nelts; i++) sel.quick_push (i); diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/ld1rq_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/ld1rq_2.c new file mode 100644 index 00000000000..84bf77328c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/ld1rq_2.c @@ -0,0 +1,37 @@ +/* PR target/124908 */ +/* { dg-options "-O2 -msve-vector-bits=128" } */ + +#include + +/* Verify that folding svld1rq does not ICE with -msve-vector-bits=128. */ + +svuint8_t +f_u8 (const uint8_t *p) +{ + return svld1rq_u8 (svptrue_b8 (), p); +} + +svint8_t +f_s8 (const int8_t *p) +{ + return svld1rq_s8 (svptrue_b8 (), p); +} + +svuint16_t +f_u16 (const uint16_t *p) +{ + return svld1rq_u16 (svptrue_b16 (), p); +} + +svuint32_t +f_u32 (const uint32_t *p) +{ + return svld1rq_u32 (svptrue_b32 (), p); +} + +svfloat64_t +f_f64 (const float64_t *p) +{ + return svld1rq_f64 (svptrue_b64 (), p); +} + commit 956bc995a904df30b510801de68b71965e747cc5 Author: Stefan Schulze Frielinghaus Date: Fri Jun 12 11:15:14 2026 +0200 ira: Allow multiple uses within an insn [PR125173] For the attached test we end up during IRA with 6: r99:DI=`s' REG_EQUIV `s' 7: {[`b']=asm_operands; [const(`s'+0x4)]=asm_operands; [`a']=asm_operands;clobber flags:CC;} REG_DEAD r99:DI REG_UNUSED flags:CC where r99 is used in each asm_operands (mem/c:SI (plus:DI (reg/f:DI 99) (const_int 4 [0x4])) [2 s.d+0 S4 A32]) This in turn means that we hit multiple times the very same insn while iterating over all uses of r99 which in the end triggers the assert. This patch relaxes the assert since what we want to ensure here is that a register is not used by multiple insns since otherwise we cannot trivially move or delete the definition. PR rtl-optimization/125173 gcc/ChangeLog: * ira.cc (combine_and_move_insns): Allow multiple uses within an insn. gcc/testsuite/ChangeLog: * gcc.dg/pr125173-1.c: New test. (cherry picked from commit 107d2ad166d09883b43ec1a5cf1e37c68b134a93) diff --git a/gcc/ira.cc b/gcc/ira.cc index 5642aea3caa..1619259ec04 100644 --- a/gcc/ira.cc +++ b/gcc/ira.cc @@ -3908,6 +3908,7 @@ combine_and_move_insns (void) continue; rtx_insn *use_insn = 0; + bool multiple_insns = false; for (df_ref use = DF_REG_USE_CHAIN (regno); use; use = DF_REF_NEXT_REG (use)) @@ -3915,11 +3916,20 @@ combine_and_move_insns (void) { if (DEBUG_INSN_P (DF_REF_INSN (use))) continue; - gcc_assert (!use_insn); + if (use_insn && DF_REF_INSN (use) != use_insn) + { + multiple_insns = true; + break; + } use_insn = DF_REF_INSN (use); } gcc_assert (use_insn); + /* If a register is used by more than one insn, we cannot trivially move + or delete the definition anymore. */ + if (multiple_insns) + continue; + /* Don't substitute into jumps. indirect_jump_optimize does this for anything we are prepared to handle. */ if (JUMP_P (use_insn)) diff --git a/gcc/testsuite/gcc.dg/pr125173-1.c b/gcc/testsuite/gcc.dg/pr125173-1.c new file mode 100644 index 00000000000..5f66b24fcb0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr125173-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-fuse-ops-with-volatile-access -fno-forward-propagate --param=max-cse-insns=0" } */ + +int a; +volatile short b; + +struct +{ + char c; + int d; +} s; + +void +foo () +{ + __asm__ ("":"+m" (b), "+m" (s.d), "+m" (a)); +} commit af09980fdcd18bf9989514a739d5cafbda0ffee4 Author: GCC Administrator Date: Wed Jul 1 00:19:54 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3af80e852b2..112762190f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2026-06-30 Stefan Schulze Frielinghaus + + Backported from master: + 2026-06-12 Stefan Schulze Frielinghaus + + PR rtl-optimization/125173 + * ira.cc (combine_and_move_insns): Allow multiple uses within + an insn. + +2026-06-30 Kyrylo Tkachov + + Backported from master: + 2026-04-22 Kyrylo Tkachov + + PR target/124908 + * config/aarch64/aarch64-sve-builtins-base.cc + (svld1rq_impl::fold): When the SVE vector length equals the + quadword width, emit VIEW_CONVERT_EXPR instead of VEC_PERM_EXPR. + 2026-06-29 Alex Coplan Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 264735f723d..e74af993156 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260630 +20260701 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 584e139e0b8..4f811d66db8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2026-06-30 Stefan Schulze Frielinghaus + + Backported from master: + 2026-06-12 Stefan Schulze Frielinghaus + + PR rtl-optimization/125173 + * gcc.dg/pr125173-1.c: New test. + +2026-06-30 Kyrylo Tkachov + + Backported from master: + 2026-04-22 Kyrylo Tkachov + + PR target/124908 + * gcc.target/aarch64/sve/acle/general/ld1rq_2.c: New test. + 2026-06-29 Alex Coplan Backported from master: commit 96a242d46e4d57e41b7748469c6236a35eca7916 Author: Eric Botcazou Date: Wed Jul 1 10:23:46 2026 +0200 PTA: Fix wrong optimization of conditional dynamic allocation This is a regression present on mainline, 16, 15 and 14 branches introduced by the fix for PR tree-optimization/112653 (PTA and return). What happens is that DSE incorrectly eliminates a call to memcpy, whose destination is obtained from (an equivalent of) malloc and is ultimately returned from the function. But this happens only when the dynamic allocation is conditional. The difference between the unconditional and conditional cases is: ESCAPED_RETURN = { ESCAPED NONLOCAL HEAP(30) } vs ESCAPED_RETURN = { ANYTHING } The fix is to apply in set_uids_in_ptset the same treatment to ANYTHING in the escaped return case as in the escaped case. gcc/ * tree-ssa-structalias.cc (set_uids_in_ptset): If ANYTHING is present in the ESCAPED_RETURN solution, record that the global solution has an escaped heap if FROM contains a heap variable. gcc/testsuite/ * gnat.dg/opt109.adb: New test. * gnat.dg/opt109_pkg.ads, gnat.dg/opt109_pkg.adb: New helper. diff --git a/gcc/testsuite/gnat.dg/opt109.adb b/gcc/testsuite/gnat.dg/opt109.adb new file mode 100644 index 00000000000..caa9e587123 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt109.adb @@ -0,0 +1,13 @@ +-- { dg-do run } +-- { dg-options "-O" } + +with Opt109_Pkg; use Opt109_Pkg; + +procedure Opt109 is + S : constant String := "Hello World!"; + R : constant Rec := F (S); +begin + if R.B.Data.all /= S then + raise Program_Error; + end if; +end; diff --git a/gcc/testsuite/gnat.dg/opt109_pkg.adb b/gcc/testsuite/gnat.dg/opt109_pkg.adb new file mode 100644 index 00000000000..410a3e41755 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt109_pkg.adb @@ -0,0 +1,16 @@ +package body Opt109_Pkg is + + function F (Value : String) return Rec is + begin + if Value'Length > Max then + return Result : Rec (Is_Small => False) do + Result.B.Data := new String'(Value); + end return; + else + return Result : Rec (Is_Small => True) do + Result.S.Data (Value'Length + 1 .. Max) := (others => ' '); + end return; + end if; + end; + +end Opt109_Pkg; diff --git a/gcc/testsuite/gnat.dg/opt109_pkg.ads b/gcc/testsuite/gnat.dg/opt109_pkg.ads new file mode 100644 index 00000000000..0e483ed40c7 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt109_pkg.ads @@ -0,0 +1,33 @@ +with System; + +package Opt109_Pkg is + + Max : constant Natural := 7; + subtype Small_String_Size is Natural range 0 .. Max; + + type Small_String is record + Is_Small : Boolean; + Length : Small_String_Size; + Data : aliased String (1 .. Max); + end record; + + type Big_String_Access is access all String; + + type Big_String is record + Data : Big_String_Access := null; + end record; + + for Big_String use record + Data at 0 range 0 .. System.Word_Size - 1; + end record; + + type Rec (Is_Small : Boolean := True) is record + case Is_Small is + when True => S : Small_String; + when False => B : Big_String; + end case; + end record with Unchecked_Union; + + function F (Value : String) return Rec; + +end Opt109_Pkg; diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc index ab44a28235f..87c8f9bd95a 100644 --- a/gcc/tree-ssa-structalias.cc +++ b/gcc/tree-ssa-structalias.cc @@ -6660,12 +6660,15 @@ static void set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt, tree fndecl) { + const varinfo_t escaped_vi = get_varinfo (find (escaped_id)); + const varinfo_t escaped_return_vi = get_varinfo (find (escaped_return_id)); + const bool everything_escaped + = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id); + const bool everything_escaped_return + = escaped_return_vi->solution + && bitmap_bit_p (escaped_return_vi->solution, anything_id); unsigned int i; bitmap_iterator bi; - varinfo_t escaped_vi = get_varinfo (find (escaped_id)); - varinfo_t escaped_return_vi = get_varinfo (find (escaped_return_id)); - bool everything_escaped - = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id); EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi) { @@ -6681,8 +6684,10 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt, pt->vars_contains_escaped = true; pt->vars_contains_escaped_heap |= vi->is_heap_var; } - if (escaped_return_vi->solution - && bitmap_bit_p (escaped_return_vi->solution, i)) + + if (everything_escaped_return + || (escaped_return_vi->solution + && bitmap_bit_p (escaped_return_vi->solution, i))) pt->vars_contains_escaped_heap |= vi->is_heap_var; if (vi->is_restrict_var) commit 022e5449d2b31930999ef63dd3d2dc31ba47a3d4 Author: Stefan Schulze Frielinghaus Date: Fri Jun 26 16:46:48 2026 +0200 s390: Deal with non-compare conditions during RTX costing [PR125972] During cprop we have to cost intermediate RTXs which may have non-compare conditions as e.g. r108={(0x1)?r113:r109} which get folded later on. First seen with r16-5417-g97a7d568f3d720. PR target/125972 gcc/ChangeLog: * config/s390/s390.cc (s390_rtx_costs): Deal with non-compare conditions during costing. Also fix some indentation. gcc/testsuite/ChangeLog: * gcc.target/s390/pr125972.c: New test. (cherry picked from commit f070b1aaa0f87dc6405a1840581c17c005a1f5b1) diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 9f09f0a3e1e..47515d1b3e8 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -3777,13 +3777,15 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code, case MEM: *total = 0; return true; - case SET: { + case SET: + { rtx dst = SET_DEST (x); rtx src = SET_SRC (x); switch (GET_CODE (src)) { - case IF_THEN_ELSE: { + case IF_THEN_ELSE: + { /* Without this a conditional move instruction would be accounted as 3 * COSTS_N_INSNS (set, if_then_else, comparison operator). That's a bit pessimistic. */ @@ -3792,6 +3794,12 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code, return false; rtx cond = XEXP (src, 0); + /* Intermediate RTXs may have a non-compare condition as e.g. a + constant like r108={(0x1)?r113:r109} which get folded later + on. */ + if (GET_RTX_CLASS (GET_CODE (cond)) != RTX_COMPARE + && GET_RTX_CLASS (GET_CODE (cond)) != RTX_COMM_COMPARE) + return false; if (!CC_REG_P (XEXP (cond, 0)) || !CONST_INT_P (XEXP (cond, 1))) return false; @@ -3850,7 +3858,8 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code, /* Otherwise just cost the src. */ *total += rtx_cost (src, mode, SET, 1, speed); return true; - case MEM: { + case MEM: + { rtx address = XEXP (dst, 0); rtx tmp; HOST_WIDE_INT tmp2; diff --git a/gcc/testsuite/gcc.target/s390/pr125972.c b/gcc/testsuite/gcc.target/s390/pr125972.c new file mode 100644 index 00000000000..a7180477c3b --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr125972.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-march=z16 -O3" } */ + +int a, b, c; +long d, e; +int *f; +__int128 g; +void h() { + g = 0; + for (; g <= 33; ++g) { + int *i = &c; + *i = d - a; + if (*i) { + c = 0; + for (; c <= 8; ++c) + f = &b; + } else + ++e; + } +} commit 0bc11088d13c06c2202f5b2275150d1a680ea726 Author: GCC Administrator Date: Thu Jul 2 00:19:56 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 112762190f4..191f578516f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2026-07-01 Stefan Schulze Frielinghaus + + Backported from master: + 2026-06-26 Stefan Schulze Frielinghaus + + PR target/125972 + * config/s390/s390.cc (s390_rtx_costs): Deal with non-compare + conditions during costing. Also fix some indentation. + +2026-07-01 Eric Botcazou + + * tree-ssa-structalias.cc (set_uids_in_ptset): If ANYTHING is + present in the ESCAPED_RETURN solution, record that the global + solution has an escaped heap if FROM contains a heap variable. + 2026-06-30 Stefan Schulze Frielinghaus Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e74af993156..ad088ccf4d9 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260701 +20260702 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4f811d66db8..abb0b4e8810 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2026-07-01 Stefan Schulze Frielinghaus + + Backported from master: + 2026-06-26 Stefan Schulze Frielinghaus + + PR target/125972 + * gcc.target/s390/pr125972.c: New test. + +2026-07-01 Eric Botcazou + + * gnat.dg/opt109.adb: New test. + * gnat.dg/opt109_pkg.ads, gnat.dg/opt109_pkg.adb: New helper. + 2026-06-30 Stefan Schulze Frielinghaus Backported from master: commit aa6624aaf260f5f5da65a77274439ca7e34be2f5 Author: GCC Administrator Date: Fri Jul 3 00:19:54 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ad088ccf4d9..e0b5151540e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260702 +20260703 commit 47df36a07bc715b59ce76d6d10461bfb3a146cb5 Author: Stefan Schulze Frielinghaus Date: Fri Jul 3 18:07:23 2026 +0200 testsuite: Fix up gcc.dg/pr125173-1.c [PR125173] Option -fno-fuse-ops-with-volatile-access is only available since GCC 16 and shouldn't have been backported. The test is still meaningful for GCC 14 in the sense that it still works as a reproducer for an ICE without patch r14.4.0-17-g956bc995a90 and shows that the ICE is fixed by it. PR rtl-optimization/125173 gcc/testsuite/ChangeLog: * gcc.dg/pr125173-1.c: Remove option -fno-fuse-ops-with-volatile-access. diff --git a/gcc/testsuite/gcc.dg/pr125173-1.c b/gcc/testsuite/gcc.dg/pr125173-1.c index 5f66b24fcb0..4616a54e86a 100644 --- a/gcc/testsuite/gcc.dg/pr125173-1.c +++ b/gcc/testsuite/gcc.dg/pr125173-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fno-fuse-ops-with-volatile-access -fno-forward-propagate --param=max-cse-insns=0" } */ +/* { dg-options "-O1 -fno-forward-propagate --param=max-cse-insns=0" } */ int a; volatile short b; commit 7cef30f480b2b602c5be7cafcad0a63148f3f7b7 Author: GCC Administrator Date: Sat Jul 4 00:19:49 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e0b5151540e..d8351f019a6 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260703 +20260704 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index abb0b4e8810..e4203ae2b1e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2026-07-03 Stefan Schulze Frielinghaus + + PR rtl-optimization/125173 + * gcc.dg/pr125173-1.c: Remove option + -fno-fuse-ops-with-volatile-access. + 2026-07-01 Stefan Schulze Frielinghaus Backported from master: commit 97c1e21cf21365246cbe4dd78fef13e4650ace03 Author: GCC Administrator Date: Sun Jul 5 00:19:51 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index d8351f019a6..89679752866 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260704 +20260705 commit e1b871032e08928a0a3fc5218ecf4ca96376bff8 Author: Oleg Endo Date: Sat Jul 4 01:22:41 2026 +0900 SH: Fix T bit set expressions of addc and subc insns. gcc/ChangeLog: PR target/67459 PR target/122948 * config/sh/sh.md (addc): Fix T bit set expression. (subc): Likewise. gcc/testsuite/ChangeLog: PR target/67459 PR target/122948 * gcc.target/sh/pr122948.c: New test. diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 19481c07db6..dbff2a805f3 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -1563,7 +1563,10 @@ (match_operand:SI 2 "arith_reg_operand" "r")) (reg:SI T_REG))) (set (reg:SI T_REG) - (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))] + (gtu:SI (plus:DI (plus:DI (zero_extend:DI (match_dup 1)) + (zero_extend:DI (match_dup 2))) + (zero_extend:DI (reg:SI T_REG))) + (const_int 4294967295)))] "TARGET_SH1" "addc %2,%0" [(set_attr "type" "arith")]) @@ -1955,9 +1958,9 @@ (match_operand:SI 2 "arith_reg_operand" "r")) (reg:SI T_REG))) (set (reg:SI T_REG) - (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2)) - (reg:SI T_REG)) - (match_dup 1)))] + (gtu:SI (plus:DI (zero_extend:DI (match_dup 2)) + (zero_extend:DI (reg:SI T_REG))) + (zero_extend:DI (match_dup 1))))] "TARGET_SH1" "subc %2,%0" [(set_attr "type" "arith")]) diff --git a/gcc/testsuite/gcc.target/sh/pr122948.c b/gcc/testsuite/gcc.target/sh/pr122948.c new file mode 100644 index 00000000000..91732b67d29 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr122948.c @@ -0,0 +1,67 @@ +/* Verify that the T bit (carry/borrow) set expression of the subc insn is + correct. */ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +extern void abort (void); + +__attribute__ ((noipa)) unsigned int +foo (unsigned int a, unsigned int b) +{ + if (b - a - 1 <= b) + a = 0; + return a; +} + +__attribute__ ((noipa)) unsigned int +bar (unsigned int a, unsigned int b) +{ + return (b - a - 1) > b; +} + +__attribute__ ((noipa)) unsigned int +baz (unsigned int a, unsigned int b) +{ + return (a + b + 1) <= a; +} + +int +main (void) +{ + if (foo (0xffffffff, 0x4e92c833) != 0) + abort (); + + if (bar (0xffffffff, 0x4e92c833) != 0) + abort (); + + /* b - a - 1 wraps (borrow) whenever a + 1 > b (unsigned). */ + if (bar (5, 3) != 1) + abort (); + + if (bar (0, 0) != 1) + abort (); + + if (bar (0, 5) != 0) + abort (); + + /* addc carry-out: (a + b + 1) <= a. */ + /* 0xffffffff + 0 + 1 wraps to 0. */ + if (baz (0xffffffff, 0) != 1) + abort (); + + if (baz (0xffffffff, 0xffffffff) != 1) + abort (); + + /* wraps to 0. */ + if (baz (0xfffffffe, 1) != 1) + abort (); + + /* 1 <= 0 is false. */ + if (baz (0, 0) != 0) + abort (); + + if (baz (1, 2) != 0) + abort (); + + return 0; +} commit 76fde0211a198145455e5d10ec94f924c0cf1e2d Author: GCC Administrator Date: Mon Jul 6 00:19:51 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 191f578516f..a7deb6bcb82 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2026-07-05 Oleg Endo + + PR target/67459 + PR target/122948 + * config/sh/sh.md (addc): Fix T bit set expression. + (subc): Likewise. + 2026-07-01 Stefan Schulze Frielinghaus Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 89679752866..5a8d94039f1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260705 +20260706 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e4203ae2b1e..822e8e191fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2026-07-05 Oleg Endo + + PR target/67459 + PR target/122948 + * gcc.target/sh/pr122948.c: New test. + 2026-07-03 Stefan Schulze Frielinghaus PR rtl-optimization/125173 commit 0a2cc892fd4034627349e5c009737f9f1d093674 Author: GCC Administrator Date: Tue Jul 7 00:18:58 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 5a8d94039f1..a4e14241298 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260706 +20260707 commit 2e8c8ce8e1308e896790ff2a4ca110657a082b6e Author: Icenowy Zheng Date: Wed Jul 1 00:11:42 2026 +0800 RISC-V: Change initial value for fmin/fmax autovec reduce [PR126049] Currently the auto-vectorization of C fmin()/fmax() uses infinity/-infinity as the initial value for reduction, which introduces bogus infinity values when iterating over an array with only NaNs. As all C fmin()/fmax(), RV F/D fmin/fmax, RVV vfmin/vfmax and RVV vfredmin/vfredmax are implementing the IEEE754 minimumNumber or maximumNumber behavior, an initial value of NaN is more suitable than infinity when reducing the vector (if the input vector is all NaN, the result will still be NaN and if the input vector contains non-NaN elements they will cover the initial NaN). Change the initial value during reduction from corresponding inf to a quiet NaN. PR target/126049 gcc/ChangeLog: * config/riscv/autovec.md: Change fmin/fmax reduction initial value from inf/-inf to NaN for proper semantics of corresponding C funtion. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr126049.c: New. (cherry picked from commit ad45faeb14a4acb551ecbb61bc1b0e1f6ce500b0) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 12107e2d152..2e56b9c1b81 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -2301,7 +2301,7 @@ "TARGET_VECTOR && !HONOR_SNANS (mode)" { REAL_VALUE_TYPE rv; - real_inf (&rv, true); + real_nan (&rv, "", 1, VOIDmode); rtx f = const_double_from_real_value (rv, mode); riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, UNSPEC_REDUC_MAX_VL0_SAFE, @@ -2316,7 +2316,7 @@ "TARGET_VECTOR && !HONOR_SNANS (mode)" { REAL_VALUE_TYPE rv; - real_inf (&rv, false); + real_nan (&rv, "", 1, VOIDmode); rtx f = const_double_from_real_value (rv, mode); riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, UNSPEC_REDUC_MIN_VL0_SAFE, diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126049.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126049.c new file mode 100644 index 00000000000..1fab4466525 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126049.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-require-effective-target riscv_v_ok } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O2 -ftree-vectorize" } */ + +#define NAN (__builtin_nan("")) + +__attribute__ ((noipa)) float +maxx (float *arr, unsigned int sz) +{ + float val = NAN; + unsigned int i; + + for (i = 0; i < sz; i++) + val = __builtin_fmaxf (val, arr[i]); + + return val; +} + +int +main () +{ + float arr[] = { NAN, NAN, NAN, NAN }; + float res = maxx (arr, 4); + if (!__builtin_isnan (res)) + __builtin_abort (); +} commit 484c3df6b561ac48926076468b19f6079b39e3db Author: GCC Administrator Date: Wed Jul 8 00:18:29 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7deb6bcb82..c02bb651c9b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2026-07-07 Icenowy Zheng + + Backported from master: + 2026-07-01 Icenowy Zheng + + PR target/126049 + * config/riscv/autovec.md: Change fmin/fmax reduction initial + value from inf/-inf to NaN for proper semantics of corresponding + C funtion. + 2026-07-05 Oleg Endo PR target/67459 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index a4e14241298..60ebd5a3178 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260707 +20260708 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 822e8e191fe..106f47c8fbb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2026-07-07 Icenowy Zheng + + Backported from master: + 2026-07-01 Icenowy Zheng + + PR target/126049 + * gcc.target/riscv/rvv/autovec/pr126049.c: New. + 2026-07-05 Oleg Endo PR target/67459 commit ca5d499f72b6741cd3ff51b77711250d8af83b87 Author: GCC Administrator Date: Thu Jul 9 00:19:13 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 60ebd5a3178..76403c9887d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260708 +20260709 commit 2995f1a12ff87759fcfb93b99377ff4560c3d6f5 Author: Christopher Albert Date: Sun Mar 29 22:18:43 2026 +0200 fortran: Fix ICE in gfc_conv_array_initializer with invalid index [PR103367] An undefined variable used as an array index in a parameter initializer expression reaches gfc_conv_array_initializer after parameter substitution with an unexpected expression type, hitting gcc_unreachable(). Guard against unexpected expression types by returning a zero-filled constructor, since the frontend has already diagnosed the error. PR fortran/103367 gcc/fortran/ChangeLog: * trans-array.cc (gfc_conv_array_initializer): Return empty constructor for unexpected expression types after parameter substitution. gcc/testsuite/ChangeLog: * gfortran.dg/pr103367.f90: New test. Signed-off-by: Christopher Albert (cherry picked from commit a9a1ed349974f03e9ba32dc21cce7e20cd7119ee) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 3d3dda8f4d2..43bcd0f13dc 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -6629,6 +6629,15 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) && expr->symtree->n.sym->value) expr = expr->symtree->n.sym->value; + /* After parameter substitution the expression should be a constant, array + constructor, structure constructor, or NULL. Anything else means the + frontend already diagnosed an error; return a zero-filled array. */ + if (expr->expr_type != EXPR_CONSTANT + && expr->expr_type != EXPR_STRUCTURE + && expr->expr_type != EXPR_ARRAY + && expr->expr_type != EXPR_NULL) + return build_constructor (type, NULL); + switch (expr->expr_type) { case EXPR_CONSTANT: diff --git a/gcc/testsuite/gfortran.dg/pr103367.f90 b/gcc/testsuite/gfortran.dg/pr103367.f90 new file mode 100644 index 00000000000..c4c860c65ff --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103367.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +! +! PR fortran/103367 +! An undefined variable in a parameter array initializer reached +! gfc_conv_array_initializer and hit gcc_unreachable(). + +program p + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer :: y(1,2) = (x(b)%a) ! { dg-warning "Legacy Extension" } + print *, y +end commit f471192e6e4da5c75d3a68192777ec12e1562c85 Author: Christopher Albert Date: Wed Apr 8 22:37:11 2026 +0200 fortran: Diagnose invalid array initializer after parameter substitution [PR103367] Keep the trunk fallback from r16-8509, but turn it into a real constant-expression error instead of silently returning an empty constructor. This avoids the ICE from PR103367 without regressing the more specific diagnostics discussed in the Bugzilla follow-up. PR fortran/103367 gcc/fortran/ChangeLog: * trans-array.cc (gfc_conv_array_initializer): Emit an error for invalid residual initializer expressions before returning a safe empty constructor. gcc/testsuite/ChangeLog: * gfortran.dg/pr103367.f90: Expect a constant-expression error and prune the legacy-extension warning. Signed-off-by: Christopher Albert (cherry picked from commit 326fe37d6981c189fb0f2a5a4ab7f7a5b95ecf89) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 43bcd0f13dc..eceea31c934 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -6630,13 +6630,17 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) expr = expr->symtree->n.sym->value; /* After parameter substitution the expression should be a constant, array - constructor, structure constructor, or NULL. Anything else means the - frontend already diagnosed an error; return a zero-filled array. */ + constructor, structure constructor, or NULL. Anything else is invalid + and must not ICE later in lowering. */ if (expr->expr_type != EXPR_CONSTANT && expr->expr_type != EXPR_STRUCTURE && expr->expr_type != EXPR_ARRAY && expr->expr_type != EXPR_NULL) - return build_constructor (type, NULL); + { + gfc_error ("Array initializer at %L does not reduce to a constant " + "expression", &expr->where); + return build_constructor (type, NULL); + } switch (expr->expr_type) { diff --git a/gcc/testsuite/gfortran.dg/pr103367.f90 b/gcc/testsuite/gfortran.dg/pr103367.f90 index c4c860c65ff..e7c89b41a7c 100644 --- a/gcc/testsuite/gfortran.dg/pr103367.f90 +++ b/gcc/testsuite/gfortran.dg/pr103367.f90 @@ -1,14 +1,15 @@ ! { dg-do compile } ! ! PR fortran/103367 -! An undefined variable in a parameter array initializer reached -! gfc_conv_array_initializer and hit gcc_unreachable(). +! Invalid initialization expressions must not ICE if they survive +! semantic checking and reach array initializer lowering. program p type t integer :: a(1,2) = 3 end type type(t), parameter :: x(1) = t(4) - integer :: y(1,2) = (x(b)%a) ! { dg-warning "Legacy Extension" } + integer :: y(1,2) = (x(b)%a) ! { dg-error "does not reduce to a constant expression" } print *, y end +! { dg-prune-output "Legacy Extension: REAL array index" } commit 4b39571b19683d58fcc6a959bee190b7bb0f7798 Author: Jerry DeLisle Date: Mon Jul 6 18:30:05 2026 -0700 fortran: [PR103367] Followup patch to fix related test cases PR fortran/103367 gcc/fortran/ChangeLog: * expr.cc (simplify_const_ref): Hoist the call to remove_subobject_ref up a level. * primary.cc (gfc_match_rvalue): Don't copy the value expr if the type is an EXPR_VARIABLE. not * trans-array.cc (gfc_conv_array_initializer): Only copy the expr value if it does not have a ref. gcc/testsuite/ChangeLog: * gfortran.dg/pr103367_2.f90: New test. * gfortran.dg/pr103367_3.f90: New test. * gfortran.dg/pr103367_4.f90: New test. (cherry picked from commit b1eb6e08939a01a18724d35da3dd0098cb993ab9) diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc index c5b822ed013..2da336fe50f 100644 --- a/gcc/fortran/expr.cc +++ b/gcc/fortran/expr.cc @@ -1953,16 +1953,26 @@ simplify_const_ref (gfc_expr *p) switch (p->ref->type) { case REF_ARRAY: - switch (p->ref->u.ar.type) + /* , parameter :: x() = scalar_expr + will generate this. */ + if (p->expr_type != EXPR_ARRAY) { - case AR_ELEMENT: - /* , parameter :: x() = scalar_expr - will generate this. */ - if (p->expr_type != EXPR_ARRAY) + if (p->ref->u.ar.type == AR_ELEMENT) { - remove_subobject_ref (p, NULL); - break; + int dim; + for (dim = 0; dim < p->ref->u.ar.dimen; dim++) + if (!p->ref->u.ar.start[dim] + || p->ref->u.ar.start[dim]->expr_type != EXPR_CONSTANT) + return true; } + + remove_subobject_ref (p, NULL); + break; + } + + switch (p->ref->u.ar.type) + { + case AR_ELEMENT: if (!find_array_element (p->value.constructor, &p->ref->u.ar, &cons)) return false; diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc index 6ea0b6866a2..2e223103556 100644 --- a/gcc/fortran/primary.cc +++ b/gcc/fortran/primary.cc @@ -3764,7 +3764,8 @@ gfc_match_rvalue (gfc_expr **result) end up here. Unfortunately, sym->value->expr_type is set to EXPR_CONSTANT, and so the if () branch would be followed without the !sym->as check. */ - if (sym->value && sym->value->expr_type != EXPR_ARRAY && !sym->as) + if (sym->value && sym->value->expr_type != EXPR_ARRAY + && sym->value->expr_type != EXPR_VARIABLE && !sym->as) e = gfc_copy_expr (sym->value); else { diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index eceea31c934..36fd7edcad9 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -6626,7 +6626,8 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) if (expr->expr_type == EXPR_VARIABLE && expr->symtree->n.sym->attr.flavor == FL_PARAMETER - && expr->symtree->n.sym->value) + && expr->symtree->n.sym->value + && !expr->ref) expr = expr->symtree->n.sym->value; /* After parameter substitution the expression should be a constant, array diff --git a/gcc/testsuite/gfortran.dg/pr103367_2.f90 b/gcc/testsuite/gfortran.dg/pr103367_2.f90 new file mode 100644 index 00000000000..6a3c4f6357b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103367_2.f90 @@ -0,0 +1,37 @@ +! { dg-do compile } +subroutine s1 + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y(1,2) = (x(1)%a(m,1)) ! { dg-error "does not reduce to a constant expression" } + print *, y +end + +subroutine s2 + type t + integer :: a(2) = 3! + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y = x(1)%a(m) ! { dg-error "non-constant initialization expression" } + print *, y +end + +subroutine s3 + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y(1,2) = (x(b)%a) ! { dg-error "does not reduce to a constant expression" } + print *, y +end + +subroutine s4 + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer :: y(1,2) = x(b)%a ! { dg-error "does not reduce to a constant expression" } + print *, y +end +! { dg-prune-output "Legacy Extension: REAL array index" } diff --git a/gcc/testsuite/gfortran.dg/pr103367_3.f90 b/gcc/testsuite/gfortran.dg/pr103367_3.f90 new file mode 100644 index 00000000000..6c83e88b28d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103367_3.f90 @@ -0,0 +1,11 @@ +! { dg-do run } +! PR103367 Test case from the PR, previously segfaulted. +program p + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y(2) = x(1)%a(1,:) + if (any (y /= [4, 4])) stop 1 +end + diff --git a/gcc/testsuite/gfortran.dg/pr103367_4.f90 b/gcc/testsuite/gfortran.dg/pr103367_4.f90 new file mode 100644 index 00000000000..e0c052692cd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103367_4.f90 @@ -0,0 +1,14 @@ +! { dg-do run } +! PR103367, this test previously +! Test case from the PR segfaulted at compile time. +program p + type inner + integer :: n = 3 + end type + type outer + type(inner) :: a(2) = inner(1) + end type + type(outer), parameter :: x(1) = outer(inner(4)) + integer, parameter :: y(2) = x(1)%a%n + if (any (y /= [4, 4])) stop 1 +end commit 5dabebca2ea5a107b87b2a3b1af02b942471e73f Author: GCC Administrator Date: Fri Jul 10 00:18:38 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 76403c9887d..f3fe500bd97 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260709 +20260710 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 2c1142b1aa6..d543465b2ff 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,37 @@ +2026-07-09 Jerry DeLisle + + Backported from master: + 2026-07-07 Jerry DeLisle + + PR fortran/103367 + * expr.cc (simplify_const_ref): Hoist the call to + remove_subobject_ref up a level. + * primary.cc (gfc_match_rvalue): Don't copy the value expr + if the type is an EXPR_VARIABLE. + not + * trans-array.cc (gfc_conv_array_initializer): Only copy the expr + value if it does not have a ref. + +2026-07-09 Christopher Albert + + Backported from master: + 2026-04-09 Christopher Albert + + PR fortran/103367 + * trans-array.cc (gfc_conv_array_initializer): Emit an error for + invalid residual initializer expressions before returning a safe + empty constructor. + +2026-07-09 Christopher Albert + + Backported from master: + 2026-04-07 Christopher Albert + + PR fortran/103367 + * trans-array.cc (gfc_conv_array_initializer): Return empty + constructor for unexpected expression types after parameter + substitution. + 2026-06-26 Release Manager * GCC 14.4.0 released. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 106f47c8fbb..b05d17b7ac3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,30 @@ +2026-07-09 Jerry DeLisle + + Backported from master: + 2026-07-07 Jerry DeLisle + + PR fortran/103367 + * gfortran.dg/pr103367_2.f90: New test. + * gfortran.dg/pr103367_3.f90: New test. + * gfortran.dg/pr103367_4.f90: New test. + +2026-07-09 Christopher Albert + + Backported from master: + 2026-04-09 Christopher Albert + + PR fortran/103367 + * gfortran.dg/pr103367.f90: Expect a constant-expression error and + prune the legacy-extension warning. + +2026-07-09 Christopher Albert + + Backported from master: + 2026-04-07 Christopher Albert + + PR fortran/103367 + * gfortran.dg/pr103367.f90: New test. + 2026-07-07 Icenowy Zheng Backported from master: commit 97cc1ca7f88b0fc42e5e140f2ce9c430f7510e9c Author: GCC Administrator Date: Sat Jul 11 00:18:34 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index f3fe500bd97..97b47c66021 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260710 +20260711 commit 852498f466dd8de8b516ae659b7c4799e351247a Author: GCC Administrator Date: Sun Jul 12 00:18:29 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 97b47c66021..bbcf50646c2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260711 +20260712 commit 818e522d0fc00451241590fc0564de10bcfdac86 Author: Paul Thomas Date: Thu May 7 08:04:27 2026 +0100 Fortran: Fix complex associate-name with inferred kind [PR125172] 2026-05-07 Samir Ouchene ts from sym->ts. (resolve_assoc_var): For an inferred-type complex/character associate-name, refresh sym->ts from the resolved target when only the kind differs. gcc/testsuite PR fortran/125172 * gfortran.dg/associate_79.f90: New test. (cherry picked from commit 7cd09938f5484b2c66ca381a15f1dc8b1ecb8d01) diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index b43fd8bdfe6..f8a76545ec2 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -5927,6 +5927,13 @@ resolve_variable (gfc_expr *e) if (e->expr_type == EXPR_CONSTANT) return true; } + else if (IS_INFERRED_TYPE (e) + && sym->ts.type != BT_UNKNOWN + && (sym->ts.type != e->ts.type || sym->ts.kind != e->ts.kind)) + /* No subobject ref, but the expression's typespec was set at parse + time before the target's actual type/kind was known. Refresh from + the now-resolved associate-name symbol. */ + e->ts = sym->ts; else if (sym->attr.select_type_temporary && sym->ns->assoc_name_inferred) gfc_fixup_inferred_type_refs (e); @@ -6306,6 +6313,15 @@ gfc_fixup_inferred_type_refs (gfc_expr *e) sym->assoc->target->ts.kind); gfc_replace_expr (e, ne); } + else if (ref && ref->type == REF_INQUIRY + && (ref->u.i == INQUIRY_RE || ref->u.i == INQUIRY_IM) + && sym->ts.type == BT_COMPLEX + && e->ts.type == BT_REAL + && e->ts.kind != sym->ts.kind) + /* primary.cc set the inquiry-result kind to the default real kind + when the associate-name's type was inferred from %re/%im before + the target was resolved. Now use the (resolved) selector kind. */ + e->ts.kind = sym->ts.kind; /* Now that the references are all sorted out, set the expression rank and return. */ @@ -9551,6 +9567,16 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) /* Confirmed to be either a derived type or misidentified to be a scalar class object, when the selector is a class array. */ sym->ts = target->ts; + else if (sym->assoc->inferred_type + && (sym->ts.type == BT_COMPLEX + || sym->ts.type == BT_CHARACTER) + && target->ts.type == sym->ts.type + && sym->ts.kind != target->ts.kind) + /* The inferred type was set from a %re, %im or %len inquiry on + the associate name with the default kind, before the target's + actual type was known. Now that the target has been resolved, + update the kind to match. */ + sym->ts = target->ts; } diff --git a/gcc/testsuite/gfortran.dg/associate_79.f90 b/gcc/testsuite/gfortran.dg/associate_79.f90 new file mode 100644 index 00000000000..c7b04e0ab4b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_79.f90 @@ -0,0 +1,34 @@ +! { dg-do run } +! +! Verify that an associate-name whose target is a call to an internal +! procedure (CONTAINS in a program) gets the correct declared kind from +! the function's return type, instead of falling back to default kind. +! +program demo + use, intrinsic :: iso_fortran_env, only: wp => real64 + implicit none + complex(wp) :: z + real(wp) :: re_ref, im_ref + + z = (1.0_wp, 2.0_wp) + re_ref = real (sin (z), wp) + im_ref = aimag (sin (z)) + + associate (k => myfunc (z)) + if (kind (k%re) /= kind (1.0_wp)) stop 1 + if (kind (k%im) /= kind (1.0_wp)) stop 2 + if (kind (aimag (k)) /= kind (1.0_wp)) stop 3 + if (abs (k%re - re_ref) > 1.0e-12_wp) stop 4 + if (abs (k%im - im_ref) > 1.0e-12_wp) stop 5 + if (abs (aimag (k) - im_ref) > 1.0e-12_wp) stop 6 + end associate + +contains + + complex(wp) function myfunc (x) + complex(wp), intent(in) :: x + myfunc = sin (x) + end function myfunc + +end program demo + commit cacda2894da2513f97f2261ba8cb8db0aa45c89f Author: GCC Administrator Date: Mon Jul 13 00:18:33 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index bbcf50646c2..c5c47643d09 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260712 +20260713 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d543465b2ff..34867a95e3b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,18 @@ +2026-07-12 Paul Thomas + + Backported from master: + 2026-05-07 Paul Thomas + + PR fortran/125172 + * resolve.cc (gfc_fixup_inferred_type_refs): Update kind for + INQUIRY_RE and INQUIRY_IM references on inferred complex + associate-name. + (resolve_variable): For an inferred-type associate-name with + no subobject ref, refresh e->ts from sym->ts. + (resolve_assoc_var): For an inferred-type complex/character + associate-name, refresh sym->ts from the resolved target when + only the kind differs. + 2026-07-09 Jerry DeLisle Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b05d17b7ac3..8b6936531e3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2026-07-12 Paul Thomas + + Backported from master: + 2026-05-07 Paul Thomas + + PR fortran/125172 + * gfortran.dg/associate_79.f90: New test. + 2026-07-09 Jerry DeLisle Backported from master: commit a62d27278b033fc192d7dc4e0be572235007c89d Author: GCC Administrator Date: Tue Jul 14 00:18:36 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c5c47643d09..d5dd05aa12f 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260713 +20260714 commit 52039ea1eec23516955a15829c3bf219b6b565d7 Author: Richard Earnshaw Date: Wed Aug 21 16:15:34 2024 +0100 arm: avoid indirect sibcalls when IP is live [PR116597] On Arm only r0-r3 (the argument registers) and IP are available for use as an address for an indirect sibcall. But if all the argument registers are used and IP is clobbered during the epilogue, or is used to pass closure information, then there is no spare register to hold the address and we must reject the sibcall. arm_function_ok_for_sibcall did try to handle this, but it did this by examining the function declaration. That doesn't work if the function has no prototype, or if the prototype has variadic arguments: we must, instead, look at the list of actuals for the call rather than the list of formals. The old code also worked by laying out all the arguments and then trying to add one more integer argument at the end of the list, but this missed a corner case where a hole had been left in the argument register list due to argument alignment. We fix all of this by now scanning the list of actual values to be passed and then checking if a core register has been assigned to that argument. If it has, then we record which registers were assigned. Once done we then look to see if all the argument registers have been assigned and only block the sibcall if that is the case. This permits us to sibcall: int (*d)(int, ...); int g(void); int i () { return d(g(), 2LL);} because r1 remains free (the 2LL argument is passed in {r2,r3}). gcc/ PR target/116597 * config/arm/arm.cc (arm_function_ok_for_sibcall): Use the list of actuals for the call, not the list of formals. gcc/testsuite/ PR target/116597 * gcc.target/arm/pac-sibcall-2.c: New test. * gcc.target/arm/pac-sibcall-3.c: New test. (cherry picked from commit 670cfd5fe6433ee8f2e86eedb197d2523dbb033b) diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 7df10cd199b..bd3590ea4ad 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -8021,10 +8021,11 @@ arm_function_ok_for_sibcall (tree decl, tree exp) && DECL_WEAK (decl)) return false; - /* We cannot tailcall an indirect call by descriptor if all the call-clobbered - general registers are live (r0-r3 and ip). This can happen when: - - IP contains the static chain, or - - IP is needed for validating the PAC signature. */ + /* Indirect tailcalls need a call-clobbered register to hold the function + address. But we only have r0-r3 and ip in that class. If r0-r3 all hold + function arguments, then we can only use IP. But IP may be needed in the + epilogue (for PAC validation), or for passing the static chain. We have + to disable the tail call if nothing is available. */ if (!decl && ((CALL_EXPR_BY_DESCRIPTOR (exp) && !flag_trampolines) || arm_current_function_pac_enabled_p())) @@ -8036,18 +8037,33 @@ arm_function_ok_for_sibcall (tree decl, tree exp) arm_init_cumulative_args (&cum, fntype, NULL_RTX, NULL_TREE); cum_v = pack_cumulative_args (&cum); - for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t)) + tree arg; + call_expr_arg_iterator iter; + unsigned used_regs = 0; + + /* Layout each actual argument in turn. If it is allocated to + core regs, note which regs have been allocated. */ + FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) { - tree type = TREE_VALUE (t); - if (!VOID_TYPE_P (type)) + tree type = TREE_TYPE (arg); + function_arg_info arg_info (type, /*named=*/true); + rtx reg = arm_function_arg (cum_v, arg_info); + if (reg && REG_P (reg) + && REGNO (reg) <= LAST_ARG_REGNUM) { - function_arg_info arg (type, /*named=*/true); - arm_function_arg_advance (cum_v, arg); + /* Avoid any chance of UB here. We don't care if TYPE + is very large since it will use up all the argument regs. */ + unsigned nregs = MIN (ARM_NUM_REGS2 (GET_MODE (reg), type), + LAST_ARG_REGNUM + 1); + used_regs |= ((1 << nregs) - 1) << REGNO (reg); } + arm_function_arg_advance (cum_v, arg_info); } - function_arg_info arg (integer_type_node, /*named=*/true); - if (!arm_function_arg (cum_v, arg)) + /* We've used all the argument regs, and we know IP is live during the + epilogue for some reason, so we can't tailcall. */ + if ((used_regs & ((1 << (LAST_ARG_REGNUM + 1)) - 1)) + == ((1 << (LAST_ARG_REGNUM + 1)) - 1)) return false; } diff --git a/gcc/testsuite/gcc.target/arm/pac-sibcall-2.c b/gcc/testsuite/gcc.target/arm/pac-sibcall-2.c new file mode 100644 index 00000000000..f758e656c1f --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pac-sibcall-2.c @@ -0,0 +1,14 @@ +/* If all call-clobbered general registers are live (r0-r3, ip), disable + indirect tail-call for a PAC-enabled function. */ + +/* { dg-do compile } */ +/* { dg-require-effective-target arm_arch_v8_1m_main_pacbti_ok } */ +/* { dg-add-options arm_arch_v8_1m_main_pacbti } */ +/* { dg-additional-options "-mbranch-protection=pac-ret+leaf -O2" } */ + +void fail(void (*f)(int, ...)) +{ + f(1, 2, 3, 4); +} + +/* { dg-final { scan-assembler-not "bx\tip\t@ indirect register sibling call" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pac-sibcall-3.c b/gcc/testsuite/gcc.target/arm/pac-sibcall-3.c new file mode 100644 index 00000000000..1391718d567 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pac-sibcall-3.c @@ -0,0 +1,14 @@ +/* Although ip is not available, we can make use of a hole in the + argument list for the indirect address (r1 is unused). */ + +/* { dg-do compile } */ +/* { dg-require-effective-target arm_arch_v8_1m_main_pacbti_ok } */ +/* { dg-add-options arm_arch_v8_1m_main_pacbti } */ +/* { dg-additional-options "-mbranch-protection=pac-ret+leaf -O2 -std=c99" } */ + +void fail(void (*f)(int, ...)) +{ + f(1, 2LL); +} + +/* { dg-final { scan-assembler "bx\tr1\t@ indirect register sibling call" } } */ commit 9af0208459de10cd0c42bf8312176b0ede84d686 Author: GCC Administrator Date: Wed Jul 15 00:18:47 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c02bb651c9b..10917a11fb4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2026-07-14 Richard Earnshaw + + Backported from master: + 2024-09-11 Richard Earnshaw + + PR target/116597 + * config/arm/arm.cc (arm_function_ok_for_sibcall): Use the list of + actuals for the call, not the list of formals. + 2026-07-07 Icenowy Zheng Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index d5dd05aa12f..bac33848059 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260714 +20260715 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8b6936531e3..83dcab9365c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2026-07-14 Richard Earnshaw + + Backported from master: + 2024-09-11 Richard Earnshaw + + PR target/116597 + * gcc.target/arm/pac-sibcall-2.c: New test. + * gcc.target/arm/pac-sibcall-3.c: New test. + 2026-07-12 Paul Thomas Backported from master: commit 0e5ac71cc74b47c0c1e8cb10e554db2cc741ce7d Author: GCC Administrator Date: Thu Jul 16 00:18:48 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index bac33848059..cffc20fbe3d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260715 +20260716 commit 1d595d7a6d48107a867cd2c46e7dd8df65a4387a Author: Jeevitha Date: Wed Jul 15 22:06:12 2026 -0500 rs6000: Fix PTImode attribute handling [PR106895] PTImode is used to generate even/odd register pairs for 128-bit values. When PTImode is specified via a type attribute, compilation fails because no internal type exists to represent this mode. Introduce signed and unsigned PTImode internal builtin types to handle PTImode. These __pti_internal types are not documented, as they are not intended for direct user use. 2026-06-04 Jeevitha Palanisamy gcc/ PR target/106895 * config/rs6000/rs6000.h (enum rs6000_builtin_type_index): Add RS6000_BTI_INTPTI and RS6000_BTI_UINTPTI. (intPTI_type_internal_node, uintPTI_type_internal_node): New PTImode type macros. * config/rs6000/rs6000-builtin.cc (rs6000_init_builtins): Register signed and unsigned PTImode internal builtin types. * config/rs6000/sync.md (trunctipti2): New splitter. (extendptiti2): Likewise. (zero_extendptiti2): Likewise. gcc/testsuite/ PR target/106895 * gcc.target/powerpc/pr106895-1.c: New test. * gcc.target/powerpc/pr106895-2.c: New test. (cherry picked from commit 92bd6918a1892d36a5ad51d4be12f004cc20d931) diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index 72278367bdb..3f179e688e7 100644 --- a/gcc/config/rs6000/rs6000-builtin.cc +++ b/gcc/config/rs6000/rs6000-builtin.cc @@ -756,6 +756,21 @@ rs6000_init_builtins (void) else ieee128_float_type_node = NULL_TREE; + /* PTImode to get even/odd register pairs. */ + if (TARGET_POWERPC64) + { + intPTI_type_internal_node = make_signed_type (GET_MODE_BITSIZE (PTImode)); + SET_TYPE_MODE (intPTI_type_internal_node, PTImode); + t = build_qualified_type (intPTI_type_internal_node, TYPE_QUAL_CONST); + lang_hooks.types.register_builtin_type (intPTI_type_internal_node, + "__pti_internal"); + + uintPTI_type_internal_node = make_unsigned_type (GET_MODE_BITSIZE (PTImode)); + SET_TYPE_MODE (uintPTI_type_internal_node, PTImode); + t = build_qualified_type (uintPTI_type_internal_node, TYPE_QUAL_CONST); + lang_hooks.types.register_builtin_type (uintPTI_type_internal_node, + "__upti_internal"); + } /* Vector pair and vector quad support. */ vector_pair_type_node = make_node (OPAQUE_TYPE); SET_TYPE_MODE (vector_pair_type_node, OOmode); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 9b5cf321876..13a21b0218d 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2307,6 +2307,8 @@ enum rs6000_builtin_type_index RS6000_BTI_ptr_vector_quad, RS6000_BTI_ptr_long_long, RS6000_BTI_ptr_long_long_unsigned, + RS6000_BTI_INTPTI, + RS6000_BTI_UINTPTI, RS6000_BTI_MAX }; @@ -2351,6 +2353,8 @@ enum rs6000_builtin_type_index #define uintDI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTDI]) #define intTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTTI]) #define uintTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTTI]) +#define intPTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTPTI]) +#define uintPTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTPTI]) #define float_type_internal_node (rs6000_builtin_types[RS6000_BTI_float]) #define double_type_internal_node (rs6000_builtin_types[RS6000_BTI_double]) #define long_double_type_internal_node (rs6000_builtin_types[RS6000_BTI_long_double]) diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md index 425eff855d2..ee46ffe4871 100644 --- a/gcc/config/rs6000/sync.md +++ b/gcc/config/rs6000/sync.md @@ -198,6 +198,57 @@ DONE; }) +;; PTI and TI are both 128-bit modes; the following conversions are +;; register-class changes only, no actual truncation, sign or zero +;; extension occurs. +(define_insn_and_split "trunctipti2" + [(set (match_operand:PTI 0 "register_operand" "=r,r") + (truncate:PTI (match_operand:TI 1 "register_operand" "0,r")))] + "TARGET_POWERPC64" + "#" + "&& reload_completed" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = gen_lowpart (DImode, operands[0]); + operands[3] = gen_highpart (DImode, operands[0]); + operands[4] = gen_lowpart (DImode, operands[1]); + operands[5] = gen_highpart (DImode, operands[1]); +} +[(set_attr "length" "0,8")]) + +(define_insn_and_split "extendptiti2" + [(set (match_operand:TI 0 "register_operand" "=r,r") + (sign_extend:TI (match_operand:PTI 1 "register_operand" "0,r")))] + "TARGET_POWERPC64" + "#" + "&& reload_completed" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = gen_lowpart (DImode, operands[0]); + operands[3] = gen_highpart (DImode, operands[0]); + operands[4] = gen_lowpart (DImode, operands[1]); + operands[5] = gen_highpart (DImode, operands[1]); +} +[(set_attr "length" "0,8")]) + +(define_insn_and_split "zero_extendptiti2" + [(set (match_operand:TI 0 "register_operand" "=r,r") + (zero_extend:TI (match_operand:PTI 1 "register_operand" "0,r")))] + "TARGET_POWERPC64" + "#" + "&& reload_completed" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = gen_lowpart (DImode, operands[0]); + operands[3] = gen_highpart (DImode, operands[0]); + operands[4] = gen_lowpart (DImode, operands[1]); + operands[5] = gen_highpart (DImode, operands[1]); +} +[(set_attr "length" "0,8")]) + ;; If TARGET_PREFIXED, always use pstq rather than stq. (define_insn "store_quadpti" [(set (match_operand:PTI 0 "quad_memory_operand" "=wQ") diff --git a/gcc/testsuite/gcc.target/powerpc/pr106895-1.c b/gcc/testsuite/gcc.target/powerpc/pr106895-1.c new file mode 100644 index 00000000000..dfcafcd57e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr106895-1.c @@ -0,0 +1,16 @@ +/* PR target/106895 */ +/* { dg-do assemble } */ +/* { dg-require-effective-target int128 } */ +/* { dg-options "-O2 -save-temps" } */ + +/* Verify the following generates even/odd register pairs. */ + +typedef __int128 pti __attribute__((mode(PTI))); + +void +set128 (pti val, pti *mem) +{ + asm ("stq %1,%0" : "=m" (*mem) : "r" (val)); +} + +/* { dg-final { scan-assembler {\mstq\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr106895-2.c b/gcc/testsuite/gcc.target/powerpc/pr106895-2.c new file mode 100644 index 00000000000..db8e29c6706 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr106895-2.c @@ -0,0 +1,24 @@ +/* PR target/106895 */ +/* { dg-do run } */ +/* { dg-require-effective-target int128 } */ +/* { dg-options "-O2" } */ + +#include + +typedef __int128 ti; +typedef __int128 pti __attribute__((mode(PTI))); + +volatile ti a = 140; +volatile pti b; +volatile ti c; + +int main(void) +{ + b = (pti) a; + c = (ti) b; + + if (c != a) + abort(); + + return 0; +} commit a11b76ce4db284c4071901a3fe283be655bc74b5 Author: Jakub Jelinek Date: Fri Jun 12 22:43:06 2026 +0200 c++: Diagnose invalid type of bitfield widths in templates [PR125674] As the first testcase shows, outside of templates or when the bitfield width is not type dependent, we diagnose it in grokbitfield: if (width != error_mark_node) { /* The width must be an integer type. */ if (!type_dependent_expression_p (width) && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width))) error ("width of bit-field %qD has non-integral type %qT", value, TREE_TYPE (width)); else if (!check_for_bare_parameter_packs (width)) { /* Temporarily stash the width in DECL_BIT_FIELD_REPRESENTATIVE. check_bitfield_decl picks it from there later and sets DECL_SIZE accordingly. */ DECL_BIT_FIELD_REPRESENTATIVE (value) = width; SET_DECL_C_BIT_FIELD (value); } } Later on in check_bitfield_decl we verify it is a constant expression, folded into INTEGER_CST, non-negative etc. But during instantiation, we don't repeat that check, so only call check_bitfield_decl later on which can sometimes emit different diagnostics (so e.g. bit-field ‘D<1.0e+0>::d’ width not an integer constant instead of width of bit-field ‘D::d’ has non-integral type ‘double’ ) but what the second testcase shows, we can ICE during cxx_constant_value even before that if the type is even more problematic. The following patch fixes that by repeating the test from grokbitfield during tsubst_decl. 2026-06-12 Jakub Jelinek PR c++/125674 * pt.cc (tsubst_decl): Diagnose bit-field widths with invalid type. * g++.dg/template/bitfield5.C: New test. * g++.dg/template/bitfield6.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 50ba4a8ca7a51a72514aae55d9fb81732ef7a3bd) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 0685b21d55c..44a4b8bf476 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -15394,11 +15394,26 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, cp_apply_type_quals_to_decl (cp_type_quals (type), r); if (DECL_C_BIT_FIELD (r)) - /* For bit-fields, DECL_BIT_FIELD_REPRESENTATIVE gives the - number of bits. */ - DECL_BIT_FIELD_REPRESENTATIVE (r) - = tsubst_expr (DECL_BIT_FIELD_REPRESENTATIVE (t), args, - complain, in_decl); + { + /* For bit-fields, DECL_BIT_FIELD_REPRESENTATIVE gives the + number of bits. */ + tree width + = tsubst_expr (DECL_BIT_FIELD_REPRESENTATIVE (t), args, + complain, in_decl); + if (width + && width != error_mark_node + && !type_dependent_expression_p (width) + && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P + (TREE_TYPE (width))) + { + if (complain & tf_error) + error_at (DECL_SOURCE_LOCATION (t), + "width of bit-field %qD has non-integral " + "type %qT", r, TREE_TYPE (width)); + RETURN (error_mark_node); + } + DECL_BIT_FIELD_REPRESENTATIVE (r) = width; + } if (DECL_INITIAL (t)) { /* Set up DECL_TEMPLATE_INFO so that we can get at the diff --git a/gcc/testsuite/g++.dg/template/bitfield5.C b/gcc/testsuite/g++.dg/template/bitfield5.C new file mode 100644 index 00000000000..ba2d42ef38e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/bitfield5.C @@ -0,0 +1,16 @@ +// PR c++/125674 +// { dg-do compile { target c++20 } } + +struct A { int a : 1.; }; // { dg-error "width of bit-field 'a' has non-integral type 'double'" } +template +struct B { int b : 1.; }; // { dg-error "width of bit-field 'b' has non-integral type 'double'" } +template +struct C { T c : 1.; }; // { dg-error "width of bit-field 'c' has non-integral type 'double'" } +template +struct D { int d : N; }; // { dg-error "width of bit-field 'D::d' has non-integral type 'double'" } +template +struct E { T e : N; }; // { dg-error "width of bit-field 'E::e' has non-integral type 'double'" } +B b; +C c; +D <1.> d; +E e; diff --git a/gcc/testsuite/g++.dg/template/bitfield6.C b/gcc/testsuite/g++.dg/template/bitfield6.C new file mode 100644 index 00000000000..48763f04f47 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/bitfield6.C @@ -0,0 +1,9 @@ +// PR c++/125674 +// { dg-do compile } + +template +struct A { + int f (); + int i : f; // { dg-error "width of bit-field 'A::i' has non-integral type ''" } +}; +A a; commit c106ebf2f84d15e6033d7310fe21d193470e9751 Author: Jakub Jelinek Date: Fri Jul 3 20:45:07 2026 +0200 c++: Fix structured binding mangling during error recovery [PR126057] The following testcase ICEs during error recovery. We try to mangle a structured binding base variable, but because it has been erroneous, the mangling ICEs as it can't find the corresponding structured bindings. Now, we already have a hack in cp_finish_decomp when things are erroneous, we set assembler name to so that mangling isn't done. But we do that only for DECL_NAMESPACE_SCOPE_P bases and block scope static structured bindings can be mangled too, and during instantiation, if tsubst_decomp_names fails, we don't call cp_finish_decomp at all, so in that case we need to also avoid the mangling of the structured binding base. 2026-07-03 Jakub Jelinek PR c++/126057 * decl.cc (cp_finish_decomp): Set assembler name to during error recovery whenever TREE_STATIC rather than just DECL_NAMESPACE_SCOPE_P. * pt.cc (tsubst_stmt): If tsubst_decomp_names fails, set assembler name to . * g++.dg/cpp2a/decomp11.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 0b533aa54d375d22a34cf34e6b35c75a317d65d3) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 3497168b89a..d1775c48213 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -9340,7 +9340,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) } first = DECL_CHAIN (first); } - if (DECL_P (decl) && DECL_NAMESPACE_SCOPE_P (decl)) + if (DECL_P (decl) && TREE_STATIC (decl)) SET_DECL_ASSEMBLER_NAME (decl, get_identifier ("")); return; } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 44a4b8bf476..cafa3bbc0cf 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -18707,6 +18707,12 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl) decomp = &decomp_d; ndecl = tsubst_decomp_names (decl, pattern_decl, args, complain, in_decl, decomp); + if (ndecl == error_mark_node && TREE_STATIC (decl)) + { + /* As in cp_finish_decomp. */ + tree id = get_identifier (""); + SET_DECL_ASSEMBLER_NAME (decl, id); + } } init = tsubst_init (init, decl, args, complain, in_decl); diff --git a/gcc/testsuite/g++.dg/cpp2a/decomp11.C b/gcc/testsuite/g++.dg/cpp2a/decomp11.C new file mode 100644 index 00000000000..624cc892fc4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/decomp11.C @@ -0,0 +1,12 @@ +// PR c++/126057 +// { dg-do compile { target c++20 } } + +template +int +foo () +{ + static auto [a] = 0; // { dg-error "cannot decompose non-array non-class type 'int'" } + return 0; +} + +int a = foo (); commit 84049571efe88547ce898c636221fc8606707a5a Author: Jakub Jelinek Date: Sun Jul 5 16:47:47 2026 +0200 testsuite: Add C++ testcase for the recent PTA bug On Wed, Jul 01, 2026 at 09:47:46AM +0200, Eric Botcazou wrote: > this is a regression present on mainline, 16, 15 and 14 branches introduced by > the fix for PR tree-optimization/112653 (PTA and return). What happens is > that DSE incorrectly eliminates a call to __builtin_memcpy, whose destination > is obtained from (an equivalent of) malloc and is ultimately returned from the > function. But this happens only when the dynamic allocation is conditional. For us Ada illiterate, here is a C++ testcase which got fixed by this too. 2026-07-05 Jakub Jelinek * g++.dg/opt/20260703-1.C: New test. Reviewed-by: Richard Biener (cherry picked from commit 7da47d53d716b689784eaad20ebe26fdbb33982a) diff --git a/gcc/testsuite/g++.dg/opt/20260703-1.C b/gcc/testsuite/g++.dg/opt/20260703-1.C new file mode 100644 index 00000000000..007f3d2f112 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/20260703-1.C @@ -0,0 +1,46 @@ +// This started to be miscompiled with r15-579 or in a larger +// test with r15-3956 and got fixed with r17-2039. +// DSE would optimize away the store of 42. +// { dg-do run { target c++11 } } +// { dg-options "-O2" } + +struct B { }; + +void *volatile g; + +template +struct D { T foo (void) const { return (T) g; } }; + +struct G : public B +{ + virtual B *bar (int); + struct H : public B { H () : h (42) {} int h; }; + struct I : public B {}; + D g; +}; + +struct H : public G { virtual B *bar (int) { return nullptr; } }; + +B * +G::bar (int x) +{ + if (x == 0) + return new H (); + I *y = g.foo (); + return y; +} + +[[gnu::noipa]] B * +baz (G *x, int y) +{ + return x->bar (y); +} + +int +main () +{ + G g; + G::H *h = (G::H *) baz (&g, 0); + if (h->h != 42) + __builtin_abort (); +} commit f656c3987286673082dfa3a98b729a41d890b496 Author: Jakub Jelinek Date: Tue Jul 14 10:37:03 2026 +0200 cfgexpand: Align the whole asan var block to crtl->stack_alignment_needed [PR120201] If crtl->stack_alignment_needed / BITS_PER_UNIT is larger than data.asan_alignb, we can end up with misaligned stack for further allocations (e.g. to spill SSA_NAMEs with vector modes and large alignment). This patch increments data.asan_alignb in that case. 2026-07-14 Jakub Jelinek H.J. Lu PR tree-optimization/120201 * cfgexpand.cc (expand_used_vars): Set data.asan_alignb to maximum of itself and crtl->stack_alignment_needed / BITS_PER_UNIT. * g++.dg/asan/pr120201-1.C: New test. Signed-off-by: H.J. Lu (cherry picked from commit 0f485cf70171a41ea39deec0a8b65aad0b9d2a9b) diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index 2e09d11e994..d495dc8f55e 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -2389,6 +2389,9 @@ expand_used_vars (bitmap forced_stack_vars) HOST_WIDE_INT offset, sz, redzonesz; redzonesz = ASAN_RED_ZONE_SIZE; sz = data.asan_vec[0] - prev_offset; + data.asan_alignb = MAX (data.asan_alignb, + crtl->stack_alignment_needed + / BITS_PER_UNIT); if (data.asan_alignb > ASAN_RED_ZONE_SIZE && data.asan_alignb <= 4096 && sz + ASAN_RED_ZONE_SIZE >= (int) data.asan_alignb) diff --git a/gcc/testsuite/g++.dg/asan/pr120201-1.C b/gcc/testsuite/g++.dg/asan/pr120201-1.C new file mode 100644 index 00000000000..7a1a748f014 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/pr120201-1.C @@ -0,0 +1,42 @@ +// { dg-do run } +// { dg-options "-O3 -std=c++23 -fsanitize=address" } + +using size_t = decltype (sizeof 0); + +float* shaderLightData; + +using ShaderShadowTransform = float[4z * 4z * 6z]; +using Transform = float[4 * 4]; + +__attribute__ ((noipa)) +#if defined(__i386__) || defined(__x86_64__) +__attribute__ ((target ("arch=x86-64-v4"))) +#endif +static void +do_test (void) +{ + int lightCount = 3; + ShaderShadowTransform* shaderShadowData = new ShaderShadowTransform[lightCount]; + for (int index = 0; index < lightCount; index++) + { + Transform transforms[6]; + + const size_t matSize = 4z * 4z; + float* transformBlockStart = shaderShadowData[index]; + for (int face = 0; face < 6; face++) + __builtin_memcpy(transformBlockStart + (matSize * face), + &transforms[face][0], matSize * sizeof(float)); + } + + delete [] shaderShadowData; +} + +int +main (void) +{ +#if defined(__i386__) || defined(__x86_64__) + if (__builtin_cpu_supports ("x86-64-v4")) +#endif + do_test (); + return 0; +} commit 0d60b63b8310f8c6cd32518f4e3fb1123cafd24f Author: Jakub Jelinek Date: Tue Jul 14 10:39:55 2026 +0200 bitintlower: Handle .ASAN_POISON and .ASAN_POISON_USE with large/huge _BitInt [PR126084] If we have .ASAN_MARK (UNPOISON, &a, 24); .ASAN_MARK (UNPOISON, &b, 24); p_7 = &a; q_8 = &b; .ASAN_MARK (POISON, &a, 24); .ASAN_MARK (POISON, &b, 24); _1 = *p_7; _2 = *q_8; _3 = _1 + _2; = _3; return ; or .ASAN_MARK (UNPOISON, &a, 24); .ASAN_MARK (UNPOISON, &b, 24); p_4 = &a; q_5 = &b; .ASAN_MARK (POISON, &a, 24); .ASAN_MARK (POISON, &b, 24); *p_4 = 1; *q_5 = 2; return; which represent load or store uses after scope and decide not to make the vars addressable anymore, we turn that into a_10 = .ASAN_POISON (); b_11 = .ASAN_POISON (); _1 = a_10 + b_11; = _1; return ; or a_8 = .ASAN_POISON (); b_9 = .ASAN_POISON (); .ASAN_POISON_USE (a_8); .ASAN_POISON_USE (b_9); return; These 2 internal fns are something that is normally lowere during sanopt. Now, if the involved vars are large/huge _BitInt, the bitintlower pass doesn't handle them and we end up with invalid IL (we try to change the lhs of .ASAN_POISON from SSA_NAME to a var etc. which violates what sanopt expects and get an extra .ASAN_POISON_USE while doing that etc. I thought what would be the best way to deal with these, e.g. try to replace them with something tracking just one limb in those (although it is nicer to report the proper sizes in asan rather than just small part of it), but the .ASAN_POISON () uses can be also PHI args and some PHI args could be .ASAN_POISON () uses while others could be unrelated SSA_NAMEs, so we'd need to change those uses to be extensions from the .ASAN_POISONed limb into full size on all edges and what to do with abnormal edges etc. So, in the end I've decided instead to just perform what sanopt pass does for these 2 ifns if large/huge _BitInt is involved at the start of the bitintlower pass (similarly how we lower switches there). The asan.cc changes are needed so that we can properly report 24 bytes or 568 bytes etc. READs or WRITEs after scope. 2026-07-14 Jakub Jelinek PR middle-end/126084 * gimple-lower-bitint.cc: Include "attribs.h" and "asan.h". (gimple_lower_bitint): Use asan_expand_poison_ifn to lower .ASAN_POISON calls with large/huge _BitInt lhs. * asan.cc (report_error_func): Set *nargs and use _n builtin even if size is not a power of two or larger than 16. (asan_expand_poison_ifn): Handle nargs == 2. * gcc.dg/asan/bitint-1.c: New test. * gcc.dg/asan/bitint-2.c: New test. Reviewed-by: Richard Biener (cherry picked from commit 8837b1d542fb685da3b36176a0bd82a46f472b80) diff --git a/gcc/asan.cc b/gcc/asan.cc index 268bb9fe070..b19be889982 100644 --- a/gcc/asan.cc +++ b/gcc/asan.cc @@ -2379,8 +2379,13 @@ report_error_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes, *nargs = 2; return builtin_decl_implicit (report[recover_p][is_store][5]); } - *nargs = 1; int size_log2 = exact_log2 (size_in_bytes); + if (size_log2 == -1 || size_log2 >= 5) + { + *nargs = 2; + return builtin_decl_implicit (report[recover_p][is_store][5]); + } + *nargs = 1; return builtin_decl_implicit (report[recover_p][is_store][size_log2]); } @@ -4219,8 +4224,12 @@ asan_expand_poison_ifn (gimple_stmt_iterator *iter, { tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size), &nargs); - call = gimple_build_call (fun, 1, - build_fold_addr_expr (shadow_var)); + call = gimple_build_call (fun, nargs, + build_fold_addr_expr (shadow_var), + nargs == 2 + ? fold_convert (pointer_sized_int_node, + size) + : NULL_TREE); } gimple_set_location (call, gimple_location (use)); gimple *call_to_insert = call; diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 7399587d16b..05f7e929106 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -56,6 +56,8 @@ along with GCC; see the file COPYING3. If not see #include "ubsan.h" #include "stor-layout.h" #include "gimple-lower-bitint.h" +#include "attribs.h" +#include "asan.h" /* Split BITINT_TYPE precisions in 4 categories. Small _BitInt, where target hook says it is a single limb, middle _BitInt which per ABI @@ -6175,6 +6177,40 @@ gimple_lower_bitint (void) } } + if (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_HWADDRESS)) + { + hash_map shadow_vars_mapping; + bool need_commit_edge_insert = false; + bool any_asan_poison = false; + for (unsigned j = 0; j < num_ssa_names; ++j) + { + tree s = ssa_name (j); + if (s == NULL) + continue; + tree type = TREE_TYPE (s); + if (BITINT_TYPE_P (type) + && gimple_call_internal_p (SSA_NAME_DEF_STMT (s), + IFN_ASAN_POISON) + && bitint_precision_kind (type) >= bitint_prec_large) + { + any_asan_poison = true; + gimple_stmt_iterator gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (s)); + asan_expand_poison_ifn (&gsi, &need_commit_edge_insert, + shadow_vars_mapping); + } + } + if (any_asan_poison) + { + if (need_commit_edge_insert) + gsi_commit_edge_inserts (); + i = 0; + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + mark_virtual_operands_for_renaming (cfun); + cleanup_tree_cfg (TODO_update_ssa); + } + } + struct bitint_large_huge large_huge; bool has_large_huge_parm_result = false; bool has_large_huge = false; diff --git a/gcc/testsuite/gcc.dg/asan/bitint-1.c b/gcc/testsuite/gcc.dg/asan/bitint-1.c new file mode 100644 index 00000000000..8f32f1f421d --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/bitint-1.c @@ -0,0 +1,26 @@ +/* PR middle-end/126084 */ +/* { dg-do run { target bitint575 } } */ +/* { dg-shouldfail "asan" } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ + +_BitInt(135) +foo () +{ + _BitInt(135) *p, *q; + { + _BitInt(135) a, b; + p = &a; + q = &b; + } + return *p + *q; +} + +int +main () +{ + volatile _BitInt(135) x = foo (); +} + +/* { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" } */ +/* { dg-output "READ of size .*" } */ +/* { dg-output ".*'a' \\(line 11\\) <== Memory access at offset \[0-9\]* is inside this variable.*" } */ diff --git a/gcc/testsuite/gcc.dg/asan/bitint-2.c b/gcc/testsuite/gcc.dg/asan/bitint-2.c new file mode 100644 index 00000000000..47048449e30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/bitint-2.c @@ -0,0 +1,27 @@ +/* PR middle-end/126084 */ +/* { dg-do run { target bitint575 } } */ +/* { dg-shouldfail "asan" } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ + +void +foo () +{ + _BitInt(135) *p, *q; + { + _BitInt(135) a, b; + p = &a; + q = &b; + } + *p = 1; + *q = 2; +} + +int +main () +{ + foo (); +} + +/* { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" } */ +/* { dg-output "WRITE of size .*" } */ +/* { dg-output ".*'a' \\(line 11\\) <== Memory access at offset \[0-9\]* is inside this variable.*" } */ commit 097433757515c05313a6e26d1b87cf1b5758aebc Author: Jakub Jelinek Date: Wed Jul 15 10:27:56 2026 +0200 match.pd: Guard x+x -> x*2 simplification [PR126257] The x+x -> x*2 simplication obviously requires that 2 is representable in type, so that rules out unsigned _BitInt(1) and signed _BitInt(2) (and 1 too in C2Y, ditto unsigned:1 and signed:2 and :1), otherwise we don't multiply by 2 but by 0 or -2. While perhaps we could transform in those cases x+x to x<<1, I'm not convinced it is worth it. 2026-07-15 Jakub Jelinek PR tree-optimization/126257 * match.pd (x+x -> x*2): Only optimize if 2 is representable in the type. * gcc.dg/torture/bitint-101.c: New test. Reviewed-by: Richard Biener (cherry picked from commit d5059b35e03e63c7686288c3554c2922a2c37468) diff --git a/gcc/match.pd b/gcc/match.pd index d1b11483520..2ab43a773b3 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4940,7 +4940,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (plus @0 @0) (if (SCALAR_FLOAT_TYPE_P (type)) (mult @0 { build_real (type, dconst2); }) - (if (INTEGRAL_TYPE_P (type)) + (if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) > (2 - TYPE_UNSIGNED (type))) (mult @0 { build_int_cst (type, 2); })))) /* 0 - X -> -X. */ diff --git a/gcc/testsuite/gcc.dg/torture/bitint-101.c b/gcc/testsuite/gcc.dg/torture/bitint-101.c new file mode 100644 index 00000000000..42f3998ccbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-101.c @@ -0,0 +1,27 @@ +/* PR tree-optimization/126257 */ +/* { dg-do run } */ +/* { dg-additional-options "-std=c23" } */ + +_BitInt(2) a; +long long b, c, d; + +int +main () +{ + int e; + _BitInt(2) f; + bool g; + long long h = b; +lab: + e = h; + if (e != 4) + f = -1; + f = f + f; + a = f; + g = d - 4; + if (!g) + goto lab; + c = a; + if (c != -2) + __builtin_abort (); +} commit dfb752d89d76b76c2be6cf244790dce32d9d28d0 Author: Jakub Jelinek Date: Thu Jul 16 09:55:37 2026 +0200 bitintlower: Avoid coalescing lhs with operands for .MUL_OVERFLOW [PR126262] We need to avoid overlap between the lhs and input operands of __mulbitint3 and __divmodbitint4. This is done in build_bitint_stmt_ssa_conflicts, when muldiv_p is set, we call use on all the SSA use operands (including operands of stmts on worklist) first and def on the lhs at the end, while for !muldiv_p, at least for stmts with a single lhs we call def first and then all the use calls. For MULT_EXPR etc. we already handle it: case MULT_EXPR: case TRUNC_DIV_EXPR: case EXACT_DIV_EXPR: case TRUNC_MOD_EXPR: muldiv_p = true; Now, for the IFN_*_OVERFLOW, we handle it for bitint_big_endian only currently, on big endian there is a problem that if the sizes don't match exactly, even in order updates of the limbs can clobber stuff. But, for IFN_MUL_OVERFLOW and IFN_UBSAN_CHECK_MUL, we actually use __mulbitint3 libgcc call and that function really can't be called with overlapping destination and inputs, because it traverses the inputs multiple times while writing destination one by one (and it intentionally doesn't allocate memory for temporaries). So, the following patch fixes it by making IFN_MUL_OVERFLOW and IFN_UBSAN_CHECK_MUL calls be always handled as muldiv_p. 2026-07-16 Jakub Jelinek PR tree-optimization/126262 * gimple-lower-bitint.cc (build_bitint_stmt_ssa_conflicts): Treat IFN_MUL_OVERFLOW and IFN_UBSAN_CHECK_MUL like IFN_BSWAP, regardless of bitint_big_endian. * gcc.dg/torture/bitint-102.c: New test. Reviewed-by: Richard Biener (cherry picked from commit b032f71e16603f974b4cbc3d87752d21f43980af) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 05f7e929106..e4c9e261bd8 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -5977,6 +5977,18 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track *live, } } } + else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt)) + switch (gimple_call_internal_fn (stmt)) + { + case IFN_MUL_OVERFLOW: + case IFN_UBSAN_CHECK_MUL: + lhs = gimple_call_lhs (stmt); + if (lhs) + muldiv_p = true; + break; + default: + break; + } ssa_op_iter iter; tree var; diff --git a/gcc/testsuite/gcc.dg/torture/bitint-102.c b/gcc/testsuite/gcc.dg/torture/bitint-102.c new file mode 100644 index 00000000000..7541849636d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-102.c @@ -0,0 +1,33 @@ +/* PR tree-optimization/126262 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=gnu23" } */ + +#if __BITINT_MAXWIDTH__ >= 1024 +typedef unsigned _BitInt (512) A; +typedef _BitInt (1024) B; + +[[gnu::noipa]] int +foo (signed char x, A y) +{ + B b = -(B) y; + A c; + if (__builtin_mul_overflow (1, b, &c)) + c = 42; + B f; + if (__builtin_mul_overflow (x, 9, &f)) + f = 42; + int i; + if (__builtin_mul_overflow (f, 1, &i)) + i = 42; + return c + i; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 1024 + if (foo (1, -2) != 51) + __builtin_abort (); +#endif +} commit f2f60ebaaca3ebfd09340702594660842b69a1ad Author: Rainer Orth Date: Thu Jul 16 09:56:58 2026 +0200 testsuite: Require bitint in gcc.dg/torture/bitint-101.c The new gcc.dg/torture/bitint-101.c test FAILs on Solaris/SPARC: FAIL: gcc.dg/torture/bitint-101.c -O0 (test for excess errors) UNRESOLVED: gcc.dg/torture/bitint-101.c -O0 compilation failed to produce executable Excess errors: gcc.dg/torture/bitint-101.c:4:1: sorry, unimplemented: '_BitInt(2)' is not supported on this target gcc.dg/torture/bitint-101.c:11:3: sorry, unimplemented: '_BitInt(2)' is not supported on this target Fixed by requiring bitint support. Tested on sparc-sun-solaris2.11 and i386-pc-solaris2.11. 2026-07-16 Rainer Orth gcc/testsuite: * gcc.dg/torture/bitint-101.c: Require bitint. (cherry picked from commit 1731ba6e70ff806c209ab4d73c402257afd41768) diff --git a/gcc/testsuite/gcc.dg/torture/bitint-101.c b/gcc/testsuite/gcc.dg/torture/bitint-101.c index 42f3998ccbf..df3acd344a6 100644 --- a/gcc/testsuite/gcc.dg/torture/bitint-101.c +++ b/gcc/testsuite/gcc.dg/torture/bitint-101.c @@ -1,5 +1,5 @@ /* PR tree-optimization/126257 */ -/* { dg-do run } */ +/* { dg-do run { target bitint } } */ /* { dg-additional-options "-std=c23" } */ _BitInt(2) a; commit fa7d773e17ffc8a722a5ae6d50db6a8bd68594aa Author: GCC Administrator Date: Fri Jul 17 00:18:49 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10917a11fb4..8fc0a5d6849 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,62 @@ +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-16 Jakub Jelinek + + PR tree-optimization/126262 + * gimple-lower-bitint.cc (build_bitint_stmt_ssa_conflicts): Treat + IFN_MUL_OVERFLOW and IFN_UBSAN_CHECK_MUL like IFN_BSWAP, regardless + of bitint_big_endian. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-15 Jakub Jelinek + + PR tree-optimization/126257 + * match.pd (x+x -> x*2): Only optimize if 2 is representable in the + type. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-14 Jakub Jelinek + + PR middle-end/126084 + * gimple-lower-bitint.cc: Include "attribs.h" and "asan.h". + (gimple_lower_bitint): Use asan_expand_poison_ifn to lower + .ASAN_POISON calls with large/huge _BitInt lhs. + * asan.cc (report_error_func): Set *nargs and use _n builtin + even if size is not a power of two or larger than 16. + (asan_expand_poison_ifn): Handle nargs == 2. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-14 Jakub Jelinek + H.J. Lu + + PR tree-optimization/120201 + * cfgexpand.cc (expand_used_vars): Set data.asan_alignb to + maximum of itself and crtl->stack_alignment_needed + / BITS_PER_UNIT. + +2026-07-16 Jeevitha + + Backported from master: + 2026-07-16 Jeevitha Palanisamy + + PR target/106895 + * config/rs6000/rs6000.h (enum rs6000_builtin_type_index): Add + RS6000_BTI_INTPTI and RS6000_BTI_UINTPTI. + (intPTI_type_internal_node, uintPTI_type_internal_node): New + PTImode type macros. + * config/rs6000/rs6000-builtin.cc (rs6000_init_builtins): Register + signed and unsigned PTImode internal builtin types. + * config/rs6000/sync.md (trunctipti2): New splitter. + (extendptiti2): Likewise. + (zero_extendptiti2): Likewise. + 2026-07-14 Richard Earnshaw Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index cffc20fbe3d..cc04947086b 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260716 +20260717 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 29c3524b81d..89ac1cd7856 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-03 Jakub Jelinek + + PR c++/126057 + * decl.cc (cp_finish_decomp): Set assembler name to + during error recovery whenever TREE_STATIC + rather than just DECL_NAMESPACE_SCOPE_P. + * pt.cc (tsubst_stmt): If tsubst_decomp_names fails, + set assembler name to . + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-06-12 Jakub Jelinek + + PR c++/125674 + * pt.cc (tsubst_decl): Diagnose bit-field widths + with invalid type. + 2026-06-27 Patrick Palka Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 83dcab9365c..bd4d0953e16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,77 @@ +2026-07-16 Rainer Orth + + Backported from master: + 2026-07-16 Rainer Orth + + * gcc.dg/torture/bitint-101.c: Require bitint. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-16 Jakub Jelinek + + PR tree-optimization/126262 + * gcc.dg/torture/bitint-102.c: New test. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-15 Jakub Jelinek + + PR tree-optimization/126257 + * gcc.dg/torture/bitint-101.c: New test. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-14 Jakub Jelinek + + PR middle-end/126084 + * gcc.dg/asan/bitint-1.c: New test. + * gcc.dg/asan/bitint-2.c: New test. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-14 Jakub Jelinek + H.J. Lu + + PR tree-optimization/120201 + * g++.dg/asan/pr120201-1.C: New test. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-05 Jakub Jelinek + + * g++.dg/opt/20260703-1.C: New test. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-07-03 Jakub Jelinek + + PR c++/126057 + * g++.dg/cpp2a/decomp11.C: New test. + +2026-07-16 Jakub Jelinek + + Backported from master: + 2026-06-12 Jakub Jelinek + + PR c++/125674 + * g++.dg/template/bitfield5.C: New test. + * g++.dg/template/bitfield6.C: New test. + +2026-07-16 Jeevitha + + Backported from master: + 2026-07-16 Jeevitha Palanisamy + + PR target/106895 + * gcc.target/powerpc/pr106895-1.c: New test. + * gcc.target/powerpc/pr106895-2.c: New test. + 2026-07-14 Richard Earnshaw Backported from master: commit e437555cc1f6694d85aaf4095eead81737efb279 Author: GCC Administrator Date: Sat Jul 18 00:18:46 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index cc04947086b..7154e3d89d4 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260717 +20260718 commit e5f8af0511dd14a1236f7316fc62d1d83a96bbcc Author: GCC Administrator Date: Sun Jul 19 00:18:37 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 7154e3d89d4..420ab44d5e5 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260718 +20260719 commit d3a42cc05035856355b88f02e150b1b173dd4730 Author: GCC Administrator Date: Mon Jul 20 00:19:08 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 420ab44d5e5..565cf268bc8 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260719 +20260720 commit 9fd8ab39ac196a0603fa1c7ba4c82e2a8c6c7a86 Author: Kyrylo Tkachov Date: Wed Jun 17 07:25:31 2026 -0700 LRA: reload non-representable subregs of hard registers through memory [PR105116] PR target/105116 is an aarch64 ICE in lra_split_hard_reg_for ("unable to find a register to spill"). A wide vector value (OImode, a pair of Q registers) is pinned to FP registers via asm register variables and an operation with no Advanced SIMD form (an integer vector divide or modulo) is scalarised by vector lowering. The scalar pieces read non-lowpart scalar subregs of the OImode register, e.g. (subreg:DI (reg:OI v2) 8), the high 64 bits of the first Q register. Such a subreg is not representable as a hard register (subreg_get_info returns representable_p == false), but the hard-register branch of simplify_operand_subreg only called alter_subreg, which resolves it to the wrong part of the register. For GENERAL_REGS uses, curr_insn_transform then tried to reload the whole OImode inner register into GENERAL_REGS, which is impossible (aarch64_hard_regno_mode_ok is false for OImode in GENERAL_REGS) and gave the ICE; for FP-context uses the bad subreg survived to final and silently read the wrong bytes (a latent wrong-code bug). Handle this in simplify_operand_subreg: when a narrowing subreg of a hard register is not representable, reload the inner register through memory (NO_REGS) so that the correct bytes are accessed, mirroring the existing handling for pseudos. The frame, arg and stack pointers are left alone, as simplify_subreg_regno can reject them merely because reload is not finished. This only affects the already non-representable case; representable subregs are unchanged. Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux. Signed-off-by: Kyrylo Tkachov gcc/ChangeLog: PR target/105116 * lra-constraints.cc (simplify_operand_subreg): Reload a non-representable narrowing subreg of a hard register through memory instead of resolving it lossily. gcc/testsuite/ChangeLog: PR target/105116 * gcc.target/aarch64/sve/pr105116.c: New test. * gcc.target/aarch64/sve/pr105116-run.c: New test. (cherry picked from commit d00acdc3ecff20ce0591103364be86505c382af6) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 365f7b1d7db..2bb166d759d 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -1790,6 +1790,36 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) } else if (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER) { + /* A narrowing subreg of a hard register that is not representable as a + hard register (its offset does not fall on a register boundary) cannot + be turned into one, and would otherwise be resolved to the wrong part + of the register. Reload it through memory so that the correct bytes + are accessed, as is done for pseudos below. Leave the frame, arg and + stack pointers alone: simplify_subreg_regno can reject them simply + because reload is not finished yet. */ + if (partial_subreg_p (mode, innermode) + && REGNO (reg) != FRAME_POINTER_REGNUM + && REGNO (reg) != ARG_POINTER_REGNUM + && REGNO (reg) != STACK_POINTER_REGNUM + && simplify_subreg_regno (REGNO (reg), innermode, + SUBREG_BYTE (operand), mode) < 0) + { + if (get_reload_reg (type, innermode, reg, NO_REGS, NULL, + true, false, "non-representable subreg", &new_reg)) + { + bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); + bool insert_before = (type != OP_OUT + || read_modify_subreg_p (operand)); + bool insert_after = (type != OP_IN); + insert_move_for_subreg (insert_before ? &before : NULL, + insert_after ? &after : NULL, + reg, new_reg); + } + SUBREG_REG (operand) = new_reg; + lra_process_new_insns (curr_insn, before, after, + "Inserting non-representable subreg reload"); + return true; + } alter_subreg (curr_id->operand_loc[nop], false); return true; } diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr105116-run.c b/gcc/testsuite/gcc.target/aarch64/sve/pr105116-run.c new file mode 100644 index 00000000000..1a5798d4873 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr105116-run.c @@ -0,0 +1,48 @@ +/* PR target/105116 */ +/* { dg-do run { target aarch64_sve_hw } } */ +/* { dg-options "-O2 -fno-split-wide-types" } */ + +/* Besides the ICE, the non-representable high-lane subregs used to be + resolved lossily (silently reading lane 0), miscompiling the upper lanes. + Check the scalarised divide produces the correct result for every lane. */ + +typedef signed char vnx16qi __attribute__((vector_size (32))); + +__attribute__((noipa)) void +vdiv_vnx16qi (vnx16qi *x, vnx16qi y, vnx16qi z) +{ + register vnx16qi dst asm ("z0"); + register vnx16qi src1 asm ("z2"); + register vnx16qi src2 asm ("z4"); + dst = *x; + src1 = y; + src2 = z; + asm volatile ("" :: "w" (dst), "w" (src1), "w" (src2)); + dst = src2 - (dst / src1); + asm volatile ("" :: "w" (dst)); + *x = dst; +} + +int +main (void) +{ + vnx16qi X, Y, Z; + signed char xv[32], yv[32], zv[32]; + for (int i = 0; i < 32; i++) + { + xv[i] = (signed char) (i * 7 - 50); + yv[i] = (signed char) (((i % 5) + 1) * (i & 1 ? 1 : -1)); + zv[i] = (signed char) (100 - i * 3); + } + __builtin_memcpy (&X, xv, 32); + __builtin_memcpy (&Y, yv, 32); + __builtin_memcpy (&Z, zv, 32); + vdiv_vnx16qi (&X, Y, Z); + signed char got[32]; + __builtin_memcpy (got, &X, 32); + for (int i = 0; i < 32; i++) + if (got[i] + != (signed char) (zv[i] - (signed char) ((int) xv[i] / (int) yv[i]))) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr105116.c b/gcc/testsuite/gcc.target/aarch64/sve/pr105116.c new file mode 100644 index 00000000000..84912356755 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr105116.c @@ -0,0 +1,32 @@ +/* PR target/105116 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-split-wide-types" } */ + +/* Wide GNU vectors pinned to SVE z registers and then scalarised by vector + lowering used to ICE in lra_split_hard_reg_for ("unable to find a register + to spill"): LRA reloaded a non-representable scalar subreg of the OImode + register pair into GENERAL_REGS, which cannot hold OImode. Integer vector + divide and modulo have no Advanced SIMD form, so they are still scalarised + and exercise the reload path. */ + +typedef signed char vnx16qi __attribute__((vector_size (32))); + +#define TEST(NAME, OP) \ + void \ + NAME (vnx16qi *x, vnx16qi y, vnx16qi z) \ + { \ + register vnx16qi dst asm ("z0"); \ + register vnx16qi src1 asm ("z2"); \ + register vnx16qi src2 asm ("z4"); \ + dst = *x; \ + src1 = y; \ + src2 = z; \ + asm volatile ("" :: "w" (dst), "w" (src1), "w" (src2)); \ + dst = src2 - (OP); \ + asm volatile ("" :: "w" (dst)); \ + *x = dst; \ + } + +TEST (vmul_vnx16qi, dst * src1) +TEST (vdiv_vnx16qi, dst / src1) +TEST (vmod_vnx16qi, dst % src1) commit 52131c2fe079baec12c27403d7202be739a952c8 Author: Mikael Morin Date: Mon Jul 20 13:28:12 2026 +0200 fortran: Don't reuse original descriptors for packed arrays [PR125998] Don't try to reuse the original descriptor when creating a descriptor for packed data in gfc_conv_array_parameter. For a non-transposed array (anything but TRANSPOSE(VAR)) the original descriptor was reused, and only the data was reset to the result of packing. This is wrong because the original descriptor can be non-contiguous, it can't be correct as the descriptor of packed data. In the testcase, a dummy array associated with a transposed array actual argument matches this case. Reusing the descriptor in that case would cause the packed data to be used transposed, that is not in the normal array element order. This change removes this case to always fallback to what was previously the transposed case (see next). For the transposed case (TRANSPOSE(VAR)), the full dimensions of the original untransposed descriptor were reused (in other words, the dimensions of VAR). This is wrong because packing doesn't change the shape, so the packed array should have the same bounds as the bounds of TRANSPOSE(VAR), not the same bounds as VAR. Reusing the strides of an unpacked array for a packed array doesn't seem right either. This change uses matching dimensions when copying from the original descriptor, and only copies the lbound and ubound. The strides are recalculated. And then the offset is recalculated as well (even though I couldn't find a testcase where it made a difference). PR fortran/97592 PR fortran/125998 gcc/fortran/ChangeLog: * trans-array.cc (gfc_conv_array_parameter): Always create a new descriptor. Copy lbound and ubound from the original descriptor using matching dimension indexes. Recalculate stride and offset. gcc/testsuite/ChangeLog: * gfortran.dg/contiguous_17.f90: New test. (cherry picked from commit 6658c2347d4a88d82e80f44a450b14dc7287bcef) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 36fd7edcad9..341bb4ff351 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -8989,14 +8989,10 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77, { tmp = build_fold_indirect_ref_loc (input_location, desc); - gfc_ss * ss = gfc_walk_expr (expr); - if (!transposed_dims (ss) && expr->rank != -1) - { - if (!ctree) - gfc_conv_descriptor_data_set (&se->pre, tmp, ptr); - } - else if (!ctree) + if (!ctree) { + /* The original descriptor may have transposed dims so we + can't reuse it directly; we have to create a new one. */ tree old_field, new_field; tree old_desc = tmp; tree new_desc = gfc_create_var (TREE_TYPE (old_desc), "arg_desc"); @@ -9061,19 +9057,55 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77, } else { - /* The original descriptor has transposed dims so we can't - reuse it directly; we have to create a new one. */ - old_field = gfc_conv_descriptor_offset_get (old_desc); - gfc_conv_descriptor_offset_set (&se->pre, new_desc, old_field); + tree offset = gfc_index_zero_node; + + tree stride = gfc_index_one_node; for (int i = 0; i < expr->rank; i++) { - old_field = gfc_conv_descriptor_dimension (old_desc, - gfc_rank_cst[get_array_ref_dim_for_loop_dim (ss, i)]); - new_field = gfc_conv_descriptor_dimension (new_desc, - gfc_rank_cst[i]); - gfc_add_modify (&se->pre, new_field, old_field); + tree dim = gfc_rank_cst[i]; + + tree lbound = gfc_conv_descriptor_lbound_get (old_desc, + dim); + lbound = gfc_evaluate_now (lbound, &se->pre); + gfc_conv_descriptor_lbound_set (&se->pre, new_desc, dim, + lbound); + + tree ubound = gfc_conv_descriptor_ubound_get (old_desc, + dim); + ubound = gfc_evaluate_now (ubound, &se->pre); + gfc_conv_descriptor_ubound_set (&se->pre, new_desc, dim, + ubound); + + gfc_conv_descriptor_stride_set (&se->pre, new_desc, dim, + stride); + + tree tmp = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, + stride, lbound); + offset = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, + offset, tmp); + offset = gfc_evaluate_now (offset, &se->pre); + + /* Now calculate the stride for next dimension, unless the + current dimension is the last one. */ + if (i == expr->rank - 1) + break; + + tmp = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, + lbound, gfc_index_one_node); + tree extent = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, + ubound, tmp); + stride = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, + stride, extent); + stride = gfc_evaluate_now (stride, &se->pre); } + + gfc_conv_descriptor_offset_set (&se->pre, new_desc, offset); } if (flag_coarray == GFC_FCOARRAY_LIB @@ -9089,7 +9121,6 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77, gfc_conv_descriptor_data_set (&se->pre, new_desc, ptr); se->expr = gfc_build_addr_expr (NULL_TREE, new_desc); } - gfc_free_ss (ss); } if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS) diff --git a/gcc/testsuite/gfortran.dg/contiguous_17.f90 b/gcc/testsuite/gfortran.dg/contiguous_17.f90 new file mode 100644 index 00000000000..0fd27b1d41e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/contiguous_17.f90 @@ -0,0 +1,229 @@ +! { dg-do run } +! +! PR fortran/125998 +! Check the correct passing of a transposed array to an assumed-shape dummy +! having the contiguous and target attributes. +! +! Original testcase from Federico Perini + +subroutine original + real(8) :: a(3,4) + integer :: dims(2) + character(48) :: iomsg + call show(transpose(a),dims) + if (any(dims/=shape(transpose(a)))) then + write(iomsg,1) 'invalid a^T dims',dims, & + ' should be',shape(transpose(a)) + error stop iomsg + endif + 1 format(*(a,' [',i0,',',i0,']')) + +contains + + subroutine show(x,dims) + ! "3 4" with `contiguous` (BUG); "4 3" without + real(8), intent(in), target, contiguous :: x(:,:) + integer, intent(out) :: dims(2) + dims = [size(x,1),size(x,2)] + end + +end + +module m + implicit none + private + public :: check_all + +contains + + subroutine abort_different(lx,x,ly,y,code) + character(*), intent(in) :: lx, ly + integer, intent(in) :: x(..), y(..), code + write(6,'(a," /= ",a)') lx, ly + select rank(x) + rank(1) + write(6,3) lx + write(6,*) x + rank(2) + write(6,3) lx + write(6,*) x + rank default + end select + select rank(y) + rank(1) + write(6,3) ly + write(6,*) y + rank(2) + write(6,3) ly + write(6,*) y + rank default + end select + error stop code + 3 format(a,":") + end subroutine + + subroutine check_target(x,expected,num_error) + integer, intent(in), target, contiguous :: x(:,:) + integer, intent(in) :: num_error, expected(:,:) + if (any(shape(x) /= shape(expected))) then + call abort_different( & + "shape(x)",shape(x), & + "shape(expected)",shape(expected), & + num_error*10+1 & + ) + end if + if (any(x /= expected)) then + call abort_different("x",x,"expected",expected,num_error*10+2) + end if + if (x(2,2) /= expected(2,2)) then + call abort_different( & + "x(2,2)",x(2,2), & + "expected(2,2)",expected(2,2), & + num_error*10+3 & + ) + end if + end + + subroutine check_non_target(x,expected,num_error) + integer, intent(in), contiguous :: x(:,:) + integer, intent(in) :: num_error, expected(:,:) + if (any(shape(x) /= shape(expected))) then + call abort_different( & + "shape(x)",shape(x), & + "shape(expected)",shape(expected), & + num_error*10+1 & + ) + end if + if (any(x /= expected)) then + call abort_different("x",x,"expected",expected,num_error*10+2) + end if + if (x(2,2) /= expected(2,2)) then + call abort_different( & + "x(2,2)",x(2,2), & + "expected(2,2)",expected(2,2), & + num_error*10+3 & + ) + end if + end + + subroutine wrapper_target(x,expected,num_error) + integer, intent(in), target :: x(:,:) + integer, intent(in) :: expected(:,:) + integer, intent(in) :: num_error + call check_target(x,expected,num_error) + end subroutine + + subroutine wrapper_non_target(x,expected,num_error) + integer, intent(in) :: x(:,:), expected(:,:) + integer, intent(in) :: num_error + call check_non_target(x,expected,num_error) + end subroutine + + subroutine wrapper_transpose_target(x,expected,num_error) + integer, intent(in), target :: x(:,:) + integer, intent(in) :: expected(:,:) + integer, intent(in) :: num_error + call check_target(transpose(x),expected,num_error) + end subroutine + + subroutine wrapper_transpose_non_target(x,expected,num_error) + integer, intent(in) :: x(:,:), expected(:,:) + integer, intent(in) :: num_error + call check_non_target(transpose(x),expected,num_error) + end subroutine + + subroutine check_all + integer :: a(3,4) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call check_target( & + transpose(a), & + reshape([0,2,8,34,1,3,13,55,1,5,21,89],[4,3]), & + 1 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call check_non_target( & + transpose(a), & + reshape([0,2,8,34,1,3,13,55,1,5,21,89],[4,3]), & + 2 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_target( & + transpose(a), & + reshape([0,2,8,34,1,3,13,55,1,5,21,89],[4,3]), & + 3 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_non_target( & + transpose(a), & + reshape([0,2,8,34,1,3,13,55,1,5,21,89],[4,3]), & + 4 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_transpose_target( & + a, & + reshape([0,2,8,34,1,3,13,55,1,5,21,89],[4,3]), & + 5 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_transpose_non_target( & + a, & + reshape([0,2,8,34,1,3,13,55,1,5,21,89],[4,3]), & + 6 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_transpose_target( & + transpose(a), & + reshape([0,1,1,2,3,5,8,13,21,34,55,89],[3,4]), & + 7 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_transpose_non_target( & + transpose(a), & + reshape([0,1,1,2,3,5,8,13,21,34,55,89],[3,4]), & + 8 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call check_target( & + a(::2,::2), & + reshape([0,1,8,21],[2,2]), & + 9 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call check_non_target( & + a(::2,::2), & + reshape([0,1,8,21],[2,2]), & + 10 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_target( & + a(::2,::2), & + reshape([0,1,8,21],[2,2]), & + 11 & + ) + + a = reshape([0,1,1,2,3,5,8,13,21,34,55,89],shape(a)) + call wrapper_non_target( & + a(::2,::2), & + reshape([0,1,8,21],[2,2]), & + 12 & + ) + + end subroutine + +end module + +use m +call original +call check_all +end commit 5f09af8d2a236f5a74020a3a72a6f97cd5029015 Author: GCC Administrator Date: Tue Jul 21 00:19:09 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fc0a5d6849..d41eb7a793d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2026-07-20 Kyrylo Tkachov + + Backported from master: + 2026-06-29 Kyrylo Tkachov + + PR target/105116 + * lra-constraints.cc (simplify_operand_subreg): Reload a + non-representable narrowing subreg of a hard register through + memory instead of resolving it lossily. + 2026-07-16 Jakub Jelinek Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 565cf268bc8..d5ecb901551 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260720 +20260721 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 34867a95e3b..08bd518293c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2026-07-20 Mikael Morin + + Backported from master: + 2026-07-03 Mikael Morin + + PR fortran/97592 + PR fortran/125998 + * trans-array.cc (gfc_conv_array_parameter): Always create a new + descriptor. Copy lbound and ubound from the original descriptor + using matching dimension indexes. Recalculate stride and + offset. + 2026-07-12 Paul Thomas Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd4d0953e16..aef0220223e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2026-07-20 Mikael Morin + + Backported from master: + 2026-07-03 Mikael Morin + + PR fortran/97592 + PR fortran/125998 + * gfortran.dg/contiguous_17.f90: New test. + +2026-07-20 Kyrylo Tkachov + + Backported from master: + 2026-06-29 Kyrylo Tkachov + + PR target/105116 + * gcc.target/aarch64/sve/pr105116.c: New test. + * gcc.target/aarch64/sve/pr105116-run.c: New test. + 2026-07-16 Rainer Orth Backported from master: commit c1d1bf1f42523dad8e10056fa7058d9d67648a3f Author: Alice Carlotti Date: Thu Apr 16 13:02:35 2026 +0100 aarch64: Fix ZA state transition [PR119210] In the INACTIVE_CALLER -> INACTIVE LOCAL transition, ensure ZA is active and zeroed before setting tpidr2_el0. gcc/ChangeLog: PR target/119210 * config/aarch64/aarch64.cc (aarch64_mode_emit_local_sme_state): Add PSTATE.ZA enablement, and zero it if already enabled. gcc/testsuite/ChangeLog: PR target/119210 * gcc.target/aarch64/sme/za_state_8.c: New test. diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 152de30aecf..0b8a36c4af1 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -29555,7 +29555,8 @@ aarch64_mode_emit_local_sme_state (aarch64_local_sme_state mode, emit_insn (gen_aarch64_tpidr2_save ()); emit_insn (gen_aarch64_clear_tpidr2 ()); if (mode == aarch64_local_sme_state::ACTIVE_LIVE - || mode == aarch64_local_sme_state::ACTIVE_DEAD) + || mode == aarch64_local_sme_state::ACTIVE_DEAD + || mode == aarch64_local_sme_state::INACTIVE_LOCAL) { if (aarch64_cfun_has_state ("za")) emit_insn (gen_aarch64_initial_zero_za ()); @@ -29637,6 +29638,16 @@ aarch64_mode_emit_local_sme_state (aarch64_local_sme_state mode, if (mode == aarch64_local_sme_state::INACTIVE_LOCAL) { + if (prev_mode == aarch64_local_sme_state::INACTIVE_CALLER) + /* Enable ZA (if it wasn't already enabled on entry). Enabling ZA has + the side-effect of zeroing ZA. + + A functionally correct alternative would be to leave TPIDR2_EL0 null + and zero the save buffer. However, zeroing the save buffer would require + more code and would optimize for the case in which a callee also + initialises private ZA state (which should be a rare event). */ + emit_insn (gen_aarch64_smstart_za ()); + if (prev_mode == aarch64_local_sme_state::ACTIVE_LIVE || prev_mode == aarch64_local_sme_state::ACTIVE_DEAD || prev_mode == aarch64_local_sme_state::INACTIVE_CALLER) diff --git a/gcc/testsuite/gcc.target/aarch64/sme/za_state_8.c b/gcc/testsuite/gcc.target/aarch64/sme/za_state_8.c new file mode 100644 index 00000000000..9b7a6ffa69c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme/za_state_8.c @@ -0,0 +1,25 @@ +// { dg-options "-O -fomit-frame-pointer -fno-optimize-sibling-calls" } +// { dg-final { check-function-bodies "**" "" } } + +#include + +void callee_ns(); +__arm_streaming __arm_inout("za") void callee_s(); + +/* +** foo: +** ... +** smstart za +** ... +** msr tpidr2_el0, x\d+ +** ... +*/ +__arm_locally_streaming __arm_new("za") const float * foo(const float* x) { + callee_ns (); + const float32_t *x_f_in = x; + svzero_za(); + callee_s (); + return x_f_in; +} + + commit 7d852c36ec2ff07652fc720cbfb06ecd0610d870 Author: Alice Carlotti Date: Fri Mar 27 15:21:58 2026 +0000 Fix some mode switching doc/comment typos I found a few typos and inconsistent variable names in mode switching comments and documentation. Fix them. gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_mode_confluence): Fix comment typo. * target.def (mode_switching): Fix incorrect variable names in documentation. * doc/tm.texi: Regenerate. diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 0b8a36c4af1..025df1ade56 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -29978,7 +29978,7 @@ aarch64_mode_confluence (int entity, int mode1, int mode2) } /* Implement TARGET_MODE_BACKPROP for an entity that either stays - NO throughput, or makes one transition from NO to YES. */ + NO throughout, or makes one transition from NO to YES. */ static aarch64_tristate_mode aarch64_one_shot_backprop (aarch64_tristate_mode mode1, diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index cd50078227d..d6f57179087 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10512,8 +10512,8 @@ mode or ``no mode'', depending on context. @deftypefn {Target Hook} void TARGET_MODE_EMIT (int @var{entity}, int @var{mode}, int @var{prev_mode}, HARD_REG_SET @var{regs_live}) Generate one or more insns to set @var{entity} to @var{mode}. -@var{hard_reg_live} is the set of hard registers live at the point where -the insn(s) are to be inserted. @var{prev_moxde} indicates the mode +@var{regs_live} is the set of hard registers live at the point where +the insn(s) are to be inserted. @var{prev_mode} indicates the mode to switch from, or is the number of modes if the previous mode is not known. Sets of a lower numbered entity will be emitted before sets of a higher numbered entity to a mode of the same or lower priority. diff --git a/gcc/target.def b/gcc/target.def index c27df8095be..ba814ed76ff 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -7148,8 +7148,8 @@ HOOK_VECTOR (TARGET_TOGGLE_, mode_switching) DEFHOOK (emit, "Generate one or more insns to set @var{entity} to @var{mode}.\n\ -@var{hard_reg_live} is the set of hard registers live at the point where\n\ -the insn(s) are to be inserted. @var{prev_moxde} indicates the mode\n\ +@var{regs_live} is the set of hard registers live at the point where\n\ +the insn(s) are to be inserted. @var{prev_mode} indicates the mode\n\ to switch from, or is the number of modes if the previous mode is not\n\ known. Sets of a lower numbered entity will be emitted before\n\ sets of a higher numbered entity to a mode of the same or lower priority.", commit c1a9f8efda333d23cbb3463e1f9faba8735684c8 Author: Alice Carlotti Date: Thu Apr 16 12:37:53 2026 +0100 aarch64: Extend comment about saving/restoring zt0 Explain why aarch64_start_call_args only needs to save and restore zt0 if the callee shares ZA state. gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_start_call_args): Extend comment. diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 025df1ade56..b4ac8db0a39 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -11202,7 +11202,8 @@ aarch64_start_call_args (cumulative_args_t ca_v) emit_insn (gen_aarch64_start_private_za_call ()); /* If this is a call to a shared-ZA function that doesn't share ZT0, - save and restore ZT0 around the call. */ + save and restore ZT0 around the call. If ZA is not shared, then the + save/restore is instead emitted by aarch64_mode_emit_local_sme_state. */ if (aarch64_cfun_has_state ("zt0") && (ca->isa_mode & AARCH64_FL_ZA_ON) && ca->shared_zt0_flags == 0) commit a3f7fa43579bd7a6fe6190904c8aea85d40c617f Author: GCC Administrator Date: Wed Jul 22 00:19:05 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d41eb7a793d..cb93ebbaf8c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2026-07-21 Alice Carlotti + + * config/aarch64/aarch64.cc (aarch64_start_call_args): Extend + comment. + +2026-07-21 Alice Carlotti + + * config/aarch64/aarch64.cc (aarch64_mode_confluence): Fix + comment typo. + * target.def (mode_switching): Fix incorrect variable names in + documentation. + * doc/tm.texi: Regenerate. + +2026-07-21 Alice Carlotti + + PR target/119210 + * config/aarch64/aarch64.cc (aarch64_mode_emit_local_sme_state): + Add PSTATE.ZA enablement, and zero it if already enabled. + 2026-07-20 Kyrylo Tkachov Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index d5ecb901551..195bd556d38 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260721 +20260722 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aef0220223e..767ee57a36e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2026-07-21 Alice Carlotti + + PR target/119210 + * gcc.target/aarch64/sme/za_state_8.c: New test. + 2026-07-20 Mikael Morin Backported from master: commit 218ce55ae770b24fd7e0a5cce95d2f1b26c33be5 Author: GCC Administrator Date: Thu Jul 23 00:19:14 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 195bd556d38..f3ec639a346 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260722 +20260723 commit c0f61cd6029b708ac1b5d9f7eab4bd7ebdb9642c Author: GCC Administrator Date: Fri Jul 24 00:19:21 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index f3ec639a346..1713b244987 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260723 +20260724 commit 137cad0622316a765a68252c9a5d6a6de5fcd1db Author: GCC Administrator Date: Sat Jul 25 00:19:02 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 1713b244987..3f02e008f43 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260724 +20260725 commit 1085a8f803c2992b970731959656bd6ccf789b10 Author: GCC Administrator Date: Sun Jul 26 00:19:01 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 3f02e008f43..deff22c3cc6 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260725 +20260726 commit 447291bf9aa647f9f13c454065b543ec39b92e14 Author: GCC Administrator Date: Mon Jul 27 00:18:51 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index deff22c3cc6..8d1412f6b15 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260726 +20260727 commit ebb85adb7bf4391abfad69268ac51d2ef5237071 Author: Thomas Koenig Date: Sun Jul 26 13:41:32 2026 +0200 Fix size calculation for reallocation for matmul of rank 2 a and rank 1 b. This is a rather simple one-character (well, two-bit) fix for th calculation of the size of the reallocation of the LHS if that is allocatable. gcc/fortran/ChangeLog: PR fortran/126386 * frontend-passes.cc (matmul_lhs_realloc): Fix size calculation of A2B1 case. gcc/testsuite/ChangeLog: PR fortran/126386 * gfortran.dg/inline_matmul_28.f90: New test. (cherry picked from commit 4d855f3af5b18e539585d1d4832470e500323c12) diff --git a/gcc/fortran/frontend-passes.cc b/gcc/fortran/frontend-passes.cc index 5422eb88f92..4adae60825a 100644 --- a/gcc/fortran/frontend-passes.cc +++ b/gcc/fortran/frontend-passes.cc @@ -3604,7 +3604,7 @@ matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b, ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1); cond = build_logical_expr (INTRINSIC_NE, get_array_inq_function (GFC_ISYM_SIZE, c, 1), - get_array_inq_function (GFC_ISYM_SIZE, a, 2)); + get_array_inq_function (GFC_ISYM_SIZE, a, 1)); break; case A1B2: diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_28.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_28.f90 new file mode 100644 index 00000000000..569c29c41c8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_matmul_28.f90 @@ -0,0 +1,21 @@ +! { dg-do run } +! { dg-options "-ffrontend-optimize" } +! PR 126386 - size calculation for allocation of the lhs for matmmul +! was wrong. Original test case by Christoph Hofer. + +PROGRAM reallocation_bug + REAL(8), DIMENSION(:), ALLOCATABLE :: y + REAL(8), DIMENSION(3,2) :: A + real(8), dimension(3) :: x + + A(:,1) = [1,-2,3] + A(:,2) = [-4,5,6] + + x = [7,-8,9] + + ALLOCATE(y(3)) + y = matmul(transpose(2*a),x) + if (size(y,1) /= 2) stop 1 + if (any(y /= [100, -28])) stop 2 + +END PROGRAM reallocation_bug commit acd50f9147b9b57f0b245be5dea0c89e88194696 Author: GCC Administrator Date: Tue Jul 28 00:19:55 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 8d1412f6b15..5976d0f0fac 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260727 +20260728 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 08bd518293c..d6a9b5451bb 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2026-07-27 Thomas Koenig + + Backported from master: + 2026-07-26 Thomas Koenig + + PR fortran/126386 + * frontend-passes.cc (matmul_lhs_realloc): Fix size calculation of + A2B1 case. + 2026-07-20 Mikael Morin Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 767ee57a36e..4cecfd31fac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2026-07-27 Thomas Koenig + + Backported from master: + 2026-07-26 Thomas Koenig + + PR fortran/126386 + * gfortran.dg/inline_matmul_28.f90: New test. + 2026-07-21 Alice Carlotti PR target/119210 commit 45d1f64f0975163a42982cce40d4b4ae3e039023 Author: Haochen Jiang Date: Tue Jul 28 11:00:38 2026 +0800 i386: Correct vdpbf16ps mask usage in pattern [PR126429] 512 bit vdpbf16ps is using 16 bit mask. However, it only take the lower 8 bit into consideration due to avx512fhalfmaskmode usage in pattern. Correct to avx512fmaskmode and remove not used iterators and patterns. 256 bit and 128 bit vdpbf16ps are not affected since they are both 8 bit mask. gcc/ChangeLog: PR target/126429 * config/i386/sse.md (avx512fmaskhalfmode): Removed. (avx512f_dpbf16ps__maskz): Use avx512fmaskmode instead of avx512fmaskhalfmode. (avx512f_dpbf16ps__mask): Ditto. (avx512f_dpbf16ps_): Rename to ... (avx512f_dpbf16ps_): ... this. Use corresponding sd_mask_op4. * config/i386/subst.md (maskz_half): Remove not used pattern. gcc/testsuite/ChangeLog: PR target/126429 * gcc.target/i386/pr126429-1.c: New test. (cherry picked from commit ed04be2c33faaf19d14521f8e6959b12a812701a) diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index e2c4e6c8f69..812d23ecd62 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1040,17 +1040,6 @@ (V16SF "hi") (V8SF "qi") (V4SF "qi") (V8DF "qi") (V4DF "qi") (V2DF "qi")]) -;; Mapping of vector modes to corresponding mask half size -(define_mode_attr avx512fmaskhalfmode - [(V64QI "SI") (V32QI "HI") (V16QI "QI") - (V32HI "HI") (V16HI "QI") (V8HI "QI") (V4HI "QI") - (V16SI "QI") (V8SI "QI") (V4SI "QI") - (V8DI "QI") (V4DI "QI") (V2DI "QI") - (V32HF "HI") (V16HF "QI") (V8HF "QI") - (V32BF "HI") (V16BF "QI") (V8BF "QI") - (V16SF "QI") (V8SF "QI") (V4SF "QI") - (V8DF "QI") (V4DF "QI") (V2DF "QI")]) - ;; Mapping of vector float modes to an integer mode of the same size (define_mode_attr sseintvecmode [(V32HF "V32HI") (V32BF "V32HI") (V16SF "V16SI") (V8DF "V8DI") @@ -30695,7 +30684,7 @@ (match_operand:VF1_AVX512VL 1 "register_operand") (match_operand: 2 "register_operand") (match_operand: 3 "register_operand") - (match_operand: 4 "register_operand")] + (match_operand: 4 "register_operand")] "TARGET_AVX512BF16" { emit_insn (gen_avx512f_dpbf16ps__maskz_1(operands[0], operands[1], @@ -30703,7 +30692,7 @@ DONE; }) -(define_insn "avx512f_dpbf16ps_" +(define_insn "avx512f_dpbf16ps_" [(set (match_operand:VF1_AVX512VL 0 "register_operand" "=v") (unspec:VF1_AVX512VL [(match_operand:VF1_AVX512VL 1 "register_operand" "0") @@ -30711,7 +30700,7 @@ (match_operand: 3 "nonimmediate_operand" "vm")] UNSPEC_VDPBF16PS))] "TARGET_AVX512BF16" - "vdpbf16ps\t{%3, %2, %0|%0, %2, %3}") + "vdpbf16ps\t{%3, %2, %0|%0, %2, %3}") (define_insn "avx512f_dpbf16ps__mask" [(set (match_operand:VF1_AVX512VL 0 "register_operand" "=v") @@ -30722,7 +30711,7 @@ (match_operand: 3 "nonimmediate_operand" "vm")] UNSPEC_VDPBF16PS) (match_dup 1) - (match_operand: 4 "register_operand" "Yk")))] + (match_operand: 4 "register_operand" "Yk")))] "TARGET_AVX512BF16" "vdpbf16ps\t{%3, %2, %0%{%4%}|%0%{%4%}, %2, %3}") diff --git a/gcc/config/i386/subst.md b/gcc/config/i386/subst.md index 763e4a8de69..537d03f7c35 100644 --- a/gcc/config/i386/subst.md +++ b/gcc/config/i386/subst.md @@ -471,16 +471,3 @@ (const_int 1)) (match_operand:SI 3 "const48_operand")] UNSPEC_EMBEDDED_ROUNDING))]) - -(define_subst_attr "maskz_half_name" "maskz_half" "" "_maskz_1") -(define_subst_attr "maskz_half_operand4" "maskz_half" "" "%{%5%}%N4") - -(define_subst "maskz_half" - [(set (match_operand:SUBST_V 0) - (match_operand:SUBST_V 1))] - "" - [(set (match_dup 0) - (vec_merge:SUBST_V - (match_dup 1) - (match_operand:SUBST_V 2 "const0_operand") - (match_operand: 3 "register_operand" "Yk")))]) diff --git a/gcc/testsuite/gcc.target/i386/pr126429-1.c b/gcc/testsuite/gcc.target/i386/pr126429-1.c new file mode 100644 index 00000000000..ef84fe14d1c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr126429-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512bf16 -mavx512dq" } */ +/* { dg-final { scan-assembler-not "kmovb" } } */ + +#include + +__m512 dp16ps_mask (__m512 src, __mmask16 k, __m512bh a, __m512bh b) +{ + return _mm512_mask_dpbf16_ps (src, k, a, b); +} + +__m512 dp16ps_maskz (__mmask16 k, __m512 src, __m512bh a, __m512bh b) +{ + return _mm512_maskz_dpbf16_ps (k, src, a, b); +} commit 11d4783b390916a5e8b18ab0ffe74ca35b7bbfed Author: GCC Administrator Date: Wed Jul 29 00:19:57 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb93ebbaf8c..344efe7b795 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2026-07-28 Haochen Jiang + + Backported from master: + 2026-07-28 Haochen Jiang + + PR target/126429 + * config/i386/sse.md (avx512fmaskhalfmode): Removed. + (avx512f_dpbf16ps__maskz): Use avx512fmaskmode instead of + avx512fmaskhalfmode. + (avx512f_dpbf16ps__mask): Ditto. + (avx512f_dpbf16ps_): Rename to ... + (avx512f_dpbf16ps_): ... this. Use + corresponding sd_mask_op4. + * config/i386/subst.md (maskz_half): Remove not used pattern. + 2026-07-21 Alice Carlotti * config/aarch64/aarch64.cc (aarch64_start_call_args): Extend diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 5976d0f0fac..c7b4ba62bfc 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260728 +20260729 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4cecfd31fac..347837a965c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2026-07-28 Haochen Jiang + + Backported from master: + 2026-07-28 Haochen Jiang + + PR target/126429 + * gcc.target/i386/pr126429-1.c: New test. + 2026-07-27 Thomas Koenig Backported from master: commit bd236a3b41d5292c47dd239e187580db2464440f Author: GCC Administrator Date: Thu Jul 30 00:19:52 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c7b4ba62bfc..96192f4db24 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260729 +20260730 commit 0f1b43a38bbe8a12a8a0789a13ed581b92f3e613 Author: GCC Administrator Date: Fri Jul 31 00:19:57 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 96192f4db24..4856dc75a20 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260730 +20260731 commit de802d741d5fb2c34f65d95e6de6d67e47c0da4d Author: Jonathan Wakely Date: Sat Mar 14 10:32:11 2026 +0000 libstdc++: Fix time zone transitions for Rule changes during DST [PR116110] The Australia/Broken_Hill example in PR libstdc++/116110 demonstrates a bug in the time zone code. The current code gives incorrect results when a zone changes from one named Rule to another during DST, e.g. the Broken_Hill time zone uses: 9:30 AN AC%sT 2000 9:30 AS AC%sT So the AS Rules take effect on 2000 Jan 1 which is during DST (which runs from October to March). The fix for this is to update info.offset and info.save when we find an active rule, instead of only updating the 'letters' variable. The new tests for Pacific/Kiritimati and Pacific/Apia have some FIXME comments. The UNTIL times of the zone changes are incorrectly interpreted as UTC not wall time (due to the main topic of Bug 116110), and the "24" time for the Pacific/Apia zone is incorrectly ignored so that the change happens 24h too early (due to Bug 124513). Those tests will need to be adjusted later when the bugs are fixed. libstdc++-v3/ChangeLog: PR libstdc++/116110 * src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Update info.offset and info.save to values from the active rule. * testsuite/std/time/time_zone/116110.cc: New test. Reviewed-by: Tomasz Kamiński (cherry picked from commit 663e5ade184813a8a5f6f76b873c3e212c1e8e75) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 4c6aea9fdbe..0270382fb54 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -892,7 +892,11 @@ namespace std::chrono } if (active_rule) - letters = active_rule->letters; + { + info.offset = ri.offset() + active_rule->save; + info.save = chrono::duration_cast(active_rule->save); + letters = active_rule->letters; + } else if (first_std) letters = first_std->letters; } diff --git a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc new file mode 100644 index 00000000000..d86011cf573 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc @@ -0,0 +1,85 @@ +// { dg-do run { target c++20 } } +// { dg-require-effective-target tzdb } +// { dg-require-effective-target cxx11_abi } + +#include +#include + +using namespace std::chrono; + +void +test_broken_hill() +{ + /* + R AN 1996 2005 - Mar lastSun 2s 0 S + R AN 2000 o - Aug lastSun 2s 1 D + Z Australia/Broken_Hill 9:25:48 - LMT 1895 Feb + 10 - AEST 1896 Aug 23 + 9 - ACST 1899 May + 9:30 AU AC%sT 1971 + 9:30 AN AC%sT 2000 + 9:30 AS AC%sT + */ + auto* tz = locate_zone("Australia/Broken_Hill"); + auto info = tz->get_info(sys_days(2000y/February/29d) + 23h + 23min + 23s); + VERIFY( info.offset == 630min ); + VERIFY( info.save == 60min ); + VERIFY( info.abbrev == "ACDT" ); +} + +void +test_kiritimati() +{ + /* No named rules involved here, just change of fixed STDOFF at 1994-12-31: + Z Pacific/Kiritimati -10:29:20 - LMT 1901 + -10:40 - %z 1979 Oct + -10 - %z 1994 Dec 31 + 14 - %z + */ + auto* tz = locate_zone("Pacific/Kiritimati"); + local_seconds t = local_days(1994y/December/31); + + sys_seconds ut(t.time_since_epoch() /* FIXME: should be + 10h */); + sys_info info; + info = tz->get_info(ut - 1s); + VERIFY( info.offset == -10h ); + VERIFY( info.save == 0h ); + VERIFY( info.abbrev == "-10" ); + info = tz->get_info(ut); + VERIFY( info.offset == 14h ); + VERIFY( info.save == 0h ); + VERIFY( info.abbrev == "+14" ); +} + +void +test_apia() +{ + /* Refers to same named rule before/after change at 2011-12-29 24:00 + but the offset changed from -11h+1h to +13h+1h + Z Pacific/Apia 12:33:4 - LMT 1892 Jul 5 + -11:26:56 - LMT 1911 + -11:30 - %z 1950 + -11 WS %z 2011 Dec 29 24 + 13 WS %z + */ + auto* tz = locate_zone("Pacific/Apia"); + local_seconds t = local_days(2011y/December/29) + 24h; + + sys_seconds ut(t.time_since_epoch() /* FIXME: should be + 10h */ - 24h ); + sys_info info; + info = tz->get_info(ut - 1s); + VERIFY( info.offset == (-11h + info.save) ); + VERIFY( info.save == 1h ); + VERIFY( info.abbrev == "-10" ); + info = tz->get_info(ut); + VERIFY( info.offset == (13h + info.save) ); + VERIFY( info.save == 1h ); + VERIFY( info.abbrev == "+14" ); +} + +int main() +{ + test_broken_hill(); + test_kiritimati(); + test_apia(); +} commit 813acf0009efb6f4e2908cc0579ce271e76b7653 Author: Jonathan Wakely Date: Mon Mar 16 21:48:30 2026 +0000 libstdc++: Partial fix for interpretation of non-UTC UNTIL times in tzdata.zi [PR116110] This is a partial fix for PR 116110, so that zone changes that occur at a time specified as standard time will be parsed correctly. Previously all UNTIL times were assumed to be UTC, which is incorrect according to the spec. Only times with a 'u' suffix (or the equivalent 'g' or 'z') are UTC times. An 's' suffix means standard time (i.e. the zone's usual offset from UTC, without any DST adjustment) and a 'w' suffix (or no suffix) means wall time, so the offset and any DST adjustment. This commit fixes the handling of 's' suffixes, so that the ZoneInfo::m_until member is set correctly. It also fixes the handling of some UNTIL times using wall time, specifically those where the DST adjustment is known during parsing of the tzdata.zi file. This is not a complete fix, because as noted in PR 116110 a Zone line that refers to a named Rule and uses wall time cannot be determined while parsing tzdata.zi. We need to remember that the m_until member is not correct, and then adjust it later when we find the rule that applies at a given time point. That requires more work. Some existing tests need to be adjusted due to the fixes in this commit. The std/time/time_zone/get_info_sys.cc and std/time/zoned_time/1.cc tests are corrected to check that the changes happens at midnight local time, not midnight UTC as previously assumed. One of the FIXME comments in std/time/time_zone/116110.cc can be removed now, because the UNTIL time is correctly interpreted as midnight local time. The other FIXME needs to be changed to midnight at the local standard time, which is still wrong but we don't currently adjust it for the DST save time of one hour. It also still needs the incorrect +24h due to Bug 124513. libstdc++-v3/ChangeLog: PR libstdc++/116110 * src/c++20/tzdb.cc (operator>>(istream&, ZoneInfo&)): Adjust inf.m_until according to indicator suffix on AT time in UNTIL. * testsuite/std/time/time_zone/116110.cc (test_kiritimati): Remove FIXME now that the UNTIL time is adjusted for STDOFF. (test_apia): Adjust FIXME now that UNTIL time is adusted for STDOFF. * testsuite/std/time/time_zone/get_info_sys.cc: Adjust expected results to account for corrected logic. * testsuite/std/time/zoned_time/1.cc: Likewise. Reviewed-by: Tomasz Kamiński (cherry picked from commit cddf4111c4c4383f8d686ab822a9f3fc3ed6db44) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 0270382fb54..3612f01638a 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -2204,11 +2204,18 @@ namespace std::chrono at_time t{}; // XXX DAY should support ON format, e.g. lastSun or Sun>=8 in >> m >> d >> t; - // XXX UNTIL field should be interpreted - // "using the rules in effect just before the transition" - // so might need to store as year_month_day and hh_mm_ss and only - // convert to a sys_time once we know the offset in effect. inf.m_until = sys_days(year(y)/m.m/day(d)) + seconds(t.time); + if (t.indicator != at_time::Universal) + { // UNTIL uses "the rules in effect just before the transition" + // adjust by STDOFF + inf.m_until -= seconds(inf.m_offset); + if (t.indicator != at_time::Standard) + { + if (inf.m_expanded) // Not a named Rule, SAVE is known now. + inf.m_until -= inf.m_save; + // else Named Rule, SAVE is unknown. FIXME: PR 116110 + } + } } else inf.m_until = sys_days(year::max()/December/31); diff --git a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc index d86011cf573..0f3e09690e0 100644 --- a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc +++ b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc @@ -39,7 +39,7 @@ test_kiritimati() auto* tz = locate_zone("Pacific/Kiritimati"); local_seconds t = local_days(1994y/December/31); - sys_seconds ut(t.time_since_epoch() /* FIXME: should be + 10h */); + sys_seconds ut(t.time_since_epoch() + 10h); sys_info info; info = tz->get_info(ut - 1s); VERIFY( info.offset == -10h ); @@ -65,7 +65,9 @@ test_apia() auto* tz = locate_zone("Pacific/Apia"); local_seconds t = local_days(2011y/December/29) + 24h; - sys_seconds ut(t.time_since_epoch() /* FIXME: should be + 10h */ - 24h ); + // FIXME: this should be + 10h but we do not account for DST yet, so + 11h. + // The 24h is because we don't parse the "24" in the Zone line (PR 124513). + sys_seconds ut(t.time_since_epoch() + 11h - 24h ); sys_info info; info = tz->get_info(ut - 1s); VERIFY( info.offset == (-11h + info.save) ); diff --git a/libstdc++-v3/testsuite/std/time/time_zone/get_info_sys.cc b/libstdc++-v3/testsuite/std/time/time_zone/get_info_sys.cc index 769c7744017..88f16b76ff4 100644 --- a/libstdc++-v3/testsuite/std/time/time_zone/get_info_sys.cc +++ b/libstdc++-v3/testsuite/std/time/time_zone/get_info_sys.cc @@ -12,33 +12,37 @@ test_zurich() const time_zone* const tz = locate_zone("Europe/Zurich"); { - sys_days d = 1853y/July/16; + sys_days d = 1853y/July/16; // On this date ... + auto offset = 34min + 8s; // ... local time is this far ahead of UTC, + auto t = d - offset; // so LMT to BMT transition is at this time. - auto info = tz->get_info(d - 1s); - VERIFY( info.offset == (34min + 8s) ); + auto info = tz->get_info(t - 1s); + VERIFY( info.offset == offset ); VERIFY( info.abbrev == "LMT" ); - info = tz->get_info(d); + info = tz->get_info(t); VERIFY( info.offset == (29min + 46s) ); VERIFY( info.abbrev == "BMT" ); - info = tz->get_info(d + 1s); + info = tz->get_info(t + 1s); VERIFY( info.offset == (29min + 46s) ); VERIFY( info.abbrev == "BMT" ); - info = tz->get_info(d + 0.001s); + info = tz->get_info(t + 0.001s); VERIFY( info.offset == (29min + 46s) ); VERIFY( info.abbrev == "BMT" ); } { sys_days d = 1894y/June/1; + auto offset = 29min + 46s; + auto t = d - offset; - auto info = tz->get_info(d - 1s); - VERIFY( info.offset == (29min + 46s) ); + auto info = tz->get_info(t - 1s); + VERIFY( info.offset == offset ); VERIFY( info.abbrev == "BMT" ); - info = tz->get_info(d); + info = tz->get_info(t); VERIFY( info.offset == 1h ); VERIFY( info.abbrev == "CET" ); } diff --git a/libstdc++-v3/testsuite/std/time/zoned_time/1.cc b/libstdc++-v3/testsuite/std/time/zoned_time/1.cc index 1623aca1c7a..a77cd99dd55 100644 --- a/libstdc++-v3/testsuite/std/time/zoned_time/1.cc +++ b/libstdc++-v3/testsuite/std/time/zoned_time/1.cc @@ -48,24 +48,26 @@ test_zurich() const time_zone* const zurich = locate_zone("Europe/Zurich"); { - sys_days d = 1853y/July/16; + sys_days d = 1853y/July/16; // On this date ... + auto offset = 34min + 8s; // ... local time is this far ahead of UTC, + auto t = d - offset; // so LMT to BMT transition is at this time. - auto z = zoned_seconds(zurich, sys_seconds(d) - 1s); + auto z = zoned_seconds(zurich, t - 1s); auto info = z.get_info(); - VERIFY( info.offset == (34min + 8s) ); + VERIFY( info.offset == offset ); VERIFY( info.abbrev == "LMT" ); - z = zoned_seconds(zurich, d); + z = zoned_seconds(zurich, t); info = z.get_info(); VERIFY( info.offset == (29min + 46s) ); VERIFY( info.abbrev == "BMT" ); - z = zoned_seconds(zurich, d + 1s); + z = zoned_seconds(zurich, t + 1s); info = z.get_info(); VERIFY( info.offset == (29min + 46s) ); VERIFY( info.abbrev == "BMT" ); - auto z2 = zoned_time(zurich, d + 0.001s); + auto z2 = zoned_time(zurich, t + 0.001s); info = z2.get_info(); VERIFY( info.offset == (29min + 46s) ); VERIFY( info.abbrev == "BMT" ); @@ -73,13 +75,15 @@ test_zurich() { sys_days d = 1894y/June/1; + auto offset = 29min + 46s; + auto t = d - offset; - auto z = zoned_seconds(zurich, sys_seconds(d) - 1s); + auto z = zoned_seconds(zurich, t - 1s); auto info = z.get_info(); VERIFY( info.offset == (29min + 46s) ); VERIFY( info.abbrev == "BMT" ); - z = zoned_seconds(zurich, d); + z = zoned_seconds(zurich, t); info = z.get_info(); VERIFY( info.offset == 1h ); VERIFY( info.abbrev == "CET" ); commit 951a5779aa7798e632ab2db8272c3c3510422e4a Author: Jonathan Wakely Date: Thu Mar 19 11:42:48 2026 +0000 libstdc++: Fix parsing of UNTIL times in tzdata.zi [PR124513] Zone lines ending with a plain number as the time for the DST transition (e.g. "2026 Mar 16 2") were incorrectly parsed as changing at midnight. The problem was that eofbit got set after extracting the "2" from the stream using `in >> i`, then the `in >> at.indicator` expression failed and set failbit, so that the `if (in >> at.indicator)` condition was always false and so the assignment to at.time guarded by that condition was never performed. So the at.time member was always left equal to zero, i.e. midnight. Suffixed times such as "2s" or "2u" were parsed correctly. This commit fixes the operator>> overload for the Indicator enum to not cause failbit to be set if eofbit is already set. This means that the `in >> at.indicator` expression yields true when converted to bool, and the assignment to at.time happens. Not trying to extract an Indicator when eofbit is already set is correct, because it's valid for there to be no indicator suffix on an AT time (that just means the time should be interpreted as wall time). There was also a bug in the handling of a "-" value for the time, which is supposed to mean midnight but was not being parsed due to failing to skip leading whitespace. That did no harm in most cases, because the "-" would not be extracted from the stream but would then cause a failure to parse an integer number of hours, and no time would be set, causing it to default to midnight, which is what "-" means anyway. However, a value of "-u" is supposed to mean midnight UTC and "-s" is supposed to mean midnight standard time, and the indicators for UTC or standard were not being set in those cases. This fix uses std::ws to skip initial whitespace, and then correctly handles "-" followed by EOF. libstdc++-v3/ChangeLog: PR libstdc++/124513 * src/c++20/tzdb.cc (operator>>(istream&, at_time::Indicator&)): Do not peek at the next character if eofbit is already set. (istream& operator>>(istream&, at_time&)): Skip whitespace before the first character. Handle EOF when parsing "-" as time. Do not peek for ":" or "." if eofbit already set. * testsuite/std/time/time_zone/116110.cc (test_apia): Remove offset of 24h now that the UNTIL time is parsed correctly. * testsuite/std/time/time_zone/124513.cc: New test. Reviewed-by: Tomasz Kamiński (cherry picked from commit fbc5d2b1ab17ba7eb919f2c77f5788645c18006a) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 3612f01638a..dd7541f9bab 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -247,11 +247,14 @@ namespace std::chrono // If not, indic is unchanged. Callers should set a default first. friend istream& operator>>(istream& in, Indicator& indic) { - auto [val, yes] = at_time::is_indicator(in.peek()); - if (yes) + if (!in.eof()) { - in.ignore(1); - indic = val; + auto [val, yes] = at_time::is_indicator(in.peek()); + if (yes) + { + in.ignore(1); + indic = val; + } } return in; } @@ -2101,10 +2104,11 @@ namespace std::chrono istream& operator>>(istream& in, at_time& at) { int sign = 1; - if (in.peek() == '-') + if (ws(in).peek() == '-') { in.ignore(1); - if (auto [val, yes] = at_time::is_indicator(in.peek()); yes) + if (auto [val, yes] = at_time::is_indicator(in.peek()); + in.eof() || yes) { in.ignore(1); at.time = 0s; @@ -2123,11 +2127,11 @@ namespace std::chrono in.ignore(1); // discard the colon. in >> i; m = minutes{i}; - if (in.peek() == ':') + if (!in.eof() && in.peek() == ':') { in.ignore(1); // discard the colon. in >> i; - if (in.peek() == '.') + if (!in.eof() && in.peek() == '.') { double frac; in >> frac; diff --git a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc index 0f3e09690e0..26b9ba33c31 100644 --- a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc +++ b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc @@ -66,8 +66,7 @@ test_apia() local_seconds t = local_days(2011y/December/29) + 24h; // FIXME: this should be + 10h but we do not account for DST yet, so + 11h. - // The 24h is because we don't parse the "24" in the Zone line (PR 124513). - sys_seconds ut(t.time_since_epoch() + 11h - 24h ); + sys_seconds ut(t.time_since_epoch() + 11h ); sys_info info; info = tz->get_info(ut - 1s); VERIFY( info.offset == (-11h + info.save) ); diff --git a/libstdc++-v3/testsuite/std/time/time_zone/124513.cc b/libstdc++-v3/testsuite/std/time/time_zone/124513.cc new file mode 100644 index 00000000000..49d7ba8bb01 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/time_zone/124513.cc @@ -0,0 +1,111 @@ +// { dg-do run { target c++20 } } +// { dg-require-effective-target tzdb } +// { dg-require-effective-target cxx11_abi } +// { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } } + +#include +#include +#include + +static bool override_used = false; + +namespace __gnu_cxx +{ + const char* zoneinfo_dir_override() { + override_used = true; + return "./"; + } +} + +void +test_mawson() +{ + using namespace std::chrono; + + std::ofstream("tzdata.zi") << R"(# version test1 +Z Antarctica/Mawson 0 - -00 1954 F 13 + 6 - %z 2009 O 18 2 + 5 - %z +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test1" ); + + auto zone = locate_zone("Antarctica/Mawson"); + auto info = zone->get_info(sys_days(2009y/October/19)); + VERIFY( info.begin == sys_days(2009y/October/17) + 20h); +} + +void +test_custom() +{ + using namespace std::chrono; + + std::ofstream("tzdata.zi") << R"(# version test2 +Z Test/Zomg 3:00:00 - LMT 1990 Mar 1 2 + 4 - DST 1990 Oct 1 2 + 3 - STD 1991 Mar 1 3:30 + 3 1 DST 1991 Oct 1 3:45:01 + 3 - STD 1992 Mar 1 - + 3 1 DST 1992 Oct 1 -u + 3 - STD 1993 Mar 1 -s + 3 2 DST 1993 Oct 1 -s + 3 - STD + +Z Test/Zoinks 0:00 - LMT 1990 Mar 1 2 + 0:00 1:00 DST 1990 Oct 1 3 + 0:00 - STD 1991 Mar 1 1:30 + 0:00 1:00 DST 1991 Oct 1 3:30 + 0:00 - STD +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test2" ); + + const auto offset = 3h; + + const time_zone* zone; + sys_info info; + + zone = locate_zone("Test/Zomg"); + info = zone->get_info(sys_days(1990y/June/1)); + VERIFY( info.begin == sys_days(1990y/March/1) + 2h - 3h); + VERIFY( info.end == sys_days(1990y/October/1) + 2h - 4h); + + info = zone->get_info(sys_days(1991y/June/1)); + VERIFY( info.begin == sys_days(1991y/March/1) + 3h + 30min - 3h); + VERIFY( info.end == sys_days(1991y/October/1) + 3h + 45min + 1s - 4h); + + info = zone->get_info(sys_days(1992y/June/1)); + VERIFY( info.begin == sys_days(1992y/March/1) - 3h); + VERIFY( info.end == sys_days(1992y/October/1)); // -u means midnight UTC + + info = zone->get_info(sys_days(1992y/November/1)); + VERIFY( info.begin == sys_days(1992y/October/1)); // -u means midnight UTC + VERIFY( info.end == sys_days(1993y/March/1) - 3h); // -s means midnight STD + + info = zone->get_info(sys_days(1993y/June/1)); + VERIFY( info.begin == sys_days(1993y/March/1) -3h); // -s means midnight STD + VERIFY( info.end == sys_days(1993y/October/1) - 3h); + + + zone = locate_zone("Test/Zoinks"); + info = zone->get_info(sys_days(1990y/June/1)); + VERIFY( info.begin == sys_days(1990y/March/1) + 2h); + VERIFY( info.end == sys_days(1990y/October/1) + 3h - 1h); + + info = zone->get_info(sys_days(1991y/June/1)); + VERIFY( info.begin == sys_days(1991y/March/1) + 1h + 30min); + VERIFY( info.end == sys_days(1991y/October/1) + 3h + 30min - 1h); + + info = zone->get_info(sys_days(1992y/June/1)); + VERIFY( info.begin == sys_days(1991y/October/1) + 3h + 30min - 1h); +} + +int main() +{ + test_custom(); + test_mawson(); +} commit a4aac975dbc905e0a57dbf3c3f56185e93f0203e Author: Álvaro Begué Date: Sun Apr 26 19:51:17 2026 -0400 libstdc++: Fix numeric save offset on Zone lines [PR124851] When a Zone line specifies a numeric value as its RULES field (the constant DST save value for that zone line, e.g. Africa/Gaborone's "2 1 CAST" line), the parser stored the standard offset alone in ZoneInfo::m_offset. ZoneInfo::to() then returned that as sys_info::offset, dropping the numeric save and reporting a total offset that was wrong by the save amount. This was inconsistent with the two ZoneInfo constructors that take a sys_info, which previously stored the *total* offset (stdoff + save) in m_offset. As a result m_offset's semantics depended on which code path created the ZoneInfo, and only the parser path's lines with non-zero numeric save were observably broken. Fix by giving m_offset a single semantics: always the standard offset only. The two sys_info-taking constructors now subtract the save before storing, and to(0 adds it back when reconstructing the sys_info. The remaining .offset() callers inside _M_get_sys_info already expect the standard offset (they are computing rule firing times, where the save component is added separately from the active rule's save value), so no other call sites need adjustment. libstdc++-v3/ChangeLog: PR libstdc++/124851 * src/c++20/tzdb.cc (ZoneInfo::ZoneInfo(sys_info&&)): Store stdoff only in m_offset (subtract info.save). (ZoneInfo::ZoneInfo(const pair&)): Likewise. (ZoneInfo::offset()): Document new semantics. (ZoneInfo::to(sys_info&)): Add m_save back to offset() when populating sys_info::offset. * testsuite/std/time/time_zone/numeric_save.cc: New test. Reviewed-by: Jonathan Wakely Reviewed-by: Tomasz Kamiński Signed-off-by: Álvaro Begué (cherry picked from commit 864f26bd7548d1a290b334b8f5375199449fcff5) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index dd7541f9bab..18a3768d2f4 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -449,12 +449,13 @@ namespace std::chrono ZoneInfo(sys_info&& info) : m_buf(std::move(info.abbrev)), m_expanded(true), m_save(info.save), - m_offset(info.offset), m_until(info.end) + m_offset(info.offset - seconds(info.save)), m_until(info.end) { } ZoneInfo(const pair& info) - : m_expanded(true), m_save(info.first.save), m_offset(info.first.offset), - m_until(info.first.end) + : m_expanded(true), m_save(info.first.save), + m_offset(info.first.offset - seconds(info.first.save)), + m_until(info.first.end) { if (info.second.size()) { @@ -465,7 +466,7 @@ namespace std::chrono m_buf += info.first.abbrev; } - // STDOFF: Seconds from UTC during standard time. + // STDOFF: Seconds from UTC during standard time (without any save). seconds offset() const noexcept { return m_offset; } @@ -510,7 +511,7 @@ namespace std::chrono return false; info.end = until(); - info.offset = offset(); + info.offset = offset() + seconds(m_save); info.save = minutes(m_save); info.abbrev = format(); format_abbrev_str(info); // expand %z diff --git a/libstdc++-v3/testsuite/std/time/time_zone/numeric_save.cc b/libstdc++-v3/testsuite/std/time/time_zone/numeric_save.cc new file mode 100644 index 00000000000..687524bb355 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/time_zone/numeric_save.cc @@ -0,0 +1,58 @@ +// { dg-do run { target c++20 } } +// { dg-require-effective-target tzdb } +// { dg-require-effective-target cxx11_abi } +// { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } } + +// When a Zone line specifies a numeric value as its RULES field, that +// value is the constant DST save value for that zone line. Per +// [time.zone.info.sys] sys_info::offset is the total UTC offset +// (stdoff + save). + +#include +#include +#include + +static bool override_used = false; + +namespace __gnu_cxx +{ + const char* zoneinfo_dir_override() { + override_used = true; + return "./"; + } +} + +int +main() +{ + using namespace std::chrono; + + std::ofstream("tzdata.zi") << R"(# version test_numeric_save +Z Test/Gaborone 2 - CAT 1943 Sep 19 2 + 2 1 CAST 1944 Mar 19 2 + 2 - CAT +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test_numeric_save" ); + + auto* tz = locate_zone("Test/Gaborone"); + + // Sample well inside the CAST (numeric-save) zone line. + auto info = tz->get_info(sys_days(1943y/December/15)); + VERIFY( info.offset == 3h ); // stdoff +2h + save +1h + VERIFY( info.save == 60min ); + VERIFY( info.abbrev == "CAST" ); + + // Bordering zone lines should report the standard offset with save 0. + auto before = tz->get_info(sys_days(1943y/September/1)); + VERIFY( before.offset == 2h ); + VERIFY( before.save == 0min ); + VERIFY( before.abbrev == "CAT" ); + + auto after = tz->get_info(sys_days(1944y/April/15)); + VERIFY( after.offset == 2h ); + VERIFY( after.save == 0min ); + VERIFY( after.abbrev == "CAT" ); +} commit c7c4fa25e59db38994195bbe75341a7adc8987d7 Author: Álvaro Begué Date: Tue May 12 14:55:01 2026 +0200 libstdc++: Support ON-format DAY in Zone UNTIL field [PR124852] The Zone-line UNTIL parser only accepted a plain day-of-month integer for the DAY field, while the tzdata.zi grammar accepts the same ON-style forms as Rule lines: lastSun, Sun>=8, Sat<=20, etc. Real zones use these forms in their UNTIL DAY: Europe/Simferopol's `3 - MSK 1997 Mar lastSu 1u`, for instance, became `Mar 1` (silently misparsed) instead of `Mar 30`, leaving Simferopol an extra 29 days in MSK. The previous parser's `int d = 1; in >> m >> d >> t;` chain silently left d == 1 when the day token wasn't a digit, then went on to parse the remainder as the TIME field. Renames on_day to on_month_day, and factor out the day-component parser parser from operator>>(istream&, on_day&) as operator>> for newly added on_day_t tag type, and reuse it for the UNTIL DAY field. The operator handles all three on_day forms (DayOfMonth, LastWeekday, LessEq / GreaterEq). The MONTH-only and YEAR-only short forms are still accepted because the DAY/TIME fields are optional and default to day 1, time 00:00. The on_day struct's pin() method handles the year/month-relative resolution. The DAY field is unambiguously distinguishable from a TIME field that could otherwise follow the MONTH directly: per zic's grammar, MONTH must be followed by DAY before any TIME is allowed. So we always attempt to parse a DAY if any non-whitespace remains after the MONTH. libstdc++-v3/ChangeLog: PR libstdc++/124852 * src/c++20/tzdb.cc (on_day): Rename to... (on_day_month): Rename from on_day. (on_day_month::on_day_t, on_day_month::on_day): Define. (operator>>(istream&, on_day_t&&)): Factored out of operator>>(istream&, on_day&). (operator>>(istream&, on_day&)): Use on_day_t parser. (operator>>(istream&, ZoneInfo&)): Replace the integer DAY parser with on_day_t for the UNTIL field. * testsuite/std/time/time_zone/until_day_on.cc: New test. Reviewed-by: Jonathan Wakely Co-authored-by: Tomasz Kamiński Signed-off-by: Álvaro Begué Signed-off-by: Tomasz Kamiński (cherry picked from commit 2b5e55eea69acbc6e46fa3463164e62bcc436e0d) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 18a3768d2f4..42c73426b92 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -185,7 +185,7 @@ namespace std::chrono #include "tzdb_globals.h" - // The data structures defined in this file (Rule, on_day, at_time etc.) + // The data structures defined in this file (Rule, on_month_day, at_time etc.) // are used to represent the information parsed from the tzdata.zi file // described at https://man7.org/linux/man-pages/man8/zic.8.html#FILES @@ -274,7 +274,7 @@ namespace std::chrono }; // The IN and ON fields of a RULE record, e.g. "March lastSunday". - struct on_day + struct on_month_day { using rep = uint_least16_t; // Equivalent to Kind, chrono::month, chrono::day, chrono::weekday, @@ -338,7 +338,15 @@ namespace std::chrono return ymd; } - friend istream& operator>>(istream&, on_day&); + struct on_day_t // tag type for reading ON and DAY fields only + { + on_month_day& parent; + friend istream& operator>>(istream&, on_day_t&&); + }; + + on_day_t on_day() { return on_day_t{*this}; } + + friend istream& operator>>(istream&, on_month_day&); }; // Wrapper for two chrono::year values, which reads the FROM and TO @@ -561,9 +569,9 @@ namespace std::chrono // A RULE record from the tzdata.zi timezone info file. struct Rule { - // This allows on_day to reuse padding of at_time. + // This allows on_month_day to reuse padding of at_time. // This keeps the size to 8 bytes and the alignment to 4 bytes. - struct datetime : at_time { on_day day; }; + struct datetime : at_time { on_month_day day; }; // TODO combining name+letters into a single string (like in ZoneInfo) // would save sizeof(string) and make Rule fit in a single cacheline. @@ -625,17 +633,17 @@ namespace std::chrono << ' ' << r.when.day.get_month() << ' '; switch (r.when.day.kind) { - case on_day::DayOfMonth: + case on_month_day::DayOfMonth: out << (unsigned)r.when.day.get_day(); break; - case on_day::LastWeekday: + case on_month_day::LastWeekday: out << "last" << weekday(r.when.day.day_of_week); break; - case on_day::LessEq: + case on_month_day::LessEq: out << weekday(r.when.day.day_of_week) << " <= " << r.when.day.day_of_month; break; - case on_day::GreaterEq: + case on_month_day::GreaterEq: out << weekday(r.when.day.day_of_week) << " >= " << r.when.day.day_of_month; break; @@ -2047,22 +2055,25 @@ namespace std::chrono } }; - istream& operator>>(istream& in, on_day& to) + // Read the day-component of an on_month_day expression (everything after + // the month). Three forms are accepted: a plain day-of-month number, + // "lastXxx" where Xxx is a weekday name (LastWeekday), or "Xxx<=N" or + // "Xxx>=N" (LessEq / GreaterEq). On failure the function sets failbit + // and leaves `to.parent` unchanged. + istream& operator>>(istream& in, on_month_day::on_day_t&& to) { - on_day on{}; - abbrev_month m{}; - in >> m; - on.month = static_cast(m.m); + using enum on_month_day::Kind; + + on_month_day& on = to.parent; int c = ws(in).peek(); if ('0' <= c && c <= '9') { - on.kind = on_day::DayOfMonth; unsigned d; in >> d; if (d <= 31) [[likely]] { + on.kind = DayOfMonth; on.day_of_month = d; - to = on; return in; } } @@ -2071,9 +2082,8 @@ namespace std::chrono in.ignore(4); if (abbrev_weekday w{}; in >> w) [[likely]] { - on.kind = on_day::LastWeekday; + on.kind = LastWeekday; on.day_of_week = w.wd.c_encoding(); - to = on; return in; } } @@ -2085,14 +2095,13 @@ namespace std::chrono { if (in.get() == '=') { - on.kind = c == '<' ? on_day::LessEq : on_day::GreaterEq; - on.day_of_week = w.wd.c_encoding(); unsigned d; in >> d; if (d <= 31) [[likely]] { + on.kind = c == '<' ? LessEq : GreaterEq; + on.day_of_week = w.wd.c_encoding(); on.day_of_month = d; - to = on; return in; } } @@ -2102,6 +2111,17 @@ namespace std::chrono return in; } + istream& operator>>(istream& in, on_month_day& to) + { + on_month_day md{}; + abbrev_month m{}; + in >> m; + md.month = static_cast(m.m); + if (in >> md.on_day()) + to = md; + return in; + } + istream& operator>>(istream& in, at_time& at) { int sign = 1; @@ -2204,12 +2224,16 @@ namespace std::chrono in.exceptions(ios::goodbit); // Don't throw ios::failure if YEAR absent. if (int y = int(year::max()); in >> y) { - abbrev_month m{January}; - int d = 1; + on_month_day on{ .kind = on_month_day::DayOfMonth, + .month = 1, .day_of_month = 1 }; at_time t{}; - // XXX DAY should support ON format, e.g. lastSun or Sun>=8 - in >> m >> d >> t; - inf.m_until = sys_days(year(y)/m.m/day(d)) + seconds(t.time); + if (abbrev_month m{January}; in >> m) + { + on.month = static_cast(m.m); + in >> on.on_day() >> t; + } + year_month_day ymd = on.pin(year(y)); + inf.m_until = sys_days(ymd) + seconds(t.time); if (t.indicator != at_time::Universal) { // UNTIL uses "the rules in effect just before the transition" // adjust by STDOFF diff --git a/libstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc b/libstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc new file mode 100644 index 00000000000..38e4bc254cc --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc @@ -0,0 +1,222 @@ +// { dg-do run { target c++20 } } +// { dg-require-effective-target tzdb } +// { dg-require-effective-target cxx11_abi } +// { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } } + +// The DAY portion of a Zone line's UNTIL field accepts not only a +// numeric day-of-month but also "lastXxx" (last weekday in the month) +// and "Xxx<=N" / "Xxx>=N" forms, just like the ON field of a Rule line. +// +// Real-world example: Europe/Simferopol has +// 3 - MSK 1997 Mar lastSu 1u +// which places the boundary on 1997-03-30 (the last Sunday of March). + +#include +#include +#include + +static bool override_used = false; + +namespace __gnu_cxx +{ + const char* zoneinfo_dir_override() { + override_used = true; + return "./"; + } +} + +void +test_lastsu() +{ + using namespace std::chrono; + + std::ofstream("tzdata.zi") << R"(# version test_lastsu +Z Test/LastSu 3 - MSK 1997 Mar lastSu 1u + 3 - X +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test_lastsu" ); + + auto* tz = locate_zone("Test/LastSu"); + + // True boundary: 1997-03-30 01:00 UTC (lastSu of March 1997 is Mar 30, + // and the indicator is 'u' = Universal so no offset adjustment). + sys_seconds boundary = sys_days{1997y/March/30} + 1h; + + // Just before: still in the MSK line. + auto before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "MSK" ); + VERIFY( before.offset == 3h ); + + // At/after the boundary: in the X line. + auto at = tz->get_info(boundary); + VERIFY( at.abbrev == "X" ); + + // Check that the lastSu day is parsed correctly, and not defaulted + // to the 1st: a March 15 query must still be in the MSK line. + auto mid_march = tz->get_info(sys_days{1997y/March/15}); + VERIFY( mid_march.abbrev == "MSK" ); + VERIFY( mid_march.offset == 3h ); +} + +void +test_sun_ge_n() +{ + using namespace std::chrono; + + std::ofstream("tzdata.zi") << R"(# version test_sun_ge_n +Z Test/SunGE 0 - A 1990 Jun Sun>=8 0u + 0 - B +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test_sun_ge_n" ); + + auto* tz = locate_zone("Test/SunGE"); + + // First Sunday >= June 8 1990 = June 10 (June 8 1990 was a Friday). + sys_seconds boundary = sys_days{1990y/June/10}; + + auto before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "A" ); + auto at = tz->get_info(boundary); + VERIFY( at.abbrev == "B" ); + + // Check that Sun>=8 is parsed correctly, and not defaulted to the 1st. + auto early = tz->get_info(sys_days{1990y/June/1}); + VERIFY( early.abbrev == "A" ); +} + +void +test_sun_le_n() +{ + using namespace std::chrono; + + std::ofstream("tzdata.zi") << R"(# version test_sun_le_n +Z Test/SunLE 0 - A 1990 Jun Sun<=15 0u + 0 - B +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test_sun_le_n" ); + + auto* tz = locate_zone("Test/SunLE"); + + // Last Sunday <= June 15 1990 = June 10. + sys_seconds boundary = sys_days{1990y/June/10}; + + auto before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "A" ); + auto at = tz->get_info(boundary); + VERIFY( at.abbrev == "B" ); +} + +void +test_year_only() +{ + using namespace std::chrono; + + // MONTH, DAY and TIME default to January 1st 00:00 if not specified. + std::ofstream("tzdata.zi") << R"(# version test_year_only +Z Test/YearOnly 0 - A 1990 + 0 - B +Z Test/YearOnlyC 4 - C 1995 # comment + 4 - D +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test_year_only" ); + + auto* tz = locate_zone("Test/YearOnly"); + sys_seconds boundary = sys_days{1990y/January/1}; + auto before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "A" ); + auto at = tz->get_info(boundary); + VERIFY( at.abbrev == "B" ); + + tz = locate_zone("Test/YearOnlyC"); + boundary = sys_days{1995y/January/1} - 4h; + before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "C" ); + at = tz->get_info(boundary); + VERIFY( at.abbrev == "D" ); +} + +void +test_year_month_only() +{ + using namespace std::chrono; + + // DAY and TIME default to the 1st 00:00 if not specified. + std::ofstream("tzdata.zi") << R"(# version test_year_month_only +Z Test/YearMonth 0 - A 1990 Jul + 0 - B +Z Test/YearMonthC 3 - C 1995 Apr # comment + 3 - D +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test_year_month_only" ); + + auto* tz = locate_zone("Test/YearMonth"); + sys_seconds boundary = sys_days{1990y/July/1}; + auto before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "A" ); + auto at = tz->get_info(boundary); + VERIFY( at.abbrev == "B" ); + + tz = locate_zone("Test/YearMonthC"); + boundary = sys_days{1995y/April/1} - 3h; + before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "C" ); + at = tz->get_info(boundary); + VERIFY( at.abbrev == "D" ); +} + +void +test_year_month_day_only() +{ + using namespace std::chrono; + + std::ofstream("tzdata.zi") << R"(# version test_day_only +Z Test/DayOnly 0 - A 1997 Mar 12 + 0 - B +Z Test/DayOnlyC 5 - C 1998 Jun 14 # comment + 5 - D +)"; + + const auto& db = reload_tzdb(); + VERIFY( override_used ); // If this fails then XFAIL for the target. + VERIFY( db.version == "test_day_only" ); + + auto* tz = locate_zone("Test/DayOnly"); + sys_seconds boundary = sys_days{1997y/March/12}; + auto before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "A" ); + auto at = tz->get_info(boundary); + VERIFY( at.abbrev == "B" ); + + tz = locate_zone("Test/DayOnlyC"); + boundary = sys_days{1998y/June/14} - 5h; + before = tz->get_info(boundary - 1s); + VERIFY( before.abbrev == "C" ); + at = tz->get_info(boundary); + VERIFY( at.abbrev == "D" ); +} + +int +main() +{ + test_lastsu(); + test_sun_ge_n(); + test_sun_le_n(); + test_year_only(); + test_year_month_only(); + test_year_month_day_only(); +} commit 9b2b0e0ccf5f47dc1496616440726fac569a52c9 Author: Tomasz Kamiński Date: Wed May 13 09:17:47 2026 +0200 libstdc++: Use on_month_day istream operator in ZoneInfo parsing. [PR124852] This patch changes ZoneInfo parsing, to use operator>> for on_month_day directly, and removes on_day tag. The operator>>(istream&, on_month_day) is updated to not override on.month if the MONTH component is not present, and set failbit instead. This allows to use in >> on >> time, to parse MONTH DAY TIME. We also handle failure to parse day number N for Www>=N or Www<=N productions, by leaving the day part of input unchanged and setting failbit. PR libstdc++/124852 libstdc++-v3/ChangeLog: * src/c++20/tzdb.cc (on_month_day::on_day_t, on_month_day::on_day): Remove. (operator>>(istream&, on_month_day::day_t&)): Inlined into... (operator>>(istream&, on_month_day)): Inlined on_month_day::on_day. Avoid modifying on.month if MONTH is not present. Report failure on failure to parse day for LessEq / GreaterEq. Reviewed-by: Jonathan Wakely Signed-off-by: Tomasz Kamiński (cherry picked from commit 2451667193e4e00b49c4ef9d95c0a3a1aa955f82) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 42c73426b92..3c19f5c6467 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -338,13 +338,6 @@ namespace std::chrono return ymd; } - struct on_day_t // tag type for reading ON and DAY fields only - { - on_month_day& parent; - friend istream& operator>>(istream&, on_day_t&&); - }; - - on_day_t on_day() { return on_day_t{*this}; } friend istream& operator>>(istream&, on_month_day&); }; @@ -2055,73 +2048,55 @@ namespace std::chrono } }; - // Read the day-component of an on_month_day expression (everything after - // the month). Three forms are accepted: a plain day-of-month number, - // "lastXxx" where Xxx is a weekday name (LastWeekday), or "Xxx<=N" or - // "Xxx>=N" (LessEq / GreaterEq). On failure the function sets failbit - // and leaves `to.parent` unchanged. - istream& operator>>(istream& in, on_month_day::on_day_t&& to) + // Read the MONTH DAY. Three forms are accepted for DAY: + // * a plain day-of-month number (DayOfMonth), + // * "lastWww" where Www is a weekday name (LastWeekday), + // * "Www<=N" or "Www>=N" (LessEq / GreaterEq). + // On failure to read either MONTH or DAY this function sets + // failbit. If DAY is not parsed, only `on.month` is modified, + // otherwise `on` is left unchanged. + istream& operator>>(istream& in, on_month_day& on) { using enum on_month_day::Kind; - - on_month_day& on = to.parent; - int c = ws(in).peek(); - if ('0' <= c && c <= '9') + if (abbrev_month m{}; in >> m) { - unsigned d; - in >> d; - if (d <= 31) [[likely]] + on.month = static_cast(m.m); + if (int c = ws(in).peek(); '0' <= c && c <= '9') { - on.kind = DayOfMonth; - on.day_of_month = d; - return in; + if (unsigned d; (in >> d) && (d <= 31)) [[likely]] + { + on.kind = DayOfMonth; + on.day_of_month = d; + return in; + } } - } - else if (c == 'l') // lastSunday, lastWed, ... - { - in.ignore(4); - if (abbrev_weekday w{}; in >> w) [[likely]] + else if (c == 'l') // lastSunday, lastWed, ... { - on.kind = LastWeekday; - on.day_of_week = w.wd.c_encoding(); - return in; + in.ignore(4); + if (abbrev_weekday w{}; in >> w) [[likely]] + { + on.kind = LastWeekday; + on.day_of_week = w.wd.c_encoding(); + return in; + } } - } - else - { - abbrev_weekday w; - in >> w; - if (auto c = in.get(); c == '<' || c == '>') + else if (abbrev_weekday w; in >> w) [[likely]] { - if (in.get() == '=') - { - unsigned d; - in >> d; - if (d <= 31) [[likely]] + if (c = in.get(); c == '<' || c == '>') + if (in.get() == '=') + if (unsigned d; (in >> d) && (d <= 31)) [[likely]] { on.kind = c == '<' ? LessEq : GreaterEq; on.day_of_week = w.wd.c_encoding(); on.day_of_month = d; return in; } - } } } in.setstate(ios::failbit); return in; } - istream& operator>>(istream& in, on_month_day& to) - { - on_month_day md{}; - abbrev_month m{}; - in >> m; - md.month = static_cast(m.m); - if (in >> md.on_day()) - to = md; - return in; - } - istream& operator>>(istream& in, at_time& at) { int sign = 1; @@ -2227,11 +2202,7 @@ namespace std::chrono on_month_day on{ .kind = on_month_day::DayOfMonth, .month = 1, .day_of_month = 1 }; at_time t{}; - if (abbrev_month m{January}; in >> m) - { - on.month = static_cast(m.m); - in >> on.on_day() >> t; - } + in >> on >> t; year_month_day ymd = on.pin(year(y)); inf.m_until = sys_days(ymd) + seconds(t.time); if (t.indicator != at_time::Universal) commit 296b23d0b9e70cf8f416d0a502e0bfbf520fc4d4 Author: Tomasz Kamiński Date: Fri Jul 17 21:14:42 2026 +0200 libstdc++: Fix condition for stopping lazy zone expansion [PR116110] At indicated by the pre-existing comment, the lazy zone expansion can be only resumed from STD (save == 0) zone. However, the current condition for stopping on DST (save != 0) doesn't ensure that, as some rule specify transitions between DST zones. For example August 1945 of Y rule used by America/Dawson only change letters: Y 1942 o - F 9 2 1 W Y 1945 o - Au 14 23u 1 P This patch correct the condition, by using next_rule (i.e. one applying after last expanded zone): either there is no zone (last expanded range) or it have save zero. libstdc++-v3/ChangeLog: PR libstdc++/116110 * src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Correct condition for stopping zone expansion before STD zone. * testsuite/std/time/time_zone/116110.cc (test_dawson): Add test for America/Dawson August 1945 transition. Reviewed-by: Jonathan Wakely Signed-off-by: Tomasz Kamiński (cherry picked from commit 57a09e2f362ab8a8be84250fd4266b333a74b977) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 3c19f5c6467..25dd5d2e4de 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -989,10 +989,10 @@ namespace std::chrono result_index = new_infos.size() - 1; else if (result_index >= 0 && !merged) { - // Finish on a DST sys_info if possible, so that if we resume + // Finish before a STD sys_info if possible, so that if we resume // generating sys_info objects after this time point, save=0 // should be correct for the next sys_info. - if (num_after > 1 || info.save != 0min) + if (num_after > 1 || !next_rule || next_rule->save == 0s) --num_after; } diff --git a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc index 26b9ba33c31..3751c5df910 100644 --- a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc +++ b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc @@ -78,9 +78,50 @@ test_apia() VERIFY( info.abbrev == "+14" ); } +void +test_dawson() +{ + /* 1945 August rule change changes letters (abbrev) + and remains in DST: + R Y 1942 o - F 9 2 1 W + R Y 1945 o - Au 14 23u 1 P + R Y 1945 o - S 30 2 0 S + Z America/Dawson -9:17:40 - LMT 1900 Au 20 + -9 Y Y%sT 1965 + -9 Yu Y%sT 1973 O 28 + */ + + auto* tz = locate_zone("America/Dawson"); + + // Triggers rule transitions from the start. + sys_info info = tz->get_info(sys_days(1900y/August/20) + 10h); + VERIFY( info.offset == -9h ); + VERIFY( info.save == 0min ); + VERIFY( info.abbrev == "YST" ); + + // Check YWT transition at 02:00 + 9h UT, that is DST + info = tz->get_info(sys_days(1942y/February/9) + 11h); + VERIFY( info.offset == -8h ); + VERIFY( info.save == 60min ); + VERIFY( info.abbrev == "YWT" ); + + // Check YPT transition at 23:00 UT, remains DST + info = tz->get_info(sys_days(1945y/August/14) + 23h); + VERIFY( info.offset == -8h ); + VERIFY( info.save == 60min ); + VERIFY( info.abbrev == "YPT" ); + + // Check YST transition at 02:00 + 8h UT, switches to STD + info = tz->get_info(sys_days(1945y/September/30) + 10h); + VERIFY( info.offset == -9h ); + VERIFY( info.save == 0min ); + VERIFY( info.abbrev == "YST" ); +} + int main() { test_broken_hill(); test_kiritimati(); test_apia(); + test_dawson(); } commit b78e22e1298577aa8ff932c3e128675a9e88b712 Author: GCC Administrator Date: Sat Aug 1 00:19:56 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4856dc75a20..89a5952fcdc 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260731 +20260801 diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 57d4cedcd1c..5fb05af306b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,100 @@ +2026-07-31 Tomasz Kamiński + + Backported from master: + 2026-07-20 Tomasz Kamiński + + PR libstdc++/116110 + * src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Correct + condition for stopping zone expansion before STD zone. + * testsuite/std/time/time_zone/116110.cc (test_dawson): + Add test for America/Dawson August 1945 transition. + +2026-07-31 Tomasz Kamiński + + Backported from master: + 2026-05-18 Tomasz Kamiński + + PR libstdc++/124852 + * src/c++20/tzdb.cc (on_month_day::on_day_t, on_month_day::on_day): + Remove. + (operator>>(istream&, on_month_day::day_t&)): Inlined into... + (operator>>(istream&, on_month_day)): Inlined on_month_day::on_day. + Avoid modifying on.month if MONTH is not present. Report failure + on failure to parse day for LessEq / GreaterEq. + +2026-07-31 Álvaro Begué + + Backported from master: + 2026-05-13 Álvaro Begué + Tomasz Kamiński + + PR libstdc++/124852 + * src/c++20/tzdb.cc (on_day): Rename to... + (on_day_month): Rename from on_day. + (on_day_month::on_day_t, on_day_month::on_day): Define. + (operator>>(istream&, on_day_t&&)): Factored out of + operator>>(istream&, on_day&). + (operator>>(istream&, on_day&)): Use on_day_t parser. + (operator>>(istream&, ZoneInfo&)): Replace the integer DAY + parser with on_day_t for the UNTIL field. + * testsuite/std/time/time_zone/until_day_on.cc: New test. + +2026-07-31 Álvaro Begué + + Backported from master: + 2026-05-13 Álvaro Begué + + PR libstdc++/124851 + * src/c++20/tzdb.cc (ZoneInfo::ZoneInfo(sys_info&&)): Store + stdoff only in m_offset (subtract info.save). + (ZoneInfo::ZoneInfo(const pair&)): + Likewise. + (ZoneInfo::offset()): Document new semantics. + (ZoneInfo::to(sys_info&)): Add m_save back to offset() when + populating sys_info::offset. + * testsuite/std/time/time_zone/numeric_save.cc: New test. + +2026-07-31 Jonathan Wakely + + Backported from master: + 2026-03-19 Jonathan Wakely + + PR libstdc++/124513 + * src/c++20/tzdb.cc (operator>>(istream&, at_time::Indicator&)): + Do not peek at the next character if eofbit is already set. + (istream& operator>>(istream&, at_time&)): Skip whitespace + before the first character. Handle EOF when parsing "-" as time. + Do not peek for ":" or "." if eofbit already set. + * testsuite/std/time/time_zone/116110.cc (test_apia): Remove + offset of 24h now that the UNTIL time is parsed correctly. + * testsuite/std/time/time_zone/124513.cc: New test. + +2026-07-31 Jonathan Wakely + + Backported from master: + 2026-03-19 Jonathan Wakely + + PR libstdc++/116110 + * src/c++20/tzdb.cc (operator>>(istream&, ZoneInfo&)): Adjust + inf.m_until according to indicator suffix on AT time in UNTIL. + * testsuite/std/time/time_zone/116110.cc (test_kiritimati): + Remove FIXME now that the UNTIL time is adjusted for STDOFF. + (test_apia): Adjust FIXME now that UNTIL time is adusted for + STDOFF. + * testsuite/std/time/time_zone/get_info_sys.cc: Adjust expected + results to account for corrected logic. + * testsuite/std/time/zoned_time/1.cc: Likewise. + +2026-07-31 Jonathan Wakely + + Backported from master: + 2026-03-19 Jonathan Wakely + + PR libstdc++/116110 + * src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Update + info.offset and info.save to values from the active rule. + * testsuite/std/time/time_zone/116110.cc: New test. + 2026-06-27 Patrick Palka Backported from master: commit bb2ee2e3d1233155b16fe08ba5c38b60af0cdae5 Author: Jakub Jelinek Date: Mon Jul 20 10:30:43 2026 +0200 libsanitizer: Initialize local_head member [PR126307] The following patch cherry picks an upstream fix for this. 2026-07-20 Jakub Jelinek PR sanitizer/126307 * tsan/tsan_trace.h: Cherry-pick llvm-project revision cdfdb06c9155080ec97d6e4f4dd90b6e7cefb0ca. (cherry picked from commit b75f76eb7fbd6314d452471d5795d24f004de5f2) diff --git a/libsanitizer/tsan/tsan_trace.h b/libsanitizer/tsan/tsan_trace.h index 01bb7b34f43..1e791ff765f 100644 --- a/libsanitizer/tsan/tsan_trace.h +++ b/libsanitizer/tsan/tsan_trace.h @@ -190,7 +190,7 @@ struct Trace { Mutex mtx; IList parts; // First node non-queued into ctx->trace_part_recycle. - TracePart* local_head; + TracePart* local_head = nullptr; // Final position in the last part for finished threads. Event* final_pos = nullptr; // Number of trace parts allocated on behalf of this trace specifically. commit 3f11a19f09d7fe984bd7821b1fecbae571907efe Author: Jakub Jelinek Date: Mon Jul 27 18:54:37 2026 +0200 fortran: Fix ICE with loops with (deprecated) non-integral iterators [PR126303] do_subscript contains do_sym = dl->ext.iterator->var->symtree->n.sym; if (do_sym->ts.type != BT_INTEGER) continue; check to ignore loops with non-integral iterator. But r15-11154 PR94978 change has added inner_loop_may_be_skipped function and that happily accesses inner loop iterator's step, start and end if EXPR_CONSTANT with mpz_init_set (..., ...value.integer); Now, given the layout of mpfr_t (usually long, int, long, pointer) and mpz_t (usually int, int, pointer), this sometimes just produces silently garbage (e.g. on 64-bit little-endian, where the second int in mpz_t is the most significant 32-bits of _mpfr_prec and so usually 0 and so _mp_size is 0 and nothing is dereferenced: p loop->ext.iterator->step.value.real $1 = {{_mpfr_prec = 24, _mpfr_sign = 1, _mpfr_exp = 1, _mpfr_d = 0x4eac658}} p loop->ext.iterator->step.value.integer $2 = {{_mp_alloc = 24, _mp_size = 0, _mp_d = 0x1}} or it ICEs somewhere in gmp (on 32-bit little-endian, e.g. i686, or big-endian, e.g. s390x), because _mp_size is in that case _mpfr_sign but _mp_d is _mpfr_exp (32-bit little-endian), or _mp_size is least significant part of _mpfr_prec, in both cases non-zero, but _mp_d is not a usable pointer in either case. The following patch fixes that by punting for inner loops with non-integral iterator. 2026-07-27 Jakub Jelinek PR fortran/126303 * frontend-passes.cc (inner_loop_may_be_skipped): If inner loop iterator is not integral, return true. * gfortran.dg/pr126303.f: New test. Reviewed-by: Jerry DeLisle (cherry picked from commit 822ce7e451fdbbeeca2df5d8ddbdf6bccc254abb) diff --git a/gcc/fortran/frontend-passes.cc b/gcc/fortran/frontend-passes.cc index 4adae60825a..e2910cc6edc 100644 --- a/gcc/fortran/frontend-passes.cc +++ b/gcc/fortran/frontend-passes.cc @@ -2816,6 +2816,9 @@ inner_loop_may_be_skipped (int loop_index, gfc_symbol *outer_sym, mpz_t outer_va if (loop == NULL || loop->ext.iterator == NULL || loop->ext.iterator->var == NULL) return true; + if (loop->ext.iterator->var->symtree->n.sym->ts.type != BT_INTEGER) + return true; + if (!evaluate_loop_bound (loop->ext.iterator->step, outer_sym, outer_val, do_step)) return true; diff --git a/gcc/testsuite/gfortran.dg/pr126303.f b/gcc/testsuite/gfortran.dg/pr126303.f new file mode 100644 index 00000000000..0e6f8381c87 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr126303.f @@ -0,0 +1,9 @@ +! PR fortran/126303 +! { dg-do compile } +! { dg-options "-std=legacy" } + COMMON FOO(8) + DO 10 M=1,8 + DO 10 T=0D0,1D0 + FOO(M)=1 + 10 CONTINUE + END commit 0d628c7cd27ff552dafb2066f5afefd215480d84 Author: Jakub Jelinek Date: Wed Jul 29 10:04:30 2026 +0200 bitintlower: Fix _BitInt SSA_NAME coalescing ICE [PR126447] The following testcases ICE, because the build_bitint_stmt_ssa_conflicts function sets for those ifns muldiv_p to true (similarly to the MULT_EXPR and division/modulo ones) to prevent the lhs from being mapped into the same underlying variable as the input operand(s). Now, if the lhs and at least one of the operands SSA_NAME_OCCURS_IN_ABNORMAL_PHI, we can trigger ICE because we fail to coalesce something that has to be coalesced. For MULT_EXPR etc. we handle this in gimple_lower_bitint, by /* For multiplication and division with (ab) lhs and one or both operands force the operands into new SSA_NAMEs to avoid coalescing failures. */ if (TREE_CODE (rhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)) { first_large_huge = 0; tree t = make_ssa_name (TREE_TYPE (rhs1)); g = gimple_build_assign (t, SSA_NAME, rhs1); gsi_insert_before (&gsi, g, GSI_SAME_STMT); gimple_set_location (g, loc); gimple_assign_set_rhs1 (stmt, t); if (rhs1 == rhs2) { gimple_assign_set_rhs2 (stmt, t); rhs2 = t; } update_stmt (stmt); } etc. a few lines above the hunk below. This patch just adds the same thing for the problematic internal fn calls (not handling that way the .MUL_OVERFLOW etc. ifns, because those do return COMPLEX_EXPR of BITINT_TYPE and so the problematic case shouldn't exist there). 2026-07-29 Jakub Jelinek PR middle-end/126447 * gimple-lower-bitint.cc (gimple_lower_bitint): For ifn calls with large/huge _BitInt (ab) SSA_NAME lhs if they have such (ab) argument too, force it into temporary SSA_NAME for IFN_UBSAN_CHECK_MUL. * gcc.dg/ubsan/bitint-5.c: New test. Reviewed-by: Andrea Pinski (cherry picked from commit cd9428362b6585e77ea2a171ec030894fcfa4d1c) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index e4c9e261bd8..d288b2d376b 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -6440,6 +6440,39 @@ gimple_lower_bitint (void) add_phi_arg (phi, rhs2, e3, UNKNOWN_LOCATION); break; } + else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s) + && is_gimple_call (stmt) + && gimple_call_internal_p (stmt)) + switch (gimple_call_internal_fn (stmt)) + { + case IFN_UBSAN_CHECK_MUL: + for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i) + { + location_t loc = gimple_location (stmt); + gsi = gsi_for_stmt (stmt); + /* Similar case to multiplication/division with (ab) + above for internal functions which set muldiv_p. */ + tree arg = gimple_call_arg (stmt, i); + if (TREE_CODE (arg) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg)) + { + first_large_huge = 0; + tree t = make_ssa_name (TREE_TYPE (arg)); + g = gimple_build_assign (t, SSA_NAME, arg); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + gimple_set_location (g, loc); + gimple_call_set_arg (stmt, i, t); + if (i == 0 + && gimple_call_num_args (stmt) >= 2 + && gimple_call_arg (stmt, 1) == arg) + gimple_call_set_arg (stmt, 1, t); + update_stmt (stmt); + } + } + break; + default: + break; + } } /* We need to also rewrite stores of large/huge _BitInt INTEGER_CSTs into memory. Such functions could have no large/huge SSA_NAMEs. */ diff --git a/gcc/testsuite/gcc.dg/ubsan/bitint-5.c b/gcc/testsuite/gcc.dg/ubsan/bitint-5.c new file mode 100644 index 00000000000..22a613dd06a --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/bitint-5.c @@ -0,0 +1,36 @@ +/* PR middle-end/126447 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-fsanitize=signed-integer-overflow" } */ + +void foo (int); +[[gnu::returns_twice]] void bar (); + +_BitInt(575) +baz () +{ + _BitInt(575) w = 1; + bar (); + w *= 3; + foo (3); + return w; +} + +_BitInt(575) +qux () +{ + _BitInt(575) w = 1; + bar (); + w += 3; + foo (3); + return w; +} + +_BitInt(575) +fred (_BitInt(575) x) +{ + _BitInt(575) w = 1; + bar (); + w -= x; + foo (3); + return w; +} commit 68baea6ab2800cea75f9fce3021734a489404a5c Author: Jakub Jelinek Date: Wed Jul 29 10:15:11 2026 +0200 i386: Fix ICE on out of bounds vector elt access [PR126446] The following testcase ICEs on x86_64. The isel pass has a check for out of bounds constant index before optimizing into .VEC_SET, but it does it using // if index is a constant, then check the bounds poly_uint64 idx_poly; if (poly_int_tree_p (idx, &idx_poly)) { poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (view_op0)); if (known_gt (idx_poly, nelts)) return false; } In the testcase below, idx is INTEGER_CST with long long type and negative value, that doesn't fit into poly_uint64, so we happily convert it into .VEC_SET. And another problem is that the x86 backend isn't trying to be careful and handle out of bounds elt gracefully (I think it could still in theory happen, if GIMPLE lets it through but e.g. something during expansion figures out the index is constant or whatever). The following patch fixes it in the backend to avoid triggering UB at compile time by doing HOST_WIDE_INT_1U << elt etc. when elt is negative or too large. In order to avoid ICE, we need to emit something, so I emit a no-op move, out of bounds vector set shouldn't change anything in the target. gimple-isel.cc will be changed incrementally. 2026-07-29 Jakub Jelinek PR target/126446 * config/i386/i386-expand.cc (ix86_expand_vector_set): If elt is out of bounds, emit a no-op move. * gcc.target/i386/avx2-pr126446.c: New test. Reviewed-by: Uros Bizjak (cherry picked from commit 1bc2fdc4f4cbe1b68237f49f211473c56d8a44a3) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 15551ca1ac6..20a218e4542 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -17261,6 +17261,11 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) machine_mode mmode = VOIDmode; rtx (*gen_blendm) (rtx, rtx, rtx, rtx); + if (!IN_RANGE (elt, 0, GET_MODE_NUNITS (mode))) + { + emit_move_insn (target, target); + return; + } switch (mode) { case E_V2SImode: diff --git a/gcc/testsuite/gcc.target/i386/avx2-pr126446.c b/gcc/testsuite/gcc.target/i386/avx2-pr126446.c new file mode 100644 index 00000000000..4af8cfd283c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-pr126446.c @@ -0,0 +1,14 @@ +/* PR target/126446 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mavx2" } */ + +typedef signed char V __attribute__((vector_size (16))); + +signed char +foo () +{ + V b = {}; + long long c = ~2878966870562407444LL; + b[c] = 1; + return b[0]; +} commit b750098281a54d88207f31b648dd644c32371642 Author: Jakub Jelinek Date: Wed Jul 29 23:34:54 2026 +0200 isel: Fix ICE on out of bounds vector elt access [PR126446] The isel pass has a check for out of bounds constant index before optimizing into .VEC_SET, but it does it using // if index is a constant, then check the bounds poly_uint64 idx_poly; if (poly_int_tree_p (idx, &idx_poly)) { poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (view_op0)); if (known_gt (idx_poly, nelts)) return false; } In the testcase below, idx is INTEGER_CST with long long type and negative value, that doesn't fit into poly_uint64, so we happily convert it into .VEC_SET. Furthermore, the known_gt check looks wrong, already idx_poly known_eq to nelts is too large and out of bounds for .VEC_SET. This patch fixes that by punting if !poly_int_tree_p (idx, &idx_poly) and poly_int_tree_p (idx), so when it is INTEGER_CST or POLY_INT_CST which doesn't fit into poly_uint64 (so likely negative), and uses known_ge instead of known_gt. 2026-07-29 Jakub Jelinek PR target/126446 * gimple-isel.cc (gimple_expand_vec_set_extract_expr): Punt if idx doesn't fit into poly_uint64 but is poly_int_tree_p. Use known_ge rather than known_gt for out of bounds check. Formatting fixes. Reviewed-by: Richard Biener (cherry picked from commit a7ba10ac1e027349a655ee4572abf34c1b9c1db1) diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index e35c24f5725..fd7a0035f47 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -93,10 +93,11 @@ gimple_expand_vec_set_extract_expr (struct function *fun, return false; tree op0 = TREE_OPERAND (ref, 0); - if (TREE_CODE (op0) == VIEW_CONVERT_EXPR && DECL_P (TREE_OPERAND (op0, 0)) + if (TREE_CODE (op0) == VIEW_CONVERT_EXPR + && DECL_P (TREE_OPERAND (op0, 0)) && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))) - && TYPE_MODE (TREE_TYPE (ref)) - == TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0))))) + && (TYPE_MODE (TREE_TYPE (ref)) + == TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0)))))) { tree pos = TREE_OPERAND (ref, 1); @@ -108,9 +109,13 @@ gimple_expand_vec_set_extract_expr (struct function *fun, if (poly_int_tree_p (idx, &idx_poly)) { poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (view_op0)); - if (known_gt (idx_poly, nelts)) + if (known_ge (idx_poly, nelts)) return false; } + else if (poly_int_tree_p (idx)) + // if idx doesn't fit into poly_uint64, but is constant, it + // must be out of bounds + return false; machine_mode outermode = TYPE_MODE (TREE_TYPE (view_op0)); machine_mode extract_mode = TYPE_MODE (TREE_TYPE (ref)); commit 8910ccc73acd643917b6a00968d65865ffd1795b Author: Jakub Jelinek Date: Thu Jul 30 09:52:45 2026 +0200 match.pd: Fix .PARITY(~x) simplification [PR126471] The parity(~X) simpliciation to parity(X) is incorrect for types with odd element precision, in that case parity(~X) is equivalent to parity(X) ^ 1. The following patch fixes this. 2026-07-30 Jakub Jelinek PR tree-optimization/126471 * match.pd (parity(~X) is parity(X)): Only optimize this way if element_precision is even, otherwise optimize into parity(X) ^ 1. * gcc.dg/bitint-139.c: New test. Reviewed-by: Andrea Pinski (cherry picked from commit 1f4cc0f7a14b52fdfbd02ac890cc7aedbdfb1979) diff --git a/gcc/match.pd b/gcc/match.pd index 2ab43a773b3..72004f144d8 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -9037,10 +9037,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) #endif /* PARITY simplifications. */ -/* parity(~X) is parity(X). */ +/* parity(~X) is parity(X) for even precision and parity(X) ^ 1 otherwise. */ (simplify (PARITY (bit_not @0)) - (PARITY @0)) + (if ((element_precision (TREE_TYPE (@0)) & 1) == 0) + (PARITY @0) + (bit_xor (PARITY:type @0) { build_one_cst (type); }))) /* parity(bswap(x)) is parity(x). */ (for parity (PARITY) diff --git a/gcc/testsuite/gcc.dg/bitint-139.c b/gcc/testsuite/gcc.dg/bitint-139.c new file mode 100644 index 00000000000..f71b90e7063 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-139.c @@ -0,0 +1,36 @@ +/* PR tree-optimization/126471 */ +/* { dg-do run { target bitint575 } } */ +/* { dg-options "-O2" } */ + +[[gnu::noipa]] int +foo (unsigned _BitInt(129) x) +{ + return __builtin_parityg (~x); +} + +[[gnu::noipa]] int +bar (unsigned _BitInt(7) x) +{ + return __builtin_parityg (~x); +} + +[[gnu::noipa]] int +baz (unsigned _BitInt(256) x) +{ + return __builtin_parityg (~x); +} + +int +main () +{ + if (foo (0) != 1 + || foo (~(unsigned _BitInt(129)) 0) != 0 + || foo (1) != 0 + || bar (0) != 1 + || bar (~(unsigned _BitInt(7)) 0) != 0 + || bar (1) != 0 + || baz (0) != 0 + || baz (~(unsigned _BitInt(256)) 0) != 0 + || baz (1) != 1) + __builtin_abort (); +} commit 0a6d540b5a4e274445e4777d6449508432a289cc Author: Jakub Jelinek Date: Thu Jul 30 09:54:53 2026 +0200 asan: Don't emit __asan_handle_no_return_call before __asan_report_* calls [PR126084] Alex reported that since my r17-2388 fix we now emit an undesirable __asan_handle_no_return call before the __asan_report_{load,store}* calls added during bitintlower pass. Normally (when large/huge _BitInt is not involved), those are added by the sanopt pass which runs after the asan pass and so aren't instrumented. The following patch avoids instrumenting those. Unfortunately the first hunk isn't all that is needed. That is because for the bitintlower added __asan_report_* calls gimple_call_builtin_p (stmt, BUILT_IN_NORMAL) returns false due to argument type mismatch. THe C/C++/Fortran FEs use DEF_PRIMITIVE_TYPE (BT_PTRMODE, (*lang_hooks.types.type_for_mode)(ptr_mode, 0)) and so use signed type with TYPE_MODE (ptr_mode). The fallback initialization in initialize_sanitizer_builtins (done for non-C/C++/Fortran FEs) uses for PTRMODE instead pointer_sized_int_node type, which is initialized to: pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1); where ptr_mode = as_a (mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0).require ()); so, I think both have the same precision, just one is signed and one unsigned. And then asan_expand_poison_ifn uses pointer_sized_int_node. The following patch just changes initialize_sanitizer_builtins and asan_expand_poison_ifn to do the same thing as the C/C++/Fortran FEs here. Seems asan.cc is full of similar builtin argument type mismatches, but I've changed only what was needed for this patch. 2026-07-30 Jakub Jelinek PR middle-end/126084 * asan.cc (maybe_instrument_call): Don't instrument BUILT_IN_ASAN_REPORT_{LOAD,STORE}{1,2,4,8,16,_N} builtins. (initialize_sanitizer_builtins): Use (*lang_hooks.types.type_for_mode) (ptr_mode, 0) instead of pointer_sized_int_mode for PTRMODE arguments. (asan_expand_poison_ifn): Likewise. Reviewed-by: Richard Biener (cherry picked from commit 2720a372bda550b8516a786562e0f5b705aede5b) diff --git a/gcc/asan.cc b/gcc/asan.cc index b19be889982..43dfb4fb87b 100644 --- a/gcc/asan.cc +++ b/gcc/asan.cc @@ -3024,6 +3024,18 @@ maybe_instrument_call (gimple_stmt_iterator *iter) case BUILT_IN_UNREACHABLE: case BUILT_IN_UNREACHABLE_TRAP: case BUILT_IN_TRAP: + case BUILT_IN_ASAN_REPORT_LOAD1: + case BUILT_IN_ASAN_REPORT_LOAD2: + case BUILT_IN_ASAN_REPORT_LOAD4: + case BUILT_IN_ASAN_REPORT_LOAD8: + case BUILT_IN_ASAN_REPORT_LOAD16: + case BUILT_IN_ASAN_REPORT_LOAD_N: + case BUILT_IN_ASAN_REPORT_STORE1: + case BUILT_IN_ASAN_REPORT_STORE2: + case BUILT_IN_ASAN_REPORT_STORE4: + case BUILT_IN_ASAN_REPORT_STORE8: + case BUILT_IN_ASAN_REPORT_STORE16: + case BUILT_IN_ASAN_REPORT_STORE_N: /* Don't instrument these. */ return false; default: @@ -3424,6 +3436,7 @@ initialize_sanitizer_builtins (void) if (builtin_decl_implicit_p (BUILT_IN_ASAN_INIT)) return; + tree ptrmode_type = (*lang_hooks.types.type_for_mode) (ptr_mode, 0); tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE); tree BT_FN_VOID_PTR = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); @@ -3437,7 +3450,7 @@ initialize_sanitizer_builtins (void) ptr_type_node, ptr_type_node, NULL_TREE); tree BT_FN_VOID_PTR_PTRMODE = build_function_type_list (void_type_node, ptr_type_node, - pointer_sized_int_node, NULL_TREE); + ptrmode_type, NULL_TREE); tree BT_FN_VOID_INT = build_function_type_list (void_type_node, integer_type_node, NULL_TREE); tree BT_FN_SIZE_CONST_PTR_INT @@ -3472,7 +3485,7 @@ initialize_sanitizer_builtins (void) tree BT_FN_VOID_PTR_UINT8_PTRMODE = build_function_type_list (void_type_node, ptr_type_node, unsigned_char_type_node, - pointer_sized_int_node, NULL_TREE); + ptrmode_type, NULL_TREE); tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5]; tree BT_FN_IX_CONST_VPTR_INT[5]; @@ -4224,11 +4237,13 @@ asan_expand_poison_ifn (gimple_stmt_iterator *iter, { tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size), &nargs); + tree ptrmode_type + = (nargs == 2 ? (*lang_hooks.types.type_for_mode) (ptr_mode, 0) + : NULL_TREE); call = gimple_build_call (fun, nargs, build_fold_addr_expr (shadow_var), nargs == 2 - ? fold_convert (pointer_sized_int_node, - size) + ? fold_convert (ptrmode_type, size) : NULL_TREE); } gimple_set_location (call, gimple_location (use)); commit dec926dc5ce424249afc21f2ef9b6f356cee6b6f Author: Jakub Jelinek Date: Thu Jul 30 09:56:41 2026 +0200 range-op-float: Fix up inf handling in reverse narrowing float to float cast [PR126464] The following testcase is miscompiled since my r16-1108 change. The problem is if we handle a reverse of a narrowing float to float cast (in the example there are double -> float and long double -> double cast) and the lhs range is [-inf, -inf] or [+inf, +inf] (note, regardless of whether some NaNs are allowed or not, so not necessarily lhs.known_isinf ()), then handling that range in the wider type also as [-inf, -inf] or [+inf, +inf] is wrong, e.g. for the double -> float conversion, [-inf, -0x0.ffffff8p+128] double range could map to just that [-inf, -inf]. We have already float_widen_lhs_range function but that just extends the range by +/-1ulp or 0.5ulp if the bounds are finite. If the range isn't singleton (except for optional NaN), then the minimum (or maximum) finite is already in the range, so this just extends the case where they are singleton. I don't know how to portably figure out that 0x0.ffffff8p+128 for double -> float (especially when in float_widen_lhs_range we don't know yet the wider type), so the patch just uses the +/-1ulp extension (i.e. [-inf, min_finite] or [+inf, max_finite] case. 2026-07-30 Jakub Jelinek PR tree-optimization/126464 * range-op-float.cc (float_widen_lhs_range): Add also_inf argument defaulted to false, if true, extend even lb of +inf and ub of -inf. * gcc.dg/pr126464.c: New test. Reviewed-by: Richard Biener (cherry picked from commit 3754582630fa1eeff44a39f656ba0c7db6e58d0d) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 1293f8ae364..cd10bbf801c 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -2366,14 +2366,14 @@ zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known) in each direction. See PR109008 for more details. */ static frange -float_widen_lhs_range (tree type, const frange &lhs) +float_widen_lhs_range (tree type, const frange &lhs, bool also_inf = false) { frange ret = lhs; if (lhs.known_isnan ()) return ret; REAL_VALUE_TYPE lb = lhs.lower_bound (); REAL_VALUE_TYPE ub = lhs.upper_bound (); - if (real_isfinite (&lb)) + if (real_isfinite (&lb) || (also_inf && !real_isneg (&lb))) { frange_nextafter (TYPE_MODE (type), lb, dconstninf); if (real_isinf (&lb)) @@ -2387,7 +2387,9 @@ float_widen_lhs_range (tree type, const frange &lhs) lb = dconstm1; SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1); } - if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type))) + if (!flag_rounding_math + && !MODE_COMPOSITE_P (TYPE_MODE (type)) + && (!also_inf || real_isfinite (&lhs.lower_bound ()))) { /* If not -frounding-math nor IBM double double, actually widen just by 0.5ulp rather than 1ulp. */ @@ -2396,7 +2398,7 @@ float_widen_lhs_range (tree type, const frange &lhs) real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2); } } - if (real_isfinite (&ub)) + if (real_isfinite (&ub) || (also_inf && real_isneg (&ub))) { frange_nextafter (TYPE_MODE (type), ub, dconstinf); if (real_isinf (&ub)) @@ -2405,7 +2407,9 @@ float_widen_lhs_range (tree type, const frange &lhs) ub = dconst1; SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1); } - if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type))) + if (!flag_rounding_math + && !MODE_COMPOSITE_P (TYPE_MODE (type)) + && (!also_inf || real_isfinite (&lhs.upper_bound ()))) { /* If not -frounding-math nor IBM double double, actually widen just by 0.5ulp rather than 1ulp. */ diff --git a/gcc/testsuite/gcc.dg/pr126464.c b/gcc/testsuite/gcc.dg/pr126464.c new file mode 100644 index 00000000000..b6eb1320dec --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr126464.c @@ -0,0 +1,61 @@ +/* PR tree-optimization/126464 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-add-options ieee } */ +/* { dg-skip-if "not IEEE float" { "pdp11-*-*" } } */ + +[[gnu::noipa]] double +foo (double x) +{ + float y = (float) x; + + if (y == -__builtin_inff ()) + return x * 0.5; + return y; +} + +[[gnu::noipa]] long double +bar (long double x) +{ + double y = (double) x; + + if (y == __builtin_inf ()) + return x * 0.5L; + return y; +} + +[[gnu::noipa]] double +baz (double x) +{ + float y = (float) x; + + if (y == __builtin_inff ()) + return x * 0.5; + return y; +} + +[[gnu::noipa]] long double +qux (long double x) +{ + double y = (double) x; + + if (y == -__builtin_inf ()) + return x * 0.5L; + return y; +} + +int +main () +{ + if (!__builtin_isinf ((double) 1e300) + && __builtin_isinf ((float) 1e300) + && (foo (-1e300) != -5e299 + || baz (1e300) != 5e299)) + __builtin_abort (); + + if (!__builtin_isinf ((long double) 1e4000L) + && __builtin_isinf ((double) 1e4000L) + && (bar (1e4000L) != 5e3999L + || qux (-1e4000L) != -5e3999L)) + __builtin_abort (); +} commit b56074b3831ccfde9b87cb4ac322a30c38d7d63d Author: Jakub Jelinek Date: Fri Jul 31 08:53:52 2026 +0200 match.pd: Fix up ((C << A) & D) != 0 simplification [PR126476] This simplification for power of two @1 and @2 folds to false (resp. to true for the == version) if @1 is larger than @2 (in unsigned comparison), because @1 & @2 is known to be zero (i.e. for shift count 0) and for shift count larger than that it will be zero too, either because @1 << @0 is even larger, or if @0 is too large @1 << @0 overflows to zero. This is the case of e.g. ((4 << x) & 2) != 0, which is always false. Now, this PR is about a different problem, if @1 is smaller than @2, say ((1 << x) & 256) != 0, but x has a very narrow type, say unsigned _BitInt(3), then the largest possible value of x is 7 and ((1 << 7) & 256) is still 0, 1 << 7 is 128 and so still smaller than 256. So, if c1 - c2 doesn't fit into the shift count type (resp. for the other case c2 - c1), it will be also always false (resp. true). Trying to improve it and using range of x (aka @0) is not needed, this simplification folds it into @0 != (c1 - c2) and so will be folded later. Just the case where c1 - c2 overflows is problematic because we've lost the details (unless we'd promote both operands or something). Another possible way to do this would be build_int_cst and check for the overflow flags, but I think this is shorter. 2026-07-31 Jakub Jelinek PR tree-optimization/126476 * match.pd (((C << A) & D) != 0 -> A == 0, ((C << A) & D) == 0 -> A != 0): Fold to false/true if c1 - c2 resp. c2 - c1 doesn't fit into TREE_TYPE (@0). * gcc.dg/torture/bitint-103.c: New test. Reviewed-by: Richard Biener (cherry picked from commit 5c62a2771f2c7d5301ee6456f1817098c2fea113) diff --git a/gcc/match.pd b/gcc/match.pd index 72004f144d8..ad9ca4ce1ec 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4437,7 +4437,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cmp (bit_and (lshift integer_pow2p@1 @0) integer_pow2p@2) integer_zerop) (with { int c1 = wi::clz (wi::to_wide (@1)); int c2 = wi::clz (wi::to_wide (@2)); } - (if (c1 < c2) + (if (c1 < c2 + /* If c1 - c2 isn't representable in TREE_TYPE (@0), it is also + never true, because for any valid x C << x will be smaller + than D. See PR126476. */ + || !wi::fits_to_tree_p (wi::shwi (c1 - c2, HOST_BITS_PER_INT), + TREE_TYPE (@0))) { constant_boolean_node (cmp == NE_EXPR ? false : true, type); } (icmp @0 { build_int_cst (TREE_TYPE (@0), c1 - c2); })))) (simplify @@ -4445,7 +4450,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (tree_int_cst_sgn (@1) > 0) (with { int c1 = wi::clz (wi::to_wide (@1)); int c2 = wi::clz (wi::to_wide (@2)); } - (if (c1 > c2) + (if (c1 > c2 + || !wi::fits_to_tree_p (wi::shwi (c2 - c1, HOST_BITS_PER_INT), + TREE_TYPE (@0))) { constant_boolean_node (cmp == NE_EXPR ? false : true, type); } (icmp @0 { build_int_cst (TREE_TYPE (@0), c2 - c1); }))))) /* `(1 >> X) != 0` -> `X == 0` */ diff --git a/gcc/testsuite/gcc.dg/torture/bitint-103.c b/gcc/testsuite/gcc.dg/torture/bitint-103.c new file mode 100644 index 00000000000..54c0fc0b1d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-103.c @@ -0,0 +1,22 @@ +/* PR tree-optimization/126476 */ +/* { dg-do run { target bitint } } */ + +[[gnu::noipa]] int +foo (unsigned _BitInt(4) n) +{ + return ((1ULL << n) & (1ULL << 20)) != 0; +} + +[[gnu::noipa]] int +bar (unsigned _BitInt(4) n) +{ + return (((1ULL << 40) >> n) & (1ULL << 20)) != 0; +} + +int +main () +{ + for (unsigned i = 0; i < 16; i++) + if (foo (i) != 0 || bar (i) != 0) + __builtin_abort (); +} commit db8b415de6b3eb6ebcad50c8f8d4e386ccc09ef7 Author: Jakub Jelinek Date: Fri Jul 31 08:56:03 2026 +0200 range-op-float: Fix up inf handling in other reverse ops [PR126464] On Thu, Jul 30, 2026 at 09:31:17AM +0200, Richard Biener wrote: > > The following testcase is miscompiled since my r16-1108 change. > > The problem is if we handle a reverse of a narrowing float to float cast > > (in the example there are double -> float and long double -> double > > cast) and the lhs range is [-inf, -inf] or [+inf, +inf] (note, regardless > > of whether some NaNs are allowed or not, so not necessarily > > lhs.known_isinf ()), then handling that range in the wider type also > > as [-inf, -inf] or [+inf, +inf] is wrong, e.g. for the double -> float > > conversion, [-inf, -0x0.ffffff8p+128] double range could map to just > > that [-inf, -inf]. We have already float_widen_lhs_range function > > but that just extends the range by +/-1ulp or 0.5ulp if the bounds > > are finite. If the range isn't singleton (except for optional NaN), > > then the minimum (or maximum) finite is already in the range, so this just > > extends the case where they are singleton. > > I don't know how to portably figure out that 0x0.ffffff8p+128 for > > double -> float (especially when in float_widen_lhs_range we don't know > > yet the wider type), so the patch just uses the +/-1ulp extension (i.e. > > [-inf, min_finite] or [+inf, max_finite] case. On a second thought, this actually isn't specific to just reverse of narrowing float to float casts, it is a problem for any other reverse binary ops too. E.g. the following testcase is miscompiled at -O2 since r13-3926-gd4c2f1d376da (but works with -O0). The lhs of the addition is [-inf, -inf], one of its operand is [-1e304, -1e300] and we think the other operand has to be [-inf, -inf]. That is obviously wrong, even much larger operands can result in -inf, anything below -DBL_MAX + -1e300 where x + -1e300 doesn't round to -DBL_MAX or higher but to -inf. So, the following patch just widens lb of +inf and ub of -inf by 1ulp for all callers (and thus doesn't need the also_inf argument. 2026-07-31 Jakub Jelinek PR tree-optimization/126464 * range-op-float.cc (float_widen_lhs_range): Remove also_inf argument, replace its uses as if it was always true. * gcc.dg/torture/pr126464.c: New test. Reviewed-by: Richard Biener (cherry picked from commit 6f32166346de2d1c0f6253e4fe37e8a6edac655d) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index cd10bbf801c..dbad68eacf0 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -2366,14 +2366,14 @@ zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known) in each direction. See PR109008 for more details. */ static frange -float_widen_lhs_range (tree type, const frange &lhs, bool also_inf = false) +float_widen_lhs_range (tree type, const frange &lhs) { frange ret = lhs; if (lhs.known_isnan ()) return ret; REAL_VALUE_TYPE lb = lhs.lower_bound (); REAL_VALUE_TYPE ub = lhs.upper_bound (); - if (real_isfinite (&lb) || (also_inf && !real_isneg (&lb))) + if (real_isfinite (&lb) || !real_isneg (&lb)) { frange_nextafter (TYPE_MODE (type), lb, dconstninf); if (real_isinf (&lb)) @@ -2389,7 +2389,7 @@ float_widen_lhs_range (tree type, const frange &lhs, bool also_inf = false) } if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)) - && (!also_inf || real_isfinite (&lhs.lower_bound ()))) + && real_isfinite (&lhs.lower_bound ())) { /* If not -frounding-math nor IBM double double, actually widen just by 0.5ulp rather than 1ulp. */ @@ -2398,7 +2398,7 @@ float_widen_lhs_range (tree type, const frange &lhs, bool also_inf = false) real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2); } } - if (real_isfinite (&ub) || (also_inf && real_isneg (&ub))) + if (real_isfinite (&ub) || real_isneg (&ub)) { frange_nextafter (TYPE_MODE (type), ub, dconstinf); if (real_isinf (&ub)) @@ -2409,7 +2409,7 @@ float_widen_lhs_range (tree type, const frange &lhs, bool also_inf = false) } if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)) - && (!also_inf || real_isfinite (&lhs.upper_bound ()))) + && real_isfinite (&lhs.upper_bound ())) { /* If not -frounding-math nor IBM double double, actually widen just by 0.5ulp rather than 1ulp. */ diff --git a/gcc/testsuite/gcc.dg/torture/pr126464.c b/gcc/testsuite/gcc.dg/torture/pr126464.c new file mode 100644 index 00000000000..c0dced1eedc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr126464.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/126464 */ +/* { dg-do run } */ + +#if __DBL_MANT_DIG__ == 53 && __DBL_MAX_10_EXP__ == 308 \ + && __DBL_HAS_INFINITY__ && __FLT_EVAL_METHOD__ == 0 +[[gnu::noipa]] double +foo (double x, double y) +{ + if (y >= -1e304 && y <= -1e300) + { + if (x + y == -__builtin_inf ()) + return x * 0.5; + } + return x; +} +#endif + +int +main () +{ +#if __DBL_MANT_DIG__ == 53 && __DBL_MAX_10_EXP__ == 308 \ + && __DBL_HAS_INFINITY__ && __FLT_EVAL_METHOD__ == 0 + if (foo (-__builtin_inf (), -1e303) != -__builtin_inf ()) + __builtin_abort (); + if (foo (-1.797693134862e308, -1e303) != -1.797693134862e308 / 2.0) + __builtin_abort (); +#endif +} commit 4475b8ac966d4107263ce28d3961c2d41818a1fb Author: Jakub Jelinek Date: Fri Jul 31 09:03:05 2026 +0200 match.pd: Fix (a & b) == (a ^ b) -> !(a | b) simplification [PR126490] The following testcase is miscompiled. We have 2 different simplifications (a & b) ^ (a == b) -> !(a | b) (a & b) == (a ^ b) -> !(a | b) where both a and b are truth_valued_p. That doesn't mean they have boolean type, it means that either they have integral type with one bit precision (boolean, unsigned or signed) or they are result of comparisons etc. Now, because both a and b appear as operands of the same &, they necessarily have the same or uselessly compatible type. For the first case, the a == b comparison necessarily has to have the same type too and so type is the same type as well. For the second case that is not the case, e.g. in the problematic testcase both a and b are unsigned _BitInt(1) while == has int type, but it could very well be also that a and b are results of comparisons etc. and have int type. Now, the comment properly uses ! for the replacement, but the replacement of the simplification actually uses bit_not, so ~. ~ is fine for 1-bit precision, but not for wider ones. The following patch differentiates between the case when a and b have 1-bit precision type, then it ensures ~ is done in that type and only then it is converted to type, while for other cases it does ^ 1 instead. 2026-07-31 Jakub Jelinek PR tree-optimization/126490 * match.pd ((a & b) == (a ^ b) -> !(a | b)): If @0 has integral one bit precision type, use (convert:type ...) around the bit_not just in case the comparison has a different result type from the type of its operands. Otherwise do that too but with bit_not replaced with bit_xor with one of the appropriate type. * gcc.dg/torture/bitint-104.c: New test. Reviewed-by: Richard Biener (cherry picked from commit a7a444ddd1eb51d755d613e5cc413548f6574b53) diff --git a/gcc/match.pd b/gcc/match.pd index ad9ca4ce1ec..642183a1658 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2445,7 +2445,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) second_op (eq bit_xor) (simplify (first_op:c (bit_and:c truth_valued_p@0 truth_valued_p@1) (second_op:c @0 @1)) - (bit_not (bit_ior @0 @1)))) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_PRECISION (TREE_TYPE (@0)) == 1) + (convert:type (bit_not (bit_ior @0 @1))) + (convert:type (bit_xor (bit_ior @0 @1) { build_one_cst (TREE_TYPE (@0)); }))))) /* Convert ~ (A - 1) or ~ (A + -1) to -A. */ (simplify diff --git a/gcc/testsuite/gcc.dg/torture/bitint-104.c b/gcc/testsuite/gcc.dg/torture/bitint-104.c new file mode 100644 index 00000000000..935b4e7a138 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-104.c @@ -0,0 +1,78 @@ +/* PR tree-optimization/126490 */ +/* { dg-do run { target bitint } } */ + +typedef unsigned _BitInt(1) T; + +[[gnu::noipa]] int +foo (T a, T b) +{ + return ((a & b) == (a ^ b)) + 1; +} + +[[gnu::noipa]] int +bar (T a, T b) +{ + return ((a & b) == (a ^ b)) != 0; +} + +[[gnu::noipa]] int +baz (T a, T b) +{ + return ((a & b) == (a ^ b)) == 0; +} + +[[gnu::noipa]] int +qux (T a, T b) +{ + return ((a & b) == (a ^ b)) < 1; +} + +[[gnu::noipa]] int +corge (int a, int b) +{ + return (a & b) == (a ^ b); +} + +[[gnu::noipa]] int +garply (T a, T b) +{ + return ((a & b) ^ (a == b)) + 1; +} + +[[gnu::noipa]] int +fred (T a, T b) +{ + return ((a & b) ^ (a == b)) != 0; +} + +[[gnu::noipa]] int +xyzzy (T a, T b) +{ + return ((a & b) ^ (a == b)) == 0; +} + +[[gnu::noipa]] int +waldo (T a, T b) +{ + return ((a & b) ^ (a == b)) < 1; +} + +int +main () +{ + for (int i = 0; i < 4; ++i) + { + int a = i & 1; + int b = i >> 1; + int c = corge (a, b); + if (foo (a, b) != c + 1 + || bar (a, b) != (c != 0) + || baz (a, b) != (c == 0) + || qux (a, b) != (c < 1) + || garply (a, b) != c + 1 + || fred (a, b) != (c != 0) + || xyzzy (a, b) != (c == 0) + || waldo (a, b) != (c < 1)) + __builtin_abort (); + } +} commit bbe1892f92c5b76637a53c376e6ff7f8095ca851 Author: Jakub Jelinek Date: Fri Jul 31 09:05:50 2026 +0200 gimplify: Allow declarations in recalculate_side_effects [PR126497] The following testcase ICEs, because we decide to fold a comparison into just one of its operands, we call recalculate_side_effects on that and ICE on the assertion that it isn't called on anything unexpected (here PARM_DECL). Already some time ago we had to add an exception for SSA_NAME for the same reason. The tcc_declaration case is slightly different, TREE_SIDE_EFFECTS is sometimes present on those if they are TREE_THIS_VOLATILE, but it is something the FE should take care of when creating those decls, not a business of the gimplifier. 2026-07-31 Jakub Jelinek PR middle-end/126497 * gimplify.cc (recalculate_side_effects): Return for tcc_declaration. * gcc.dg/bitint-141.c: New test. Reviewed-by: Andrea Pinski (cherry picked from commit ca867fd9d5ace4ede8289dba9ae731e554bde618) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 7fdfbe25a8a..6cc2d1299f0 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -3372,6 +3372,13 @@ recalculate_side_effects (tree t) /* No side-effects. */ return; + case tcc_declaration: + /* These can have side-effects if TREE_THIS_VOLATILE, + but those should be set elsewhere, not in + recalculate_side_effects. Can be triggered e.g. if + a comparison is folded into one of its operands. */ + return; + default: if (code == SSA_NAME) /* No side-effects. */ diff --git a/gcc/testsuite/gcc.dg/bitint-141.c b/gcc/testsuite/gcc.dg/bitint-141.c new file mode 100644 index 00000000000..f3f22bbb0bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-141.c @@ -0,0 +1,19 @@ +/* PR middle-end/126497 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=c23" } */ + +typedef unsigned _BitInt (1) U; + +U +foo (U a) +{ + U t = a >= 1uwb; + return t; +} + +U +bar (U a) +{ + U t = a == 1uwb; + return t; +} commit 170fdce6efed1148cbc37960725828860bc6d5bd Author: Jakub Jelinek Date: Fri Jul 31 09:07:26 2026 +0200 bitintlower: Fix up handle_plus_minus [PR126503] The following testcase is miscompiled on aarch64 (but not on x86_64). The difference is that x86_64/i686 define optabs that make it use IFN_UADDC and IFN_USUBC, those are then used both in the loop and to perform the most significant limb, so # _6 = PHI <0(2), _7(3)> # _9 = PHI <0(2), _10(3)> _8 = VIEW_CONVERT_EXPR(a)[_6]; _11 = .USUBC (0, _8, _9); _12 = IMAGPART_EXPR <_11>; _13 = REALPART_EXPR <_11>; VIEW_CONVERT_EXPR()[_6] = _13; _14 = _6 + 1; _15 = VIEW_CONVERT_EXPR(a)[_14]; _16 = .USUBC (0, _15, _12); _10 = IMAGPART_EXPR <_16>; _17 = REALPART_EXPR <_16>; VIEW_CONVERT_EXPR()[_14] = _17; _7 = _6 + 2; if (_7 != 4) in the loop and _18 = MEM [(_BitInt(257) *)&a + 32B]; _19 = () _18; _20 = () _19; _21 = (unsigned long) _20; _22 = .USUBC (0, _21, _10); _23 = IMAGPART_EXPR <_22>; _24 = REALPART_EXPR <_22>; _25 = () _24; _26 = (unsigned long) _25; MEM [(unsigned _BitInt(400) *)& + 32B] = _26; ... after the loop. Now, on targets which don't support the optab, we instead use # _6 = PHI <0(2), _7(3)> # _9 = PHI <0(2), _10(3)> _8 = VIEW_CONVERT_EXPR(a)[_6]; _11 = .SUB_OVERFLOW (0, _8); _13 = REALPART_EXPR <_11>; _14 = IMAGPART_EXPR <_11>; _15 = .SUB_OVERFLOW (_13, _9); _16 = IMAGPART_EXPR <_15>; _12 = _14 + _16; _17 = REALPART_EXPR <_15>; VIEW_CONVERT_EXPR()[_6] = _17; _18 = _6 + 1; _19 = VIEW_CONVERT_EXPR(a)[_18]; _20 = .SUB_OVERFLOW (0, _19); _21 = REALPART_EXPR <_20>; _22 = IMAGPART_EXPR <_20>; _23 = .SUB_OVERFLOW (_21, _12); _24 = IMAGPART_EXPR <_23>; _10 = _22 + _24; _25 = REALPART_EXPR <_23>; VIEW_CONVERT_EXPR()[_18] = _25; _7 = _6 + 2; if (_7 != 4) in the loop (i.e. instead of one .USUBC 2 .SUB_OVERFLOW) and then after the loop for the most significant limb _26 = MEM [(_BitInt(257) *)&a + 32B]; _27 = () _26; _28 = () _10; _29 = 0 - _27; _30 = _29 - _28; _31 = (unsigned long) _30; MEM [(unsigned _BitInt(400) *)& + 32B] = _31; Now, the last thing is what is wrong. We need to do two subtractions (or after folding one negation and one subtraction), and while in the original operation signed overflow is indeed undefined, it just means that the two operations together don't overflow, but one of them can. In this testcase (in foo function) on aarch64, _26 is 1 (the most significant bit of 257-bit negative value) and _10 is also 1 (borrow from within the loop). When we perform this computation in signed 1-bit precision, we have 0 - -1 (overflow) and -1 - -1 (another overflow). The RTL emitted for this then results in miscompilation, but we really shouldn't introduce UB into the IL for something that didn't have UB originally. So, the following patch forces use of unsigned type for these and casts to the signed one only at the end. 2026-07-31 Jakub Jelinek PR tree-optimization/126503 * gimple-lower-bitint.cc (bitint_large_huge::handle_plus_minus): If IFN_ADDC/IFN_SUBC can't be used and rhs1_type is not the limb type and is signed, perform both additions or both subtractions in unsigned type for the rhs1_type and cast to rhs1_type at the end. * gcc.dg/torture/bitint-106.c: New test. Reviewed-by: Richard Biener (cherry picked from commit b61bb45f622b94dd2a2ebafb4a7e815b6bdf5dad) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index d288b2d376b..ceccb2d3857 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -1209,16 +1209,27 @@ bitint_large_huge::handle_plus_minus (tree_code code, tree rhs1, tree rhs2, } else { - tree in = add_cast (rhs1_type, data_in); - lhs = make_ssa_name (rhs1_type); + /* Always perform the two additions or subtractions in + unsigned type, avoid introducing a temporary UB. While + the end result of the 2 additions or 2 subtractions in + a valid program should not overflow, temporarily it can. + See PR126503. */ + tree utype = unsigned_type_for (rhs1_type); + tree in = add_cast (utype, data_in); + lhs = make_ssa_name (utype); + if (utype != rhs1_type) + { + rhs1 = add_cast (utype, rhs1); + rhs2 = add_cast (utype, rhs2); + } g = gimple_build_assign (lhs, code, rhs1, rhs2); insert_before (g); - rhs1 = make_ssa_name (rhs1_type); + rhs1 = make_ssa_name (utype); g = gimple_build_assign (rhs1, code, lhs, in); insert_before (g); m_data[m_data_cnt] = NULL_TREE; m_data_cnt += 2; - return rhs1; + return utype != rhs1_type ? add_cast (rhs1_type, rhs1) : rhs1; } rhs1 = make_ssa_name (m_limb_type); g = gimple_build_assign (rhs1, REALPART_EXPR, diff --git a/gcc/testsuite/gcc.dg/torture/bitint-106.c b/gcc/testsuite/gcc.dg/torture/bitint-106.c new file mode 100644 index 00000000000..11ee5384aa1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-106.c @@ -0,0 +1,38 @@ +/* PR tree-optimization/126503 */ +/* { dg-do run { target bitint575 } } */ + +[[gnu::noipa]] unsigned _BitInt(400) +foo (_BitInt(257) a) +{ + return (unsigned _BitInt(400)) (-a); +} + +[[gnu::noipa]] unsigned _BitInt(300) +bar (_BitInt(7) a, unsigned _BitInt(17) b) +{ + _BitInt(257) x = (_BitInt(257)) a + -1; + return ~((unsigned _BitInt(300)) x ^ (unsigned _BitInt(300)) b); +} + +[[gnu::noipa]] _BitInt(129) +baz (_BitInt(129) x) +{ + return x - 24; +} + +[[gnu::noipa]] int +qux (_BitInt(129) x, _BitInt(129) y) +{ + return x == y; +} + +int +main () +{ + if (foo (-1wb) != 1uwb) + __builtin_abort (); + if (bar (1wb, 3uwb) != (unsigned _BitInt(300)) -4wb) + __builtin_abort (); + if (!qux (baz (100), 76)) + __builtin_abort (); +} commit db35e319ed2de90b99d630d78c86257e9eb2b873 Author: Jakub Jelinek Date: Fri Jul 31 09:11:08 2026 +0200 match.pd: Fix 2 further problems with narrow shift count types [PR126504] This is the same problem as in just fixed PR126476, we have patterns which simplify something involving a shift to comparison of the shift count against a compile time determined value. Like in PR126476, if the shift count has a very narrow type like unsigned _BitInt(4) in the example and we want to compare it against something that doesn't fit into that type (like 20), then we miscompile it as comparison against something else (like 4), even when actually it just means that for no valid value the original will ever be true (resp. false), depending on what comparison it is. Now, why we have 4 very similar simplifiers is weird, sure, the first two changed in the last PR were one left shift and one right shift and in both cases powers of two, but here we have two others which look very similar, especially the last one to the first one. 2026-07-31 Jakub Jelinek PR tree-optimization/126504 * match.pd ((CST1 << A) == CST2 -> A == ctz (CST2) - ctz (CST1)): If cand isn't representable in TREE_TYPE (@1), simplify to cmp == NE_EXPR. (((1 << n) & M) != 0 -> n == log2 (M)): Don't simplify if log2 doesn't fit into TREE_TYPE (@0). * gcc.dg/torture/bitint-105.c: New test. (cherry picked from commit acd94fdfa20bf1195061d57a57e85cdd6beaa571) diff --git a/gcc/match.pd b/gcc/match.pd index 642183a1658..91e16fe1924 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4474,7 +4474,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { int cand = wi::ctz (wi::to_wide (@2)) - wi::ctz (wi::to_wide (@0)); } (if (cand < 0 || (!integer_zerop (@2) - && wi::lshift (wi::to_wide (@0), cand) != wi::to_wide (@2))) + && wi::lshift (wi::to_wide (@0), cand) != wi::to_wide (@2)) + || !wi::fits_to_tree_p (wi::shwi (cand, HOST_BITS_PER_INT), + TREE_TYPE (@1))) { constant_boolean_node (cmp == NE_EXPR, type); } (if (!integer_zerop (@2) && wi::lshift (wi::to_wide (@0), cand) == wi::to_wide (@2)) @@ -4622,8 +4624,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_and (nop_convert? (lshift integer_onep @0)) integer_pow2p@1) integer_zerop) (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))) - (icmp @0 { wide_int_to_tree (TREE_TYPE (@0), - wi::exact_log2 (wi::to_wide (@1))); })))) + (with { int c = wi::exact_log2 (wi::to_wide (@1)); } + (if (wi::fits_to_tree_p (wi::shwi (c, HOST_BITS_PER_INT), TREE_TYPE (@0))) + (icmp @0 { wide_int_to_tree (TREE_TYPE (@0), c); })))))) /* Fold (X {&,^,|} C2) << C1 into (X << C1) {&,^,|} (C2 << C1) (X {&,^,|} C2) >> C1 into (X >> C1) & (C2 >> C1). */ diff --git a/gcc/testsuite/gcc.dg/torture/bitint-105.c b/gcc/testsuite/gcc.dg/torture/bitint-105.c new file mode 100644 index 00000000000..4080bdc8a37 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-105.c @@ -0,0 +1,24 @@ +/* PR tree-optimization/126504 */ +/* { dg-do run { target bitint } } */ + +typedef unsigned _BitInt(4) U; + +[[gnu::noipa]] int +foo (U n) +{ + return ((1 << n) & (1 << 20)) != 0; +} + +[[gnu::noipa]] int +bar (U n) +{ + return ((unsigned) (1 << n) & (1u << 20)) != 0; +} + +int +main () +{ + for (unsigned i = 0; i < 16; i++) + if (foo (i) || bar (i)) + __builtin_abort (); +} commit 0b6f8f5e15abba659cae2ea4888b2da675749eb9 Author: GCC Administrator Date: Sun Aug 2 00:20:09 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 344efe7b795..3e62603dcd4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,128 @@ +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126504 + * match.pd ((CST1 << A) == CST2 -> A == ctz (CST2) - ctz (CST1)): + If cand isn't representable in TREE_TYPE (@1), simplify to + cmp == NE_EXPR. + (((1 << n) & M) != 0 -> n == log2 (M)): Don't simplify if + log2 doesn't fit into TREE_TYPE (@0). + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126503 + * gimple-lower-bitint.cc (bitint_large_huge::handle_plus_minus): If + IFN_ADDC/IFN_SUBC can't be used and rhs1_type is not the limb type + and is signed, perform both additions or both subtractions in + unsigned type for the rhs1_type and cast to rhs1_type at the end. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR middle-end/126497 + * gimplify.cc (recalculate_side_effects): Return for + tcc_declaration. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126490 + * match.pd ((a & b) == (a ^ b) -> !(a | b)): If @0 has + integral one bit precision type, use (convert:type ...) around the + bit_not just in case the comparison has a different result type + from the type of its operands. Otherwise do that too but with + bit_not replaced with bit_xor with one of the appropriate type. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126464 + * range-op-float.cc (float_widen_lhs_range): Remove also_inf + argument, replace its uses as if it was always true. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126476 + * match.pd (((C << A) & D) != 0 -> A == 0, + ((C << A) & D) == 0 -> A != 0): Fold to false/true if + c1 - c2 resp. c2 - c1 doesn't fit into TREE_TYPE (@0). + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-30 Jakub Jelinek + + PR tree-optimization/126464 + * range-op-float.cc (float_widen_lhs_range): Add also_inf argument + defaulted to false, if true, extend even lb of +inf and ub of -inf. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-30 Jakub Jelinek + + PR middle-end/126084 + * asan.cc (maybe_instrument_call): Don't instrument + BUILT_IN_ASAN_REPORT_{LOAD,STORE}{1,2,4,8,16,_N} builtins. + (initialize_sanitizer_builtins): Use + (*lang_hooks.types.type_for_mode) (ptr_mode, 0) instead of + pointer_sized_int_mode for PTRMODE arguments. + (asan_expand_poison_ifn): Likewise. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-30 Jakub Jelinek + + PR tree-optimization/126471 + * match.pd (parity(~X) is parity(X)): Only optimize this way + if element_precision is even, otherwise optimize into parity(X) ^ 1. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-29 Jakub Jelinek + + PR target/126446 + * gimple-isel.cc (gimple_expand_vec_set_extract_expr): Punt if + idx doesn't fit into poly_uint64 but is poly_int_tree_p. Use + known_ge rather than known_gt for out of bounds check. Formatting + fixes. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-29 Jakub Jelinek + + PR target/126446 + * config/i386/i386-expand.cc (ix86_expand_vector_set): If elt is + out of bounds, emit a no-op move. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-29 Jakub Jelinek + + PR middle-end/126447 + * gimple-lower-bitint.cc (gimple_lower_bitint): For + ifn calls with large/huge _BitInt (ab) SSA_NAME lhs if they + have such (ab) argument too, force it into temporary SSA_NAME + for IFN_UBSAN_CHECK_MUL. + 2026-07-28 Haochen Jiang Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 89a5952fcdc..d1a36c0c53a 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260801 +20260802 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d6a9b5451bb..24b30b62d39 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-27 Jakub Jelinek + + PR fortran/126303 + * frontend-passes.cc (inner_loop_may_be_skipped): If inner loop iterator + is not integral, return true. + 2026-07-27 Thomas Koenig Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 347837a965c..6692c106867 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,91 @@ +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126504 + * gcc.dg/torture/bitint-105.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126503 + * gcc.dg/torture/bitint-106.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR middle-end/126497 + * gcc.dg/bitint-141.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126490 + * gcc.dg/torture/bitint-104.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126464 + * gcc.dg/torture/pr126464.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-31 Jakub Jelinek + + PR tree-optimization/126476 + * gcc.dg/torture/bitint-103.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-30 Jakub Jelinek + + PR tree-optimization/126464 + * gcc.dg/pr126464.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-30 Jakub Jelinek + + PR tree-optimization/126471 + * gcc.dg/bitint-139.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-29 Jakub Jelinek + + PR target/126446 + * gcc.target/i386/avx2-pr126446.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-29 Jakub Jelinek + + PR middle-end/126447 + * gcc.dg/ubsan/bitint-5.c: New test. + +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-27 Jakub Jelinek + + PR fortran/126303 + * gfortran.dg/pr126303.f: New test. + 2026-07-28 Haochen Jiang Backported from master: diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index a10df8b29c0..097b5c3eac6 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,12 @@ +2026-08-01 Jakub Jelinek + + Backported from master: + 2026-07-20 Jakub Jelinek + + PR sanitizer/126307 + * tsan/tsan_trace.h: Cherry-pick llvm-project revision + cdfdb06c9155080ec97d6e4f4dd90b6e7cefb0ca. + 2026-06-26 Release Manager * GCC 14.4.0 released. commit f78add46612776e3a24891b1ecaedef99b8f1d14 Author: GCC Administrator Date: Mon Aug 3 00:19:50 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index d1a36c0c53a..4c2ec002628 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260802 +20260803 commit 52173c71fe661e37615d9215c95d2ce5883e44fc Author: GCC Administrator Date: Tue Aug 4 00:19:56 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4c2ec002628..509e118b673 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260803 +20260804 commit 70e457ec87b6ad7e1f4f5a3807b368cf9ffca666 Author: GCC Administrator Date: Wed Aug 5 00:20:05 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 509e118b673..abc8f80bb9f 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260804 +20260805 commit 96b128fdca4e19c75cf5a1924b40878c4a5a0e1a Author: Jerry DeLisle Date: Tue Jul 28 12:53:30 2026 -0700 fortran: [PR125866] Fix ICE: a module procedure with an allocatable, intent(out) Co-authored by: Steve Kargl PR fortran/125866 gcc/fortran/ChangeLog: * expr.cc (is_CFI_desc): Add check for proc_name. gcc/testsuite/ChangeLog: * gfortran.dg/pr125866.f90: New test. (cherry picked from commit 2886a168e82e603f8141d5ea633a0eb0a4a58a6e) diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc index 2da336fe50f..e2873421710 100644 --- a/gcc/fortran/expr.cc +++ b/gcc/fortran/expr.cc @@ -1128,7 +1128,7 @@ is_CFI_desc (gfc_symbol *sym, gfc_expr *e) && e && e->expr_type == EXPR_VARIABLE) sym = e->symtree->n.sym; - if (sym && sym->attr.dummy + if (sym && sym->attr.dummy && sym->ns && sym->ns->proc_name && sym->ns->proc_name->attr.is_bind_c && (sym->attr.pointer || sym->attr.allocatable diff --git a/gcc/testsuite/gfortran.dg/pr125866.f90 b/gcc/testsuite/gfortran.dg/pr125866.f90 new file mode 100644 index 00000000000..e0bc7b746f6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr125866.f90 @@ -0,0 +1,28 @@ +! { dg-do compile } +! ICE: a module procedure with an allocatable, intent(out) +! derived-type array dummy. Reduced from the original in the PR + +module m + interface + module subroutine s (a) + integer, allocatable, intent(out) :: a + end subroutine + end interface +end module + +submodule (m) sm1 +contains + module subroutine s (a) + integer, allocatable, intent(out) :: a + allocate (a, source = 7) + end subroutine +end submodule + +submodule (m:sm1) sm2 +contains + subroutine caller + integer, allocatable :: b + call s (b) + if (b /= 7) stop 1 + end subroutine +end submodule commit e57597862659f77a7ee1f934a7d5a36f44c6bae8 Author: GCC Administrator Date: Thu Aug 6 00:20:04 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index abc8f80bb9f..cb66c222632 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260805 +20260806 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 24b30b62d39..ddacbfbdb5e 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2026-08-05 Jerry DeLisle + + Backported from master: + 2026-07-28 Jerry DeLisle + + PR fortran/125866 + * expr.cc (is_CFI_desc): Add check for proc_name. + 2026-08-01 Jakub Jelinek Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6692c106867..7b6cf745ae0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2026-08-05 Jerry DeLisle + + Backported from master: + 2026-07-28 Jerry DeLisle + + PR fortran/125866 + * gfortran.dg/pr125866.f90: New test. + 2026-08-01 Jakub Jelinek Backported from master: commit 0eff70ac3c0c63681db0aa00e2bfa534e2348fec Author: GCC Administrator Date: Fri Aug 7 00:20:11 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index cb66c222632..4d4df8e5573 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260806 +20260807 commit b264e1a30435cd09eba144cdb13fe6d6abd9ae74 Author: GCC Administrator Date: Sat Aug 8 00:20:40 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4d4df8e5573..ac282fe95ef 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260807 +20260808 commit d57996b84cb21104ef58d5dac9455f34fa5ad818 Author: Paul Thomas Date: Sat May 23 14:58:36 2026 +0100 Fortran: Fix scalar class to derived select type entities. [PR125263] 2026-05-23 Paul Thomas gcc/fortran PR fortran/125263 * trans-expr.cc (gfc_trans_assignment_1): Pass scalar class to derived type assignment expressions to gfc_trans_scalar_assign. gcc/testsuite/ PR fortran/125263 * gfortran.dg/pr125263.f90: New test. (cherry picked from commit 6e1679ebd5e62dd63ee6c93df2514e0c08a2b674) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index a984130c227..7bbd6524e54 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -12441,13 +12441,19 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, needed. */ lhs_attr = gfc_expr_attr (expr1); + /* What can be sent to trans_class_assignment includes all the obvious + candidates but scalar assignment of a class expression to a derived type + must be done using gfc_trans_scalar_assign; partly because it is simpler + and partly because some cases fail, eg. class assignment to derived_type + select type temporaries. */ is_poly_assign = (use_vptr_copy || ((lhs_attr.pointer || lhs_attr.allocatable) && !lhs_attr.dimension)) && (expr1->ts.type == BT_CLASS || gfc_is_class_array_ref (expr1, NULL) || gfc_is_class_scalar_expr (expr1) || gfc_is_class_array_ref (expr2, NULL) - || gfc_is_class_scalar_expr (expr2)) + || (gfc_is_class_scalar_expr (expr2) + && !(expr1->ts.type == BT_DERIVED && !lhs_attr.dimension))) && lhs_attr.flavor != FL_PROCEDURE; realloc_flag = flag_realloc_lhs diff --git a/gcc/testsuite/gfortran.dg/pr125263.f90 b/gcc/testsuite/gfortran.dg/pr125263.f90 new file mode 100644 index 00000000000..9d8d4d08987 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr125263.f90 @@ -0,0 +1,71 @@ +! { dg-do run } +! +! Test the fix for pr125263, in which the selector expressions were not +! correctly set after the first two ASSOCIATE constructs below. +! +! Conributed by Bastiaan Braams +! +program Main + implicit none (type, external) + type :: Foo_Type + integer, allocatable :: x(:) + end type Foo_Type + class (Foo_Type), allocatable :: fv(:), f, g + integer :: nx = 2, nf = 3, i + + ! Create fv(:) with all component vectors initialized to 0. + allocate (Foo_Type::fv(0:nf-1)) + do i = 0, nf-1 + allocate (fv(i)%x(0:nx-1)) + fv(i)%x(:) = 0 + end do + + ! Create f with f%x(:) equal to 1 and g with g%x(:) equal to 2. + allocate (Foo_Type::f, g) + allocate (f%x(0:nx-1),g%x(0:nx-1)) + f%x(:) = 1 + g%x(:) = 2 + + ! Use intrinsic assignment to copy f to fv(0). + associate (ft => fv(0)) + select type (ft => fv(0)) + type is (Foo_Type) + ft = f + ft%x = [2,3,4] + class default + error stop 'select type (ft): type error' + end select + end associate + + ! Verify the copy on the element x(0) and that f is not overwritten. + if (any (fv(0)%x /= [2,3,4])) stop 1 + if (any (f%x /= [1,1])) stop 2 + + ! All scalar selector-exprs have the same problem, not just array elements. + f%x(:) = 1 + associate (ft => g) + select type (ft) + type is (Foo_Type) + ft = f + ft%x = [4,5,6] + class default + error stop 'select type (ft): type error' + end select + end associate + ! Verify the copy on g and that f is not overwritten. + if (any (g%x /= [4,5,6])) stop 3 + if (any (f%x /= [1,1])) stop 4 + + ! Assignment to an element of an array associate name was OK. + fv(0)%x(:) = [0,0,0] + select type (ft => fv) + type is (Foo_Type) + ft = f + ft(0)%x = [2,3,4] + class default + error stop 'select type (ft): type error' + end select + if (any (fv(0)%x /= [2,3,4])) stop 5 + if (any (f%x /= [1,1])) stop 6 + +end program Main commit ee3ccfd4552398c366d6704474fec1695e2399dc Author: Paul Thomas Date: Tue Feb 3 18:00:54 2026 +0000 Fortran: Fix module proc with array valued dummy procedure [PR123952] 2026-01-14 Paul Thomas gcc/fortran PR fortran/123952 * symbol.cc (gfc_copy_dummy_sym): Ensure that external, array valued destination symbols have the correct interface so that conflicts do not arise when adding attributes. gcc/testsuite PR fortran/123952 * gfortran.dg/pr123952.f90: New test. (cherry picked from commit 7c4d1a6a78e45e3a9fee21b09ad664346ede25a2) diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc index 048e81dc666..422814e2eac 100644 --- a/gcc/fortran/symbol.cc +++ b/gcc/fortran/symbol.cc @@ -2218,6 +2218,10 @@ gfc_copy_dummy_sym (gfc_symbol **dsym, gfc_symbol *sym, int result) if (!gfc_add_type (*dsym, &(sym->ts), &gfc_current_locus)) return 1; + if (sym->attr.external + && (sym->attr.codimension || sym->attr.dimension)) + (*dsym)->attr.if_source = IFSRC_DECL; + if (!gfc_copy_attr (&(*dsym)->attr, &(sym->attr), &gfc_current_locus)) return 1; diff --git a/gcc/testsuite/gfortran.dg/pr123952.f90 b/gcc/testsuite/gfortran.dg/pr123952.f90 new file mode 100644 index 00000000000..54be1b0385f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr123952.f90 @@ -0,0 +1,35 @@ +! { dg-do compile } +! +! Test the fix for PR123952, which failed as below. +! +! Contributed by Damian.Rouson +! +module tensors_1D_m + abstract interface + function scalar_1D_initializer_i() result(f) + double precision, allocatable :: f(:) + end function + end interface + + type :: scalar_1D_t + integer gradient_operator_1D_ + end type + + interface scalar_1D_t + module function construct_1D_scalar_from_function(initializer) result(scalar_1D) + procedure(scalar_1D_initializer_i), pointer :: initializer + type(scalar_1D_t) scalar_1D + end function + end interface + +end module tensors_1D_m + +submodule(tensors_1D_m) scalar_1D_s +contains + + module procedure construct_1D_scalar_from_function ! "MODULE PROCEDURE at (1) must be + ! in a generic module interface" + scalar_1D = scalar_1D_t (42) ! "Unexpected assignment statement..." + end procedure ! "Expecting END SUBMODULE statement at (1)" + +end submodule scalar_1D_s commit 3c2e3ad854f8861e07aabec650f3d9584f3c22ee Author: GCC Administrator Date: Sun Aug 9 00:18:38 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ac282fe95ef..8cb42c2ba5a 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260808 +20260809 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ddacbfbdb5e..34b7ddb8a06 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,22 @@ +2026-08-08 Paul Thomas + + Backported from master: + 2026-02-03 Paul Thomas + + PR fortran/123952 + * symbol.cc (gfc_copy_dummy_sym): Ensure that external, array + valued destination symbols have the correct interface so that + conflicts do not arise when adding attributes. + +2026-08-08 Paul Thomas + + Backported from master: + 2026-05-23 Paul Thomas + + PR fortran/125263 + * trans-expr.cc (gfc_trans_assignment_1): Pass scalar class to + derived type assignment expressions to gfc_trans_scalar_assign. + 2026-08-05 Jerry DeLisle Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b6cf745ae0..4a01bf902f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2026-08-08 Paul Thomas + + Backported from master: + 2026-02-03 Paul Thomas + + PR fortran/123952 + * gfortran.dg/pr123952.f90: New test. + +2026-08-08 Paul Thomas + + Backported from master: + 2026-05-23 Paul Thomas + + PR fortran/125263 + * gfortran.dg/pr125263.f90: New test. + 2026-08-05 Jerry DeLisle Backported from master: commit c56e990f78094fb47c2457b18d0772520071b370 Author: GCC Administrator Date: Mon Aug 10 00:18:37 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 8cb42c2ba5a..6c93e5aba5c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260809 +20260810 commit 2516507e19ed3624f4a3272532dee11db5946f31 Author: GCC Administrator Date: Tue Aug 11 00:18:49 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 6c93e5aba5c..be531dce922 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260810 +20260811 commit 05833009c1b3ebe2e5917f7c7af70573fcdcea2b Author: Robin Dapp Date: Tue Aug 4 11:37:33 2026 +0200 RISC-V: Fix single-step expansion [PR126550]. In expand_const_vector_single_step_npatterns, we use a second vector builder that is derived from the main one, in order to create a different alternating pattern for constant synthesis. We later use the second builder's number of patterns for creating an intermediate operation. The second builder can have a different number of patterns than the first one, however, for example when its "global" pattern is simpler. This patch uses npatterns from the original builder. PR target/126550 gcc/ChangeLog: * config/riscv/riscv-v.cc (expand_const_vector_single_step_npatterns): User global builder's npatterns. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr126550-2.c: New test. * gcc.target/riscv/rvv/autovec/pr126550.c: New test. (cherry picked from commit 6a7406611b2d2091d6a5e96e202e35e20da0f70b) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index bb38d8b42c7..96bb7c20147 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1415,7 +1415,7 @@ expand_const_vector (rtx target, rtx src) rtx tmp2 = gen_reg_rtx (builder.mode ()); rtx step = simplify_binary_operation (MINUS, builder.inner_mode (), - builder.elt (v.npatterns()), + builder->elt (builder->npatterns ()), builder.elt (0)); expand_vec_series (tmp2, const0_rtx, step, tmp); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126550-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126550-2.c new file mode 100644 index 00000000000..d04231f6e09 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126550-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv64gcv_zvl256b -mabi=lp64d" } */ + +#include +typedef uint16_t v16 __attribute__((vector_size(32))); + +v16 +foo (v16 x) +{ + return __builtin_shufflevector (x, x, 0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, + 7, 6, 7); +} + +/* { dg-final { scan-assembler-not "vmv.v.i\\sv\[0-9\]+,0" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126550.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126550.c new file mode 100644 index 00000000000..41b04d1c596 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126550.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-require-effective-target rvv_zvl256b_ok } */ +/* { dg-additional-options "-O3 -march=rv64gcv_zvl256b -mabi=lp64d -fno-vect-cost-model -std=gnu99" } */ + +#include + +struct Pair { uint16_t first, second; }; +struct S { uint16_t a[2], b[2]; uint32_t r; }; + +__attribute__((noipa)) +void load(struct S *dst, const struct Pair *src, unsigned long n) +{ + for (unsigned long k = 0; k < n; k++) { + dst[k].a[0] = src[k].first; + dst[k].a[1] = src[k].second; + dst[k].b[0] = src[k].first; + dst[k].b[1] = src[k].second; + } +} + +#define N 40 +static struct Pair src[N]; +static struct S out[N]; + +int main(void) +{ + for (unsigned i = 0; i < N; i++) { + src[i].first = (uint16_t)(i * 2u + 1); + src[i].second = (uint16_t)(i * 3u + 2); + } + load(out, src, N); + + for (unsigned i = 0; i < N; i++) { + uint16_t f = src[i].first, s = src[i].second; + if (out[i].a[0] != f || out[i].a[1] != s || + out[i].b[0] != f || out[i].b[1] != s) { + __builtin_abort (); + } + } + return 0; +} commit 736b8a9e2c9d78be31aed8905e012c7e1d233544 Author: Jeff Law Date: Tue Aug 11 07:15:58 2026 -0600 [RISC-V] Fix typo in manually merged patch PR target/126550 gcc/ * config/riscv/riscv-v.cc (expand_const_vector): Fix typo in manually merged patch. (cherry picked from commit e26d50c48017978e2fcdf9c9ce847ca053094c77) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 96bb7c20147..5d3fcf027bc 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1415,7 +1415,7 @@ expand_const_vector (rtx target, rtx src) rtx tmp2 = gen_reg_rtx (builder.mode ()); rtx step = simplify_binary_operation (MINUS, builder.inner_mode (), - builder->elt (builder->npatterns ()), + builder.elt (builder.npatterns ()), builder.elt (0)); expand_vec_series (tmp2, const0_rtx, step, tmp); commit 7912912fc3968186b97e5f3430a6417be3c2df66 Author: Robin Dapp Date: Tue Jul 21 10:37:58 2026 +0200 RISC-V: Use ordered scatter variants. The vectorizer expects scatters to write in an ordered fashion. Only the ordered indexed stores offer this, so use them instead of the unordered ones. PR target/126334 gcc/ChangeLog: * config/riscv/riscv-v.cc (get_gather_scatter_code): Use ordered indexed stores. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c: Adjust test expectations. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c: Ditto. (cherry picked from commit 7a5e4c2325ab22a096abb6127e4c9a1daadf3d3f) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 5d3fcf027bc..8f2bf428283 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -4008,7 +4008,7 @@ prepare_gather_scatter (machine_mode vec_mode, machine_mode idx_mode, bool is_load) { if (!is_load) - return code_for_pred_indexed_store (UNSPEC_UNORDERED, vec_mode, idx_mode); + return code_for_pred_indexed_store (UNSPEC_ORDERED, vec_mode, idx_mode); else { unsigned src_eew_bitsize = GET_MODE_BITSIZE (GET_MODE_INNER (idx_mode)); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c index 8ae5106b8a0..61579909a96 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c @@ -37,4 +37,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c index d705c920a2b..c6aa8165065 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c index 4e183cd9170..1f351627a8d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c @@ -31,4 +31,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c index 6277682e529..0f9fc62aaa3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c @@ -109,4 +109,4 @@ TEST_LOOP (double, uint64_t) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not "vluxei64\.v" } } */ -/* { dg-final { scan-assembler-not "vsuxei64\.v" } } */ +/* { dg-final { scan-assembler-not "vsoxei64\.v" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c index e4e42fef972..22e86765d51 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c @@ -37,4 +37,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c index e385fee109d..471494b68c8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c index e5cb19de42f..bd874d9e19c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c index a437e7393ee..3d2879296e5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c index 487dca9928b..121f3bd1404 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c index ff91929b8e7..51ba792b266 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c index 81df57fcbd2..decbfc6c6db 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c index 238b6bce042..dfb51a1af37 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c @@ -34,4 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c index c0b583354ad..d5b233fd815 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c @@ -38,4 +38,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c index 9e4fcee19ff..25cf4bf1d7e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c index e5741812b21..49568f65448 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c @@ -112,5 +112,5 @@ TEST_LOOP (double, uint64_t) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not "vluxei64\.v" } } */ -/* { dg-final { scan-assembler-not "vsuxei64\.v" } } */ +/* { dg-final { scan-assembler-not "vsoxei64\.v" } } */ /* { dg-final { scan-assembler-not {vlse64\.v\s+v[0-9]+,\s*0\([a-x0-9]+\),\s*zero} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c index aadc0206f2e..c69130e57c5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c @@ -38,4 +38,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c index b547dd61616..99e686b2b17 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c index ac601255879..b1ca99cda76 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c index f003a17ec31..fa0a2f6f1b8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c index d1d9581e81d..23fdefcfb5b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c index c8b5cea359f..97d75ceb3cb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c index dfb8a93626a..c9832330ec4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c index 32ddba6c167..40ae9b45898 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c @@ -35,4 +35,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c index 39e09f45640..fce72afa789 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c @@ -38,4 +38,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c index b1a234441eb..27432c60137 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c @@ -35,4 +35,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c index b52219366ad..fa89d997462 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c @@ -38,4 +38,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c index 4706d0f15d9..351ca111aff 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c @@ -35,4 +35,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c index aec7a930c5e..42084f62291 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c @@ -35,4 +35,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c index 286e2db19cf..a17f6a640a4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c @@ -35,4 +35,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c index 7674e2a7c80..f2d7ac0c067 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c @@ -35,4 +35,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c index 1738f7367b0..b21f23dd9c6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c @@ -35,4 +35,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c index d819a1a7515..87e90c448be 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c @@ -35,4 +35,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c index ee453e5e4c9..0c6c7a0ce27 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c @@ -40,4 +40,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c index 27c982aa354..61ea7de72e3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c @@ -37,3 +37,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c index 93f33696a20..480c9543a79 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c @@ -34,3 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c index cbb22507ad3..f5e98c68558 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c @@ -37,3 +37,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c index 93a84056b92..ad39056327e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c @@ -34,3 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c index c5816e06fdd..f87100c1b0f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c @@ -34,3 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c index c140d05b15e..37e3df9d037 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c @@ -34,3 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c index 41a03d31b70..b340e4da945 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c @@ -34,3 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c index f29ae25e8cc..a82a29a7193 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c @@ -34,3 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c index 8d72d98fb49..ed9cf262ae6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c @@ -34,3 +34,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c index dfd9412376d..052c82543ba 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c @@ -39,3 +39,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c index 4ad244b8e83..8748b2664d7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c @@ -37,4 +37,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c index a44cbc18b68..65d97346749 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c index 35e97012469..b424b894562 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c index fb72b092b7c..444254ea19b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c index 7b562bd94a9..36159a46db1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c index 67ea0e005f1..f822f6378e1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c index 76f84850b2b..0336028c0af 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c index e6e49019fb1..3b71e95b9f6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c index 81eb9352598..37ad2fa321f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c @@ -34,4 +34,5 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-assembler-not {vluxei64\.v} } } */ -/* { dg-final { scan-assembler-not {vsuxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsoxei64\.v} } } */ +/* { dg-final { scan-assembler-not {vsuxei32\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c index 343a3658396..01caf5bdc4f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c @@ -36,3 +36,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c index 76b0b075ba3..1c12ab13625 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c index 7eb881989b3..448666fdc4b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c @@ -36,3 +36,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c index 47e8ce3e186..d49bb18e728 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c index 5c51741e892..253f2d36abc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c index cc0b2fe15c4..5a5d233c25e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c index 3408cbd88d6..8a96bd9e20f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c index f45c9bc6727..a6fae802464 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c index 64fe30548cb..ee5a507f258 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c index bd1538db045..5f36eb8b37a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c @@ -33,3 +33,4 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-assembler-not "vsuxei" } } */ commit bd61dd7f657c3dd9a213843e72ca18674d618697 Author: GCC Administrator Date: Wed Aug 12 00:18:42 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e62603dcd4..86f1306fe0a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2026-08-11 Robin Dapp + + Backported from master: + 2026-08-11 Robin Dapp + + PR target/126334 + * config/riscv/riscv-v.cc (get_gather_scatter_code): Use ordered + indexed stores. + +2026-08-11 Jeff Law + + Backported from master: + 2026-08-11 Jeff Law + + PR target/126550 + * config/riscv/riscv-v.cc (expand_const_vector): Fix typo in manually + merged patch. + +2026-08-11 Robin Dapp + + Backported from master: + 2026-08-11 Robin Dapp + + PR target/126550 + * config/riscv/riscv-v.cc (expand_const_vector_single_step_npatterns): + User global builder's npatterns. + 2026-08-01 Jakub Jelinek Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index be531dce922..a2a375f6690 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260811 +20260812 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4a01bf902f0..4eaeb8c58bd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,82 @@ +2026-08-11 Robin Dapp + + Backported from master: + 2026-08-11 Robin Dapp + + PR target/126334 + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-1.c: + Adjust test expectations. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-12.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_32-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_32-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_32-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_64-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_32-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_64-9.c: Ditto. + +2026-08-11 Robin Dapp + + Backported from master: + 2026-08-11 Robin Dapp + + PR target/126550 + * gcc.target/riscv/rvv/autovec/pr126550-2.c: New test. + * gcc.target/riscv/rvv/autovec/pr126550.c: New test. + 2026-08-08 Paul Thomas Backported from master: commit eeb10396cb04dd9f0d1136ebc0c08559e8971f45 Author: GCC Administrator Date: Thu Aug 13 00:18:48 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index a2a375f6690..b945d86017f 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260812 +20260813 commit ec628b5263470fa75d9a286a58dc0bd03e410b4f Author: Uros Bizjak Date: Wed Aug 12 21:13:15 2026 +0200 i386: Fix some minor issues with BT patterns Relax register constraint on operand 1 of *bt from "q" to "r" so it is no longer restricted to the legacy byte-addressable register class. Also remove the unneeded "r,m" constraints on operand 0 of *bt_mask pre-reload splitter, keeping only the nonimmediate_operand predicate. gcc/ChangeLog: * config/i386/i386.md (*bt): Change operand 1 constraint from "q," to "r,". (*bt_mask): Remove constraints from operand 0. (cherry picked from commit f296bb38423fb786f20d213f9f87bf2c7ce14b63) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2af48a3ff7a..8dd758ecbdc 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -17638,7 +17638,7 @@ (zero_extract:SWI48 (match_operand:SWI48 0 "nonimmediate_operand" "r,m") (const_int 1) - (match_operand:QI 1 "nonmemory_operand" "q,"))))] + (match_operand:QI 1 "nonmemory_operand" "r,"))))] "" { switch (get_attr_mode (insn)) @@ -17667,7 +17667,7 @@ (compare:CCC (const_int 0) (zero_extract:SWI48 - (match_operand:SWI48 0 "nonimmediate_operand" "r,m") + (match_operand:SWI48 0 "nonimmediate_operand") (const_int 1) (subreg:QI (and:SWI248 commit 65485cb64290135f8ba10c3f1477588fb45a5467 Author: GCC Administrator Date: Fri Aug 14 00:18:32 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86f1306fe0a..fd8a4e046cd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2026-08-13 Uros Bizjak + + Backported from master: + 2026-08-12 Uros Bizjak + + * config/i386/i386.md (*bt): Change operand 1 constraint + from "q," to "r,". + (*bt_mask): Remove constraints from operand 0. + 2026-08-11 Robin Dapp Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index b945d86017f..0a060f7a584 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260813 +20260814 commit c4433ca7a344ecb4f4924badd28117cb3c7ff93c Author: GCC Administrator Date: Sat Aug 15 00:18:51 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 0a060f7a584..c896594582e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260814 +20260815 commit b0a1bcacd1c1e38e5fde67a8a9fb8f9d595b38e2 Author: GCC Administrator Date: Sun Aug 16 00:18:41 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c896594582e..434dacbd75d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260815 +20260816 commit 91fa0296cca17b759075e08f930d7e3ae01610f8 Author: GCC Administrator Date: Mon Aug 17 00:18:30 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 434dacbd75d..16d61608baf 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260816 +20260817 commit 551771f93d1cd8eeade21fba87c80a69534bd766 Author: Jonathan Wakely Date: Mon Aug 17 14:09:16 2026 +0100 libstdc++: Fix preprocessor check for bfloat16_t in [PR126849] libstdc++-v3/ChangeLog: PR libstdc++/126849 * include/std/numbers: Fix preprocessor check for std::bfloat16_t support. (cherry picked from commit 92bcc711fafc026e0cc2f48b7f3ab23657787a8c) diff --git a/libstdc++-v3/include/std/numbers b/libstdc++-v3/include/std/numbers index 9836afac645..9b49ccfcb7b 100644 --- a/libstdc++-v3/include/std/numbers +++ b/libstdc++-v3/include/std/numbers @@ -217,7 +217,7 @@ __glibcxx_numbers (_Float64, F64); __glibcxx_numbers (_Float128, F128); #endif -#ifdef __STDCPP_BFLOAT128_T__ +#ifdef __STDCPP_BFLOAT16_T__ __glibcxx_numbers (__gnu_cxx::__bfloat16_t, BF16); #endif commit 8a91459bc2d960bf4947bfa1bf86cc32fbd71a19 Author: GCC Administrator Date: Tue Aug 18 00:18:42 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 16d61608baf..96f8ad477e2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260817 +20260818 diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 5fb05af306b..b5e7d616d85 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2026-08-17 Jonathan Wakely + + Backported from master: + 2026-08-17 Jonathan Wakely + + PR libstdc++/126849 + * include/std/numbers: Fix preprocessor check for + std::bfloat16_t support. + 2026-07-31 Tomasz Kamiński Backported from master: commit 2dd0596e0d0c5d34907de947567e139808453c68 Author: Piotr Kubaj Date: Wed Jul 22 15:45:04 2026 +0200 libgcc: rs6000: fix TOC restore when unwinding on FreeBSD powerpc64 ELFv2 [PR target/125803] On powerpc64, when the unwind info for a frame does not explicitly describe how r2 (the TOC pointer) was saved -- which is the normal case for the linker-generated PLT call stubs -- frob_update_context inspects the code stream to locate the saved TOC and arranges for r2 to be restored from it. The FreeBSD version of this hook hard-coded the ELFv1 TOC save slot offset of 40 bytes, matching "std r2,40(r1)" (0xF8410028) and "ld r2,40(r1)" (0xE8410028). FreeBSD/powerpc64 (both big-endian and powerpc64le) uses ELFv2, where the TOC is saved at offset 24 ("std r2,24(r1)" / "ld r2,24(r1)"). As a result the checks never matched, r2 was left unrestored, and code reached by unwinding -- e.g. a C++ catch handler in a different module than libgcc_s -- ran with the wrong TOC. Any global or PLT access from such a handler then computed a bogus address, typically crashing. This made C++ exceptions unusable on FreeBSD/powerpc64le whenever gcc's shared libgcc_s provided the unwinder (for instance any clang-built C++ program that pulls in libgfortran). Define TOC_SAVE_SLOT based on _CALL_ELF (24 for ELFv2, 40 otherwise) and use it throughout, and guard the ELFv1-only code-reading cases (the old PLT stub form and the function pointer call sequence) with _CALL_ELF != 2, mirroring linux-unwind.h. libgcc/ChangeLog: PR target/125803 * config/rs6000/freebsd-unwind.h (TOC_SAVE_SLOT): New macro, defined according to _CALL_ELF. (frob_update_context): Use TOC_SAVE_SLOT instead of the hard-coded ELFv1 offset 40 when checking for and locating the saved TOC, so that r2 is restored correctly under ELFv2. Guard the ELFv1-only PLT stub and function pointer call sequences with _CALL_ELF != 2, mirroring linux-unwind.h. Signed-off-by: Piotr Kubaj diff --git a/libgcc/config/rs6000/freebsd-unwind.h b/libgcc/config/rs6000/freebsd-unwind.h index f261babb604..4c6ca91919f 100644 --- a/libgcc/config/rs6000/freebsd-unwind.h +++ b/libgcc/config/rs6000/freebsd-unwind.h @@ -24,6 +24,14 @@ #define R_LR 65 +#ifdef __powerpc64__ +#if _CALL_ELF == 2 +#define TOC_SAVE_SLOT 24 +#else +#define TOC_SAVE_SLOT 40 +#endif +#endif + #define MD_FROB_UPDATE_CONTEXT frob_update_context static void @@ -40,9 +48,13 @@ frob_update_context (struct _Unwind_Context *context, figure out if it was saved. The big problem here is that the code that does the save/restore is generated by the linker, so we have no good way to determine at compile time what to do. */ - if (pc[0] == 0xF8410028 + if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT +#if _CALL_ELF != 2 + /* The ELFv2 linker never generates the old PLT stub form. */ || ((pc[0] & 0xFFFF0000) == 0x3D820000 - && pc[1] == 0xF8410028)) + && pc[1] == 0xF8410000 + TOC_SAVE_SLOT) +#endif + ) { /* We are in a plt call stub or r2 adjusting long branch stub, before r2 has been saved. Keep REG_UNSAVED. */ @@ -51,18 +63,21 @@ frob_update_context (struct _Unwind_Context *context, { unsigned int *insn = (unsigned int *) _Unwind_GetGR (context, R_LR); - if (insn && *insn == 0xE8410028) - _Unwind_SetGRPtr (context, 2, context->cfa + 40); + if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT) + _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT); +#if _CALL_ELF != 2 + /* ELFv2 does not use this function pointer call sequence. */ else if (pc[0] == 0x4E800421 - && pc[1] == 0xE8410028) + && pc[1] == 0xE8410000 + TOC_SAVE_SLOT) { /* We are at the bctrl instruction in a call via function pointer. gcc always emits the load of the new R2 just before the bctrl so this is the first and only place we need to use the stored R2. */ _Unwind_Word sp = _Unwind_GetGR (context, 1); - _Unwind_SetGRPtr (context, 2, (void *)(sp + 40)); + _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT)); } +#endif } } #endif commit 5bd713d35f7af3954ea21ec3049ae126b50e99e6 Author: Jonathan Wakely Date: Wed Jul 29 16:55:39 2026 +0100 libstdc++: Fix grep for linker warning about --gc-sections [PR126452] Current versions of GNU ld print "warning" with a lowercase 'w' so adjust the grep patter. Also use LC_ALL=C to ensure the warning isn't translated. Because m4 uses square brackets as quotes, we need to use double brackets in the grep pattern to expand to "[Ww]" in the configure script. libstdc++-v3/ChangeLog: PR libstdc++/126452 * acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Use LC_ALL_C and match both "Warning" and "warning" in ld output. * configure: Regenerate. Reviewed-by: Jakub Jelinek (cherry picked from commit b7ce998a967639b955159eeeae940cb069c518d8) diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 51a08bcc8b1..6ab5fa0c452 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -253,8 +253,8 @@ AC_DEFUN([GLIBCXX_CHECK_LINKER_FEATURES], [ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[[Ww]]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 08d2a7a8259..af54b44a8eb 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -23012,8 +23012,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -28848,8 +28848,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -32027,8 +32027,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -38245,8 +38245,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -38533,8 +38533,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -38998,8 +38998,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -42440,8 +42440,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -45835,8 +45835,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi @@ -46048,8 +46048,8 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conftest.c touch conftest.c if $CC -c conftest.c; then - if $LD --gc-sections -o conftest conftest.o 2>&1 | \ - grep "Warning: gc-sections option ignored" > /dev/null; then + if LC_ALL=C $LD --gc-sections -o conftest conftest.o 2>&1 | \ + grep "[Ww]arning: gc-sections option ignored" > /dev/null; then ac_gcsections=no fi fi commit ddf0caf17f4e8244702d6725b472154feca00728 Author: GCC Administrator Date: Wed Aug 19 00:18:48 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 96f8ad477e2..a8e78f54d93 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260818 +20260819 diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 88946912d24..81a76693284 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,14 @@ +2026-08-18 Piotr Kubaj + + PR target/125803 + * config/rs6000/freebsd-unwind.h (TOC_SAVE_SLOT): New macro, + defined according to _CALL_ELF. + (frob_update_context): Use TOC_SAVE_SLOT instead of the + hard-coded ELFv1 offset 40 when checking for and locating the + saved TOC, so that r2 is restored correctly under ELFv2. Guard + the ELFv1-only PLT stub and function pointer call sequences + with _CALL_ELF != 2, mirroring linux-unwind.h. + 2026-06-26 Release Manager * GCC 14.4.0 released. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b5e7d616d85..23a8271b30d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2026-08-18 Jonathan Wakely + + Backported from master: + 2026-07-29 Jonathan Wakely + + PR libstdc++/126452 + * acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Use LC_ALL_C and + match both "Warning" and "warning" in ld output. + * configure: Regenerate. + 2026-08-17 Jonathan Wakely Backported from master: commit 829adce14577038d6c55870a71f67cfd498357a8 Author: Alice Carlotti Date: Fri Aug 7 17:56:49 2026 +0100 aarch64: Fix -march=native when -mtune is used [PR124629] Handling of -march=native for recognised cores was broken by r13-2937-g00c22ba69d8e73, which added "V" to ARCH_IDENT values and filtered it out in some locations. This causes a lookup by stringified ARCH_IDENT values to fail. If no -mtune or -mcpu option is used, then we avoid this bug by upgrading -march=native to -mcpu=native. Fix this by removing the '+ 1' string offset, so that the ident strings match again. It would be marginally more efficient to use enum values here, but I've stuck with this simpler fix instead. gcc/ChangeLog: PR target/124629 * config/aarch64/driver-aarch64.cc (AARCH64_ARCH): Don't skip first character of #ARCH_IDENT. gcc/testsuite/ChangeLog: PR target/124629 * gcc.target/aarch64/cpunative/info_36: New test file. * gcc.target/aarch64/cpunative/native_cpu_36.c: New test. diff --git a/gcc/config/aarch64/driver-aarch64.cc b/gcc/config/aarch64/driver-aarch64.cc index fa0c57e6074..f56de7ef119 100644 --- a/gcc/config/aarch64/driver-aarch64.cc +++ b/gcc/config/aarch64/driver-aarch64.cc @@ -79,9 +79,8 @@ struct aarch64_arch_driver_info aarch64_feature_flags flags; }; -/* Skip the leading "V" in the architecture name. */ #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH_REV, FLAGS) \ - { #ARCH_IDENT + 1, NAME, feature_deps::ARCH_IDENT ().enable }, + { #ARCH_IDENT, NAME, feature_deps::ARCH_IDENT ().enable }, static CONSTEXPR const aarch64_arch_driver_info aarch64_arches[] = { diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_36 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_36 new file mode 100644 index 00000000000..620340fdfae --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_36 @@ -0,0 +1,9 @@ +processor : 0 +BogoMIPS : 100.00 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 fphp asimdhp fcma +CPU implementer : 0x41 +CPU architecture: 8 +CPU variant : 0x0 +CPU part : 0xd08 +CPU revision : 2 + diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_36.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_36.c new file mode 100644 index 00000000000..04af5b04ba5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_36.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */ +/* { dg-set-compiler-env-var GCC_CPUINFO "$srcdir/gcc.target/aarch64/cpunative/info_36" } */ +/* { dg-additional-options "-march=native -mtune=cortex-a34" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler {\.arch armv8-a\+dotprod\+crc\+crypto\+sve2\n} } } */ commit 09d4413c87510afe867c927793245a76f8165f28 Author: GCC Administrator Date: Thu Aug 20 00:18:50 2026 +0000 Daily bump. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd8a4e046cd..72f76b9ddce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2026-08-19 Alice Carlotti + + PR target/124629 + * config/aarch64/driver-aarch64.cc (AARCH64_ARCH): + Don't skip first character of #ARCH_IDENT. + 2026-08-13 Uros Bizjak Backported from master: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index a8e78f54d93..7a23bbffaa7 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260819 +20260820 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4eaeb8c58bd..cf9971f693d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2026-08-19 Alice Carlotti + + PR target/124629 + * gcc.target/aarch64/cpunative/info_36: New test file. + * gcc.target/aarch64/cpunative/native_cpu_36.c: New test. + 2026-08-11 Robin Dapp Backported from master: commit 49ae529a50ecae550d56c26401b379a148720e4c Author: GCC Administrator Date: Fri Aug 21 00:18:52 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 7a23bbffaa7..e500c1b0842 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260820 +20260821 commit 6916a5fd1fd3b4b88f865d3844798c769d832197 Author: GCC Administrator Date: Sat Aug 22 00:18:51 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e500c1b0842..56ffce9b6ae 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260821 +20260822 commit 3a6699feae05498cf33706f33ffa3ee13c21998a Author: GCC Administrator Date: Sun Aug 23 00:18:39 2026 +0000 Daily bump. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 56ffce9b6ae..8f179cc6bab 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20260822 +20260823