[PATCH] Fix PR70288

Richard Biener rguenther@suse.de
Fri Mar 18 11:41:00 GMT 2016


The following fixes excessive compile-time and memory-usage needed to
build the testcases which is caused by severe mis-calculation of
size-after-unrolling because it simply assumes that conditionals
with is_gimple_min_invariant ops can be folded to a constant.
This is not always true, like for

 int a[1], b[1];
 if (a < b)
   ...

which causes the testcase to explode.  The easiest fix is to look
for a change in constness due to peeling rather than only
constness.

Of course in the end we want to fold these (and comparing
&a[i] < &b[i] will run into the issue even w/o the fix).  But it
is not clear to me to what we should simplify the compare - replacing
it with __builtin_trap () might be best I suppose but I'm sure
it will break things out in the wild in interesting ways.  Not
optimizing is a better choice here IMHO.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-03-18  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/70288
	* tree-ssa-loop-ivcanon.c (tree_estimate_loop_size): Make sure
	we do not estimate unsimplified all-constant conditionals or
	switches as optimized away.

	* gcc.dg/torture/pr70288-1.c: New testcase.
	* gcc.dg/torture/pr70288-2.c: Likewise.

Index: gcc/tree-ssa-loop-ivcanon.c
===================================================================
*** gcc/tree-ssa-loop-ivcanon.c	(revision 234320)
--- gcc/tree-ssa-loop-ivcanon.c	(working copy)
*************** tree_estimate_loop_size (struct loop *lo
*** 298,308 ****
  	  /* Conditionals.  */
  	  else if ((gimple_code (stmt) == GIMPLE_COND
  		    && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
! 		    && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop))
  		   || (gimple_code (stmt) == GIMPLE_SWITCH
  		       && constant_after_peeling (gimple_switch_index (
  						    as_a <gswitch *> (stmt)),
! 						  stmt, loop)))
  	    {
  	      if (dump_file && (dump_flags & TDF_DETAILS))
  	        fprintf (dump_file, "   Constant conditional.\n");
--- 298,314 ----
  	  /* Conditionals.  */
  	  else if ((gimple_code (stmt) == GIMPLE_COND
  		    && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
! 		    && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop)
! 		    /* We don't simplify all constant compares so make sure
! 		       they are not both constant already.  See PR70288.  */
! 		    && (! is_gimple_min_invariant (gimple_cond_lhs (stmt))
! 			|| ! is_gimple_min_invariant (gimple_cond_rhs (stmt))))
  		   || (gimple_code (stmt) == GIMPLE_SWITCH
  		       && constant_after_peeling (gimple_switch_index (
  						    as_a <gswitch *> (stmt)),
! 						  stmt, loop)
! 		       && ! is_gimple_min_invariant (gimple_switch_index (
! 						       as_a <gswitch *> (stmt)))))
  	    {
  	      if (dump_file && (dump_flags & TDF_DETAILS))
  	        fprintf (dump_file, "   Constant conditional.\n");
Index: gcc/testsuite/gcc.dg/torture/pr70288-1.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr70288-1.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr70288-1.c	(working copy)
***************
*** 0 ****
--- 1,36 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target int32plus } */
+ 
+ int main()
+ {
+   int var6 = -1267827473;
+   do {
+       ++var6;
+       double s1_115[4], s2_108[4];
+       int var8 = -161498264;
+       do {
+ 	  ++var8;
+ 	  int var12 = 1260960076;
+ 	  for (; var12 <= 1260960080; ++var12) {
+ 	      int var13 = 1960990937;
+ 	      do {
+ 		  ++var13;
+ 		  int var14 = 2128638723;
+ 		  for (; var14 <= 2128638728; ++var14) {
+ 		      int var22 = -1141190839;
+ 		      do {
+ 			  ++var22;
+ 			  if (s2_108 > s1_115) {
+ 			      int var23 = -890798748;
+ 			      do {
+ 				  ++var23;
+ 				  long long e_119[4];
+ 			      } while (var23 <= -890798746);
+ 			  }
+ 		      } while (var22 <= -1141190829);
+ 		  }
+ 	      } while (var13 <= 1960990946);
+ 	  }
+       } while (var8 <= -161498254);
+   } while (var6 <= -1267827462);
+ }
Index: gcc/testsuite/gcc.dg/torture/pr70288-2.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr70288-2.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr70288-2.c	(working copy)
***************
*** 0 ****
--- 1,35 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target int32plus } */
+ 
+ int main()
+ {
+   int var6 = -1267827473;
+   do {
+       ++var6;
+       double s1_115[4], s2_108[4];
+       int var8 = -161498264;
+       do {
+ 	  ++var8;
+ 	  int var12 = 1260960076;
+ 	  for (; var12 <= 1260960080; ++var12) {
+ 	      int var13 = 1960990937;
+ 	      do {
+ 		  ++var13;
+ 		  int var14 = 2128638723;
+ 		  for (; var14 <= 2128638728; ++var14) {
+ 		      int var22 = -1141190839;
+ 		      do {
+ 			  ++var22;
+ 			  if (s2_108 > s1_115) {
+ 			      int var23 = -890798748;
+ 			      do {
+ 				  long long e_119[4];
+ 			      } while (var23 <= -890798746);
+ 			  }
+ 		      } while (var22 <= -1141190829);
+ 		  }
+ 	      } while (var13 <= 1960990946);
+ 	  }
+       } while (var8 <= -161498254);
+   } while (var6 <= -1267827462);
+ }



More information about the Gcc-patches mailing list