SCEV analysis requires us to be in loop-closed SSA form to be able to compute overall effects of inner loops when required. Unfortunately we have too many places it is used where we are not in loop-closed SSA form. The following patch makes us more conservative in two places where we previously ICEd.
I'm not 100% sure we'll get away w/ not being in loop-closed SSA form (code correctness wise) but unless we get a testcase showing this the following is a sane approach (esp. on release branches). Bootstrap and regtest in progress on x86_64-unknown-linux-gnu. Richard. 2017-04-27 Richard Biener <rguent...@suse.de> PR middle-end/80539 * tree-chrec.c (chrec_fold_plus_poly_poly): Deal with not being in loop-closed SSA form conservatively. (chrec_fold_multiply_poly_poly): Likewise. * gcc.dg/torture/pr80539.c: New testcase. Index: gcc/tree-chrec.c =================================================================== --- gcc/tree-chrec.c (revision 247293) +++ gcc/tree-chrec.c (working copy) @@ -149,7 +149,12 @@ chrec_fold_plus_poly_poly (enum tree_cod /* This function should never be called for chrecs of loops that do not belong to the same loop nest. */ - gcc_assert (loop0 == loop1); + if (loop0 != loop1) + { + /* It still can happen if we are not in loop-closed SSA form. */ + gcc_assert (! loops_state_satisfies_p (LOOP_CLOSED_SSA)); + return chrec_dont_know; + } if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR) { @@ -211,7 +216,12 @@ chrec_fold_multiply_poly_poly (tree type chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1), CHREC_RIGHT (poly0)); - gcc_assert (loop0 == loop1); + if (loop0 != loop1) + { + /* It still can happen if we are not in loop-closed SSA form. */ + gcc_assert (! loops_state_satisfies_p (LOOP_CLOSED_SSA)); + return chrec_dont_know; + } /* poly0 and poly1 are two polynomials in the same variable, {a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */ Index: gcc/testsuite/gcc.dg/torture/pr80539.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr80539.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr80539.c (working copy) @@ -0,0 +1,22 @@ +/* { dg-do compile } */ + +signed char a, b; +void fn1() +{ + signed char c, e; + short d; + if (0) { + for (; d;) { +l1: + for (c = 7; a; c++) + ; + e = 6; + for (; b; e++) + ; + } + c -= e; + } + if (d == 7) + goto l1; + a = c; +}