commit:     ca74e5013ee7a20aefc727dade6cc0f6b0724940
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 16 19:22:41 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Sep 16 19:22:41 2025 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=ca74e501

16.0.0: add fix for forwprop hang

Bug: https://gcc.gnu.org/PR121962
Signed-off-by: Sam James <sam <AT> gentoo.org>

 16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch | 161 ++++++++++++++++++++++
 16.0.0/gentoo/README.history                      |   4 +
 2 files changed, 165 insertions(+)

diff --git a/16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch 
b/16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch
new file mode 100644
index 0000000..52d25d6
--- /dev/null
+++ b/16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch
@@ -0,0 +1,161 @@
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121962#c11
+
+From 9463f1db7bc409b9a59dab1d11b6e82e423c4466 Mon Sep 17 00:00:00 2001
+From: Andrew Pinski <[email protected]>
+Date: Tue, 16 Sep 2025 10:55:03 -0700
+Subject: [PATCH] forwprop: Fix up "nop" copies after recent changes [PR121962]
+
+After r16-3887-g597b50abb0d2fc, the check to see if the copy is
+a nop copy becomes inefficient. The code going into an infinite
+loop as the copy keeps on being propagated over and over again.
+
+That is if we have:
+```
+  struct s1 *b = &a.t;
+  a.t = *b;
+  p = *b;
+```
+
+This goes into an infinite loop propagating over and over again the
+`MEM[&a]`.
+To solve this a new function is needed for the comparison that is
+similar to new_src_based_on_copy.
+
+       PR tree-optimization/121962
+
+gcc/ChangeLog:
+
+       * tree-ssa-forwprop.cc (same_for_assignment): New function.
+       (optimize_agr_copyprop_1): Use same_for_assignment to check for
+       nop copies.
+       (optimize_agr_copyprop): Likewise.
+
+gcc/testsuite/ChangeLog:
+
+       * gcc.dg/torture/pr121962-1.c: New test.
+
+Signed-off-by: Andrew Pinski <[email protected]>
+---
+ gcc/testsuite/gcc.dg/torture/pr121962-1.c | 21 ++++++++
+ gcc/tree-ssa-forwprop.cc                  | 64 ++++++++++++++++++++++-
+ 2 files changed, 83 insertions(+), 2 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.dg/torture/pr121962-1.c
+
+diff --git a/gcc/testsuite/gcc.dg/torture/pr121962-1.c 
b/gcc/testsuite/gcc.dg/torture/pr121962-1.c
+new file mode 100644
+index 00000000000..97f88ad5734
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/torture/pr121962-1.c
+@@ -0,0 +1,21 @@
++/* PR tree-optimization/121962 */
++struct s1
++{
++  int t;
++};
++
++struct s2
++{
++  struct s1 t;
++};
++
++struct s1 p;
++
++void f(struct s2 a)
++{
++  struct s1 *b = &a.t;
++  /* this is a nop load/store and should be ignored
++     by copy propagation for aggregates.  */
++  a.t = *b;
++  p = *b;
++}
+diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
+index 9d389e1b9bf..833a354ce2c 100644
+--- a/gcc/tree-ssa-forwprop.cc
++++ b/gcc/tree-ssa-forwprop.cc
+@@ -1528,6 +1528,66 @@ new_src_based_on_copy (tree src2, tree dest, tree src)
+   return fold_build1 (VIEW_CONVERT_EXPR,TREE_TYPE (src2), src);
+ }
+ 
++/* Returns true if SRC and DEST are the same address such that
++   `SRC == DEST;` is conisdered a nop. This is more than an
++   operand_equal_p check as it needs to be similar to
++   new_src_based_on_copy.  */
++
++static bool
++same_for_assignment (tree src, tree dest)
++{
++  if (operand_equal_p (dest, src, 0))
++    return true;
++  /* if both dest and src2 are decls, then we know these 2
++     accesses can't be the same.  */
++  if (DECL_P (dest) && DECL_P (src))
++    return false;
++
++  tree core1, core2;
++  poly_int64 bytepos1, bytepos2;
++  poly_int64 bytesize1, bytesize2;
++  tree toffset1, toffset2;
++  int reversep1 = 0;
++  int reversep2 = 0;
++  poly_int64 diff = 0;
++  core1 = split_core_and_offset_size (dest, &bytesize1, &bytepos1,
++                                    &toffset1, &reversep1);
++  core2 = split_core_and_offset_size (src, &bytesize2, &bytepos2,
++                                    &toffset2, &reversep2);
++  if (!core1 || !core2)
++    return false;
++  if (reversep1 != reversep2)
++    return false;
++  /* The sizes of the 2 accesses need to be the same. */
++  if (!known_eq (bytesize1, bytesize2))
++    return false;
++  if (!operand_equal_p (core1, core2, 0))
++    return false;
++  if (toffset1 && toffset2)
++    {
++      tree type = TREE_TYPE (toffset1);
++      if (type != TREE_TYPE (toffset2))
++      toffset2 = fold_convert (type, toffset2);
++
++      tree tdiff = fold_build2 (MINUS_EXPR, type, toffset1, toffset2);
++      if (!cst_and_fits_in_hwi (tdiff))
++      return false;
++
++      diff = int_cst_value (tdiff);
++    }
++  else if (toffset1 || toffset2)
++    {
++      /* If only one of the offsets is non-constant, the difference cannot
++       be a constant.  */
++      return false;
++    }
++  diff += bytepos1 - bytepos2;
++  /* The offset between the 2 need to be 0. */
++  if (!known_eq (diff, 0))
++    return false;
++  return true;
++}
++
+ /* Helper function for optimize_agr_copyprop.
+    For aggregate copies in USE_STMT, see if DEST
+    is on the lhs of USE_STMT and replace it with SRC. */
+@@ -1542,7 +1602,7 @@ optimize_agr_copyprop_1 (gimple *stmt, gimple *use_stmt,
+   tree dest2 = gimple_assign_lhs (use_stmt);
+   tree src2 = gimple_assign_rhs1 (use_stmt);
+   /* If the new store is `src2 = src2;` skip over it. */
+-  if (operand_equal_p (src2, dest2, 0))
++  if (same_for_assignment (src2, dest2))
+     return false;
+   src = new_src_based_on_copy (src2, dest, src);
+   if (!src)
+@@ -1702,7 +1762,7 @@ optimize_agr_copyprop (gimple_stmt_iterator *gsip)
+   tree dest = gimple_assign_lhs (stmt);
+   tree src = gimple_assign_rhs1 (stmt);
+   /* If the statement is `src = src;` then ignore it. */
+-  if (operand_equal_p (dest, src, 0))
++  if (same_for_assignment (dest, src))
+     return false;
+ 
+   tree vdef = gimple_vdef (stmt);
+-- 
+2.43.0

diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history
index 3a58f30..7db3c43 100644
--- a/16.0.0/gentoo/README.history
+++ b/16.0.0/gentoo/README.history
@@ -1,3 +1,7 @@
+15     ????
+
+       + 87_all_PR121962-forwprop-hang.patch
+
 14     7 September 2025
 
        - 91_all_PR121699-mesa.patch

Reply via email to