https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100359
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Indeed: -Setting value number of a.0_1 to &b (changed) +Setting value number of a.0_1 to a.0_1 (changed) +Using extra use virtual operand .MEM_39 +Making available beyond BB2 a.0_1 for value a.0_1 ... Setting value number of _3 to &b (changed) Value numbering stmt = _4 = *_3; -Setting value number of _4 to 0 (changed) +Setting value number of _4 to _4 (changed) +Making available beyond BB2 _4 for value _4 Value numbering stmt = if (_4 != 0) -marking known outgoing edge 2 -> 5 executable and the IL difference is just <bb 2> [local count: 1073741824]: f = 0; a = &b; - c.2_18 = c; - *c.2_18 = &b; + j ={v} {CLOBBER}; + c.2_40 = c; + *c.2_40 = &b; f = 1; a.0_1 = a; *a.0_1 = 0; note that 'a' is ESCAPED and _18/_40 point to ESCAPED. So what doesn't work with the CLOBBER is /* If we reach a clobbering statement try to skip it and see if we find a VN result with exactly the same value as the possible clobber. In this case we can ignore the clobber and return the found value. */ in vn_reference_lookup_3 because that does a non-walking lookup. I think we have a duplicate report for this exact issue somewhere. The clobber is removed at -O2 as part of the useless vars removal before stdarg. DCE2 leaves us with <bb 4> [local count: 8687547609]: - a = &b; + j[0] = &b; + _13 = j[0]; + a = _13; j ={v} {CLOBBER}; so we have stray uses left with -O3 which is ultimatively because cunrolli unrolls only the outer loop with -O3!? Ah, the reason is try_unroll_loop_completely has /* See if we can improve our estimate by using recorded loop bounds. */ if ((allow_peel || maxiter == 0 || ul == UL_NO_GROWTH) && maxiter >= 0 && (!n_unroll_found || (unsigned HOST_WIDE_INT)maxiter < n_unroll)) { n_unroll = maxiter; n_unroll_found = true; /* Loop terminates before the IV variable test, so we cannot remove it in the last iteration. */ edge_to_cancel = NULL; } but with -O3 we have !allow_peel and ul == UL_ALL (and maxiter == 1), niter is unknown. I changed this with g:a52206ae28ed3e55d601118bedd52739456401ab but the intent there was clearly to allow the peeling if we restrict the cases to UL_NO_GROWTH, not to disallow it with UL_ALL.