This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][4.2] Fix PR32500, wrong code with VRP (number of iterations analysis)


This fixes PR32500 where we incorrectly derive a number of iterations from
undefined conditions in a basic block that is not always executed.  Fixed
by backporting from mainline the check that restricts this to blocks that
are always executed.  I didn't backport the rewrite of number of 
iterations analysis to still use them for a hint though.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the
4.2 branch, testcase added to trunk as well.

Richard.

2007-07-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/32500
	* tree-ssa-loop-niter.c (infer_loop_bounds_from_undefined):
	Only use basic blocks that are always executed to infer loop bounds.

	* gcc.c-torture/execute/pr32500.c: New testcase.

Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 126260)
--- tree-ssa-loop-niter.c	(working copy)
*************** infer_loop_bounds_from_undefined (struct
*** 1747,1752 ****
--- 1747,1758 ----
      {
        bb = bbs[i];
  
+       /* If BB is not executed in each iteration of the loop, we cannot
+ 	 use the operations in it to infer reliable upper bound on the
+ 	 # of iterations of the loop.  */
+       if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
+ 	continue;
+ 
        for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
          {
  	  tree stmt = bsi_stmt (bsi);
Index: testsuite/gcc.c-torture/execute/pr32500.c
===================================================================
*** testsuite/gcc.c-torture/execute/pr32500.c	(revision 0)
--- testsuite/gcc.c-torture/execute/pr32500.c	(revision 0)
***************
*** 0 ****
--- 1,26 ----
+ extern void abort(void);
+ extern void exit(int);
+ void foo(int) __attribute__((noinline));
+ void bar(void) __attribute__((noinline));
+ 
+ /* Make sure foo is not inlined or considered pure/const.  */
+ int x;
+ void foo(int i) { x = i; }
+ void bar(void) { exit(0); }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+ 	int i;
+ 	int numbers[4] = { 0xdead, 0xbeef, 0x1337, 0x4242 };
+ 
+ 	for (i = 1; i <= 12; i++) {
+ 		if (i <= 4)
+ 			foo(numbers[i]);
+ 		else if (i >= 7 && i <= 9)
+ 			bar();
+ 	}
+ 
+ 	abort();
+ }
+ 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]