The following patch fixes a miscompilation due to bogus loop iteration bound derived from array accesses in an inner loop. idx_infer_loop_bounds analyzes the evoultion of an SSA name with respect to a loop it is not defined in - which seems to lead to random weird behavior. The correct thing to do (as documented) is to analyze the evolution with respect to the loop the stmt we are interested in is in.
Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu. Thanks, Richard. 2012-12-17 Richard Biener <rguent...@suse.de> PR tree-optimization/55555 * tree-ssa-loop-niter.c (idx_infer_loop_bounds): Properly analyze evolution of the index for the loop it is used in. * gcc.dg/torture/pr55555.c: New testcase. Index: gcc/tree-ssa-loop-niter.c =================================================================== *** gcc/tree-ssa-loop-niter.c (revision 194552) --- gcc/tree-ssa-loop-niter.c (working copy) *************** idx_infer_loop_bounds (tree base, tree * *** 2671,2677 **** upper = false; } ! ev = instantiate_parameters (loop, analyze_scalar_evolution (loop, *idx)); init = initial_condition (ev); step = evolution_part_in_loop_num (ev, loop->num); --- 2671,2682 ---- upper = false; } ! struct loop *dloop = loop_containing_stmt (data->stmt); ! if (!dloop) ! return true; ! ! ev = analyze_scalar_evolution (dloop, *idx); ! ev = instantiate_parameters (loop, ev); init = initial_condition (ev); step = evolution_part_in_loop_num (ev, loop->num); Index: gcc/testsuite/gcc.dg/torture/pr55555.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr55555.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr55555.c (working copy) *************** *** 0 **** --- 1,34 ---- + /* { dg-do run } */ + + double s[4] = { 1.0, 2.0, 3.0, 4.0 }, pol_x[2] = { 5.0, 6.0 }; + + __attribute__((noinline)) int + foo (void) + { + double coef_x[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int lxp = 0; + if (lxp <= 1) + do + { + double t = pol_x[lxp]; + long S; + long l = lxp * 4L - 1; + for (S = 1; S <= 4; S++) + coef_x[S + l] = coef_x[S + l] + s[S - 1] * t; + } + while (lxp++ != 1); + asm volatile ("" : : "r" (coef_x) : "memory"); + for (lxp = 0; lxp < 8; lxp++) + if (coef_x[lxp] != ((lxp & 3) + 1) * (5.0 + (lxp >= 4))) + __builtin_abort (); + return 1; + } + + int + main () + { + asm volatile ("" : : : "memory"); + if (!foo ()) + __builtin_abort (); + return 0; + }