[gcc r15-6726] ada: Cleanup preanalysis of static expressions (part 3)

2025-01-09 Thread Marc Poulhi?s via Gcc-cvs
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

2025-01-09 Thread Marc Poulhi?s via Gcc-cvs
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.

2025-01-09 Thread LuluCheng via Gcc-cvs
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

2025-01-09 Thread Sam James via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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]

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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]

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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]

2025-01-09 Thread Jonathan Wakely via Gcc-cvs
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]

2025-01-09 Thread Jonathan Wakely via Gcc-cvs
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]

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Libstdc++-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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

2025-01-09 Thread Jonathan Wakely via Gcc-cvs
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

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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)

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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]

2025-01-09 Thread Jonathan Wakely via Gcc-cvs
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<>

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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

2025-01-09 Thread Jonathan Wakely via Gcc-cvs
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)

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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

2025-01-09 Thread Mikael Morin via Gcc-cvs
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

2025-01-09 Thread Vladimir Makarov via Gcc-cvs
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

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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

2025-01-09 Thread Torbjorn Svensson via Gcc-cvs
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]

2025-01-09 Thread Martin Uecker via Gcc-cvs
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

2025-01-09 Thread Jason Merrill via Gcc-cvs
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]

2025-01-09 Thread Tamar Christina via Gcc-cvs
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

2025-01-09 Thread Edwin Lu via Gcc-cvs
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

2025-01-09 Thread Mikael Morin via Gcc-cvs
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

2025-01-09 Thread Jason Merrill via Gcc-cvs
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

2025-01-09 Thread Jason Merrill via Gcc-cvs
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

2025-01-09 Thread Torbjorn Svensson via Gcc-cvs
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

2025-01-09 Thread Torbjorn Svensson via Gcc-cvs
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

2025-01-09 Thread Torbjorn Svensson via Gcc-cvs
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

2025-01-09 Thread Sam James via Gcc-cvs
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

2025-01-09 Thread Sam James via Gcc-cvs
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

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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

2025-01-09 Thread Jonathan Wakely via Libstdc++-cvs
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
-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
 to provide the symbols for the experimental C++ Contracts 
support.13.3
 Symbols for the Filesystem TS and C++23 
diff --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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jonathan Wakely via Gcc-cvs
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]

2025-01-09 Thread Thomas Schwinge via Gcc-cvs
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

2025-01-09 Thread Dimitar Dimitrov via Gcc-cvs
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]

2025-01-09 Thread Christophe Lyon via Gcc-cvs
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

2025-01-09 Thread Jonathan Wakely via Gcc-cvs
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
-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
 to provide the symbols for the experimental C++ Contracts 
support.13.3
 Symbols for the Filesystem TS and C++23 
diff --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)

2025-01-09 Thread Christophe Lyon via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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]

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

2025-01-09 Thread H.J. Lu via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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

2025-01-09 Thread Marc Poulhi?s via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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

2025-01-09 Thread Marc Poulhi?s via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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

2025-01-09 Thread Richard Biener via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Jakub Jelinek via Gcc-cvs
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]

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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]

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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]

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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]

2025-01-09 Thread Andre Vehreschild via Gcc-cvs
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]

2025-01-09 Thread Stefan Schulze Frielinghaus via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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]

2025-01-09 Thread Patrick Palka via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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]

2025-01-09 Thread Alexandre Oliva via Gcc-cvs
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

  1   2   >