diff mbox

Avoid (ab) SSA_NAMEs in reassoc (PR tree-optimization/79411)

Message ID 20170209195101.GP1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 9, 2017, 7:51 p.m. UTC
Hi!

This is a big hammer approach for (ab) SSA_NAME issues in reassoc, on
the following testcase we extend the lifetime of (ab) SSA_NAME and ICE
because it can't be coalesced anymore.  In theory we could try to be careful
and whenever changing something that could extend (ab) lifetime, instead
insert a non-(ab) SSA_NAME to copy the (ab) SSA_NAME to at the point of use
and then use the temporary later on, but after looking for a while, it would
mean changing way too many places, so this patch just punts on them or
stops linearing when seeing them, so the ops vectors should not contain
(ab) SSA_NAMEs, the various negations/undistributions etc. should also avoid
them etc.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-02-09  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/79411
	* tree-ssa-reassoc.c (is_reassociable_op): Return false if
	stmt operands are SSA_NAMEs used in abnormal phis.
	(can_reassociate_p): Return false if op is SSA_NAME used in abnormal
	phis.

	* gcc.c-torture/compile/pr79411.c: New test.


	Jakub

Comments

Richard Biener Feb. 10, 2017, 7:56 a.m. UTC | #1
On Thu, 9 Feb 2017, Jakub Jelinek wrote:

> Hi!
> 
> This is a big hammer approach for (ab) SSA_NAME issues in reassoc, on
> the following testcase we extend the lifetime of (ab) SSA_NAME and ICE
> because it can't be coalesced anymore.  In theory we could try to be careful
> and whenever changing something that could extend (ab) lifetime, instead
> insert a non-(ab) SSA_NAME to copy the (ab) SSA_NAME to at the point of use
> and then use the temporary later on, but after looking for a while, it would
> mean changing way too many places, so this patch just punts on them or
> stops linearing when seeing them, so the ops vectors should not contain
> (ab) SSA_NAMEs, the various negations/undistributions etc. should also avoid
> them etc.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

I suppose at the point we add the ability to associate undefined-overflow
ops (and have to be careful to not introduce new undefined-overflow cases)
we'll have enough infrastructure in place to improve on this.  Like
for undefined-overflow re-writing everything to unsigned arithmetic and
for the abnormal case inserting copies at the original point of uses.
(both less than ideal but working)

Thanks,
Richard.

> 2017-02-09  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/79411
> 	* tree-ssa-reassoc.c (is_reassociable_op): Return false if
> 	stmt operands are SSA_NAMEs used in abnormal phis.
> 	(can_reassociate_p): Return false if op is SSA_NAME used in abnormal
> 	phis.
> 
> 	* gcc.c-torture/compile/pr79411.c: New test.
> 
> --- gcc/tree-ssa-reassoc.c.jj	2017-01-24 23:29:09.000000000 +0100
> +++ gcc/tree-ssa-reassoc.c	2017-02-09 13:14:23.711878845 +0100
> @@ -605,7 +605,18 @@ is_reassociable_op (gimple *stmt, enum t
>    if (is_gimple_assign (stmt)
>        && gimple_assign_rhs_code (stmt) == code
>        && has_single_use (gimple_assign_lhs (stmt)))
> -    return true;
> +    {
> +      tree rhs1 = gimple_assign_rhs1 (stmt);
> +      tree rhs2 = gimple_assign_rhs1 (stmt);
> +      if (TREE_CODE (rhs1) == SSA_NAME
> +	  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
> +	return false;
> +      if (rhs2
> +	  && TREE_CODE (rhs2) == SSA_NAME
> +	  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2))
> +	return false;
> +      return true;
> +    }
>  
>    return false;
>  }
> @@ -4989,6 +5000,8 @@ static bool
>  can_reassociate_p (tree op)
>  {
>    tree type = TREE_TYPE (op);
> +  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
> +    return false;
>    if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
>        || NON_SAT_FIXED_POINT_TYPE_P (type)
>        || (flag_associative_math && FLOAT_TYPE_P (type)))
> --- gcc/testsuite/gcc.c-torture/compile/pr79411.c.jj	2017-02-09 13:34:06.016485562 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr79411.c	2017-02-09 13:33:53.000000000 +0100
> @@ -0,0 +1,22 @@
> +/* PR tree-optimization/79411 */
> +
> +typedef struct __jmp_buf_tag { char buf[1024]; } jmp_buf[1];
> +extern int setjmp (jmp_buf);
> +extern int bar (unsigned int *);
> +extern jmp_buf *baz (void);
> +struct C { int c1; unsigned int c2, c3, c4; };
> +
> +void
> +foo (struct C *x, const int *y, unsigned int *z, unsigned int e, unsigned int g)
> +{
> +  unsigned int d = 0;
> +  unsigned long f;
> +  setjmp (*baz ());
> +  f = 1 + d;
> +  if ((x->c1 || x->c2) && g && (!e || d >= 8))
> +    d = 16;
> +  else
> +    d = 8;
> +  if ((!x->c3 && !x->c4 || *y == 0) && !e && bar (z))
> +    *z = 1 + f;
> +}
> 
> 	Jakub
> 
>
diff mbox

Patch

--- gcc/tree-ssa-reassoc.c.jj	2017-01-24 23:29:09.000000000 +0100
+++ gcc/tree-ssa-reassoc.c	2017-02-09 13:14:23.711878845 +0100
@@ -605,7 +605,18 @@  is_reassociable_op (gimple *stmt, enum t
   if (is_gimple_assign (stmt)
       && gimple_assign_rhs_code (stmt) == code
       && has_single_use (gimple_assign_lhs (stmt)))
-    return true;
+    {
+      tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree rhs2 = gimple_assign_rhs1 (stmt);
+      if (TREE_CODE (rhs1) == SSA_NAME
+	  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
+	return false;
+      if (rhs2
+	  && TREE_CODE (rhs2) == SSA_NAME
+	  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2))
+	return false;
+      return true;
+    }
 
   return false;
 }
@@ -4989,6 +5000,8 @@  static bool
 can_reassociate_p (tree op)
 {
   tree type = TREE_TYPE (op);
+  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
+    return false;
   if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
       || NON_SAT_FIXED_POINT_TYPE_P (type)
       || (flag_associative_math && FLOAT_TYPE_P (type)))
--- gcc/testsuite/gcc.c-torture/compile/pr79411.c.jj	2017-02-09 13:34:06.016485562 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr79411.c	2017-02-09 13:33:53.000000000 +0100
@@ -0,0 +1,22 @@ 
+/* PR tree-optimization/79411 */
+
+typedef struct __jmp_buf_tag { char buf[1024]; } jmp_buf[1];
+extern int setjmp (jmp_buf);
+extern int bar (unsigned int *);
+extern jmp_buf *baz (void);
+struct C { int c1; unsigned int c2, c3, c4; };
+
+void
+foo (struct C *x, const int *y, unsigned int *z, unsigned int e, unsigned int g)
+{
+  unsigned int d = 0;
+  unsigned long f;
+  setjmp (*baz ());
+  f = 1 + d;
+  if ((x->c1 || x->c2) && g && (!e || d >= 8))
+    d = 16;
+  else
+    d = 8;
+  if ((!x->c3 && !x->c4 || *y == 0) && !e && bar (z))
+    *z = 1 + f;
+}