https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120236
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Ever confirmed|0 |1 --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- OK, so the issue is then LIM hoisting <bb 2> [local count: 118111600]: # PT = null _2 = c; which becomes available as CSE target in PRE and we then eventually elide the c.2_6 = c; *c.2_6 = 1; sequence because a store to 'null' is unnecessary. That said, -fno-move-loop-stores makes it easier to look at what LIM does. <bb 2> [local count: 118111600]: + # PT = null + _2 = c; + b.0_4 = b; goto <bb 5>; [100.00%] <bb 3> [local count: 955630224]: *d_12(D) = &c; - # PT = null - _2 = c; _3 = *_2; a = _3; - b.0_4 = b; if (b.0_4 != 0) goto <bb 4>; [0.00%] else The issue then still is that points-to analysis computed *d_13(D) = &c; # PT = null _1 = *d_13(D); # PT = null _2 = *_1; _3 = *_2; a = _3; b.0_4 = b; and DOM (aka CSE) made that *d_12(D) = &c; # PT = null _1 = &c; # PT = null _2 = c; _3 = *_2; a = _3; b.0_4 = b; so basically the points-to info is UB manifested but with CSE the code no longer has UB (but the points-to info is still there) and we hoist the code, making the UB target to CSE. Without DOM there's the dependence of the *d_13(D) load on the previous store, so nothing is hoisted. I don't see how to "fix" this. A hack would be to try fixing up things at the point we CSE the PT = null pointer with the later pointer with sensible points-to info. The most optimistic handling would intersect both sets, but the latter is # PT = nonlocal unit-escaped null { D.2832 } (nonlocal, escaped) c.2_6 = c; so we'd end up with 'null' this way. We could start cleaning points-to info whenever we clear flow-sensitive info. For the reason that, as seen in this case, we inject flow-sensitive info into the otherwise flow-insensitive solution by handling SSA default defs specially: /* For undefined SSA names return nothing. */ else if (!ssa_defined_default_def_p (t)) { cexpr.var = nothing_id; cexpr.type = SCALAR; cexpr.offset = 0; results->safe_push (cexpr); return; short of using pt_anything here and polluting all PHI induced default defs this way there's no solution.