[gcc r13-8455] gimple-iterator: Some gsi_safe_insert_*before fixes

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:73898ceb25052518b7e5427df3f05fe7e2784f55

commit r13-8455-g73898ceb25052518b7e5427df3f05fe7e2784f55
Author: Jakub Jelinek 
Date:   Thu Mar 14 09:57:13 2024 +0100

gimple-iterator: Some gsi_safe_insert_*before fixes

When trying to use the gsi_safe_insert*before APIs in bitint lowering,
I've discovered 3 issues and the following patch addresses those:

1) both split_block and split_edge update CDI_DOMINATORS if they are
   available, but because edge_before_returns_twice_call first splits
   and then adds an extra EDGE_ABNORMAL edge and then removes another
   one, the immediate dominators of both the new bb and the bb with
   returns_twice call need to change
2) the new EDGE_ABNORMAL edge had uninitialized probability; this patch
   copies the probability from the edge that is going to be removed
   and similarly copies other flags (EDGE_EXECUTABLE, EDGE_DFS_BACK,
   EDGE_IRREDUCIBLE_LOOP etc.)
3) if edge_before_returns_twice_call splits a block, then the bb with
   returns_twice call changes, so the gimple_stmt_iterator for it is
   no longer accurate, it points to the right statement, but gsi_bb
   and gsi_seq are no longer correct; the patch updates it

2024-03-14  Jakub Jelinek  

* gimple-iterator.cc (edge_before_returns_twice_call): Copy all
flags and probability from ad_edge to e edge.  If CDI_DOMINATORS
are computed, recompute immediate dominator of other_edge->src
and other_edge->dest.
(gsi_safe_insert_before, gsi_safe_insert_seq_before): Update *iter
for the returns_twice call case to the gsi_for_stmt (stmt) to deal
with update it for bb splitting.

(cherry picked from commit 8f6e0814b4bfd0a399055e9214562aebfcd902ad)

Diff:
---
 gcc/gimple-iterator.cc | 13 +
 1 file changed, 13 insertions(+)

diff --git a/gcc/gimple-iterator.cc b/gcc/gimple-iterator.cc
index c18ea22c486..07a77ca2a77 100644
--- a/gcc/gimple-iterator.cc
+++ b/gcc/gimple-iterator.cc
@@ -996,7 +996,18 @@ edge_before_returns_twice_call (basic_block bb)
  add_phi_arg (new_phi, PHI_ARG_DEF_FROM_EDGE (phi, ad_edge),
   e, gimple_phi_arg_location_from_edge (phi, ad_edge));
}
+  e->flags = ad_edge->flags;
+  e->probability = ad_edge->probability;
   remove_edge (ad_edge);
+  if (dom_info_available_p (CDI_DOMINATORS))
+   {
+ set_immediate_dominator (CDI_DOMINATORS, other_edge->src,
+  recompute_dominator (CDI_DOMINATORS,
+   other_edge->src));
+ set_immediate_dominator (CDI_DOMINATORS, other_edge->dest,
+  recompute_dominator (CDI_DOMINATORS,
+   other_edge->dest));
+   }
 }
   return other_edge;
 }
@@ -1044,6 +1055,7 @@ gsi_safe_insert_before (gimple_stmt_iterator *iter, 
gimple *g)
   if (new_bb)
e = single_succ_edge (new_bb);
   adjust_before_returns_twice_call (e, g);
+  *iter = gsi_for_stmt (stmt);
 }
   else
 gsi_insert_before (iter, g, GSI_SAME_STMT);
@@ -1074,6 +1086,7 @@ gsi_safe_insert_seq_before (gimple_stmt_iterator *iter, 
gimple_seq seq)
  if (g == l)
break;
}
+  *iter = gsi_for_stmt (stmt);
 }
   else
 gsi_insert_seq_before (iter, seq, GSI_SAME_STMT);


[gcc r13-8453] gimple-iterator, ubsan: Fix ICE during instrumentation of returns_twice calls [PR112709]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:3d231faed146352543794bf9e9afbee2e6c76889

commit r13-8453-g3d231faed146352543794bf9e9afbee2e6c76889
Author: Jakub Jelinek 
Date:   Wed Mar 13 09:16:45 2024 +0100

gimple-iterator, ubsan: Fix ICE during instrumentation of returns_twice 
calls [PR112709]

ubsan, asan (both PR112709) and _BitInt lowering (PR113466) want to
insert some instrumentation or adjustment statements before some statement.
This unfortunately creates invalid IL if inserting before a returns_twice
call, because we require that such calls are the first statement in a basic
block and that we have an edge from the .ABNORMAL_DISPATCHER block to
the block containing the returns_twice call (in addition to other edge(s)).

The following patch adds helper functions for such insertions and uses it
for now in ubsan (I'll post a follow up which uses it in asan and will
work later on the _BitInt lowering PR).

In particular, if the bb with returns_twice call at the start has just
2 edges, one EDGE_ABNORMAL from .ABNORMAL_DISPATCHER and another
(non-EDGE_ABNORMAL/EDGE_EH) from some other bb, it just inserts the
statement or sequence on that other edge.
If the bb has more predecessor edges or the one not from
.ABNORMAL_DISPATCHER is e.g. an EH edge (this latter case likely shouldn't
happen, one would need labels or something like that), the patch splits the
block with returns_twice call such that there is just one edge next to
.ABNORMAL_DISPATCHER edge and adjusts PHIs as needed to make it happen.
The functions also replace uses of PHIs from the returns_twice bb with
the corresponding PHI arguments, because otherwise it would be invalid IL.

E.g. in ubsan/pr112709-2.c (qux) we have before the ubsan pass
   :
  # .MEM_5(ab) = PHI <.MEM_4(9), .MEM_25(ab)(11)>
  # _7(ab) = PHI <_20(9), _8(ab)(11)>
  # .MEM_21(ab) = VDEF <.MEM_5(ab)>
  _22 = bar (*_7(ab));
where bar is returns_twice call and bb 11 has .ABNORMAL_DISPATCHER call,
this patch instruments it like:
   :
  # .MEM_4 = PHI <.MEM_17(ab)(4), .MEM_10(D)(5), .MEM_14(ab)(8)>
  # DEBUG BEGIN_STMT
  # VUSE <.MEM_4>
  _20 = p;
  # .MEM_27 = VDEF <.MEM_4>
  .UBSAN_NULL (_20, 0B, 0);
  # VUSE <.MEM_27>
  _2 = __builtin_dynamic_object_size (_20, 0);
  # .MEM_28 = VDEF <.MEM_27>
  .UBSAN_OBJECT_SIZE (_20, 1024, _2, 0);

   :
  # .MEM_5(ab) = PHI <.MEM_28(9), .MEM_25(ab)(11)>
  # _7(ab) = PHI <_20(9), _8(ab)(11)>
  # .MEM_21(ab) = VDEF <.MEM_5(ab)>
  _22 = bar (*_7(ab));
The edge from .ABNORMAL_DISPATCHER is there just to represent the
returning for 2nd and later times, the instrumentation can't be
done at that point as there is no code executed during that point.
The ubsan/pr112709-1.c testcase includes non-virtual PHIs to cover
the handling of those as well.

2024-03-13  Jakub Jelinek  

PR sanitizer/112709
* gimple-iterator.h (gsi_safe_insert_before,
gsi_safe_insert_seq_before): Declare.
* gimple-iterator.cc: Include gimplify.h.
(edge_before_returns_twice_call, adjust_before_returns_twice_call,
gsi_safe_insert_before, gsi_safe_insert_seq_before): New functions.
* ubsan.cc (instrument_mem_ref, instrument_pointer_overflow,
instrument_nonnull_arg, instrument_nonnull_return): Use
gsi_safe_insert_before instead of gsi_insert_before.
(maybe_instrument_pointer_overflow): Use force_gimple_operand,
gimple_seq_add_seq_without_update and gsi_safe_insert_seq_before
instead of force_gimple_operand_gsi.
(instrument_object_size): Likewise.  Use gsi_safe_insert_before
instead of gsi_insert_before.

* gcc.dg/ubsan/pr112709-1.c: New test.
* gcc.dg/ubsan/pr112709-2.c: New test.

(cherry picked from commit 364c684c474841e3c9c04e025a5c1bca49705c86)

Diff:
---
 gcc/gimple-iterator.cc  | 135 
 gcc/gimple-iterator.h   |   2 +
 gcc/testsuite/gcc.dg/ubsan/pr112709-1.c |  64 +++
 gcc/testsuite/gcc.dg/ubsan/pr112709-2.c |  62 +++
 gcc/ubsan.cc|  46 ++-
 5 files changed, 285 insertions(+), 24 deletions(-)

diff --git a/gcc/gimple-iterator.cc b/gcc/gimple-iterator.cc
index 1cc3d581b96..c18ea22c486 100644
--- a/gcc/gimple-iterator.cc
+++ b/gcc/gimple-iterator.cc
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfg.h"
 #include "tree-ssa.h"
 #include "value-prof.h"
+#include "gimplify.h"
 
 
 /* Mark the statement STMT as modified, and update it.  */
@@ -943,3 +944,137 @@ gsi_start_phis (basic_block bb)
 
   return i;
 }
+
+/* Helper function for gsi_safe_insert_before and gsi_safe_insert_seq_before.
+   Find edge to insert stateme

[gcc r13-8452] i386: Fix a pasto in ix86_expand_int_sse_cmp [PR114339]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:ec5cb2a0f2436618219ce0ada3086f6088e37332

commit r13-8452-gec5cb2a0f2436618219ce0ada3086f6088e37332
Author: Jakub Jelinek 
Date:   Fri Mar 15 10:46:47 2024 +0100

i386: Fix a pasto in ix86_expand_int_sse_cmp [PR114339]

In r13-3803-gfa271afb58 I've added an optimization for LE/LEU/GE/GEU
comparison against CONST_VECTOR.  As the comments say:
 /* x <= cst can be handled as x < cst + 1 unless there is
wrap around in cst + 1.  */
...
 /* For LE punt if some element is signed maximum.  */
...
 /* For LEU punt if some element is unsigned maximum.  */
and
 /* x >= cst can be handled as x > cst - 1 unless there is
wrap around in cst - 1.  */
...
 /* For GE punt if some element is signed minimum.  */
...
 /* For GEU punt if some element is zero.  */
