commit:     46883551fe0614e80638fa08805e1f1bc7710a96
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 17 03:04:26 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Sep 17 03:04:26 2025 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=46883551

16.0.0: add a prereq patch for the forwprop hang

Signed-off-by: Sam James <sam <AT> gentoo.org>

 .../87_all_PR121962-forwprop-hang-prereq.patch     | 244 +++++++++++++++++++++
 ...g.patch => 88_all_PR121962-forwprop-hang.patch} |   0
 16.0.0/gentoo/README.history                       |   3 +-
 3 files changed, 246 insertions(+), 1 deletion(-)

diff --git a/16.0.0/gentoo/87_all_PR121962-forwprop-hang-prereq.patch 
b/16.0.0/gentoo/87_all_PR121962-forwprop-hang-prereq.patch
new file mode 100644
index 0000000..245a78b
--- /dev/null
+++ b/16.0.0/gentoo/87_all_PR121962-forwprop-hang-prereq.patch
@@ -0,0 +1,244 @@
+From 41dc015782a42cb64680a55f6766ed5504c4ca53 Mon Sep 17 00:00:00 2001
+Message-ID: 
<41dc015782a42cb64680a55f6766ed5504c4ca53.1758078219.git....@gentoo.org>
+From: Andrew Pinski <[email protected]>
+Date: Mon, 15 Sep 2025 10:19:13 -0700
+Subject: [PATCH] forwprop: Handle memcpy for arguments with respect to copies
+
+This moves the code used in optimize_agr_copyprop_1 (r16-3887-g597b50abb0d)
+to handle this same case into its new function and use it inside
+optimize_agr_copyprop_arg. This allows to remove more copies that show up only
+in arguments.
+
+Bootstrapped and tested on x86_64-linux-gnu.
+
+gcc/ChangeLog:
+
+       * tree-ssa-forwprop.cc (optimize_agr_copyprop_1): Split out
+       the case where `operand_equal_p (dest, src2)` is false into ...
+       (new_src_based_on_copy): This. New function.
+       (optimize_agr_copyprop_arg): Use new_src_based_on_copy
+       instead of operand_equal_p to find the new src.
+
+gcc/testsuite/ChangeLog:
+
+       * gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c: New test.
+
+Signed-off-by: Andrew Pinski <[email protected]>
+---
+ .../tree-ssa/copy-prop-aggregate-arg-2.c      |  33 +++++
+ gcc/tree-ssa-forwprop.cc                      | 135 ++++++++++--------
+ 2 files changed, 106 insertions(+), 62 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c
+
+diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c
+new file mode 100644
+index 000000000000..11f0768c1112
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c
+@@ -0,0 +1,33 @@
++/* { dg-do compile } */
++/* { dg-options "-O1 -fdump-tree-forwprop1-details -fdump-tree-optimized" } */
++
++
++struct s1
++{
++  int t[1024];
++};
++
++struct s2 {
++  struct s1 t;
++};
++
++struct s3
++{
++  struct s2 t;
++};
++
++void g(struct s3);
++
++void f(struct s1 s)
++{
++  struct s2 removeme;
++  removeme.t = s;
++  struct s3 removeme2;
++  removeme2.t = removeme;
++  g(removeme2);
++}
++
++
++/* { dg-final { scan-tree-dump-times "after previous" 2 "forwprop1" } } */
++/* { dg-final { scan-tree-dump-not "removeme " "optimized" } } */
++/* { dg-final { scan-tree-dump-not "removeme2 " "optimized" } } */
+diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
+index 1eacff01587c..f58a7b8c591d 100644
+--- a/gcc/tree-ssa-forwprop.cc
++++ b/gcc/tree-ssa-forwprop.cc
+@@ -1458,6 +1458,72 @@ split_core_and_offset_size (tree expr,
+   return core;
+ }
+ 
++/* Returns a new src based on the
++   copy `DEST = SRC` and for the old SRC2.
++   Returns null if SRC2 is not related to DEST.  */
++
++static tree
++new_src_based_on_copy (tree src2, tree dest, tree src)
++{
++  /* If the second src is not exactly the same as dest,
++     try to handle it seperately; see it is address/size equivalent.
++     Handles `a` and `a.b` and `MEM<char[N]>(&a)` which all have
++     the same size and offsets as address/size equivalent.
++     This allows copying over a memcpy and also one for copying
++     where one field is the same size as the whole struct.  */
++  if (operand_equal_p (dest, src2))
++    return src;
++  /* A VCE can't be used with imag/real or BFR so reject them early. */
++  if (TREE_CODE (src) == IMAGPART_EXPR
++      || TREE_CODE (src) == REALPART_EXPR
++      || TREE_CODE (src) == BIT_FIELD_REF)
++    return NULL_TREE;
++  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 (src2, &bytesize2, &bytepos2,
++                                        &toffset2, &reversep2);
++  if (!core1 || !core2)
++    return NULL_TREE;
++  if (reversep1 != reversep2)
++    return NULL_TREE;
++  /* The sizes of the 2 accesses need to be the same. */
++  if (!known_eq (bytesize1, bytesize2))
++    return NULL_TREE;
++  if (!operand_equal_p (core1, core2, 0))
++    return NULL_TREE;
++
++  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 NULL_TREE;
++
++      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 NULL_TREE;
++    }
++  diff += bytepos1 - bytepos2;
++  /* The offset between the 2 need to be 0. */
++  if (!known_eq (diff, 0))
++    return NULL_TREE;
++  return fold_build1 (VIEW_CONVERT_EXPR,TREE_TYPE (src2), src);
++}
++
+ /* 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. */
+@@ -1474,66 +1540,9 @@ optimize_agr_copyprop_1 (gimple *stmt, gimple *use_stmt,
+   /* If the new store is `src2 = src2;` skip over it. */
+   if (operand_equal_p (src2, dest2, 0))
+     return false;
+-  /* If the second src is not exactly the same as dest,
+-     try to handle it seperately; see it is address/size equivalent.
+-     Handles `a` and `a.b` and `MEM<char[N]>(&a)` which all have
+-     the same size and offsets as address/size equivalent.
+-     This allows copying over a memcpy and also one for copying
+-     where one field is the same size as the whole struct.  */
+-  if (!operand_equal_p (dest, src2, 0))
+-    {
+-      /* A VCE can't be used with imag/real or BFR so reject them early. */
+-      if (TREE_CODE (src) == IMAGPART_EXPR
+-        || TREE_CODE (src) == REALPART_EXPR
+-        || TREE_CODE (src) == BIT_FIELD_REF)
+-      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 (src2, &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;
+-      src = fold_build1_loc (gimple_location (use_stmt),
+-                           VIEW_CONVERT_EXPR,
+-                           TREE_TYPE (src2), src);
+-    }
++  src = new_src_based_on_copy (src2, dest, src);
++  if (!src)
++    return false;
+   /* For 2 memory refences and using a temporary to do the copy,
+      don't remove the temporary as the 2 memory references might overlap.
+      Note t does not need to be decl as it could be field.
+@@ -1634,8 +1643,10 @@ optimize_agr_copyprop_arg (gimple *defstmt, gcall *call,
+         || is_gimple_min_invariant (*argptr)
+         || TYPE_VOLATILE (TREE_TYPE (*argptr)))
+       continue;
+-      if (!operand_equal_p (*argptr, dest, 0))
++      tree newsrc = new_src_based_on_copy (*argptr, dest, src);
++      if (!newsrc)
+       continue;
++
+       if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+         fprintf (dump_file, "Simplified\n  ");
+@@ -1643,7 +1654,7 @@ optimize_agr_copyprop_arg (gimple *defstmt, gcall *call,
+         fprintf (dump_file, "after previous\n  ");
+         print_gimple_stmt (dump_file, defstmt, 0, dump_flags);
+       }
+-      *argptr = unshare_expr (src);
++      *argptr = unshare_expr (newsrc);
+       changed = true;
+       if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+
+base-commit: e690b97761e18daccb4fff0151c97c1d0115b55f
+-- 
+2.51.0
+

diff --git a/16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch 
b/16.0.0/gentoo/88_all_PR121962-forwprop-hang.patch
similarity index 100%
rename from 16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch
rename to 16.0.0/gentoo/88_all_PR121962-forwprop-hang.patch

diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history
index 7db3c43..023c43f 100644
--- a/16.0.0/gentoo/README.history
+++ b/16.0.0/gentoo/README.history
@@ -1,6 +1,7 @@
 15     ????
 
-       + 87_all_PR121962-forwprop-hang.patch
+       + 87_all_PR121962-forwprop-hang-prereq.patch
+       + 88_all_PR121962-forwprop-hang.patch
 
 14     7 September 2025
 

Reply via email to