[gcc r15-7848] RISC-V: Tweak asm check for test case multiple_rgroup_zbb.c
https://gcc.gnu.org/g:0aa9b079aec260b120b7c9fdba8c21066425c73d commit r15-7848-g0aa9b079aec260b120b7c9fdba8c21066425c73d Author: Pan Li Date: Thu Mar 6 09:24:18 2025 +0800 RISC-V: Tweak asm check for test case multiple_rgroup_zbb.c The changes to vsetvl pass since 14 result in the asm check failure, update the asm check to meet the newest behavior. The below test suites are passed for this patch. * The rv64gcv fully regression test. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/partial/multiple_rgroup_zbb.c: Tweak the asm check for vsetvl. Signed-off-by: Pan Li Diff: --- .../gcc.target/riscv/rvv/autovec/partial/multiple_rgroup_zbb.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/multiple_rgroup_zbb.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/multiple_rgroup_zbb.c index a851229daacf..a6d4b77ccd72 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/multiple_rgroup_zbb.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/multiple_rgroup_zbb.c @@ -20,4 +20,7 @@ test (uint16_t *__restrict f, uint32_t *__restrict d, uint64_t *__restrict e, } } -/* { dg-final { scan-assembler-times "vsetvli\tzero,\s*\[a-z0-9\]+,\s*e16,\s*m1,\s*ta,\s*ma" 4 } } */ +/* { dg-final { scan-assembler-times "vsetvli\tzero,\s*\[a-z0-9\]+,\s*e16,\s*m\[1248\],\s*ta,\s*ma" 1 } } */ +/* { dg-final { scan-assembler-times "vsetvli\tzero,\s*\[a-z0-9\]+,\s*e32,\s*m\[1248\],\s*ta,\s*ma" 1 } } */ +/* { dg-final { scan-assembler-times "vsetvli\tzero,\s*\[a-z0-9\]+,\s*e64,\s*m\[1248\],\s*ta,\s*ma" 1 } } */ +/* { dg-final { scan-assembler-times "vsetivli\tzero,\s*\[0-9\]+,\s*e64,\s*m\[1248\],\s*ta,\s*ma" 1 } } */
[gcc r15-7847] Improve coverage of ext-dce tests in risc-v testsuite
https://gcc.gnu.org/g:316eaca17ee11f575fc72e139e8cc3f9f5ccb067 commit r15-7847-g316eaca17ee11f575fc72e139e8cc3f9f5ccb067 Author: Jeff Law Date: Wed Mar 5 22:24:05 2025 -0700 Improve coverage of ext-dce tests in risc-v testsuite Inspired by Liao Shihua, this adjusts two tests in the RISC-V testsuite to get more coverage. Drop the -O1 argument and replace it with -fext-dce. That way the test gets run across the full set of flags. We just need to make sure to skip -O0. gcc/testsuite/ChangeLog: * gcc.target/riscv/core_list_init.c: Use -fext-dce rather than -O1. Skip for -O0. * gcc.target/riscv/pr111384.c: Ditto. Diff: --- gcc/testsuite/gcc.target/riscv/core_list_init.c | 3 ++- gcc/testsuite/gcc.target/riscv/pr111384.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/core_list_init.c b/gcc/testsuite/gcc.target/riscv/core_list_init.c index 2f36dae85aa7..eec3a817d80c 100644 --- a/gcc/testsuite/gcc.target/riscv/core_list_init.c +++ b/gcc/testsuite/gcc.target/riscv/core_list_init.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-rtl-ext_dce" } */ +/* { dg-options "-fext-dce -fdump-rtl-ext_dce" } */ /* { dg-final { scan-rtl-dump {Successfully transformed} "ext_dce" } } */ +/* { dg-skip-if "" { *-*-* } { "-O0"} } */ unsigned short core_list_init (int size, short seed) { diff --git a/gcc/testsuite/gcc.target/riscv/pr111384.c b/gcc/testsuite/gcc.target/riscv/pr111384.c index a4e77d4aeb64..bcf33ebf 100644 --- a/gcc/testsuite/gcc.target/riscv/pr111384.c +++ b/gcc/testsuite/gcc.target/riscv/pr111384.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-rtl-ext_dce" } */ +/* { dg-options "-fext-dce -fdump-rtl-ext_dce" } */ /* { dg-final { scan-rtl-dump {Successfully transformed} "ext_dce" } } */ +/* { dg-skip-if "" { *-*-* } { "-O0"} } */ void foo(unsigned int src, unsigned short *dst1, unsigned short *dst2)
[gcc r15-7825] c++: Fix checking assert upon invalid class definition [PR116740]
https://gcc.gnu.org/g:b3d078220d202094a2b4eaef9b4a5ad1b84d30e6 commit r15-7825-gb3d078220d202094a2b4eaef9b4a5ad1b84d30e6 Author: Simon Martin Date: Wed Mar 5 09:08:57 2025 +0100 c++: Fix checking assert upon invalid class definition [PR116740] A checking assert triggers upon the following invalid code since GCC 11: === cut here === class { a (struct b; } struct b === cut here === The problem is that during error recovery, we call set_identifier_type_value_with_scope for B in the global namespace, and the checking assert added via r11-7228-g8f93e1b892850b fails. This patch relaxes that assert to not fail if we've seen a parser error (it a generalization of another fix done to that checking assert via r11-7266-g24bf79f1798ad1). PR c++/116740 gcc/cp/ChangeLog: * name-lookup.cc (set_identifier_type_value_with_scope): Don't fail assert with ill-formed input. gcc/testsuite/ChangeLog: * g++.dg/parse/crash80.C: New test. Diff: --- gcc/cp/name-lookup.cc| 6 ++ gcc/testsuite/g++.dg/parse/crash80.C | 7 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index d1abb205bc7f..742e5d289dc9 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -5101,10 +5101,8 @@ set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b) if (b->kind == sk_namespace) /* At namespace scope we should not see an identifier type value. */ gcc_checking_assert (!REAL_IDENTIFIER_TYPE_VALUE (id) -/* We could be pushing a friend underneath a template - parm (ill-formed). */ -|| (TEMPLATE_PARM_P -(TYPE_NAME (REAL_IDENTIFIER_TYPE_VALUE (id); +/* But we might end up here with ill-formed input. */ +|| seen_error ()); else { /* Push the current type value, so we can restore it later */ diff --git a/gcc/testsuite/g++.dg/parse/crash80.C b/gcc/testsuite/g++.dg/parse/crash80.C new file mode 100644 index ..cd9216adf5c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash80.C @@ -0,0 +1,7 @@ +// PR c++/116740 +// { dg-do "compile" } + +class K { + int a(struct b; // { dg-error "expected '\\)'" } +}; +struct b {};
[gcc r15-7829] middle-end/97323 - TYPE_CANONICAL vs. ARRAY_TYPE modes
https://gcc.gnu.org/g:556e25f0e9abc720c940994bd9a1491062933d49 commit r15-7829-g556e25f0e9abc720c940994bd9a1491062933d49 Author: Richard Biener Date: Tue Mar 4 16:13:09 2025 +0100 middle-end/97323 - TYPE_CANONICAL vs. ARRAY_TYPE modes For strict-alignment targets we can end up with BLKmode single-element array types when the element type is unaligned. This confuses type checking since the canonical type would have an aligned element type and a non-BLKmode mode. The following simply ignores the mode we assign to array types for this purpose, like we already do for record and union types. PR middle-end/97323 * tree.cc (gimple_canonical_types_compatible_p): Ignore TYPE_MODE also for ARRAY_TYPE. (verify_type): Likewise. * gcc.dg/pr97323.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/pr97323.c | 5 + gcc/tree.cc| 2 ++ 2 files changed, 7 insertions(+) diff --git a/gcc/testsuite/gcc.dg/pr97323.c b/gcc/testsuite/gcc.dg/pr97323.c new file mode 100644 index ..8845a34fa158 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr97323.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-g" } */ + +typedef int a __attribute__((aligned(2))); +a b[1]; diff --git a/gcc/tree.cc b/gcc/tree.cc index 0743ed71c789..4e855b4b2d33 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -13982,6 +13982,7 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2, flexible array members, we allow mismatching modes for structures or unions. */ if (!RECORD_OR_UNION_TYPE_P (t1) + && TREE_CODE (t1) != ARRAY_TYPE && TYPE_MODE (t1) != TYPE_MODE (t2)) return false; @@ -14313,6 +14314,7 @@ verify_type (const_tree t) flexible array members. */ && !RECORD_OR_UNION_TYPE_P (t) && !RECORD_OR_UNION_TYPE_P (TYPE_CANONICAL (t)) + && TREE_CODE (t) != ARRAY_TYPE && TYPE_MODE (t) != TYPE_MODE (TYPE_CANONICAL (t))) { error ("% of % is not compatible");
[gcc r13-9410] aarch64: Fix caller saves of VNx2QI [PR116238]
https://gcc.gnu.org/g:995f0e76f01abcbbb29c47d9019418d253c41a43 commit r13-9410-g995f0e76f01abcbbb29c47d9019418d253c41a43 Author: Richard Sandiford Date: Wed Mar 5 08:25:54 2025 + aarch64: Fix caller saves of VNx2QI [PR116238] The testcase contains a VNx2QImode pseudo that is live across a call and that cannot be allocated a call-preserved register. LRA quite reasonably tried to save it before the call and restore it afterwards. Unfortunately, the target told it to do that in SImode, even though punning between SImode and VNx2QImode is disallowed by both TARGET_CAN_CHANGE_MODE_CLASS and TARGET_MODES_TIEABLE_P. The natural class to use for SImode is GENERAL_REGS, so this led to an unsalvageable situation in which we had: (set (subreg:VNx2QI (reg:SI A) 0) (reg:VNx2QI B)) where A needed GENERAL_REGS and B needed FP_REGS. We therefore ended up in a reload loop. The hooks above should ensure that this situation can never occur for incoming subregs. It only happened here because the target explicitly forced it. The decision to use SImode for modes smaller than 4 bytes dates back to the beginning of the port, before 16-bit floating-point modes existed. I'm not sure whether promoting to SImode really makes sense for any FPR, but that's a separate performance/QoI discussion. For now, this patch just disallows using SImode when it is wrong for correctness reasons, since that should be safer to backport. gcc/ PR testsuite/116238 * config/aarch64/aarch64.cc (aarch64_hard_regno_caller_save_mode): Only return SImode if we can convert to and from it. gcc/testsuite/ PR testsuite/116238 * gcc.target/aarch64/sve/pr116238.c: New test. (cherry picked from commit ec9d6d45191f639482344362d048294e74587ca3) Diff: --- gcc/config/aarch64/aarch64.cc | 7 --- gcc/testsuite/gcc.target/aarch64/sve/pr116238.c | 13 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 2f01580a7973..a18355e8c96b 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -4168,10 +4168,11 @@ aarch64_hard_regno_caller_save_mode (unsigned regno, unsigned, unnecessarily significant. */ if (PR_REGNUM_P (regno)) return mode; - if (known_ge (GET_MODE_SIZE (mode), 4)) -return mode; - else + if (known_lt (GET_MODE_SIZE (mode), 4) + && REG_CAN_CHANGE_MODE_P (regno, mode, SImode) + && REG_CAN_CHANGE_MODE_P (regno, SImode, mode)) return SImode; + return mode; } /* Return true if I's bits are consecutive ones from the MSB. */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr116238.c b/gcc/testsuite/gcc.target/aarch64/sve/pr116238.c new file mode 100644 index ..fe66b198107f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr116238.c @@ -0,0 +1,13 @@ +/* { dg-additional-options "-O2 -msve-vector-bits=128" } */ + +void foo(); +typedef unsigned char v2qi __attribute__((vector_size(2))); +void f(v2qi *ptr) +{ + v2qi x = *ptr; + asm volatile ("" :: "w" (x)); + asm volatile ("" ::: "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"); + foo(); + asm volatile ("" :: "w" (x)); + *ptr = x; +}
[gcc r13-9411] aarch64: Fix folding of degenerate svwhilele case [PR117045]
https://gcc.gnu.org/g:591e34c1f7bbaa6ac1046ec45f7d162fdb33a1de commit r13-9411-g591e34c1f7bbaa6ac1046ec45f7d162fdb33a1de Author: Richard Sandiford Date: Wed Mar 5 08:25:54 2025 + aarch64: Fix folding of degenerate svwhilele case [PR117045] The svwhilele folder mishandled the degenerate case in which the second argument is the maximum integer. In that case, the result is all-true regardless of the first parameter: If the second scalar operand is equal to the maximum signed integer value then a condition which includes an equality test can never fail and the result will be an all-true predicate. This is because the conceptual "increment the first operand by 1 after each element" is done modulo the range of the operand. The GCC code was instead treating it as infinite precision. whilele_5.c even had a test for the incorrect behaviour. The easiest fix seemed to be to handle that case specially before doing constant folding. This also copes with variable first operands. gcc/ PR target/116999 PR target/117045 * config/aarch64/aarch64-sve-builtins-base.cc (svwhilelx_impl::fold): Check for WHILELTs of the minimum value and WHILELEs of the maximum value. Fold them to all-false and all-true respectively. gcc/testsuite/ PR target/116999 PR target/117045 * gcc.target/aarch64/sve/acle/general/whilele_5.c: Fix bogus expected result. * gcc.target/aarch64/sve/acle/general/whilele_11.c: New test. * gcc.target/aarch64/sve/acle/general/whilele_12.c: Likewise. (cherry picked from commit 50e7c51b0a0e9dc1d93f829016ae743b4f2e5070) Diff: --- gcc/config/aarch64/aarch64-sve-builtins-base.cc| 11 ++- .../aarch64/sve/acle/general/whilele_11.c | 31 .../aarch64/sve/acle/general/whilele_12.c | 34 ++ .../aarch64/sve/acle/general/whilele_5.c | 2 +- 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc index 852f569461ad..85585c5941c8 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc @@ -2456,7 +2456,9 @@ public: : while_comparison (unspec_for_sint, unspec_for_uint), m_eq_p (eq_p) {} - /* Try to fold a call by treating its arguments as constants of type T. */ + /* Try to fold a call by treating its arguments as constants of type T. + We have already filtered out the degenerate cases of X .LT. MIN + and X .LE. MAX. */ template gimple * fold_type (gimple_folder &f) const @@ -2509,6 +2511,13 @@ public: gimple * fold (gimple_folder &f) const override { +/* Filter out cases where the condition is always true or always false. */ +tree arg1 = gimple_call_arg (f.call, 1); +if (!m_eq_p && operand_equal_p (arg1, TYPE_MIN_VALUE (TREE_TYPE (arg1 + return f.fold_to_pfalse (); +if (m_eq_p && operand_equal_p (arg1, TYPE_MAX_VALUE (TREE_TYPE (arg1 + return f.fold_to_ptrue (); + if (f.type_suffix (1).unsigned_p) return fold_type (f); else diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_11.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_11.c new file mode 100644 index ..2be9dc5c5347 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_11.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include +#include + +svbool_t +f1 (volatile int32_t *ptr) +{ + return svwhilelt_b8_s32 (*ptr, INT32_MIN); +} + +svbool_t +f2 (volatile uint32_t *ptr) +{ + return svwhilelt_b16_u32 (*ptr, 0); +} + +svbool_t +f3 (volatile int64_t *ptr) +{ + return svwhilelt_b32_s64 (*ptr, INT64_MIN); +} + +svbool_t +f4 (volatile uint64_t *ptr) +{ + return svwhilelt_b64_u64 (*ptr, 0); +} + +/* { dg-final { scan-assembler-times {\tpfalse\tp[0-9]+\.b\n} 4 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_12.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_12.c new file mode 100644 index ..713065c31453 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_12.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include +#include + +svbool_t +f1 (volatile int32_t *ptr) +{ + return svwhilele_b8_s32 (*ptr, INT32_MAX); +} + +svbool_t +f2 (volatile uint32_t *ptr) +{ + return svwhilele_b16_u32 (*ptr, UINT32_MAX); +} + +svbool_t +f3 (volatile int64_t *ptr) +{ + return svwhilele_b32_s64 (*ptr, INT64_MAX); +} + +svbool_t +f4 (volatile uint64_t *ptr) +{ + return svwhilele_b64_u64 (*ptr, UINT64_MAX); +} + +/* { dg-final { scan-assembler {\tptrue\tp[0-9]+\.b(?:, all)\n} } } */ +/* { dg-final { scan-ass
[gcc r15-7830] libstdc++: Fix subrange conversion to pair-like [PR119121]
https://gcc.gnu.org/g:95b2f8d8fb3131165b1b38645dacf10a5dd2bc15 commit r15-7830-g95b2f8d8fb3131165b1b38645dacf10a5dd2bc15 Author: Tomasz Kamiński Date: Wed Mar 5 11:11:55 2025 +0100 libstdc++: Fix subrange conversion to pair-like [PR119121] Fix regression introduced by r14-8710-g65b4cba9d6a9ff PR libstdc++/119121 libstdc++-v3/ChangeLog: * include/bits/ranges_util.h (__detail::__pair_like_convertible_from): Use `_Tp` in `is_reference_v` check * testsuite/std/ranges/subrange/tuple_like.cc: New tests for pair-like conversion Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/bits/ranges_util.h| 2 +- .../testsuite/std/ranges/subrange/tuple_like.cc| 29 ++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index 2f56b727e55a..51024ecbebe5 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -244,7 +244,7 @@ namespace ranges template concept __pair_like_convertible_from - = !range<_Tp> && !is_reference_v<_Vp> && __pair_like<_Tp> + = !range<_Tp> && !is_reference_v<_Tp> && __pair_like<_Tp> && constructible_from<_Tp, _Up, _Vp> && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>> && convertible_to<_Vp, tuple_element_t<1, _Tp>>; diff --git a/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc index 6d05eb3ef7d5..80fe618642a0 100644 --- a/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc +++ b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc @@ -18,6 +18,8 @@ // { dg-do compile { target c++20 } } #include +#include +#include using S1 = std::ranges::subrange; using S2 = std::ranges::subrange; @@ -49,3 +51,30 @@ static_assert( std::same_as(s2)), void*> ); const S2 c2; static_assert( std::same_as(c2)), long*> ); static_assert( std::same_as(c2)), void*> ); + +std::pair p1 = s1; +std::pair p2 = s2; +std::tuple t1 = s1; +std::tuple t2 = s2; + +std::pair const& p3 = s1; +std::tuple&& t3 = s1; + +std::pair p4 = s1; +std::tuple t4 = s1; + +static_assert( !std::convertible_to, std::pair> ); +static_assert( !std::convertible_to, std::tuple> ); + +static_assert( !std::convertible_to, std::pair> ); +static_assert( !std::convertible_to, std::tuple> ); + +struct B {}; +struct D : B {}; + +std::ranges::subrange sd; +std::pair p5 = sd; +std::tuple t5 = sd; + +static_assert( !std::convertible_to, std::pair> ); +static_assert( !std::convertible_to, std::tuple> );
[gcc r13-9412] Fix folding of BIT_NOT_EXPR for POLY_INT_CST [PR118976]
https://gcc.gnu.org/g:7995713012fcc0e0e098157d87fe5ff9d85c820b commit r13-9412-g7995713012fcc0e0e098157d87fe5ff9d85c820b Author: Richard Sandiford Date: Wed Mar 5 08:25:55 2025 + Fix folding of BIT_NOT_EXPR for POLY_INT_CST [PR118976] There was an embarrassing typo in the folding of BIT_NOT_EXPR for POLY_INT_CSTs: it used - rather than ~ on the poly_int. Not sure how that happened, but it might have been due to the way that ~x is implemented as -1 - x internally. gcc/ PR tree-optimization/118976 * fold-const.cc (const_unop): Use ~ rather than - for BIT_NOT_EXPR. * config/aarch64/aarch64.cc (aarch64_test_sve_folding): New function. (aarch64_run_selftests): Run it. (cherry picked from commit 78380fd7f743e23dfdf013d68a2f0347e1511550) Diff: --- gcc/config/aarch64/aarch64.cc | 11 +++ gcc/fold-const.cc | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index a18355e8c96b..0a98f005b71c 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -27639,6 +27639,16 @@ aarch64_test_fractional_cost () ASSERT_EQ (cf (1, 2).as_double (), 0.5); } +/* Test SVE arithmetic folding. */ + +static void +aarch64_test_sve_folding () +{ + tree res = fold_unary (BIT_NOT_EXPR, ssizetype, +ssize_int (poly_int64 (1, 1))); + ASSERT_TRUE (operand_equal_p (res, ssize_int (poly_int64 (-2, -1; +} + /* Run all target-specific selftests. */ static void @@ -27646,6 +27656,7 @@ aarch64_run_selftests (void) { aarch64_test_loading_full_dump (); aarch64_test_fractional_cost (); + aarch64_test_sve_folding (); } } // namespace selftest diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 8215cbef991f..b5a83f6c5f31 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -1828,7 +1828,7 @@ const_unop (enum tree_code code, tree type, tree arg0) if (TREE_CODE (arg0) == INTEGER_CST) return fold_not_const (arg0, type); else if (POLY_INT_CST_P (arg0)) - return wide_int_to_tree (type, -poly_int_cst_value (arg0)); + return wide_int_to_tree (type, ~poly_int_cst_value (arg0)); /* Perform BIT_NOT_EXPR on each element individually. */ else if (TREE_CODE (arg0) == VECTOR_CST) {
[gcc r15-7826] Fortran: Add view convert to pointer assign when only pointer/alloc attr differs [PR104684]
https://gcc.gnu.org/g:705ae582d519f1230de3ec0d75a75e72341a674e commit r15-7826-g705ae582d519f1230de3ec0d75a75e72341a674e Author: Andre Vehreschild Date: Tue Mar 4 17:06:31 2025 +0100 Fortran: Add view convert to pointer assign when only pointer/alloc attr differs [PR104684] PR fortran/104684 gcc/fortran/ChangeLog: * trans-array.cc (gfc_conv_expr_descriptor): Look at the lang-specific akind and do a view convert when only the akind attribute differs between pointer and allocatable array. gcc/testsuite/ChangeLog: * gfortran.dg/coarray/ptr_comp_6.f08: New test. Diff: --- gcc/fortran/trans-array.cc | 10 +- gcc/testsuite/gfortran.dg/coarray/ptr_comp_6.f08 | 25 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 6a00d26cb2f3..925030465ac3 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -8186,8 +8186,16 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) { if (se->direct_byref && !se->byref_noassign) { + struct lang_type *lhs_ls + = TYPE_LANG_SPECIFIC (TREE_TYPE (se->expr)), + *rhs_ls = TYPE_LANG_SPECIFIC (TREE_TYPE (desc)); + /* When only the array_kind differs, do a view_convert. */ + tmp = lhs_ls && rhs_ls && lhs_ls->rank == rhs_ls->rank + && lhs_ls->akind != rhs_ls->akind + ? build1 (VIEW_CONVERT_EXPR, TREE_TYPE (se->expr), desc) + : desc; /* Copy the descriptor for pointer assignments. */ - gfc_add_modify (&se->pre, se->expr, desc); + gfc_add_modify (&se->pre, se->expr, tmp); /* Add any offsets from subreferences. */ gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE, diff --git a/gcc/testsuite/gfortran.dg/coarray/ptr_comp_6.f08 b/gcc/testsuite/gfortran.dg/coarray/ptr_comp_6.f08 new file mode 100644 index ..397a09bc8bc2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray/ptr_comp_6.f08 @@ -0,0 +1,25 @@ +!{ dg-do run } +! +! Contributed by Arseny Solokha + +program pr104684 + type :: index_map +integer, allocatable :: send_index(:) + end type + type(index_map) :: imap + + imap%send_index = [5,4,3] + call sub(imap) +contains + subroutine sub(this) +type(index_map), intent(inout), target :: this +type :: box + integer, pointer :: array(:) +end type +type(box), allocatable :: buffer[:] +allocate(buffer[*]) +buffer%array => this%send_index +if (any(buffer%array /= [5,4,3])) stop 1 + end subroutine +end program +
[gcc r15-7827] libstdc++: implement constexpr memory algorithms
https://gcc.gnu.org/g:3052b336455e19a773b06e1eaa681917b3d93169 commit r15-7827-g3052b336455e19a773b06e1eaa681917b3d93169 Author: Giuseppe D'Angelo Date: Sun Feb 16 19:37:07 2025 +0100 libstdc++: implement constexpr memory algorithms This commit adds support for C++26's constexpr specialized memory algorithms, introduced by P2283R2, P3508R0, P3369R0. The uninitialized_default, value, copy, move and fill algorithms are affected, in all of their variants (iterator-based, range-based and _n versions.) The changes are mostly mechanical -- add `constexpr` to a number of signatures when compiling in C++26 and above modes. The internal helper guard class for range algorithms instead can be marked unconditionally. uninitialized_default_construct is implemented in terms of the _Construct_novalue helper, which requires support for C++26's constexpr placement new from the compiler (P2747R2, which GCC implements). We can simply mark it as constexpr in C++26 language modes, even if the compiler does not support P2747R2 (e.g. Clang 17/18), because C++23's P2448R2 makes it OK to mark functions as constexpr even if they never qualify, and other compilers implement this. The only "real" change to the implementation of the algorithms is that during constant evaluation I need to dispatch to a constexpr-friendly version of them. For each algorithm family I've added only one test to cover it and its variants; the idea is to avoid too much repetition and simplify future maintenance. libstdc++-v3/ChangeLog: * include/bits/ranges_uninitialized.h: Mark the specialized memory algorithms as constexpr in C++26. Also mark the members of the _DestroyGuard helper class. * include/bits/stl_uninitialized.h: Ditto. * include/bits/stl_construct.h: (_Construct_novalue) Mark it as constexpr in C++26. * include/bits/version.def (raw_memory_algorithms): Bump the feature-testing macro for C++26. * include/bits/version.h: Regenerate. * testsuite/20_util/headers/memory/synopsis.cc: Add constexpr to the uninitialized_* algorithms (when in C++26) in the test. * testsuite/20_util/specialized_algorithms/feature_test_macro.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_copy/constexpr.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constexpr.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_fill/constexpr.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_move/constexpr.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constexpr.cc: New test. Reviewed-by: Patrick Palka Diff: --- libstdc++-v3/include/bits/ranges_uninitialized.h | 21 +++ libstdc++-v3/include/bits/stl_construct.h | 1 + libstdc++-v3/include/bits/stl_uninitialized.h | 39 + libstdc++-v3/include/bits/version.def | 5 ++ libstdc++-v3/include/bits/version.h| 7 ++- .../testsuite/20_util/headers/memory/synopsis.cc | 12 .../specialized_algorithms/feature_test_macro.cc | 14 + .../uninitialized_copy/constexpr.cc| 58 ++ .../uninitialized_default_construct/constexpr.cc | 67 + .../uninitialized_fill/constexpr.cc| 68 ++ .../uninitialized_move/constexpr.cc| 51 .../uninitialized_value_construct/constexpr.cc | 64 12 files changed, 406 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h index ced7bda5e37c..990929efaa9b 100644 --- a/libstdc++-v3/include/bits/ranges_uninitialized.h +++ b/libstdc++-v3/include/bits/ranges_uninitialized.h @@ -105,15 +105,18 @@ namespace ranges const _Iter* _M_cur; public: + constexpr explicit _DestroyGuard(const _Iter& __iter) : _M_first(__iter), _M_cur(std::__addressof(__iter)) { } + constexpr void release() noexcept { _M_cur = nullptr; } + constexpr ~_DestroyGuard() { if (_M_cur != nullptr) @@ -126,10 +129,12 @@ namespace ranges && is_trivially_destructible_v> struct _DestroyGuard<_Iter> { + constexpr explicit _DestroyGuard(const _Iter&) { } + constexpr void release() noexcept { } @@ -141,6 +146,7 @@ namespace ranges template<__detail::__nothrow_forward_iterator _Iter, __det
[gcc r15-7823] c++: Fix a comment typo
https://gcc.gnu.org/g:b85b405ed333a428a51b68cb914a48ac31bf0203 commit r15-7823-gb85b405ed333a428a51b68cb914a48ac31bf0203 Author: Jakub Jelinek Date: Wed Mar 5 06:42:48 2025 +0100 c++: Fix a comment typo During the 118874 coro investigation I found a typo in a comment. Fixed thusly. 2025-03-05 Jakub Jelinek * typeck.cc (check_return_expr): Fix comment typo, rom -> from. Diff: --- gcc/cp/typeck.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index bbaca960bd7c..fe8aceddffa1 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -11450,7 +11450,7 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling) bool converted = false; tree moved; /* Until C++23, this was only interesting for class type, but in C++23, -we should do the below when we're converting rom/to a class/reference +we should do the below when we're converting from/to a class/reference (a non-scalar type). */ if ((cxx_dialect < cxx23 ? CLASS_TYPE_P (functype)
[gcc r14-11386] aarch64: Check for invalid use arrays in ldp_fusion [PR118320]
https://gcc.gnu.org/g:1a4f1e5f91a69434f2ec0d95c91bad2c928dcff3 commit r14-11386-g1a4f1e5f91a69434f2ec0d95c91bad2c928dcff3 Author: Richard Sandiford Date: Wed Mar 5 12:18:20 2025 + aarch64: Check for invalid use arrays in ldp_fusion [PR118320] As Andrew says in the bugzilla comments, this PR is about a case where we tried to fuse two stores of x0, one in which x0 was defined and one in which it was undefined. merge_access_arrays failed on the conflict, but the failure wasn't caught. Normally the hazard detection code would fail if the instructions had incompatible uses. However, an undefined use doesn't impose many restrictions on movements. I think this is likely to be the only case where hazard detection isn't enough. As Andrew notes in bugzilla, it might be possible to allow uses of defined and undefined values to be merged to the defined value. But that sounds dangerous in the general case, as an rtl-ssa-level decision. We might run the risk of turning conditional UB into unconditional UB. And LLVM proves that the definition of "undef" isn't simple. This is a backport of r15-7282-gf559ac896942ffe0e2315d0a4d8b8b517a16d607. gcc/ PR rtl-optimization/118320 * config/aarch64/aarch64-ldp-fusion.cc (ldp_bb_info::fuse_pair): Commonize the merge of input_uses and return early if it fails. gcc/testsuite/ PR rtl-optimization/118320 * g++.dg/torture/pr118320.C: New test. Co-authored-by: Alex Coplan Diff: --- gcc/config/aarch64/aarch64-ldp-fusion.cc | 31 +-- gcc/testsuite/g++.dg/torture/pr118320.C | 15 +++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/gcc/config/aarch64/aarch64-ldp-fusion.cc b/gcc/config/aarch64/aarch64-ldp-fusion.cc index f32d30d54c5c..1791ca5563c5 100644 --- a/gcc/config/aarch64/aarch64-ldp-fusion.cc +++ b/gcc/config/aarch64/aarch64-ldp-fusion.cc @@ -1784,6 +1784,24 @@ ldp_bb_info::fuse_pair (bool load_p, input_uses[i] = remove_note_accesses (attempt, input_uses[i]); } + // Get the uses that the pair instruction would have, and punt if + // the unpaired instructions use different definitions of the same + // register. That would normally be caught as a side-effect of + // hazard detection below, but this check also deals with cases + // in which one use is undefined and the other isn't. + auto new_uses = merge_access_arrays (attempt, + drop_memory_access (input_uses[0]), + drop_memory_access (input_uses[1])); + if (!new_uses.is_valid ()) +{ + if (dump_file) + fprintf (dump_file, +" rejecting pair: i%d and i%d use different definiitions of" +" the same register\n", +insns[0]->uid (), insns[1]->uid ()); + return false; +} + // Edge case: if the first insn is a writeback load and the // second insn is a non-writeback load which transfers into the base // register, then we should drop the writeback altogether as the @@ -1911,10 +1929,7 @@ ldp_bb_info::fuse_pair (bool load_p, input_defs[1]); gcc_assert (pair_change->new_defs.is_valid ()); - pair_change->new_uses - = merge_access_arrays (attempt, - drop_memory_access (input_uses[0]), - drop_memory_access (input_uses[1])); + pair_change->new_uses = new_uses; gcc_assert (pair_change->new_uses.is_valid ()); set_pair_pat (pair_change); } @@ -1936,9 +1951,7 @@ ldp_bb_info::fuse_pair (bool load_p, case Action::CHANGE: { set_pair_pat (change); - change->new_uses = merge_access_arrays (attempt, - input_uses[0], - input_uses[1]); + change->new_uses = new_uses; auto d1 = drop_memory_access (input_defs[0]); auto d2 = drop_memory_access (input_defs[1]); change->new_defs = merge_access_arrays (attempt, d1, d2); @@ -1970,9 +1983,7 @@ ldp_bb_info::fuse_pair (bool load_p, auto new_insn = crtl->ssa->create_insn (attempt, INSN, pair_pat); change = make_change (new_insn); change->move_range = move_range; - change->new_uses = merge_access_arrays (attempt, - input_uses[0], - input_uses[1]); + change->new_uses = new_uses; gcc_assert (change->new_uses.is_valid ()); auto d1 = drop_memory_access (input_defs[0]); diff --git a/gcc/testsuite/g++.dg/torture/pr118320.C b/gcc/testsuite/g++.dg/tor
[gcc r15-7835] libstdc++: Some concat_view bugfixes [PR115215, PR115218, LWG 4082]
https://gcc.gnu.org/g:81c6c99efa6a7afd3082785a9ab7fb64d2c93e1d commit r15-7835-g81c6c99efa6a7afd3082785a9ab7fb64d2c93e1d Author: Patrick Palka Date: Wed Mar 5 11:11:35 2025 -0500 libstdc++: Some concat_view bugfixes [PR115215, PR115218, LWG 4082] - Use __builtin_unreachable to suppress a false-positive "control reaches end of non-void function" warning in the recursive lambda (which the existing tests failed to notice since test01 wasn't being called at runtime) - Relax the constraints on views::concat in the single-argument case as per PR115215 - Add an input_range requirement to that same case as per LWG 4082 - In the const-converting constructor of concat_view's iterator, don't require the first iterator to be default constructible PR libstdc++/115215 PR libstdc++/115218 libstdc++-v3/ChangeLog: * include/std/ranges (concat_view::iterator::_S_invoke_with_runtime_index): Use __builtin_unreachable in recursive lambda to certify it always exits via 'return'. (concat_view::iterator::iterator): In the const-converting constructor, direct initialize _M_it. (views::_Concat::operator()): Adjust constraints in the single-argument case as per LWG 4082. * testsuite/std/ranges/concat/1.cc (test01): Call it at runtime too. (test04): New test. Reviewed-by: Tomasz Kamiński Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/std/ranges | 25 + libstdc++-v3/testsuite/std/ranges/concat/1.cc | 16 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index c0b1134ab328..def7527431cd 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -9922,6 +9922,7 @@ namespace ranges return __f.template operator()<_Idx>(); if constexpr (_Idx + 1 < sizeof...(_Vs)) return __self.template operator()<_Idx + 1>(); + __builtin_unreachable(); }.template operator()<0>(); } @@ -9943,12 +9944,12 @@ namespace ranges constexpr _Iterator(_Iterator __it) requires _Const && (convertible_to, iterator_t> && ...) -: _M_parent(__it._M_parent) -{ - _M_invoke_with_runtime_index([this, &__it]() { - _M_it.template emplace<_Idx>(std::get<_Idx>(std::move(__it._M_it))); - }); -} +: _M_parent(__it._M_parent), + _M_it(_S_invoke_with_runtime_index([this, &__it]() { + return __base_iter(in_place_index<_Idx>, +std::get<_Idx>(std::move(__it._M_it))); + }, __it._M_it.index())) +{ } constexpr decltype(auto) operator*() const @@ -10186,12 +10187,12 @@ namespace ranges requires __detail::__can_concat_view<_Ts...> constexpr auto operator() [[nodiscard]] (_Ts&&... __ts) const - { - if constexpr (sizeof...(_Ts) == 1) - return views::all(std::forward<_Ts>(__ts)...); - else - return concat_view(std::forward<_Ts>(__ts)...); - } + { return concat_view(std::forward<_Ts>(__ts)...); } + + template + constexpr auto + operator() [[nodiscard]] (_Range&& __t) const + { return views::all(std::forward<_Range>(__t)); } }; inline constexpr _Concat concat; diff --git a/libstdc++-v3/testsuite/std/ranges/concat/1.cc b/libstdc++-v3/testsuite/std/ranges/concat/1.cc index e5d10f476e93..16721912a37d 100644 --- a/libstdc++-v3/testsuite/std/ranges/concat/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/concat/1.cc @@ -85,10 +85,26 @@ test03() VERIFY( ranges::equal(view2, std::vector{4, 5, 6, 1, 2, 3}) ); } +void +test04() +{ + // PR libstdc++/115215 - views::concat rejects non-movable reference + int x[] = {1,2,3}; + struct nomove { +nomove() = default; +nomove(const nomove&) = delete; + }; + auto v = x | views::transform([](int) { return nomove{}; }); + using type = decltype(views::concat(v)); + using type = decltype(v); +} + int main() { static_assert(test01()); + test01(); test02(); test03(); + test04(); }
[gcc r15-7834] c++: Check invalid use of constrained auto with trailing return type [PR100589]
https://gcc.gnu.org/g:7439febd94368f42bc46885224e22d2f135fedb2 commit r15-7834-g7439febd94368f42bc46885224e22d2f135fedb2 Author: Da Xie Date: Sun Mar 2 14:45:11 2025 +0800 c++: Check invalid use of constrained auto with trailing return type [PR100589] Add check for constrained auto type specifier in function declaration or function type declaration with trailing return type. Issue error if such usage is detected. Test file renamed, and added a new test for type declaration. Successfully bootstrapped and regretested on x86_64-pc-linux-gnu: Added 6 passed and 4 unsupported tests. PR c++/100589 gcc/cp/ChangeLog: * decl.cc (grokdeclarator): Issue an error for a declarator with constrained auto type specifier and trailing return types. Include function names if available. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-pr100589.C: New test. Signed-off-by: Da Xie Reviewed-by: Patrick Palka Reviewed-by: Jason Merrill Diff: --- gcc/cp/decl.cc | 13 + gcc/testsuite/g++.dg/cpp2a/concepts-pr100589.C | 9 + 2 files changed, 22 insertions(+) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 9ca8c6c44816..337ee65752e4 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -14037,6 +14037,19 @@ grokdeclarator (const cp_declarator *declarator, "invalid use of %"); return error_mark_node; } + else if (is_constrained_auto (type)) + { + if (funcdecl_p) + error_at (typespec_loc, + "%qs function with trailing return type " + "has constrained % type specifier " + "rather than plain %", + name); + else + error_at (typespec_loc, + "invalid use of constrained % type"); + return error_mark_node; + } tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node); if (!tmpl) if (tree late_auto = type_uses_auto (late_return_type)) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr100589.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr100589.C new file mode 100644 index ..918ba50ac707 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr100589.C @@ -0,0 +1,9 @@ +// PR c++/100589 +// { dg-do compile { target c++20 } } + +template +concept false_concept = false; + +false_concept auto f() -> int; // { dg-error "'f' \[^\r\n\]* trailing return type has constrained 'auto'" } + +using type = false_concept auto() -> int; // { dg-error "invalid use of constrained 'auto' type" }
[gcc r15-7836] arm: Fix signedness of vld1q intrinsic parms [PR118942]
https://gcc.gnu.org/g:4d0a333ef13e2da140cd44c4941b20f48a80dc0f commit r15-7836-g4d0a333ef13e2da140cd44c4941b20f48a80dc0f Author: Hannes Braun Date: Thu Feb 20 15:09:41 2025 +0100 arm: Fix signedness of vld1q intrinsic parms [PR118942] vld1q_s8_x3, vld1q_s16_x3, vld1q_s8_x4 and vld1q_s16_x4 were expecting pointers to unsigned integers. These parameters should be pointers to signed integers. gcc/ChangeLog: PR target/118942 * config/arm/arm_neon.h (vld1q_s8_x3): Use int8_t instead of uint16_t. (vld1q_s16_x3): Use int16_t instead of uint16_t. (vld1q_s8_x4): Likewise. (vld1q_s16_x4): Likewise. gcc/testsuite/ChangeLog: PR target/118942 * gcc.target/arm/simd/vld1q_base_xN_1.c: Add -Wpointer-sign. Signed-off-by: Hannes Braun Diff: --- gcc/config/arm/arm_neon.h | 8 gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h index 5b1c55c8d9f8..578ada88fa69 100644 --- a/gcc/config/arm/arm_neon.h +++ b/gcc/config/arm/arm_neon.h @@ -10854,7 +10854,7 @@ vld1q_s64_x2 (const int64_t * __a) __extension__ extern __inline int8x16x3_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s8_x3 (const uint8_t * __a) +vld1q_s8_x3 (const int8_t * __a) { union { int8x16x3_t __i; __builtin_neon_ci __o; } __rv; __rv.__o = __builtin_neon_vld1q_x3v16qi ((const __builtin_neon_qi *) __a); @@ -10863,7 +10863,7 @@ vld1q_s8_x3 (const uint8_t * __a) __extension__ extern __inline int16x8x3_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s16_x3 (const uint16_t * __a) +vld1q_s16_x3 (const int16_t * __a) { union { int16x8x3_t __i; __builtin_neon_ci __o; } __rv; __rv.__o = __builtin_neon_vld1q_x3v8hi ((const __builtin_neon_hi *) __a); @@ -10890,7 +10890,7 @@ vld1q_s64_x3 (const int64_t * __a) __extension__ extern __inline int8x16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s8_x4 (const uint8_t * __a) +vld1q_s8_x4 (const int8_t * __a) { union { int8x16x4_t __i; __builtin_neon_xi __o; } __rv; __rv.__o = __builtin_neon_vld1q_x4v16qi ((const __builtin_neon_qi *) __a); @@ -10899,7 +10899,7 @@ vld1q_s8_x4 (const uint8_t * __a) __extension__ extern __inline int16x8x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s16_x4 (const uint16_t * __a) +vld1q_s16_x4 (const int16_t * __a) { union { int16x8x4_t __i; __builtin_neon_xi __o; } __rv; __rv.__o = __builtin_neon_vld1q_x4v8hi ((const __builtin_neon_hi *) __a); diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c index 01b29b600847..c73afe2b723b 100644 --- a/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c +++ b/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c @@ -1,6 +1,6 @@ /* { dg-do assemble } */ /* { dg-require-effective-target arm_neon_ok } */ -/* { dg-options "-save-temps -O2" } */ +/* { dg-options "-save-temps -O2 -Wpointer-sign" } */ /* { dg-add-options arm_neon } */ #include "arm_neon.h"
[gcc r15-7837] c++: coroutines and return in registers [PR118874]
https://gcc.gnu.org/g:7e576d5b64ae92432fc2749b8f66105cee8db356 commit r15-7837-g7e576d5b64ae92432fc2749b8f66105cee8db356 Author: Jason Merrill Date: Wed Mar 5 08:45:34 2025 -0500 c++: coroutines and return in registers [PR118874] Because coroutines insert a call to the resumer between the initialization of the return value and the actual return to the caller, we need to duplicate the work of gimplify_return_expr for the !aggregate_value_p case. PR c++/117364 PR c++/118874 gcc/cp/ChangeLog: * coroutines.cc (cp_coroutine_transform::build_ramp_function): For !aggregate_value_p return force return value into a local temp. gcc/testsuite/ChangeLog: * g++.dg/coroutines/torture/pr118874.C: New test. Co-authored-by: Jakub Jelinek Diff: --- gcc/cp/coroutines.cc | 18 +++- gcc/testsuite/g++.dg/coroutines/torture/pr118874.C | 33 ++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index d3c7ff3bd72d..b92d09fa4ead 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -5161,6 +5161,7 @@ cp_coroutine_transform::build_ramp_function () /* Used for return objects in the RESULT slot. */ tree ret_val_dtor = NULL_TREE; + tree retval = NULL_TREE; /* [dcl.fct.def.coroutine] / 7 The expression promise.get_return_object() is used to initialize the @@ -5189,6 +5190,21 @@ cp_coroutine_transform::build_ramp_function () /* Check for bad things. */ if (!r || r == error_mark_node) return false; + if (!aggregate_value_p (fn_return_type, orig_fn_decl) + && TREE_CODE (r) == INIT_EXPR) + { + /* If fn_return_type doesn't need to be returned in memory, normally +gimplify_return_expr redirects the INIT_EXPR to a temporary. But +r isn't wrapped in the RETURN_EXPR, so we need to do the +redirection here as well. See PR118874. */ + tree temp = create_temporary_var (fn_return_type); + add_decl_expr (temp); + retval = copy_node (r); + TREE_OPERAND (r, 0) = temp; + TREE_OPERAND (retval, 1) = temp; + } + else + retval = DECL_RESULT (orig_fn_decl); } finish_expr_stmt (r); @@ -5215,7 +5231,7 @@ cp_coroutine_transform::build_ramp_function () /* The ramp is done, we just need the return statement, which we build from the return object we constructed before we called the actor. */ - r = void_ramp_p ? NULL_TREE : DECL_RESULT (orig_fn_decl); + r = retval; /* The reminder of finish_return_expr (). */ r = build_stmt (loc, RETURN_EXPR, r); diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr118874.C b/gcc/testsuite/g++.dg/coroutines/torture/pr118874.C new file mode 100644 index ..925d56ae2ea2 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr118874.C @@ -0,0 +1,33 @@ +// PR c++/118874 +// { dg-do compile } +// { dg-additional-options "-std=c++20" } + +#include + +struct B { + bool await_ready () const noexcept; + void await_suspend (std::coroutine_handle<> h) const noexcept; + void await_resume () const noexcept; +}; + +struct C { + struct promise_type { +const char *value; +std::suspend_never initial_suspend (); +std::suspend_always final_suspend () noexcept; +void return_value (const char *v); +void unhandled_exception (); +C get_return_object () { return C{this}; } + }; + promise_type *p; + explicit C (promise_type *p) : p(p) {} + const char *get (); +}; + +C +bar (bool x) +{ + if (x) +co_await B{}; + co_return "foobar"; +}
[gcc r15-7838] libstdc++: use if consteval in stable_sort
https://gcc.gnu.org/g:24ea4539300d4926d9f073822e68f0d2f369452d commit r15-7838-g24ea4539300d4926d9f073822e68f0d2f369452d Author: Giuseppe D'Angelo Date: Wed Mar 5 14:34:41 2025 +0100 libstdc++: use if consteval in stable_sort This is a C++ >= 26 codepath for supporting constexpr stable_sort, so we know that we have if consteval available; it just needs protection with the feature-testing macro. Also merge the return in the same statement. Amends r15-7708-gff43f9853d3b10. libstdc++-v3/ChangeLog: * include/bits/stl_algo.h (__stable_sort): Use if consteval instead of is_constant_evaluated. Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/bits/stl_algo.h | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 41b4d0853b71..c3fea76014cb 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -4987,11 +4987,11 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return; #if _GLIBCXX_HOSTED - if (__is_constant_evaluated()) - { - std::__inplace_stable_sort(__first, __last, __comp); - return; - } +# if __glibcxx_constexpr_algorithms >= 202306L // >= C++26 + if consteval { + return std::__inplace_stable_sort(__first, __last, __comp); + } +# endif typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf; // __stable_sort_adaptive sorts the range in two halves,
[gcc r15-7831] value-range: Fix up irange::union_bitmask [PR118953]
https://gcc.gnu.org/g:54da358ff51ded726fe7c026fa59c8db0a1b72ed commit r15-7831-g54da358ff51ded726fe7c026fa59c8db0a1b72ed Author: Jakub Jelinek Date: Wed Mar 5 14:30:35 2025 +0100 value-range: Fix up irange::union_bitmask [PR118953] The following testcase is miscompiled during evrp. Before vrp, we have (from ccp): # RANGE [irange] long long unsigned int [0, +INF] MASK 0xc000 VALUE 0x2d _3 = _2 + 18446744073708503085; ... # RANGE [irange] long long unsigned int [0, +INF] MASK 0xc000 VALUE 0x59 _6 = (long long unsigned int) _5; # RANGE [irange] int [-INF, +INF] MASK 0xc000 VALUE 0x34 _7 = k_11 + -1048524; switch (_7) [33.33%], case 8: [33.33%], case 24: [33.33%], case 32: [33.33%]> ... # RANGE [irange] long long unsigned int [0, +INF] MASK 0xc07d VALUE 0x0 # i_20 = PHI <_3(4), 0(3), _6(2)> and evrp is now trying to figure out range for i_20 in range_of_phi. All the ranges and MASK/VALUE pairs above are correct for the testcase, k_11 and _2 based on it is a result of multiplication by a constant with low 14 bits cleared and then some numbers are added to it. There is an obvious missed optimization for which I've filed PR119039, simplify_switch_using_ranges could see that all the labels but default are unreachable because the controlling expression has MASK 0xc000 VALUE 0x34 and none of 8, 24 and 32 satisfy that. Anyway, during range_of_phi for i_20, we process the PHI arguments in order. For the _3(4) case, we figure out that it is reachable through the case 24: case 32: labels only of the switch and that 0x34 - 0x2d is 7, so derive [irange] long long unsigned int [17, 17][25, 25] MASK 0xc000 VALUE 0x2d (the MASK/VALUE just got inherited from the _3 earlier range). Now (not suprisingly because those labels aren't actually reachable), that range is inconsistent, 0x2d is 45, so there is conflict between the values and the irange_bitmask. value-range.{h,cc} code differentiates between actually stored irange_bitmask, which is that MASK 0xc000 VALUE 0x2d, and semantic bitmask, which is what get_bitmask returns. That is // The mask inherent in the range is calculated on-demand. For // example, [0,255] does not have known bits set by default. This // saves us considerable time, because setting it at creation incurs // a large penalty for irange::set. At the time of writing there // was a 5% slowdown in VRP if we kept the mask precisely up to date // at all times. Instead, we default to -1 and set it when // explicitly requested. However, this function will always return // the correct mask. // // This also means that the mask may have a finer granularity than // the range and thus contradict it. Think of the mask as an // enhancement to the range. For example: // // [3, 1000] MASK 0xfffe VALUE 0x0 // // 3 is in the range endpoints, but is excluded per the known 0 bits // in the mask. // // See also the note in irange_bitmask::intersect. irange_bitmask bm = get_bitmask_from_range (type (), lower_bound (), upper_bound ()); if (!m_bitmask.unknown_p ()) bm.intersect (m_bitmask); Now, get_bitmask_from_range here is MASK 0x1f VALUE 0x0 and it intersects that with that MASK 0xc000 VALUE 0x2d. Which triggers the ugly special case in irange_bitmask::intersect: // If we have two known bits that are incompatible, the resulting // bit is undefined. It is unclear whether we should set the entire // range to UNDEFINED, or just a subset of it. For now, set the // entire bitmask to unknown (VARYING). if (wi::bit_and (~(m_mask | src.m_mask), m_value ^ src.m_value) != 0) { unsigned prec = m_mask.get_precision (); m_mask = wi::minus_one (prec); m_value = wi::zero (prec); } so the semantic bitmask is actually MASK 0x VALUE 0x0. Next, range_of_phi attempts to union it with the 0(3) PHI argument, and during irange::union_ first adds the [0,0] to the subranges, so [irange] long long unsigned int [0, 0][17, 17][25, 25] MASK 0xc000 VALUE 0x2d and then goes on to irange::union_bitmask which does if (m_bitmask == r.m_bitmask) return false; irange_bitmask bm = get_bitmask (); irange_bitmask save = bm; bm.union_ (r.get_bitmask ()); if (save == bm) return false; m_bitmask = bm; if (save == get_bitmask ()) return false; m_bitmask MASK 0xc000 VALUE 0x2d isn't the same as r.m_bitmask MASK 0x0 VALUE 0x0, so we compute the semantic bitmask (but note, not from the original range before
[gcc r14-11384] libstdc++: Fix subrange conversion to pair-like [PR119121]
https://gcc.gnu.org/g:750d691077d96879068312dd4b25a51c1d6958c5 commit r14-11384-g750d691077d96879068312dd4b25a51c1d6958c5 Author: Tomasz Kamiński Date: Wed Mar 5 11:11:55 2025 +0100 libstdc++: Fix subrange conversion to pair-like [PR119121] Fix regression introduced by r14-8710-g65b4cba9d6a9ff PR libstdc++/119121 libstdc++-v3/ChangeLog: * include/bits/ranges_util.h (__detail::__pair_like_convertible_from): Use `_Tp` in `is_reference_v` check * testsuite/std/ranges/subrange/tuple_like.cc: New tests for pair-like conversion Reviewed-by: Jonathan Wakely (cherry picked from commit 95b2f8d8fb3131165b1b38645dacf10a5dd2bc15) Diff: --- libstdc++-v3/include/bits/ranges_util.h| 2 +- .../testsuite/std/ranges/subrange/tuple_like.cc| 29 ++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index aba5b6a88c0c..c2a87a233415 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -243,7 +243,7 @@ namespace ranges template concept __pair_like_convertible_from - = !range<_Tp> && !is_reference_v<_Vp> && __pair_like<_Tp> + = !range<_Tp> && !is_reference_v<_Tp> && __pair_like<_Tp> && constructible_from<_Tp, _Up, _Vp> && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>> && convertible_to<_Vp, tuple_element_t<1, _Tp>>; diff --git a/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc index a02475b1157e..71f9535106d7 100644 --- a/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc +++ b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc @@ -18,6 +18,8 @@ // { dg-do compile { target c++20 } } #include +#include +#include using S1 = std::ranges::subrange; using S2 = std::ranges::subrange; @@ -49,3 +51,30 @@ static_assert( std::same_as(s2)), void*> ); const S2 c2; static_assert( std::same_as(c2)), long*> ); static_assert( std::same_as(c2)), void*> ); + +std::pair p1 = s1; +std::pair p2 = s2; +std::tuple t1 = s1; +std::tuple t2 = s2; + +std::pair const& p3 = s1; +std::tuple&& t3 = s1; + +std::pair p4 = s1; +std::tuple t4 = s1; + +static_assert( !std::convertible_to, std::pair> ); +static_assert( !std::convertible_to, std::tuple> ); + +static_assert( !std::convertible_to, std::pair> ); +static_assert( !std::convertible_to, std::tuple> ); + +struct B {}; +struct D : B {}; + +std::ranges::subrange sd; +std::pair p5 = sd; +std::tuple t5 = sd; + +static_assert( !std::convertible_to, std::pair> ); +static_assert( !std::convertible_to, std::tuple> );
[gcc r13-9414] testsuite: Add tests for already fixed PR [PR119071]
https://gcc.gnu.org/g:5ab16e594f29f2c1b4f4b54b2174de171be6c2a6 commit r13-9414-g5ab16e594f29f2c1b4f4b54b2174de171be6c2a6 Author: Jakub Jelinek Date: Tue Mar 4 09:52:22 2025 +0100 testsuite: Add tests for already fixed PR [PR119071] Uros' r15-7793 fixed this PR as well, I'm just committing tests from the PR so that it can be closed. 2025-03-04 Jakub Jelinek PR rtl-optimization/119071 * gcc.dg/pr119071.c: New test. * gcc.c-torture/execute/pr119071.c: New test. (cherry picked from commit ccf9db9a6fa4b5bc7aad5e9603e2ac71984142a0) Diff: --- gcc/testsuite/gcc.c-torture/execute/pr119071.c | 15 + gcc/testsuite/gcc.dg/pr119071.c| 45 ++ 2 files changed, 60 insertions(+) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr119071.c b/gcc/testsuite/gcc.c-torture/execute/pr119071.c new file mode 100644 index ..91f29cce3d55 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr119071.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/119071 */ + +int a, b; + +int +main () +{ + int c = 0; + if (a + 2) +c = 1; + int d = (1 + c - 2 + c == 1) - 1; + b = ((d + 1) << d) + d; + if (b != 1) +__builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/pr119071.c b/gcc/testsuite/gcc.dg/pr119071.c new file mode 100644 index ..ade1d288d2ae --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119071.c @@ -0,0 +1,45 @@ +/* PR rtl-optimization/119071 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fgimple" } */ + +int a, b; + +int __GIMPLE (ssa,startwith("expand")) +foo (void) +{ + int _1; + int _2; + int _3; + int _5; + _Bool _7; + int _8; + int _9; + _Bool _14; + int _15; + int _16; + _Bool _17; + int _18; + + __BB(2): + _1 = a; + _17 = _1 != _Literal (int) -2; + _18 = (int) _17; + _2 = _18 + _Literal (int) -1; + _3 = _2 + _18; + _14 = _3 != 1; + _15 = (int) _14; + _16 = -_15; + _7 = _3 == 1; + _9 = (int) _7; + _5 = _9 << _16; + _8 = _5 - _15; + b = _8; + return _8; +} + +int +main () +{ + if (foo () != 1) +__builtin_abort (); +}
[gcc r12-10976] combine: Discard REG_UNUSED note in i2 when register is also referenced in i3 [PR118739]
https://gcc.gnu.org/g:77172598dcb07b6ea71f4549917f2647eb34f38a commit r12-10976-g77172598dcb07b6ea71f4549917f2647eb34f38a Author: Uros Bizjak Date: Wed Feb 12 11:19:57 2025 +0100 combine: Discard REG_UNUSED note in i2 when register is also referenced in i3 [PR118739] The combine pass is trying to combine: Trying 16, 22, 21 -> 23: 16: r104:QI=flags:CCNO>0 22: {r120:QI=r104:QI^0x1;clobber flags:CC;} REG_UNUSED flags:CC 21: r119:QI=flags:CCNO<=0 REG_DEAD flags:CCNO 23: {r110:QI=r119:QI|r120:QI;clobber flags:CC;} REG_DEAD r120:QI REG_DEAD r119:QI REG_UNUSED flags:CC and creates the following two insn sequence: modifying insn i222: r104:QI=flags:CCNO>0 REG_DEAD flags:CC deferring rescan insn with uid = 22. modifying insn i323: r110:QI=flags:CCNO<=0 REG_DEAD flags:CC deferring rescan insn with uid = 23. where the REG_DEAD note in i2 is not correct, because the flags register is still referenced in i3. In try_combine() megafunction, we have this part: --cut here-- /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */ if (i3notes) distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, elim_i0); if (i2notes) distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, elim_i0); if (i1notes) distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL, elim_i2, local_elim_i1, local_elim_i0); if (i0notes) distribute_notes (i0notes, i0, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, local_elim_i0); if (midnotes) distribute_notes (midnotes, NULL, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, elim_i0); --cut here-- where the compiler distributes REG_UNUSED note from i2: 22: {r120:QI=r104:QI^0x1;clobber flags:CC;} REG_UNUSED flags:CC via distribute_notes() using the following: --cut here-- /* Otherwise, if this register is used by I3, then this register now dies here, so we must put a REG_DEAD note here unless there is one already. */ else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)) && ! (REG_P (XEXP (note, 0)) ? find_regno_note (i3, REG_DEAD, REGNO (XEXP (note, 0))) : find_reg_note (i3, REG_DEAD, XEXP (note, 0 { PUT_REG_NOTE_KIND (note, REG_DEAD); place = i3; } --cut here-- Flags register is used in I3, but there already is a REG_DEAD note in I3. The above condition doesn't trigger and continues in the "else" part where REG_DEAD note is put to I2. The proposed solution corrects the above logic to trigger every time the register is referenced in I3, avoiding the "else" part. PR rtl-optimization/118739 gcc/ChangeLog: * combine.cc (distribute_notes) : Correct the logic when the register is used by I3. gcc/testsuite/ChangeLog: * gcc.target/i386/pr118739.c: New test. (cherry picked from commit a92dc3fe31c95d56019b2fb95a58414bca06241f) Diff: --- gcc/combine.cc | 15 +- gcc/testsuite/gcc.target/i386/pr118739.c | 50 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/gcc/combine.cc b/gcc/combine.cc index e79500d40c9d..718da753b87c 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -14324,14 +14324,15 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2, /* Otherwise, if this register is used by I3, then this register now dies here, so we must put a REG_DEAD note here unless there is one already. */ - else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)) - && ! (REG_P (XEXP (note, 0)) -? find_regno_note (i3, REG_DEAD, - REGNO (XEXP (note, 0))) -: find_reg_note (i3, REG_DEAD, XEXP (note, 0 + else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))) { - PUT_REG_NOTE_KIND (note, REG_DEAD); - place = i3; + if (! (REG_P (XEXP (note, 0)) +? find_regno_note (i3, REG_DEAD, REGNO (XEXP (note, 0))) +: find_reg_note (i3, REG_DEAD, XEXP (note, 0 + { + PUT_REG_NOTE_KIND (note, REG_DEAD); + place = i3; + } }
[gcc r13-9413] combine: Discard REG_UNUSED note in i2 when register is also referenced in i3 [PR118739]
https://gcc.gnu.org/g:3634a7d15d94590cef313f503a32d4698276fd04 commit r13-9413-g3634a7d15d94590cef313f503a32d4698276fd04 Author: Uros Bizjak Date: Wed Feb 12 11:19:57 2025 +0100 combine: Discard REG_UNUSED note in i2 when register is also referenced in i3 [PR118739] The combine pass is trying to combine: Trying 16, 22, 21 -> 23: 16: r104:QI=flags:CCNO>0 22: {r120:QI=r104:QI^0x1;clobber flags:CC;} REG_UNUSED flags:CC 21: r119:QI=flags:CCNO<=0 REG_DEAD flags:CCNO 23: {r110:QI=r119:QI|r120:QI;clobber flags:CC;} REG_DEAD r120:QI REG_DEAD r119:QI REG_UNUSED flags:CC and creates the following two insn sequence: modifying insn i222: r104:QI=flags:CCNO>0 REG_DEAD flags:CC deferring rescan insn with uid = 22. modifying insn i323: r110:QI=flags:CCNO<=0 REG_DEAD flags:CC deferring rescan insn with uid = 23. where the REG_DEAD note in i2 is not correct, because the flags register is still referenced in i3. In try_combine() megafunction, we have this part: --cut here-- /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */ if (i3notes) distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, elim_i0); if (i2notes) distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, elim_i0); if (i1notes) distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL, elim_i2, local_elim_i1, local_elim_i0); if (i0notes) distribute_notes (i0notes, i0, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, local_elim_i0); if (midnotes) distribute_notes (midnotes, NULL, i3, newi2pat ? i2 : NULL, elim_i2, elim_i1, elim_i0); --cut here-- where the compiler distributes REG_UNUSED note from i2: 22: {r120:QI=r104:QI^0x1;clobber flags:CC;} REG_UNUSED flags:CC via distribute_notes() using the following: --cut here-- /* Otherwise, if this register is used by I3, then this register now dies here, so we must put a REG_DEAD note here unless there is one already. */ else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)) && ! (REG_P (XEXP (note, 0)) ? find_regno_note (i3, REG_DEAD, REGNO (XEXP (note, 0))) : find_reg_note (i3, REG_DEAD, XEXP (note, 0 { PUT_REG_NOTE_KIND (note, REG_DEAD); place = i3; } --cut here-- Flags register is used in I3, but there already is a REG_DEAD note in I3. The above condition doesn't trigger and continues in the "else" part where REG_DEAD note is put to I2. The proposed solution corrects the above logic to trigger every time the register is referenced in I3, avoiding the "else" part. PR rtl-optimization/118739 gcc/ChangeLog: * combine.cc (distribute_notes) : Correct the logic when the register is used by I3. gcc/testsuite/ChangeLog: * gcc.target/i386/pr118739.c: New test. (cherry picked from commit a92dc3fe31c95d56019b2fb95a58414bca06241f) Diff: --- gcc/combine.cc | 15 +- gcc/testsuite/gcc.target/i386/pr118739.c | 50 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/gcc/combine.cc b/gcc/combine.cc index 39d47f50f47e..4f9d01366f7c 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -14338,14 +14338,15 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2, /* Otherwise, if this register is used by I3, then this register now dies here, so we must put a REG_DEAD note here unless there is one already. */ - else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)) - && ! (REG_P (XEXP (note, 0)) -? find_regno_note (i3, REG_DEAD, - REGNO (XEXP (note, 0))) -: find_reg_note (i3, REG_DEAD, XEXP (note, 0 + else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))) { - PUT_REG_NOTE_KIND (note, REG_DEAD); - place = i3; + if (! (REG_P (XEXP (note, 0)) +? find_regno_note (i3, REG_DEAD, REGNO (XEXP (note, 0))) +: find_reg_note (i3, REG_DEAD, XEXP (note, 0 + { + PUT_REG_NOTE_KIND (note, REG_DEAD); + place = i3; + } }
[gcc r12-10977] testsuite: Add tests for already fixed PR [PR119071]
https://gcc.gnu.org/g:9496f5088111d9330bba2659b024f7e7a2175b4b commit r12-10977-g9496f5088111d9330bba2659b024f7e7a2175b4b Author: Jakub Jelinek Date: Tue Mar 4 09:52:22 2025 +0100 testsuite: Add tests for already fixed PR [PR119071] Uros' r15-7793 fixed this PR as well, I'm just committing tests from the PR so that it can be closed. 2025-03-04 Jakub Jelinek PR rtl-optimization/119071 * gcc.dg/pr119071.c: New test. * gcc.c-torture/execute/pr119071.c: New test. (cherry picked from commit ccf9db9a6fa4b5bc7aad5e9603e2ac71984142a0) Diff: --- gcc/testsuite/gcc.c-torture/execute/pr119071.c | 15 + gcc/testsuite/gcc.dg/pr119071.c| 45 ++ 2 files changed, 60 insertions(+) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr119071.c b/gcc/testsuite/gcc.c-torture/execute/pr119071.c new file mode 100644 index ..91f29cce3d55 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr119071.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/119071 */ + +int a, b; + +int +main () +{ + int c = 0; + if (a + 2) +c = 1; + int d = (1 + c - 2 + c == 1) - 1; + b = ((d + 1) << d) + d; + if (b != 1) +__builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/pr119071.c b/gcc/testsuite/gcc.dg/pr119071.c new file mode 100644 index ..ade1d288d2ae --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119071.c @@ -0,0 +1,45 @@ +/* PR rtl-optimization/119071 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fgimple" } */ + +int a, b; + +int __GIMPLE (ssa,startwith("expand")) +foo (void) +{ + int _1; + int _2; + int _3; + int _5; + _Bool _7; + int _8; + int _9; + _Bool _14; + int _15; + int _16; + _Bool _17; + int _18; + + __BB(2): + _1 = a; + _17 = _1 != _Literal (int) -2; + _18 = (int) _17; + _2 = _18 + _Literal (int) -1; + _3 = _2 + _18; + _14 = _3 != 1; + _15 = (int) _14; + _16 = -_15; + _7 = _3 == 1; + _9 = (int) _7; + _5 = _9 << _16; + _8 = _5 - _15; + b = _8; + return _8; +} + +int +main () +{ + if (foo () != 1) +__builtin_abort (); +}
[gcc r15-7833] PR rtl-optimization/119046: aarch64: Fix PARALLEL mode for vec_perm DUP expansion
https://gcc.gnu.org/g:ff505948631713d8c62523005059b10e25343617 commit r15-7833-gff505948631713d8c62523005059b10e25343617 Author: Kyrylo Tkachov Date: Wed Mar 5 03:03:52 2025 -0800 PR rtl-optimization/119046: aarch64: Fix PARALLEL mode for vec_perm DUP expansion The PARALLEL created in aarch64_evpc_dup is used to hold the lane number. It is not appropriate for it to have a vector mode. Other such uses use VOIDmode. Do this here as well. This avoids the risk of generic code treating the PARALLEL as trapping when it has floating-point mode. Bootstrapped and tested on aarch64-none-linux-gnu. Signed-off-by: Kyrylo Tkachov PR rtl-optimization/119046 * config/aarch64/aarch64.cc (aarch64_evpc_dup): Use VOIDmode for PARALLEL. Diff: --- gcc/config/aarch64/aarch64.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index af3871ce8a1f..9196b8d906c8 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -26301,7 +26301,7 @@ aarch64_evpc_dup (struct expand_vec_perm_d *d) in0 = d->op0; lane = GEN_INT (elt); /* The pattern corrects for big-endian. */ - rtx parallel = gen_rtx_PARALLEL (vmode, gen_rtvec (1, lane)); + rtx parallel = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, lane)); rtx select = gen_rtx_VEC_SELECT (GET_MODE_INNER (vmode), in0, parallel); emit_set_insn (out, gen_rtx_VEC_DUPLICATE (vmode, select)); return true;
[gcc r15-7828] MAINTAINERS: Add myself to write after approval
https://gcc.gnu.org/g:2653d988e92bc9d70a3ac674d1b819610858e00a commit r15-7828-g2653d988e92bc9d70a3ac674d1b819610858e00a Author: Tomasz Kamiński Date: Wed Mar 5 10:33:23 2025 +0100 MAINTAINERS: Add myself to write after approval ChangeLog: * MAINTAINERS: Add myself. Diff: --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 193cd802a078..84c0a6b892bb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -570,6 +570,7 @@ Teresa Johnson tejohnson Kean Johnston - Phillip Jordan pmj Tim Josling timjosling +Tomasz Kamiński tkaminsk Victor Kaplanskyvictork Evgeny Karpov - Filip Kastl pheeck
[gcc r15-7832] PR rtl-optimization/119046: Don't mark PARALLEL RTXes with floating-point mode as trapping
https://gcc.gnu.org/g:db76482175c4e76db273d7fb3a00ae0f932529a6 commit r15-7832-gdb76482175c4e76db273d7fb3a00ae0f932529a6 Author: Kyrylo Tkachov Date: Thu Feb 27 09:00:25 2025 -0800 PR rtl-optimization/119046: Don't mark PARALLEL RTXes with floating-point mode as trapping In this testcase late-combine was failing to merge: dup v31.4s, v31.s[3] fmlav30.4s, v31.4s, v29.4s into the lane-wise fmla form. This is because late-combine checks may_trap_p under the hood on the dup insn. This ended up returning true for the insn: (set (reg:V4SF 152 [ _32 ]) (vec_duplicate:V4SF (vec_select:SF (reg:V4SF 111 [ rhs_panel.8_31 ]) (parallel:V4SF [ (const_int 3 [0x3])] Although mem_trap_p correctly reasoned that vec_duplicate and vec_select of floating-point modes can't trap, it assumed that the V4SF parallel can trap. The correct behaviour is to recurse into vector inside the PARALLEL and check the sub-expression. This patch adjusts may_trap_p_1 to do just that. With this check the above insn is not deemed to be trapping and is propagated into the FMLA giving: fmlavD.4s, vA.4s, vB.s[3] Bootstrapped and tested on aarch64-none-linux-gnu. Apparently this also fixes a regression in gcc.target/aarch64/vmul_element_cost.c that I observed. Signed-off-by: Kyrylo Tkachov gcc/ PR rtl-optimization/119046 * rtlanal.cc (may_trap_p_1): Don't mark FP-mode PARALLELs as trapping. gcc/testsuite/ PR rtl-optimization/119046 * gcc.target/aarch64/pr119046.c: New test. Diff: --- gcc/rtlanal.cc | 1 + gcc/testsuite/gcc.target/aarch64/pr119046.c | 16 2 files changed, 17 insertions(+) diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc index 8caffafdaa44..7ad67afb9fe8 100644 --- a/gcc/rtlanal.cc +++ b/gcc/rtlanal.cc @@ -3252,6 +3252,7 @@ may_trap_p_1 (const_rtx x, unsigned flags) return true; break; +case PARALLEL: case NEG: case ABS: case SUBREG: diff --git a/gcc/testsuite/gcc.target/aarch64/pr119046.c b/gcc/testsuite/gcc.target/aarch64/pr119046.c new file mode 100644 index ..aa5fa7c848c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr119046.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O2" } */ + +#include + +float32x4_t madd_helper_1(float32x4_t a, float32x4_t b, float32x4_t d) +{ + float32x4_t t = a; + t = vfmaq_f32 (t, vdupq_n_f32(vgetq_lane_f32 (b, 1)), d); + t = vfmaq_f32 (t, vdupq_n_f32(vgetq_lane_f32 (b, 1)), d); + return t; +} + +/* { dg-final { scan-assembler-not {\tdup\tv[0-9]+\.4s, v[0-9]+.s\[1\]\n} } } */ +/* { dg-final { scan-assembler-times {\tfmla\tv[0-9]+\.4s, v[0-9]+\.4s, v[0-9]+\.s\[1\]\n} 2 } } */ +
[gcc r14-11385] arm: Fix signedness of vld1q intrinsic parms [PR118942]
https://gcc.gnu.org/g:6e17b356a78635e66d1a895b86fbcc0bde0589bb commit r14-11385-g6e17b356a78635e66d1a895b86fbcc0bde0589bb Author: Hannes Braun Date: Thu Feb 20 15:09:41 2025 +0100 arm: Fix signedness of vld1q intrinsic parms [PR118942] vld1q_s8_x3, vld1q_s16_x3, vld1q_s8_x4 and vld1q_s16_x4 were expecting pointers to unsigned integers. These parameters should be pointers to signed integers. gcc/ChangeLog: PR target/118942 * config/arm/arm_neon.h (vld1q_s8_x3): Use int8_t instead of uint16_t. (vld1q_s16_x3): Use int16_t instead of uint16_t. (vld1q_s8_x4): Likewise. (vld1q_s16_x4): Likewise. gcc/testsuite/ChangeLog: PR target/118942 * gcc.target/arm/simd/vld1q_base_xN_1.c: Add -Wpointer-sign. Signed-off-by: Hannes Braun (cherry picked from commit 4d0a333ef13e2da140cd44c4941b20f48a80dc0f) Diff: --- gcc/config/arm/arm_neon.h | 8 gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h index 8e70c7177315..11d2dc06877a 100644 --- a/gcc/config/arm/arm_neon.h +++ b/gcc/config/arm/arm_neon.h @@ -10854,7 +10854,7 @@ vld1q_s64_x2 (const int64_t * __a) __extension__ extern __inline int8x16x3_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s8_x3 (const uint8_t * __a) +vld1q_s8_x3 (const int8_t * __a) { union { int8x16x3_t __i; __builtin_neon_ci __o; } __rv; __rv.__o = __builtin_neon_vld1q_x3v16qi ((const __builtin_neon_qi *) __a); @@ -10863,7 +10863,7 @@ vld1q_s8_x3 (const uint8_t * __a) __extension__ extern __inline int16x8x3_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s16_x3 (const uint16_t * __a) +vld1q_s16_x3 (const int16_t * __a) { union { int16x8x3_t __i; __builtin_neon_ci __o; } __rv; __rv.__o = __builtin_neon_vld1q_x3v8hi ((const __builtin_neon_hi *) __a); @@ -10890,7 +10890,7 @@ vld1q_s64_x3 (const int64_t * __a) __extension__ extern __inline int8x16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s8_x4 (const uint8_t * __a) +vld1q_s8_x4 (const int8_t * __a) { union { int8x16x4_t __i; __builtin_neon_xi __o; } __rv; __rv.__o = __builtin_neon_vld1q_x4v16qi ((const __builtin_neon_qi *) __a); @@ -10899,7 +10899,7 @@ vld1q_s8_x4 (const uint8_t * __a) __extension__ extern __inline int16x8x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vld1q_s16_x4 (const uint16_t * __a) +vld1q_s16_x4 (const int16_t * __a) { union { int16x8x4_t __i; __builtin_neon_xi __o; } __rv; __rv.__o = __builtin_neon_vld1q_x4v8hi ((const __builtin_neon_hi *) __a); diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c index 01b29b600847..c73afe2b723b 100644 --- a/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c +++ b/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c @@ -1,6 +1,6 @@ /* { dg-do assemble } */ /* { dg-require-effective-target arm_neon_ok } */ -/* { dg-options "-save-temps -O2" } */ +/* { dg-options "-save-temps -O2 -Wpointer-sign" } */ /* { dg-add-options arm_neon } */ #include "arm_neon.h"
[gcc r15-7840] libstdc++: Implement P3138R5 views::cache_latest
https://gcc.gnu.org/g:410a4c126407c0ce048ad848d09cf4d39f578756 commit r15-7840-g410a4c126407c0ce048ad848d09cf4d39f578756 Author: Patrick Palka Date: Wed Mar 5 16:46:15 2025 -0500 libstdc++: Implement P3138R5 views::cache_latest libstdc++-v3/ChangeLog: * include/bits/version.def (ranges_cache_latest): Define. * include/bits/version.h: Regenerate. * include/std/ranges (__detail::__non_propagating_cache::_M_reset): Export from base class _Optional_base. (cache_latest_view): Define for C++26. (cache_latest_view::_Iterator): Likewise. (cache_latest_view::_Sentinel): Likewise. (views::__detail::__can_cache_latest): Likewise. (views::_CacheLatest, views::cache_latest): Likewise. * testsuite/std/ranges/adaptors/cache_latest/1.cc: New test. Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/bits/version.def | 8 + libstdc++-v3/include/bits/version.h| 10 ++ libstdc++-v3/include/std/ranges| 189 + .../std/ranges/adaptors/cache_latest/1.cc | 72 4 files changed, 279 insertions(+) diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 0cdc2e82fc55..eb2c6d8a3ee7 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -1846,6 +1846,14 @@ ftms = { }; }; +ftms = { + name = ranges_cache_latest; + values = { +v = 202411; +cxxmin = 26; + }; +}; + ftms = { name = ranges_concat; values = { diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index ec52cba517fa..05dadd6fd19c 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -2045,6 +2045,16 @@ #endif /* !defined(__cpp_lib_is_virtual_base_of) && defined(__glibcxx_want_is_virtual_base_of) */ #undef __glibcxx_want_is_virtual_base_of +#if !defined(__cpp_lib_ranges_cache_latest) +# if (__cplusplus > 202302L) +# define __glibcxx_ranges_cache_latest 202411L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges_cache_latest) +# define __cpp_lib_ranges_cache_latest 202411L +# endif +# endif +#endif /* !defined(__cpp_lib_ranges_cache_latest) && defined(__glibcxx_want_ranges_cache_latest) */ +#undef __glibcxx_want_ranges_cache_latest + #if !defined(__cpp_lib_ranges_concat) # if (__cplusplus > 202302L) && (__cpp_pack_indexing) # define __glibcxx_ranges_concat 202403L diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index def7527431cd..6790fcf7af19 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -57,6 +57,7 @@ #define __glibcxx_want_ranges #define __glibcxx_want_ranges_as_const #define __glibcxx_want_ranges_as_rvalue +#define __glibcxx_want_ranges_cache_latest #define __glibcxx_want_ranges_cartesian_product #define __glibcxx_want_ranges_concat #define __glibcxx_want_ranges_chunk @@ -1534,6 +1535,8 @@ namespace views::__adaptor this->_M_payload._M_apply(_Optional_func{__f}, __i); return this->_M_get(); } + + using _Optional_base<_Tp>::_M_reset; }; template @@ -10201,6 +10204,192 @@ namespace ranges } // namespace ranges #endif // __cpp_lib_ranges_concat +#if __cpp_lib_ranges_cache_latest // C++ >= 26 +namespace ranges +{ + template +requires view<_Vp> + class cache_latest_view : public view_interface> + { +_Vp _M_base = _Vp(); + +using __cache_t = __conditional_t>, + add_pointer_t>, + range_reference_t<_Vp>>; +__detail::__non_propagating_cache<__cache_t> _M_cache; + +class _Iterator; +class _Sentinel; + + public: +cache_latest_view() requires default_initializable<_Vp> = default; + +constexpr explicit +cache_latest_view(_Vp __base) +: _M_base(std::move(__base)) +{ } + +constexpr _Vp +base() const & requires copy_constructible<_Vp> +{ return _M_base; } + +constexpr _Vp +base() && +{ return std::move(_M_base); } + +constexpr auto +begin() +{ return _Iterator(*this); } + +constexpr auto +end() +{ return _Sentinel(*this); } + +constexpr auto +size() requires sized_range<_Vp> +{ return ranges::size(_M_base); } + +constexpr auto +size() const requires sized_range +{ return ranges::size(_M_base); } + }; + + template +cache_latest_view(_Range&&) -> cache_latest_view>; + + template +requires view<_Vp> + class cache_latest_view<_Vp>::_Iterator + { +cache_latest_view* _M_parent; +iterator_t<_Vp> _M_current; + +constexpr explicit +_Iterator(cache_latest_view& __parent) +: _M_parent(std::__addressof(__parent)), + _M_current(ranges::begin(__parent._M_base)) +{ } + +friend clas
[gcc r14-11387] c++: disable -Wnonnull in unevaluated context [PR115580]
https://gcc.gnu.org/g:8c635072ae68f60f14333cf113e75fa25a55becf commit r14-11387-g8c635072ae68f60f14333cf113e75fa25a55becf Author: Marek Polacek Date: Tue Mar 4 13:07:27 2025 -0500 c++: disable -Wnonnull in unevaluated context [PR115580] This PR complains that we issue a -Wnonnull even in a decltype. This fix disables even -Wformat and -Wrestrict. I think that's fine. PR c++/115580 gcc/c-family/ChangeLog: * c-common.cc (check_function_arguments): Return early if c_inhibit_evaluation_warnings. gcc/testsuite/ChangeLog: * g++.dg/warn/Wnonnull16.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 459c8a55567b06522e4b9cc0a4ef62f9d3024526) Diff: --- gcc/c-family/c-common.cc | 3 +++ gcc/testsuite/g++.dg/warn/Wnonnull16.C | 16 2 files changed, 19 insertions(+) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index d5b28efd6db4..0d05694b6d04 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -6160,6 +6160,9 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, { bool warned_p = false; + if (c_inhibit_evaluation_warnings) +return warned_p; + /* Check for null being passed in a pointer argument that must be non-null. In C++, this includes the this pointer. We also need to do this if format checking is enabled. */ diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull16.C b/gcc/testsuite/g++.dg/warn/Wnonnull16.C new file mode 100644 index ..8740f351ac76 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnonnull16.C @@ -0,0 +1,16 @@ +// PR c++/115580 +// { dg-do compile { target c++11 } } + +class WithMember { +public: + int foo(); +}; + +decltype(((WithMember*)nullptr)->foo()) footype; // { dg-bogus "pointer is null" } + +int f(void*) __attribute__((nonnull)); + +void g() +{ + [[maybe_unused]] decltype(f(nullptr)) b; // { dg-bogus "non-null" } +}
[gcc r15-7839] c++: disable -Wnonnull in unevaluated context [PR115580]
https://gcc.gnu.org/g:459c8a55567b06522e4b9cc0a4ef62f9d3024526 commit r15-7839-g459c8a55567b06522e4b9cc0a4ef62f9d3024526 Author: Marek Polacek Date: Tue Mar 4 13:07:27 2025 -0500 c++: disable -Wnonnull in unevaluated context [PR115580] This PR complains that we issue a -Wnonnull even in a decltype. This fix disables even -Wformat and -Wrestrict. I think that's fine. PR c++/115580 gcc/c-family/ChangeLog: * c-common.cc (check_function_arguments): Return early if c_inhibit_evaluation_warnings. gcc/testsuite/ChangeLog: * g++.dg/warn/Wnonnull16.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/c-family/c-common.cc | 3 +++ gcc/testsuite/g++.dg/warn/Wnonnull16.C | 16 2 files changed, 19 insertions(+) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 49508fe9ee60..587d76461e9e 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -6261,6 +6261,9 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, { bool warned_p = false; + if (c_inhibit_evaluation_warnings) +return warned_p; + /* Check for null being passed in a pointer argument that must be non-null. In C++, this includes the this pointer. We also need to do this if format checking is enabled. */ diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull16.C b/gcc/testsuite/g++.dg/warn/Wnonnull16.C new file mode 100644 index ..8740f351ac76 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnonnull16.C @@ -0,0 +1,16 @@ +// PR c++/115580 +// { dg-do compile { target c++11 } } + +class WithMember { +public: + int foo(); +}; + +decltype(((WithMember*)nullptr)->foo()) footype; // { dg-bogus "pointer is null" } + +int f(void*) __attribute__((nonnull)); + +void g() +{ + [[maybe_unused]] decltype(f(nullptr)) b; // { dg-bogus "non-null" } +}
[gcc r15-7841] Regenerate fortran/lang.opt.urls
https://gcc.gnu.org/g:3c02d195bfe4dad6097b5cc574fe1797c22267b4 commit r15-7841-g3c02d195bfe4dad6097b5cc574fe1797c22267b4 Author: Mark Wielaard Date: Wed Mar 5 22:58:56 2025 +0100 Regenerate fortran/lang.opt.urls fortran added a new -Wexternal-argument-mismatch option, but the lang.opt.urls file wasn't regenerated. Fixes: 21ca9153ebe5 ("C prototypes for external arguments; add warning for mismatch.") gcc/fortran/ChangeLog: * lang.opt.urls: Regenerated. Diff: --- gcc/fortran/lang.opt.urls | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcc/fortran/lang.opt.urls b/gcc/fortran/lang.opt.urls index 00991602eea6..4972ff8b7b9b 100644 --- a/gcc/fortran/lang.opt.urls +++ b/gcc/fortran/lang.opt.urls @@ -97,6 +97,9 @@ LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-Wconversion- Wdo-subscript LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-Wdo-subscript) +Wexternal-argument-mismatch +LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-Wexternal-argument-mismatch) + Wextra UrlSuffix(gcc/Warning-Options.html#index-Wextra) LangUrlSuffix_D(gdc/Warnings.html#index-Wextra) LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-Wextra)
[gcc r15-7842] libstdc++: Move new functions to separate files [PR119110]
https://gcc.gnu.org/g:c21d5a3591fd761872e18278e1cd8ec18e36d4cb commit r15-7842-gc21d5a3591fd761872e18278e1cd8ec18e36d4cb Author: Jonathan Wakely Date: Mon Mar 3 13:36:54 2025 + libstdc++: Move new functions to separate files [PR119110] The new test functions I added in r15-7765-g3866ca796d5281 are causing those tests to FAIL on Solaris and arm-thumb due to the linker complaining about undefined functions. The new test functions are not called, so it shouldn't matter that they call undefined member functions, but it does. Move those functions to separate { dg-do compile } files so the linker isn't used and won't complain. libstdc++-v3/ChangeLog: PR libstdc++/119110 * testsuite/25_algorithms/move/constrained.cc: Move test06 function to ... * testsuite/25_algorithms/move/105609.cc: New test. * testsuite/25_algorithms/move_backward/constrained.cc: Move test04 function to ... * testsuite/25_algorithms/move_backward/105609.cc: New test. Diff: --- .../testsuite/25_algorithms/move/105609.cc | 33 ++ .../testsuite/25_algorithms/move/constrained.cc| 29 --- .../25_algorithms/move_backward/105609.cc | 33 ++ .../25_algorithms/move_backward/constrained.cc | 29 --- 4 files changed, 66 insertions(+), 58 deletions(-) diff --git a/libstdc++-v3/testsuite/25_algorithms/move/105609.cc b/libstdc++-v3/testsuite/25_algorithms/move/105609.cc new file mode 100644 index ..810451987c9e --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/move/105609.cc @@ -0,0 +1,33 @@ +// { dg-do compile { target c++20 } } + +// PR libstdc++/105609 +// ranges::move should use ranges::iter_move instead of std::move + +#include + +namespace pr105609 +{ + struct I { +using value_type = int; +using difference_type = std::ptrdiff_t; +int operator*() const; +I& operator++(); +I operator++(int); +I& operator--(); +I operator--(int); +bool operator==(I) const; +friend int& iter_move(const I&); + }; +} + +void +test(pr105609::I i) +{ + struct O { +O(int&) { } +O(int&&) = delete; + }; + + O* o = nullptr; + std::ranges::move(i, i, o); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/move/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/move/constrained.cc index e2b45b070ef2..587b2f3728b1 100644 --- a/libstdc++-v3/testsuite/25_algorithms/move/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/move/constrained.cc @@ -204,35 +204,6 @@ test05() VERIFY( ranges::equal(v, (int[]){1,2,3,0}) ); } -namespace pr105609 -{ - struct I { -using value_type = int; -using difference_type = std::ptrdiff_t; -int operator*() const; -I& operator++(); -I operator++(int); -I& operator--(); -I operator--(int); -bool operator==(I) const; -friend int& iter_move(const I&); - }; -} - -void -test06(pr105609::I i) -{ - // PR libstdc++/105609 - // ranges::move should use ranges::iter_move instead of std::move - struct O { -O(int&) { } -O(int&&) = delete; - }; - - O* o = nullptr; - std::ranges::move(i, i, o); -} - int main() { diff --git a/libstdc++-v3/testsuite/25_algorithms/move_backward/105609.cc b/libstdc++-v3/testsuite/25_algorithms/move_backward/105609.cc new file mode 100644 index ..a4fb8d846bda --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/move_backward/105609.cc @@ -0,0 +1,33 @@ +// { dg-do compile { target c++20 } } + +// PR libstdc++/105609 +// ranges::move should use ranges::iter_move instead of std::move + +#include + +namespace pr105609 +{ + struct I { +using value_type = int; +using difference_type = std::ptrdiff_t; +int operator*() const; +I& operator++(); +I operator++(int); +I& operator--(); +I operator--(int); +bool operator==(I) const; +friend int& iter_move(const I&); + }; +} + +void +test(pr105609::I i) +{ + struct O { +O(int&) { } +O(int&&) = delete; + }; + + O* o = nullptr; + std::ranges::move_backward(i, i, o); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/move_backward/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/move_backward/constrained.cc index 4d94d386dd0b..8f6fd455b4b6 100644 --- a/libstdc++-v3/testsuite/25_algorithms/move_backward/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/move_backward/constrained.cc @@ -160,35 +160,6 @@ test03() return ok; } -namespace pr105609 -{ - struct I { -using value_type = int; -using difference_type = std::ptrdiff_t; -int operator*() const; -I& operator++(); -I operator++(int); -I& operator--(); -I operator--(int); -bool operator==(I) const; -friend int& iter_move(const I&); - }; -} - -void -test04(pr105609::I i) -{ - // PR libstdc++/105609 - // ranges::move should use ranges::iter_move instea
[gcc r15-7844] libstdc++: Make enumerate_view::iterator::operator- noexcept
https://gcc.gnu.org/g:c7449f1b1511abbee1c6b060090eda4d2d6b1879 commit r15-7844-gc7449f1b1511abbee1c6b060090eda4d2d6b1879 Author: Jonathan Wakely Date: Wed Mar 5 18:06:25 2025 + libstdc++: Make enumerate_view::iterator::operator- noexcept Implement LWG 3912, approved in Varna, June 2023. libstdc++-v3/ChangeLog: * include/std/ranges (enumerate_view::_Iterator::operator-): Add noexcept, as per LWG 3912. * testsuite/std/ranges/adaptors/enumerate/1.cc: Check iterator difference is noexcept. Diff: --- libstdc++-v3/include/std/ranges | 2 +- libstdc++-v3/testsuite/std/ranges/adaptors/enumerate/1.cc | 11 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 6790fcf7af19..e21f5284b46d 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -9176,7 +9176,7 @@ namespace views::__adaptor { return auto(__x) -= __y; } friend constexpr difference_type -operator-(const _Iterator& __x, const _Iterator& __y) +operator-(const _Iterator& __x, const _Iterator& __y) noexcept { return __x._M_pos - __y._M_pos; } friend constexpr auto diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/enumerate/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/enumerate/1.cc index c33aa9ff51e1..19aa98284d08 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/enumerate/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/enumerate/1.cc @@ -91,6 +91,17 @@ test02() } } +void +test_lwg3912() +{ + int x[] = {1, 2, 3}; + test_input_range rx (x); + auto v = rx | views::enumerate; + auto iter = std::ranges::begin(v); + // LWG 3912. enumerate_view::iterator::operator- should be noexcept + static_assert( noexcept(iter - iter) ); +} + int main() {
[gcc r15-7843] libstdc++: fix possible undefined std::timespec in module std
https://gcc.gnu.org/g:a08a5bc4b3998bd4f8d0cca491b8ab6c93769e07 commit r15-7843-ga08a5bc4b3998bd4f8d0cca491b8ab6c93769e07 Author: yxj-github-437 <2457369...@qq.com> Date: Fri Jan 17 00:01:01 2025 +0800 libstdc++: fix possible undefined std::timespec in module std I notice std::timespec and std::timespec_get are used in preprocessor condition _GLIBCXX_HAVE_TIMESPEC_GET. So in module std, it should be the same. libstdc++-v3: * src/c++23/std-clib.cc.in (timespec): Move within preprocessor group guarded by _GLIBCXX_HAVE_TIMESPEC_GET. Diff: --- libstdc++-v3/src/c++23/std-clib.cc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libstdc++-v3/src/c++23/std-clib.cc.in b/libstdc++-v3/src/c++23/std-clib.cc.in index 6809ad229d7c..10fc03e7ce0b 100644 --- a/libstdc++-v3/src/c++23/std-clib.cc.in +++ b/libstdc++-v3/src/c++23/std-clib.cc.in @@ -585,9 +585,9 @@ export C_LIB_NAMESPACE using std::strftime; using std::time; using std::time_t; - using std::timespec; using std::tm; #ifdef _GLIBCXX_HAVE_TIMESPEC_GET + using std::timespec; using std::timespec_get; #endif }
[gcc r15-7845] PR modula2/118998 Rotate of a packetset causes different types to binary operator error
https://gcc.gnu.org/g:1b43154b90be6a2f691b98d4e395c07ac6c7045c commit r15-7845-g1b43154b90be6a2f691b98d4e395c07ac6c7045c Author: Gaius Mulley Date: Wed Mar 5 23:01:45 2025 + PR modula2/118998 Rotate of a packetset causes different types to binary operator error This patch allow a packedset to be rotated by the system module intrinsic procedure function. It ensures that both operands to the tree rotate are of the same type. In turn the result will be the same type and the assignment into the designator (of the same set type) will succeed. gcc/m2/ChangeLog: PR modula2/118998 * gm2-gcc/m2expr.cc (m2expr_BuildLRotate): Convert nBits to the return type. (m2expr_BuildRRotate): Ditto. (m2expr_BuildLogicalRotate): Convert op3 to an integer type. Replace op3 aith rotateCount. Negate rotateCount if it is negative and call rotate right. * gm2-gcc/m2pp.cc (m2pp_bit_and_expr): New function. (m2pp_binary_function): Ditto. (m2pp_simple_expression): BIT_AND_EXPR new case clause. LROTATE_EXPR ditto. RROTATE_EXPR ditto. gcc/testsuite/ChangeLog: PR modula2/118998 * gm2/iso/pass/testrotate.mod: New test. * gm2/pim/fail/tinyconst.mod: New test. * gm2/sets/run/pass/simplepacked.mod: New test. Signed-off-by: Gaius Mulley Diff: --- gcc/m2/gm2-gcc/m2expr.cc | 13 ++--- gcc/m2/gm2-gcc/m2pp.cc | 32 gcc/testsuite/gm2/iso/pass/testrotate.mod| 11 + gcc/testsuite/gm2/pim/fail/tinyconst.mod | 6 +++ gcc/testsuite/gm2/sets/run/pass/simplepacked.mod | 62 5 files changed, 118 insertions(+), 6 deletions(-) diff --git a/gcc/m2/gm2-gcc/m2expr.cc b/gcc/m2/gm2-gcc/m2expr.cc index 7c2a6f1cb5a9..83709595de6c 100644 --- a/gcc/m2/gm2-gcc/m2expr.cc +++ b/gcc/m2/gm2-gcc/m2expr.cc @@ -673,6 +673,7 @@ m2expr_BuildLRotate (location_t location, tree op1, tree nBits, op1 = m2expr_FoldAndStrip (op1); nBits = m2expr_FoldAndStrip (nBits); + nBits = m2convert_BuildConvert (location, TREE_TYPE (op1), nBits, needconvert); t = m2expr_build_binary_op (location, LROTATE_EXPR, op1, nBits, needconvert); return m2expr_FoldAndStrip (t); } @@ -688,6 +689,7 @@ m2expr_BuildRRotate (location_t location, tree op1, tree nBits, op1 = m2expr_FoldAndStrip (op1); nBits = m2expr_FoldAndStrip (nBits); + nBits = m2convert_BuildConvert (location, TREE_TYPE (op1), nBits, needconvert); t = m2expr_build_binary_op (location, RROTATE_EXPR, op1, nBits, needconvert); return m2expr_FoldAndStrip (t); } @@ -801,18 +803,17 @@ m2expr_BuildLogicalRotate (location_t location, tree op1, tree op2, tree op3, { char *labelElseName = createUniqueLabel (); char *labelEndName = createUniqueLabel (); - tree is_less = m2expr_BuildLessThan (location, - m2convert_ToInteger (location, op3), + tree rotateCount = m2convert_ToInteger (location, op3); + tree is_less = m2expr_BuildLessThan (location, rotateCount, m2expr_GetIntegerZero (location)); m2statement_DoJump (location, is_less, NULL, labelElseName); - res = m2expr_BuildLRLn (location, op2, op3, nBits, needconvert); + res = m2expr_BuildLRLn (location, op2, rotateCount, nBits, needconvert); m2statement_BuildAssignmentTree (location, op1, res); m2statement_BuildGoto (location, labelEndName); m2statement_DeclareLabel (location, labelElseName); - res = m2expr_BuildLRRn (location, op2, - m2expr_BuildNegate (location, op3, needconvert), - nBits, needconvert); + rotateCount = m2expr_BuildNegate (location, rotateCount, needconvert); + res = m2expr_BuildLRRn (location, op2, rotateCount, nBits, needconvert); m2statement_BuildAssignmentTree (location, op1, res); m2statement_DeclareLabel (location, labelEndName); } diff --git a/gcc/m2/gm2-gcc/m2pp.cc b/gcc/m2/gm2-gcc/m2pp.cc index 0f6d35a710e4..d7f5a4187c8f 100644 --- a/gcc/m2/gm2-gcc/m2pp.cc +++ b/gcc/m2/gm2-gcc/m2pp.cc @@ -1922,6 +1922,14 @@ m2pp_bit_ior_expr (pretty *s, tree t) m2pp_binary (s, t, "|"); } +/* m2pp_bit_and_expr generate a C style bit and. */ + +static void +m2pp_bit_and_expr (pretty *s, tree t) +{ + m2pp_binary (s, t, "&"); +} + /* m2pp_truth_expr. */ static void @@ -1938,6 +1946,21 @@ m2pp_truth_expr (pretty *s, tree t, const char *op) m2pp_print (s, ")"); } +/* m2pp_binary_function handle GCC expression tree as a function. */ + +static void +m2pp_binary_function (pretty *s, tree t, const char *funcname) +{ + m2pp_print (s, funcname); + m2pp_needspace (s); + m2pp_print (s, "("); + m2pp_expression (s, TREE_OPERAND (t