Apparently I wrote the GE/GEU (second case) first and then
copied/adjusted it for LE/LEU, most of the adjustments look correct, but
I've left if (code == GE) comparison when testing if it should punt for
signed maximum.  That condition is never true, because this is in
switch (code) { ... case LE: case LEU: block and we really meant to
be what the comment says, for LE punt if some element is signed maximum,
as then cst + 1 wraps around.

The following patch fixes the pasto.

2024-03-15  Jakub Jelinek  

PR target/114339
* config/i386/i386-expand.cc (ix86_expand_int_sse_cmp) : 
Fix
a pasto, compare code against LE rather than GE.

* gcc.target/i386/pr114339.c: New test.

(cherry picked from commit ab2da8fb67b1aa0557a16b62689a888730dba610)

Diff:
---
 gcc/config/i386/i386-expand.cc   |  2 +-
 gcc/testsuite/gcc.target/i386/pr114339.c | 20 
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 0eb8cfc81e1..3112c0b78dc 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -4582,7 +4582,7 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, 
rtx cop0, rtx cop1,
  rtx elt = CONST_VECTOR_ELT (cop1, i);
  if (!CONST_INT_P (elt))
break;
- if (code == GE)
+ if (code == LE)
{
  /* For LE punt if some element is signed maximum.  */
  if ((INTVAL (elt) & (GET_MODE_MASK (eltmode) >> 1))
diff --git a/gcc/testsuite/gcc.target/i386/pr114339.c 
b/gcc/testsuite/gcc.target/i386/pr114339.c
new file mode 100644
index 000..8fba3747cf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr114339.c
@@ -0,0 +1,20 @@
+/* PR target/114339 */
+/* { dg-do run } */
+/* { dg-options "-O2 -Wno-psabi" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+typedef long long V __attribute__((vector_size (16)));
+
+__attribute__((noipa)) V
+foo (V a)
+{
+  return a <= (V) {0, __LONG_LONG_MAX__ };
+}
+
+int
+main ()
+{
+  V t = foo ((V) { 0, 0 });
+  if (t[0] != -1LL || t[1] != -1LL)
+__builtin_abort ();
+}


[gcc r13-8451] icf: Reset SSA_NAME_{PTR, RANGE}_INFO in successfully merged functions [PR113907]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:9f255e4baac68fc3568820cdca9412f67ff07940

commit r13-8451-g9f255e4baac68fc3568820cdca9412f67ff07940
Author: Jakub Jelinek 
Date:   Thu Mar 14 17:48:30 2024 +0100

icf: Reset SSA_NAME_{PTR,RANGE}_INFO in successfully merged functions 
[PR113907]

AFAIK we have no code in LTO streaming to stream out or in
SSA_NAME_{RANGE,PTR}_INFO, so LTO effectively throws it all away
and let vrp1 and alias analysis after IPA recompute that.  There is
just one spot, for IPA VRP and IPA bit CCP we save/restore ranges
and set SSA_NAME_{PTR,RANGE}_INFO e.g. on parameters depending on what
we saved and propagated, but that is after streaming in bodies for the
post IPA optimizations.

Now, without LTO SSA_NAME_{RANGE,PTR}_INFO is already computed from
earlier in many cases (er.g. evrp and early alias analysis but other spots
too), but IPA ICF is ignoring the ranges and points-to details when
comparing the bodies.  I think ignoring that is just fine, that is
effectively what we do for LTO where we throw that information away
before the analysis, and not ignoring it could lead to fewer ICF merging
possibilities.

So, the following patch instead verifies that for LTO 
SSA_NAME_{PTR,RANGE}_INFO
just isn't there on SSA_NAMEs in functions into which other functions have
been ICFed, and for non-LTO throws that information away (which matches the
LTO behavior).

Another possibility would be to remember the SSA_NAME <-> SSA_NAME mapping
vector (just one of the 2) on successful sem_function::equals on the
sem_function which is not the chosen leader (e.g. how SSA_NAMEs in the
leader map to SSA_NAMEs in the other function) and use that vector
to union the ranges in sem_function::merge.  I can implement that for
comparison, but wanted to post this first if there is an agreement on
doing that or if Honza thinks we should take SSA_NAME_{RANGE,PTR}_INFO
into account.  I think we can compare SSA_NAME_RANGE_INFO, but have
no idea how to try to compare points to info.  And I think it will result
in less effective ICF for non-LTO vs. LTO unnecessarily.

2024-03-12  Jakub Jelinek  

PR middle-end/113907
* ipa-icf.cc (sem_item_optimizer::merge_classes): Reset
SSA_NAME_RANGE_INFO and SSA_NAME_PTR_INFO on successfully ICF merged
functions.

* gcc.dg/pr113907-1.c: New test.

(cherry picked from commit 7580e39452b65ab5fb5a06f3f1ad7d59720269b5)

Diff:
---
 gcc/ipa-icf.cc| 32 -
 gcc/testsuite/gcc.dg/pr113907-1.c | 49 +++
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index cb9f768d85d..5c1a29e1402 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -3389,6 +3389,7 @@ sem_item_optimizer::merge_classes (unsigned int 
prev_class_count,
  continue;
 
sem_item *source = c->members[0];
+   bool this_merged_p = false;
 
if (DECL_NAME (source->decl)
&& MAIN_NAME_P (DECL_NAME (source->decl)))
@@ -3435,7 +3436,7 @@ sem_item_optimizer::merge_classes (unsigned int 
prev_class_count,
if (dbg_cnt (merged_ipa_icf))
  {
bool merged = source->merge (alias);
-   merged_p |= merged;
+   this_merged_p |= merged;
 
if (merged && alias->type == VAR)
  {
@@ -3444,6 +3445,35 @@ sem_item_optimizer::merge_classes (unsigned int 
prev_class_count,
  }
  }
  }
+
+   merged_p |= this_merged_p;
+   if (this_merged_p
+   && source->type == FUNC
+   && (!flag_wpa || flag_checking))
+ {
+   unsigned i;
+   tree name;
+   FOR_EACH_SSA_NAME (i, name, DECL_STRUCT_FUNCTION (source->decl))
+ {
+   /* We need to either merge or reset SSA_NAME_*_INFO.
+  For merging we don't preserve the mapping between
+  original and alias SSA_NAMEs from successful equals
+  calls.  */
+   if (POINTER_TYPE_P (TREE_TYPE (name)))
+ {
+   if (SSA_NAME_PTR_INFO (name))
+ {
+   gcc_checking_assert (!flag_wpa);
+   SSA_NAME_PTR_INFO (name) = NULL;
+ }
+ }
+   else if (SSA_NAME_RANGE_INFO (name))
+ {
+   gcc_checking_assert (!flag_wpa);
+   SSA_NAME_RANGE_INFO (name) = NULL;
+ }
+ }
+ }
   }
 
   if (!m_merged_variables.is_empty ())
diff --git a/gcc/testsuite/gcc.dg/pr113907-1.c 
b/gcc/testsuite/gcc.dg/pr113907-1.c
new file mode 100644
index 000..04c4fb8c128
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr113907-1.c
@@ -0,0 +

[gcc r13-8454] asan: Fix ICE during instrumentation of returns_twice calls [PR112709]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:847391913443069358986b398c2f86dac906d742

commit r13-8454-g847391913443069358986b398c2f86dac906d742
Author: Jakub Jelinek 
Date:   Wed Mar 13 09:19:05 2024 +0100

asan: Fix ICE during instrumentation of returns_twice calls [PR112709]

The following patch on top of the previously posted ubsan/gimple-iterator
one handles asan the same.  While the case of returning by hidden reference
is handled differently because of the first recently posted asan patch,
this deals with instrumentation of the aggregates returned in registers
case as well as instrumentation of loads from aggregate memory in the
function arguments of returns_twice calls.

2024-03-13  Jakub Jelinek  

PR sanitizer/112709
* asan.cc (maybe_create_ssa_name, maybe_cast_to_ptrmode,
build_check_stmt, maybe_instrument_call, asan_expand_mark_ifn): Use
gsi_safe_insert_before instead of gsi_insert_before.

* gcc.dg/asan/pr112709-2.c: New test.

(cherry picked from commit 6586359e8e4c611dd96129b5d4f24023949ac3fc)

Diff:
---
 gcc/asan.cc| 10 +++
 gcc/testsuite/gcc.dg/asan/pr112709-2.c | 50 ++
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/gcc/asan.cc b/gcc/asan.cc
index 8d0ffb497cc..15feecfb495 100644
--- a/gcc/asan.cc
+++ b/gcc/asan.cc
@@ -2571,7 +2571,7 @@ maybe_create_ssa_name (location_t loc, tree base, 
gimple_stmt_iterator *iter,
   gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (base)), base);
   gimple_set_location (g, loc);
   if (before_p)
-gsi_insert_before (iter, g, GSI_SAME_STMT);
+gsi_safe_insert_before (iter, g);
   else
 gsi_insert_after (iter, g, GSI_NEW_STMT);
   return gimple_assign_lhs (g);
@@ -2590,7 +2590,7 @@ maybe_cast_to_ptrmode (location_t loc, tree len, 
gimple_stmt_iterator *iter,
  NOP_EXPR, len);
   gimple_set_location (g, loc);
   if (before_p)
-gsi_insert_before (iter, g, GSI_SAME_STMT);
+gsi_safe_insert_before (iter, g);
   else
 gsi_insert_after (iter, g, GSI_NEW_STMT);
   return gimple_assign_lhs (g);
@@ -2681,7 +2681,7 @@ build_check_stmt (location_t loc, tree base, tree len,
 align / BITS_PER_UNIT));
   gimple_set_location (g, loc);
   if (before_p)
-gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+gsi_safe_insert_before (&gsi, g);
   else
 {
   gsi_insert_after (&gsi, g, GSI_NEW_STMT);
@@ -3020,7 +3020,7 @@ maybe_instrument_call (gimple_stmt_iterator *iter)
  tree decl = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN);
  gimple *g = gimple_build_call (decl, 0);
  gimple_set_location (g, gimple_location (stmt));
- gsi_insert_before (iter, g, GSI_SAME_STMT);
+ gsi_safe_insert_before (iter, g);
}
 }
 
@@ -3844,7 +3844,7 @@ asan_expand_mark_ifn (gimple_stmt_iterator *iter)
   g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
   NOP_EXPR, len);
   gimple_set_location (g, loc);
-  gsi_insert_before (iter, g, GSI_SAME_STMT);
+  gsi_safe_insert_before (iter, g);
   tree sz_arg = gimple_assign_lhs (g);
 
   tree fun
