[PATCH] Fix PR57326

Richard Biener rguenther@suse.de
Fri Aug 12 12:43:00 GMT 2016


On Fri, 12 Aug 2016, Richard Biener wrote:

> 
> The following fixes a missed optimization in PRE which was over-cautionous
> with rejecting simplifications to SSA names during phi-translation.
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Requires some testsuite adjustments as below as PRE now catches quite
some predictive commoning cases.

Tested on x86_64_unknown-linux-gnu, applied.

Richard.

2016-08-12  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/57326
	* tree-ssa-pre.c (fully_constant_expression): Handle simplification
	returning an SSA name.
	(phi_translate_1): When fully_constant_expression returns a NAME
	make sure we have a leader for it.

	* gcc.dg/tree-ssa/ssa-pre-32.c: New testcase.
	* gcc.dg/tree-ssa/loadpre14.c: Adjust.
	* gcc.dg/tree-ssa/pr35287.c: Likewise.
	* gcc.target/i386/pr45685.c: Likewise.
	* gcc.dg/tree-ssa/predcom-1.c: Disable PRE.
	* gcc.dg/tree-ssa/predcom-2.c: Likewise.
	* gcc.dg/tree-ssa/predcom-3.c: Likewise.
	* gcc.dg/tree-ssa/ssa-sink-10.c: Likewise.
	* gfortran.dg/pr34163.f90: Likewise.

Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 239361)
--- gcc/tree-ssa-pre.c	(working copy)
*************** get_or_alloc_expr_for (tree t)
*** 1201,1207 ****
  }
  
  /* Return the folded version of T if T, when folded, is a gimple
!    min_invariant.  Otherwise, return T.  */
  
  static pre_expr
  fully_constant_expression (pre_expr e)
--- 1201,1207 ----
  }
  
  /* Return the folded version of T if T, when folded, is a gimple
!    min_invariant or an SSA name.  Otherwise, return T.  */
  
  static pre_expr
  fully_constant_expression (pre_expr e)
*************** fully_constant_expression (pre_expr e)
*** 1218,1227 ****
  	  return e;
  	if (is_gimple_min_invariant (res))
  	  return get_or_alloc_expr_for_constant (res);
! 	/* We might have simplified the expression to a
! 	   SSA_NAME for example from x_1 * 1.  But we cannot
! 	   insert a PHI for x_1 unconditionally as x_1 might
! 	   not be available readily.  */
  	return e;
        }
      case REFERENCE:
--- 1218,1225 ----
  	  return e;
  	if (is_gimple_min_invariant (res))
  	  return get_or_alloc_expr_for_constant (res);
! 	if (TREE_CODE (res) == SSA_NAME)
! 	  return get_or_alloc_expr_for_name (res);
  	return e;
        }
      case REFERENCE:
