https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96722
Martin Liška <marxin at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|marxin at gcc dot gnu.org |unassigned at gcc dot gnu.org Status|ASSIGNED |NEW --- Comment #2 from Martin Liška <marxin at gcc dot gnu.org> --- So the problematic transformation happens in einline: BEFORE: void foo(S*) (struct S * a) { <bb 2> [0.00%] [count: INV]: if (a_2(D) != 0B) goto <bb 4>; [0.00%] [count: INV] else goto <bb 3>; [0.00%] [count: INV] <bb 3> [100.00%] [count: INV]: MEM[(struct &)a_2(D)] ={v} {CLOBBER}; <bb 4> [0.00%] [count: INV]: return; } after: void foo(S*) (struct S * a) { <bb 2> [0.00%] [count: INV]: if (a_2(D) != 0B) goto <bb 3>; [0.00%] [count: INV] else goto <bb 4>; [0.00%] [count: INV] <bb 3> [0.00%] [count: INV]: // predicted unlikely by early return (on trees) predictor. goto <bb 5>; [0.00%] [count: INV] <bb 4> [100.00%] [count: INV]: MEM[(struct &)a_2(D)] ={v} {CLOBBER}; <bb 5> [0.00%] [count: INV]: return; } So as seen, the CFG is more complex as there's an extra GIMPLE_PREDICT. main then inlines to: Scope blocks after cleanups: { Scope block #0 { Scope block #7 ../pr96722.C:8 Originating from : extern void S (struct S *, int); } { Scope block #8 ../pr96722.C:14 Originating from : extern void S (struct S *, int); } } int main() () { int _5; <bb 2> [100.00%] [count: INV]: _5 = 0; return _5; } No longer having address taken: s Scope blocks after cleanups: { Scope block #0 { Scope block #7 ../pr96722.C:8 Originating from : extern void S (struct S *, int); { Scope block #8 Originating from :#0 } } { Scope block #9 ../pr96722.C:14 Originating from : extern void S (struct S *, int); } } int main() () { int _5; <bb 2> [100.00%] [count: INV]: MEM[(struct &)0B] ={v} {CLOBBER}; _5 = 0; return _5; } So I bet it's hidden in a CFG cleanup where it somehow removes the clobber? I guess it was latent before my revision..