tree-optimization/105163 - abnormal SSA coalescing and reassoc
authorRichard Biener <rguenther@suse.de>
Wed, 6 Apr 2022 07:36:38 +0000 (09:36 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 6 Apr 2022 08:33:13 +0000 (10:33 +0200)
The negate propagation optimizations in reassoc did not look out for
abnormal SSA coalescing issues.  The following fixes that.

2022-04-06  Richard Biener  <rguenther@suse.de>

PR tree-optimization/105163
* tree-ssa-reassoc.cc (repropagate_negates): Avoid propagating
negated abnormals.

* gcc.dg/torture/pr105163.c: New testcase.

gcc/testsuite/gcc.dg/torture/pr105163.c [new file with mode: 0644]
gcc/tree-ssa-reassoc.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr105163.c b/gcc/testsuite/gcc.dg/torture/pr105163.c
new file mode 100644 (file)
index 0000000..23e0410
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target nonlocal_goto } */
+
+#include <setjmp.h>
+
+extern int bar (unsigned int *);
+extern jmp_buf *baz (void);
+struct C { int c1; };
+void foo (struct C *x, int *z, int e)
+{
+  unsigned int d = 0;
+  long f;
+  setjmp (*baz());
+  f = 1 + ~d;
+  d = 8;
+  if ((!0) && !e && bar(z)) *z = 1 + f;
+}
index 7ee5094..0d55fc7 100644 (file)
@@ -5970,10 +5970,14 @@ repropagate_negates (void)
   FOR_EACH_VEC_ELT (plus_negates, i, negate)
     {
       gimple *user = get_single_immediate_use (negate);
-
       if (!user || !is_gimple_assign (user))
        continue;
 
+      tree negateop = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (negate));
+      if (TREE_CODE (negateop) == SSA_NAME
+         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (negateop))
+       continue;
+
       /* The negate operand can be either operand of a PLUS_EXPR
         (it can be the LHS if the RHS is a constant for example).
 
@@ -5996,9 +6000,9 @@ repropagate_negates (void)
          if (gimple_assign_rhs2 (user) == negate)
            {
              tree rhs1 = gimple_assign_rhs1 (user);
-             tree rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (negate));
              gimple_stmt_iterator gsi = gsi_for_stmt (user);
-             gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
+             gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1,
+                                             negateop);
              update_stmt (user);
            }
        }
@@ -6007,21 +6011,20 @@ repropagate_negates (void)
          if (gimple_assign_rhs1 (user) == negate)
            {
              /* We have
-                  x = -a
+                  x = -negateop
                   y = x - b
                 which we transform into
-                  x = a + b
+                  x = negateop + b
                   y = -x .
                 This pushes down the negate which we possibly can merge
                 into some other operation, hence insert it into the
                 plus_negates vector.  */
              gimple *feed = SSA_NAME_DEF_STMT (negate);
-             tree a = gimple_assign_rhs1 (feed);
              tree b = gimple_assign_rhs2 (user);
              gimple_stmt_iterator gsi = gsi_for_stmt (feed);
              gimple_stmt_iterator gsi2 = gsi_for_stmt (user);
              tree x = make_ssa_name (TREE_TYPE (gimple_assign_lhs (feed)));
-             gimple *g = gimple_build_assign (x, PLUS_EXPR, a, b);
+             gimple *g = gimple_build_assign (x, PLUS_EXPR, negateop, b);
              gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
              gimple_assign_set_rhs_with_ops (&gsi2, NEGATE_EXPR, x);
              user = gsi_stmt (gsi2);
@@ -6032,13 +6035,11 @@ repropagate_negates (void)
            }
          else
            {
-             /* Transform "x = -a; y = b - x" into "y = b + a", getting
-                rid of one operation.  */
-             gimple *feed = SSA_NAME_DEF_STMT (negate);
-             tree a = gimple_assign_rhs1 (feed);
+             /* Transform "x = -negateop; y = b - x" into "y = b + negateop",
+                getting rid of one operation.  */
              tree rhs1 = gimple_assign_rhs1 (user);
              gimple_stmt_iterator gsi = gsi_for_stmt (user);
-             gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, rhs1, a);
+             gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, rhs1, negateop);
              update_stmt (gsi_stmt (gsi));
            }
        }