diff --git a/gcc/testsuite/gcc.dg/asan/pr112709-2.c 
b/gcc/testsuite/gcc.dg/asan/pr112709-2.c
new file mode 100644
index 000..e793f53507f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr112709-2.c
@@ -0,0 +1,50 @@
+/* PR sanitizer/112709 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=address -O2" } */
+
+struct S { char c[1024]; } *p;
+int foo (int);
+
+__attribute__((returns_twice, noipa)) int
+bar (struct S x)
+{
+  (void) x.c[0];
+  return 0;
+}
+
+void
+baz (int *y)
+{
+  foo (1);
+  *y = bar (*p);
+}
+
+void
+qux (int x, int *y)
+{
+  if (x == 25)
+x = foo (2);
+  else if (x == 42)
+x = foo (foo (3));
+  *y = bar (*p);
+}
+
+void
+corge (int x, int *y)
+{
+  void *q[] = { &&l1, &&l2, &&l3, &&l3 };
+  if (x == 25)
+{
+l1:
+  x = foo (2);
+}
+  else if (x == 42)
+{
+l2:
+  x = foo (foo (3));
+}
+l3:
+  *y = bar (*p);
+  if (x < 4)
+goto *q[x & 3];
+}


[gcc r13-8450] aarch64: Fix TImode __sync_*_compare_and_exchange expansion with LSE [PR114310]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:1c907cee6163a3ec2c0edaebeace73e2d32835ee

commit r13-8450-g1c907cee6163a3ec2c0edaebeace73e2d32835ee
Author: Jakub Jelinek 
Date:   Thu Mar 14 14:09:20 2024 +0100

aarch64: Fix TImode __sync_*_compare_and_exchange expansion with LSE 
[PR114310]

The following testcase ICEs with LSE atomics.
The problem is that the @atomic_compare_and_swap expander uses
aarch64_reg_or_zero predicate for the desired operand, which is fine,
given that for most of the modes and even for TImode in some cases
it can handle zero immediate just fine, but the TImode
@aarch64_compare_and_swap_lse just uses register_operand for
that operand instead, again intentionally so, because the casp,
caspa, caspl and caspal instructions need to use a pair of consecutive
registers for the operand and xzr is just one register and we can't
just store zero into the link register to emulate pair of zeros.

So, the following patch fixes that by forcing the newval operand into
a register for the TImode LSE case.

2024-03-14  Jakub Jelinek  

PR target/114310
* config/aarch64/aarch64.cc (aarch64_expand_compare_and_swap): For
TImode force newval into a register.

* gcc.dg/pr114310.c: New test.

(cherry picked from commit 9349aefa1df7ae36714b7b9f426ad46e314892d1)

Diff:
---
 gcc/config/aarch64/aarch64.cc   |  2 ++
 gcc/testsuite/gcc.dg/pr114310.c | 20 
 2 files changed, 22 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index f546c48ae2d..f6d14cd791a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -23081,6 +23081,8 @@ aarch64_expand_compare_and_swap (rtx operands[])
 rval = copy_to_mode_reg (r_mode, oldval);
   else
emit_move_insn (rval, gen_lowpart (r_mode, oldval));
+  if (mode == TImode)
+   newval = force_reg (mode, newval);
 
   emit_insn (gen_aarch64_compare_and_swap_lse (mode, rval, mem,
   newval, mod_s));
