When a optimization pass in the loop pipeline moves stmts between loops or removes loops we have to reset the SCEV cache to not have stale CHREC_LOOPs. This patch does it for loop distribution for which I have a testcase.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2015-01-13 Richard Biener <rguent...@suse.de> PR tree-optimization/64406 * tree-loop-distibution.c (pass_loop_distribution::execute): Reset the SCEV hashtable if we distributed anything. * gcc.dg/pr64406.c: New testcase. Index: gcc/tree-loop-distribution.c =================================================================== --- gcc/tree-loop-distribution.c (revision 219520) +++ gcc/tree-loop-distribution.c (working copy) @@ -1838,6 +1851,9 @@ out: if (changed) { + /* Cached scalar evolutions now may refer to wrong or non-existing + loops. */ + scev_reset_htab (); mark_virtual_operands_for_renaming (fun); rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); } Index: gcc/testsuite/gcc.dg/pr64406.c =================================================================== --- gcc/testsuite/gcc.dg/pr64406.c (revision 0) +++ gcc/testsuite/gcc.dg/pr64406.c (working copy) @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-loop-distribute-patterns -fno-tree-loop-ivcanon -fno-tree-loop-vectorize -ftree-vectorize" } */ + +unsigned in[72]; + +void bar (unsigned out[], unsigned ia[]); + +void +foo () +{ + int i; + unsigned out[72], ia[8]; + for (i = 0; i < 8; i++) + { + out[i * 8] = in[i * 8] + 5; + out[i * 8 + 1] = in[i * 8 + 1] + 6; + out[i * 8 + 2] = in[i * 8 + 2] + 7; + out[i * 8 + 3] = in[i * 8 + 3] + 8; + out[i * 8 + 4] = in[i * 8 + 4] + 9; + out[i * 8 + 5] = in[i * 8 + 5] + 10; + out[i * 8 + 6] = in[i * 8 + 6] + 11; + out[i * 8 + 7] = in[i * 8 + 7] + 12; + ia[i] = in[i]; + } + bar (out, ia); +}