[gcc r16-5556] phiprop: allowing prop into loop if there is a phi already

Andrew Pinski pinskia@gcc.gnu.org
Mon Nov 24 17:32:44 GMT 2025


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

commit r16-5556-ge94e91d6f37750cae671ea7f82ce55bda3f8f372
Author: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
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 <andrew.pinski@oss.qualcomm.com>

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;
 }


More information about the Gcc-cvs mailing list