http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58417
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |sebpop at gmail dot com --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- SCCP does "constant propagation" each SSA name at the beginning which is where it replaces sum_23 with 0. It ends up there through interpret_condition_phi with respect to loop 0 which analyzes the scalar evolution of sum_11 in loop 1 to 0 because it simply passes down the loop #2 0x0000000000c417c2 in interpret_condition_phi (loop=0x7ffff6d13320, condition_phi=<gimple_phi 0x7ffff6e48200>) at /space/rguenther/src/svn/trunk/gcc/tree-scalar-evolution.c:1585 1585 (loop, PHI_ARG_DEF (condition_phi, i)); (gdb) l 1580 res = chrec_dont_know; 1581 break; 1582 } 1583 1584 branch_chrec = analyze_scalar_evolution 1585 (loop, PHI_ARG_DEF (condition_phi, i)); 1586 1587 res = chrec_merge (res, branch_chrec); 1588 } that is, this is a loop-closed PHI node, not a "condition PHI". The SSA edge following code seems to have the same issues. That is, if an edge into a PHI is coming from an inner loop then we need to compute the evolution of the PHI arg with respect to that (the definition loop) and compute the overall effects for that inner loop before using the result. Hm, but analyzing sum_11 in loop1 results in _10 = {0, +, _9}_1 prevsum_21 = {0, +, _9}_1 and thus sum_11 = _10 - prevsum_21 = 0. Hmm. I don't think that's a valid CHREC (_9 is defined in loop 1). And indeed resolve_mixers will drop those to scev_not_known. But it doesn't get to that as we first cancel the thing by doing the minus ... So, Index: tree-scalar-evolution.c =================================================================== --- tree-scalar-evolution.c (revision 202619) +++ tree-scalar-evolution.c (working copy) @@ -1699,6 +1699,8 @@ interpret_rhs_expr (struct loop *loop, g chrec2 = analyze_scalar_evolution (loop, rhs2); chrec1 = chrec_convert (type, chrec1, at_stmt); chrec2 = chrec_convert (type, chrec2, at_stmt); + chrec1 = resolve_mixers (loop, chrec1); + chrec2 = resolve_mixers (loop, chrec2); res = chrec_fold_minus (type, chrec1, chrec2); break; fixes this, but ... I suppose we need to do that for each binary/ternary op and chrec (or just those that call chrec_fold_{plus,minus}). That said, we cannot hope on such SSA names canceling themselves out as they may not refer to the same actual value.