r17-1238-g8e3eff39a4564c added an early return for SSA names that
occur in abnormal phis.  That had the effect of bypassing the later:

          /* If STMT is a phi, remove any information recorded for
             its arguments.  */
          if (is_a <gphi *> (stmt))
            reprocess_inputs (stmt);

That reprocessing is important since (by design) the pass initially
makes optimistic assumptions about backedges.

Tested on aarch64-linux-gnu, powerpc64le-linux-gnu and x86_64-linux-gnu.
Also tested by Sam on the glibc testsuite (thanks!).

OK to install?

Richard


gcc/
        PR tree-optimization/125653
        * gimple-ssa-backprop.cc (backprop::process_var): Avoid early
        return for SSA names that occur in abnormal phis.

gcc/testsuite/
        PR tree-optimization/125653
        * gcc.dg/torture/pr125653.c: New test.
---
 gcc/gimple-ssa-backprop.cc              |  9 ++++-----
 gcc/testsuite/gcc.dg/torture/pr125653.c | 26 +++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr125653.c

diff --git a/gcc/gimple-ssa-backprop.cc b/gcc/gimple-ssa-backprop.cc
index f32f18f1014..e101430bb8e 100644
--- a/gcc/gimple-ssa-backprop.cc
+++ b/gcc/gimple-ssa-backprop.cc
@@ -633,12 +633,11 @@ backprop::process_var (tree var, var_info *v)
   if (has_zero_uses (var))
     return;
 
-  /* Propagating along abnormal edges is delicate, punt for now.  */
-  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (var))
-    return;
-
   usage_info info;
-  intersect_uses (var, &info);
+
+  /* Propagating along abnormal edges is delicate, punt for now.  */
+  if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (var))
+    intersect_uses (var, &info);
 
   gimple *stmt = SSA_NAME_DEF_STMT (var);
   auto hash = SSA_NAME_VERSION (var);
diff --git a/gcc/testsuite/gcc.dg/torture/pr125653.c 
b/gcc/testsuite/gcc.dg/torture/pr125653.c
new file mode 100644
index 00000000000..d88f30f3d1f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr125653.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+
+int
+main ()
+{
+  __label__ set, neg, check;
+  void *ops[] = { &&set, &&neg, &&check };
+  int i = 0;
+  double foo = 0.0;
+
+next:
+  goto *ops[i++];
+
+set:
+  foo = 1.0;
+  goto next;
+
+neg:
+  foo = -foo;
+  goto next;
+
+check:
+  if (foo != -1.0)
+    __builtin_abort ();
+  return 0;
+}
-- 
2.54.0

Reply via email to