]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
phiprop: allowing prop into loop if there is a phi already
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 21 Nov 2025 07:14:24 +0000 (23:14 -0800)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Mon, 24 Nov 2025 17:31:09 +0000 (09:31 -0800)
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>
gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c [new file with mode: 0644]
gcc/tree-ssa-phiprop.cc

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 (file)
index 0000000..b76b17c
--- /dev/null
@@ -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"} } */
index 124d06c81911a572102a33eed2a60ae4c9c159f8..a2e039fb72d9ac48ec1096ba861549dc7bc915bd 100644 (file)
@@ -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;
 }