https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90348
--- Comment #7 from Michael Matz <matz at gcc dot gnu.org> --- No, this is not a problem in the stack slot sharing algorithm, but rather in the input. As presented to expand, and only showing the important parts, and reordering some BBs to make the flow more obvious: ;; basic block 2, loop depth 0 ;; pred: ENTRY _30 = (unsigned long) ∈ ivtmp.27_29 = _30 + 1; goto <bb 5>; [100.00%] So, 'in' becomes "live" here, it's address in _30 and _29. Fallthrough to bb5, which also uses in, but otherwise is uninteresting, except that it can reach only BBs 6 and 7: ;; basic block 5, loop depth 1 ... _2 = check_zero (&in, _31); if (_2 != 0) goto <bb 7>; [99.96%] else goto <bb 6>; [0.04%] bb6 is a no-return block, hence uninteresting. bb7 _is_ interesting in that it clobbers in: ;; basic block 7, loop depth 1 ;; pred: 5 in ={v} {CLOBBER}; if (i_11 != 5) goto <bb 8>; [83.33%] else goto <bb 9>; [16.67%] Note that the semantics of the clobber is not only that the former contents are destroyed, but rather that the very storage associated with the clobbered entity is gone. So, from now on, any pointers into 'in', and memory accesses into 'in' are invalid. Nevertheless the flow from bb7 goes to bb 8 and 9, the latter being the return block, so: ;; basic block 8, loop depth 1 ;; pred: 7 if (i_11 > 0) goto <bb 3>; [100.00%] else goto <bb 4>; [0.00%] and here we finally have a path into bb3, which is the other interesting one: ;; basic block 3, loop depth 2 # ivtmp.20_6 = PHI <_30(8), ivtmp.20_18(3)> .... BOOM! .... Here _30 is used, and ... _4 = (void *) ivtmp.20_6; MEM[base: _4, offset: 0B] = 0; ... even written into ... That's invalid. _30 is associated with an object that is clobbered and gone ... set_one (&buf); buf ={v} {CLOBBER}; ivtmp.20_18 = ivtmp.20_6 + 1; ... and as the MEM[] write can't have possibly been into 'in' (as that is invalid, as 'in' didn't exist at the MEM access), it's okay and sensible to allocate 'in' and 'buf' into the same memory. It seems to be a common misconception of what the clobber is really about. I designed it to mean what I wrote above, the storage associated with the clobbered entities is gone after the clobber (not merely it's former contents!). But ivopts or dom extends the lifetime of 'in' (by moving an address-taken earlier) and hence the lifetime of its storage, but without doing anything about the clobber (and hence not _really_ extending the lifetime). That doesn't work. It's basically a mirrored transformation of the usual take-address-of-local and access it out of it's declared scope, just that here the _start_ of the supposed lifetime is moved out of the declared scope, not the end.