[gcc r15-6726] ada: Cleanup preanalysis of static expressions (part 3)
https://gcc.gnu.org/g:aa086b7bf86945c1448fee665b8289c39dbcb743 commit r15-6726-gaa086b7bf86945c1448fee665b8289c39dbcb743 Author: Javier Miranda Date: Wed Dec 25 06:42:10 2024 + ada: Cleanup preanalysis of static expressions (part 3) Avoid reporting spurious errors. gcc/ada/ChangeLog: * freeze.adb (Freeze_Expr_Types): Reverse patch; that is, restore calls to Preanalyze_Spec_Expression instead of Preanalyze_And_Resolve for the sake of consistency with Analyze_Expression_Function. Patch suggested by Eric Botcazou. * exp_put_image.adb (Image_Should_Call_Put_Image): Ensure that function Defining_Identifier is called with a proper node to avoid internal assertion failure. Diff: --- gcc/ada/exp_put_image.adb | 2 ++ gcc/ada/freeze.adb| 8 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb index 38bde44ff5af..ae5fa40fa380 100644 --- a/gcc/ada/exp_put_image.adb +++ b/gcc/ada/exp_put_image.adb @@ -1190,6 +1190,8 @@ package body Exp_Put_Image is -- aspects, not just for Put_Image? if Is_Itype (U_Type) + and then Nkind (Associated_Node_For_Itype (U_Type)) in + N_Full_Type_Declaration | N_Subtype_Declaration and then Has_Aspect (Defining_Identifier (Associated_Node_For_Itype (U_Type)), Aspect_Put_Image) diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index 10f0de78d9d7..54b620214e80 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -9389,14 +9389,16 @@ package body Freeze is -- pre/postconditions during expansion of the subprogram body, the -- subprogram is already installed. + -- Call Preanalyze_Spec_Expression instead of Preanalyze_And_Resolve + -- for the sake of consistency with Analyze_Expression_Function. + if Def_Id /= Current_Scope then Push_Scope (Def_Id); Install_Formals (Def_Id); - - Preanalyze_And_Resolve (Dup_Expr, Typ); + Preanalyze_Spec_Expression (Dup_Expr, Typ); End_Scope; else - Preanalyze_And_Resolve (Dup_Expr, Typ); + Preanalyze_Spec_Expression (Dup_Expr, Typ); end if; -- Restore certain attributes of Def_Id since the preanalysis may
[gcc r15-6727] ada: Error on Disable_Controlled aspect in Multiway_Trees
https://gcc.gnu.org/g:659b70b3f86ae7dc5be6cc6f53741c2ee9c290ff commit r15-6727-g659b70b3f86ae7dc5be6cc6f53741c2ee9c290ff Author: squirek Date: Mon Dec 30 19:59:45 2024 + ada: Error on Disable_Controlled aspect in Multiway_Trees This patch fixes an issue in the compiler whereby instantiating Multiway_Trees with a formal type leads to a compile-time error due to the expression supplied for aspect Disable_Controlled specified on types decalred within Multiway_Trees' body not being static. gcc/ada/ChangeLog: * libgnat/a-comutr.adb, libgnat/a-comutr.ads: Move the declarations of iterator types into the specification and add additional comments. Diff: --- gcc/ada/libgnat/a-comutr.adb | 49 gcc/ada/libgnat/a-comutr.ads | 39 +++ 2 files changed, 39 insertions(+), 49 deletions(-) diff --git a/gcc/ada/libgnat/a-comutr.adb b/gcc/ada/libgnat/a-comutr.adb index e866e2ff8954..df374107 100644 --- a/gcc/ada/libgnat/a-comutr.adb +++ b/gcc/ada/libgnat/a-comutr.adb @@ -41,55 +41,6 @@ is pragma Warnings (Off, "variable ""Lock*"" is not referenced"); -- See comment in Ada.Containers.Helpers - - -- Root_Iterator -- - - - type Root_Iterator is abstract new Limited_Controlled and - Tree_Iterator_Interfaces.Forward_Iterator with - record - Container : Tree_Access; - Subtree : Tree_Node_Access; - end record - with Disable_Controlled => not T_Check; - - overriding procedure Finalize (Object : in out Root_Iterator); - - --- - -- Subtree_Iterator -- - --- - - -- ??? these headers are a bit odd, but for sure they do not substitute - -- for documenting things, what *is* a Subtree_Iterator? - - type Subtree_Iterator is new Root_Iterator with null record; - - overriding function First (Object : Subtree_Iterator) return Cursor; - - overriding function Next - (Object : Subtree_Iterator; - Position : Cursor) return Cursor; - - - - -- Child_Iterator -- - - - - type Child_Iterator is new Root_Iterator and - Tree_Iterator_Interfaces.Reversible_Iterator with null record - with Disable_Controlled => not T_Check; - - overriding function First (Object : Child_Iterator) return Cursor; - - overriding function Next - (Object : Child_Iterator; - Position : Cursor) return Cursor; - - overriding function Last (Object : Child_Iterator) return Cursor; - - overriding function Previous - (Object : Child_Iterator; - Position : Cursor) return Cursor; - --- -- Local Subprograms -- --- diff --git a/gcc/ada/libgnat/a-comutr.ads b/gcc/ada/libgnat/a-comutr.ads index b6d006fd6263..adc2cad8e5e5 100644 --- a/gcc/ada/libgnat/a-comutr.ads +++ b/gcc/ada/libgnat/a-comutr.ads @@ -491,6 +491,45 @@ private for Reference_Type'Write use Write; + -- Base iterator type for shared functionality between Child_Iterator + -- and Subtree_Iterator - namely finalization. + type Root_Iterator is abstract new Limited_Controlled and + Tree_Iterator_Interfaces.Forward_Iterator with + record + Container : Tree_Access; + Subtree : Tree_Node_Access; + end record + with Disable_Controlled => not T_Check; + + overriding procedure Finalize (Object : in out Root_Iterator); + + -- Iterator to handle traversal within a specific subtree. + type Subtree_Iterator is new Root_Iterator with null record; + + overriding function First (Object : Subtree_Iterator) return Cursor; + + overriding function Next + (Object : Subtree_Iterator; + Position : Cursor) return Cursor; + + -- Iterator to handle bidirectional traversal of a node's immediate + -- children for operations like reverse enumeration and selective + -- insertion. + type Child_Iterator is new Root_Iterator and + Tree_Iterator_Interfaces.Reversible_Iterator with null record + with Disable_Controlled => not T_Check; + + overriding function First (Object : Child_Iterator) return Cursor; + + overriding function Next + (Object : Child_Iterator; + Position : Cursor) return Cursor; + + overriding function Last (Object : Child_Iterator) return Cursor; + + overriding function Previous + (Object : Child_Iterator; + Position : Cursor) return Cursor; -- See Ada.Containers.Vectors for documentation on the following function Pseudo_Reference
[gcc r15-6755] LoongArch: Opitmize the cost of vec_construct.
https://gcc.gnu.org/g:e8a57884ad4898fdec5c13a8933d73bcbaf06099 commit r15-6755-ge8a57884ad4898fdec5c13a8933d73bcbaf06099 Author: chenxiaolong Date: Tue Jan 7 21:04:51 2025 +0800 LoongArch: Opitmize the cost of vec_construct. When analyzing 525 on LoongArch architecture, it was found that the for loop of hotspot function x264_pixel_satd_8x4 could not be quantized 256-bit due to the cost of vec_construct setting. After re-adjusting vec_construct, the performance of 525 program was improved by 16.57%. It was found that this function can be vectorized on the aarch64 and x86 architectures, see [PR98138]. Co-Authored-By: Deng Jianbo . gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_builtin_vectorization_cost): Modify the construction cost of the vec_construct vector. gcc/testsuite/ChangeLog: * gcc.target/loongarch/vect-slp-two-operator.c: New test. Diff: --- gcc/config/loongarch/loongarch.cc | 6 ++-- .../gcc.target/loongarch/vect-slp-two-operator.c | 38 ++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index d506354c48a0..24c19031026a 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -4127,10 +4127,10 @@ loongarch_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, case vec_construct: elements = TYPE_VECTOR_SUBPARTS (vectype); - if (ISA_HAS_LASX) - return elements + 1; + if (LASX_SUPPORTED_MODE_P (mode) && !LSX_SUPPORTED_MODE_P (mode)) + return elements / 2 + 3; else - return elements; + return elements / 2 + 1; default: gcc_unreachable (); diff --git a/gcc/testsuite/gcc.target/loongarch/vect-slp-two-operator.c b/gcc/testsuite/gcc.target/loongarch/vect-slp-two-operator.c new file mode 100644 index ..43b46759902b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vect-slp-two-operator.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -ftree-vectorize -fdump-tree-vect -fdump-tree-vect-details" } */ + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; + +#define HADAMARD4(d0, d1, d2, d3, s0, s1, s2, s3) \ + { \ +int t0 = s0 + s1; \ +int t1 = s0 - s1; \ +int t2 = s2 + s3; \ +int t3 = s2 - s3; \ +d0 = t0 + t2; \ +d1 = t1 + t3; \ +d2 = t0 - t2; \ +d3 = t1 - t3; \ + } + +void sink (uint32_t tmp[4][4]); + +void +x264_pixel_satd_8x4 (uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2) +{ + uint32_t tmp[4][4]; + int sum = 0; + for (int i = 0; i < 4; i++, pix1 += i_pix1, pix2 += i_pix2) +{ + uint32_t a0 = (pix1[0] - pix2[0]) + ((pix1[4] - pix2[4]) << 16); + uint32_t a1 = (pix1[1] - pix2[1]) + ((pix1[5] - pix2[5]) << 16); + uint32_t a2 = (pix1[2] - pix2[2]) + ((pix1[6] - pix2[6]) << 16); + uint32_t a3 = (pix1[3] - pix2[3]) + ((pix1[7] - pix2[7]) << 16); + HADAMARD4 (tmp[i][0], tmp[i][1], tmp[i][2], tmp[i][3], a0, a1, a2, a3); +} + sink (tmp); +} + +/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
[gcc r12-10892] doc: cpp: fix version test example syntax
https://gcc.gnu.org/g:36db43d30282521732736ba5da23c397fb51f1e0 commit r12-10892-g36db43d30282521732736ba5da23c397fb51f1e0 Author: Sam James Date: Wed Jan 1 17:16:17 2025 + doc: cpp: fix version test example syntax gcc/ChangeLog: * doc/cpp.texi (Common Predefined Macros): Fix syntax. Diff: --- gcc/doc/cpp.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 90b2767e39a0..fe92522a7b7f 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1970,7 +1970,7 @@ like this: #if __GNUC__ > 3 || \ (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \ (__GNUC_MINOR__ == 2 && \ -__GNUC_PATCHLEVEL__ > 0)) +__GNUC_PATCHLEVEL__ > 0))) @end smallexample @noindent
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] reuse left-hand mask to decode right-hand xor operand
https://gcc.gnu.org/g:b88da512d56ccbdf5dc012e2253dec14b427bfa1 commit b88da512d56ccbdf5dc012e2253dec14b427bfa1 Author: Alexandre Oliva Date: Thu Jan 9 11:57:03 2025 -0300 [ifcombine] reuse left-hand mask to decode right-hand xor operand If fold_truth_andor_for_ifcombine applies a mask to an xor, say because the result of the xor is compared with a power of two [minus one], we have to apply the same mask when processing both the left- and right-hand xor paths for the transformation to be sound. Arrange for decode_field_reference to propagate the incoming mask along with the expression to the right-hand operand. Don't require the right-hand xor operand to be a constant, that was a cut&pasto. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Add xor_pand_mask. Propagate pand_mask to the right-hand xor operand. Don't require the right-hand xor operand to be a constant. (fold_truth_andor_for_ifcombine): Pass right-hand mask when appropriate. Diff: --- gcc/gimple-fold.cc | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index d95f04213ee4..0ad92de3a218 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7519,8 +7519,9 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, - *XOR_P will be set to TRUE, and the left-hand operand of the XOR will be - decoded. If *XOR_P is TRUE, XOR_CMP_OP is supposed to be NULL, and then the + *XOR_P will be set to TRUE, *XOR_PAND_MASK will be copied from *PAND_MASK, + and the left-hand operand of the XOR will be decoded. If *XOR_P is TRUE, + XOR_CMP_OP and XOR_PAND_MASK are supposed to be NULL, and then the right-hand operand of the XOR will be decoded. *LOAD is set to the load stmt of the innermost reference, if any, @@ -7537,7 +7538,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpos, bool *punsignedp, bool *preversep, bool *pvolatilep, wide_int *pand_mask, bool *psignbit, - bool *xor_p, tree *xor_cmp_op, + bool *xor_p, tree *xor_cmp_op, wide_int *xor_pand_mask, gimple **load, location_t loc[4]) { tree exp = *pexp; @@ -7599,15 +7600,14 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, and_mask = *pand_mask; /* Turn (a ^ b) [!]= 0 into a [!]= b. */ - if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops) - && uniform_integer_cst_p (res_ops[1])) + if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops)) { /* No location recorded for this one, it's entirely subsumed by the compare. */ if (*xor_p) { exp = res_ops[1]; - gcc_checking_assert (!xor_cmp_op); + gcc_checking_assert (!xor_cmp_op && !xor_pand_mask); } else if (!xor_cmp_op) /* Not much we can do when xor appears in the right-hand compare @@ -7618,6 +7618,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, *xor_p = true; exp = res_ops[0]; *xor_cmp_op = *pexp; + *xor_pand_mask = *pand_mask; } } @@ -8152,19 +8153,21 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, bool l_xor = false, r_xor = false; ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos, &ll_unsignedp, &ll_reversep, &volatilep, -&ll_and_mask, &ll_signbit, &l_xor, &lr_arg, +&ll_and_mask, &ll_signbit, +&l_xor, &lr_arg, &lr_and_mask, &ll_load, ll_loc); lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos, &lr_unsignedp, &lr_reversep, &volatilep, -&lr_and_mask, &lr_signbit, &l_xor, 0, +&lr_and_mask, &lr_signbit, &l_xor, 0, 0, &lr_load, lr_loc); rl_inner = decode_field_reference (&rl_arg, &rl_bitsize, &rl_bitpos, &rl_unsignedp, &rl_reversep, &volatilep, -&rl_and_mask, &rl_signbit, &r_xor, &rr_arg, +&rl_and_mask, &rl_signbit, +&r_xor, &rr_arg, &rr_and_mask, &rl_load, rl_loc); rr_inner = decode_field_reference (&rr_arg, &rr_bitsize, &rr_bitpos, &rr_unsignedp, &rr_reversep, &v
[gcc/aoliva/heads/testme] (3 commits) [ifcombine] drop other misuses of uniform_integer_cst_p
The branch 'aoliva/heads/testme' was updated to point to: f419ad18d1ba... [ifcombine] drop other misuses of uniform_integer_cst_p It previously pointed to: adbdc5d3f1f3... [ifcombine] fix mask variable test to match use [PR118344] Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- adbdc5d... [ifcombine] fix mask variable test to match use [PR118344] b17ab50... [ifcombine] reuse left-hand mask to decode right-hand xor o Summary of changes (added commits): --- f419ad1... [ifcombine] drop other misuses of uniform_integer_cst_p 98ead44... [ifcombine] fix mask variable test to match use [PR118344] b88da51... [ifcombine] reuse left-hand mask to decode right-hand xor o
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] fix mask variable test to match use [PR118344]
https://gcc.gnu.org/g:98ead44962ac7673b7a835c1872ad166195b69bd commit 98ead44962ac7673b7a835c1872ad166195b69bd Author: Alexandre Oliva Date: Thu Jan 9 10:23:50 2025 -0300 [ifcombine] fix mask variable test to match use [PR118344] There was a cut&pasto in the rr_and_mask's adjustment to match the combined type: the test on whether there was a mask already was testing the wrong variable, and then it might crash or otherwise fail accessing an undefined mask. This only hit with checking enabled, and rarely at that. for gcc/ChangeLog PR tree-optimization/118344 * gimple-fold.cc (fold_truth_andor_for_ifcombine): Fix typo in rr_and_mask's type adjustment test. for gcc/testsuite/ChangeLog PR tree-optimization/118344 * gcc.dg/field-merge-19.c: New. Diff: --- gcc/gimple-fold.cc| 2 +- gcc/testsuite/gcc.dg/field-merge-19.c | 41 +++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 0ad92de3a218..20b5024d861d 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -8644,7 +8644,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, xlr_bitpos); else lr_mask = wi::shifted_mask (xlr_bitpos, lr_bitsize, false, rnprec); - if (rl_and_mask.get_precision ()) + if (rr_and_mask.get_precision ()) rr_mask = wi::lshift (wide_int::from (rr_and_mask, rnprec, UNSIGNED), xrr_bitpos); else diff --git a/gcc/testsuite/gcc.dg/field-merge-19.c b/gcc/testsuite/gcc.dg/field-merge-19.c new file mode 100644 index ..5622baa52b0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/field-merge-19.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fchecking" } */ + +/* PR tree-optimization/118344 */ + +/* This used to ICE attempting to extend a mask variable after testing the + wrong mask variable. */ + +int d, e, g, h, i, c, j; +static short k; +char o; +static int *p; +static long *a; +int b[0]; +int q(int s, int t, int *u, int *v) { + for (int f = 0; f < s; f++) +if ((t & v[f]) != u[f]) + return 0; + return 1; +} +int w(int s, int t) { + int l[] = {t, t, t, t}, m[] = {e, e, 3, 1}; + int n = q(s, d, l, m); + return n; +} +int x(unsigned s) { + unsigned r; + if (s >= -1) +return 1; + r = 1000; + while (s > 1 / r) +r /= 2; + return g ? 2 : 0; +} +void y() { + for (;;) { +b[w(8, *p)] = h; +for (; a + k; j = o) + i &= c = x(6) < 0; + } +}
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] drop other misuses of uniform_integer_cst_p
https://gcc.gnu.org/g:f419ad18d1ba1a9ccc61a2fdbc53f0c54344eb40 commit f419ad18d1ba1a9ccc61a2fdbc53f0c54344eb40 Author: Alexandre Oliva Date: Fri Jan 10 04:24:22 2025 -0300 [ifcombine] drop other misuses of uniform_integer_cst_p As Jakub pointed out in PR118206, the use of uniform_integer_cst_p in ifcombine makes no sense, we're not dealing with vectors. Indeed, I've been misunderstanding and misusing it since I cut&pasted it from some preexisting match predicate in earlier version of the ifcombine field-merge patch. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Drop misuses of uniform_integer_cst_p. (fold_truth_andor_for_ifcombine): Likewise. Diff: --- gcc/gimple-fold.cc | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 20b5024d861d..a3987c4590ae 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7577,7 +7577,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, /* Recognize and save a masking operation. Combine it with an incoming mask. */ if (pand_mask && gimple_binop_def_p (BIT_AND_EXPR, exp, res_ops) - && uniform_integer_cst_p (res_ops[1])) + && TREE_CODE (res_ops[1]) == INTEGER_CST) { loc[1] = gimple_location (SSA_NAME_DEF_STMT (exp)); exp = res_ops[0]; @@ -7632,7 +7632,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, /* Take note of shifts. */ if (gimple_binop_def_p (RSHIFT_EXPR, exp, res_ops) - && uniform_integer_cst_p (res_ops[1])) + && TREE_CODE (res_ops[1]) == INTEGER_CST) { loc[2] = gimple_location (SSA_NAME_DEF_STMT (exp)); exp = res_ops[0]; @@ -8092,7 +8092,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, else if ((lcode == LT_EXPR || lcode == GE_EXPR) && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)) && TYPE_UNSIGNED (TREE_TYPE (ll_arg)) - && uniform_integer_cst_p (lr_arg) + && TREE_CODE (lr_arg) == INTEGER_CST && wi::popcount (wi::to_wide (lr_arg)) == 1) { ll_and_mask = ~(wi::to_wide (lr_arg) - 1); @@ -8104,7 +8104,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, else if ((lcode == LE_EXPR || lcode == GT_EXPR) && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)) && TYPE_UNSIGNED (TREE_TYPE (ll_arg)) - && uniform_integer_cst_p (lr_arg) + && TREE_CODE (lr_arg) == INTEGER_CST && wi::popcount (wi::to_wide (lr_arg) + 1) == 1) { ll_and_mask = ~wi::to_wide (lr_arg); @@ -8123,7 +8123,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, else if ((rcode == LT_EXPR || rcode == GE_EXPR) && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg)) && TYPE_UNSIGNED (TREE_TYPE (rl_arg)) - && uniform_integer_cst_p (rr_arg) + && TREE_CODE (rr_arg) == INTEGER_CST && wi::popcount (wi::to_wide (rr_arg)) == 1) { rl_and_mask = ~(wi::to_wide (rr_arg) - 1); @@ -8133,7 +8133,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, else if ((rcode == LE_EXPR || rcode == GT_EXPR) && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg)) && TYPE_UNSIGNED (TREE_TYPE (rl_arg)) - && uniform_integer_cst_p (rr_arg) + && TREE_CODE (rr_arg) == INTEGER_CST && wi::popcount (wi::to_wide (rr_arg) + 1) == 1) { rl_and_mask = ~wi::to_wide (rr_arg); @@ -8392,7 +8392,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, HOST_WIDE_INT ll_align = TYPE_ALIGN (TREE_TYPE (ll_inner)); poly_uint64 ll_end_region = 0; if (TYPE_SIZE (TREE_TYPE (ll_inner)) - && uniform_integer_cst_p (TYPE_SIZE (TREE_TYPE (ll_inner + && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (ll_inner ll_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (ll_inner))); if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region, ll_align, BITS_PER_WORD, volatilep, &lnmode)) @@ -8585,7 +8585,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, HOST_WIDE_INT lr_align = TYPE_ALIGN (TREE_TYPE (lr_inner)); poly_uint64 lr_end_region = 0; if (TYPE_SIZE (TREE_TYPE (lr_inner)) - && uniform_integer_cst_p (TYPE_SIZE (TREE_TYPE (lr_inner + && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (lr_inner lr_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (lr_inner))); if (!get_best_mode (end_bit - first_bit, first_bit, 0, lr_end_region, lr_align, BITS_PER_WORD, volatilep, &rnmode))
[gcc r14-11175] c++: template-id dependence wrt local static arg [PR117792]
https://gcc.gnu.org/g:4dbfc2ff0a84edf6addeaa425272a5beacbbc7db commit r14-11175-g4dbfc2ff0a84edf6addeaa425272a5beacbbc7db Author: Patrick Palka Date: Thu Jan 9 10:49:45 2025 -0500 c++: template-id dependence wrt local static arg [PR117792] Here we end up ICEing at instantiation time for the call to f ultimately because we wrongly consider the call to be non-dependent, and so we specialize f ahead of time and then get confused when fully substituting this specialization. The call is dependent due to [temp.dep.temp]/3 and we miss that because function template-id arguments aren't coerced until overload resolution, and so the local static template argument lacks an implicit cast to reference type that value_dependent_expression_p looks for before considering dependence of the address. Other kinds of template-ids aren't affected since they're coerced ahead of time. So when considering dependence of a function template-id, we need to conservatively consider dependence of the address of each argument (if applicable). PR c++/117792 gcc/cp/ChangeLog: * pt.cc (type_dependent_expression_p): Consider the dependence of the address of each template argument of a function template-id. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/nontype7.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 40f0f6ab75a391906bed40cbdc098b0df3a91af7) Diff: --- gcc/cp/pt.cc | 10 -- gcc/testsuite/g++.dg/cpp1z/nontype7.C | 22 ++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c2c66a7567a4..d5bf6af8467f 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -28704,9 +28704,15 @@ type_dependent_expression_p (tree expression) if (TREE_CODE (expression) == TEMPLATE_ID_EXPR) { - if (any_dependent_template_arguments_p - (TREE_OPERAND (expression, 1))) + tree args = TREE_OPERAND (expression, 1); + if (any_dependent_template_arguments_p (args)) return true; + /* Arguments of a function template-id aren't necessarily coerced +yet so we must conservatively assume that the address (and not +just value) of the argument matters as per [temp.dep.temp]/3. */ + for (tree arg : tree_vec_range (args)) + if (has_value_dependent_address (arg)) + return true; expression = TREE_OPERAND (expression, 0); if (identifier_p (expression)) return true; diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype7.C b/gcc/testsuite/g++.dg/cpp1z/nontype7.C new file mode 100644 index ..f103d5a6888e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nontype7.C @@ -0,0 +1,22 @@ +// PR c++/117792 +// { dg-do compile { target c++17 } } + +template +void f(T) { } + +template +void f(...) = delete; + +template int v; + +template struct A { }; + +template +void g() { + static constexpr int local_static = 0; + auto x = v; // OK + A y; // OK + f(0); // ICE +} + +template void g();
[gcc r14-11176] c++: relax ICE for unexpected trees during constexpr [PR117925]
https://gcc.gnu.org/g:aa1e19d821a39d973c4c8c0e8d1d19811d2fa433 commit r14-11176-gaa1e19d821a39d973c4c8c0e8d1d19811d2fa433 Author: Patrick Palka Date: Thu Jan 9 10:50:08 2025 -0500 c++: relax ICE for unexpected trees during constexpr [PR117925] When we encounter an unexpected (likely templated) tree code during constexpr evaluation we currently ICE even in release mode. But it seems more user-friendly to just gracefully treat the expression as non-constant, which will be harmless most of the time (e.g. in the case of warning-specific or speculative constexpr folding as in the PR), and at worst will transform an ICE-on-valid bug into a rejects-valid bug. This is also what e.g. tsubst_expr does when it encounters an unexpected tree code. PR c++/117925 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression) : Relax ICE when encountering an unexpected tree code into a checking ICE guarded by flag_checking. Reviewed-by: Jason Merrill (cherry picked from commit eeedc54cc81c4dfb472ecbd6f14cfbf2dd035474) Diff: --- gcc/cp/constexpr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index c5cd5c87680f..6025b4c29437 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8626,7 +8626,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, error_at (EXPR_LOCATION (t), "statement is not a constant expression"); } - else + else if (flag_checking) internal_error ("unexpected expression %qE of kind %s", t, get_tree_code_name (TREE_CODE (t))); *non_constant_p = true;
[gcc r14-11184] libstdc++: Fix parallel std::exclusive_scan [PR108236]
https://gcc.gnu.org/g:f0eb0ba218968715506c435ca4ff71043e86617c commit r14-11184-gf0eb0ba218968715506c435ca4ff71043e86617c Author: Jonathan Wakely Date: Tue Dec 3 16:36:05 2024 + libstdc++: Fix parallel std::exclusive_scan [PR108236] The standard says that std::exclusive_scan can be used to work in place, i.e. where the output range is the same as the input range. This means that the first sum cannot be written to the output until after reading the first input value, otherwise we'll already have overwritten the first input value. While writing a new testcase I also realised that the serial version of std::exclusive_scan uses copy construction for the accumulator variable, but the standard only requires Cpp17MoveConstructible. We also require move assignable, which is missing from the standard's requirements, but we should at least use move construction not copy construction. A similar problem exists for some other new C++17 numeric algos, but I'll fix the others in a subsequent commit. libstdc++-v3/ChangeLog: PR libstdc++/108236 * include/pstl/glue_numeric_impl.h (exclusive_scan): Pass __init as rvalue. * include/pstl/numeric_impl.h (__brick_transform_scan): Do not write through __result until after reading through __first. Move __init into return value. (__pattern_transform_scan): Pass __init as rvalue. * include/std/numeric (exclusive_scan): Move construct instead of copy constructing. * testsuite/26_numerics/exclusive_scan/2.cc: New test. * testsuite/26_numerics/pstl/numeric_ops/108236.cc: New test. (cherry picked from commit cd107a6343c96c4ef26096e250d43a4a4211eced) Diff: --- libstdc++-v3/include/pstl/glue_numeric_impl.h | 2 +- libstdc++-v3/include/pstl/numeric_impl.h | 9 ++-- libstdc++-v3/include/std/numeric | 4 +- .../testsuite/26_numerics/exclusive_scan/2.cc | 46 .../26_numerics/pstl/numeric_ops/108236.cc | 50 ++ 5 files changed, 104 insertions(+), 7 deletions(-) diff --git a/libstdc++-v3/include/pstl/glue_numeric_impl.h b/libstdc++-v3/include/pstl/glue_numeric_impl.h index 490175c8b835..10d4912deede 100644 --- a/libstdc++-v3/include/pstl/glue_numeric_impl.h +++ b/libstdc++-v3/include/pstl/glue_numeric_impl.h @@ -108,7 +108,7 @@ exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIte using namespace __pstl; return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, -__result, __pstl::__internal::__no_op(), __init, __binary_op, +__result, __pstl::__internal::__no_op(), std::move(__init), __binary_op, /*inclusive=*/std::false_type()); } diff --git a/libstdc++-v3/include/pstl/numeric_impl.h b/libstdc++-v3/include/pstl/numeric_impl.h index 7ba83eeb7149..e1ebec160398 100644 --- a/libstdc++-v3/include/pstl/numeric_impl.h +++ b/libstdc++-v3/include/pstl/numeric_impl.h @@ -160,11 +160,12 @@ __brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _Outpu { for (; __first != __last; ++__first, ++__result) { -*__result = __init; + _Tp __v = std::move(__init); _PSTL_PRAGMA_FORCEINLINE -__init = __binary_op(__init, __unary_op(*__first)); +__init = __binary_op(__v, __unary_op(*__first)); +*__result = std::move(__v); } -return std::make_pair(__result, __init); +return std::make_pair(__result, std::move(__init)); } // Inclusive form @@ -225,7 +226,7 @@ __pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Fo _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _Inclusive) noexcept { -return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), +return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, std::move(__init), __binary_op, _Inclusive(), typename _Tag::__is_vector{}) .first; } diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric index c912db4a5195..a4cda3d5c36f 100644 --- a/libstdc++-v3/include/std/numeric +++ b/libstdc++-v3/include/std/numeric @@ -485,8 +485,8 @@ namespace __detail { while (__first != __last) { - auto __v = __init; - __init = __binary_op(__init, *__first); + _Tp __v = std::move(__init); + __init = __binary_op(__v, *__first); ++__first; *__result++ = std::move(__v);
[gcc r14-11180] libstdc++: Skip redundant assertions in std::span construction [PR117966]
https://gcc.gnu.org/g:83fa0822aeec8af2162825976209efb90ca40c87 commit r14-11180-g83fa0822aeec8af2162825976209efb90ca40c87 Author: Jonathan Wakely Date: Mon Dec 9 17:35:24 2024 + libstdc++: Skip redundant assertions in std::span construction [PR117966] As PR c++/117966 shows, the Debug Mode checks cause a compilation error for a global constexpr std::span. Those debug checks are redundant when constructing from an array or a range, because we already know we have a valid range and we know its size. Instead of delegating to the std::span(contiguous_iterator, contiguous_iterator) constructor, just initialize the data members directly. libstdc++-v3/ChangeLog: PR libstdc++/117966 * include/std/span (span(T (&)[N])): Do not delegate to constructor that performs redundant checks. (span(array&), span(const array&)): Likewise. (span(Range&&), span(const span&)): Likewise. * testsuite/23_containers/span/117966.cc: New test. (cherry picked from commit e95bda027e0b81922c1bf44770674190bdf787e8) Diff: --- libstdc++-v3/include/std/span | 10 +- libstdc++-v3/testsuite/23_containers/span/117966.cc | 13 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index 00fc52791526..726f0f339f14 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -185,21 +185,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION requires (_Extent == dynamic_extent || _ArrayExtent == _Extent) constexpr span(type_identity_t (&__arr)[_ArrayExtent]) noexcept - : span(static_cast(__arr), _ArrayExtent) + : _M_ptr(__arr), _M_extent(_ArrayExtent) { } template requires __is_compatible_array<_Tp, _ArrayExtent>::value constexpr span(array<_Tp, _ArrayExtent>& __arr) noexcept - : span(static_cast(__arr.data()), _ArrayExtent) + : _M_ptr(__arr.data()), _M_extent(_ArrayExtent) { } template requires __is_compatible_array::value constexpr span(const array<_Tp, _ArrayExtent>& __arr) noexcept - : span(static_cast(__arr.data()), _ArrayExtent) + : _M_ptr(__arr.data()), _M_extent(_ArrayExtent) { } template @@ -213,7 +213,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION span(_Range&& __range) noexcept(noexcept(ranges::data(__range)) && noexcept(ranges::size(__range))) - : span(ranges::data(__range), ranges::size(__range)) + : _M_ptr(ranges::data(__range)), _M_extent(ranges::size(__range)) { if constexpr (extent != dynamic_extent) { @@ -231,7 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr explicit(extent != dynamic_extent && _OExtent == dynamic_extent) span(const span<_OType, _OExtent>& __s) noexcept - : _M_extent(__s.size()), _M_ptr(__s.data()) + : _M_ptr(__s.data()), _M_extent(__s.size()) { if constexpr (extent != dynamic_extent) { diff --git a/libstdc++-v3/testsuite/23_containers/span/117966.cc b/libstdc++-v3/testsuite/23_containers/span/117966.cc new file mode 100644 index ..8bbb5ca1e079 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/span/117966.cc @@ -0,0 +1,13 @@ +// { dg-options "-D_GLIBCXX_DEBUG" } +// { dg-do compile { target c++20 } } + +// Bug 117966 +// constexpr std::span construction fails to compile with D_GLIBCXX_DEBUG + +#include +#include + +struct A { + constexpr A(std::span) {} +}; +constexpr A val{std::array{0x11, 0x22}};
[gcc r14-11185] libstdc++: Remove __builtin_expect from consteval assertion
https://gcc.gnu.org/g:cfe866ebfb94499b95107e79f3e910bbe8c4c321 commit r14-11185-gcfe866ebfb94499b95107e79f3e910bbe8c4c321 Author: Jonathan Wakely Date: Wed Nov 27 12:28:30 2024 + libstdc++: Remove __builtin_expect from consteval assertion libstdc++-v3/ChangeLog: * include/bits/c++config (__glibcxx_assert): Remove useless __builtin_expect from constexpr-only assertion. Improve comments. (cherry picked from commit 73e5d2f87c257c2c12ee72fd4de9bdbb6a8e1aa9) Diff: --- libstdc++-v3/include/bits/c++config | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index b57e3f338e92..773a99077e09 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -590,14 +590,17 @@ namespace std #endif #if defined(_GLIBCXX_ASSERTIONS) -// Enable runtime assertion checks, and also check in constant expressions. +// When _GLIBCXX_ASSERTIONS is defined we enable runtime assertion checks. +// These checks will also be done during constant evaluation. # define __glibcxx_assert(cond) \ do { \ if (__builtin_expect(!bool(cond), false)) \ _GLIBCXX_ASSERT_FAIL(cond); \ } while (false) #elif _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED -// Only check assertions during constant evaluation. +// _GLIBCXX_ASSERTIONS is not defined, so assertions checks are only enabled +// during constant evaluation. This ensures we diagnose undefined behaviour +// in constant expressions. namespace std { __attribute__((__always_inline__,__visibility__("default"))) @@ -607,12 +610,12 @@ namespace std } # define __glibcxx_assert(cond) \ do { \ -if (std::__is_constant_evaluated()) \ - if (__builtin_expect(!bool(cond), false)) \ - std::__glibcxx_assert_fail(); \ +if (std::__is_constant_evaluated() && !bool(cond)) \ + std::__glibcxx_assert_fail();\ } while (false) #else -// Don't check any assertions. +// _GLIBCXX_ASSERTIONS is not defined and __is_constant_evaluated() doesn't +// work so don't check any assertions. # define __glibcxx_assert(cond) #endif
[gcc r14-11181] libstdc++: Skip redundant assertions in std::array equality [PR106212]
https://gcc.gnu.org/g:1e696cac2baa35f011f85878e76039fc3945d241 commit r14-11181-g1e696cac2baa35f011f85878e76039fc3945d241 Author: Jonathan Wakely Date: Mon Dec 9 17:35:24 2024 + libstdc++: Skip redundant assertions in std::array equality [PR106212] As PR c++/106212 shows, the Debug Mode checks cause a compilation error for equality comparisons involving std::array prvalues in constant expressions. Those Debug Mode checks are redundant when comparing two std::array objects, because we already know we have a valid range. We can also avoid the unnecessary step of using std::__niter_base to do __normal_iterator unwrapping, which isn't needed because our std::array iterators are just pointers. Using std::__equal_aux1 instead of std::equal avoids the redundant checks in std::equal and std::__equal_aux. libstdc++-v3/ChangeLog: PR libstdc++/106212 * include/std/array (operator==): Use std::__equal_aux1 instead of std::equal. * testsuite/23_containers/array/comparison_operators/106212.cc: New test. (cherry picked from commit 3aeb2edee2f9fc39ab77c7e020f09d7204b167ac) Diff: --- libstdc++-v3/include/std/array| 2 +- .../23_containers/array/comparison_operators/106212.cc| 15 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 8710bf75924b..2e632d0ea864 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -301,7 +301,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline bool operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) -{ return std::equal(__one.begin(), __one.end(), __two.begin()); } +{ return std::__equal_aux1(__one.begin(), __one.end(), __two.begin()); } #if __cpp_lib_three_way_comparison // C++ >= 20 && lib_concepts template diff --git a/libstdc++-v3/testsuite/23_containers/array/comparison_operators/106212.cc b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/106212.cc new file mode 100644 index ..f7b12bd04efd --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/106212.cc @@ -0,0 +1,15 @@ +// { dg-options "-D_GLIBCXX_DEBUG" } +// { dg-do compile { target c++20 } } + +// Bug libstdc++/106212 - Code becomes non-constexpr with _GLIBCXX_DEBUG + +#include + +struct A +{ + constexpr A(int i) : e{i} {} + constexpr bool operator==(const A& a) const = default; + std::array e; +}; + +static_assert(A{1} != A{2}, "");
[gcc r14-11183] libstdc++: Fix debug containers for constant evaluation [PR117962]
https://gcc.gnu.org/g:3590d9f68207861b8973f2812adf02fdba0840ba commit r14-11183-g3590d9f68207861b8973f2812adf02fdba0840ba Author: Jonathan Wakely Date: Mon Dec 9 10:52:10 2024 + libstdc++: Fix debug containers for constant evaluation [PR117962] Using a stateful allocator with std::vector would fail in Debug Mode, because the allocator-extended move constructor tries to swap all the attached safe iterators, but that uses a non-inline function which isn't constexpr. We don't actually need to swap any iterators in constant expressions, because we never attach them to the container in the first place. This bug went unnoticed because the tests for constexpr std::vector were using a stateful allocator with a std::allocator base class, but were failing to override the inherited is_always_equal trait from std::allocator. That meant that the allocators took the always-equal code paths, and didn't try to use the buggy constructor. In C++26 the std::allocator::is_always_equal trait goes away, and so the tests changed behaviour, revealing the bug. libstdc++-v3/ChangeLog: PR libstdc++/117962 * include/debug/safe_container.h: Make allocator-extended move constructor a no-op during constant evaluation. (cherry picked from commit 6fbe9e65645f54cc564a928bc0bc69c8b421cb98) Diff: --- libstdc++-v3/include/debug/safe_container.h | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/debug/safe_container.h b/libstdc++-v3/include/debug/safe_container.h index 9a6c4f7ba743..75c6834bfaec 100644 --- a/libstdc++-v3/include/debug/safe_container.h +++ b/libstdc++-v3/include/debug/safe_container.h @@ -64,10 +64,13 @@ namespace __gnu_debug _Safe_container(_Safe_container&& __x, const _Alloc& __a, std::false_type) : _Safe_container() { - if (__x._M_cont().get_allocator() == __a) - _Base::_M_swap(__x); - else if (!std::__is_constant_evaluated()) - __x._M_invalidate_all(); + if (!std::__is_constant_evaluated()) + { + if (__x._M_cont().get_allocator() == __a) + _Base::_M_swap(__x); + else + __x._M_invalidate_all(); + } } protected:
[gcc r14-11182] libstdc++: Disable __gnu_debug::__is_singular(T*) in constexpr [PR109517]
https://gcc.gnu.org/g:845a0b71c82ad8f1d9967a6f15d10ef402f7f2e5 commit r14-11182-g845a0b71c82ad8f1d9967a6f15d10ef402f7f2e5 Author: Jonathan Wakely Date: Tue Dec 10 10:56:41 2024 + libstdc++: Disable __gnu_debug::__is_singular(T*) in constexpr [PR109517] Because of PR c++/85944 we have several bugs where _GLIBCXX_DEBUG causes errors for constexpr code. Although Bug 117966 could be fixed by avoiding redundant debug checks in std::span, and Bug 106212 could be fixed by avoiding redundant debug checks in std::array, there are many more cases where similar __glibcxx_requires_valid_range checks fail to compile and removing the checks everywhere isn't desirable. This just disables the __gnu_debug::__check_singular(T*) check during constant evaluation. Attempting to dereference a null pointer will certainly fail during constant evaluation (if it doesn't fail then it's a compiler bug and not the library's problem). Disabling this check during constant evaluation shouldn't do any harm. libstdc++-v3/ChangeLog: PR libstdc++/109517 PR libstdc++/109976 * include/debug/helper_functions.h (__valid_range_aux): Treat all input iterator ranges as valid during constant evaluation. (cherry picked from commit 9616deb23a17ebe81ad89ede191d7f9f752abdec) Diff: --- libstdc++-v3/include/debug/helper_functions.h | 5 + 1 file changed, 5 insertions(+) diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h index 5474399dc67a..d44e2712699b 100644 --- a/libstdc++-v3/include/debug/helper_functions.h +++ b/libstdc++-v3/include/debug/helper_functions.h @@ -169,6 +169,11 @@ namespace __gnu_debug __valid_range_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { + // FIXME: The checks for singular iterators fail during constant eval + // due to PR c++/85944. e.g. PR libstdc++/109517 and PR libstdc++/109976. + if (std::__is_constant_evaluated()) + return true; + return __first == __last || (!__gnu_debug::__check_singular(__first) && !__gnu_debug::__check_singular(__last));
[gcc r14-11177] c++: constexpr potentiality of CAST_EXPR [PR117925]
https://gcc.gnu.org/g:70cea067dd2b101edc6b3710678529eb8ba2eec2 commit r14-11177-g70cea067dd2b101edc6b3710678529eb8ba2eec2 Author: Patrick Palka Date: Thu Jan 9 10:50:12 2025 -0500 c++: constexpr potentiality of CAST_EXPR [PR117925] We're incorrectly treating the templated callee (FnPtr)fnPtr, represented as CAST_EXPR with TREE_LIST operand, as potentially constant here due to neglecting to look through the TREE_LIST in the CAST_EXPR case of p_c_e_1. PR c++/117925 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) : Fix check for class conversion to literal type to properly look through the TREE_LIST operand of a CAST_EXPR. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent35.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 76d1061237b5cd57a274cd8bc8fe02a6f407baa9) Diff: --- gcc/cp/constexpr.cc | 11 --- gcc/testsuite/g++.dg/template/non-dependent35.C | 8 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 6025b4c29437..79dd6a7423c0 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -10279,9 +10279,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, && (dependent_type_p (TREE_TYPE (t)) || !COMPLETE_TYPE_P (TREE_TYPE (t)) || literal_type_p (TREE_TYPE (t))) - && TREE_OPERAND (t, 0)) - { - tree type = TREE_TYPE (TREE_OPERAND (t, 0)); + && TREE_OPERAND (t, 0) + && (TREE_CODE (t) != CAST_EXPR + || !TREE_CHAIN (TREE_OPERAND (t, 0 + { + tree from = TREE_OPERAND (t, 0); + if (TREE_CODE (t) == CAST_EXPR) + from = TREE_VALUE (from); + tree type = TREE_TYPE (from); /* If this is a dependent type, it could end up being a class with conversions. */ if (type == NULL_TREE || WILDCARD_TYPE_P (type)) diff --git a/gcc/testsuite/g++.dg/template/non-dependent35.C b/gcc/testsuite/g++.dg/template/non-dependent35.C new file mode 100644 index ..7e3ba99b0235 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent35.C @@ -0,0 +1,8 @@ +// PR c++/117925 + +typedef int(*FnPtr)(); + +template +void fnICE(void* fnPtr) { + ((FnPtr)fnPtr)(); +}
[gcc r14-11173] libstdc++: Implement LWG 3563 changes to keys_view and values_view
https://gcc.gnu.org/g:03d0440d73a37e65311b504f62e76f5bcf237795 commit r14-11173-g03d0440d73a37e65311b504f62e76f5bcf237795 Author: Patrick Palka Date: Thu Nov 14 13:27:41 2024 -0500 libstdc++: Implement LWG 3563 changes to keys_view and values_view This LWG issue corrects the definition of these alias templates to make them suitable for alias CTAD. libstdc++-v3/ChangeLog: * include/std/ranges (keys_view): Adjust as per LWG 3563. (values_view): Likewise. * testsuite/std/ranges/adaptors/elements.cc (test08): New test. Reviewed-by: Jonathan Wakely (cherry picked from commit 361050589b144913ec05d9d8e10639afa98319a8) Diff: --- libstdc++-v3/include/std/ranges| 6 -- libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc | 14 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 36e36569afca..eba539176848 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -4547,11 +4547,13 @@ namespace views::__adaptor inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Tp>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3563. keys_view example is broken template -using keys_view = elements_view, 0>; +using keys_view = elements_view<_Range, 0>; template -using values_view = elements_view, 1>; +using values_view = elements_view<_Range, 1>; namespace views { diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc index a15192bf0ecf..0a05ce7378f9 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc @@ -148,6 +148,19 @@ test07() b == e; } +void +test08() +{ + // LWG 3563 - keys_view example is broken + std::pair x[] = {{1,2},{3,4}}; + auto v = ranges::keys_view{views::all(x)}; + auto w = ranges::values_view{views::all(x)}; + using ty1 = decltype(v); + using ty1 = ranges::elements_view, 0>; + using ty2 = decltype(w); + using ty2 = ranges::elements_view, 1>; +} + int main() { @@ -158,4 +171,5 @@ main() test05(); test06(); test07(); + test08(); }
[gcc r14-11174] libstdc++: Avoid unnecessary copies in ranges::min/max [PR112349]
https://gcc.gnu.org/g:f236c897af48c3ae52095a894d57e66065b8ad87 commit r14-11174-gf236c897af48c3ae52095a894d57e66065b8ad87 Author: Patrick Palka Date: Fri Dec 13 13:17:29 2024 -0500 libstdc++: Avoid unnecessary copies in ranges::min/max [PR112349] Use a local reference for the (now possibly lifetime extended) result of *__first so that we copy it only when necessary. PR libstdc++/112349 libstdc++-v3/ChangeLog: * include/bits/ranges_algo.h (__min_fn::operator()): Turn local object __tmp into a reference. * include/bits/ranges_util.h (__max_fn::operator()): Likewise. * testsuite/25_algorithms/max/constrained.cc (test04): New test. * testsuite/25_algorithms/min/constrained.cc (test04): New test. Reviewed-by: Jonathan Wakely (cherry picked from commit b8314ebff2495ee22f9e2203093bdada9843a0f5) Diff: --- libstdc++-v3/include/bits/ranges_algo.h| 4 ++-- libstdc++-v3/include/bits/ranges_util.h| 4 ++-- .../testsuite/25_algorithms/max/constrained.cc | 25 ++ .../testsuite/25_algorithms/min/constrained.cc | 25 ++ 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 6347ec98606a..a29d387dc711 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -2909,11 +2909,11 @@ namespace ranges auto __result = *__first; while (++__first != __last) { - auto __tmp = *__first; + auto&& __tmp = *__first; if (std::__invoke(__comp, std::__invoke(__proj, __result), std::__invoke(__proj, __tmp))) - __result = std::move(__tmp); + __result = std::forward(__tmp); } return __result; } diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index 34d8b1e8f143..aba5b6a88c0c 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -733,11 +733,11 @@ namespace ranges auto __result = *__first; while (++__first != __last) { - auto __tmp = *__first; + auto&& __tmp = *__first; if (std::__invoke(__comp, std::__invoke(__proj, __tmp), std::__invoke(__proj, __result))) - __result = std::move(__tmp); + __result = std::forward(__tmp); } return __result; } diff --git a/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc index e7269e1b734a..ad2d47f2f101 100644 --- a/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc @@ -73,10 +73,35 @@ test03() VERIFY( ranges::max({2,3,1,4}, ranges::greater{}, std::negate<>{}) == 4 ); } +void +test04() +{ + // PR libstdc++/112349 - ranges::max/min make unnecessary copies + static int copies, moves; + struct A { +A(int m) : m(m) { } +A(const A& other) : m(other.m) { ++copies; } +A(A&& other) : m(other.m) { ++moves; } +A& operator=(const A& other) { m = other.m; ++copies; return *this; } +A& operator=(A&& other) { m = other.m; ++moves; return *this; } +int m; + }; + A r[5] = {5, 4, 3, 2, 1}; + ranges::max(r, ranges::less{}, &A::m); + VERIFY( copies == 1 ); + VERIFY( moves == 0 ); + copies = moves = 0; + A s[5] = {1, 2, 3, 4, 5}; + ranges::max(s, ranges::less{}, &A::m); + VERIFY( copies == 5 ); + VERIFY( moves == 0 ); +} + int main() { test01(); test02(); test03(); + test04(); } diff --git a/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc index 7198df69adf7..17048fda6394 100644 --- a/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc @@ -73,10 +73,35 @@ test03() VERIFY( ranges::min({2,3,1,4}, ranges::greater{}, std::negate<>{}) == 1 ); } +void +test04() +{ + // PR libstdc++/112349 - ranges::max/min make unnecessary copies + static int copies, moves; + struct A { +A(int m) : m(m) { } +A(const A& other) : m(other.m) { ++copies; } +A(A&& other) : m(other.m) { ++moves; } +A& operator=(const A& other) { m = other.m; ++copies; return *this; } +A& operator=(A&& other) { m = other.m; ++moves; return *this; } +int m; + }; + A r[5] = {5, 4, 3, 2, 1}; + ranges::min(r, ranges::less{}, &A::m); + VERIFY( copies == 5 ); + VERIFY( moves == 0 ); + copies = moves = 0; + A s[5] = {1, 2, 3, 4, 5}; + ranges::min(s, ranges::less{}, &A::m); + VERIFY( copies == 1 ); + VERIFY( moves == 0 ); +} + int main() { test01(); test02();
[gcc r14-11172] libstdc++: Fix complexity of drop_view::begin() const [PR112641]
https://gcc.gnu.org/g:9d650c29562bbb18c1ea5d0064e07f48c177912b commit r14-11172-g9d650c29562bbb18c1ea5d0064e07f48c177912b Author: Patrick Palka Date: Tue Oct 29 09:26:19 2024 -0400 libstdc++: Fix complexity of drop_view::begin() const [PR112641] Views are required to have a amortized O(1) begin(), but our drop_view's const begin overload is O(n) for non-common ranges with a non-sized sentinel. This patch reimplements it so that it's O(1) always. See also LWG 4009. PR libstdc++/112641 libstdc++-v3/ChangeLog: * include/std/ranges (drop_view::begin): Reimplement const overload so that it's O(1) always. * testsuite/std/ranges/adaptors/drop.cc (test10): New test. Reviewed-by: Jonathan Wakely (cherry picked from commit 7f622ee83fbbcf4a4ca70e020db8a0ce4b556b61) Diff: --- libstdc++-v3/include/std/ranges| 4 ++-- libstdc++-v3/testsuite/std/ranges/adaptors/drop.cc | 12 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 44c6d2ff11e9..36e36569afca 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -2660,8 +2660,8 @@ namespace views::__adaptor begin() const requires random_access_range && sized_range { - return ranges::next(ranges::begin(_M_base), _M_count, - ranges::end(_M_base)); + return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base), + _M_count); } constexpr auto diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/drop.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/drop.cc index c9987c61e3c1..0bd5bebb785d 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/drop.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/drop.cc @@ -274,6 +274,17 @@ test09() static_assert(!requires { views::all | drop; }); } +constexpr bool +test10() +{ + // PR libstdc++/112641 - drop_view::begin const may have O(n) complexity + const auto s = ranges::subrange(views::iota(size_t(1)), size_t(-1)); + const auto r = ranges::drop_view(s, s.size() - 1); + const auto b = r.begin(); // time out + VERIFY( *b == size_t(-1) ); + return true; +} + int main() { @@ -286,4 +297,5 @@ main() test07(); test08(); test09(); + static_assert(test10()); }
[gcc r14-11178] c++: ICE during requires-expr partial subst [PR118060]
https://gcc.gnu.org/g:f73ecaf1957d35a9990735ebe228c8dd6188 commit r14-11178-gf73ecaf1957d35a9990735ebe228c8dd6188 Author: Patrick Palka Date: Thu Jan 9 10:50:19 2025 -0500 c++: ICE during requires-expr partial subst [PR118060] Here during partial substitution of the requires-expression (as part of CTAD constraint rewriting) we segfault from the INDIRECT_REF case of convert_to_void due *f(u) being type-dependent. We should just defer checking convert_to_void until satisfaction. PR c++/118060 gcc/cp/ChangeLog: * constraint.cc (tsubst_valid_expression_requirement): Don't check convert_to_void during partial substitution. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-requires40.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit ca79349c050c27ff466735ba78d2e2bbce56ffdc) Diff: --- gcc/cp/constraint.cc | 4 +++- gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C | 12 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index b6c6a5e23306..cbf6357ad681 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1993,7 +1993,9 @@ tsubst_valid_expression_requirement (tree t, tree args, sat_info info) { tsubst_flags_t quiet = info.complain & ~tf_warning_or_error; tree r = tsubst_expr (t, args, quiet, info.in_decl); - if (convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node) + if (r != error_mark_node + && (processing_template_decl + || convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node)) return r; if (info.diagnose_unsatisfaction_p ()) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C new file mode 100644 index ..918bab410f30 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C @@ -0,0 +1,12 @@ +// PR c++/118060 +// { dg-do compile { target c++20 } } + +int* f(int); + +template +struct A { + template requires requires (U u) { *f(u); } + A(T, U); +}; + +A a{0, 0};
[gcc r14-11179] libstdc++: Fix std::deque::insert(pos, first, last) undefined behaviour [PR118035]
https://gcc.gnu.org/g:67c457de5a3f74151fc2d0085387127bf9e4e3c5 commit r14-11179-g67c457de5a3f74151fc2d0085387127bf9e4e3c5 Author: Jonathan Wakely Date: Mon Dec 16 17:42:24 2024 + libstdc++: Fix std::deque::insert(pos, first, last) undefined behaviour [PR118035] Inserting an empty range into a std::deque results in undefined calls to either std::copy, std::copy_backward, std::move, or std::move_backward. We call those algos with invalid arguments where the output range is the same as the input range, e.g. std::copy(first, last, first) which violates the preconditions for the algorithms. This fix simply returns early if there's nothing to insert. Most callers already ensure that we don't even call _M_range_insert_aux with an empty range, but some callers don't. Rather than checking for n == 0 in each of the callers, this just does the check once and uses __builtin_expect to treat empty insertions as unlikely. libstdc++-v3/ChangeLog: PR libstdc++/118035 * include/bits/deque.tcc (_M_range_insert_aux): Return immediately if inserting an empty range. * testsuite/23_containers/deque/modifiers/insert/118035.cc: New test. (cherry picked from commit b273e25e11c842a5729d0e03c85088cf5ba8e06c) Diff: --- libstdc++-v3/include/bits/deque.tcc| 3 +++ .../23_containers/deque/modifiers/insert/118035.cc | 26 ++ 2 files changed, 29 insertions(+) diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index 2c12358ca5bf..e50f5dc9d093 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -601,6 +601,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); + if (__builtin_expect(__n == 0, 0)) + return; + if (__pos._M_cur == this->_M_impl._M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/insert/118035.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/insert/118035.cc new file mode 100644 index ..a37d3dc3d04c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/insert/118035.cc @@ -0,0 +1,26 @@ +// { dg-do run } + +#include +#include + +struct Sparks +{ + Sparks& operator=(const Sparks& s) + { +VERIFY( this != &s ); // This town ain't big enough for the both of us. +return *this; + } +}; + +void +test_pr118035() +{ + std::deque d(3, Sparks()); + Sparks s[1]; + d.insert(d.begin() + 1, s, s); +} + +int main() +{ + test_pr118035(); +}
[gcc r14-11187] libstdc++: Fix some typos and grammatical errors in docs
https://gcc.gnu.org/g:2f20d092fcf6d84128451278e7c3d53ff1671131 commit r14-11187-g2f20d092fcf6d84128451278e7c3d53ff1671131 Author: Jonathan Wakely Date: Wed Oct 30 21:10:58 2024 + libstdc++: Fix some typos and grammatical errors in docs Also remove some redundant 'void' parameters from code examples. libstdc++-v3/ChangeLog: * doc/xml/manual/using_exceptions.xml: Fix typos and grammatical errors. * doc/html/manual/using_exceptions.html: Regenerate. (cherry picked from commit 96566cc46d633c2026976e585b5743e880a8f99b) Diff: --- libstdc++-v3/doc/html/manual/using_exceptions.html | 12 ++-- libstdc++-v3/doc/xml/manual/using_exceptions.xml | 12 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libstdc++-v3/doc/html/manual/using_exceptions.html b/libstdc++-v3/doc/html/manual/using_exceptions.html index 706b27e14793..eb4501b1f6ba 100644 --- a/libstdc++-v3/doc/html/manual/using_exceptions.html +++ b/libstdc++-v3/doc/html/manual/using_exceptions.html @@ -158,7 +158,7 @@ exception neutrality and exception safety. Doing without C++ is a language that strives to be as efficient as is possible in delivering features. As such, considerable care is used by both -language implementer and designers to make sure unused features +language implementer and designers to make sure unused features do not impose hidden or unexpected costs. The GNU system tries to be as flexible and as configurable as possible. So, it should come as no surprise that GNU C++ provides an optional language extension, @@ -166,7 +166,7 @@ exception neutrality and exception safety. implicitly generated magic necessary to support try and catch blocks and thrown objects. (Language support -for -fno-exceptions is documented in the GCC +for -fno-exceptions is documented in the GCC https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options"; target="_top">manual.) Before detailing the library support for -fno-exceptions, first a passing note on @@ -179,7 +179,7 @@ exception neutrality and exception safety. uses try or catch, you shouldn't use -fno-exceptions. -And what it to be gained, tinkering in the back alleys with a +And what is to be gained, tinkering in the back alleys with a language like this? Exception handling overhead can be measured in the size of the executable binary, and varies with the capabilities of the underlying operating system and specific @@ -216,15 +216,15 @@ exception neutrality and exception safety. # define __throw_exception_again #endif - In addition, for every object derived from + In addition, for most of the classes derived from class exception, there exists a corresponding function with C language linkage. An example: #if __cpp_exceptions - void __throw_bad_exception(void) + void __throw_bad_exception() { throw bad_exception(); } #else - void __throw_bad_exception(void) + void __throw_bad_exception() { abort(); } #endif diff --git a/libstdc++-v3/doc/xml/manual/using_exceptions.xml b/libstdc++-v3/doc/xml/manual/using_exceptions.xml index ab42c8099399..ac2ba9dffd45 100644 --- a/libstdc++-v3/doc/xml/manual/using_exceptions.xml +++ b/libstdc++-v3/doc/xml/manual/using_exceptions.xml @@ -274,7 +274,7 @@ exception neutrality and exception safety. C++ is a language that strives to be as efficient as is possible in delivering features. As such, considerable care is used by both -language implementer and designers to make sure unused features +language implementer and designers to make sure unused features do not impose hidden or unexpected costs. The GNU system tries to be as flexible and as configurable as possible. So, it should come as no surprise that GNU C++ provides an optional language extension, @@ -282,7 +282,7 @@ exception neutrality and exception safety. implicitly generated magic necessary to support try and catch blocks and thrown objects. (Language support -for -fno-exceptions is documented in the GCC +for -fno-exceptions is documented in the GCC http://www.w3.org/1999/xlink"; xlink:href="https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options";>manual.) @@ -299,7 +299,7 @@ exception neutrality and exception safety. -And what it to be gained, tinkering in the back alleys with a +And what is to be gained, tinkering in the back alleys with a language like this? Exception handling overhead can be measured in the size of the executable binary, and varies with the capabilities of the underlying operating system and specific @@ -344,17 +344,17 @@ exception neutrality and exception safety. - In addition, for every object derived from + In addition, for most of the classes derived from class exception, there exists a correspo
[gcc r14-11189] libstdc++: Fix typo in comment in src/c++17/fs_dir.cc
https://gcc.gnu.org/g:d05d583f80ce3595e417955019d434690295b332 commit r14-11189-gd05d583f80ce3595e417955019d434690295b332 Author: Jonathan Wakely Date: Thu Dec 12 20:38:54 2024 + libstdc++: Fix typo in comment in src/c++17/fs_dir.cc libstdc++-v3/ChangeLog: * src/c++17/fs_dir.cc: Fix typo in comment. (cherry picked from commit 93069606949f45cb5f60bc7f4efc4860c23c8e1c) Diff: --- libstdc++-v3/src/c++17/fs_dir.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc index 28d27f6a9fa1..fa0f7281f369 100644 --- a/libstdc++-v3/src/c++17/fs_dir.cc +++ b/libstdc++-v3/src/c++17/fs_dir.cc @@ -479,7 +479,7 @@ fs::recursive_directory_iterator::__erase(error_code* ecptr) #if _GLIBCXX_FILESYSTEM_IS_WINDOWS // _Dir::unlink uses fs::remove which uses std::system_category() for - // Windows errror codes, so we can't just check for EPERM and EISDIR. + // Windows error codes, so we can't just check for EPERM and EISDIR. // Use directory_entry::refresh() here to check if we have a directory. // This can be a TOCTTOU race, but we don't have openat or unlinkat to // solve that on Windows, and generally don't support symlinks anyway.
[gcc r14-11188] libstdc++: Make std::println use locale from ostream (LWG 4088)
https://gcc.gnu.org/g:0cdd4c97c40331eadbd3e0e08c3c6f122c765c87 commit r14-11188-g0cdd4c97c40331eadbd3e0e08c3c6f122c765c87 Author: Jonathan Wakely Date: Wed Dec 11 09:37:48 2024 + libstdc++: Make std::println use locale from ostream (LWG 4088) This was just approved in Wrocław. libstdc++-v3/ChangeLog: * include/std/ostream (println): Pass stream's locale to std::format, as per LWG 4088. * testsuite/27_io/basic_ostream/print/1.cc: Check std::println with custom locale. Remove unused brit_punc class. (cherry picked from commit 1fd7e36e990396c22823cedd068def2aa3b112ce) Diff: --- libstdc++-v3/include/std/ostream | 6 -- libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc | 18 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 12be6c4fd178..cb5675fe1bda 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -992,8 +992,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline void println(ostream& __os, format_string<_Args...> __fmt, _Args&&... __args) { - std::print(__os, "{}\n", -std::format(__fmt, std::forward<_Args>(__args)...)); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4088. println ignores the locale imbued in std::ostream + std::print(__os, "{}\n", std::format(__os.getloc(), __fmt, + std::forward<_Args>(__args)...)); } // Defined for C++26, supported as an extension to C++23. diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc index cd4b116ac1c0..183e08733d23 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc @@ -63,14 +63,6 @@ test_vprint_nonunicode() // { dg-output "garbage in . garbage out" } } -struct brit_punc : std::numpunct -{ - std::string do_grouping() const override { return "\3\3"; } - char do_thousands_sep() const override { return ','; } - std::string do_truename() const override { return "yes mate"; } - std::string do_falsename() const override { return "nah bruv"; } -}; - void test_locale() { @@ -82,7 +74,7 @@ test_locale() // The default C locale. std::locale cloc = std::locale::classic(); - // A custom locale using comma digit separators. + // A custom locale using tilde digit separators. std::locale bloc(cloc, new stream_punc); { @@ -101,6 +93,14 @@ test_locale() std::print(os, "{:L} {}", 12345, 6789); VERIFY(os.str() == "1~23~45 6789"); } + + { +// LWG 4088. println ignores the locale imbued in std::ostream +std::ostringstream os; +os.imbue(bloc); +std::println(os, "{:L} {}", 12345, 6789); +VERIFY(os.str() == "1~23~45 6789\n"); + } } void
[gcc r14-11186] libstdc++: Document when std::string::shrink_to_fit was added
https://gcc.gnu.org/g:b84070e7bdf1e3666953d008f30f2b7472d9174c commit r14-11186-gb84070e7bdf1e3666953d008f30f2b7472d9174c Author: Jonathan Wakely Date: Tue May 14 14:28:21 2024 +0100 libstdc++: Document when std::string::shrink_to_fit was added This section can be misread to say that shrink_to_fit is available from GCC 3.4, but it was added later. libstdc++-v3/ChangeLog: * doc/xml/manual/strings.xml: Clarify that GCC 4.5 added std::string::shrink_to_fit. * doc/html/manual/strings.html: Regenerate. (cherry picked from commit 0a99ad5c52caa06c113b1889bbe6634812b89be5) Diff: --- libstdc++-v3/doc/html/manual/strings.html | 4 ++-- libstdc++-v3/doc/xml/manual/strings.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/doc/html/manual/strings.html b/libstdc++-v3/doc/html/manual/strings.html index ceb09f97eac4..34a34dfa980c 100644 --- a/libstdc++-v3/doc/html/manual/strings.html +++ b/libstdc++-v3/doc/html/manual/strings.html @@ -269,8 +269,8 @@ stringtok(Container &container, string const &in, (see this FAQ entry) but the regular copy constructor cannot be used because libstdc++'s string is Copy-On-Write in GCC 3. - In C++11 mode you can call - s.shrink_to_fit() to achieve the same effect as + From GCC 4.5 in C++11 mode you + can call s.shrink_to_fit() to achieve the same effect as s.reserve(s.size()). CString (MFC) A common lament seen in various newsgroups deals with the Standard diff --git a/libstdc++-v3/doc/xml/manual/strings.xml b/libstdc++-v3/doc/xml/manual/strings.xml index b0dab645a2d9..4a63dd964771 100644 --- a/libstdc++-v3/doc/xml/manual/strings.xml +++ b/libstdc++-v3/doc/xml/manual/strings.xml @@ -356,8 +356,8 @@ stringtok(Container &container, string const &in, entry) but the regular copy constructor cannot be used because libstdc++'s string is Copy-On-Write in GCC 3. - In C++11 mode you can call - s.shrink_to_fit() to achieve the same effect as + From GCC 4.5 in C++11 mode you + can call s.shrink_to_fit() to achieve the same effect as s.reserve(s.size()).
[gcc r14-11190] libstdc++: Give std::memory_order a fixed underlying type [PR89624]
https://gcc.gnu.org/g:72fe42c9a095ef9b4125bd65999cd1012dfb73b7 commit r14-11190-g72fe42c9a095ef9b4125bd65999cd1012dfb73b7 Author: Jonathan Wakely Date: Thu Apr 11 19:12:48 2024 +0100 libstdc++: Give std::memory_order a fixed underlying type [PR89624] Prior to C++20 this enum type doesn't have a fixed underlying type, which means it can be modified by -fshort-enums, which then means the HLE bits are outside the range of valid values for the type. As it has a fixed type of int in C++20 and later, do the same for earlier standards too. This is technically a change for C++17 down, because the implicit underlying type (without -fshort-enums) was unsigned before. I doubt it matters in practice. That incompatibility already exists between C++17 and C++20 and nobody has noticed or complained. Now at least the underlying type will be int for all -std modes. libstdc++-v3/ChangeLog: PR libstdc++/89624 * include/bits/atomic_base.h (memory_order): Use int as underlying type. * testsuite/29_atomics/atomic/89624.cc: New test. (cherry picked from commit 99dd1be14172445795f0012b935359e7014a2215) Diff: --- libstdc++-v3/include/bits/atomic_base.h | 4 ++-- libstdc++-v3/testsuite/29_atomics/atomic/89624.cc | 9 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index 3a23c7881cdf..20901b7fc06f 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -78,7 +78,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel; inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst; #else - typedef enum memory_order + enum memory_order : int { memory_order_relaxed, memory_order_consume, @@ -86,7 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION memory_order_release, memory_order_acq_rel, memory_order_seq_cst -} memory_order; +}; #endif /// @cond undocumented diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc b/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc new file mode 100644 index ..480f7c65e2d7 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc @@ -0,0 +1,9 @@ +// { dg-options "-fshort-enums" } +// { dg-do compile { target c++11 } } + +// Bug 89624 HLE bits don't work with -fshort-enums or -fstrict-enums + +#include + +static_assert((std::memory_order_acquire | std::__memory_order_hle_acquire) +!= std::memory_order_acquire, "HLE acquire sets a bit");
[gcc r14-11193] libstdc++: Use feature test macro for pmr::polymorphic_allocator<>
https://gcc.gnu.org/g:a4c0f16f048b64c1ab3b2521e3a1595afc64462b commit r14-11193-ga4c0f16f048b64c1ab3b2521e3a1595afc64462b Author: Jonathan Wakely Date: Tue Dec 10 14:35:07 2024 + libstdc++: Use feature test macro for pmr::polymorphic_allocator<> Check the __glibcxx_polymorphic_allocator macro instead of just checking whether __cplusplus > 201703L. libstdc++-v3/ChangeLog: * include/bits/memory_resource.h (polymoprhic_allocator): Use feature test macro for P0339R6 features. (cherry picked from commit b26d92f4f71594206385d6f645ff626c0bf9b59c) Diff: --- libstdc++-v3/include/bits/memory_resource.h | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/memory_resource.h b/libstdc++-v3/include/bits/memory_resource.h index db515fb30ef9..9bfeaedf078d 100644 --- a/libstdc++-v3/include/bits/memory_resource.h +++ b/libstdc++-v3/include/bits/memory_resource.h @@ -168,7 +168,7 @@ namespace pmr __attribute__((__nonnull__)) { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); } -#if __cplusplus > 201703L +#ifdef __glibcxx_polymorphic_allocator // >= C++20 [[nodiscard]] void* allocate_bytes(size_t __nbytes, size_t __alignment = alignof(max_align_t)) @@ -218,9 +218,9 @@ namespace pmr __p->~_Up(); deallocate_object(__p); } -#endif // C++2a +#endif // C++20 -#if ! __glibcxx_make_obj_using_allocator +#if ! __glibcxx_make_obj_using_allocator // >= C++20 template __attribute__((__nonnull__)) typename __not_pair<_Tp1>::type @@ -336,7 +336,7 @@ namespace pmr #endif private: -#if ! __glibcxx_make_obj_using_allocator +#if ! __glibcxx_make_obj_using_allocator // >= C++20 using __uses_alloc1_ = __uses_alloc1; using __uses_alloc2_ = __uses_alloc2;
[gcc r14-11192] libstdc++: Improve Doxygen docs for std::allocator_traits specializations
https://gcc.gnu.org/g:e6d2bcf74235ec8760136b2d7364ec472954b65b commit r14-11192-ge6d2bcf74235ec8760136b2d7364ec472954b65b Author: Jonathan Wakely Date: Fri Aug 23 21:54:21 2024 +0100 libstdc++: Improve Doxygen docs for std::allocator_traits specializations The main fix here is to use @header so that the docs show the correct header file instead of an internal header like alloc_traits.h. libstdc++-v3/ChangeLog: * include/bits/alloc_traits.h: Improve doxygen docs for allocator_traits specializations. * include/bits/memory_resource.h: Likewise. (cherry picked from commit cd8e0ea7273425931a0843f4355ad61e177e1bf2) Diff: --- libstdc++-v3/include/bits/alloc_traits.h| 16 ++-- libstdc++-v3/include/bits/memory_resource.h | 9 +++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index a81b286eee70..9d55a1912885 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -450,7 +450,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #pragma GCC diagnostic pop #if _GLIBCXX_HOSTED - /// Partial specialization for std::allocator. + /** + * @brief Partial specialization for `std::allocator` + * @headerfile memory + * @ingroup allocators + * @since C++11 + * @see std::allocator_traits + */ template struct allocator_traits> { @@ -621,7 +627,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __rhs; } }; - /// Explicit specialization for std::allocator. + /** + * @brief Explicit specialization for `std::allocator` + * @headerfile memory + * @ingroup allocators + * @since C++11 + * @see std::allocator_traits + */ template<> struct allocator_traits> { diff --git a/libstdc++-v3/include/bits/memory_resource.h b/libstdc++-v3/include/bits/memory_resource.h index 5f50b296df7b..db515fb30ef9 100644 --- a/libstdc++-v3/include/bits/memory_resource.h +++ b/libstdc++-v3/include/bits/memory_resource.h @@ -52,7 +52,7 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace pmr { - /// Class memory_resource + /// Class `memory_resource` /** * @ingroup pmr * @headerfile memory_resource @@ -385,7 +385,12 @@ namespace pmr template struct allocator_traits; - /// Partial specialization for std::pmr::polymorphic_allocator + /// Partial specialization for `std::pmr::polymorphic_allocator` + /** + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ template struct allocator_traits> {
[gcc r14-11191] libstdc++: Undeprecate std::pmr::polymorphic_allocator::destroy (P2875R4)
https://gcc.gnu.org/g:734d7dae428a17647d49ed2734ccc1d7d9c9a3b5 commit r14-11191-g734d7dae428a17647d49ed2734ccc1d7d9c9a3b5 Author: Jonathan Wakely Date: Tue Jun 18 16:09:08 2024 +0100 libstdc++: Undeprecate std::pmr::polymorphic_allocator::destroy (P2875R4) This member function was previously deprecated, but that was reverted by P2875R4, approved earlier this year in Tokyo. Since it's not going to be deprecated in C++26, and so presumably not removed, there is no point in giving deprecated warnings for C++23 mode. libstdc++-v3/ChangeLog: * include/bits/memory_resource.h (polymorphic_allocator::destroy): Remove deprecated attribute. (cherry picked from commit c3e237338eb7ffc90f3cc8d32a3971d17f6d0b31) Diff: --- libstdc++-v3/include/bits/memory_resource.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libstdc++-v3/include/bits/memory_resource.h b/libstdc++-v3/include/bits/memory_resource.h index 022371245c15..5f50b296df7b 100644 --- a/libstdc++-v3/include/bits/memory_resource.h +++ b/libstdc++-v3/include/bits/memory_resource.h @@ -305,7 +305,6 @@ namespace pmr #endif template - _GLIBCXX20_DEPRECATED_SUGGEST("allocator_traits::destroy") __attribute__((__nonnull__)) void destroy(_Up* __p)
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Introduction gfc_copy_sequence_descriptor
https://gcc.gnu.org/g:f90f6f2d65980c675903c9d931b3312a89e5f269 commit f90f6f2d65980c675903c9d931b3312a89e5f269 Author: Mikael Morin Date: Tue Dec 31 15:27:35 2024 +0100 Introduction gfc_copy_sequence_descriptor Diff: --- gcc/fortran/trans-array.cc | 26 +- gcc/fortran/trans-expr.cc | 43 +++ gcc/fortran/trans.h| 1 + 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 4c237b561aa6..d42575c38485 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -9902,31 +9902,7 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, conv_shift_descriptor (&block, se->expr, expr->rank); tmp = gfc_class_data_get (ctree); - if (expr->rank > 1 && CLASS_DATA (fsym)->as->rank != expr->rank - && CLASS_DATA (fsym)->as->type == AS_EXPLICIT && !no_pack) - { - tree arr = gfc_create_var (TREE_TYPE (tmp), "parm"); - gfc_conv_descriptor_data_set (&block, arr, - gfc_conv_descriptor_data_get ( - se->expr)); - gfc_conv_descriptor_lbound_set (&block, arr, gfc_index_zero_node, - gfc_index_zero_node); - gfc_conv_descriptor_ubound_set ( - &block, arr, gfc_index_zero_node, - gfc_conv_descriptor_size (se->expr, expr->rank)); - gfc_conv_descriptor_stride_set ( - &block, arr, gfc_index_zero_node, - gfc_conv_descriptor_stride_get (se->expr, gfc_index_zero_node)); - gfc_add_modify (&block, gfc_conv_descriptor_dtype (arr), - gfc_conv_descriptor_dtype (se->expr)); - gfc_add_modify (&block, gfc_conv_descriptor_rank (arr), - build_int_cst (signed_char_type_node, 1)); - gfc_conv_descriptor_span_set (&block, arr, - gfc_conv_descriptor_span_get (arr)); - gfc_conv_descriptor_offset_set (&block, arr, gfc_index_zero_node); - se->expr = arr; - } - gfc_class_array_data_assign (&block, tmp, se->expr, true); + gfc_copy_sequence_descriptor (block, tmp, se->expr); /* Handle optional. */ if (fsym && fsym->attr.optional && sym && sym->attr.optional) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 003754cdad6f..09a8fc9dd5dd 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -846,6 +846,49 @@ descriptor_rank (tree descriptor) } +void +gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc) +{ + int lhs_rank = descriptor_rank (lhs_desc); + int rhs_rank = descriptor_rank (rhs_desc); + tree desc; + + if (lhs_rank == rhs_rank) +desc = rhs_desc; + else +{ + tree arr = gfc_create_var (TREE_TYPE (lhs_desc), "parm"); + gfc_conv_descriptor_data_set (&block, arr, + gfc_conv_descriptor_data_get (rhs_desc)); + gfc_conv_descriptor_lbound_set (&block, arr, gfc_index_zero_node, + gfc_index_zero_node); + tree size = gfc_conv_descriptor_size (rhs_desc, rhs_rank); + gfc_conv_descriptor_ubound_set (&block, arr, gfc_index_zero_node, size); + gfc_conv_descriptor_stride_set ( + &block, arr, gfc_index_zero_node, + gfc_conv_descriptor_stride_get (rhs_desc, gfc_index_zero_node)); + for (int i = 1; i < lhs_rank; i++) + { + gfc_conv_descriptor_lbound_set (&block, arr, gfc_rank_cst[i], + gfc_index_zero_node); + gfc_conv_descriptor_ubound_set (&block, arr, gfc_rank_cst[i], + gfc_index_zero_node); + gfc_conv_descriptor_stride_set (&block, arr, gfc_rank_cst[i], size); + } + gfc_add_modify (&block, gfc_conv_descriptor_dtype (arr), + gfc_conv_descriptor_dtype (rhs_desc)); + gfc_add_modify (&block, gfc_conv_descriptor_rank (arr), + build_int_cst (signed_char_type_node, lhs_rank)); + gfc_conv_descriptor_span_set (&block, arr, + gfc_conv_descriptor_span_get (arr)); + gfc_conv_descriptor_offset_set (&block, arr, gfc_index_zero_node); + desc = arr; +} + + gfc_class_array_data_assign (&block, lhs_desc, desc, true); +} + + void gfc_class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc, bool) diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 449d2b3026c0..544cf3fb6497 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -465,6 +465,7 @@ void gfc_finalize_tree_expr (gfc_se *, gfc_symbol *, symbol_attribute, int); bool gfc_assignm
[gcc r15-6751] [PR118017][LRA]: Don't inherit reg of non-uniform reg class
https://gcc.gnu.org/g:fab96de044f1f023f52d43af866205d17d8895fb commit r15-6751-gfab96de044f1f023f52d43af866205d17d8895fb Author: Vladimir N. Makarov Date: Thu Jan 9 16:22:02 2025 -0500 [PR118017][LRA]: Don't inherit reg of non-uniform reg class In the PR case LRA inherited value of register of class INT_SSE_REGS which resulted in LRA cycling when LRA tried to use different move alternatives with SSE/general regs and memory. The patch rejects to inherit such (non-uniform) classes to prevent cycling. gcc/ChangeLog: PR target/118017 * lra-constraints.cc (inherit_reload_reg): Check reg class on uniformity. gcc/testsuite/ChangeLog: PR target/118017 * gcc.target/i386/pr118017.c: New. Diff: --- gcc/lra-constraints.cc | 14 ++ gcc/testsuite/gcc.target/i386/pr118017.c | 21 + 2 files changed, 35 insertions(+) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index a0f05b290dde..8f32e98f1c47 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -5878,6 +5878,20 @@ inherit_reload_reg (bool def_p, int original_regno, } return false; } + if (ira_reg_class_min_nregs[rclass][GET_MODE (original_reg)] + != ira_reg_class_max_nregs[rclass][GET_MODE (original_reg)]) +{ + if (lra_dump_file != NULL) + { + fprintf (lra_dump_file, + "Rejecting inheritance for %d " + "because of requiring non-uniform class %s\n", + original_regno, reg_class_names[rclass]); + fprintf (lra_dump_file, + ">>\n"); + } + return false; +} new_reg = lra_create_new_reg (GET_MODE (original_reg), original_reg, rclass, NULL, "inheritance"); start_sequence (); diff --git a/gcc/testsuite/gcc.target/i386/pr118017.c b/gcc/testsuite/gcc.target/i386/pr118017.c new file mode 100644 index ..c82d71e8d293 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr118017.c @@ -0,0 +1,21 @@ +/* PR target/118017 */ +/* { dg-do compile } */ +/* { dg-options "-Og -frounding-math -mno-80387 -mno-mmx -Wno-psabi" } */ + +typedef __attribute__((__vector_size__ (64))) _Float128 F; +typedef __attribute__((__vector_size__ (64))) _Decimal64 G; +typedef __attribute__((__vector_size__ (64))) _Decimal128 H; + +void +bar(_Float32, _BitInt(1025), _BitInt(1025), _Float128, __int128, __int128, F, +int, int, G, _Float64, __int128, __int128, H, F); + + +void +foo () +{ + bar ((__int128)68435455, 0, 0, 0, 0, 0, (F){}, 0, 0, (G){3689348814741910323}, + 0, 0, 0, (H){0, (_Decimal128) ((__int128) 860933398830926 << 64), + (_Decimal128) ((__int128) 966483857959145 << 64), 4}, + (F){(__int128) 3689348814741910323 << 64 | 3}); +}
[gcc r15-6748] s390: Add testcase for just fixed PR118362
https://gcc.gnu.org/g:8e4120500e0cfc71956dc6569fe4ff00d2c20949 commit r15-6748-g8e4120500e0cfc71956dc6569fe4ff00d2c20949 Author: Jakub Jelinek Date: Thu Jan 9 22:04:58 2025 +0100 s390: Add testcase for just fixed PR118362 On Thu, Jan 09, 2025 at 01:29:27PM +0100, Stefan Schulze Frielinghaus wrote: > Optimization s390_constant_via_vgbm_p() should only apply to constant > vectors which can be expressed by the hardware, i.e., which have a size > of at most 16-bytes, similar as it is done for s390_constant_via_vgm_p() > and s390_constant_via_vrepi_p(). > > gcc/ChangeLog: > > PR target/118362 > * config/s390/s390.cc (s390_constant_via_vgbm_p): Allow at most > 16-byte vectors. > --- > Bootstrap and regtest are still running. If both are successful, I > will push this one promptly. This was committed without a testcase, which IMHO shouldn't hurt. 2025-01-09 Jakub Jelinek PR target/118362 * gcc.c-torture/compile/pr118362.c: New test. * gcc.target/s390/pr118362.c: New test. Diff: --- gcc/testsuite/gcc.c-torture/compile/pr118362.c | 19 +++ gcc/testsuite/gcc.target/s390/pr118362.c | 5 + 2 files changed, 24 insertions(+) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr118362.c b/gcc/testsuite/gcc.c-torture/compile/pr118362.c new file mode 100644 index ..b01c46ad3a73 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr118362.c @@ -0,0 +1,19 @@ +/* PR target/118362 */ + +int a, b, c[18]; + +void +foo (void) +{ + for (int i = 0; i < 8; i++) +if (b) + { + c[i * 2 + 1] = a; + c[i * 2 + 2] = 200; + } +else + { + c[i * 2 + 1] = 100; + c[i * 2 + 2] = 200; + } +} diff --git a/gcc/testsuite/gcc.target/s390/pr118362.c b/gcc/testsuite/gcc.target/s390/pr118362.c new file mode 100644 index ..d2fdacbf8f42 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr118362.c @@ -0,0 +1,5 @@ +/* PR target/118362 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=z14" } */ + +#include "../../gcc.c-torture/compile/pr118362.c"
[gcc r15-6749] testsuite: arm: Fix typo in gcc.target/arm/armv8_2-fp16-conv-1.c
https://gcc.gnu.org/g:424a9ac45ab1a80359b22ee30d2815fb0f2c5149 commit r15-6749-g424a9ac45ab1a80359b22ee30d2815fb0f2c5149 Author: Torbjörn SVENSSON Date: Thu Jan 9 21:57:50 2025 +0100 testsuite: arm: Fix typo in gcc.target/arm/armv8_2-fp16-conv-1.c gcc/testsuite/ChangeLog: * gcc.target/arm/armv8_2-fp16-conv-1.c: Fix typo. Signed-off-by: Torbjörn SVENSSON Diff: --- gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c index 517ffd7e123b..e5145b993ede 100644 --- a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c +++ b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c @@ -156,9 +156,9 @@ f64_to_s16 (double a) } /* -** f64_to_s16: +** f64_to_u16: ** ... -** vcvt\.s32\.f64 s[0-9]+, d[0-9]+ +** vcvt\.u32\.f64 s[0-9]+, d[0-9]+ ** ... */ unsigned short
[gcc r15-6747] c: Restore warning for incomplete structures declared in parameter list [PR117866]
https://gcc.gnu.org/g:21571cdd8355f2162910d40f2f7d2dd4046f commit r15-6747-g21571cdd8355f2162910d40f2f7d2dd4046f Author: Martin Uecker Date: Mon Jan 6 15:32:16 2025 +0100 c: Restore warning for incomplete structures declared in parameter list [PR117866] In C23 mode the warning about declaring structures and union in parameter lists was removed, because it is possible to redeclare a compatible type elsewhere. This is not the case for incomplete types, so restore the warning for those types. PR c/117866 gcc/c/ChangeLog: * c-decl.cc (get_parm_info): Change condition for warning. gcc/testsuite/ChangeLog: * gcc.dg/pr117866.c: New test. * gcc.dg/strub-pr118007.c: Adapt. Diff: --- gcc/c/c-decl.cc | 2 +- gcc/testsuite/gcc.dg/pr117866.c | 5 + gcc/testsuite/gcc.dg/strub-pr118007.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index f60b2a54a17a..56d13884182d 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -8677,7 +8677,7 @@ get_parm_info (bool ellipsis, tree expr) if (b->id) { /* The %s will be one of 'struct', 'union', or 'enum'. */ - if (!flag_isoc23) + if (!flag_isoc23 || !COMPLETE_TYPE_P (decl)) warning_at (b->locus, 0, "%<%s %E%> declared inside parameter list" " will not be visible outside of this definition or" diff --git a/gcc/testsuite/gcc.dg/pr117866.c b/gcc/testsuite/gcc.dg/pr117866.c new file mode 100644 index ..3caf707791d3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr117866.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c23" } */ + +void convert(struct fractpoint *pt); /* { dg-warning "declared inside parameter list" } */ + diff --git a/gcc/testsuite/gcc.dg/strub-pr118007.c b/gcc/testsuite/gcc.dg/strub-pr118007.c index 6c24cad65296..51f48245b3f2 100644 --- a/gcc/testsuite/gcc.dg/strub-pr118007.c +++ b/gcc/testsuite/gcc.dg/strub-pr118007.c @@ -2,4 +2,4 @@ /* { dg-do compile } */ /* { dg-options "-fstrub=all -O2" } */ -void rb_ec_error_print(struct rb_execution_context_struct *volatile) {} +void rb_ec_error_print(struct rb_execution_context_struct *volatile) {} /* { dg-warning "declared inside parameter list" } */
[gcc r15-6750] c++: be permissive about eh spec mismatch for op new
https://gcc.gnu.org/g:3cae3a80695e5aabd7353c02e179c997158eef30 commit r15-6750-g3cae3a80695e5aabd7353c02e179c997158eef30 Author: Jason Merrill Date: Thu Jan 9 15:12:07 2025 -0500 c++: be permissive about eh spec mismatch for op new r15-3532 made us more strict about exception-specification mismatches with the standard library, but let's still be permissive about operator new, since previously you needed to say throw(std::bad_alloc). gcc/cp/ChangeLog: * decl.cc (check_redeclaration_exception_specification): Be more lenient about ::operator new. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept88.C: New test. Diff: --- gcc/cp/decl.cc | 11 +-- gcc/testsuite/g++.dg/cpp0x/noexcept88.C | 9 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 288da65fd8db..5c6a4996a89e 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -1398,7 +1398,14 @@ check_redeclaration_exception_specification (tree new_decl, location_t new_loc = DECL_SOURCE_LOCATION (new_decl); auto_diagnostic_group d; - if (DECL_IN_SYSTEM_HEADER (old_decl) && DECL_EXTERN_C_P (old_decl)) + /* Be permissive about C++98 vs C++11 operator new declarations. */ + bool global_new = (IDENTIFIER_NEW_OP_P (DECL_NAME (new_decl)) +&& CP_DECL_CONTEXT (new_decl) == global_namespace +&& (nothrow_spec_p (new_exceptions) +== nothrow_spec_p (old_exceptions))); + + if (DECL_IN_SYSTEM_HEADER (old_decl) + && (global_new || DECL_EXTERN_C_P (old_decl))) /* Don't fuss about the C library; the C library functions are not specified to have exception specifications (just behave as if they have them), but some implementations include them. */ @@ -1407,7 +1414,7 @@ check_redeclaration_exception_specification (tree new_decl, /* We used to silently permit mismatched eh specs with -fno-exceptions, so only complain if -pedantic. */ complained = pedwarn (new_loc, OPT_Wpedantic, msg, new_decl); - else if (!new_exceptions) + else if (!new_exceptions || global_new) /* Reduce to pedwarn for omitted exception specification. No warning flag for this; silence the warning by correcting the code. */ complained = pedwarn (new_loc, 0, msg, new_decl); diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept88.C b/gcc/testsuite/g++.dg/cpp0x/noexcept88.C new file mode 100644 index ..9b57fddbf0a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept88.C @@ -0,0 +1,9 @@ +// { dg-options -Wsystem-headers } + +#include +#include + +void *operator new (std::size_t) throw (std::bad_alloc); // { dg-line decl } +// { dg-error "dynamic exception spec" "" { target c++17 } decl } +// { dg-warning "dynamic exception spec" "" { target { c++11 && { ! c++17 } } } decl } +// { dg-warning "different exception spec" "" { target { c++11 && { ! c++17 } } } decl }
[gcc r15-6752] AArch64: Fix costing of emulated gathers/scatters [PR118188]
https://gcc.gnu.org/g:08b6e875c6b1b52c6e98f4a2e37124bf8c6a6ccb commit r15-6752-g08b6e875c6b1b52c6e98f4a2e37124bf8c6a6ccb Author: Tamar Christina Date: Thu Jan 9 21:31:05 2025 + AArch64: Fix costing of emulated gathers/scatters [PR118188] When a target does not support gathers and scatters the vectorizer tries to emulate these using scalar loads/stores and a reconstruction of vectors from scalar. The loads are still marked with VMAT_GATHER_SCATTER to indicate that they are gather/scatters, however the vectorizer also asks the target to cost the instruction that generates the indexes for the emulated instructions. This is done by asking the target to cost vec_to_scalar and vec_construct with a stmt_vinfo being the VMAT_GATHER_SCATTER. Since Adv. SIMD does not have an LD1 variant that takes an Adv. SIMD Scalar element the operation is lowered entirely into a sequence of GPR loads to create the x registers for the indexes. At the moment however we don't cost these, and so the vectorizer things that when it emulates the instructions that it's much cheaper than using an actual gather/scatter with SVE. Consider: #define iterations 10 #define LEN_1D 32000 float a[LEN_1D], b[LEN_1D]; float s4115 (int *ip) { float sum = 0.; for (int i = 0; i < LEN_1D; i++) { sum += a[i] * b[ip[i]]; } return sum; } which before this patch with -mcpu= generates: .L2: add x3, x0, x1 ldrsw x4, [x0, x1] ldrsw x6, [x3, 4] ldpsw x3, x5, [x3, 8] ldr s1, [x2, x4, lsl 2] ldr s30, [x2, x6, lsl 2] ldr s31, [x2, x5, lsl 2] ldr s29, [x2, x3, lsl 2] uzp1v30.2s, v30.2s, v31.2s ldr q31, [x7, x1] add x1, x1, 16 uzp1v1.2s, v1.2s, v29.2s zip1v30.4s, v1.4s, v30.4s fmlav0.4s, v31.4s, v30.4s cmp x1, x8 bne .L2 but during costing: a[i_18] 1 times vector_load costs 4 in body *_4 1 times unaligned_load (misalign -1) costs 4 in body b[_5] 4 times vec_to_scalar costs 32 in body b[_5] 4 times scalar_load costs 16 in body b[_5] 1 times vec_construct costs 3 in body _1 * _6 1 times vector_stmt costs 2 in body _7 + sum_16 1 times scalar_to_vec costs 4 in prologue _7 + sum_16 1 times vector_stmt costs 2 in epilogue _7 + sum_16 1 times vec_to_scalar costs 4 in epilogue _7 + sum_16 1 times vector_stmt costs 2 in body Here we see that the latency for the vec_to_scalar is very high. We know the intermediate vector isn't usable by the target ISA and will always be elided. However these latencies need to remain high because when costing gather/scatters IFNs we still pass the nunits of the type along. In other words, the vectorizer is still costing vector gather/scatters as scalar load/stores. Lowering the cost for the emulated gathers would result in emulation being seemingly cheaper. So while the emulated costs are very high, they need to be higher than those for the IFN costing. i.e. the vectorizer generates: vect__5.9_8 = MEM [(intD.7 *)vectp_ip.7_14]; _35 = BIT_FIELD_REF ; _36 = (sizetype) _35; _37 = _36 * 4; _38 = _34 + _37; _39 = (voidD.55 *) _38; # VUSE <.MEM_10(D)> _40 = MEM[(floatD.32 *)_39]; which after IVopts is: _63 = &MEM [(int *)ip_11(D) + ivtmp.19_27 * 1]; _47 = BIT_FIELD_REF [(int *)_63], 32, 64>; _41 = BIT_FIELD_REF [(int *)_63], 32, 32>; _35 = BIT_FIELD_REF [(int *)_63], 32, 0>; _53 = BIT_FIELD_REF [(int *)_63], 32, 96>; Which we correctly lower in RTL to individual loads to avoid the repeated umov. As such, we should cost the vec_to_scalar as GPR loads and also do so for the throughput which we at the moment cost as: note: Vector issue estimate: note:load operations = 6 note:store operations = 0 note:general operations = 6 note:reduction latency = 2 note:estimated min cycles per iteration = 2.00 Which means 3 loads for the GOR indexes are missing, making it seem like the emulated loop has a much lower cycles per iter than it actually does since the bottleneck on the load units are not modelled. But worse, because the vectorizer costs gathers/scatters IFNs as scalar load/stores the number of loads required for an SVE gather is always much higher than the equivalent emulated variant. gcc/ChangeLog: PR target/118188 * config/aarch64/aarch64.cc (aarch64_vector_costs::count_ops): Adjust throughput of emu
[gcc r15-6753] RISC-V: testsuite: fix target selector for sync_char_short
https://gcc.gnu.org/g:2d0f3457a80b804dc0d33924781cf386a0088511 commit r15-6753-g2d0f3457a80b804dc0d33924781cf386a0088511 Author: Edwin Lu Date: Thu Jan 9 10:32:07 2025 -0800 RISC-V: testsuite: fix target selector for sync_char_short The effective-target selector for riscv on sync_char_short did not check to see if atomics were enabled. As a result, these test cases were ran on targets without the a extension. Add additional checks for zalrsc or zabha extensions. gcc/testsuite/ChangeLog: * lib/target-supports.exp: Fix effective target sync_char_short for riscv*-*-* Signed-off-by: Edwin Lu Diff: --- gcc/testsuite/lib/target-supports.exp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index a89f531f8876..939ef3a41196 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -10080,7 +10080,9 @@ proc check_effective_target_sync_char_short { } { || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9]) || ([istarget arc*-*-*] && [check_effective_target_arc_atomic]) || [istarget loongarch*-*-*] -|| [istarget riscv*-*-*] +|| ([istarget riscv*-*-*] +&& ([check_effective_target_riscv_zalrsc] +|| [check_effective_target_riscv_zabha])) || [check_effective_target_mips_llsc] }}] }
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction variable inutilisée
https://gcc.gnu.org/g:594c3d47fa952a6a78bce3a166620f8090009681 commit 594c3d47fa952a6a78bce3a166620f8090009681 Author: Mikael Morin Date: Thu Jan 9 22:35:38 2025 +0100 Correction variable inutilisée Diff: --- gcc/fortran/trans-expr.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index b65474a0c919..57a976df58ff 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11595,7 +11595,6 @@ fcncall_realloc_result (gfc_se *se, int rank, tree dtype) tree desc; tree res_desc; tree tmp; - tree offset; tree zero_cond; tree not_same_shape; stmtblock_t shape_block;
[gcc r15-6756] c++: modules, generic lambda, constexpr if
https://gcc.gnu.org/g:6fe395025deda274f2f92b04e3e329aa53771dfe commit r15-6756-g6fe395025deda274f2f92b04e3e329aa53771dfe Author: Jason Merrill Date: Mon Nov 25 23:29:25 2024 -0500 c++: modules, generic lambda, constexpr if In std/ranges/concat/1.cc we end up instantiating concat_view::iterator::operator-, which has nested generic lambdas, where the innermost is all constexpr if. tsubst_lambda_expr propagates the returns_* flags for generic lambdas since we might not substitute into the whole function, as in this case with constexpr if. But the module wasn't preserving that flag, and so the importer gave a bogus "no return statement" diagnostic. gcc/cp/ChangeLog: * module.cc (trees_out::write_function_def): Write returns* flags. (struct post_process_data): Add returns_* flags. (trees_in::read_function_def): Set them. (module_state::read_cluster): Use them. gcc/testsuite/ChangeLog: * g++.dg/modules/constexpr-if-1_a.C: New test. * g++.dg/modules/constexpr-if-1_b.C: New test. Diff: --- gcc/cp/module.cc| 24 +--- gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C | 14 ++ gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C | 8 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 5350e6c4badb..0533a2bcf2c1 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2929,6 +2929,10 @@ struct post_process_data { tree decl; location_t start_locus; location_t end_locus; + bool returns_value; + bool returns_null; + bool returns_abnormally; + bool infinite_loop; }; /* Tree stream reader. Note that reading a stream doesn't mark the @@ -12263,10 +12267,16 @@ trees_out::write_function_def (tree decl) { unsigned flags = 0; + flags |= 1 * DECL_NOT_REALLY_EXTERN (decl); if (f) - flags |= 2; - if (DECL_NOT_REALLY_EXTERN (decl)) - flags |= 1; + { + flags |= 2; + /* These flags are needed in tsubst_lambda_expr. */ + flags |= 4 * f->language->returns_value; + flags |= 8 * f->language->returns_null; + flags |= 16 * f->language->returns_abnormally; + flags |= 32 * f->language->infinite_loop; + } u (flags); } @@ -12314,6 +12324,10 @@ trees_in::read_function_def (tree decl, tree maybe_template) { pdata.start_locus = state->read_location (*this); pdata.end_locus = state->read_location (*this); + pdata.returns_value = flags & 4; + pdata.returns_null = flags & 8; + pdata.returns_abnormally = flags & 16; + pdata.infinite_loop = flags & 32; } if (get_overrun ()) @@ -16232,6 +16246,10 @@ module_state::read_cluster (unsigned snum) cfun->language->base.x_stmt_tree.stmts_are_full_exprs_p = 1; cfun->function_start_locus = pdata.start_locus; cfun->function_end_locus = pdata.end_locus; + cfun->language->returns_value = pdata.returns_value; + cfun->language->returns_null = pdata.returns_null; + cfun->language->returns_abnormally = pdata.returns_abnormally; + cfun->language->infinite_loop = pdata.infinite_loop; if (abstract) ; diff --git a/gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C b/gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C new file mode 100644 index ..80a064f4d397 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C @@ -0,0 +1,14 @@ +// { dg-do compile { target c++20 } } +// { dg-additional-options -fmodules } + +export module M; + +export +template +inline void f() +{ + []() -> int { +if constexpr (M > 0) { return true; } +else { return false; } + }; +} diff --git a/gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C b/gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C new file mode 100644 index ..af285da79ac5 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules } + +import M; + +int main() +{ + f(); +}
[gcc r15-6757] c++: improve some modules comments
https://gcc.gnu.org/g:bd28244ec92b9aac082f822987818ff1e11b67fd commit r15-6757-gbd28244ec92b9aac082f822987818ff1e11b67fd Author: Jason Merrill Date: Mon Nov 25 18:02:30 2024 -0500 c++: improve some modules comments gcc/cp/ChangeLog: * error.cc (cxx_initialize_diagnostics): Improve comment. * module.cc (modules): Improve comment. (get_originating_module): Add function comment. Diff: --- gcc/cp/error.cc | 2 +- gcc/cp/module.cc | 6 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index cc4cc4a7eb46..615ae0d1b65a 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -285,7 +285,7 @@ cxx_initialize_diagnostics (diagnostic_context *context) context->m_adjust_diagnostic_info = cp_adjust_diagnostic_info; } -/* Dump an '@module' name suffix for DECL, if any. */ +/* Dump an '@module' name suffix for DECL, if it's attached to an import. */ static void dump_module_suffix (cxx_pretty_printer *pp, tree decl) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 0533a2bcf2c1..fec820603521 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -4076,7 +4076,8 @@ static unsigned lazy_hard_limit; /* Hard limit on open modules. */ pass, but ICBW. */ #define LAZY_HEADROOM 15 /* File descriptor headroom. */ -/* Vector of module state. Indexed by OWNER. Has at least 2 slots. */ +/* Vector of module state. Indexed by OWNER. Index 0 is reserved for the + current TU; imports start at 1. */ static GTY(()) vec *modules; /* Hash of module state, findable by {name, parent}. */ @@ -19947,6 +19948,9 @@ get_originating_module (tree decl, bool for_mangle) return mod; } +/* DECL is imported, return which module imported it. + If FLEXIBLE, return -1 if not found, otherwise checking ICE. */ + unsigned get_importing_module (tree decl, bool flexible) {
[gcc r15-6745] testsuite: arm: Verify asm per function for armv8_2-fp16-conv-1.c
https://gcc.gnu.org/g:794f6721e0ebd1b6cb6931285a033b9f1f30d650 commit r15-6745-g794f6721e0ebd1b6cb6931285a033b9f1f30d650 Author: Torbjörn SVENSSON Date: Fri Dec 27 17:22:55 2024 +0100 testsuite: arm: Verify asm per function for armv8_2-fp16-conv-1.c This change will enforce that the expected instructions are generated per function rather than allowing some other function to use the expected instructions. gcc/testsuite/ChangeLog: * gcc.target/arm/armv8_2-fp16-conv-1.c: Convert scan-assembler-times to check-function-bodies. Signed-off-by: Torbjörn SVENSSON Diff: --- gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c | 101 + 1 file changed, 84 insertions(+), 17 deletions(-) diff --git a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c index c9639a542ae3..517ffd7e123b 100644 --- a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c +++ b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-conv-1.c @@ -1,101 +1,168 @@ /* { dg-do compile } */ /* { dg-require-effective-target arm_v8_2a_fp16_scalar_ok } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -fno-schedule-insns -fno-schedule-insns2" } */ /* { dg-add-options arm_v8_2a_fp16_scalar } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Test ARMv8.2 FP16 conversions. */ #include +/* +** f16_to_f32: +** ... +** vcvtb\.f32\.f16 (s[0-9]+), \1 +** ... +*/ float f16_to_f32 (__fp16 a) { return (float)a; } +/* +** f16_to_pf32: +** ... +** vcvtb\.f32\.f16 (s[0-9]+), \1 +** ... +*/ float f16_to_pf32 (__fp16* a) { return (float)*a; } +/* +** f16_to_s16: +** ... +** vcvtb\.f32\.f16 (s[0-9]+), \1 +** vcvt\.s32\.f32 \1, \1 +** ... +*/ short f16_to_s16 (__fp16 a) { return (short)a; } +/* +** pf16_to_s16: +** ... +** vcvtb\.f32\.f16 (s[0-9]+), \1 +** vcvt\.s32\.f32 \1, \1 +** ... +*/ short pf16_to_s16 (__fp16* a) { return (short)*a; } -/* { dg-final { scan-assembler-times {vcvtb\.f32\.f16\ts[0-9]+, s[0-9]+} 4 } } */ - +/* +** f32_to_f16: +** ... +** vcvtb\.f16\.f32 (s[0-9]+), \1 +** ... +*/ __fp16 f32_to_f16 (float a) { return (__fp16)a; } +/* +** f32_to_pf16: +** ... +** vcvtb\.f16\.f32 (s[0-9]+), \1 +** ... +*/ void f32_to_pf16 (__fp16* x, float a) { *x = (__fp16)a; } +/* +** s16_to_f16: +** ... +** vcvt\.f32\.s32 (s[0-9]+), \1 +** vcvtb\.f16\.f32 \1, \1 +** ... +*/ __fp16 s16_to_f16 (short a) { return (__fp16)a; } +/* +** s16_to_pf16: +** ... +** vcvt\.f32\.s32 (s[0-9]+), \1 +** vcvtb\.f16\.f32 \1, \1 +** ... +*/ void s16_to_pf16 (__fp16* x, short a) { *x = (__fp16)a; } -/* { dg-final { scan-assembler-times {vcvtb\.f16\.f32\ts[0-9]+, s[0-9]+} 4 } } */ - +/* +** s16_to_f32: +** ... +** vcvt\.f32\.s32 (s[0-9]+), \1 +** ... +*/ float s16_to_f32 (short a) { return (float)a; } -/* { dg-final { scan-assembler-times {vcvt\.f32\.s32\ts[0-9]+, s[0-9]+} 3 } } */ - +/* +** f32_to_s16: +** ... +** vcvt\.s32\.f32 (s[0-9]+), \1 +** ... +*/ short f32_to_s16 (float a) { return (short)a; } -/* { dg-final { scan-assembler-times {vcvt\.s32\.f32\ts[0-9]+, s[0-9]+} 3 } } */ - +/* +** f32_to_u16: +** ... +** vcvt\.u32\.f32 (s[0-9]+), \1 +** ... +*/ unsigned short f32_to_u16 (float a) { return (unsigned short)a; } -/* { dg-final { scan-assembler-times {vcvt\.u32\.f32\ts[0-9]+, s[0-9]+} 1 } } */ - +/* +** f64_to_s16: +** ... +** vcvt\.s32\.f64 s[0-9]+, d[0-9]+ +** ... +*/ short f64_to_s16 (double a) { return (short)a; } -/* { dg-final { scan-assembler-times {vcvt\.s32\.f64\ts[0-9]+, d[0-9]+} 1 } } */ - +/* +** f64_to_s16: +** ... +** vcvt\.s32\.f64 s[0-9]+, d[0-9]+ +** ... +*/ unsigned short f64_to_u16 (double a) { return (unsigned short)a; } - -/* { dg-final { scan-assembler-times {vcvt\.s32\.f64\ts[0-9]+, d[0-9]+} 1 } } */ - -
[gcc r15-6746] testsuite: arm: Use -Os in memset-inline-8* tests
https://gcc.gnu.org/g:681934aead9c1310e3b910d18986b76272168a80 commit r15-6746-g681934aead9c1310e3b910d18986b76272168a80 Author: Torbjörn SVENSSON Date: Sun Dec 22 16:19:17 2024 +0100 testsuite: arm: Use -Os in memset-inline-8* tests When the test was initially created, -fcommon was the default, but in commit r10-4867-g6271dd984d7 the default value changed to -fno-common. This change made the test start failing. To counter the over-alignment caused by 'a' no longer being common, use -Os. gcc/testsuite/ChangeLog: * gcc.target/arm/memset-inline-8.c: Use -Os and prefix assembler instructions with a tab to improve test stability. * gcc.target/arm/memset-inline-8-exe.c: Use -Os. Signed-off-by: Torbjörn SVENSSON Diff: --- gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-8.c | 8 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c index 0ff1f6cbe894..157cf1e05688 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ /* { dg-require-effective-target arm_neon_hw } */ -/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-options "-save-temps -Os -fno-inline" } */ /* { dg-add-options "arm_neon" } */ #include "./memset-inline-8.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-8.c b/gcc/testsuite/gcc.target/arm/memset-inline-8.c index e12e9330f75c..39fe4d5d392c 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-8.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-8.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ -/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-options "-save-temps -Os -fno-inline" } */ /* { dg-add-options "arm_neon" } */ #include @@ -37,6 +37,6 @@ main(void) return 0; } -/* { dg-final { scan-assembler-not "bl?\[ \t\]*memset" { target { arm_thumb2_ok } } } } */ -/* { dg-final { scan-assembler "vst1" { target { arm_little_endian && arm_neon } } } } */ -/* { dg-final { scan-assembler-not "vstr" { target { arm_little_endian && arm_neon } } } } */ +/* { dg-final { scan-assembler-not "\tbl?\[ \t\]*memset" { target { arm_thumb2_ok } } } } */ +/* { dg-final { scan-assembler "\tvst1" { target { arm_little_endian && arm_neon } } } } */ +/* { dg-final { scan-assembler-not "\tvstr" { target { arm_little_endian && arm_neon } } } } */
[gcc r14-11171] testsuite: arm: Use -Os in memset-inline-8* tests
https://gcc.gnu.org/g:1f509da6d7c9679f727daf539c30f8f1816dd16e commit r14-11171-g1f509da6d7c9679f727daf539c30f8f1816dd16e Author: Torbjörn SVENSSON Date: Sun Dec 22 16:19:17 2024 +0100 testsuite: arm: Use -Os in memset-inline-8* tests When the test was initially created, -fcommon was the default, but in commit r10-4867-g6271dd984d7 the default value changed to -fno-common. This change made the test start failing. To counter the over-alignment caused by 'a' no longer being common, use -Os. gcc/testsuite/ChangeLog: * gcc.target/arm/memset-inline-8.c: Use -Os and prefix assembler instructions with a tab to improve test stability. * gcc.target/arm/memset-inline-8-exe.c: Use -Os. Signed-off-by: Torbjörn SVENSSON (cherry picked from commit 681934aead9c1310e3b910d18986b76272168a80) Diff: --- gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-8.c | 8 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c index 0ff1f6cbe894..157cf1e05688 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ /* { dg-require-effective-target arm_neon_hw } */ -/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-options "-save-temps -Os -fno-inline" } */ /* { dg-add-options "arm_neon" } */ #include "./memset-inline-8.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-8.c b/gcc/testsuite/gcc.target/arm/memset-inline-8.c index e12e9330f75c..39fe4d5d392c 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-8.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-8.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ -/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-options "-save-temps -Os -fno-inline" } */ /* { dg-add-options "arm_neon" } */ #include @@ -37,6 +37,6 @@ main(void) return 0; } -/* { dg-final { scan-assembler-not "bl?\[ \t\]*memset" { target { arm_thumb2_ok } } } } */ -/* { dg-final { scan-assembler "vst1" { target { arm_little_endian && arm_neon } } } } */ -/* { dg-final { scan-assembler-not "vstr" { target { arm_little_endian && arm_neon } } } } */ +/* { dg-final { scan-assembler-not "\tbl?\[ \t\]*memset" { target { arm_thumb2_ok } } } } */ +/* { dg-final { scan-assembler "\tvst1" { target { arm_little_endian && arm_neon } } } } */ +/* { dg-final { scan-assembler-not "\tvstr" { target { arm_little_endian && arm_neon } } } } */
[gcc r14-11195] doc: cpp: fix version test example syntax
https://gcc.gnu.org/g:91b524aa80e2ce22c4613f6bea625a72d1f5f4ed commit r14-11195-g91b524aa80e2ce22c4613f6bea625a72d1f5f4ed Author: Sam James Date: Wed Jan 1 17:16:17 2025 + doc: cpp: fix version test example syntax gcc/ChangeLog: * doc/cpp.texi (Common Predefined Macros): Fix syntax. Diff: --- gcc/doc/cpp.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 3de6e7aa7378..a2f982c510af 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1971,7 +1971,7 @@ like this: #if __GNUC__ > 3 || \ (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \ (__GNUC_MINOR__ == 2 && \ -__GNUC_PATCHLEVEL__ > 0)) +__GNUC_PATCHLEVEL__ > 0))) @end smallexample @noindent
[gcc r13-9290] doc: cpp: fix version test example syntax
https://gcc.gnu.org/g:5ff315e398b6a790471029950dd7eef4e168c312 commit r13-9290-g5ff315e398b6a790471029950dd7eef4e168c312 Author: Sam James Date: Wed Jan 1 17:16:17 2025 + doc: cpp: fix version test example syntax gcc/ChangeLog: * doc/cpp.texi (Common Predefined Macros): Fix syntax. Diff: --- gcc/doc/cpp.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index b0a2ce3ac6b6..48a877e6fd38 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1970,7 +1970,7 @@ like this: #if __GNUC__ > 3 || \ (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \ (__GNUC_MINOR__ == 2 && \ -__GNUC_PATCHLEVEL__ > 0)) +__GNUC_PATCHLEVEL__ > 0))) @end smallexample @noindent
[gcc r14-11159] libstdc++: Add Doxygen docs for std::forward_like
https://gcc.gnu.org/g:785ddc26e20755b3eabff27f9817a1b3aa3751a0 commit r14-11159-g785ddc26e20755b3eabff27f9817a1b3aa3751a0 Author: Jonathan Wakely Date: Tue Jan 7 15:13:56 2025 + libstdc++: Add Doxygen docs for std::forward_like Also add "@since C++11" to std::move, std::forward etc. libstdc++-v3/ChangeLog: * include/bits/move.h (forward, move, move_if_noexcept, addressof): Add @since to Doxygen comments. (forward_like): Add Doxygen comment. (cherry picked from commit 4a4e5394b3001b1b3fb35c274d184ffba30156e8) Diff: --- libstdc++-v3/include/bits/move.h | 12 1 file changed, 12 insertions(+) diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index 8397a01b6323..82d889b44292 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -63,6 +63,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @return The parameter cast to the specified type. * * This function is used to implement "perfect forwarding". + * @since C++11 */ template _GLIBCXX_NODISCARD @@ -75,6 +76,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @return The parameter cast to the specified type. * * This function is used to implement "perfect forwarding". + * @since C++11 */ template _GLIBCXX_NODISCARD @@ -109,6 +111,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template using __like_t = typename __like_impl<_Tp&&, _Up&>::type; + /** @brief Forward with the cv-qualifiers and value category of another type. + * @tparam _Tp An lvalue reference or rvalue reference. + * @tparam _Up An lvalue reference type deduced from the function argument. + * @param __x An lvalue. + * @return `__x` converted to match the qualifiers of `_Tp`. + * @since C++23 + */ template [[nodiscard]] constexpr __like_t<_Tp, _Up> @@ -120,6 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @brief Convert a value to an rvalue. * @param __t A thing of arbitrary type. * @return The parameter cast to an rvalue-reference to allow moving it. + * @since C++11 */ template _GLIBCXX_NODISCARD @@ -140,6 +150,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * Same as std::move unless the type's move constructor could throw and the * type is copyable, in which case an lvalue-reference is returned instead. + * @since C++11 */ template _GLIBCXX_NODISCARD @@ -156,6 +167,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * operator&. * @param __r Reference to an object or function. * @return The actual address. + * @since C++11 */ template _GLIBCXX_NODISCARD
[gcc r14-11158] libstdc++: Fix incorrect DocBook element in manual
https://gcc.gnu.org/g:7178e38e89e51031d073f39543a291cd2f4e898f commit r14-11158-g7178e38e89e51031d073f39543a291cd2f4e898f Author: Jonathan Wakely Date: Mon Jan 6 21:29:54 2025 + libstdc++: Fix incorrect DocBook element in manual libstdc++-v3/ChangeLog: * doc/xml/manual/evolution.xml: Replace invalid elements with . * doc/html/*: Regenerate. (cherry picked from commit 720945e8bcbc86285fb3b176627f05ada8a7d136) Diff: --- libstdc++-v3/doc/html/index.html | 4 ++-- libstdc++-v3/doc/html/manual/api.html | 4 ++-- libstdc++-v3/doc/xml/manual/evolution.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libstdc++-v3/doc/html/index.html b/libstdc++-v3/doc/html/index.html index 395908f17a1a..88ef88412669 100644 --- a/libstdc++-v3/doc/html/index.html +++ b/libstdc++-v3/doc/html/index.html @@ -1,6 +1,6 @@ -http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>http://www.w3.org/1999/xhtml";>The GNU C++ LibraryThe GNU C++ Library   NextThe GNU C++ LibraryShort Contents - Copyright (C) 2008-2024 +http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>http://www.w3.org/1999/xhtml";>The GNU C++ LibraryThe GNU C++ Library   NextThe GNU C++ LibraryShort Contents + Copyright (C) 2008-2025 https://www.fsf.org"; target="_top">FSF diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html index 59ed4c888628..1d62e1de8cd2 100644 --- a/libstdc++-v3/doc/html/manual/api.html +++ b/libstdc++-v3/doc/html/manual/api.html @@ -483,8 +483,8 @@ the process. Calling a std::bind result as volatile is ill-formed for C++20 and later. 13 -Tunablesglibcxx.eh_pool.obj_count and -glibcxx.eh_pool.obj_size were added. +Tunables glibcxx.eh_pool.obj_count and +glibcxx.eh_pool.obj_size were added. Static library libstdc++exp.a was added to provide the symbols for the experimental C++ Contracts support.13.3 Symbols for the Filesystem TS and C++23diff --git a/libstdc++-v3/doc/xml/manual/evolution.xml b/libstdc++-v3/doc/xml/manual/evolution.xml index a375ae14b83d..4c4ee98eb604 100644 --- a/libstdc++-v3/doc/xml/manual/evolution.xml +++ b/libstdc++-v3/doc/xml/manual/evolution.xml @@ -1096,8 +1096,8 @@ and later. 13 -Tunables glibcxx.eh_pool.obj_count and -glibcxx.eh_pool.obj_size were added. +Tunables glibcxx.eh_pool.obj_count and +glibcxx.eh_pool.obj_size were added. Static library libstdc++exp.a was added
[gcc r14-11156] c++: Diagnose earlier non-static data members with cv containing class type [PR116108]
https://gcc.gnu.org/g:ec9ccda503d79865c5bf5bc9ef850003784c5b95 commit r14-11156-gec9ccda503d79865c5bf5bc9ef850003784c5b95 Author: Jakub Jelinek Date: Tue Dec 17 10:13:24 2024 +0100 c++: Diagnose earlier non-static data members with cv containing class type [PR116108] In r10-6457 aka PR92593 fix a check has been added to reject earlier non-static data members with current_class_type in templates, as the deduction then can result in endless recursion in reshape_init. It fixed the template struct S { S s = 1; }; S t{2}; crashes, but as the following testcase shows, didn't catch when there are cv qualifiers on the non-static data member. Fixed by using TYPE_MAIN_VARIANT. 2024-12-17 Jakub Jelinek PR c++/116108 gcc/cp/ * decl.cc (grokdeclarator): Pass TYYPE_MAIN_VARIANT (type) rather than type to same_type_p when checking if the non-static data member doesn't have current class type. gcc/testsuite/ * g++.dg/cpp1z/class-deduction117.C: New test. (cherry picked from commit 88bfee560681d8248b89f130ada249e35ee2e344) Diff: --- gcc/cp/decl.cc | 3 ++- gcc/testsuite/g++.dg/cpp1z/class-deduction117.C | 7 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index d5cef069fce5..ada0a0c2299a 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -14792,7 +14792,8 @@ grokdeclarator (const cp_declarator *declarator, } else if (!staticp && ((current_class_type - && same_type_p (type, current_class_type)) + && same_type_p (TYPE_MAIN_VARIANT (type), + current_class_type)) || (!dependent_type_p (type) && !COMPLETE_TYPE_P (complete_type (type)) && (!complete_or_array_type_p (type) diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction117.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction117.C new file mode 100644 index ..8ab91018377f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction117.C @@ -0,0 +1,7 @@ +// PR c++/116108 +// { dg-do compile { target c++11 } } +template +struct S { const S s = 1; }; // { dg-error "field 's' has incomplete type 'const S'" } +S t{2};// { dg-error "invalid use of template-name 'S' without an argument list" "" { target c++14_down } } +// { dg-error "class template argument deduction failed" "" { target c++17 } .-1 } +// { dg-error "no matching function for call to 'S\\\(int\\\)'" "" { target c++17 } .-2 }
[gcc r14-11157] c++: Honor complain in cp_build_function_call_vec for check_function_arguments warnings [PR117825]
https://gcc.gnu.org/g:da82bf0a5fe31319735af1b67218578440ed8333 commit r14-11157-gda82bf0a5fe31319735af1b67218578440ed8333 Author: Jakub Jelinek Date: Wed Jan 8 23:12:02 2025 +0100 c++: Honor complain in cp_build_function_call_vec for check_function_arguments warnings [PR117825] The following testcase ICEs due to re-entering diagnostics. When diagnosing -Wformat-security warning, we try to print instantiation context, which calls tsubst with tf_none, but that in the end calls cp_build_function_call_vec which calls check_function_arguments which diagnoses another warning (again -Wformat-security). The other check_function_arguments caller, build_over_call, doesn't call that function if !(complain & tf_warning), so I think the best fix is to do it the same in cp_build_function_call_vec as well. 2025-01-08 Jakub Jelinek PR c++/117825 * typeck.cc (cp_build_function_call_vec): Don't call check_function_arguments if complain doesn't have tf_warning bit set. * g++.dg/warn/pr117825.C: New test. (cherry picked from commit e5180fbcbcc356c71154413588288cbd30e5198d) Diff: --- gcc/cp/typeck.cc | 6 -- gcc/testsuite/g++.dg/warn/pr117825.C | 18 ++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 6ca2cee682c4..0982fed58a5a 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -4469,8 +4469,10 @@ cp_build_function_call_vec (tree function, vec **params, /* Check for errors in format strings and inappropriately null parameters. */ - bool warned_p = check_function_arguments (input_location, fndecl, fntype, - nargs, argarray, NULL); + bool warned_p += ((complain & tf_warning) + && check_function_arguments (input_location, fndecl, fntype, + nargs, argarray, NULL)); ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl); diff --git a/gcc/testsuite/g++.dg/warn/pr117825.C b/gcc/testsuite/g++.dg/warn/pr117825.C new file mode 100644 index ..077e09d9a57b --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr117825.C @@ -0,0 +1,18 @@ +// PR c++/117825 +// { dg-do compile { target c++17 } } +// { dg-options "-Wformat -Wformat-security" } + +__attribute__((format (printf, 1, 2))) +int fails (const char *, ...) { return 0; } + +template +auto wrap (Args... args) -> decltype (func (args...)) +{ + return func (args...); // { dg-warning "format not a string literal and no format arguments" } +} + +int +main () +{ + wrap ("Test!"); +}
[gcc r14-11153] c++: allow stores to anon union vars to change current union member in constexpr [PR117614]
https://gcc.gnu.org/g:7ae55c2f73626e8a7a6871a1e4fd4cde2e6c8460 commit r14-11153-g7ae55c2f73626e8a7a6871a1e4fd4cde2e6c8460 Author: Jakub Jelinek Date: Wed Dec 11 17:28:47 2024 +0100 c++: allow stores to anon union vars to change current union member in constexpr [PR117614] Since r14-4771 the FE tries to differentiate between cases where the lhs of a store allows changing the current union member and cases where it doesn't, and cases where it doesn't includes everything that has gone through the cxx_eval_constant_expression path on the lhs. As the testcase shows, DECL_ANON_UNION_VAR_P vars were handled like that too, even when stores to them are the only way how to change the current union member in the sources. So, the following patch just handles that case manually without calling cxx_eval_constant_expression and without setting evaluated to true. 2024-12-11 Jakub Jelinek PR c++/117614 * constexpr.cc (cxx_eval_store_expression): For stores to DECL_ANON_UNION_VAR_P vars just continue with DECL_VALUE_EXPR of it, without setting evaluated to true or full cxx_eval_constant_expression. * g++.dg/cpp2a/constexpr-union8.C: New test. (cherry picked from commit 337815c8bbd0fb5034223ad0e7899d1493e958a2) Diff: --- gcc/cp/constexpr.cc | 8 +++ gcc/testsuite/g++.dg/cpp2a/constexpr-union8.C | 31 +++ 2 files changed, 39 insertions(+) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 40cc755258ff..c5cd5c87680f 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -6326,6 +6326,14 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, object = probe; else { + tree pvar = tree_strip_any_location_wrapper (probe); + if (VAR_P (pvar) && DECL_ANON_UNION_VAR_P (pvar)) + { + /* Stores to DECL_ANON_UNION_VAR_P var are allowed to change +active union member. */ + probe = DECL_VALUE_EXPR (pvar); + break; + } probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue, non_constant_p, overflow_p); evaluated = true; diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-union8.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-union8.C new file mode 100644 index ..1e51857b3dff --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-union8.C @@ -0,0 +1,31 @@ +// PR c++/117614 +// { dg-do compile { target c++20 } } + +constexpr int +foo () +{ + union { +int x{0}; +char y; + }; + y = 1; + return y; +} + +constexpr int +bar () +{ + union { +union { + int x{0}; + char y; +}; +long long z; + }; + y = 1; + z = 2; + return z; +} + +static_assert (foo () == 1); +static_assert (bar () == 2);
[gcc r14-11143] c-family: Yet another fix for _BitInt & __sync_* builtins [PR117641]
https://gcc.gnu.org/g:6b417daf0c4c486a754ee99ec07c85aa5d55c610 commit r14-11143-g6b417daf0c4c486a754ee99ec07c85aa5d55c610 Author: Jakub Jelinek Date: Fri Nov 22 19:47:52 2024 +0100 c-family: Yet another fix for _BitInt & __sync_* builtins [PR117641] Sorry, the last patch only partially fixed the __sync_* ICEs with _BitInt(128) on ia32. Even for !fetch we need to error out and return 0. I was afraid of APIs like __atomic_exchange/__atomic_compare_exchange, those obviously need to be supported even on _BitInt(128) on ia32, but they actually never sync_resolve_size, they are handled by adding the size argument and using the library version much earlier. For fetch && !orig_format (i.e. __atomic_fetch_* etc.) we need to return -1 so that we handle it with a manualy __atomic_load + __atomic_compare_exchange loop in the caller, all other cases should be rejected. 2024-11-22 Jakub Jelinek PR c/117641 * c-common.cc (sync_resolve_size): For size 16 with _BitInt on targets where TImode isn't supported, use goto incompatible if !fetch. * gcc.dg/bitint-117.c: New test. (cherry picked from commit 44984f7f7523f136085ba60fd107ba8309d4115b) Diff: --- gcc/c-family/c-common.cc | 3 +-- gcc/testsuite/gcc.dg/bitint-117.c | 13 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 661115bf1db1..d5b28efd6db4 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -7383,11 +7383,10 @@ sync_resolve_size (tree function, vec *params, bool fetch, size = tree_to_uhwi (TYPE_SIZE_UNIT (type)); if (size == 16 - && fetch && TREE_CODE (type) == BITINT_TYPE && !targetm.scalar_mode_supported_p (TImode)) { - if (!orig_format) + if (fetch && !orig_format) return -1; goto incompatible; } diff --git a/gcc/testsuite/gcc.dg/bitint-117.c b/gcc/testsuite/gcc.dg/bitint-117.c new file mode 100644 index ..16a76165d1e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-117.c @@ -0,0 +1,13 @@ +/* PR c/117641 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-std=c23" } */ + +void +foo (_BitInt(128) *b) +{ + __sync_add_and_fetch (b, 1); /* { dg-error "incompatible" "" { target { ! int128 } } } */ + __sync_val_compare_and_swap (b, 0, 1); /* { dg-error "incompatible" "" { target { ! int128 } } } */ + __sync_bool_compare_and_swap (b, 0, 1); /* { dg-error "incompatible" "" { target { ! int128 } } } */ + __sync_lock_test_and_set (b, 1); /* { dg-error "incompatible" "" { target { ! int128 } } } */ + __sync_lock_release (b); /* { dg-error "incompatible" "" { target { ! int128 } } } */ +}
[gcc r14-11160] libstdc++: Fix std::future::wait_until for subsecond negative times [PR118093]
https://gcc.gnu.org/g:a7c5c4931f50b9898409d0101fad47abc9a223c3 commit r14-11160-ga7c5c4931f50b9898409d0101fad47abc9a223c3 Author: Jonathan Wakely Date: Tue Dec 17 21:32:19 2024 + libstdc++: Fix std::future::wait_until for subsecond negative times [PR118093] The current check for negative times (i.e. before the epoch) only checks for a negative number of seconds. For a time 1ms before the epoch the seconds part will be zero, but the futex syscall will still fail with an EINVAL error. Extend the check to handle this case. This change adds a redundant check in the headers too, so that we avoid even calling into the library for negative times. Both checks can be marked [[unlikely]]. The check in the headers avoids the cost of splitting the time into seconds and nanoseconds and then making a PLT call. The check inside the library matches where we were checking already, and fixes existing binaries that were compiled against older headers but use a newer libstdc++.so.6 at runtime. libstdc++-v3/ChangeLog: PR libstdc++/118093 * include/bits/atomic_futex.h (_M_load_and_test_until_impl): Return false for times before the epoch. * src/c++11/futex.cc (_M_futex_wait_until): Extend check for negative times to check for subsecond times. Add unlikely attribute. (_M_futex_wait_until_steady): Likewise. * testsuite/30_threads/future/members/118093.cc: New test. (cherry picked from commit 8ade3c3ea77e166f2873fb7ae57f9690e2b8d0e0) Diff: --- libstdc++-v3/include/bits/atomic_futex.h | 20 ++--- libstdc++-v3/src/c++11/futex.cc| 4 ++-- .../testsuite/30_threads/future/members/118093.cc | 26 ++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h index dd6541748739..390c3e500ded 100644 --- a/libstdc++-v3/include/bits/atomic_futex.h +++ b/libstdc++-v3/include/bits/atomic_futex.h @@ -170,11 +170,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool __equal, memory_order __mo, const chrono::time_point& __atime) { - auto __s = chrono::time_point_cast(__atime); - auto __ns = chrono::duration_cast(__atime - __s); - // XXX correct? + auto __d = __atime.time_since_epoch(); + if (__d < __d.zero()) [[__unlikely__]] + return false; + auto __s = chrono::duration_cast(__d); + auto __ns = chrono::duration_cast(__d - __s); return _M_load_and_test_until(__assumed, __operand, __equal, __mo, - true, __s.time_since_epoch(), __ns); + true, __s, __ns); } template @@ -183,11 +185,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool __equal, memory_order __mo, const chrono::time_point& __atime) { - auto __s = chrono::time_point_cast(__atime); - auto __ns = chrono::duration_cast(__atime - __s); - // XXX correct? + auto __d = __atime.time_since_epoch(); + if (__d < __d.zero()) [[__unlikely__]] + return false; + auto __s = chrono::duration_cast(__d); + auto __ns = chrono::duration_cast(__d - __s); return _M_load_and_test_until_steady(__assumed, __operand, __equal, __mo, - true, __s.time_since_epoch(), __ns); + true, __s, __ns); } public: diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc index ada2fdf3c417..6139fc354c61 100644 --- a/libstdc++-v3/src/c++11/futex.cc +++ b/libstdc++-v3/src/c++11/futex.cc @@ -128,7 +128,7 @@ namespace if (!futex_clock_realtime_unavailable.load(std::memory_order_relaxed)) { // futex sets errno=EINVAL for absolute timeouts before the epoch. - if (__s.count() < 0) + if (__s.count() < 0 || __ns.count() < 0) [[unlikely]] return false; syscall_timespec rt; @@ -204,7 +204,7 @@ namespace if (!futex_clock_monotonic_unavailable.load(std::memory_order_relaxed)) { // futex sets errno=EINVAL for absolute timeouts before the epoch. - if (__s.count() < 0) [[unlikely]] + if (__s.count() < 0 || __ns.count() < 0) [[unlikely]] return false; syscall_timespec rt; diff --git a/libstdc++-v3/testsuite/30_threads/future/members/118093.cc b/libstdc++-v3/testsuite/30_threads/future/members/118093.cc new file mode 100644 index ..2bb1e1c6dadc --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/future/members/118093.cc @@ -0,0 +1,26 @@ +// { dg-do run { target c++11 } } + +#include +#include + +void +test_sys() +{ + std::promise p; + std::chrono::system_clock::time_point tp(std::chrono::milliseconds{-10}); + (void) p.get_future().wait_until(tp); +} + +void +test_steady() +{ + std::promise p; + std::chrono::steady_clo
[gcc r15-6733] nvptx: PTX 'alloca' for '-mptx=7.3'+, '-march=sm_52'+ [PR65181]
https://gcc.gnu.org/g:3861d362ec7e3c50742fc43833fe9d8674f4070e commit r15-6733-g3861d362ec7e3c50742fc43833fe9d8674f4070e Author: Thomas Schwinge Date: Sat Dec 7 00:17:49 2024 +0100 nvptx: PTX 'alloca' for '-mptx=7.3'+, '-march=sm_52'+ [PR65181] ..., and use it for '-mno-soft-stack': PTX "native" stacks. PR target/65181 gcc/ * config/nvptx/nvptx.cc (nvptx_get_drap_rtx): Handle '!TARGET_SOFT_STACK'. * config/nvptx/nvptx.md (define_c_enum "unspec"): Add 'UNSPEC_STACKSAVE', 'UNSPEC_STACKRESTORE'. (define_expand "allocate_stack", define_expand "save_stack_block") (define_expand "save_stack_block"): Handle '!TARGET_SOFT_STACK', PTX 'alloca'. (define_insn "@nvptx_alloca_") (define_insn "@nvptx_stacksave_") (define_insn "@nvptx_stackrestore_"): New. * doc/invoke.texi (Nvidia PTX Options): Update '-msoft-stack', '-mno-soft-stack'. * doc/sourcebuild.texi (nvptx-specific attributes): Document 'nvptx_runtime_alloca_ptx'. (Add Options): Document 'nvptx_alloca_ptx'. gcc/testsuite/ * gcc.target/nvptx/alloca-1.c: Evolve into... * gcc.target/nvptx/alloca-1-O0.c: ... this, ... * gcc.target/nvptx/alloca-1-O1.c: ... this, and... * gcc.target/nvptx/alloca-1-sm_30.c: ... this. * gcc.target/nvptx/vla-1.c: Evolve into... * gcc.target/nvptx/vla-1-O0.c: ... this, ... * gcc.target/nvptx/vla-1-O1.c: ... this, and... * gcc.target/nvptx/vla-1-sm_30.c: ... this. * gcc.c-torture/execute/pr36321.c: Adjust. * gcc.target/nvptx/__builtin_alloca_0-1-O0.c: Likewise. * gcc.target/nvptx/__builtin_alloca_0-1-O1.c: Likewise. * gcc.target/nvptx/__builtin_stack_save___builtin_stack_restore-1.c: Likewise. * gcc.target/nvptx/softstack.c: Likewise. * gcc.target/nvptx/__builtin_stack_save___builtin_stack_restore-1-sm_30.c: New. * gcc.target/nvptx/alloca-2-O0.c: Likewise. * gcc.target/nvptx/alloca-3-O1.c: Likewise. * gcc.target/nvptx/alloca-4-O3.c: Likewise. * gcc.target/nvptx/alloca-5.c: Likewise. * lib/target-supports.exp (check_effective_target_alloca): Adjust. (check_nvptx_default_ptx_isa_target_architecture_at_least) (check_nvptx_runtime_ptx_isa_target_architecture_at_least) (check_effective_target_nvptx_runtime_alloca_ptx) (add_options_for_nvptx_alloca_ptx): New. libgomp/ * fortran.c (omp_get_device_from_uid_): Adjust. * testsuite/libgomp.oacc-fortran/privatized-ref-2.f90: Likewise. Diff: --- gcc/config/nvptx/nvptx.cc | 4 +- gcc/config/nvptx/nvptx.md | 92 +++--- gcc/doc/invoke.texi| 13 ++- gcc/doc/sourcebuild.texi | 6 ++ gcc/testsuite/gcc.c-torture/execute/pr36321.c | 3 + .../gcc.target/nvptx/__builtin_alloca_0-1-O0.c | 2 + .../gcc.target/nvptx/__builtin_alloca_0-1-O1.c | 2 + ...in_stack_save___builtin_stack_restore-1-sm_30.c | 28 ++ ..._builtin_stack_save___builtin_stack_restore-1.c | 8 +- gcc/testsuite/gcc.target/nvptx/alloca-1-O0.c | 49 ++ gcc/testsuite/gcc.target/nvptx/alloca-1-O1.c | 33 +++ .../nvptx/{alloca-1.c => alloca-1-sm_30.c} | 1 + gcc/testsuite/gcc.target/nvptx/alloca-2-O0.c | 12 +++ gcc/testsuite/gcc.target/nvptx/alloca-3-O1.c | 40 gcc/testsuite/gcc.target/nvptx/alloca-4-O3.c | 55 +++ gcc/testsuite/gcc.target/nvptx/alloca-5.c | 107 + gcc/testsuite/gcc.target/nvptx/softstack.c | 2 + gcc/testsuite/gcc.target/nvptx/vla-1-O0.c | 29 ++ gcc/testsuite/gcc.target/nvptx/vla-1-O1.c | 40 .../gcc.target/nvptx/{vla-1.c => vla-1-sm_30.c}| 1 + gcc/testsuite/lib/target-supports.exp | 105 +++- libgomp/fortran.c | 4 +- .../libgomp.oacc-fortran/privatized-ref-2.f90 | 10 -- 23 files changed, 611 insertions(+), 35 deletions(-) diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc index 5860b3df6dd7..060f45318f45 100644 --- a/gcc/config/nvptx/nvptx.cc +++ b/gcc/config/nvptx/nvptx.cc @@ -245,7 +245,7 @@ default_ptx_version_option (void) warp convergence. */ res = MAX (res, PTX_VERSION_6_0); - /* For sm_52+, pick at least 7.3. */ + /* For sm_52+, pick at least 7.3, to enable PTX 'alloca'. */ if (ptx_isa_option >= PTX_ISA_SM52) res = MAX (res, PTX_VERSION_7_3); @@ -1797,7 +1797,7 @@ nvptx_function_ok_for_sibcall (tree, tree) static rtx nvptx_get_drap_rtx (void)
[gcc r15-6743] testsuite: Require trampolines for gcc.dg/pr118325.c
https://gcc.gnu.org/g:04f4ac9218259a1508f9a86ca98cf1d36cab2df2 commit r15-6743-g04f4ac9218259a1508f9a86ca98cf1d36cab2df2 Author: Dimitar Dimitrov Date: Thu Jan 9 20:18:08 2025 +0200 testsuite: Require trampolines for gcc.dg/pr118325.c The test case uses a nested function, which is not supported by some targets. gcc/testsuite/ChangeLog: * gcc.dg/pr118325.c: Require effective target trampolines. Signed-off-by: Dimitar Dimitrov Diff: --- gcc/testsuite/gcc.dg/pr118325.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/gcc.dg/pr118325.c b/gcc/testsuite/gcc.dg/pr118325.c index 74f92cc2bb6e..7129bc9b9be9 100644 --- a/gcc/testsuite/gcc.dg/pr118325.c +++ b/gcc/testsuite/gcc.dg/pr118325.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target trampolines } */ /* { dg-options "-std=gnu17 -fchecking" } */ void f(void*);
[gcc r14-11162] arm: [MVE intrinsics] Fix support for predicate constants [PR target/114801]
https://gcc.gnu.org/g:61de759f943ce0a5981affeee19debc82ec43744 commit r14-11162-g61de759f943ce0a5981affeee19debc82ec43744 Author: Christophe Lyon Date: Sun Nov 24 18:08:48 2024 + arm: [MVE intrinsics] Fix support for predicate constants [PR target/114801] This backport is a cherry pick of commit 2089009210a1774c37e527ead8bbcaaa1a7a9d2d, with a small change needed because force_lowpart_subreg does not exist in gcc-14: the patch replaces it with the equivalent: -x = force_lowpart_subreg (mode, x, GET_MODE (x)); +{ + auto byte = subreg_lowpart_offset (mode, GET_MODE (x)); + x = force_subreg (mode, x, GET_MODE (x), byte); +} In this PR, we have to handle a case where MVE predicates are supplied as a const_int, where individual predicates have illegal boolean values (such as 0xc for a 4-bit boolean predicate). To avoid the ICE, fix the constant (any non-zero value is converted to all 1s) and emit a warning. On MVE, V8BI and V4BI multi-bit masks are interpreted byte-by-byte at instruction level, but end-users should describe lanes rather than bytes (so all bytes of a true-predicated lane should be '1'), see the section on MVE intrinsics in the Arm ACLE specification. Since force_lowpart_subreg cannot handle const_int (because they have VOID mode), use gen_lowpart on them, force_lowpart_subreg otherwise. 2024-11-20 Christophe Lyon Jakub Jelinek PR target/114801 gcc/ * config/arm/arm-mve-builtins.cc (function_expander::add_input_operand): Handle CONST_INT predicates. gcc/testsuite/ * gcc.target/arm/mve/pr108443.c: Update predicate constant. * gcc.target/arm/mve/pr108443-run.c: Likewise. * gcc.target/arm/mve/pr114801.c: New test. (cherry picked from commit 2089009210a1774c37e527ead8bbcaaa1a7a9d2d) Diff: --- gcc/config/arm/arm-mve-builtins.cc | 35 +- gcc/testsuite/gcc.target/arm/mve/pr108443-run.c | 2 +- gcc/testsuite/gcc.target/arm/mve/pr108443.c | 4 +-- gcc/testsuite/gcc.target/arm/mve/pr114801.c | 39 + 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc index e1826ae40527..c57bf0844b05 100644 --- a/gcc/config/arm/arm-mve-builtins.cc +++ b/gcc/config/arm/arm-mve-builtins.cc @@ -2107,7 +2107,40 @@ function_expander::add_input_operand (insn_code icode, rtx x) mode = GET_MODE (x); } else if (VALID_MVE_PRED_MODE (mode)) -x = gen_lowpart (mode, x); +{ + if (CONST_INT_P (x)) + { + if (mode == V8BImode || mode == V4BImode) + { + /* In V8BI or V4BI each element has 2 or 4 bits, if those bits +aren't all the same, gen_lowpart might ICE. Canonicalize all +the 2 or 4 bits to all ones if any of them is non-zero. V8BI +and V4BI multi-bit masks are interpreted byte-by-byte at +instruction level, but such constants should describe lanes, +rather than bytes. See the section on MVE intrinsics in the +Arm ACLE specification. */ + unsigned HOST_WIDE_INT xi = UINTVAL (x); + xi |= ((xi & 0x) << 1) | ((xi & 0x) >> 1); + if (mode == V4BImode) + xi |= ((xi & 0x) << 2) | ((xi & 0x) >> 2); + if (xi != UINTVAL (x)) + warning_at (location, 0, "constant predicate argument %d" + " (%wx) does not map to %d lane numbers," + " converted to %wx", + opno, UINTVAL (x) & 0x, + mode == V8BImode ? 8 : 4, + xi & 0x); + + x = gen_int_mode (xi, HImode); + } + x = gen_lowpart (mode, x); + } + else + { + auto byte = subreg_lowpart_offset (mode, GET_MODE (x)); + x = force_subreg (mode, x, GET_MODE (x), byte); + } +} m_ops.safe_grow (m_ops.length () + 1, true); create_input_operand (&m_ops.last (), x, mode); diff --git a/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c b/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c index cb4b45bd3056..b894f019b8bb 100644 --- a/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c +++ b/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c @@ -16,7 +16,7 @@ __attribute__ ((noipa)) partial_write (uint32_t *a, uint32x4_t v, unsigned short int main (void) { - unsigned short p = 0x00CC; + unsigned short p = 0x00FF; uint32_t a[] = {0, 0, 0, 0}; uint32_t b[] = {0, 0, 0, 0}; uint32x4_t v = vdupq_n_u32 (0xU); diff --git a/gcc/testsuite/gcc.target/arm/mve/pr108443.c b/gcc/testsuite/gcc.target/arm/mve/pr10
[gcc r13-9288] libstdc++: Fix incorrect DocBook element in manual
https://gcc.gnu.org/g:4498d4817461a9780e96557ced23fbf814ef494c commit r13-9288-g4498d4817461a9780e96557ced23fbf814ef494c Author: Jonathan Wakely Date: Mon Jan 6 21:29:54 2025 + libstdc++: Fix incorrect DocBook element in manual libstdc++-v3/ChangeLog: * doc/xml/manual/evolution.xml: Replace invalid elements with . * doc/html/*: Regenerate. (cherry picked from commit 720945e8bcbc86285fb3b176627f05ada8a7d136) Diff: --- libstdc++-v3/doc/html/manual/api.html | 4 ++-- libstdc++-v3/doc/xml/manual/evolution.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html index bc3d38887ec1..1d083066a97d 100644 --- a/libstdc++-v3/doc/html/manual/api.html +++ b/libstdc++-v3/doc/html/manual/api.html @@ -483,8 +483,8 @@ the process. Calling a std::bind result as volatile is ill-formed for C++20 and later. 13 -Tunablesglibcxx.eh_pool.obj_count and -glibcxx.eh_pool.obj_size were added. +Tunables glibcxx.eh_pool.obj_count and +glibcxx.eh_pool.obj_size were added. Static library libstdc++exp.a was added to provide the symbols for the experimental C++ Contracts support.13.3 Symbols for the Filesystem TS and C++23diff --git a/libstdc++-v3/doc/xml/manual/evolution.xml b/libstdc++-v3/doc/xml/manual/evolution.xml index 55d651348f76..511702d77fef 100644 --- a/libstdc++-v3/doc/xml/manual/evolution.xml +++ b/libstdc++-v3/doc/xml/manual/evolution.xml @@ -1096,8 +1096,8 @@ and later. 13 -Tunables glibcxx.eh_pool.obj_count and -glibcxx.eh_pool.obj_size were added. +Tunables glibcxx.eh_pool.obj_count and +glibcxx.eh_pool.obj_size were added. Static library libstdc++exp.a was added
[gcc r15-6735] arm: [MVE intrinsics] Another fix for moves of tuples (PR target/118131)
https://gcc.gnu.org/g:823101941530d1aa0837f4e74436ea3e027c9241 commit r15-6735-g823101941530d1aa0837f4e74436ea3e027c9241 Author: Christophe Lyon Date: Fri Dec 20 20:31:29 2024 + arm: [MVE intrinsics] Another fix for moves of tuples (PR target/118131) Commit r15-6389-g670df03e5294a3 only partially fixed support for moves of large modes: despite the introduction of V2x* and V4x* modes in r15-6245-g4f4e13dd235b to support MVE tuples, we still need to support TI, OI and XI modes, which appear for instance in gcc.dg/pr100887.c. The problem was noticed when running the testsuite with -mthumb/-march=armv8.1-m.main+mve.fp+fp.dp/-mtune=cortex-m55/-mfloat-abi=hard/-mfpu=auto where several tests would ICE in output_move_neon. gcc/ChangeLog: PR target/118131 * config/arm/arm.h (VALID_MVE_STRUCT_MODE): Accept TI, OI and XI modes again. Diff: --- gcc/config/arm/arm.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index a06ac6f48bad..73ca00a8de35 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1128,7 +1128,10 @@ extern const int arm_arch_cde_coproc_bits[]; || (MODE) == CImode || (MODE) == XImode) #define VALID_MVE_STRUCT_MODE(MODE)\ - ((MODE) == V2x16QImode \ + ((MODE) == TImode\ + || (MODE) == OImode \ + || (MODE) == XImode \ + || (MODE) == V2x16QImode\ || (MODE) == V2x8HImode \ || (MODE) == V2x4SImode \ || (MODE) == V2x8HFmode \
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] reuse left-hand mask to decode right-hand xor operand
https://gcc.gnu.org/g:5ce16b0bfb202d06271e082af972e4a7e303e292 commit 5ce16b0bfb202d06271e082af972e4a7e303e292 Author: Alexandre Oliva Date: Thu Jan 9 11:57:03 2025 -0300 [ifcombine] reuse left-hand mask to decode right-hand xor operand Diff: --- gcc/gimple-fold.cc | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index c8a726e0ae3f..e5c9ec6709a3 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7519,8 +7519,9 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, - *XOR_P will be set to TRUE, and the left-hand operand of the XOR will be - decoded. If *XOR_P is TRUE, XOR_CMP_OP is supposed to be NULL, and then the + *XOR_P will be set to TRUE, *XOR_PAND_MASK will be copied from *PAND_MASK, + and the left-hand operand of the XOR will be decoded. If *XOR_P is TRUE, + XOR_CMP_OP and XOR_PAND_MASK are supposed to be NULL, and then the right-hand operand of the XOR will be decoded. *LOAD is set to the load stmt of the innermost reference, if any, @@ -7537,7 +7538,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpos, bool *punsignedp, bool *preversep, bool *pvolatilep, wide_int *pand_mask, bool *psignbit, - bool *xor_p, tree *xor_cmp_op, + bool *xor_p, tree *xor_cmp_op, wide_int *xor_pand_mask, gimple **load, location_t loc[4]) { tree exp = *pexp; @@ -7598,15 +7599,14 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, and_mask = *pand_mask; /* Turn (a ^ b) [!]= 0 into a [!]= b. */ - if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops) - && uniform_integer_cst_p (res_ops[1])) + if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops)) { /* No location recorded for this one, it's entirely subsumed by the compare. */ if (*xor_p) { exp = res_ops[1]; - gcc_checking_assert (!xor_cmp_op); + gcc_checking_assert (!xor_cmp_op && !xor_pand_mask); } else if (!xor_cmp_op) /* Not much we can do when xor appears in the right-hand compare @@ -7617,6 +7617,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, *xor_p = true; exp = res_ops[0]; *xor_cmp_op = *pexp; + *xor_pand_mask = *pand_mask; } } @@ -8135,19 +8136,21 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, bool l_xor = false, r_xor = false; ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos, &ll_unsignedp, &ll_reversep, &volatilep, -&ll_and_mask, &ll_signbit, &l_xor, &lr_arg, +&ll_and_mask, &ll_signbit, +&l_xor, &lr_arg, &lr_and_mask, &ll_load, ll_loc); lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos, &lr_unsignedp, &lr_reversep, &volatilep, -&lr_and_mask, &lr_signbit, &l_xor, 0, +&lr_and_mask, &lr_signbit, &l_xor, 0, 0, &lr_load, lr_loc); rl_inner = decode_field_reference (&rl_arg, &rl_bitsize, &rl_bitpos, &rl_unsignedp, &rl_reversep, &volatilep, -&rl_and_mask, &rl_signbit, &r_xor, &rr_arg, +&rl_and_mask, &rl_signbit, +&r_xor, &rr_arg, &rr_and_mask, &rl_load, rl_loc); rr_inner = decode_field_reference (&rr_arg, &rr_bitsize, &rr_bitpos, &rr_unsignedp, &rr_reversep, &volatilep, -&rr_and_mask, &rr_signbit, &r_xor, 0, +&rr_and_mask, &rr_signbit, &r_xor, 0, 0, &rr_load, rr_loc); /* It must be true that the inner operation on the lhs of each @@ -8622,7 +8625,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, xlr_bitpos); else lr_mask = wi::shifted_mask (xlr_bitpos, lr_bitsize, false, rnprec); - if (rl_and_mask.get_precision ()) + if (rr_and_mask.get_precision ()) rr_mask = wi::lshift (wide_int::from (rr_and_mask, rnprec, UNSIGNED), xrr_bitpos); else
[gcc/aoliva/heads/testme] (3 commits) [ifcombine] adjust for narrowing converts before shifts [PR
The branch 'aoliva/heads/testme' was updated to point to: 9f16aa5e1808... [ifcombine] adjust for narrowing converts before shifts [PR It previously pointed to: 0a21efd561c8... [ifcombine] fix mask variable test to match use Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 0a21efd... [ifcombine] fix mask variable test to match use a5809d9... [ifcombine] adjust for narrowing converts before shifts [PR Summary of changes (added commits): --- 9f16aa5... [ifcombine] adjust for narrowing converts before shifts [PR 5ce16b0... [ifcombine] reuse left-hand mask to decode right-hand xor o c693789... [ifcombine] fix mask variable test to match use
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] adjust for narrowing converts before shifts [PR118206]
https://gcc.gnu.org/g:9f16aa5e1808bfdcd1daeacb1ed4272201585830 commit 9f16aa5e1808bfdcd1daeacb1ed4272201585830 Author: Alexandre Oliva Date: Thu Jan 9 03:05:41 2025 -0300 [ifcombine] adjust for narrowing converts before shifts [PR118206] A narrowing conversion and a shift both drop bits from the loaded value, but we need to take into account which one comes first to get the right number of bits and mask. While at that, don't require a constant to recognize a xor, that was added in error. Fold when applying masks to parts, comparing the parts, and combining the results, in the odd chance either mask happens to be zero. for gcc/ChangeLog PR tree-optimization/118206 * gimple-fold.cc (decode_field_reference): Account for upper bits dropped by narrowing conversions whether before or after a right shift. Don't require an integer for xor. (fold_truth_andor_for_ifcombine): Fold masks, compares, and combined results. for gcc/testsuite/ChangeLog PR tree-optimization/118206 * gcc.dg/field-merge-18.c: New. Diff: --- gcc/gimple-fold.cc| 39 - gcc/testsuite/gcc.dg/field-merge-18.c | 46 +++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index e5c9ec6709a3..20b5024d861d 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7548,6 +7548,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, int shiftrt = 0; tree res_ops[2]; machine_mode mode; + bool convert_before_shift = false; *load = NULL; *psignbit = false; @@ -7652,6 +7653,12 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (*load) loc[3] = gimple_location (*load); exp = res_ops[0]; + /* This looks backwards, but we're going back the def chain, so if we +find the conversion here, after finding a shift, that's because the +convert appears before the shift, and we should thus adjust the bit +pos and size because of the shift after adjusting it due to type +conversion. */ + convert_before_shift = true; } /* Identify the load, if there is one. */ @@ -7694,6 +7701,15 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, *pvolatilep = volatilep; /* Adjust shifts... */ + if (convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) +{ + HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); + if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) + *pbitpos += excess; + *pbitsize -= excess; +} + if (shiftrt) { if (!*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -7702,7 +7718,8 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, } /* ... and bit position. */ - if (outer_type && *pbitsize > TYPE_PRECISION (outer_type)) + if (!convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) { HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -8380,6 +8397,8 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region, ll_align, BITS_PER_WORD, volatilep, &lnmode)) l_split_load = false; + /* ??? If ll and rl share the same load, reuse that? + See PR 118206 -> gcc.dg/field-merge-18.c */ else { /* Consider the possibility of recombining loads if any of the @@ -8760,11 +8779,11 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, /* Apply masks. */ for (int j = 0; j < 2; j++) if (mask[j] != wi::mask (0, true, mask[j].get_precision ())) - op[j] = build2_loc (locs[j][2], BIT_AND_EXPR, type, - op[j], wide_int_to_tree (type, mask[j])); + op[j] = fold_build2_loc (locs[j][2], BIT_AND_EXPR, type, + op[j], wide_int_to_tree (type, mask[j])); - cmp[i] = build2_loc (i ? rloc : lloc, wanted_code, truth_type, - op[0], op[1]); + cmp[i] = fold_build2_loc (i ? rloc : lloc, wanted_code, truth_type, + op[0], op[1]); } /* Reorder the compares if needed. */ @@ -8776,7 +8795,15 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (parts == 1) result = cmp[0]; else if (!separatep || !maybe_separate) -result = build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]); +{ + /* Only fold if any of the cmp is known, otherwise we may lose the +sequence point, and that may prevent further optimizations. */ + if (TREE_CODE (cmp[0]) == INT
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] fix mask variable test to match use
https://gcc.gnu.org/g:c693789712be162638987e763f709910af43a061 commit c693789712be162638987e763f709910af43a061 Author: Alexandre Oliva Date: Thu Jan 9 10:23:50 2025 -0300 [ifcombine] fix mask variable test to match use Diff:
[gcc r15-6728] ree: Skip extension on fixed register
https://gcc.gnu.org/g:14879ba89a4f9d2263472dca1423b584c1236586 commit r15-6728-g14879ba89a4f9d2263472dca1423b584c1236586 Author: H.J. Lu Date: Wed Jan 8 20:50:04 2025 +0800 ree: Skip extension on fixed register Skip extension on fixed register since we can't turn (insn 27 26 139 2 (parallel [ (set (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int 16 [0x10]))) (clobber (reg:CC 17 flags)) ]) "x.ii":14:17 discrim 1 283 {*addsi_1} (expr_list:REG_ARGS_SIZE (const_int 0 [0]) (nil))) ... (insn 43 125 74 2 (set (reg/f:DI 6 bp [145]) (zero_extend:DI (reg/f:SI 7 sp))) "x.ii":15:9 175 {*zero_extendsidi2} (nil)) into (insn 27 26 155 2 (parallel [ (set (reg:DI 6 bp) (zero_extend:DI (plus:SI (reg/f:SI 7 sp) (const_int 16 [0x10] (clobber (reg:CC 17 flags)) ]) "x.ii":14:17 discrim 1 296 {addsi_1_zext} (expr_list:REG_ARGS_SIZE (const_int 0 [0]) (nil))) (insn 155 27 139 2 (set (reg:DI 7 sp) (reg:DI 6 bp)) "x.ii":14:17 discrim 1 -1 (nil)) without updating stack frame info. gcc/ PR rtl-optimization/118266 * ree.cc (add_removable_extension): Skip extension on fixed register. gcc/testsuite/ PR rtl-optimization/118266 * gcc.target/i386/pr118266.c: New test. Signed-off-by: H.J. Lu Diff: --- gcc/ree.cc | 12 gcc/testsuite/gcc.target/i386/pr118266.c | 27 +++ 2 files changed, 39 insertions(+) diff --git a/gcc/ree.cc b/gcc/ree.cc index a44e8e5625b6..bcce9da44af0 100644 --- a/gcc/ree.cc +++ b/gcc/ree.cc @@ -1113,6 +1113,18 @@ add_removable_extension (const_rtx expr, rtx_insn *insn, struct df_link *defs, *def; ext_cand *cand; + if (fixed_regs[REGNO (reg)]) + { + if (dump_file) + { + fprintf (dump_file, "Cannot eliminate extension:\n"); + print_rtl_single (dump_file, insn); + fprintf (dump_file, " because extension on fixed register" + " isn't supported.\n"); + } + return; + } + /* Zero-extension of an undefined value is partly defined (it's completely undefined for sign-extension, though). So if there exists a path from the entry to this zero-extension that leaves this register diff --git a/gcc/testsuite/gcc.target/i386/pr118266.c b/gcc/testsuite/gcc.target/i386/pr118266.c new file mode 100644 index ..4c83cd1a561a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr118266.c @@ -0,0 +1,27 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-require-effective-target fopenacc } */ +/* { dg-options "-O2 -mx32 -fopenacc" } */ + +typedef struct { + int a; + int b; + int c; +} mystruct; +int main_j; +int +main() +{ + mystruct *m = (mystruct *)__builtin_malloc (2*sizeof (mystruct)), *mref = m; +#pragma acc enter data copyin(m[1]) + for (int i; i < 9; i++) { +#pragma acc parallel +for (; main_j;) + ; +#pragma acc parallel loop copy(mref->b, m->c) +for (main_j = 0; main_j < 4; main_j++) + ; + } +#pragma acc data copyout(m[ : 1]) + __builtin_free(m); +}
[gcc r14-11141] c-family: Fix ICE with __sync_*_and_* on _BitInt [PR117641]
https://gcc.gnu.org/g:6d0503f87898617756bd423b3fe9d14b2d4e76c6 commit r14-11141-g6d0503f87898617756bd423b3fe9d14b2d4e76c6 Author: Jakub Jelinek Date: Tue Nov 19 20:36:00 2024 +0100 c-family: Fix ICE with __sync_*_and_* on _BitInt [PR117641] Only __atomic_* builtins are meant to work on arbitrary _BitInt types (if not supported in hw we emit a CAS loop which uses __atomic_load_* in that case), the compatibility __sync_* builtins work only if there is a corresponding normal integral type (for _BitInt on 32-bit ARM we'll need to limit even that to no padding, because the padding bits are well defined there and the hw or libatomic __sync_* APIs don't guarantee that), IMHO people shouldn't mix very old APIs with very new ones and I don't see a replacement for the __atomic_load_*. For size > 16 that is how it already correctly behaves, in the hunk shown in the patch it is immediately followed by if (fetch && !orig_format && TREE_CODE (type) == BITINT_TYPE) return -1; which returns -1 for the __atomic_* builtins (i.e. !orig_format), which causes caller to use atomic_bitint_fetch_using_cas_loop, and otherwise does diagnostic and return 0 (which causes caller to punt). But for size == 16 if TImode isn't suipported (i.e. mostly 32-bit arches), we return (correctly) -1 if !orig_format, so again force atomic_bitint_fetch_using_cas_loop on those arches for e.g. _BitInt(115), but for orig_format the function returns 16 as if it could do 16 byte __sync_*_and_* (which it can't because TImode isn't supported; for 16 byte it can only do (perhaps using libatomic) normal compare and swap). So we need to error and return 0, rather than return 16. The following patch ensures that. 2024-11-19 Jakub Jelinek PR c/117641 * c-common.cc (sync_resolve_size): For size == 16 fetch of BITINT_TYPE if TImode isn't supported scalar mode diagnose and return 0 if orig_format instead of returning 16. * gcc.dg/bitint-115.c: New test. (cherry picked from commit 8663fc1c2826c86455e51e58203cb95b2b1407e3) Diff: --- gcc/c-family/c-common.cc | 7 +-- gcc/testsuite/gcc.dg/bitint-115.c | 9 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index aae998d0f738..661115bf1db1 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -7384,10 +7384,13 @@ sync_resolve_size (tree function, vec *params, bool fetch, size = tree_to_uhwi (TYPE_SIZE_UNIT (type)); if (size == 16 && fetch - && !orig_format && TREE_CODE (type) == BITINT_TYPE && !targetm.scalar_mode_supported_p (TImode)) -return -1; +{ + if (!orig_format) + return -1; + goto incompatible; +} if (size == 1 || size == 2 || size == 4 || size == 8 || size == 16) return size; diff --git a/gcc/testsuite/gcc.dg/bitint-115.c b/gcc/testsuite/gcc.dg/bitint-115.c new file mode 100644 index ..700fd6c5b517 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-115.c @@ -0,0 +1,9 @@ +/* PR c/117641 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-std=c23" } */ + +void +foo (_BitInt(128) *b) +{ + __sync_fetch_and_add (b, 1); /* { dg-error "incompatible" "" { target { ! int128 } } } */ +}
[gcc r14-11140] expand: Fix up ICE on VCE from _Complex types to _BitInt [PR117458]
https://gcc.gnu.org/g:98eabdaddc660906f59b8b3db53703588f72f39f commit r14-11140-g98eabdaddc660906f59b8b3db53703588f72f39f Author: Jakub Jelinek Date: Tue Nov 19 10:26:44 2024 +0100 expand: Fix up ICE on VCE from _Complex types to _BitInt [PR117458] extract_bit_field can't handle extraction of non-mode precision from complex mode operands which don't live in memory, e.g. gen_lowpart crashes on those. The following patch in that case defers the extract_bit_field call until op0 is forced into memory. 2024-11-19 Jakub Jelinek PR middle-end/117458 * expr.cc (expand_expr_real_1) : Don't call extract_bit_field if op0 has complex mode and isn't a MEM, instead first force op0 into memory and then call extract_bit_field. * gcc.dg/bitint-116.c: New test. (cherry picked from commit 694613a7f9adfa9c87e733adc63839c8801f2b5c) Diff: --- gcc/expr.cc | 9 - gcc/testsuite/gcc.dg/bitint-116.c | 11 +++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index 414b7fda7545..034d036b188c 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -12464,7 +12464,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, op0 = convert_modes (mode, GET_MODE (op0), op0, TYPE_UNSIGNED (TREE_TYPE (treeop0))); /* If the output type is a bit-field type, do an extraction. */ - else if (reduce_bit_field && mode != BLKmode) + else if (reduce_bit_field + && mode != BLKmode + && (MEM_P (op0) || !COMPLEX_MODE_P (GET_MODE (op0 return extract_bit_field (op0, TYPE_PRECISION (type), 0, TYPE_UNSIGNED (type), NULL_RTX, mode, mode, false, NULL); @@ -12488,6 +12490,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, emit_move_insn (target, op0); op0 = target; + + if (reduce_bit_field && mode != BLKmode) + return extract_bit_field (op0, TYPE_PRECISION (type), 0, + TYPE_UNSIGNED (type), NULL_RTX, + mode, mode, false, NULL); } /* If OP0 is (now) a MEM, we need to deal with alignment issues. If the diff --git a/gcc/testsuite/gcc.dg/bitint-116.c b/gcc/testsuite/gcc.dg/bitint-116.c new file mode 100644 index ..9af5d723d058 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-116.c @@ -0,0 +1,11 @@ +/* PR middle-end/117458 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=c23 -O2" } */ + +typedef _BitInt(33) B __attribute__((may_alias)); + +_BitInt(33) +foo (_Complex float x) +{ + return *(B *)&x; +}
[gcc r14-11139] bitintlower: Handle PAREN_EXPR [PR117459]
https://gcc.gnu.org/g:e3b2c176d3e9f721185532a4a393814316172410 commit r14-11139-ge3b2c176d3e9f721185532a4a393814316172410 Author: Jakub Jelinek Date: Tue Nov 19 10:25:57 2024 +0100 bitintlower: Handle PAREN_EXPR [PR117459] The following patch handles PAREN_EXPR in bitint lowering, and handles it as an optimization barrier, so that temporary arithmetics from PAREN_EXPR isn't mixed with temporary arithmetics from outside of the PAREN_EXPR. 2024-11-19 Jakub Jelinek PR middle-end/117459 * gimple-lower-bitint.cc (bitint_large_huge::handle_stmt, bitint_large_huge::lower_stmt): Handle PAREN_EXPR. * gcc.dg/torture/bitint-74.c: New test. (cherry picked from commit 600cab162c561c3061317c998972b0ed1b681d5b) Diff: --- gcc/gimple-lower-bitint.cc | 5 - gcc/testsuite/gcc.dg/torture/bitint-74.c | 27 +++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 58deaf253e93..e4e628b786b9 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -2142,6 +2142,7 @@ bitint_large_huge::handle_stmt (gimple *stmt, tree idx) idx), gimple_assign_rhs2 (stmt), idx); case SSA_NAME: + case PAREN_EXPR: case INTEGER_CST: return handle_operand (gimple_assign_rhs1 (stmt), idx); CASE_CONVERT: @@ -5606,7 +5607,9 @@ bitint_large_huge::lower_stmt (gimple *stmt) || gimple_store_p (stmt) || gimple_assign_load_p (stmt) || eq_p - || mergeable_cast_p) + || mergeable_cast_p + || (is_gimple_assign (stmt) + && gimple_assign_rhs_code (stmt) == PAREN_EXPR)) { lhs = lower_mergeable_stmt (stmt, cmp_code, cmp_op1, cmp_op2); if (!eq_p) diff --git a/gcc/testsuite/gcc.dg/torture/bitint-74.c b/gcc/testsuite/gcc.dg/torture/bitint-74.c new file mode 100644 index ..f9abe2367656 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-74.c @@ -0,0 +1,27 @@ +/* PR middle-end/117459 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#if __BITINT_MAXWIDTH__ >= 255 +_BitInt(255) b, c, d; + +_BitInt(255) +foo () +{ + return __builtin_assoc_barrier (b + c) + d; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 255 + b = 3162082328713384445049140446737468449630746270013462291267283007210433157591wb; + c = 1299851477887328635550261966833804427562203752161174274777867442907371807wb; + d = 5016523343681809792116154509287659112784399275423992541459788346980443294044wb; + if (foo () != 21177121227873081565800845217991961366842707749189616007001849221633783823442wb) +__builtin_abort (); +#endif +}
[gcc r14-11148] docs: Fix up __sync_* documentation [PR117642]
https://gcc.gnu.org/g:5d7186159f678f2dd42cb9468d897d757e06a101 commit r14-11148-g5d7186159f678f2dd42cb9468d897d757e06a101 Author: Jakub Jelinek Date: Thu Nov 28 14:31:44 2024 +0100 docs: Fix up __sync_* documentation [PR117642] The PR14311 commit which added support for __sync_* builtins documented that there is a warning if a particular operation cannot be implemented. But that commit nor anything later on implemented such warning, it was always silent generation of the mentioned calls (which can in most cases result in linker errors of course because those functions aren't implemented anywhere, in libatomic or elsewhere in code shipped in gcc). So, the following patch just adjust the documentation to match the implementation. 2024-11-28 Jakub Jelinek PR target/117642 * doc/extend.texi: Remove documentation of warning for unimplemented __sync_* operations, such warning has never been implemented. (cherry picked from commit 0dcc09a8b5eb275ce939daad2bdfc7076ae1863c) Diff: --- gcc/doc/extend.texi | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e290265d68d3..14834fc4a188 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13219,16 +13219,11 @@ builtins (@pxref{__atomic Builtins}). They should not be used for new code which should use the @samp{__atomic} builtins instead. Not all operations are supported by all target processors. If a particular -operation cannot be implemented on the target processor, a warning is -generated and a call to an external function is generated. The external -function carries the same name as the built-in version, -with an additional suffix +operation cannot be implemented on the target processor, a call to an +external function is generated. The external function carries the same name +as the built-in version, with an additional suffix @samp{_@var{n}} where @var{n} is the size of the data type. -@c ??? Should we have a mechanism to suppress this warning? This is almost -@c useful for implementing the operation under the control of an external -@c mutex. - In most cases, these built-in functions are considered a @dfn{full barrier}. That is, no memory operand is moved across the operation, either forward or
[gcc r14-11136] store-merging: Apply --param=store-merging-max-size= in more spots [PR117439]
https://gcc.gnu.org/g:c56b465044b2bd986cdb80eff90f6807a78a3c60 commit r14-11136-gc56b465044b2bd986cdb80eff90f6807a78a3c60 Author: Jakub Jelinek Date: Wed Nov 6 10:22:13 2024 +0100 store-merging: Apply --param=store-merging-max-size= in more spots [PR117439] Store merging assumes a merged region won't be too large. The assumption is e.g. in using inappropriate types in various spots (e.g. int for bit sizes and bit positions in a few spots, or unsigned for the total size in bytes of the merged region), in doing XNEWVEC for the whole total size of the merged region and preparing everything in there and even that XALLOCAVEC in two spots. The last case is what was breaking the test below in the patch, 64MB XALLOCAVEC is just too large, but even with that fixed I think we just shouldn't be merging gigabyte large merge groups. We already have --param=store-merging-max-size= parameter, right now with 65536 bytes maximum (if needed, we could raise that limit a little bit). That parameter is currently used when merging two adjacent stores, if the size of the already merged bitregion together with the new store's bitregion is above that limit, we don't merge those. I guess initially that was sufficient, at that time a store was always limited to MAX_BITSIZE_MODE_ANY_INT bits. But later on we've added support for empty ctors ({} and even later {CLOBBER}) and also added another spot where we merge further stores into the merge group, if there is some overlap, we can merge various other stores in one coalesce_immediate_stores iteration. And, we weren't applying the --param=store-merging-max-size= parameter in either of those cases. So a single store can be gigabytes long, and if there is some overlap, we can extend the region again to gigabytes in size. The following patch attempts to apply that parameter even in those cases. So, if testing if it should merge the merged group with info (we've already punted if those together are above the parameter) and some other stores, the first two hunks just punt if that would make the merge group too large. And the third hunk doesn't even add stores which are over the limit. 2024-11-06 Jakub Jelinek PR tree-optimization/117439 * gimple-ssa-store-merging.cc (imm_store_chain_info::coalesce_immediate_stores): Punt if merging of any of the additional overlapping stores would result in growing the bitregion size over param_store_merging_max_size. (pass_store_merging::process_store): Terminate all aliasing chains for stores with bitregion larger than param_store_merging_max_size. * g++.dg/opt/pr117439.C: New test. (cherry picked from commit 6d8764cc1f938b3edee4ac26dc5d4d8dca74dc54) Diff: --- gcc/gimple-ssa-store-merging.cc | 21 - gcc/testsuite/g++.dg/opt/pr117439.C | 16 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc index 429c18c1c78d..782be1c9fbea 100644 --- a/gcc/gimple-ssa-store-merging.cc +++ b/gcc/gimple-ssa-store-merging.cc @@ -3245,6 +3245,10 @@ imm_store_chain_info::coalesce_immediate_stores () unsigned int min_order = first_order; unsigned first_nonmergeable_int_order = ~0U; unsigned HOST_WIDE_INT this_end = end; + unsigned HOST_WIDE_INT this_bitregion_start + = new_bitregion_start; + unsigned HOST_WIDE_INT this_bitregion_end + = new_bitregion_end; k = i; first_nonmergeable_order = ~0U; for (unsigned int j = i + 1; j < len; ++j) @@ -3268,6 +3272,19 @@ imm_store_chain_info::coalesce_immediate_stores () k = 0; break; } + if (info2->bitregion_start + < this_bitregion_start) + this_bitregion_start = info2->bitregion_start; + if (info2->bitregion_end + > this_bitregion_end) + this_bitregion_end = info2->bitregion_end; + if (((this_bitregion_end - this_bitregion_start + + 1) / BITS_PER_UNIT) + > (unsigned) param_store_merging_max_size) + { + k = 0; + break; + } k = j; min_order = MIN (min_order, info2->order);
[gcc r14-11138] m2: Fix up dependencies some more
https://gcc.gnu.org/g:04d7d02d5842992ed88955211bf1d6299f38b877 commit r14-11138-g04d7d02d5842992ed88955211bf1d6299f38b877 Author: Jakub Jelinek Date: Sat Nov 9 16:45:44 2024 +0100 m2: Fix up dependencies some more Every now and then my x86_64-linux bootstrap fails due to missing dependencies somewhere in m2, usually during stage3. I'm using make -j32 and run 2 bootstraps concurrently (x86_64-linux and i686-linux) on the same box. Last night the same happened to me again, with the first error In file included from ./tm.h:29, from ../../gcc/backend.h:28, from ../../gcc/m2/gm2-gcc/gcc-consolidation.h:27, from m2/gm2-compiler-boot/M2AsmUtil.c:26: ../../gcc/config/i386/i386.h:2484:10: fatal error: insn-attr-common.h: No such file or directory 2484 | #include "insn-attr-common.h" | ^~~~ compilation terminated. make[3]: *** [../../gcc/m2/Make-lang.in:1576: m2/gm2-compiler-boot/M2AsmUtil.o] Error 1 make[3]: *** Waiting for unfinished jobs Now, gcc/Makefile.in has a general rule: # In order for parallel make to really start compiling the expensive # objects from $(OBJS) as early as possible, build all their # prerequisites strictly before all objects. $(ALL_HOST_OBJS) : | $(generated_files) which ensures that everything that might depend on the generated files waits for those to be generated. The above error clearly shows that such waiting didn't happen for m2/gm2-compiler-boot/M2AsmUtil.o and some others. ALL_HOST_OBJS includes $(ALL_HOST_FRONTEND_OBJS), where the latter is ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS)) m2_OBJS already includes various *.o files, for all those we wait until the generated files are generated. Though, seems cc1gm2 depends on m2/stage1/cc1gm2 (which is just copied there), and that depends on m2/gm2-compiler-boot/m2flex.o, $(GM2_C_OBJS) and m2/gm2-gcc/rtegraph.o already included in m2_OBJS, but also on $(GM2_LIBS_BOOT) $(MC_LIBS) where MC_LIBS=m2/mc-boot-ch/Glibc.o m2/mc-boot-ch/Gmcrts.o GM2_LIBS_BOOT = m2/gm2-compiler-boot/gm2.a \ m2/gm2-libs-boot/libgm2.a \ $(GM2-BOOT-O) GM2-BOOT-O isn't defined, and the 2 libraries depend on $(BUILD-LIBS-BOOT) $(BUILD-COMPILER-BOOT) So, the following patch adds those to m2_OBJS. I'm not sure if something further is needed, like some objects used to build the helper programs, mc and whatever else is needed, I guess it depends on if they use or can use say tm.h or similar headers which depend on the generated headers. 2024-11-09 Jakub Jelinek gcc/m2/ * Make-lang.in (m2_OBJS): Add $(BUILD-LIBS-BOOT), $(BUILD-COMPILER-BOOT) and $(MC_LIBS). (cherry picked from commit 44682fbead3bba7345e0a575a8a680d10e75ae48) Diff: --- gcc/m2/Make-lang.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in index 154270214389..e2a152f78d76 100644 --- a/gcc/m2/Make-lang.in +++ b/gcc/m2/Make-lang.in @@ -580,7 +580,8 @@ GM2_LIBS_BOOT = m2/gm2-compiler-boot/gm2.a \ $(GM2-BOOT-O) m2_OBJS = $(GM2_C_OBJS) m2/gm2-gcc/rtegraph.o \ - m2/gm2-compiler-boot/m2flex.o + m2/gm2-compiler-boot/m2flex.o \ + $(BUILD-LIBS-BOOT) $(BUILD-COMPILER-BOOT) $(MC_LIBS) cc1gm2$(exeext): m2/stage1/cc1gm2$(exeext) $(m2.prev) cp -p $< $@
[gcc r14-11146] c: Fix sizeof error recovery [PR117745]
https://gcc.gnu.org/g:0183fb1cef5e382af2a5c0dc3c59efbcd32db6ab commit r14-11146-g0183fb1cef5e382af2a5c0dc3c59efbcd32db6ab Author: Jakub Jelinek Date: Wed Nov 27 17:29:28 2024 +0100 c: Fix sizeof error recovery [PR117745] Compilation of the following testcase hangs forever after emitting first error. The problem is that in one place we just return error_mark_node directly rather than going through c_expr_sizeof_expr or c_expr_sizeof_type. The parsing of the expression could have called record_maybe_used_decl though, but nothing calls pop_maybe_used which needs to be called after parsing of every sizeof/typeof, successful or not. At the end of the toplevel declaration we free the parser_obstack and in another function record_maybe_used_decl is called again and due to the missing pop_maybe_unused we end up with a cycle in the chain. The following patch fixes it by just setting error and goto to the sizeof_expr: c_inhibit_evaluation_warnings--; in_sizeof--; mark_exp_read (expr.value); if (TREE_CODE (expr.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) error_at (expr_loc, "% applied to a bit-field"); result = c_expr_sizeof_expr (expr_loc, expr); where c_expr_sizeof_expr will do: struct c_expr ret; if (expr.value == error_mark_node) { ret.value = error_mark_node; ret.original_code = ERROR_MARK; ret.original_type = NULL; ret.m_decimal = 0; pop_maybe_used (false); } ... return ret; which is exactly what the old code did manually except for the missing pop_maybe_used call. mark_exp_read does nothing on error_mark_node and error_mark_node doesn't have COMPONENT_REF tree_code. 2024-11-27 Jakub Jelinek PR c/117745 * c-parser.cc (c_parser_sizeof_expression): If type_name is NULL, just expr.set_error () and goto sizeof_expr instead of doing error recovery manually. * gcc.dg/pr117745.c: New test. (cherry picked from commit 958f0025f41d8bd9812e4da91a72b1ad79496e5b) Diff: --- gcc/c/c-parser.cc | 12 +--- gcc/testsuite/gcc.dg/pr117745.c | 8 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 5fcfff7134a8..cd2e089fe38d 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -9891,13 +9891,11 @@ c_parser_sizeof_expression (c_parser *parser) finish = parser->tokens_buf[0].location; if (type_name == NULL) { - struct c_expr ret; - c_inhibit_evaluation_warnings--; - in_sizeof--; - ret.set_error (); - ret.original_code = ERROR_MARK; - ret.original_type = NULL; - return ret; + /* Let c_expr_sizeof_expr call pop_maybe_used and fill in c_expr +for parsing error; the parsing of the expression could have +called record_maybe_used_decl. */ + expr.set_error (); + goto sizeof_expr; } if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { diff --git a/gcc/testsuite/gcc.dg/pr117745.c b/gcc/testsuite/gcc.dg/pr117745.c new file mode 100644 index ..3485f7c9b1ab --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr117745.c @@ -0,0 +1,8 @@ +/* PR c/117745 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +static int foo (void); +void bar (void) { sizeof (int [0 ? foo () : 1); } /* { dg-error "expected" } */ +static int baz (void); +void qux (void) { sizeof (sizeof (int[baz ()])); }
[gcc r14-11135] store-merging: Don't use sub_byte_op_p mode for empty_ctor_p unless necessary [PR117439]
https://gcc.gnu.org/g:67379c5b6ea4c87d69dea90ede51f33c9f5170c8 commit r14-11135-g67379c5b6ea4c87d69dea90ede51f33c9f5170c8 Author: Jakub Jelinek Date: Wed Nov 6 10:21:09 2024 +0100 store-merging: Don't use sub_byte_op_p mode for empty_ctor_p unless necessary [PR117439] encode_tree_to_bitpos uses the more expensive sub_byte_op_p mode in which it has to allocate a buffer and do various extra work like shifting the bits etc. if bitlen or bitpos aren't multiples of BITS_PER_UNIT, or if bitlen doesn't have corresponding integer mode. The last case is explained later in the comments: /* The native_encode_expr machinery uses TYPE_MODE to determine how many bytes to write. This means it can write more than ROUND_UP (bitlen, BITS_PER_UNIT) / BITS_PER_UNIT bytes (for example write 8 bytes for a bitlen of 40). Skip the bytes that are not within bitlen and zero out the bits that are not relevant as well (that may contain a sign bit due to sign-extension). */ Now, we've later added empty_ctor_p support, either {} CONSTRUCTOR or {CLOBBER}, which doesn't use native_encode_expr at all, just memset, so that case doesn't need those fancy games unless bitlen or bitpos aren't multiples of BITS_PER_UNIT (unlikely, but let's pretend it is possible). The following patch makes us use the fast path even for empty_ctor_p which occupy full bytes, we can just memset that in the provided buffer and don't need to XALLOCAVEC another buffer. This patch in itself fixes the testcase from the PR (which was about using huge XALLLOCAVEC), but I want to do some other changes, to be posted in a next patch. 2024-11-06 Jakub Jelinek PR tree-optimization/117439 * gimple-ssa-store-merging.cc (encode_tree_to_bitpos): For empty_ctor_p use !sub_byte_op_p even if bitlen doesn't have an integral mode. (cherry picked from commit aab572240a0752da74029ed9f8918e0b1628e8ba) Diff: --- gcc/gimple-ssa-store-merging.cc | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc index 7dba4a7a781f..429c18c1c78d 100644 --- a/gcc/gimple-ssa-store-merging.cc +++ b/gcc/gimple-ssa-store-merging.cc @@ -1933,14 +1933,15 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos, unsigned int total_bytes) { unsigned int first_byte = bitpos / BITS_PER_UNIT; - bool sub_byte_op_p = ((bitlen % BITS_PER_UNIT) - || (bitpos % BITS_PER_UNIT) - || !int_mode_for_size (bitlen, 0).exists ()); bool empty_ctor_p = (TREE_CODE (expr) == CONSTRUCTOR && CONSTRUCTOR_NELTS (expr) == 0 && TYPE_SIZE_UNIT (TREE_TYPE (expr)) - && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (expr; + && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (expr; + bool sub_byte_op_p = ((bitlen % BITS_PER_UNIT) + || (bitpos % BITS_PER_UNIT) + || (!int_mode_for_size (bitlen, 0).exists () + && !empty_ctor_p)); if (!sub_byte_op_p) {
[gcc r14-11142] phiopt: Fix a pasto in spaceship_replacement [PR117612]
https://gcc.gnu.org/g:3190d6263c90f8e859b738a9b39f5e650a4a3a16 commit r14-11142-g3190d6263c90f8e859b738a9b39f5e650a4a3a16 Author: Jakub Jelinek Date: Thu Nov 21 09:38:01 2024 +0100 phiopt: Fix a pasto in spaceship_replacement [PR117612] When working on the PR117612 fix, I've noticed a pasto in tree-ssa-phiopt.cc (spaceship_replacement). The code is if (absu_hwi (tree_to_shwi (arg2)) != 1) return false; if (e1->flags & EDGE_TRUE_VALUE) { if (tree_to_shwi (arg0) != 2 || absu_hwi (tree_to_shwi (arg1)) != 1 || wi::to_widest (arg1) == wi::to_widest (arg2)) return false; } else if (tree_to_shwi (arg1) != 2 || absu_hwi (tree_to_shwi (arg0)) != 1 || wi::to_widest (arg0) == wi::to_widest (arg1)) return false; where arg{0,1,2,3} are PHI args and wants to ensure that if e1 is a true edge, then arg0 is 2 and one of arg{1,2} is -1 and one is 1, otherwise arg1 is 2 and one of arg{0,2} is -1 and one is 1. But due to pasto in the latte case doesn't verify that arg0 is different from arg2, it could be both -1 or both 1 and we wouldn't punt. The wi::to_widest (arg0) == wi::to_widest (arg1) test is always false when we've made sure in the earlier conditions that arg1 is 2 and arg0 is -1 or 1, so never 2. 2024-11-21 Jakub Jelinek PR tree-optimization/94589 PR tree-optimization/117612 * tree-ssa-phiopt.cc (spaceship_replacement): Fix up a pasto in check when arg1 is 2. (cherry picked from commit ca7430f145f5c7960f67ec77f585f3a2b58c7d10) Diff: --- gcc/tree-ssa-phiopt.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 150e58e39e3f..8cb1413b49a5 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -2558,7 +2558,7 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, } else if (tree_to_shwi (arg1) != 2 || absu_hwi (tree_to_shwi (arg0)) != 1 - || wi::to_widest (arg0) == wi::to_widest (arg1)) + || wi::to_widest (arg0) == wi::to_widest (arg2)) return false; switch (cmp2) {
[gcc r15-6731] ada: Fix missing detection of late equality operator returning subtype of Boolean
https://gcc.gnu.org/g:3b694271bec01ed971147a0f4cb68d8c9a7d0915 commit r15-6731-g3b694271bec01ed971147a0f4cb68d8c9a7d0915 Author: Eric Botcazou Date: Sun Jan 5 17:34:41 2025 +0100 ada: Fix missing detection of late equality operator returning subtype of Boolean In Ada 2012, the compiler fails to check that a primitive equality operator for an untagged record type must appear before the type is frozen, when the operator returns a subtype of Boolean. This plugs the legality loophole but adds the debug switch -gnatd_q to go back to the previous state. gcc/ada/ChangeLog: PR ada/18765 * debug.adb (d_q): Document new usage. * sem_ch6.adb (New_Overloaded_Entity): Apply the special processing to all equality operators whose base result type is Boolean, but do not enforce the new Ada 2012 freezing rule if the result type is a proper subtype of it and the -gnatd_q switch is specified. Diff: --- gcc/ada/debug.adb | 6 +- gcc/ada/sem_ch6.adb | 12 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb index 7b95fa87f02d..ac3ce41dcc51 100644 --- a/gcc/ada/debug.adb +++ b/gcc/ada/debug.adb @@ -154,7 +154,7 @@ package body Debug is -- d_n -- d_o -- d_p Ignore assertion pragmas for elaboration - -- d_q + -- d_q Do not enforce freezing for equality operator of boolean subtype -- d_r Disable the use of the return slot in functions -- d_s Stop elaboration checks on synchronous suspension -- d_t In LLVM-based CCG, dump LLVM IR after transformations are done @@ -999,6 +999,10 @@ package body Debug is -- semantics of invariants and postconditions in both the static and -- dynamic elaboration models. + -- d_q The compiler does not enforce the new freezing rule introduced for + -- primitive equality operators in Ada 2012 when the operator returns + -- a subtype of Boolean. + -- d_r The compiler does not make use of the return slot in the expansion -- of functions returning a by-reference type. If this use is required -- for these functions to return on the primary stack, then they are diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 49d83f8d5e06..80e0c9c634c3 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -12880,12 +12880,20 @@ package body Sem_Ch6 is <> if Chars (S) = Name_Op_Eq - and then Etype (S) = Standard_Boolean + and then Base_Type (Etype (S)) = Standard_Boolean and then Present (Parent (S)) and then not Is_Dispatching_Operation (S) then Make_Inequality_Operator (S); -Check_Untagged_Equality (S); + +-- The freezing rule introduced in Ada 2012 was historically +-- not enforced for operators returning a subtype of Boolean. + +if Etype (S) = Standard_Boolean + or else not Debug_Flag_Underscore_Q +then + Check_Untagged_Equality (S); +end if; end if; end New_Overloaded_Entity;
[gcc r14-11147] builtins: Handle BITINT_TYPE in __builtin_iseqsig folding [PR117802]
https://gcc.gnu.org/g:448f84a49caba91a1eb159197afb19dbf662ce15 commit r14-11147-g448f84a49caba91a1eb159197afb19dbf662ce15 Author: Jakub Jelinek Date: Thu Nov 28 10:23:47 2024 +0100 builtins: Handle BITINT_TYPE in __builtin_iseqsig folding [PR117802] In check_builtin_function_arguments in the _BitInt patchset I've changed INTEGER_TYPE tests to INTEGER_TYPE or BITINT_TYPE, but haven't done the same in fold_builtin_iseqsig, which now ICEs because of that. The following patch fixes that. BTW, that TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) test for REAL_TYPE vs. REAL_TYPE looks pretty random and dangerous, I think it would be useful to handle this builtin also in the C and C++ FEs, if both arguments have REAL_TYPE, use the FE specific routine to decide which types to use and error if a comparison between types would be erroneous (e.g. complain about _Decimal* vs. float/double/long double/_Float*, pick up the preferred type, complain about __ibm128 vs. _Float128 in C++, etc.). But the FEs can just promote one argument to the other in that case and keep fold_builtin_iseqsig as is for say Fortran and other FEs. 2024-11-28 Jakub Jelinek PR c/117802 * builtins.cc (fold_builtin_iseqsig): Handle BITINT_TYPE like INTEGER_TYPE. * gcc.dg/builtin-iseqsig-1.c: New test. * gcc.dg/bitint-118.c: New test. (cherry picked from commit 88aeea14c23a5d066a635ffb4f1d2943fddcf0bd) Diff: --- gcc/builtins.cc | 6 -- gcc/testsuite/gcc.dg/bitint-118.c| 21 + gcc/testsuite/gcc.dg/builtin-iseqsig-1.c | 20 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 77e7ade7a74d..0788f58f6371 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -9941,9 +9941,11 @@ fold_builtin_iseqsig (location_t loc, tree arg0, tree arg1) /* Choose the wider of two real types. */ cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) ? type0 : type1; - else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE) + else if (code0 == REAL_TYPE + && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE)) cmp_type = type0; - else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE) + else if ((code0 == INTEGER_TYPE || code0 == BITINT_TYPE) + && code1 == REAL_TYPE) cmp_type = type1; arg0 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg0)); diff --git a/gcc/testsuite/gcc.dg/bitint-118.c b/gcc/testsuite/gcc.dg/bitint-118.c new file mode 100644 index ..d330cc502a94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-118.c @@ -0,0 +1,21 @@ +/* PR c/117802 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-std=c23" } */ + +int +foo (float x, _BitInt(8) y) +{ + return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x); +} + +int +bar (double x, unsigned _BitInt(162) y) +{ + return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x); +} + +int +baz (long double x, _BitInt(574) y) +{ + return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x); +} diff --git a/gcc/testsuite/gcc.dg/builtin-iseqsig-1.c b/gcc/testsuite/gcc.dg/builtin-iseqsig-1.c new file mode 100644 index ..e9fe87b7f708 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-iseqsig-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +int +foo (float x, int y) +{ + return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x); +} + +int +bar (double x, unsigned long y) +{ + return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x); +} + +int +baz (long double x, long long y) +{ + return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x); +}
[gcc r14-11137] c++: Fix ICE on constexpr virtual function [PR117317]
https://gcc.gnu.org/g:bef6c31f18e546384cf8572efae6934550e5c501 commit r14-11137-gbef6c31f18e546384cf8572efae6934550e5c501 Author: Jakub Jelinek Date: Fri Nov 8 13:36:05 2024 +0100 c++: Fix ICE on constexpr virtual function [PR117317] Since C++20 virtual methods can be constexpr, and if they are constexpr evaluated, we choose tentative_decl_linkage for those defer their output and decide at_eof again. On the following testcases we ICE though, because if expand_or_defer_fn_1 decides to use tentative_decl_linkage, it returns true and the caller in that case cals emit_associated_thunks, where use_thunk which it calls asserts DECL_INTERFACE_KNOWN on the thunk destination, which isn't the case for tentative_decl_linkage. The following patch fixes the ICE by not emitting the thunks for the DECL_DEFER_OUTPUT fns just yet but waiting until at_eof time when we return to those. Note, the second testcase ICEs already since r0-110035 with -std=c++0x before it gets a chance to diagnose constexpr virtual method. 2024-11-08 Jakub Jelinek PR c++/117317 * semantics.cc (emit_associated_thunks): Do nothing for !DECL_INTERFACE_KNOWN && DECL_DEFER_OUTPUT fns. * g++.dg/cpp2a/pr117317-1.C: New test. * g++.dg/cpp2a/pr117317-2.C: New test. (cherry picked from commit 5ff9e21c1ec81f8288e74679547e56051e051975) Diff: --- gcc/cp/semantics.cc | 5 - gcc/testsuite/g++.dg/cpp2a/pr117317-1.C | 19 +++ gcc/testsuite/g++.dg/cpp2a/pr117317-2.C | 15 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index ceeac82fa081..50e8deb9ef93 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -5019,7 +5019,10 @@ emit_associated_thunks (tree fn) enabling you to output all the thunks with the function itself. */ if (DECL_VIRTUAL_P (fn) /* Do not emit thunks for extern template instantiations. */ - && ! DECL_REALLY_EXTERN (fn)) + && ! DECL_REALLY_EXTERN (fn) + /* Do not emit thunks for tentative decls, those will be processed +again at_eof if really needed. */ + && (DECL_INTERFACE_KNOWN (fn) || !DECL_DEFER_OUTPUT (fn))) { tree thunk; diff --git a/gcc/testsuite/g++.dg/cpp2a/pr117317-1.C b/gcc/testsuite/g++.dg/cpp2a/pr117317-1.C new file mode 100644 index ..f3ef3849d033 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/pr117317-1.C @@ -0,0 +1,19 @@ +// PR c++/117317 +// { dg-do compile { target c++20 } } + +struct C { + constexpr bool operator== (const C &b) const { return foo (); } + constexpr virtual bool foo () const = 0; +}; +class A : public C {}; +class B : public C {}; +template +struct D : A, B +{ + constexpr bool operator== (const D &) const = default; + constexpr bool foo () const override { return true; } +}; +struct E : D<1> {}; +constexpr E e; +constexpr E f; +static_assert (e == f, ""); diff --git a/gcc/testsuite/g++.dg/cpp2a/pr117317-2.C b/gcc/testsuite/g++.dg/cpp2a/pr117317-2.C new file mode 100644 index ..44f2ec601bbf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/pr117317-2.C @@ -0,0 +1,15 @@ +// PR c++/117317 +// { dg-do compile { target c++20 } } + +struct C { + constexpr virtual bool foo () const = 0; +}; +struct A : public C {}; +struct B : public C {}; +template +struct D : A, B +{ + constexpr bool foo () const override { return true; } +}; +constexpr D<0> d; +static_assert (d.foo (), "");
[gcc r14-11149] openmp: Add crtoffloadtableS.o and use it [PR117851]
https://gcc.gnu.org/g:326b6bac1f61302daf285e45baf39a6a30511272 commit r14-11149-g326b6bac1f61302daf285e45baf39a6a30511272 Author: Jakub Jelinek Date: Sat Nov 30 11:19:12 2024 +0100 openmp: Add crtoffloadtableS.o and use it [PR117851] Unlike crtoffload{begin,end}.o which just define some symbols at the start/end of the various .gnu.offload* sections, crtoffloadtable.o contains const void *const __OFFLOAD_TABLE__[] __attribute__ ((__visibility__ ("hidden"))) = { &__offload_func_table, &__offload_funcs_end, &__offload_var_table, &__offload_vars_end, &__offload_ind_func_table, &__offload_ind_funcs_end, }; The problem is that linking this into PIEs or shared libraries doesn't work when it is compiled without -fpic/-fpie - __OFFLOAD_TABLE__ for non-PIC code is put into .rodata section, but it really needs relocations, so for PIC it should go into .data.rel.ro/.data.rel.ro.local. As I think we don't want .data.rel.ro section in non-PIE binaries, this patch follows the path of e.g. crtbegin.o vs. crtbeginS.o and adds crtoffloadtableS.o next to crtoffloadtable.o, where crtoffloadtableS.o is compiled with -fpic. 2024-11-30 Jakub Jelinek PR libgomp/117851 gcc/ * lto-wrapper.cc (find_crtoffloadtable): Add PIE_OR_SHARED argument, search for crtoffloadtableS.o rather than crtoffloadtable.o if true. (run_gcc): Add pie_or_shared variable. If OPT_pie or OPT_shared or OPT_static_pie is seen, set pie_or_shared to true, if OPT_no_pie is seen, set pie_or_shared to false. Pass it to find_crtoffloadtable. libgcc/ * configure.ac (extra_parts): Add crtoffloadtableS.o. * Makefile.in (crtoffloadtableS$(objext)): New goal. * configure: Regenerated. (cherry picked from commit f089ef880e385e2193237b1f53ec81dac4141680) Diff: --- gcc/lto-wrapper.cc | 27 +++ libgcc/Makefile.in | 3 +++ libgcc/configure| 3 ++- libgcc/configure.ac | 3 ++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/gcc/lto-wrapper.cc b/gcc/lto-wrapper.cc index 02579951569d..c7bad4b61c25 100644 --- a/gcc/lto-wrapper.cc +++ b/gcc/lto-wrapper.cc @@ -1083,13 +1083,16 @@ copy_file (const char *dest, const char *src) the copy to the linker. */ static void -find_crtoffloadtable (int save_temps, const char *dumppfx) +find_crtoffloadtable (int save_temps, bool pie_or_shared, const char *dumppfx) { char **paths = NULL; const char *library_path = getenv ("LIBRARY_PATH"); if (!library_path) return; - unsigned n_paths = parse_env_var (library_path, &paths, "/crtoffloadtable.o"); + unsigned n_paths = parse_env_var (library_path, &paths, + pie_or_shared + ? "/crtoffloadtableS.o" + : "/crtoffloadtable.o"); unsigned i; for (i = 0; i < n_paths; i++) @@ -1108,7 +,8 @@ find_crtoffloadtable (int save_temps, const char *dumppfx) } if (i == n_paths) fatal_error (input_location, -"installation error, cannot find %"); +"installation error, cannot find %", +pie_or_shared ? "S" : ""); free_array_of_ptrs ((void **) paths, n_paths); } @@ -1423,6 +1427,11 @@ run_gcc (unsigned argc, char *argv[]) char **lto_argv, **ltoobj_argv; bool linker_output_rel = false; bool skip_debug = false; +#ifdef ENABLE_DEFAULT_PIE + bool pie_or_shared = true; +#else + bool pie_or_shared = false; +#endif const char *incoming_dumppfx = dumppfx = NULL; static char current_dir[] = { '.', DIR_SEPARATOR, '\0' }; @@ -1590,6 +1599,16 @@ run_gcc (unsigned argc, char *argv[]) diagnostic_color_init (global_dc, option->value); break; + case OPT_pie: + case OPT_shared: + case OPT_static_pie: + pie_or_shared = true; + break; + + case OPT_no_pie: + pie_or_shared = false; + break; + default: break; } @@ -1798,7 +1817,7 @@ cont1: if (offload_names) { - find_crtoffloadtable (save_temps, dumppfx); + find_crtoffloadtable (save_temps, pie_or_shared, dumppfx); for (i = 0; offload_names[i]; i++) printf ("%s\n", offload_names[i]); free_array_of_ptrs ((void **) offload_names, i); diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 0e46e9ef7686..5d0195bdfe90 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -1060,6 +1060,9 @@ crtoffloadend$(objext): $(srcdir)/offloadstuff.c crtoffloadtable$(objext): $(srcdir)/offloadstuff.c $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_TABLE + +crtoffloadtableS$(objext): $(srcdir)/offloadstuff.c + $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $< -DCRT_TABLE endif ifeq ($(enable_vtable_verify),yes
[gcc r15-6730] ada: Accept predefined multiply operator for fixed point in expression function
https://gcc.gnu.org/g:f622acc1eb2679f14758a1ad6c5b693cd9bdea23 commit r15-6730-gf622acc1eb2679f14758a1ad6c5b693cd9bdea23 Author: Eric Botcazou Date: Sun Jan 5 23:21:31 2025 +0100 ada: Accept predefined multiply operator for fixed point in expression function The RM 4.5.5(19.1/2) subclause says that the predefined multiply operator for universal_fixed is still available, despite the declaration of a user- defined primitive multiply operator for the fixed-point type at stake, if it is identified using an expanded name with prefix denoting Standard, but this is currently not the case in the context of an expression function. gcc/ada/ChangeLog: PR ada/118274 * sem_ch4.adb (Check_Arithmetic_Pair.Has_Fixed_Op): Use the original node of the operator to identify the case of an expanded name whose prefix is the package Standard. Diff: --- gcc/ada/sem_ch4.adb | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index 5b9456bed0a5..406983995f3d 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -6619,18 +6619,20 @@ package body Sem_Ch4 is -- function Has_Fixed_Op (Typ : Entity_Id; Op : Entity_Id) return Boolean is - Bas : constant Entity_Id := Base_Type (Typ); + Bas: constant Entity_Id := Base_Type (Typ); + Orig_N : constant Node_Id := Original_Node (N); + Ent : Entity_Id; F1 : Entity_Id; F2 : Entity_Id; begin - -- If the universal_fixed operation is given explicitly the rule + -- If the universal_fixed operation is given explicitly, the rule -- concerning primitive operations of the type do not apply. - if Nkind (N) = N_Function_Call - and then Nkind (Name (N)) = N_Expanded_Name - and then Entity (Prefix (Name (N))) = Standard_Standard + if Nkind (Orig_N) = N_Function_Call + and then Nkind (Name (Orig_N)) = N_Expanded_Name + and then Entity (Prefix (Name (Orig_N))) = Standard_Standard then return False; end if;
[gcc r14-11145] builtins: Fix up DFP ICEs on __builtin_fpclassify [PR102674]
https://gcc.gnu.org/g:54c381d5a8617fa0d13e3bfc9d9802eb5a1f6234 commit r14-11145-g54c381d5a8617fa0d13e3bfc9d9802eb5a1f6234 Author: Jakub Jelinek Date: Tue Nov 26 09:46:51 2024 +0100 builtins: Fix up DFP ICEs on __builtin_fpclassify [PR102674] This patch is similar to the one I've just posted, __builtin_fpclassify also needs to print decimal float minimum differently and use real_from_string3. Plus I've done some formatting fixes. 2024-11-26 Jakub Jelinek PR middle-end/102674 * builtins.cc (fold_builtin_fpclassify): Use real_from_string3 rather than real_from_string. Use "1E%d" format string rather than "0x1p%d" for decimal float minimum. Formatting fixes. * gcc.dg/dfp/pr102674.c: New test. (cherry picked from commit 5bb36d832c955e575bd458a02f3c6c5b28564aed) Diff: --- gcc/builtins.cc | 23 - gcc/testsuite/gcc.dg/dfp/pr102674.c | 65 + 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index d9d3eb4c19e0..77e7ade7a74d 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -9833,28 +9833,33 @@ fold_builtin_fpclassify (location_t loc, tree *args, int nargs) (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */ tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, -build_real (type, dconst0)); +build_real (type, dconst0)); res = fold_build3_loc (loc, COND_EXPR, integer_type_node, -tmp, fp_zero, fp_subnormal); +tmp, fp_zero, fp_subnormal); - sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); - real_from_string (&r, buf); + if (DECIMAL_FLOAT_MODE_P (mode)) +sprintf (buf, "1E%d", REAL_MODE_FORMAT (mode)->emin - 1); + else +sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); + real_from_string3 (&r, buf, mode); tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node, -arg, build_real (type, r)); - res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res); +arg, build_real (type, r)); + res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, +fp_normal, res); if (tree_expr_maybe_infinite_p (arg)) { tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, -build_real (type, dconstinf)); +build_real (type, dconstinf)); res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, -fp_infinite, res); +fp_infinite, res); } if (tree_expr_maybe_nan_p (arg)) { tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg); - res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan); + res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, +res, fp_nan); } return res; diff --git a/gcc/testsuite/gcc.dg/dfp/pr102674.c b/gcc/testsuite/gcc.dg/dfp/pr102674.c new file mode 100644 index ..c67ecf5ce71b --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pr102674.c @@ -0,0 +1,65 @@ +/* PR middle-end/102674 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 +#define FP_SUBNORMAL 3 +#define FP_NORMAL 4 + +__attribute__((noipa)) int +foo (_Decimal32 x) +{ + return __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, x); +} + +__attribute__((noipa)) int +bar (_Decimal64 x) +{ + return __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, x); +} + +__attribute__((noipa)) int +baz (_Decimal128 x) +{ + return __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, x); +} + +int +main () +{ + if (foo (__builtin_infd32 ()) != FP_INFINITE + || foo (-__builtin_infd32 ()) != FP_INFINITE + || foo (__builtin_nand32 ("")) != FP_NAN + || foo (9.99E96DF) != FP_NORMAL + || foo (-1E-95DF) != FP_NORMAL + || foo (0.99E-95DF) != FP_SUBNORMAL + || foo (-0.01E-95DF) != FP_SUBNORMAL + || foo (0.000DF) != FP_ZERO + || foo (-0.0DF) != FP_ZERO) +__builtin_abort (); + if (bar (__builtin_infd64 ()) != FP_INFINITE + || bar (-__builtin_infd64 ()) != FP_INFINITE + || bar (__builtin_nand64 ("")) != FP_NAN + || bar (9.999E384DD) != FP_NORMAL + || bar (-1E-383DD) != FP_NORMAL + || bar (0.999E-383DD) != FP_SUBNORMAL + || bar (-0.001E-383DD) != FP_SUBNORMAL + || bar (0.000DD) != FP_ZERO + || bar (-0.00DD) != FP_ZERO) +__builtin_abort (); + if (baz (__builtin_infd128 ()) != FP_INFINITE + || b
[gcc r14-11144] builtins: Fix up DFP ICEs on __builtin_is{inf, finite, normal} [PR43374]
https://gcc.gnu.org/g:59eec2ee71b851e7470b414d1c3b5e59641ac1fc commit r14-11144-g59eec2ee71b851e7470b414d1c3b5e59641ac1fc Author: Jakub Jelinek Date: Tue Nov 26 09:45:21 2024 +0100 builtins: Fix up DFP ICEs on __builtin_is{inf,finite,normal} [PR43374] __builtin_is{inf,finite,normal} builtins ICE on _Decimal{32,64,128,64x} operands unless those operands are constant. The problem is that we fold the builtins to comparisons with the largest finite number, but a) get_max_float was only handling binary floats b) real_from_string again assumes binary float and so we were ICEing in the build_real called after the two calls. This patch adds decimal handling into get_max_float (well, moves it from c-cppbuiltin.cc which was printing those for __DEC{32,64,128}_MAX__ macros) and uses real_from_string3 (perhaps it is time to rename it to just real_from_string now that we can use function overloading) so that it handles both binary and decimal floats. 2024-11-26 Jakub Jelinek PR middle-end/43374 gcc/ * real.cc (get_max_float): Handle decimal float. * builtins.cc (fold_builtin_interclass_mathfn): Use real_from_string3 rather than real_from_string. Use "1E%d" format string rather than "0x1p%d" for decimal float minimum. gcc/c-family/ * c-cppbuiltin.cc (builtin_define_decimal_float_constants): Use get_max_float. gcc/testsuite/ * gcc.dg/dfp/pr43374.c: New test. (cherry picked from commit f39e6b4f5cd4e5362cf4b1004a591df2c8b00304) Diff: --- gcc/builtins.cc| 13 + gcc/c-family/c-cppbuiltin.cc | 13 ++--- gcc/real.cc| 16 +++ gcc/testsuite/gcc.dg/dfp/pr43374.c | 56 ++ 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 7c1497561f74..d9d3eb4c19e0 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -9576,7 +9576,7 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) arg = fold_build1_loc (loc, NOP_EXPR, type, arg); } get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false); - real_from_string (&r, buf); + real_from_string3 (&r, buf, mode); result = build_call_expr (isgr_fn, 2, fold_build1_loc (loc, ABS_EXPR, type, arg), build_real (type, r)); @@ -9600,7 +9600,7 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) arg = fold_build1_loc (loc, NOP_EXPR, type, arg); } get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false); - real_from_string (&r, buf); + real_from_string3 (&r, buf, mode); result = build_call_expr (isle_fn, 2, fold_build1_loc (loc, ABS_EXPR, type, arg), build_real (type, r)); @@ -9639,9 +9639,12 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) arg = fold_build1_loc (loc, ABS_EXPR, type, arg); get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false); - real_from_string (&rmax, buf); - sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (orig_mode)->emin - 1); - real_from_string (&rmin, buf); + real_from_string3 (&rmax, buf, mode); + if (DECIMAL_FLOAT_MODE_P (mode)) + sprintf (buf, "1E%d", REAL_MODE_FORMAT (orig_mode)->emin - 1); + else + sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (orig_mode)->emin - 1); + real_from_string3 (&rmin, buf, orig_mode); max_exp = build_real (type, rmax); min_exp = build_real (type, rmin); diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index d4aadc7666b8..79e4abd01520 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -357,17 +357,8 @@ builtin_define_decimal_float_constants (const char *name_prefix, /* Compute the maximum representable value. */ sprintf (name, "__%s_MAX__", name_prefix); - p = buf; - for (digits = fmt->p; digits; digits--) -{ - *p++ = '9'; - if (digits == fmt->p) - *p++ = '.'; -} - *p = 0; - /* fmt->p plus 1, to account for the decimal point and fmt->emax - minus 1 because the digits are nines, not 1.0. */ - sprintf (&buf[fmt->p + 1], "E%d%s", fmt->emax - 1, suffix); + get_max_float (fmt, buf, sizeof (buf) - strlen (suffix), false); + strcat (buf, suffix); builtin_define_with_value (name, buf, 0); /* Compute epsilon (the difference between 1 and least value greater diff --git a/gcc/real.cc b/gcc/real.cc index 2c682b1809d4..4a6a6e76a99d 100644 --- a/gcc/real.cc +++ b/gcc/real.cc @@ -5438,6 +5438,22 @@ void get_max_float (const struct real_format *fmt, char *buf, size_t len,
[gcc r14-11154] cse: Fix up record_jump_equiv checks [PR117095]
https://gcc.gnu.org/g:fbbc1a4ac5c7e55de1edc52cfe267b95f9621e21 commit r14-11154-gfbbc1a4ac5c7e55de1edc52cfe267b95f9621e21 Author: Jakub Jelinek Date: Sat Dec 14 00:41:00 2024 +0100 cse: Fix up record_jump_equiv checks [PR117095] The following testcase is miscompiled on s390x-linux with -O2 -march=z15. The problem happens during cse2, which sees in an extended basic block (jump_insn 217 78 216 10 (parallel [ (set (pc) (if_then_else (ne (reg:SI 165) (const_int 1 [0x1])) (label_ref 216) (pc))) (set (reg:SI 165) (plus:SI (reg:SI 165) (const_int -1 [0x]))) (clobber (scratch:SI)) (clobber (reg:CC 33 %cc)) ]) "t.c":14:17 discrim 1 2192 {doloop_si64} (int_list:REG_BR_PROB 955630228 (nil)) -> 216) ... (insn 99 98 100 12 (set (reg:SI 138) (const_int 1 [0x1])) "t.c":9:31 1507 {*movsi_zarch} (nil)) (insn 100 99 103 12 (parallel [ (set (reg:SI 137) (minus:SI (reg:SI 138) (subreg:SI (reg:HI 135 [ a ]) 0))) (clobber (reg:CC 33 %cc)) ]) "t.c":9:31 1904 {*subsi3} (expr_list:REG_DEAD (reg:SI 138) (expr_list:REG_DEAD (reg:HI 135 [ a ]) (expr_list:REG_UNUSED (reg:CC 33 %cc) (nil) Note, cse2 has df_note_add_problem () before df_analyze, which add (expr_list:REG_UNUSED (reg:SI 165) (expr_list:REG_UNUSED (reg:CC 33 %cc) notes to the first insn (correctly so, %cc is clobbered there and pseudo 165 isn't used after the insn). Now, cse_extended_basic_block has an extra optimization on conditional jumps, where it records equivalence on the edge which continues in the ebb. Here it sees (ne reg:SI 165) (const_int 1) is false on the edge and remembers that pseudo 165 is comparison equivalent to (const_int 1), so on insn 100 it decides to replace (reg:SI 138) with (reg:SI 165). This optimization isn't correct here though, because the JUMP_INSN has multiple sets. Before r0-77890 record_jump_equiv has been called from cse_insn guarded on n_sets == 1 && any_condjump_p (insn), so it wouldn't be done on the above JUMP_INSN where n_sets == 2. But since that change it is guarded with single_set (insn) && any_condjump_p (insn) and that is true because of the REG_UNUSED note. Looking at that note is inappropriate in CSE though, because the whole intent of the pass is to extend the lifetimes of the pseudos if equivalence is found, so the fact that there is REG_UNUSED note for (reg:SI 165) and that the reg isn't used later doesn't imply that it won't be used after the optimization. So, unless we manage to process the other sets on the JUMP_INSN (it wouldn't be terribly hard in this exact case, the doloop insn decreases the register by 1 and so we could just record equivalence to (const_int 0) instead, but generally it might be hard), we should IMHO just punt if there are multiple sets. The patch below adds !multiple_sets (insn) check instead of replacing with it the single_set (insn) check, because apparently any_condjump_p uses pc_set which supports the case where PATTERN is a SET to PC (that is a single_set (insn) && !multiple_sets (insn), PATTERN is a PARALLEL with a single SET to PC (likewise) and some CLOBBERs, PARALLEL with two or more SETs where the first one is SET to PC (that could be single_set (insn) with REG_UNUSED notes but is not !multiple_sets (insn)) or PATTERN is UNSPEC/UNSPEC_VOLATILE with SET inside of it. For the last case !multiple_sets (insn) will be true, but IMHO we shouldn't try to derive anything from those because we haven't checked the rest of the UNSPEC* and we don't really know what it does. 2024-12-13 Jakub Jelinek PR rtl-optimization/117095 * cse.cc (cse_extended_basic_block): Don't call record_jump_equiv if multiple_sets (insn). * gcc.c-torture/execute/pr117095.c: New test. (cherry picked from commit b626ebc0d7888ddae16a55ca583b56a4b8434bdf) Diff: --- gcc/cse.cc | 10 +- gcc/testsuite/gcc.c-torture/execute/pr117095.c | 47 ++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/gcc/cse.cc b/gcc/cse.cc index 65794ac5f2ca..15565e53bbc8 100644 --- a/gcc/cse.cc +++ b/gcc/cse.cc @@ -6620,7 +6620,15 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data) && EDGE_COUNT (bb->succs) == 2 && JUMP_P (insn) && single_set (insn) - && any_condjump_p (insn)) + && any_condjump_p (insn) + /* single_set
[gcc r14-11150] bitintlower: Fix up ?ROTATE_EXPR lowering [PR117847]
https://gcc.gnu.org/g:b602b32ff06726a6ede59b10e0f5b84f9f546e4c commit r14-11150-gb602b32ff06726a6ede59b10e0f5b84f9f546e4c Author: Jakub Jelinek Date: Tue Dec 3 11:16:37 2024 +0100 bitintlower: Fix up ?ROTATE_EXPR lowering [PR117847] In the ?ROTATE_EXPR lowering I forgot to handle rotation by 0 correctly. INTEGER_CST 0 is very unlikely, it would be probably folded away, but a non-constant count can't use just p - n because then the shift count is out of bounds for zero. In the FE I use n == 0 ? x : (x << n) | (x >> (p - n)) but bitintlower here isn't prepared at this point to have bb split and am not sure if using COND_EXPR is a good idea either, so the patch uses (p - n) % p. Perhaps I should just disable lowering the rotate in the FE for the non-mode precision BITINT_TYPEs too. 2024-12-03 Jakub Jelinek PR middle-end/117847 * gimple-lower-bitint.cc (gimple_lower_bitint) : Use m = (p - n) % p instead of m = p - n for the other shift count. (cherry picked from commit 0b89341f124eadc689682d01193309225adfec23) Diff: --- gcc/gimple-lower-bitint.cc | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index e4e628b786b9..2072e54db772 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -6227,11 +6227,20 @@ gimple_lower_bitint (void) tree p = build_int_cst (TREE_TYPE (n), TYPE_PRECISION (type)); if (TREE_CODE (n) == INTEGER_CST) - m = fold_build2 (MINUS_EXPR, TREE_TYPE (n), p, n); + { + if (integer_zerop (n)) + m = n; + else + m = fold_build2 (MINUS_EXPR, TREE_TYPE (n), p, n); + } else { + tree tem = make_ssa_name (TREE_TYPE (n)); + g = gimple_build_assign (tem, MINUS_EXPR, p, n); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + gimple_set_location (g, loc); m = make_ssa_name (TREE_TYPE (n)); - g = gimple_build_assign (m, MINUS_EXPR, p, n); + g = gimple_build_assign (m, TRUNC_MOD_EXPR, tem, p); gsi_insert_before (&gsi, g, GSI_SAME_STMT); gimple_set_location (g, loc); }
[gcc r15-6732] Avoid PHI node re-allocation in loop copying
https://gcc.gnu.org/g:1db025c67fc19612332d1668607ab800f0251520 commit r15-6732-g1db025c67fc19612332d1668607ab800f0251520 Author: Richard Biener Date: Wed Jan 8 15:12:30 2025 +0100 Avoid PHI node re-allocation in loop copying duplicate_loop_body_to_header_edge redirects the original loop entry edge to the loop copy header and the copied loop exit to the old loop header. But it does so in the order that requires temporary space for an extra edge on the original loop header, causing unnecessary re-allocations. The following avoids this by swapping the order of the redirects. * cfgloopmanip.cc (duplicate_loop_body_to_header_edge): When copying to the header edge first redirect the entry to the new loop and then the exit to the old to avoid PHI node re-allocation. Diff: --- gcc/cfgloopmanip.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 534e556e1e4e..17bcf9f4acc4 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -1447,9 +1447,9 @@ duplicate_loop_body_to_header_edge (class loop *loop, edge e, } else { + redirect_edge_and_branch_force (e, new_bbs[0]); redirect_edge_and_branch_force (new_spec_edges[SE_LATCH], loop->header); - redirect_edge_and_branch_force (e, new_bbs[0]); set_immediate_dominator (CDI_DOMINATORS, new_bbs[0], e->src); e = new_spec_edges[SE_LATCH]; }
[gcc r14-11152] docs: Clarify -fsanitize=hwaddress target support [PR117960]
https://gcc.gnu.org/g:5a78e369a3995480c39c325a2c36f17c2fc37f37 commit r14-11152-g5a78e369a3995480c39c325a2c36f17c2fc37f37 Author: Jakub Jelinek Date: Mon Dec 9 14:17:39 2024 +0100 docs: Clarify -fsanitize=hwaddress target support [PR117960] Since GCC 13 -fsanitize=hwaddress is not supported just on AArch64, but also on x86_64 (but only with -mlam=u48 or -mlam=u57). 2024-12-09 Jakub Jelinek PR sanitizer/117960 * doc/invoke.texi (fsanitize=hwaddress): Clarify on which targets it is supported. (cherry picked from commit 2e958291ff68d9bff1092895a14b6763de56823b) Diff: --- gcc/doc/invoke.texi | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index b14ad30cdf2f..b575e2b96632 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -17471,8 +17471,10 @@ the available options are shown at startup of the instrumented program. See @url{https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags} for a list of supported options. The option cannot be combined with @option{-fsanitize=thread} or -@option{-fsanitize=hwaddress}. Note that the only target -@option{-fsanitize=hwaddress} is currently supported on is AArch64. +@option{-fsanitize=hwaddress}. Note that the only targets +@option{-fsanitize=hwaddress} is currently supported on are x86-64 +(only with @code{-mlam=u48} or @code{-mlam=u57} options) and AArch64, +in both cases only in ABIs with 64-bit pointers. To get more accurate stack traces, it is possible to use options such as @option{-O0}, @option{-O1}, or @option{-Og} (which, for instance, prevent
[gcc r14-11151] doloop: Fix up doloop df use [PR116799]
https://gcc.gnu.org/g:26615af93cf75c5dfae0c51a827b05968cca commit r14-11151-g26615af93cf75c5dfae0c51a827b05968cca Author: Jakub Jelinek Date: Thu Dec 5 13:01:21 2024 +0100 doloop: Fix up doloop df use [PR116799] The following testcases are miscompiled on s390x-linux, because the doloop_optimize /* Ensure that the new sequence doesn't clobber a register that is live at the end of the block. */ { bitmap modified = BITMAP_ALLOC (NULL); for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i)) note_stores (i, record_reg_sets, modified); basic_block loop_end = desc->out_edge->src; bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified); check doesn't work as intended. The problem is that it uses df, but the df analysis was only done using iv_analysis_loop_init (loop); -> df_analyze_loop (loop); which computes df inside on the bbs of the loop. While loop_end bb is inside of the loop, df_get_live_out computed that way includes registers set in the loop and used at the start of the next iteration, but doesn't include registers set in the loop (or before the loop) and used after the loop. The following patch fixes that by doing whole function df_analyze first, changes the loop iteration mode from 0 to LI_ONLY_INNERMOST (on many targets which use can_use_doloop_if_innermost target hook a so are known to only handle innermost loops) or LI_FROM_INNERMOST (I think only bfin actually allows non-innermost loops) and checking not just df_get_live_out (loop_end) (that is needed for something used by the next iteration), but also df_get_live_in (desc->out_edge->dest), i.e. what will be used after the loop. df of such a bb shouldn't be affected by the df_analyze_loop and so should be from df_analyze of the whole function. 2024-12-05 Jakub Jelinek PR rtl-optimization/113994 PR rtl-optimization/116799 * loop-doloop.cc: Include targhooks.h. (doloop_optimize): Also punt on intersection of modified with df_get_live_in (desc->out_edge->dest). (doloop_optimize_loops): Call df_analyze. Use LI_ONLY_INNERMOST or LI_FROM_INNERMOST instead of 0 as second loops_list argument. * gcc.c-torture/execute/pr116799.c: New test. * g++.dg/torture/pr113994.C: New test. (cherry picked from commit 0eed81612ad6eac2bec60286348a103d4dc02a5a) Diff: --- gcc/loop-doloop.cc | 20 - gcc/testsuite/g++.dg/torture/pr113994.C| 31 +++ gcc/testsuite/gcc.c-torture/execute/pr116799.c | 41 ++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/gcc/loop-doloop.cc b/gcc/loop-doloop.cc index 529e810e530c..0d101d64bbfc 100644 --- a/gcc/loop-doloop.cc +++ b/gcc/loop-doloop.cc @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "loop-unroll.h" #include "regs.h" #include "df.h" +#include "targhooks.h" /* This module is used to modify loops with a determinable number of iterations to use special low-overhead looping instructions. @@ -770,6 +771,18 @@ doloop_optimize (class loop *loop) basic_block loop_end = desc->out_edge->src; bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified); +/* iv_analysis_loop_init calls df_analyze_loop, which computes just + partial df for blocks of the loop only. The above will catch if + any of the modified registers are use inside of the loop body, but + it will most likely not have accurate info on registers used + at the destination of the out_edge. We call df_analyze on the + whole function at the start of the pass though and iterate only + on innermost loops or from innermost loops, so + live in on desc->out_edge->dest should be still unmodified from + the initial df_analyze. */ +if (!fail) + fail = bitmap_intersect_p (df_get_live_in (desc->out_edge->dest), +modified); BITMAP_FREE (modified); if (fail) @@ -795,7 +808,12 @@ doloop_optimize_loops (void) df_live_set_all_dirty (); } - for (auto loop : loops_list (cfun, 0)) + df_analyze (); + + for (auto loop : loops_list (cfun, + targetm.can_use_doloop_p + == can_use_doloop_if_innermost + ? LI_ONLY_INNERMOST : LI_FROM_INNERMOST)) doloop_optimize (loop); if (optimize == 1) diff --git a/gcc/testsuite/g++.dg/torture/pr113994.C b/gcc/testsuite/g++.dg/torture/pr113994.C new file mode 100644 index ..c9c186d45ee7 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr113994.C @@ -0,0 +1,31 @@ +// PR rtl-optimization/113994 +// { dg-do run } + +#include +
[gcc r14-11155] warn-access: Fix up matching_alloc_calls_p [PR118024]
https://gcc.gnu.org/g:1dd428c751fc4c394a60f007d483a61fbac3c7b9 commit r14-11155-g1dd428c751fc4c394a60f007d483a61fbac3c7b9 Author: Jakub Jelinek Date: Sat Dec 14 11:27:20 2024 +0100 warn-access: Fix up matching_alloc_calls_p [PR118024] The following testcase ICEs because of a bug in matching_alloc_calls_p. The loop was apparently meant to be walking the two attribute chains in lock-step, but doesn't really do that. If the first lookup_attribute returns non-NULL, the second one is not done, so rmats in that case can be some random unrelated attribute rather than "malloc" attribute; the body assumes even rmats if non-NULL is "malloc" attribute and relies on its argument to be a "malloc" argument and if it is some other attribute with incompatible attribute, it just crashes. Now, fixing that in the obvious way, instead of doing (amats = lookup_attribute ("malloc", amats)) || (rmats = lookup_attribute ("malloc", rmats)) in the condition do ((amats = lookup_attribute ("malloc", amats)), (rmats = lookup_attribute ("malloc", rmats)), (amats || rmats)) fixes the testcase but regresses Wmismatched-dealloc-{2,3}.c tests. The problem is that walking the attribute lists in a lock-step is obviously a very bad idea, there is no requirement that the same deallocators are present in the same order on both decls, e.g. there could be an extra malloc attribute without argument in just one of the lists, or the order of say free/realloc could be swapped, etc. We don't generally document nor enforce any particular ordering of attributes (even when for some attributes we just handle the first one rather than all). So, this patch instead simply splits it into two loops, the first one walks alloc_decl attributes, the second one walks dealloc_decl attributes. If the malloc attribute argument is a built-in, that doesn't change anything, and otherwise we have the chance to populate the whole common_deallocs hash_set in the first loop and then can check it in the second one (and don't need to use more expensive add method on it, can just check contains there). Not to mention that it also fixes the case when the function would incorrectly return true if there wasn't a common deallocator between the two, but dealloc_decl had 2 malloc attributes with the same deallocator. 2024-12-14 Jakub Jelinek PR middle-end/118024 * gimple-ssa-warn-access.cc (matching_alloc_calls_p): Walk malloc attributes of alloc_decl and dealloc_decl in separate loops rather than in lock-step. Use common_deallocs.contains rather than common_deallocs.add in the second loop. * gcc.dg/pr118024.c: New test. (cherry picked from commit 9537ca5ad9bc23d7e9c446b4a7cbb98f63bddb6a) Diff: --- gcc/gimple-ssa-warn-access.cc | 85 - gcc/testsuite/gcc.dg/pr118024.c | 15 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index 5c1f3a414b1a..59ddca017d1a 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -1933,52 +1933,49 @@ matching_alloc_calls_p (tree alloc_decl, tree dealloc_decl) headers. With AMATS set to the Allocator's Malloc ATtributes, and RMATS set to Reallocator's Malloc ATtributes... */ - for (tree amats = DECL_ATTRIBUTES (alloc_decl), -rmats = DECL_ATTRIBUTES (dealloc_decl); - (amats = lookup_attribute ("malloc", amats)) -|| (rmats = lookup_attribute ("malloc", rmats)); - amats = amats ? TREE_CHAIN (amats) : NULL_TREE, -rmats = rmats ? TREE_CHAIN (rmats) : NULL_TREE) -{ - if (tree args = amats ? TREE_VALUE (amats) : NULL_TREE) - if (tree adealloc = TREE_VALUE (args)) - { - if (DECL_P (adealloc) - && fndecl_built_in_p (adealloc, BUILT_IN_NORMAL)) - { - built_in_function fncode = DECL_FUNCTION_CODE (adealloc); - if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC) - { - if (realloc_kind == alloc_kind_t::builtin) - return true; - alloc_dealloc_kind = alloc_kind_t::builtin; - } - continue; - } - - common_deallocs.add (adealloc); - } + for (tree amats = DECL_ATTRIBUTES (alloc_decl); + (amats = lookup_attribute ("malloc", amats)); + amats = amats ? TREE_CHAIN (amats) : NULL_TREE) +if (tree args = amats ? TREE_VALUE (amats) : NULL_TREE) + if (tree adealloc = TREE_VALUE (args)) + { + if (DECL_P (adealloc) + && fndecl_built_in_p (adealloc, BUILT_IN_NORMAL)) + { + built_in_function fncode = DECL_FUNCTION_CODE (adeal
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] adjust for narrowing converts before shifts [PR118206]
https://gcc.gnu.org/g:1a5cf10d2b214485f8dfa0ac402bb897e4409eac commit 1a5cf10d2b214485f8dfa0ac402bb897e4409eac Author: Alexandre Oliva Date: Thu Jan 9 03:05:41 2025 -0300 [ifcombine] adjust for narrowing converts before shifts [PR118206] A narrowing conversion and a shift both drop bits from the loaded value, but we need to take into account which one comes first to get the right number of bits and mask. Fold when applying masks to parts, comparing the parts, and combining the results, in the odd chance either mask happens to be zero. for gcc/ChangeLog PR tree-optimization/118206 * gimple-fold.cc (decode_field_reference): Account for upper bits dropped by narrowing conversions whether before or after a right shift. (fold_truth_andor_for_ifcombine): Fold masks, compares, and combined results. for gcc/testsuite/ChangeLog PR tree-optimization/118206 * gcc.dg/field-merge-18.c: New. Diff: --- gcc/gimple-fold.cc| 39 - gcc/testsuite/gcc.dg/field-merge-18.c | 46 +++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index c8a726e0ae3f..d95f04213ee4 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7547,6 +7547,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, int shiftrt = 0; tree res_ops[2]; machine_mode mode; + bool convert_before_shift = false; *load = NULL; *psignbit = false; @@ -7651,6 +7652,12 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (*load) loc[3] = gimple_location (*load); exp = res_ops[0]; + /* This looks backwards, but we're going back the def chain, so if we +find the conversion here, after finding a shift, that's because the +convert appears before the shift, and we should thus adjust the bit +pos and size because of the shift after adjusting it due to type +conversion. */ + convert_before_shift = true; } /* Identify the load, if there is one. */ @@ -7693,6 +7700,15 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, *pvolatilep = volatilep; /* Adjust shifts... */ + if (convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) +{ + HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); + if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) + *pbitpos += excess; + *pbitsize -= excess; +} + if (shiftrt) { if (!*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -7701,7 +7717,8 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, } /* ... and bit position. */ - if (outer_type && *pbitsize > TYPE_PRECISION (outer_type)) + if (!convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) { HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -8377,6 +8394,8 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region, ll_align, BITS_PER_WORD, volatilep, &lnmode)) l_split_load = false; + /* ??? If ll and rl share the same load, reuse that? + See PR 118206 -> gcc.dg/field-merge-18.c */ else { /* Consider the possibility of recombining loads if any of the @@ -8757,11 +8776,11 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, /* Apply masks. */ for (int j = 0; j < 2; j++) if (mask[j] != wi::mask (0, true, mask[j].get_precision ())) - op[j] = build2_loc (locs[j][2], BIT_AND_EXPR, type, - op[j], wide_int_to_tree (type, mask[j])); + op[j] = fold_build2_loc (locs[j][2], BIT_AND_EXPR, type, + op[j], wide_int_to_tree (type, mask[j])); - cmp[i] = build2_loc (i ? rloc : lloc, wanted_code, truth_type, - op[0], op[1]); + cmp[i] = fold_build2_loc (i ? rloc : lloc, wanted_code, truth_type, + op[0], op[1]); } /* Reorder the compares if needed. */ @@ -8773,7 +8792,15 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (parts == 1) result = cmp[0]; else if (!separatep || !maybe_separate) -result = build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]); +{ + /* Only fold if any of the cmp is known, otherwise we may lose the +sequence point, and that may prevent further optimizations. */ + if (TREE_CODE (cmp[0]) == INTEGER_CST + || TREE_CODE (cmp[1]) == INTEGER_CST) + result = fold_build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1
[gcc/aoliva/heads/testme] (3 commits) [ifcombine] fix mask variable test to match use [PR118344]
The branch 'aoliva/heads/testme' was updated to point to: adbdc5d3f1f3... [ifcombine] fix mask variable test to match use [PR118344] It previously pointed to: 9f16aa5e1808... [ifcombine] adjust for narrowing converts before shifts [PR Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 9f16aa5... [ifcombine] adjust for narrowing converts before shifts [PR 5ce16b0... [ifcombine] reuse left-hand mask to decode right-hand xor o c693789... [ifcombine] fix mask variable test to match use Summary of changes (added commits): --- adbdc5d... [ifcombine] fix mask variable test to match use [PR118344] b17ab50... [ifcombine] reuse left-hand mask to decode right-hand xor o 1a5cf10... [ifcombine] adjust for narrowing converts before shifts [PR
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] reuse left-hand mask to decode right-hand xor operand
https://gcc.gnu.org/g:b17ab50f84f0cfcbcdb188671c65b03dc24f7acc commit b17ab50f84f0cfcbcdb188671c65b03dc24f7acc Author: Alexandre Oliva Date: Thu Jan 9 11:57:03 2025 -0300 [ifcombine] reuse left-hand mask to decode right-hand xor operand If fold_truth_andor_for_ifcombine applies a mask to an xor, say because the result of the xor is compared with a power of two [minus one], we have to apply the same mask when processing both the left- and right-hand xor paths for the transformation to be sound. Arrange for decode_field_reference to propagate the incoming mask along with the expression to the right-hand operand. Don't require the right-hand xor operand to be a constant, that was a cut&pasto. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Add xor_pand_mask. Propagate pand_mask to the right-hand xor operand. Don't require the right-hand xor operand to be a constant. (fold_truth_andor_for_ifcombine): Pass right-hand mask when appropriate. Diff: --- gcc/gimple-fold.cc | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index d95f04213ee4..20b5024d861d 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7519,8 +7519,9 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, - *XOR_P will be set to TRUE, and the left-hand operand of the XOR will be - decoded. If *XOR_P is TRUE, XOR_CMP_OP is supposed to be NULL, and then the + *XOR_P will be set to TRUE, *XOR_PAND_MASK will be copied from *PAND_MASK, + and the left-hand operand of the XOR will be decoded. If *XOR_P is TRUE, + XOR_CMP_OP and XOR_PAND_MASK are supposed to be NULL, and then the right-hand operand of the XOR will be decoded. *LOAD is set to the load stmt of the innermost reference, if any, @@ -7537,7 +7538,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpos, bool *punsignedp, bool *preversep, bool *pvolatilep, wide_int *pand_mask, bool *psignbit, - bool *xor_p, tree *xor_cmp_op, + bool *xor_p, tree *xor_cmp_op, wide_int *xor_pand_mask, gimple **load, location_t loc[4]) { tree exp = *pexp; @@ -7599,15 +7600,14 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, and_mask = *pand_mask; /* Turn (a ^ b) [!]= 0 into a [!]= b. */ - if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops) - && uniform_integer_cst_p (res_ops[1])) + if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops)) { /* No location recorded for this one, it's entirely subsumed by the compare. */ if (*xor_p) { exp = res_ops[1]; - gcc_checking_assert (!xor_cmp_op); + gcc_checking_assert (!xor_cmp_op && !xor_pand_mask); } else if (!xor_cmp_op) /* Not much we can do when xor appears in the right-hand compare @@ -7618,6 +7618,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, *xor_p = true; exp = res_ops[0]; *xor_cmp_op = *pexp; + *xor_pand_mask = *pand_mask; } } @@ -8152,19 +8153,21 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, bool l_xor = false, r_xor = false; ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos, &ll_unsignedp, &ll_reversep, &volatilep, -&ll_and_mask, &ll_signbit, &l_xor, &lr_arg, +&ll_and_mask, &ll_signbit, +&l_xor, &lr_arg, &lr_and_mask, &ll_load, ll_loc); lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos, &lr_unsignedp, &lr_reversep, &volatilep, -&lr_and_mask, &lr_signbit, &l_xor, 0, +&lr_and_mask, &lr_signbit, &l_xor, 0, 0, &lr_load, lr_loc); rl_inner = decode_field_reference (&rl_arg, &rl_bitsize, &rl_bitpos, &rl_unsignedp, &rl_reversep, &volatilep, -&rl_and_mask, &rl_signbit, &r_xor, &rr_arg, +&rl_and_mask, &rl_signbit, +&r_xor, &rr_arg, &rr_and_mask, &rl_load, rl_loc); rr_inner = decode_field_reference (&rr_arg, &rr_bitsize, &rr_bitpos, &rr_unsignedp, &rr_reversep,
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] fix mask variable test to match use [PR118344]
https://gcc.gnu.org/g:adbdc5d3f1f3d9d13f809c8c9f02f9514d2e65dc commit adbdc5d3f1f3d9d13f809c8c9f02f9514d2e65dc Author: Alexandre Oliva Date: Thu Jan 9 10:23:50 2025 -0300 [ifcombine] fix mask variable test to match use [PR118344] There was a cut&pasto in the rr_and_mask's adjustment to match the combined type: the test on whether there was a mask already was testing the wrong variable, and then it might crash or otherwise fail accessing an undefined mask. This only hit with checking enabled, and rarely at that. for gcc/ChangeLog PR tree-optimization/118344 * gimple-fold.cc (fold_truth_andor_for_ifcombine): Fix typo in rr_and_mask's type adjustment test. for gcc/testsuite/ChangeLog PR tree-optimization/118344 * gcc.dg/field-merge-19.c: New. Diff: --- gcc/testsuite/gcc.dg/field-merge-19.c | 41 +++ 1 file changed, 41 insertions(+) diff --git a/gcc/testsuite/gcc.dg/field-merge-19.c b/gcc/testsuite/gcc.dg/field-merge-19.c new file mode 100644 index ..5622baa52b0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/field-merge-19.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fchecking" } */ + +/* PR tree-optimization/118344 */ + +/* This used to ICE attempting to extend a mask variable after testing the + wrong mask variable. */ + +int d, e, g, h, i, c, j; +static short k; +char o; +static int *p; +static long *a; +int b[0]; +int q(int s, int t, int *u, int *v) { + for (int f = 0; f < s; f++) +if ((t & v[f]) != u[f]) + return 0; + return 1; +} +int w(int s, int t) { + int l[] = {t, t, t, t}, m[] = {e, e, 3, 1}; + int n = q(s, d, l, m); + return n; +} +int x(unsigned s) { + unsigned r; + if (s >= -1) +return 1; + r = 1000; + while (s > 1 / r) +r /= 2; + return g ? 2 : 0; +} +void y() { + for (;;) { +b[w(8, *p)] = h; +for (; a + k; j = o) + i &= c = x(6) < 0; + } +}
[gcc r15-6729] Fortran: Cylce detection for non vtypes only. [PR118337]
https://gcc.gnu.org/g:d107140205537aec9c8e235d869b166e9b884775 commit r15-6729-gd107140205537aec9c8e235d869b166e9b884775 Author: Andre Vehreschild Date: Wed Jan 8 14:58:35 2025 +0100 Fortran: Cylce detection for non vtypes only. [PR118337] gcc/fortran/ChangeLog: PR fortran/118337 * resolve.cc (resolve_fl_derived0): Exempt vtypes from cycle detection. Diff: --- gcc/fortran/resolve.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 6dcda70679f2..dab0c3af6018 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -16840,7 +16840,8 @@ resolve_fl_derived0 (gfc_symbol *sym) /* Resolving components below, may create vtabs for which the cyclic type information needs to be present. */ - resolve_cyclic_derived_type (sym); + if (!sym->attr.vtype) +resolve_cyclic_derived_type (sym); c = (sym->attr.is_class) ? CLASS_DATA (sym->components) : sym->components;
[gcc r15-6742] s390: Fix s390_constant_via_vgbm_p() [PR118362]
https://gcc.gnu.org/g:2f31819a0ac7b000fa3a456e5b068242e954edac commit r15-6742-g2f31819a0ac7b000fa3a456e5b068242e954edac Author: Stefan Schulze Frielinghaus Date: Thu Jan 9 17:49:02 2025 +0100 s390: Fix s390_constant_via_vgbm_p() [PR118362] Optimization s390_constant_via_vgbm_p() should only apply to constant vectors which can be expressed by the hardware, i.e., which have a size of at most 16-bytes, similar as it is done for s390_constant_via_vgm_p() and s390_constant_via_vrepi_p(). gcc/ChangeLog: PR target/118362 * config/s390/s390.cc (s390_constant_via_vgbm_p): Allow at most 16-byte vectors. Diff: --- gcc/config/s390/s390.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 918a2cd6c6df..08acb69de3e8 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -2818,7 +2818,7 @@ s390_constant_via_vgbm_p (rtx op, unsigned *mask) unsigned tmp_mask = 0; int nunit, unit_size; - if (GET_CODE (op) == CONST_VECTOR) + if (GET_CODE (op) == CONST_VECTOR && GET_MODE_SIZE (GET_MODE (op)) <= 16) { if (GET_MODE_INNER (GET_MODE (op)) == TImode || GET_MODE_INNER (GET_MODE (op)) == TFmode)
[gcc r15-6741] c++: ICE during requires-expr partial subst [PR118060]
https://gcc.gnu.org/g:ca79349c050c27ff466735ba78d2e2bbce56ffdc commit r15-6741-gca79349c050c27ff466735ba78d2e2bbce56ffdc Author: Patrick Palka Date: Thu Jan 9 10:50:19 2025 -0500 c++: ICE during requires-expr partial subst [PR118060] Here during partial substitution of the requires-expression (as part of CTAD constraint rewriting) we segfault from the INDIRECT_REF case of convert_to_void due *f(u) being type-dependent. We should just defer checking convert_to_void until satisfaction. PR c++/118060 gcc/cp/ChangeLog: * constraint.cc (tsubst_valid_expression_requirement): Don't check convert_to_void during partial substitution. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-requires40.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/constraint.cc | 4 +++- gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C | 12 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 9bcb4dcc9794..52ad88f37be0 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1336,7 +1336,9 @@ tsubst_valid_expression_requirement (tree t, tree args, sat_info info) { tsubst_flags_t quiet = info.complain & ~tf_warning_or_error; tree r = tsubst_expr (t, args, quiet, info.in_decl); - if (convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node) + if (r != error_mark_node + && (processing_template_decl + || convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node)) return r; if (info.diagnose_unsatisfaction_p ()) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C new file mode 100644 index ..918bab410f30 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C @@ -0,0 +1,12 @@ +// PR c++/118060 +// { dg-do compile { target c++20 } } + +int* f(int); + +template +struct A { + template requires requires (U u) { *f(u); } + A(T, U); +}; + +A a{0, 0};
[gcc r15-6736] c++: template-id dependence wrt local static arg [PR117792]
https://gcc.gnu.org/g:40f0f6ab75a391906bed40cbdc098b0df3a91af7 commit r15-6736-g40f0f6ab75a391906bed40cbdc098b0df3a91af7 Author: Patrick Palka Date: Thu Jan 9 10:49:45 2025 -0500 c++: template-id dependence wrt local static arg [PR117792] Here we end up ICEing at instantiation time for the call to f ultimately because we wrongly consider the call to be non-dependent, and so we specialize f ahead of time and then get confused when fully substituting this specialization. The call is dependent due to [temp.dep.temp]/3 and we miss that because function template-id arguments aren't coerced until overload resolution, and so the local static template argument lacks an implicit cast to reference type that value_dependent_expression_p looks for before considering dependence of the address. Other kinds of template-ids aren't affected since they're coerced ahead of time. So when considering dependence of a function template-id, we need to conservatively consider dependence of the address of each argument (if applicable). PR c++/117792 gcc/cp/ChangeLog: * pt.cc (type_dependent_expression_p): Consider the dependence of the address of each template argument of a function template-id. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/nontype7.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/pt.cc | 10 -- gcc/testsuite/g++.dg/cpp1z/nontype7.C | 22 ++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index dfaa8906a2cf..081285ef7209 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -29034,9 +29034,15 @@ type_dependent_expression_p (tree expression) if (TREE_CODE (expression) == TEMPLATE_ID_EXPR) { - if (any_dependent_template_arguments_p - (TREE_OPERAND (expression, 1))) + tree args = TREE_OPERAND (expression, 1); + if (any_dependent_template_arguments_p (args)) return true; + /* Arguments of a function template-id aren't necessarily coerced +yet so we must conservatively assume that the address (and not +just value) of the argument matters as per [temp.dep.temp]/3. */ + for (tree arg : tree_vec_range (args)) + if (has_value_dependent_address (arg)) + return true; expression = TREE_OPERAND (expression, 0); if (identifier_p (expression)) return true; diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype7.C b/gcc/testsuite/g++.dg/cpp1z/nontype7.C new file mode 100644 index ..f103d5a6888e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nontype7.C @@ -0,0 +1,22 @@ +// PR c++/117792 +// { dg-do compile { target c++17 } } + +template +void f(T) { } + +template +void f(...) = delete; + +template int v; + +template struct A { }; + +template +void g() { + static constexpr int local_static = 0; + auto x = v; // OK + A y; // OK + f(0); // ICE +} + +template void g();
[gcc r15-6737] c++: current inst w/ indirect dependent bases [PR117993]
https://gcc.gnu.org/g:57904dc27d5b27226912838cdd6b5272cec4d050 commit r15-6737-g57904dc27d5b27226912838cdd6b5272cec4d050 Author: Patrick Palka Date: Thu Jan 9 10:50:06 2025 -0500 c++: current inst w/ indirect dependent bases [PR117993] In the first testcase we're overeagerly diagnosing qualified name lookup failure for f from the current instantiation B::C ahead of time because we (correctly) deem C to not have any direct dependent bases: its direct base B is part of the current instantiation and therefore not a dependent base, and we decide it's safe to diagnose name lookup failure ahead of time. But this testcase demonstrates it's not enough to consider only direct dependent bases: f is defined in A which is a dependent base of B, so qualified name lookup from C won't search it ahead of time and in turn won't be exhaustive, and so it's wrong to diagnose lookup failure ahead of time. This ultimately suggests that any_dependent_bases_p needs to consider indirect bases as well. To that end it seems sufficient to make the predicate recurse into any !BINFO_DEPENDENT_BASE_P base since the recursive call will exit early for non-dependent types. So effectively we'll only recurse into bases belonging to the current instantiation. I considered more narrowly making only dependentish_scope_p consider indirect dependent bases, but it seems other any_dependent_bases_p callers also want this behavior, e.g. build_new_method_call for benefit of the second testcase (which is an even older regression since GCC 7). PR c++/117993 gcc/cp/ChangeLog: * search.cc (any_dependent_bases_p): Recurse into bases (of dependent type) that are not BINFO_DEPENDENT_BASE_P. Document default argument. gcc/testsuite/ChangeLog: * g++.dg/template/dependent-base4.C: New test. * g++.dg/template/dependent-base5.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/search.cc| 7 +-- gcc/testsuite/g++.dg/template/dependent-base4.C | 23 +++ gcc/testsuite/g++.dg/template/dependent-base5.C | 22 ++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc index af6c892d702d..cea9f7c689ba 100644 --- a/gcc/cp/search.cc +++ b/gcc/cp/search.cc @@ -2843,7 +2843,7 @@ original_binfo (tree binfo, tree here) TYPE). */ bool -any_dependent_bases_p (tree type) +any_dependent_bases_p (tree type /* = current_nonlambda_class_type () */) { if (!type || !CLASS_TYPE_P (type) || !uses_template_parms (type)) return false; @@ -2858,7 +2858,10 @@ any_dependent_bases_p (tree type) unsigned i; tree base_binfo; FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo) -if (BINFO_DEPENDENT_BASE_P (base_binfo)) +if (BINFO_DEPENDENT_BASE_P (base_binfo) + /* Recurse to also consider possibly dependent bases of a base that + is part of the current instantiation. */ + || any_dependent_bases_p (BINFO_TYPE (base_binfo))) return true; return false; diff --git a/gcc/testsuite/g++.dg/template/dependent-base4.C b/gcc/testsuite/g++.dg/template/dependent-base4.C new file mode 100644 index ..84e53b5f3fb7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-base4.C @@ -0,0 +1,23 @@ +// PR c++/117993 + +template +struct A { + void f(); + typedef void type; +}; + +template +struct B : A { + template struct C; +}; + +template +template +struct B::C : B { + void g(C& c) { +this->f(); // { dg-bogus "member" } +c.f(); // { dg-bogus "member" } +C::f(); // { dg-bogus "member" } +typename C::type* p; // { dg-bogus "not name a type" } + } +}; diff --git a/gcc/testsuite/g++.dg/template/dependent-base5.C b/gcc/testsuite/g++.dg/template/dependent-base5.C new file mode 100644 index ..2e9cdaa242bc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-base5.C @@ -0,0 +1,22 @@ +template +struct A { }; + +template +struct B : A { + template struct C; +}; + +struct D { void f(); }; + +template +template +struct B::C : B { + void g() { +D::f(); // { dg-bogus "without object" } + } +}; + +template<> +struct A : D { }; + +template struct B::C;
[gcc r15-6740] c++: tf_partial and instantiate_template [PR117887]
https://gcc.gnu.org/g:27d620d67697157f2269f3add4cb830540ac5795 commit r15-6740-g27d620d67697157f2269f3add4cb830540ac5795 Author: Patrick Palka Date: Thu Jan 9 10:50:16 2025 -0500 c++: tf_partial and instantiate_template [PR117887] Ever since r15-3530-gdfb63765e994be the extra-args mechanism now expects to see tf_partial whenever doing a partial substitution containing dependent arguments. The below testcases show that instantiate_template for AT with args={T}/{T*} is neglecting to set it in that case, and we end up ICEing from add_extra_args during the subsequent full substitution. This patch makes instantiate_template set tf_partial accordingly. PR c++/117887 gcc/cp/ChangeLog: * pt.cc (instantiate_template): Set tf_partial if arguments are dependent. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-requires39.C: New test. * g++.dg/cpp2a/lambda-targ10.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/pt.cc | 14 +++--- gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C | 17 + gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C | 17 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 081285ef7209..19df9ccb6afd 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -22437,7 +22437,10 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) substitution of a template variable, but the type of the variable template may be auto, in which case we will call do_auto_deduction in mark_used (which clears tf_partial) and the auto must be properly - reduced at that time for the deduction to work. */ + reduced at that time for the deduction to work. + + Note that later below we set tf_partial iff there are dependent arguments; + the above is concerned specifically about the non-dependent case. */ complain &= tf_warning_or_error; gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); @@ -22516,9 +22519,14 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) template, not the context of the overload resolution we're doing. */ push_to_top_level (); /* If there are dependent arguments, e.g. because we're doing partial - ordering, make sure processing_template_decl stays set. */ + ordering, make sure processing_template_decl stays set. And set + tf_partial mainly for benefit of instantiation of alias templates + that contain extra-args trees. */ if (uses_template_parms (targ_ptr)) -++processing_template_decl; +{ + ++processing_template_decl; + complain |= tf_partial; +} if (DECL_CLASS_SCOPE_P (gen_tmpl)) { tree ctx; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C new file mode 100644 index ..b13682033dac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C @@ -0,0 +1,17 @@ +// PR c++/117887 +// { dg-do compile { target c++20 } } + +template struct A { static constexpr bool value = V; }; + +template +using AT = A; + +template struct B { using type = T; }; + +template +void f() { + static_assert( B>::type::value); + static_assert(!B>::type::value); +} + +template void f(); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C new file mode 100644 index ..7f175c93062f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C @@ -0,0 +1,17 @@ +// PR c++/117887 +// { dg-do compile { target c++20 } } + +template struct A { static constexpr bool value = V; }; + +template +using AT = A<[]{return sizeof(T) != sizeof(T*); }(), T>; + +template struct B { using type = T; }; + +template +void f() { + static_assert( B>::type::value); + static_assert(!B>::type::value); +} + +template void f();
[gcc r15-6738] c++: relax ICE for unexpected trees during constexpr [PR117925]
https://gcc.gnu.org/g:eeedc54cc81c4dfb472ecbd6f14cfbf2dd035474 commit r15-6738-geeedc54cc81c4dfb472ecbd6f14cfbf2dd035474 Author: Patrick Palka Date: Thu Jan 9 10:50:08 2025 -0500 c++: relax ICE for unexpected trees during constexpr [PR117925] When we encounter an unexpected (likely templated) tree code during constexpr evaluation we currently ICE even in release mode. But it seems more user-friendly to just gracefully treat the expression as non-constant, which will be harmless most of the time (e.g. in the case of warning-specific or speculative constexpr folding as in the PR), and at worst will transform an ICE-on-valid bug into a rejects-valid bug. This is also what e.g. tsubst_expr does when it encounters an unexpected tree code. PR c++/117925 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression) : Relax ICE when encountering an unexpected tree code into a checking ICE guarded by flag_checking. Reviewed-by: Jason Merrill Diff: --- gcc/cp/constexpr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index c8be5a525ee4..7b02b51f756a 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8718,7 +8718,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, error_at (EXPR_LOCATION (t), "statement is not a constant expression"); } - else + else if (flag_checking) internal_error ("unexpected expression %qE of kind %s", t, get_tree_code_name (TREE_CODE (t))); *non_constant_p = true;
[gcc r15-6739] c++: constexpr potentiality of CAST_EXPR [PR117925]
https://gcc.gnu.org/g:76d1061237b5cd57a274cd8bc8fe02a6f407baa9 commit r15-6739-g76d1061237b5cd57a274cd8bc8fe02a6f407baa9 Author: Patrick Palka Date: Thu Jan 9 10:50:12 2025 -0500 c++: constexpr potentiality of CAST_EXPR [PR117925] We're incorrectly treating the templated callee (FnPtr)fnPtr, represented as CAST_EXPR with TREE_LIST operand, as potentially constant here due to neglecting to look through the TREE_LIST in the CAST_EXPR case of p_c_e_1. PR c++/117925 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) : Fix check for class conversion to literal type to properly look through the TREE_LIST operand of a CAST_EXPR. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent35.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/constexpr.cc | 11 --- gcc/testsuite/g++.dg/template/non-dependent35.C | 8 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 7b02b51f756a..1345bc124efb 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -10369,9 +10369,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, && (dependent_type_p (TREE_TYPE (t)) || !COMPLETE_TYPE_P (TREE_TYPE (t)) || literal_type_p (TREE_TYPE (t))) - && TREE_OPERAND (t, 0)) - { - tree type = TREE_TYPE (TREE_OPERAND (t, 0)); + && TREE_OPERAND (t, 0) + && (TREE_CODE (t) != CAST_EXPR + || !TREE_CHAIN (TREE_OPERAND (t, 0 + { + tree from = TREE_OPERAND (t, 0); + if (TREE_CODE (t) == CAST_EXPR) + from = TREE_VALUE (from); + tree type = TREE_TYPE (from); /* If this is a dependent type, it could end up being a class with conversions. */ if (type == NULL_TREE || WILDCARD_TYPE_P (type)) diff --git a/gcc/testsuite/g++.dg/template/non-dependent35.C b/gcc/testsuite/g++.dg/template/non-dependent35.C new file mode 100644 index ..7e3ba99b0235 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent35.C @@ -0,0 +1,8 @@ +// PR c++/117925 + +typedef int(*FnPtr)(); + +template +void fnICE(void* fnPtr) { + ((FnPtr)fnPtr)(); +}
[gcc(refs/users/aoliva/heads/testme)] [ifcombine] adjust for narrowing converts before shifts
https://gcc.gnu.org/g:1b562cb3056cdd750eb23e5b2b03356773117781 commit 1b562cb3056cdd750eb23e5b2b03356773117781 Author: Alexandre Oliva Date: Thu Jan 9 03:05:41 2025 -0300 [ifcombine] adjust for narrowing converts before shifts A narrowing conversion and a shift both drop bits from the loaded value, but we need to take into account which one comes first to get the right number of bits and mask. While at that, don't require a constant to recognize a xor, that was added in error. Fold when applying masks to parts, comparing the parts, and combining the results, in the odd chance either mask happens to be zero. for gcc/ChangeLog PR tree-optimization/118206 * gimple-fold.cc (decode_field_reference): Account for upper bits dropped by narrowing conversions whether before or after a right shift. Don't require an integer for xor. (fold_truth_andor_for_ifcombine): Fold masks, compares, and combined results. for gcc/testsuite/ChangeLog PR tree-optimization/118206 * gcc.dg/field-merge-18.c: New. Diff: --- gcc/gimple-fold.cc| 42 +--- gcc/testsuite/gcc.dg/field-merge-18.c | 45 +++ 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index c8a726e0ae3f..a6ecec08b8e3 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7547,6 +7547,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, int shiftrt = 0; tree res_ops[2]; machine_mode mode; + bool convert_before_shift = false; *load = NULL; *psignbit = false; @@ -7598,8 +7599,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, and_mask = *pand_mask; /* Turn (a ^ b) [!]= 0 into a [!]= b. */ - if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops) - && uniform_integer_cst_p (res_ops[1])) + if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops)) { /* No location recorded for this one, it's entirely subsumed by the compare. */ @@ -7651,6 +7651,12 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (*load) loc[3] = gimple_location (*load); exp = res_ops[0]; + /* This looks backwards, but we're going back the def chain, so if we +find the conversion here, after finding a shift, that's because the +convert appears before the shift, and we should thus adjust the bit +pos and size because of the shift after adjusting it due to type +conversion. */ + convert_before_shift = true; } /* Identify the load, if there is one. */ @@ -7693,6 +7699,15 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, *pvolatilep = volatilep; /* Adjust shifts... */ + if (convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) +{ + HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); + if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) + *pbitpos += excess; + *pbitsize -= excess; +} + if (shiftrt) { if (!*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -7701,7 +7716,8 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, } /* ... and bit position. */ - if (outer_type && *pbitsize > TYPE_PRECISION (outer_type)) + if (!convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) { HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -8377,6 +8393,8 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region, ll_align, BITS_PER_WORD, volatilep, &lnmode)) l_split_load = false; + /* ??? If ll and rl share the same load, reuse that? + See PR 118206 -> gcc.dg/field-merge-18.c */ else { /* Consider the possibility of recombining loads if any of the @@ -8757,11 +8775,11 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, /* Apply masks. */ for (int j = 0; j < 2; j++) if (mask[j] != wi::mask (0, true, mask[j].get_precision ())) - op[j] = build2_loc (locs[j][2], BIT_AND_EXPR, type, - op[j], wide_int_to_tree (type, mask[j])); + op[j] = fold_build2_loc (locs[j][2], BIT_AND_EXPR, type, + op[j], wide_int_to_tree (type, mask[j])); - cmp[i] = build2_loc (i ? rloc : lloc, wanted_code, truth_type, - op[0], op[1]); + cmp[i] = fold_build2_loc (i ? rloc : lloc, wanted_code, truth_type, + op[0], op[1]); } /* Reorder the compares if needed. */ @@ -8773,7
[gcc/aoliva/heads/testme] [ifcombine] adjust for narrowing converts before shifts
The branch 'aoliva/heads/testme' was updated to point to: 1b562cb3056c... [ifcombine] adjust for narrowing converts before shifts It previously pointed to: 64bed88e5aea... [ifcombine] adjust for narrowing converts before shifts Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 64bed88... [ifcombine] adjust for narrowing converts before shifts Summary of changes (added commits): --- 1b562cb... [ifcombine] adjust for narrowing converts before shifts
[gcc(refs/users/aoliva/heads/testme)] testsuite: generalize ifcombine field-merge tests [PR118025]
https://gcc.gnu.org/g:fe67e1e05a08778780ff887a8f2b5166c4e343ee commit fe67e1e05a08778780ff887a8f2b5166c4e343ee Author: Alexandre Oliva Date: Mon Jan 6 18:40:18 2025 -0300 testsuite: generalize ifcombine field-merge tests [PR118025] A number of tests that check for specific ifcombine transformations fail on AVR and PRU targets, whose type sizes and alignments aren't conducive of the expected transformations. Adjust the expectations. Most execution tests should run successfully regardless of the transformations, but a few that could conceivably fail if short and char have the same bit width now check for that and bypass the tests that would fail. Conversely, one test that had such a runtime test, but that would work regardless, no longer has that runtime test, and its types are narrowed so that the transformations on 32-bit targets are more likely to be the same as those that used to take place on 64-bit targets. This latter change is somewhat obviated by a separate patch, but I've left it in place anyway. for gcc/testsuite/ChangeLog PR testsuite/118025 * field-merge-1.c: Skip BIT_FIELD_REF counting on AVR and PRU. * field-merge-3.c: Bypass the test if short doesn't have the expected size. * field-merge-8.c: Likewise. * field-merge-9.c: Likewise. Skip optimization counting on AVR and PRU. * field-merge-14.c: Skip optimization counting on AVR and PRU. * field-merge-15.c: Likewise. * field-merge-17.c: Likewise. * field-merge-16.c: Likewise. Drop runtime bypass. Use smaller types. Diff: --- gcc/testsuite/gcc.dg/field-merge-1.c | 2 +- gcc/testsuite/gcc.dg/field-merge-13.c | 2 +- gcc/testsuite/gcc.dg/field-merge-14.c | 3 ++- gcc/testsuite/gcc.dg/field-merge-15.c | 2 +- gcc/testsuite/gcc.dg/field-merge-16.c | 17 +++-- gcc/testsuite/gcc.dg/field-merge-17.c | 2 +- gcc/testsuite/gcc.dg/field-merge-3.c | 2 ++ gcc/testsuite/gcc.dg/field-merge-8.c | 2 ++ gcc/testsuite/gcc.dg/field-merge-9.c | 4 +++- 9 files changed, 20 insertions(+), 16 deletions(-) diff --git a/gcc/testsuite/gcc.dg/field-merge-1.c b/gcc/testsuite/gcc.dg/field-merge-1.c index 1818e104437e..4405d40ee79d 100644 --- a/gcc/testsuite/gcc.dg/field-merge-1.c +++ b/gcc/testsuite/gcc.dg/field-merge-1.c @@ -58,7 +58,7 @@ int main () { return 0; } -/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 8 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 8 "optimized" { target { ! { avr-*-* pru-*-* } } } } } */ /* { dg-final { scan-assembler-not "cmpb" { target { i*86-*-* || x86_64-*-* } } } } */ /* { dg-final { scan-assembler-times "cmpl" 8 { target { i*86-*-* || x86_64-*-* } } } } */ /* { dg-final { scan-assembler-times "cmpw" 8 { target { powerpc*-*-* || rs6000-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/field-merge-13.c b/gcc/testsuite/gcc.dg/field-merge-13.c index 7e4f4c499347..eeef73338f8e 100644 --- a/gcc/testsuite/gcc.dg/field-merge-13.c +++ b/gcc/testsuite/gcc.dg/field-merge-13.c @@ -90,4 +90,4 @@ int main () { return 0; } -/* { dg-final { scan-tree-dump-times "optimizing" 9 "ifcombine" } } */ +/* { dg-final { scan-tree-dump-times "optimizing" 9 "ifcombine" { target { ! { avr-*-* pru-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/field-merge-14.c b/gcc/testsuite/gcc.dg/field-merge-14.c index 91d84cfebf19..73259e0936e4 100644 --- a/gcc/testsuite/gcc.dg/field-merge-14.c +++ b/gcc/testsuite/gcc.dg/field-merge-14.c @@ -1,7 +1,8 @@ /* { dg-do run } */ /* { dg-options "-O -fdump-tree-ifcombine-details" } */ -/* Check that we don't get confused by multiple conversions. */ +/* Check that we don't get confused by multiple conversions. Conceivably, we + could combine both tests using b, but the current logic won't do that. */ __attribute__((noipa)) int f(int *a,int *d) diff --git a/gcc/testsuite/gcc.dg/field-merge-15.c b/gcc/testsuite/gcc.dg/field-merge-15.c index 34641e893c92..fc3846452716 100644 --- a/gcc/testsuite/gcc.dg/field-merge-15.c +++ b/gcc/testsuite/gcc.dg/field-merge-15.c @@ -33,4 +33,4 @@ int main () { return 0; } -/* { dg-final { scan-tree-dump-times "optimizing" 6 "ifcombine" } } */ +/* { dg-final { scan-tree-dump-times "optimizing" 6 "ifcombine" { target { ! { avr-*-* pru-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/field-merge-16.c b/gcc/testsuite/gcc.dg/field-merge-16.c index 2ca23ea663a4..afdaf45b6a94 100644 --- a/gcc/testsuite/gcc.dg/field-merge-16.c +++ b/gcc/testsuite/gcc.dg/field-merge-16.c @@ -4,17 +4,17 @@ /* Check that tests for sign-extension bits are handled correctly. */ struct s { - short a; - short b; - unsigned short c; - unsigned short d; -} __attribute__ ((aligned (8))); + signed char a; + signed char b; + unsigned char c; + unsigned char d; +} __attribute__ ((align