diff mbox series

tree-optimization/105163 - abnormal SSA coalescing and reassoc

Message ID 20220406083301.3386313A8E@imap2.suse-dmz.suse.de
State New
Headers show
Series tree-optimization/105163 - abnormal SSA coalescing and reassoc | expand

Commit Message

Richard Biener April 6, 2022, 8:33 a.m. UTC
The negate propagation optimizations in reassoc did not look out for
abnormal SSA coalescing issues.  The following fixes that.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

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 | 17 +++++++++++++++++
 gcc/tree-ssa-reassoc.cc                 | 25 +++++++++++++------------
 2 files changed, 30 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr105163.c
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr105163.c b/gcc/testsuite/gcc.dg/torture/pr105163.c
new file mode 100644
index 00000000000..23e04107f68
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr105163.c
@@ -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;
+}
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 7ee50946556..0d55fc7e2d8 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -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));
 	    }
 	}