diff --git a/gcc/testsuite/gcc.dg/pr114310.c b/gcc/testsuite/gcc.dg/pr114310.c
new file mode 100644
index 000..55edd800e42
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114310.c
@@ -0,0 +1,20 @@
+/* PR target/114310 */
+/* { dg-do run { target int128 } } */
+
+volatile __attribute__((aligned (sizeof (__int128_t __int128_t v = 10;
+
+int
+main ()
+{
+#if __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+  if (__sync_val_compare_and_swap (&v, (__int128_t) 10, (__int128_t) 0) != 10)
+__builtin_abort ();
+  if (__sync_val_compare_and_swap (&v, (__int128_t) 10, (__int128_t) 15) != 0)
+__builtin_abort ();
+  if (__sync_val_compare_and_swap (&v, (__int128_t) 0, (__int128_t) 42) != 0)
+__builtin_abort ();
+  if (__sync_val_compare_and_swap (&v, (__int128_t) 31, (__int128_t) 35) != 42)
+__builtin_abort ();
+#endif
+  return 0;
+}


[gcc r13-8449] contrib: Improve dg-extract-results.sh's Python detection [PR109668]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:8c4785e77e8b54109fbb4f81a3b624e98184c2aa

commit r13-8449-g8c4785e77e8b54109fbb4f81a3b624e98184c2aa
Author: Sam James 
Date:   Fri Mar 8 15:24:20 2024 +0100

contrib: Improve dg-extract-results.sh's Python detection [PR109668]

'python' on some systems (e.g. SLES 15) might be Python 2. Prefer python3,
then python, then python2 (as the script still tries to work there).

PR other/109668
* dg-extract-results.sh: Check for python3 before python. Check for
python2 last.

(cherry picked from commit 64273a7e6bd8ba60058174d147521dd65d705637)

Diff:
---
 contrib/dg-extract-results.sh | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/contrib/dg-extract-results.sh b/contrib/dg-extract-results.sh
index 33968ed7b23..3c8a5ca0ecf 100755
--- a/contrib/dg-extract-results.sh
+++ b/contrib/dg-extract-results.sh
@@ -28,14 +28,17 @@
 
 PROGNAME=dg-extract-results.sh
 
-# Try to use the python version if possible, since it tends to be faster.
+# Try to use the python version if possible, since it tends to be faster and
+# produces more stable results.
 PYTHON_VER=`echo "$0" | sed 's/sh$/py/'`
-if test "$PYTHON_VER" != "$0" &&
-   test -f "$PYTHON_VER" &&
-   python -c 'import sys, getopt, re, io, datetime, operator; sys.exit (0 if 
sys.version_info >= (2, 6) else 1)' \
- > /dev/null 2> /dev/null; then
-  exec python $PYTHON_VER "$@"
-fi
+for python in python3 python python2 ; do
+  if test "$PYTHON_VER" != "$0" &&
+ test -f "$PYTHON_VER" &&
+ ${python} -c 'import sys, getopt, re, io, datetime, operator; sys.exit (0 
if sys.version_info >= (2, 6) else 1)' \
+   > /dev/null 2> /dev/null; then
+exec ${python} $PYTHON_VER "$@"
+  fi
+done
 
 usage() {
   cat <&2


[gcc r13-8448] bb-reorder: Fix -freorder-blocks-and-partition ICEs on aarch64 with asm goto [PR110079]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:6b69cbe2c85f0b8f4a5a6b23e257d69275bea182

commit r13-8448-g6b69cbe2c85f0b8f4a5a6b23e257d69275bea182
Author: Jakub Jelinek 
Date:   Thu Mar 7 10:02:49 2024 +0100

bb-reorder: Fix -freorder-blocks-and-partition ICEs on aarch64 with asm 
goto [PR110079]

The following testcase ICEs, because fix_crossing_unconditional_branches
thinks that asm goto is an unconditional jump and removes it, replacing it
with unconditional jump to one of the labels.
This doesn't happen on x86 because the function in question isn't invoked
there at all:
  /* If the architecture does not have unconditional branches that
 can span all of memory, convert crossing unconditional branches
 into indirect jumps.  Since adding an indirect jump also adds
 a new register usage, update the register usage information as
 well.  */
  if (!HAS_LONG_UNCOND_BRANCH)
fix_crossing_unconditional_branches ();
I think for the asm goto case, for the non-fallthru edge if any we should
handle it like any other fallthru (and fix_crossing_unconditional_branches
doesn't really deal with those, it only looks at explicit branches at the
end of bbs and we are in cfglayout mode at that point) and for the labels
we just pass the labels as immediates to the assembly and it is up to the
user to figure out how to store them/branch to them or whatever they want to
do.
So, the following patch fixes this by not treating asm goto as a simple
unconditional jump.

I really think that on the !HAS_LONG_UNCOND_BRANCH targets we have a bug
somewhere else, where outofcfglayout or whatever should actually create
those indirect jumps on the crossing edges instead of adding normal
unconditional jumps, I see e.g. in
__attribute__((cold)) int bar (char *);
__attribute__((hot)) int baz (char *);
void qux (int x) { if (__builtin_expect (!x, 1)) goto l1; bar (""); goto 
l1; l1: baz (""); }
void corge (int x) { if (__builtin_expect (!x, 0)) goto l1; baz (""); l2: 
return; l1: bar (""); goto l2; }
with -O2 -freorder-blocks-and-partition on aarch64 before/after this patch
just b .L? jumps which I believe are +-32MB, so if .text is larger than
32MB, it could fail to link, but this patch doesn't address that.

2024-03-07  Jakub Jelinek  

PR rtl-optimization/110079
* bb-reorder.cc (fix_crossing_unconditional_branches): Don't adjust
asm goto.

* gcc.dg/pr110079.c: New test.

(cherry picked from commit b209d905f5ce1fa9d76ce634fd54245ff340960b)

Diff:
---
 gcc/bb-reorder.cc   |  3 ++-
 gcc/testsuite/gcc.dg/pr110079.c | 43 +
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/gcc/bb-reorder.cc b/gcc/bb-reorder.cc
index 615d5426a34..95d21a473c8 100644
--- a/gcc/bb-reorder.cc
+++ b/gcc/bb-reorder.cc
@@ -2266,7 +2266,8 @@ fix_crossing_unconditional_branches (void)
  /* Make sure the jump is not already an indirect or table jump.  */
 
  if (!computed_jump_p (last_insn)
- && !tablejump_p (last_insn, NULL, NULL))
+ && !tablejump_p (last_insn, NULL, NULL)
+ && asm_noperands (PATTERN (last_insn)) < 0)
{
  /* We have found a "crossing" unconditional branch.  Now
 we must convert it to an indirect jump.  First create
diff --git a/gcc/testsuite/gcc.dg/pr110079.c b/gcc/testsuite/gcc.dg/pr110079.c
new file mode 100644
index 000..1682f9c2344
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110079.c
@@ -0,0 +1,43 @@
+/* PR rtl-optimization/110079 */
+/* { dg-do compile { target lra } } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-freorder-blocks-and-partition" { target freorder 
} } */
+
+int a;
+__attribute__((cold)) int bar (char *);
+__attribute__((hot)) int baz (char *);
+
+void
+foo (void)
+{
+l1:
+  while (a)
+;
+  bar ("");
+  asm goto ("" : : : : l2);
+  asm ("");
+l2:
+  goto l1;
+}
+
+void
+qux (void)
+{
+  asm goto ("" : : : : l1);
+  bar ("");
+  goto l1;
+l1:
+  baz ("");
+}
+
+void
+corge (void)
+{
+  asm goto ("" : : : : l1);
+  baz ("");
+l2:
+  return;
+l1:
+  bar ("");
+  goto l2;
+}


[gcc r13-8447] lower-subreg: Fix ROTATE handling [PR114211]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:df3994a1be3565ad450d552dc94b696748a7807a

commit r13-8447-gdf3994a1be3565ad450d552dc94b696748a7807a
Author: Jakub Jelinek 
Date:   Tue Mar 5 10:32:38 2024 +0100

lower-subreg: Fix ROTATE handling [PR114211]

On the following testcase, we have
(insn 10 7 11 2 (set (reg/v:TI 106 [ h ])
(rotate:TI (reg/v:TI 106 [ h ])
(const_int 64 [0x40]))) "pr114211.c":8:5 1042 
{rotl64ti2_doubleword}
 (nil))
before subreg1 and the pass decides to use
(reg:DI 127 [ h ]) / (reg:DI 128 [ h+8 ])
register pair instead of (reg/v:TI 106 [ h ]).
resolve_operand_for_swap_move_operator implements it by pretending it is
an assignment from
(concatn (reg:DI 127 [ h ]) (reg:DI 128 [ h+8 ]))
to
(concatn (reg:DI 128 [ h+8 ]) (reg:DI 127 [ h ]))
The problem is that if the rotate argument is the same as destination or
if there is even an overlap between the first half of the destination with
second half of the source we emit incorrect code, because the store to
(reg:DI 128 [ h+8 ]) overwrites what we need for source of the second
move.  The following patch detects that case and uses a temporary pseudo
to hold the original (reg:DI 128 [ h+8 ]) value across the first store.

2024-03-05  Jakub Jelinek  

PR rtl-optimization/114211
* lower-subreg.cc (resolve_simple_move): For double-word
rotates by BITS_PER_WORD if there is overlap between source
and destination use a temporary.

* gcc.dg/pr114211.c: New test.

(cherry picked from commit aed445b0fd0c7ed16124c61e7eb732992426f103)

Diff:
---
 gcc/lower-subreg.cc | 15 +++
 gcc/testsuite/gcc.dg/pr114211.c | 23 +++
 2 files changed, 38 insertions(+)

diff --git a/gcc/lower-subreg.cc b/gcc/lower-subreg.cc
index 481e1e85a26..98b18e27029 100644
--- a/gcc/lower-subreg.cc
+++ b/gcc/lower-subreg.cc
@@ -926,6 +926,21 @@ resolve_simple_move (rtx set, rtx_insn *insn)
 SRC's operator.  */
  dest = resolve_operand_for_swap_move_operator (dest);
  src = src_op;
+ if (resolve_reg_p (src))
+   {
+ gcc_assert (GET_CODE (src) == CONCATN);
+ if (reg_overlap_mentioned_p (XVECEXP (dest, 0, 0),
+  XVECEXP (src, 0, 1)))
+   {
+ /* If there is overlap between the first half of the
+destination and what will be stored to the second one,
+use a temporary pseudo.  See PR114211.  */
+ rtx tem = gen_reg_rtx (GET_MODE (XVECEXP (src, 0, 1)));
+ emit_move_insn (tem, XVECEXP (src, 0, 1));
+ src = copy_rtx (src);
+ XVECEXP (src, 0, 1) = tem;
+   }
+   }
}
   else if (resolve_reg_p (src_op))
{
diff --git a/gcc/testsuite/gcc.dg/pr114211.c b/gcc/testsuite/gcc.dg/pr114211.c
new file mode 100644
index 000..691dae5dbe8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114211.c
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/114211 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O -fno-tree-coalesce-vars -Wno-psabi" } */
+
+typedef unsigned __int128 V __attribute__((__vector_size__ (16)));
+unsigned int u;
+V v;
+
+V
+foo (unsigned __int128 h)
+{
+  h = h << 64 | h >> 64;
+  h *= ~u;
+  return h + v;
+}
+
+int
+main ()
+{
+  V x = foo (1);
+  if (x[0] != (unsigned __int128) 0x << 64)
+__builtin_abort ();
+}


[gcc r13-8446] i386: Fix ICEs with SUBREGs from vector etc. constants to XFmode [PR114184]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:128860abd58605d616c184a9a68886a25862b2dd

commit r13-8446-g128860abd58605d616c184a9a68886a25862b2dd
Author: Jakub Jelinek 
Date:   Mon Mar 4 10:04:19 2024 +0100

i386: Fix ICEs with SUBREGs from vector etc. constants to XFmode [PR114184]

The Intel extended format has the various weird number categories,
pseudo denormals, pseudo infinities, pseudo NaNs and unnormals.
Those are not representable in the GCC real_value and so neither
GIMPLE nor RTX VIEW_CONVERT_EXPR/SUBREG folding folds those into
constants.

As can be seen on the following testcase, because it isn't folded
(since GCC 12, before that we were folding it) we can end up with
a SUBREG of a CONST_VECTOR or similar constant, which isn't valid
general_operand, so we ICE during vregs pass trying to recognize
the move instruction.
Initially I thought it is a middle-end bug, the movxf instruction
has general_operand predicate, but the middle-end certainly never
tests that predicate, seems moves are special optabs.
And looking at other mov optabs, e.g. for vector modes the i386
patterns use nonimmediate_operand predicate on the input, yet
ix86_expand_vector_move deals with CONSTANT_P and SUBREG of CONSTANT_P
arguments which if the predicate was checked couldn't ever make it through.

The following patch handles this case similarly to the
ix86_expand_vector_move's SUBREG of CONSTANT_P case, does it just for XFmode
because I believe that is the only mode that needs it from the scalar ones,
others should just be folded.

2024-03-04  Jakub Jelinek  

PR target/114184
* config/i386/i386-expand.cc (ix86_expand_move): If XFmode op1
is SUBREG of CONSTANT_P, force the SUBREG_REG into memory or
register.

* gcc.target/i386/pr114184.c: New test.

(cherry picked from commit ea1c16f95b8fbaba4a7f3663ff9933ebedfb92a5)

Diff:
---
 gcc/config/i386/i386-expand.cc   | 17 +
 gcc/testsuite/gcc.target/i386/pr114184.c | 22 ++
 2 files changed, 39 insertions(+)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 61a9e9379a0..0eb8cfc81e1 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -429,6 +429,23 @@ ix86_expand_move (machine_mode mode, rtx operands[])
 
 default:
   break;
+
+case SUBREG:
+  /* As not all values in XFmode are representable in real_value,
+we might be called with unfoldable SUBREGs of constants.  */
+  if (mode == XFmode
+ && CONSTANT_P (SUBREG_REG (op1))
+ && can_create_pseudo_p ())
+   {
+ machine_mode imode = GET_MODE (SUBREG_REG (op1));
+ rtx r = force_const_mem (imode, SUBREG_REG (op1));
+ if (r)
+   r = validize_mem (r);
+ else
+   r = force_reg (imode, SUBREG_REG (op1));
+ op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
+   }
+  break;
 }
 
   if ((flag_pic || MACHOPIC_INDIRECT)
diff --git a/gcc/testsuite/gcc.target/i386/pr114184.c 
b/gcc/testsuite/gcc.target/i386/pr114184.c
new file mode 100644
index 000..360b3b95026
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr114184.c
@@ -0,0 +1,22 @@
+/* PR target/114184 */
+/* { dg-do compile } */
+/* { dg-options "-Og -mavx2" } */
+
+typedef unsigned char V __attribute__((vector_size (32)));
+typedef unsigned char W __attribute__((vector_size (16)));
+
+_Complex long double
+foo (void)
+{
+  _Complex long double d;
+  *(V *)&d = (V) { 149, 136, 89, 42, 38, 240, 196, 194 };
+  return d;
+}
+
+long double
+bar (void)
+{
+  long double d;
+  *(W *)&d = (W) { 149, 136, 89, 42, 38, 240, 196, 194 };
+  return d;
+}


[gcc r13-8443] Fortran: improve checks of NULL without MOLD as actual argument [PR104819]

2024-03-15 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:90442fb421823153c4f762a2d26a0d700af2e6c3

commit r13-8443-g90442fb421823153c4f762a2d26a0d700af2e6c3
Author: Harald Anlauf 
Date:   Fri Mar 1 19:21:27 2024 +0100

Fortran: improve checks of NULL without MOLD as actual argument [PR104819]

gcc/fortran/ChangeLog:

PR fortran/104819
* check.cc (gfc_check_null): Handle nested NULL()s.
(is_c_interoperable): Check for MOLD argument of NULL() as part of
the interoperability check.
* interface.cc (gfc_compare_actual_formal): Extend checks for NULL()
actual arguments for presence of MOLD argument when required by
Interp J3/22-146.

gcc/testsuite/ChangeLog:

PR fortran/104819
* gfortran.dg/assumed_rank_9.f90: Adjust testcase use of NULL().
* gfortran.dg/pr101329.f90: Adjust testcase to conform to interp.
* gfortran.dg/null_actual_4.f90: New test.

(cherry picked from commit db0b6746be075e43c8142585968483e125bb52d0)

Diff:
---
 gcc/fortran/check.cc |  5 +++-
 gcc/fortran/interface.cc | 30 
 gcc/testsuite/gfortran.dg/assumed_rank_9.f90 | 13 +++
 gcc/testsuite/gfortran.dg/null_actual_4.f90  | 35 
 gcc/testsuite/gfortran.dg/pr101329.f90   |  4 ++--
 5 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 8c1ae8c2f00..f39a7610073 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -4357,6 +4357,9 @@ gfc_check_null (gfc_expr *mold)
   if (mold == NULL)
 return true;
 
+  if (mold->expr_type == EXPR_NULL)
+return true;
+
   if (!variable_check (mold, 0, true))
 return false;
 
@@ -5187,7 +5190,7 @@ is_c_interoperable (gfc_expr *expr, const char **msg, 
bool c_loc, bool c_f_ptr)
 {
   *msg = NULL;
 
-  if (expr->expr_type == EXPR_NULL)
+  if (expr->expr_type == EXPR_NULL && expr->ts.type == BT_UNKNOWN)
 {
   *msg = "NULL() is not interoperable";
   return false;
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index e9843e9549c..5cda94753d8 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -3259,6 +3259,36 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, 
gfc_formal_arglist *formal,
  && a->expr->ts.type != BT_ASSUMED)
gfc_find_vtab (&a->expr->ts);
 
+  /* Interp J3/22-146:
+"If the context of the reference to NULL is an 
+corresponding to an  dummy argument, MOLD shall be
+present."  */
+  if (a->expr->expr_type == EXPR_NULL
+ && a->expr->ts.type == BT_UNKNOWN
+ && f->sym->as
+ && f->sym->as->type == AS_ASSUMED_RANK)
+   {
+ gfc_error ("Intrinsic % without % argument at %L "
+"passed to assumed-rank dummy %qs",
+&a->expr->where, f->sym->name);
+ ok = false;
+ goto match;
+   }
+
+  if (a->expr->expr_type == EXPR_NULL
+ && a->expr->ts.type == BT_UNKNOWN
+ && f->sym->ts.type == BT_CHARACTER
+ && !f->sym->ts.deferred
+ && f->sym->ts.u.cl
+ && f->sym->ts.u.cl->length == NULL)
+   {
+ gfc_error ("Intrinsic % without % argument at %L "
+"passed to assumed-length dummy %qs",
+&a->expr->where, f->sym->name);
+ ok = false;
+ goto match;
+   }
+
   if (a->expr->expr_type == EXPR_NULL
  && ((f->sym->ts.type != BT_CLASS && !f->sym->attr.pointer
   && (f->sym->attr.allocatable || !f->sym->attr.optional
diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_9.f90 
b/gcc/testsuite/gfortran.dg/assumed_rank_9.f90
index 1296d068959..5e59ec136c9 100644
--- a/gcc/testsuite/gfortran.dg/assumed_rank_9.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_9.f90
@@ -26,19 +26,20 @@ program main
 
   type(t), target :: y
   class(t), allocatable, target :: yac
-  
+  type(t),  pointer :: ypt
+
   y%i = 489
   allocate (yac)
   yac%i = 489
   j = 0
   call fc()
-  call fc(null())
+  call fc(null(yac))
   call fc(y)
   call fc(yac)
   if (j /= 2) STOP 1
 
   j = 0
-  call gc(null())
+! call gc(null(yac)) ! ICE
   call gc(y)
   call gc(yac)
   deallocate (yac)
@@ -54,13 +55,14 @@ program main
 
   j = 0
   call ft()
-  call ft(null())
+  call ft(null(yac))
   call ft(y)
   call ft(yac)
   if (j /= 2) STOP 4
 
   j = 0
-  call gt(null())
+  call gt(null(ypt))
+! call gt(null(yac)) ! ICE
   call gt(y)
   call gt(yac)
   deallocate (yac)
@@ -73,6 +75,7 @@ program main
   yac%i = 489
   call ht(yac)
   if (j /= 1) STOP 6
+  deallocate (yac)
 
 contains
 
diff --git a/gcc/testsuite/gfortran.dg/null_actual_4.f90 
b/gcc/testsuite/gfortran.dg/null_actual_4.f90
new file mode 100644
index 000..e03d5c8f7de
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/null_actual_4.f90
@@ -0,0 +1,35 @@
+! { dg-

[gcc r13-8445] Fortran: handle procedure pointer component in DT array [PR110826]

2024-03-15 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:4e9f475cdc8617f94c903656faaf28910c21c29b

commit r13-8445-g4e9f475cdc8617f94c903656faaf28910c21c29b
Author: Harald Anlauf 
Date:   Mon Mar 11 22:05:51 2024 +0100

Fortran: handle procedure pointer component in DT array [PR110826]

gcc/fortran/ChangeLog:

PR fortran/110826
* array.cc (gfc_array_dimen_size): When walking the ref chain of an
array and the ultimate component is a procedure pointer, do not try
to figure out its dimension even if it is a array-valued function.

gcc/testsuite/ChangeLog:

PR fortran/110826
* gfortran.dg/proc_ptr_comp_53.f90: New test.

(cherry picked from commit 81ee1298b47d3f3b3712ef3f3b2929ca26c4bcd2)

Diff:
---
 gcc/fortran/array.cc   |  7 +
 gcc/testsuite/gfortran.dg/proc_ptr_comp_53.f90 | 43 ++
 2 files changed, 50 insertions(+)

diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index be5eb8b6a0f..936f774353e 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -2600,6 +2600,13 @@ gfc_array_dimen_size (gfc_expr *array, int dimen, mpz_t 
*result)
 case EXPR_FUNCTION:
   for (ref = array->ref; ref; ref = ref->next)
{
+ /* Ultimate component is a procedure pointer.  */
+ if (ref->type == REF_COMPONENT
+ && !ref->next
+ && ref->u.c.component->attr.function
+ && IS_PROC_POINTER (ref->u.c.component))
+   return false;
+
  if (ref->type != REF_ARRAY)
continue;
 
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_53.f90 
b/gcc/testsuite/gfortran.dg/proc_ptr_comp_53.f90
new file mode 100644
index 000..affb5922235
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_53.f90
@@ -0,0 +1,43 @@
+! { dg-do compile }
+! PR fortran/110826 - procedure pointer component in DT array
+
+module m
+  implicit none
+
+  type pp
+procedure(func_template), pointer, nopass :: f =>null()
+  end type pp
+
+  abstract interface
+ function func_template(state) result(dstate)
+   implicit none
+   real, dimension(:,:), intent(in)  :: state
+   real, dimension(size(state,1), size(state,2)) :: dstate
+ end function
+  end interface
+
+contains
+
+  function zero_state(state) result(dstate)
+real, dimension(:,:), intent(in)  :: state
+real, dimension(size(state,1), size(state,2)) :: dstate
+dstate = 0.
+  end function zero_state
+
+end module m
+
+program test_func_array
+  use m
+  implicit none
+
+  real, dimension(4,6) :: state
+  type(pp) :: func_scalar
+  type(pp) :: func_array(4)
+
+  func_scalar  %f => zero_state
+  func_array(1)%f => zero_state
+  print *, func_scalar  %f(state)
+  print *, func_array(1)%f(state)
+  if (.not. all (shape (func_scalar  %f(state)) == shape (state))) stop 1
+  if (.not. all (shape (func_array(1)%f(state)) == shape (state))) stop 2
+end program test_func_array


[gcc r13-8444] Fortran: allow RESTRICT qualifier also for optional arguments [PR100988]

2024-03-15 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:337dc58139595bd9ab4101b988078c5d54d8506a

commit r13-8444-g337dc58139595bd9ab4101b988078c5d54d8506a
Author: Harald Anlauf 
Date:   Mon Dec 4 22:44:53 2023 +0100

Fortran: allow RESTRICT qualifier also for optional arguments [PR100988]

gcc/fortran/ChangeLog:

PR fortran/100988
* gfortran.h (IS_PROC_POINTER): New macro.
* trans-types.cc (gfc_sym_type): Use macro in determination if the
restrict qualifier can be used for a dummy variable.  Fix logic to
allow the restrict qualifier also for optional arguments, and to
not apply it to pointer or proc_pointer arguments.

gcc/testsuite/ChangeLog:

PR fortran/100988
* gfortran.dg/coarray_poly_6.f90: Adjust pattern.
* gfortran.dg/coarray_poly_7.f90: Likewise.
* gfortran.dg/coarray_poly_8.f90: Likewise.
* gfortran.dg/missing_optional_dummy_6a.f90: Likewise.
* gfortran.dg/pr100988.f90: New test.

Co-authored-by: Tobias Burnus  
(cherry picked from commit 9c3a880feecf81c310b4ade210fbd7004c9aece7)

Diff:
---
 gcc/fortran/gfortran.h |  3 ++
 gcc/fortran/trans-types.cc | 13 +++--
 gcc/testsuite/gfortran.dg/coarray_poly_6.f90   |  2 +-
 gcc/testsuite/gfortran.dg/coarray_poly_7.f90   |  2 +-
 gcc/testsuite/gfortran.dg/coarray_poly_8.f90   |  2 +-
 .../gfortran.dg/missing_optional_dummy_6a.f90  |  2 +-
 gcc/testsuite/gfortran.dg/pr100988.f90 | 61 ++
 7 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index aba16cf998b..e6939056a7c 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3951,6 +3951,9 @@ bool gfc_may_be_finalized (gfc_typespec);
 #define IS_POINTER(sym) \
(sym->ts.type == BT_CLASS && sym->attr.class_ok && CLASS_DATA (sym) \
 ? CLASS_DATA (sym)->attr.class_pointer : sym->attr.pointer)
+#define IS_PROC_POINTER(sym) \
+   (sym->ts.type == BT_CLASS && sym->attr.class_ok && CLASS_DATA (sym) \
+? CLASS_DATA (sym)->attr.proc_pointer : sym->attr.proc_pointer)
 
 /* frontend-passes.cc */
 
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index fc5c221a301..b514d8e5a57 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2324,8 +2324,8 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c)
   else
 byref = 0;
 
-  restricted = !sym->attr.target && !sym->attr.pointer
-   && !sym->attr.proc_pointer && !sym->attr.cray_pointee;
+  restricted = (!sym->attr.target && !IS_POINTER (sym)
+   && !IS_PROC_POINTER (sym) && !sym->attr.cray_pointee);
   if (!restricted)
 type = gfc_nonrestricted_type (type);
 
@@ -2381,11 +2381,10 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c)
  || (sym->ns->proc_name && sym->ns->proc_name->attr.entry_master))
type = build_pointer_type (type);
   else
-   {
- type = build_reference_type (type);
- if (restricted)
-   type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
-   }
+   type = build_reference_type (type);
+
+  if (restricted)
+   type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
 }
 
   return (type);
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_6.f90 
b/gcc/testsuite/gfortran.dg/coarray_poly_6.f90
index 53b80e442d3..344e12b4eff 100644
--- a/gcc/testsuite/gfortran.dg/coarray_poly_6.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_6.f90
@@ -16,6 +16,6 @@ contains
   end subroutine foo
 end
 ! { dg-final { scan-tree-dump-times "foo \\(struct __class_MAIN___T_0_1t & 
restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) 
caf_offset..\\)" 1 "original" } }
-! { dg-final { scan-tree-dump-times "bar \\(struct __class_MAIN___T_0_1t \\* 
x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "bar \\(struct __class_MAIN___T_0_1t \\* 
restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) 
caf_offset..\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "bar \\(0B, 0B, 0\\);" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "foo \\(&class.., y._data.token, 
\\(integer\\(kind=\[48\]\\)\\) class..._data.data - 
\\(integer\\(kind=\[48\]\\)\\) y._data.data\\);" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_7.f90 
b/gcc/testsuite/gfortran.dg/coarray_poly_7.f90
index 44f98e16e09..d8d83aea39b 100644
--- a/gcc/testsuite/gfortran.dg/coarray_poly_7.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_7.f90
@@ -16,6 +16,6 @@ contains
   end subroutine foo
 end
 ! { dg-final { scan-tree-dump-times "foo \\(struct __class_MAIN___T_1_1t & 
restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) 
caf_offset..\\)" 1 "original" } }
-! { dg-final { scan-tree-dump-times 

[gcc r13-8442] testsuite: fortran: fix invalid testcases (missing MOLD argument to NULL)

2024-03-15 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:ba4b4b3864d426835ea10e900a4e1dd466d06e51

commit r13-8442-gba4b4b3864d426835ea10e900a4e1dd466d06e51
Author: Harald Anlauf 
Date:   Wed Nov 22 21:45:46 2023 +0100

testsuite: fortran: fix invalid testcases (missing MOLD argument to NULL)

The Fortran standard requires that NULL() passed to an assumed-rank
dummy argument has a MOLD argument.

gcc/testsuite/ChangeLog:

PR fortran/104819
* gfortran.dg/assumed_rank_10.f90: Add MOLD argument to NULL().
* gfortran.dg/assumed_rank_8.f90: Likewise.

(cherry picked from commit 7646b5d88056cf269ff555afe95bc361dcf5e5c0)

Diff:
---
 gcc/testsuite/gfortran.dg/assumed_rank_10.f90 | 6 +++---
 gcc/testsuite/gfortran.dg/assumed_rank_8.f90  | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_10.f90 
b/gcc/testsuite/gfortran.dg/assumed_rank_10.f90
index 6a3cc94483e..f22d43ab955 100644
--- a/gcc/testsuite/gfortran.dg/assumed_rank_10.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_10.f90
@@ -50,9 +50,9 @@ program test
 
  is_present = .false.
 
- call fpa(null(), null()) ! No copy back
- call fpi(null(), null()) ! No copy back
- call fno(null(), null()) ! No copy back
+ call fpa(null(iip), null(jjp)) ! No copy back
+ call fpi(null(iip), null(jjp)) ! No copy back
+ call fno(null(iip), null(jjp)) ! No copy back
 
  call fno() ! No copy back
 
diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_8.f90 
b/gcc/testsuite/gfortran.dg/assumed_rank_8.f90
index 5873296a7a5..34ff42c0be2 100644
--- a/gcc/testsuite/gfortran.dg/assumed_rank_8.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_8.f90
@@ -22,13 +22,13 @@ program main
   call f (ii)
   call f (489)
   call f ()
-  call f (null())
+  call f (null(kk))
   call f (kk)
   if (j /= 2) STOP 1
 
   j = 0
   nullify (ll)
-  call g (null())
+  call g (null(ll))
   call g (ll)
   call g (ii)
   if (j /= 1) STOP 2


[gcc r14-9498] libgcc: Fix quotient and/or remainder negation in __divmodbitint4 [PR114327]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:a6dab195f7041671166b9aa6a37e0db4236c829d

commit r14-9498-ga6dab195f7041671166b9aa6a37e0db4236c829d
Author: Jakub Jelinek 
Date:   Fri Mar 15 19:04:33 2024 +0100

libgcc: Fix quotient and/or remainder negation in __divmodbitint4 [PR114327]

While for __mulbitint3 we actually don't negate anything and perform the
multiplication in unsigned style always, for __divmodbitint4 if the operands
aren't unsigned and are negative, we negate them first and then try to
negate them as needed at the end.
quotient is negated if just one of the operands was negated and the other
wasn't or vice versa, and remainder is negated if the first operand was
negated.
The case which doesn't work correctly is if due to limited range of the
operands we perform the division/modulo in some smaller number of limbs
and then extend it to the desired precision of the quotient and/or
remainder results.  If they aren't negated, the extension is done with
memset to 0, if they are negated, the extension was done with memset
to -1.  The problem is that if the quotient or remainder is zero,
then bitint_negate negates it again to zero (that is ok), but we should
then extend with memset to 0, not memset to -1.

The following patch achieves that by letting bitint_negate also check if
the negated operand is zero and changes the memset argument based on that.

2024-03-15  Jakub Jelinek  

PR libgcc/114327
* libgcc2.c (bitint_negate): Return UWtype bitwise or of all the 
limbs
before negation rather than void.
(__divmodbitint4): Determine whether to fill in the upper limbs 
after
negation based on whether bitint_negate returned 0 or non-zero, 
rather
then always filling with -1.

* gcc.dg/torture/bitint-63.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/torture/bitint-63.c | 30 ++
 libgcc/libgcc2.c | 19 +++
 2 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/bitint-63.c 
b/gcc/testsuite/gcc.dg/torture/bitint-63.c
new file mode 100644
index 000..97acba0fa1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/bitint-63.c
@@ -0,0 +1,30 @@
+/* PR libgcc/114327 */
+/* { 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__ >= 256
+_BitInt(256)
+foo (_BitInt(256) b, _BitInt(256) c)
+{
+  return b % c;
+}
+
+_BitInt(256)
+bar (_BitInt(256) b, _BitInt(256) c)
+{
+  return b / c;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 256
+  if (foo (-0x9e9b9fe60wb, 1wb))
+__builtin_abort ();
+  if (bar (1wb, -0x9e9b9fe60wb))
+__builtin_abort ();
+#endif
+}
diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c
index ef46153731f..dc856740a69 100644
--- a/libgcc/libgcc2.c
+++ b/libgcc/libgcc2.c
@@ -1642,19 +1642,22 @@ __mulbitint3 (UBILtype *ret, SItype retprec,
 #ifdef L_divmodbitint4
 /* D = -S.  */
 
-static void
+static UWtype
 bitint_negate (UBILtype *d, const UBILtype *s, SItype n)
 {
   UWtype c = 1;
+  UWtype r = 0;
   do
 {
   UWtype sv = *s, lo;
+  r |= sv;
   s += BITINT_INC;
   c = __builtin_add_overflow (~sv, c, &lo);
   *d = lo;
   d += BITINT_INC;
 }
   while (--n);
+  return r;
 }
 
 /* D -= S * L.  */
@@ -1977,10 +1980,10 @@ __divmodbitint4 (UBILtype *q, SItype qprec,
n = qn;
  else
n = un - vn + 1;
- bitint_negate (q + BITINT_END (qn - 1, 0),
-q2 + BITINT_END (un - vn, 0), n);
+ SItype c = bitint_negate (q + BITINT_END (qn - 1, 0),
+   q2 + BITINT_END (un - vn, 0), n) ? -1 : 0;
  if (qn > n)
-   __builtin_memset (q + BITINT_END (0, n), -1,
+   __builtin_memset (q + BITINT_END (0, n), c,
  (qn - n) * sizeof (UWtype));
}
   else
@@ -1999,11 +2002,11 @@ __divmodbitint4 (UBILtype *q, SItype qprec,
   if (uprec < 0)
{
  /* Negative remainder.  */
- bitint_negate (r + BITINT_END (rn - 1, 0),
-r + BITINT_END (rn - 1, 0),
-rn > vn ? vn : rn);
+ SItype c = bitint_negate (r + BITINT_END (rn - 1, 0),
+   r + BITINT_END (rn - 1, 0),
+   rn > vn ? vn : rn) ? -1 : 0;
  if (rn > vn)
-   __builtin_memset (r + BITINT_END (0, vn), -1,
+   __builtin_memset (r + BITINT_END (0, vn), c,
  (rn - vn) * sizeof (UWtype));
}
   else


[gcc r13-8441] libstdc++: Fix typo in C++20 status table

2024-03-15 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:d92942efb33c84275521186d351bee854f39c4f2

commit r13-8441-gd92942efb33c84275521186d351bee854f39c4f2
Author: Jonathan Wakely 
Date:   Fri Mar 15 17:04:22 2024 +

libstdc++: Fix typo in C++20 status table

libstdc++-v3/ChangeLog:

* doc/xml/manual/status_cxx2023.xml: Close parenthesis.
* doc/html/manual/status.html: Regenerate.

Diff:
---
 libstdc++-v3/doc/html/manual/status.html   | 2 +-
 libstdc++-v3/doc/xml/manual/status_cxx2023.xml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/status.html 
b/libstdc++-v3/doc/html/manual/status.html
index c732f35da0c..6f5c0238d8e 100644
--- a/libstdc++-v3/doc/html/manual/status.html
+++ b/libstdc++-v3/doc/html/manual/status.html
@@ -1903,7 +1903,7 @@ or any notes about the implementation.
 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2255r2.html"; 
target="_top">
 P2255R2
 
-   13.1 (missing changes to std::tuple  __cpp_lib_reference_from_temporary >= 202202L 

+   13.1 (missing changes to std::tuple)  __cpp_lib_reference_from_temporary >= 202202L 

 Strings and text
string contains function 
 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1679r3.html"; 
target="_top">
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2023.xml 
b/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
index d1eacbfb0d6..a3105bcde19 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
@@ -491,7 +491,7 @@ or any notes about the implementation.
 P2255R2
 
   
-   13.1 (missing changes to std::tuple 

+   13.1 (missing changes to std::tuple) 

__cpp_lib_reference_from_temporary >= 202202L 

 


[gcc r14-9497] testsuite: Fix pr113431.c FAIL on sparc* [PR113431]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:ffd47fb63ddc024db847daa07f8ae27fffdfcb28

commit r14-9497-gffd47fb63ddc024db847daa07f8ae27fffdfcb28
Author: Jakub Jelinek 
Date:   Fri Mar 15 16:50:25 2024 +0100

testsuite: Fix pr113431.c FAIL on sparc* [PR113431]

As mentioned in the PR, the new testcase FAILs on sparc*-* due to
lack of support of misaligned store.

This patch restricts that to vect_hw_misalign targets.

2024-03-15  Jakub Jelinek  

PR tree-optimization/113431
* gcc.dg/vect/pr113431.c: Restrict scan-tree-dump-times to
vect_hw_misalign targets.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr113431.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr113431.c 
b/gcc/testsuite/gcc.dg/vect/pr113431.c
index 04448d9dd81..2858a769d73 100644
--- a/gcc/testsuite/gcc.dg/vect/pr113431.c
+++ b/gcc/testsuite/gcc.dg/vect/pr113431.c
@@ -15,4 +15,4 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "optimized: basic block part vectorized" 
2 "slp1" { target vect_int } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block part vectorized" 
2 "slp1" { target { vect_int && vect_hw_misalign } } } } */


[gcc r14-9496] Regenerate opt.urls

2024-03-15 Thread YunQiang Su via Gcc-cvs
https://gcc.gnu.org/g:b5e1f0696110fbf5c73426ede70562edc6f54481

commit r14-9496-gb5e1f0696110fbf5c73426ede70562edc6f54481
Author: YunQiang Su 
Date:   Fri Mar 15 21:22:40 2024 +0800

Regenerate opt.urls

Fixes: acc38ff59976 ("MIPS: Add -m(no-)strict-align option")

gcc/ChangeLog:

* config/riscv/riscv.opt.urls: Regenerated.
* config/rs6000/sysv4.opt.urls: Likewise.
* config/xtensa/xtensa.opt.urls: Likewise.

Diff:
---
 gcc/config/riscv/riscv.opt.urls   | 2 +-
 gcc/config/rs6000/sysv4.opt.urls  | 2 +-
 gcc/config/xtensa/xtensa.opt.urls | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/config/riscv/riscv.opt.urls b/gcc/config/riscv/riscv.opt.urls
index f40795866cf..da31820e234 100644
--- a/gcc/config/riscv/riscv.opt.urls
+++ b/gcc/config/riscv/riscv.opt.urls
@@ -44,7 +44,7 @@ UrlSuffix(gcc/RISC-V-Options.html#index-mshorten-memrefs)
 ; skipping UrlSuffix for 'mcmodel=' due to finding no URLs
 
 mstrict-align
-UrlSuffix(gcc/RISC-V-Options.html#index-mstrict-align-3)
+UrlSuffix(gcc/RISC-V-Options.html#index-mstrict-align-4)
 
 ; skipping UrlSuffix for 'mexplicit-relocs' due to finding no URLs
 
diff --git a/gcc/config/rs6000/sysv4.opt.urls b/gcc/config/rs6000/sysv4.opt.urls
index f8d58d6602c..c155cddfa36 100644
--- a/gcc/config/rs6000/sysv4.opt.urls
+++ b/gcc/config/rs6000/sysv4.opt.urls
@@ -12,7 +12,7 @@ mbit-align
 UrlSuffix(gcc/RS_002f6000-and-PowerPC-Options.html#index-mbit-align)
 
 mstrict-align
-UrlSuffix(gcc/RS_002f6000-and-PowerPC-Options.html#index-mstrict-align-4)
+UrlSuffix(gcc/RS_002f6000-and-PowerPC-Options.html#index-mstrict-align-5)
 
 mrelocatable
 UrlSuffix(gcc/RS_002f6000-and-PowerPC-Options.html#index-mrelocatable)
diff --git a/gcc/config/xtensa/xtensa.opt.urls 
b/gcc/config/xtensa/xtensa.opt.urls
index 146db23d1e3..1f193a7da0c 100644
--- a/gcc/config/xtensa/xtensa.opt.urls
+++ b/gcc/config/xtensa/xtensa.opt.urls
@@ -33,5 +33,5 @@ mabi=windowed
 UrlSuffix(gcc/Xtensa-Options.html#index-mabi_003dwindowed)
 
 mstrict-align
-UrlSuffix(gcc/Xtensa-Options.html#index-mstrict-align-5)
+UrlSuffix(gcc/Xtensa-Options.html#index-mstrict-align-6)


[gcc r14-9495] lower-subreg, edit-context: Fix comment typos

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:30e1c3d7e828b2bf2eee1660661bbc79f4151bd6

commit r14-9495-g30e1c3d7e828b2bf2eee1660661bbc79f4151bd6
Author: Jakub Jelinek 
Date:   Fri Mar 15 12:20:04 2024 +0100

lower-subreg, edit-context: Fix comment typos

When backporting r14-9315 to 13 branch, I've noticed I've missed
one letter in a comment.  And grepping for similar issues I found
one word with too many.

2024-03-15  Jakub Jelinek  

* lower-subreg.cc (resolve_simple_move): Fix comment typo,
betwee -> between.
* edit-context.cc (class line_event): Fix comment typo,
betweeen -> between.

Diff:
---
 gcc/edit-context.cc | 2 +-
 gcc/lower-subreg.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/edit-context.cc b/gcc/edit-context.cc
index b02da6e809e..37ac4989de0 100644
--- a/gcc/edit-context.cc
+++ b/gcc/edit-context.cc
@@ -129,7 +129,7 @@ class added_line
 };
 
 /* Class for representing edit events that have occurred on one line of
-   one file: the replacement of some text betweeen some columns
+   one file: the replacement of some text between some columns
on the line.
 
Subsequent events will need their columns adjusting if they're
diff --git a/gcc/lower-subreg.cc b/gcc/lower-subreg.cc
index 2f7f0a83e23..d1da94336e7 100644
--- a/gcc/lower-subreg.cc
+++ b/gcc/lower-subreg.cc
@@ -933,7 +933,7 @@ resolve_simple_move (rtx set, rtx_insn *insn)
  if (reg_overlap_mentioned_p (XVECEXP (dest, 0, 0),
   XVECEXP (src, 0, 1)))
{
- /* If there is overlap betwee the first half of the
+ /* If there is overlap between the first half of the
 destination and what will be stored to the second one,
 use a temporary pseudo.  See PR114211.  */
  rtx tem = gen_reg_rtx (GET_MODE (XVECEXP (src, 0, 1)));


[gcc r14-9494] i386: Fix a pasto in ix86_expand_int_sse_cmp [PR114339]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:ab2da8fb67b1aa0557a16b62689a888730dba610

commit r14-9494-gab2da8fb67b1aa0557a16b62689a888730dba610
Author: Jakub Jelinek 
Date:   Fri Mar 15 10:46:47 2024 +0100

i386: Fix a pasto in ix86_expand_int_sse_cmp [PR114339]

In r13-3803-gfa271afb58 I've added an optimization for LE/LEU/GE/GEU
comparison against CONST_VECTOR.  As the comments say:
 /* x <= cst can be handled as x < cst + 1 unless there is
wrap around in cst + 1.  */
...
 /* For LE punt if some element is signed maximum.  */
...
 /* For LEU punt if some element is unsigned maximum.  */
and
 /* x >= cst can be handled as x > cst - 1 unless there is
wrap around in cst - 1.  */
...
 /* For GE punt if some element is signed minimum.  */
...
 /* For GEU punt if some element is zero.  */
Apparently I wrote the GE/GEU (second case) first and then
copied/adjusted it for LE/LEU, most of the adjustments look correct, but
I've left if (code == GE) comparison when testing if it should punt for
signed maximum.  That condition is never true, because this is in
switch (code) { ... case LE: case LEU: block and we really meant to
be what the comment says, for LE punt if some element is signed maximum,
as then cst + 1 wraps around.

The following patch fixes the pasto.

2024-03-15  Jakub Jelinek  

PR target/114339
* config/i386/i386-expand.cc (ix86_expand_int_sse_cmp) : 
Fix
a pasto, compare code against LE rather than GE.

* gcc.target/i386/pr114339.c: New test.

Diff:
---
 gcc/config/i386/i386-expand.cc   |  2 +-
 gcc/testsuite/gcc.target/i386/pr114339.c | 20 
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 2210e6f7cc8..8bb8f21e686 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -4690,7 +4690,7 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, 
rtx cop0, rtx cop1,
  rtx elt = CONST_VECTOR_ELT (cop1, i);
  if (!CONST_INT_P (elt))
break;
- if (code == GE)
+ if (code == LE)
{
  /* For LE punt if some element is signed maximum.  */
  if ((INTVAL (elt) & (GET_MODE_MASK (eltmode) >> 1))
diff --git a/gcc/testsuite/gcc.target/i386/pr114339.c 
b/gcc/testsuite/gcc.target/i386/pr114339.c
new file mode 100644
index 000..8fba3747cf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr114339.c
@@ -0,0 +1,20 @@
+/* PR target/114339 */
+/* { dg-do run } */
+/* { dg-options "-O2 -Wno-psabi" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+typedef long long V __attribute__((vector_size (16)));
+
+__attribute__((noipa)) V
+foo (V a)
+{
+  return a <= (V) {0, __LONG_LONG_MAX__ };
+}
+
+int
+main ()
+{
+  V t = foo ((V) { 0, 0 });
+  if (t[0] != -1LL || t[1] != -1LL)
+__builtin_abort ();
+}


[gcc r14-9493] match.pd: Only merge truncation with conversion for -fno-signed-zeros

2024-03-15 Thread Tamar Christina via Gcc-cvs
https://gcc.gnu.org/g:7dd3b2b09cbeb6712ec680a0445cb0ad41070423

commit r14-9493-g7dd3b2b09cbeb6712ec680a0445cb0ad41070423
Author: Joe Ramsay 
Date:   Fri Mar 15 09:20:45 2024 +

match.pd: Only merge truncation with conversion for -fno-signed-zeros

This optimisation does not honour signed zeros, so should not be
enabled except with -fno-signed-zeros.

gcc/ChangeLog:

* match.pd: Fix truncation pattern for -fno-signed-zeroes

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/no_merge_trunc_signed_zero.c: New test.

Diff:
---
 gcc/match.pd   |  1 +
 .../aarch64/no_merge_trunc_signed_zero.c   | 24 ++
 2 files changed, 25 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index 9ce313323a3..15a1e7350d4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4858,6 +4858,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (simplify
(float (fix_trunc @0))
(if (!flag_trapping_math
+   && !HONOR_SIGNED_ZEROS (type)
&& types_match (type, TREE_TYPE (@0))
&& direct_internal_fn_supported_p (IFN_TRUNC, type,
  OPTIMIZE_FOR_BOTH))
diff --git a/gcc/testsuite/gcc.target/aarch64/no_merge_trunc_signed_zero.c 
b/gcc/testsuite/gcc.target/aarch64/no_merge_trunc_signed_zero.c
new file mode 100644
index 000..b2c93e55567
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/no_merge_trunc_signed_zero.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-trapping-math -fsigned-zeros" } */
+
+#include 
+
+float
+f1 (float x)
+{
+  return (int) rintf(x);
+}
+
+double
+f2 (double x)
+{
+  return (long) rint(x);
+}
+
+/* { dg-final { scan-assembler "frintx\\ts\[0-9\]+, s\[0-9\]+" } } */
+/* { dg-final { scan-assembler "cvtzs\\ts\[0-9\]+, s\[0-9\]+" } } */
+/* { dg-final { scan-assembler "scvtf\\ts\[0-9\]+, s\[0-9\]+" } } */
+/* { dg-final { scan-assembler "frintx\\td\[0-9\]+, d\[0-9\]+" } } */
+/* { dg-final { scan-assembler "cvtzs\\td\[0-9\]+, d\[0-9\]+" } } */
+/* { dg-final { scan-assembler "scvtf\\td\[0-9\]+, d\[0-9\]+" } } */
+


[gcc r14-9492] expand: EXTEND_BITINT CALL_EXPR results [PR114332]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:0319f265eddd17c32cb037b71489d9882a6eb00d

commit r14-9492-g0319f265eddd17c32cb037b71489d9882a6eb00d
Author: Jakub Jelinek 
Date:   Fri Mar 15 10:10:57 2024 +0100

expand: EXTEND_BITINT CALL_EXPR results [PR114332]

The x86-64 and aarch64 psABIs (and the unwritten ia64 psABI part) say that
the padding bits of _BitInt are undefined, while the expansion internally
typically assumes that non-mode precision integers are sign/zero extended
and extends after operations.  We handle that mismatch with EXTEND_BITINT
done when reading from untrusted sources like function arguments, reading
_BitInt from memory etc. but otherwise keep relying on stuff being extended
internally (say in pseudos).
The return value of a function is an ABI boundary though too and we need
to extend that too.

2024-03-15  Jakub Jelinek  

PR middle-end/114332
* expr.cc (expand_expr_real_1): EXTEND_BITINT also CALL_EXPR 
results.

Diff:
---
 gcc/expr.cc  |  3 ++-
 gcc/testsuite/gcc.dg/torture/bitint-64.c | 22 ++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/gcc/expr.cc b/gcc/expr.cc
index f7d74525c15..2918c469735 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -12350,7 +12350,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
return expand_builtin (exp, target, subtarget, tmode, ignore);
  }
   }
-  return expand_call (exp, target, ignore);
+  temp = expand_call (exp, target, ignore);
+  return EXTEND_BITINT (temp);
 
 case VIEW_CONVERT_EXPR:
   op0 = NULL_RTX;
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-64.c 
b/gcc/testsuite/gcc.dg/torture/bitint-64.c
new file mode 100644
index 000..8f0f21cbee2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/bitint-64.c
@@ -0,0 +1,22 @@
+/* PR middle-end/114332 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -fwrapv" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+enum E { E22 = 22 } e = E22;
+
+_BitInt (5)
+foo (void)
+{
+  _Atomic _BitInt (5) b = 0;
+  b += e;
+  return b;
+}
+
+int
+main ()
+{
+  if (foo () != -10)
+__builtin_abort ();
+}


[gcc r14-9491] testsuite: Fix up pr104601.C for recent libstdc++ changes

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:8ae7062bf4005c08b093828d40e2c9278e6f6d9c

commit r14-9491-g8ae7062bf4005c08b093828d40e2c9278e6f6d9c
Author: Jakub Jelinek 
Date:   Fri Mar 15 10:01:41 2024 +0100

testsuite: Fix up pr104601.C for recent libstdc++ changes

r14-9478 added [[nodiscard]] to various  APIs including find_if
the pr104601.C testcase uses.  As it is an optimization bug fix testcase,
haven't tried to adjust the testcase to use the find_if result, but instead
have added -Wno-unused-result flag to quiet the warning.

2024-03-15  Jakub Jelinek  

* g++.dg/torture/pr104601.C: Add -Wno-unused-result to dg-options.

Diff:
---
 gcc/testsuite/g++.dg/torture/pr104601.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/torture/pr104601.C 
b/gcc/testsuite/g++.dg/torture/pr104601.C
index 92ad73d47e9..c8d4661e86d 100644
--- a/gcc/testsuite/g++.dg/torture/pr104601.C
+++ b/gcc/testsuite/g++.dg/torture/pr104601.C
@@ -1,6 +1,6 @@
 // PR tree-optimization/104601
 // { dg-do run }
-// { dg-options "-std=c++17" }
+// { dg-options "-std=c++17 -Wno-unused-result" }
 
 #include 
 #include 


[gcc r13-8440] testsuite: Added missing } in the dg-bogus comment [PR114343]

2024-03-15 Thread Torbjorn Svensson via Gcc-cvs
https://gcc.gnu.org/g:c471d29affba0d98d5cc6ab044b53f009f35324b

commit r13-8440-gc471d29affba0d98d5cc6ab044b53f009f35324b
Author: Torbjörn SVENSSON 
Date:   Fri Mar 15 09:25:06 2024 +0100

testsuite: Added missing } in the dg-bogus comment [PR114343]

gcc/testsuite/ChangeLog:

PR testsuite/114343
* 
gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c:
Added missing } in the dg-bogus comment.

Signed-off-by: Torbjörn SVENSSON 

Diff:
---
 .../gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
 
b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
index e8cde7338a0..33cf10c1e29 100644
--- 
a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
+++ 
b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
@@ -60,7 +60,7 @@ static inline enum obj_type obj_type(const enum obj_type *t)
 }
 static inline struct connection *__objt_conn(enum obj_type *t)
 {
- return ((struct connection *)(((void *)(t)) - ((long)&((struct connection 
*)0)->obj_type))); /* { dg-bogus "may result in an unaligned pointer value" 
"Fixed in r14-6517-gb7e4a4c626e" { xfail short_enums } */
+ return ((struct connection *)(((void *)(t)) - ((long)&((struct connection 
*)0)->obj_type))); /* { dg-bogus "may result in an unaligned pointer value" 
"Fixed in r14-6517-gb7e4a4c626e" { xfail short_enums } } */
 }
 static inline struct connection *objt_conn(enum obj_type *t)
 {


[gcc r14-9490] bitint: Fix up adjustment of large/huge _BitInt arguments of returns_twice calls [PR113466]

2024-03-15 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:90b9872311ccb24685ba33b6ba6f374d50f03874

commit r14-9490-g90b9872311ccb24685ba33b6ba6f374d50f03874
Author: Jakub Jelinek 
Date:   Fri Mar 15 09:16:43 2024 +0100

bitint: Fix up adjustment of large/huge _BitInt arguments of returns_twice 
calls [PR113466]

This patch (on top of the just posted gsi_safe_insert* fixes patch)
fixes the instrumentation of large/huge _BitInt SSA_NAME arguments of
returns_twice calls.

In this case it isn't just a matter of using gsi_safe_insert_before instead
of gsi_insert_before, we need to do more.

One thing is that unlike the asan/ubsan instrumentation which does just some
checking, here we want the statement before the call to load into a SSA_NAME
which is passed to the call.  With another edge we need to add a PHI,
with one PHI argument the loaded SSA_NAME, another argument an uninitialized
warning free SSA_NAME and a result and arrange for all 3 SSA_NAMEs to be
preserved (i.e. stay as is, be no longer lowered afterwards).

Unfortunately, edge_before_returns_twice_call can create new SSA_NAMEs using
copy_ssa_name and while we can have a reasonable partition for them (same
partition as PHI result correspoding to the PHI argument newly added), 
adding
SSA_NAMEs into a partition after the partitions are finalized is too ugly.
So, this patch takes a different approach suggested by Richi, just emit
the argument loads before the returns_twice call normally (i.e. temporarily
create invalid IL) and just remember that we did that, and when the bitint
lowering is otherwise done fix this up, gsi_remove those statements,
gsi_safe_insert_before and and create the needed new PHIs.

2024-03-15  Jakub Jelinek  

PR tree-optimization/113466
* gimple-lower-bitint.cc (bitint_large_huge): Add 
m_returns_twice_calls
member.
(bitint_large_huge::bitint_large_huge): Initialize it.
(bitint_large_huge::~bitint_large_huge): Release it.
(bitint_large_huge::lower_call): Remember ECF_RETURNS_TWICE call 
stmts
before which at least one statement has been inserted.
(gimple_lower_bitint): Move argument loads before ECF_RETURNS_TWICE
calls to a different block and add corresponding PHIs.

* gcc.dg/bitint-100.c: New test.

Diff:
---
 gcc/gimple-lower-bitint.cc|  71 -
 gcc/testsuite/gcc.dg/bitint-100.c | 108 ++
 2 files changed, 178 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index b58220f564c..42c39d8a47a 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -419,7 +419,8 @@ struct bitint_large_huge
   bitint_large_huge ()
 : m_names (NULL), m_loads (NULL), m_preserved (NULL),
   m_single_use_names (NULL), m_map (NULL), m_vars (NULL),
-  m_limb_type (NULL_TREE), m_data (vNULL) {}
+  m_limb_type (NULL_TREE), m_data (vNULL),
+  m_returns_twice_calls (vNULL) {}
 
   ~bitint_large_huge ();
 
@@ -553,6 +554,7 @@ struct bitint_large_huge
   unsigned m_bitfld_load;
   vec m_data;
   unsigned int m_data_cnt;
+  vec m_returns_twice_calls;
 };
 
 bitint_large_huge::~bitint_large_huge ()
@@ -565,6 +567,7 @@ bitint_large_huge::~bitint_large_huge ()
 delete_var_map (m_map);
   XDELETEVEC (m_vars);
   m_data.release ();
+  m_returns_twice_calls.release ();
 }
 
 /* Insert gimple statement G before current location
@@ -5248,6 +5251,7 @@ bitint_large_huge::lower_call (tree obj, gimple *stmt)
   default:
break;
   }
+  bool returns_twice = (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0;
   for (unsigned int i = 0; i < nargs; ++i)
 {
   tree arg = gimple_call_arg (stmt, i);
@@ -5271,6 +5275,11 @@ bitint_large_huge::lower_call (tree obj, gimple *stmt)
  arg = make_ssa_name (TREE_TYPE (arg));
  gimple *g = gimple_build_assign (arg, v);
  gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+ if (returns_twice)
+   {
+ m_returns_twice_calls.safe_push (stmt);
+ returns_twice = false;
+   }
}
   gimple_call_set_arg (stmt, i, arg);
   if (m_preserved == NULL)
@@ -7091,6 +7100,66 @@ gimple_lower_bitint (void)
   if (edge_insertions)
 gsi_commit_edge_inserts ();
 
+  /* Fix up arguments of ECF_RETURNS_TWICE calls.  Those were temporarily
+ inserted before the call, but that is invalid IL, so move them to the
+ right place and add corresponding PHIs.  */
+  if (!large_huge.m_returns_twice_calls.is_empty ())
+{
+  auto_vec arg_stmts;
+  while (!large_huge.m_returns_twice_calls.is_empty ())
+   {
+ gimple *stmt = large_huge.m_returns_twice_calls.pop ();
+ gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (stmt));
+ while (gsi_stmt (gsi) != stmt)
+