]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
phiprop: Allow non-trapping loads to be proped back into the loop
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 21 Nov 2025 06:39:48 +0000 (22:39 -0800)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Mon, 24 Nov 2025 17:31:09 +0000 (09:31 -0800)
First the testcase for PR60183 is no longer testing that we don't
prop into the loops for possible trapping cases. This adds phiprop-4.c
that tests that.
Second we can prop back into loops if we know the load will not trap.
This adds that check. phiprop-3.c tests that.

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/60183

gcc/ChangeLog:

* tree-ssa-phiprop.cc (propagate_with_phi): Allow
known non-trapping loads to happen back into the
loop.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/phiprop-3.c: New test.
* gcc.dg/tree-ssa/phiprop-4.c: New test.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.c [new file with mode: 0644]
gcc/tree-ssa-phiprop.cc

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c
new file mode 100644 (file)
index 0000000..59e9561
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiprop1-details" } */
+
+/* PR tree-optimization/60183 */
+
+unsigned char c;
+extern unsigned char d;
+int j = 2;
+
+unsigned long
+foo (void)
+{
+  unsigned char *y = &c;
+  int i;
+  unsigned w = 0;
+  for (i = 0; i < j; i++)
+    {
+      w = *y;
+      y = &d;
+    }
+  return w;
+}
+/* the load from c/d does not trap so we should able to remove the phi.  */
+/* { 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/testsuite/gcc.dg/tree-ssa/phiprop-4.c b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.c
new file mode 100644 (file)
index 0000000..ceb03ed
--- /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 < j; i++)
+    {
+      w = *y;
+      y = &d;
+    }
+  return w;
+}
+/* the load from d can trap so this should not cause a phiprop. */
+/* { dg-final { scan-tree-dump-not "Removing dead stmt:" "phiprop1"} } */
+/* { dg-final { scan-tree-dump-not "Inserting PHI for result of load" "phiprop1"} } */
index 897bd583ea7812bc170b62d2f96063ef8a840485..124d06c81911a572102a33eed2a60ae4c9c159f8 100644 (file)
@@ -271,6 +271,7 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
     return false;
 
   tree up_vuse = NULL_TREE;
+  bool canpossible_trap = false;
   /* Check if we can "cheaply" dereference all phi arguments.  */
   FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
     {
@@ -289,7 +290,11 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
          arg = gimple_assign_rhs1 (def_stmt);
        }
       if (TREE_CODE (arg) == ADDR_EXPR)
-       ;
+       {
+         tree decl = TREE_OPERAND (arg, 0);
+         if (!canpossible_trap)
+           canpossible_trap = tree_could_trap_p (decl);
+       }
       /* When we have an SSA name see if we previously encountered a
         dereference of it.  */
       else if (TREE_CODE (arg) == SSA_NAME
@@ -335,9 +340,10 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
        calculate_dominance_info (CDI_POST_DOMINATORS);
 
       /* Only replace loads in blocks that post-dominate the PHI node.  That
-         makes sure we don't end up speculating loads.  */
-      if (!dominated_by_p (CDI_POST_DOMINATORS,
-                          bb, gimple_bb (use_stmt)))
+        makes sure we don't end up speculating trapping loads.  */
+      if (canpossible_trap
+         && !dominated_by_p (CDI_POST_DOMINATORS,
+                             bb, gimple_bb (use_stmt)))
        continue;
 
       /* Check whether this is a load of *ptr.  */