*************** phi_translate_1 (pre_expr expr, bitmap_s
*** 1464,1470 ****
  	    constant = fully_constant_expression (expr);
  	    PRE_EXPR_NARY (expr) = nary;
  	    if (constant != expr)
! 	      return constant;
  
  	    tree result = vn_nary_op_lookup_pieces (newnary->length,
  						    newnary->opcode,
--- 1462,1481 ----
  	    constant = fully_constant_expression (expr);
  	    PRE_EXPR_NARY (expr) = nary;
  	    if (constant != expr)
! 	      {
! 		/* For non-CONSTANTs we have to make sure we can eventually
! 		   insert the expression.  Which means we need to have a
! 		   leader for it.  */
! 		if (constant->kind != CONSTANT)
! 		  {
! 		    unsigned value_id = get_expr_value_id (constant);
! 		    constant = find_leader_in_sets (value_id, set1, set2);
! 		    if (constant)
! 		      return constant;
! 		  }
! 		else
! 		  return constant;
! 	      }
  
  	    tree result = vn_nary_op_lookup_pieces (newnary->length,
  						    newnary->opcode,
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c	(working copy)
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-pre" } */
+ 
+ unsigned f(unsigned x, unsigned y, _Bool b)
+ {
+ #define m (b?-1:0)
+   return (x&m)|(y&~m);
+ #undef m
+ }
+ 
+ /* { dg-final { scan-tree-dump "# prephitmp_\[0-9\]+ = PHI <\[xy\]_\[0-9\]+\\(D\\)\[^,\]*, \[xy\]_\[0-9\]+\\(D\\)" "pre" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/loadpre14.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/loadpre14.c	(revision 239406)
+++ gcc/testsuite/gcc.dg/tree-ssa/loadpre14.c	(working copy)
@@ -6,7 +6,8 @@ int foo(type *a, int argc)
   type c = {0, 1};
   int d, e;
 
-  /* Should be able to eliminate the second load of *a along the main path. */
+  /* Should be able to eliminate the second load of *a and the add of zero
+     along the main path. */
   d = (*a)[0];
   if (argc)
     {
@@ -15,4 +16,4 @@ int foo(type *a, int argc)
   e = (*a)[0];
   return d + e;
 }
-/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */
Index: gcc/testsuite/gcc.dg/tree-ssa/pr35287.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr35287.c	(revision 239406)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr35287.c	(working copy)
@@ -10,5 +10,6 @@ int foo(int p)
   return (*gp + t);
 }
 
-/* We will eliminate one load of gp and one indirect load of *gp. */
-/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */
+/* We will eliminate one load of gp and one indirect load of *gp and
+   the add of zero. */
+/* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "pre"} } */
Index: gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c	(revision 239406)
+++ gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c	(working copy)
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-do run } */
-/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details" } */
+/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details -fno-tree-pre" } */
 
 void abort (void);
 
@@ -45,6 +45,6 @@ int main(void)
 /* Verify that both loops were transformed and unrolled.  */
 /* { dg-final { scan-tree-dump-times "Unrolling 2 times." 2 "pcom"} } */
 
-/* Also check that we undid the transformation previously made by PRE.  */
-/* { dg-final { scan-tree-dump-times "looparound ref" 1 "pcom"} } */
-
+/* Also check that we undid the transformation previously made by PRE.
+   ???  PRE now does the predictive commoning in count_averages.  */
+/* dg-final { scan-tree-dump-times "looparound ref" 1 "pcom" } */
Index: gcc/testsuite/gcc.dg/tree-ssa/predcom-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/predcom-2.c	(revision 239406)
+++ gcc/testsuite/gcc.dg/tree-ssa/predcom-2.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details" } */
+/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details -fno-tree-pre" } */
 
 void abort (void);
 
Index: gcc/testsuite/gcc.dg/tree-ssa/predcom-3.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/predcom-3.c	(revision 239406)
+++ gcc/testsuite/gcc.dg/tree-ssa/predcom-3.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details" } */
+/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details -fno-tree-pre" } */
 
 int a[1000], b[1000];
 
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c	(revision 239406)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-sink-details" } */
+/* { dg-options "-O2 -fdump-tree-sink-details -fno-tree-pre" } */
 
 int x[1024], y[1024], z[1024], w[1024];
 void foo (void)
Index: gcc/testsuite/gcc.target/i386/pr45685.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr45685.c	(revision 239406)
+++ gcc/testsuite/gcc.target/i386/pr45685.c	(working copy)
@@ -36,4 +36,4 @@ int summation_helper_2(int64_t* products
 	return s;
 }
 
-/* { dg-final { scan-assembler-times "cmov" 4 } } */
+/* { dg-final { scan-assembler-times "cmov" 6 } } */
Index: gcc/testsuite/gfortran.dg/pr34163.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr34163.f90	(revision 239406)
+++ gcc/testsuite/gfortran.dg/pr34163.f90	(working copy)
@@ -1,5 +1,5 @@
 ! { dg-do compile }
-! { dg-options "-O2 -fpredictive-commoning -fdump-tree-pcom-details" }
+! { dg-options "-O2 -fno-tree-pre -fpredictive-commoning -fdump-tree-pcom-details" }
 subroutine trisolve2(x,i1,i2,nxyz)
 integer :: nxyz
 real,dimension(nxyz):: au1



More information about the Gcc-patches mailing list