https://gcc.gnu.org/g:e94e91d6f37750cae671ea7f82ce55bda3f8f372

commit r16-5556-ge94e91d6f37750cae671ea7f82ce55bda3f8f372
Author: Andrew Pinski <[email protected]>
Date:   Thu Nov 20 23:14:24 2025 -0800

    phiprop: allowing prop into loop if there is a phi already
    
    This is a small improvement over the original change
    for PR60183 where if we created a phi already we can
    reuse it always but since the order of this use might
    be before the use which was valid to transform. we
    need a vector to save the delayed ones.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/60183
    
    gcc/ChangeLog:
    
            * tree-ssa-phiprop.cc (propagate_with_phi): Delay the decision
            of always rejecting proping into the loop until all are done.
            if there was some delay stmts and a phi was created fill them in.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/phiprop-5.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c | 26 ++++++++++++++++++++++
 gcc/tree-ssa-phiprop.cc                   | 37 ++++++++++++++++++++++---------
 2 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c
new file mode 100644
index 000000000000..b76b17c046a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { weak_undefined } } } */
+/* { dg-options "-O1 -fdump-tree-phiprop1-details" } */
+/* { dg-add-options weak_undefined } */
+
+/* PR tree-optimization/60183 */
+
+unsigned char c;
+extern unsigned char d __attribute__((weak));
+int j = 2;
+
+unsigned long
+foo (void)
+{
+  unsigned char *y = &c;
+  int i;
+  unsigned w = 0;
+  for (i = 0; i < *y; i++)
+    {
+      w = *y;
+      y = &d;
+    }
+  return w;
+}
+/* the load from d can trap but the load always happen so this should be done. 
 */
+/* { dg-final { scan-tree-dump "Removing dead stmt:" "phiprop1"} } */
+/* { dg-final { scan-tree-dump "Inserting PHI for result of load" "phiprop1"} 
} */
diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc
index 124d06c81911..a2e039fb72d9 100644
--- a/gcc/tree-ssa-phiprop.cc
+++ b/gcc/tree-ssa-phiprop.cc
@@ -331,10 +331,12 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
      can move the loads to the place of the ptr phi node.  */
   phi_inserted = false;
   changed = false;
+  auto_vec<gimple*> delayed_uses;
   FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
     {
       gimple *def_stmt;
       tree vuse;
+      bool delay = false;
 
       if (!dom_info_available_p (cfun, CDI_POST_DOMINATORS))
        calculate_dominance_info (CDI_POST_DOMINATORS);
@@ -344,7 +346,7 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
       if (canpossible_trap
          && !dominated_by_p (CDI_POST_DOMINATORS,
                              bb, gimple_bb (use_stmt)))
-       continue;
+       delay = true;
 
       /* Check whether this is a load of *ptr.  */
       if (!(is_gimple_assign (use_stmt)
@@ -396,6 +398,9 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
          insert aggregate copies on the edges instead.  */
       if (!is_gimple_reg_type (TREE_TYPE (gimple_assign_lhs (use_stmt))))
        {
+         /* aggregate copies are too hard to handled if delayed.  */
+         if (delay)
+           goto next;
          if (!gimple_vdef (use_stmt))
            goto next;
 
@@ -450,10 +455,19 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
 
          changed = true;
        }
-
+      /* Further replacements are easy, just make a copy out of the
+        load.  */
+      else if (phi_inserted)
+       {
+         gimple_assign_set_rhs1 (use_stmt, res);
+         update_stmt (use_stmt);
+         changed = true;
+       }
+      else if (delay)
+       delayed_uses.safe_push (use_stmt);
       /* Found a proper dereference.  Insert a phi node if this
         is the first load transformation.  */
-      else if (!phi_inserted)
+      else
        {
          res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n, dce_ssa_names);
          type = TREE_TYPE (res);
@@ -470,19 +484,20 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
          phi_inserted = true;
          changed = true;
        }
-      else
-       {
-         /* Further replacements are easy, just make a copy out of the
-            load.  */
-         gimple_assign_set_rhs1 (use_stmt, res);
-         update_stmt (use_stmt);
-         changed = true;
-       }
 
 next:;
       /* Continue searching for a proper dereference.  */
     }
 
+  /* Update the delayed uses if there is any
+     as now we know this is safe to do. */
+  if (phi_inserted)
+    for (auto use_stmt : delayed_uses)
+      {
+       gimple_assign_set_rhs1 (use_stmt, res);
+       update_stmt (use_stmt);
+      }
+
   return changed;
 }

Reply via email to