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 <[email protected]>
---
gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c | 25 ++++++++++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.c | 26 +++++++++++++++++++++++
gcc/tree-ssa-phiprop.cc | 14 ++++++++----
3 files changed, 61 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.c
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
index 00000000000..59e95613c8c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c
@@ -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
index 00000000000..ceb03edac74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.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 < 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"} } */
diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc
index 897bd583ea7..124d06c8191 100644
--- a/gcc/tree-ssa-phiprop.cc
+++ b/gcc/tree-ssa-phiprop.cc
@@ -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. */
--
2.43.0