https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86732
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2018-07-30 CC| |law at gcc dot gnu.org, | |rguenth at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- We have the isolate-errorneous-paths pass which does: example (const int & a) { int _3; int _4; const int * _5; const int * _6; int _7; <bb 2> [local count: 1073741825]: _3 = *a_2(D); if (_3 == 0) goto <bb 3>; [100.00%] else goto <bb 4>; [0.00%] <bb 3> [local count: 598933193]: # _5 = PHI <a_2(D)(2)> _4 = *_5; return _4; <bb 4> [count: 0]: # _6 = PHI <0B(2)> _7 ={v} *_6; __builtin_trap (); } note how it doesn't eliminate the actual load which probably causes the odd code-generation. Nothing removes it afterwards because it may (and will!) trap. Then isolate-errorneus-paths runs a bit late so the next CSE pass to CSE *a_2(D) and *_5 is PRE. But we still end up with the following in the end, keeping the condition live. As Marc said the condition would be only dead if we'd use __builtin_unreachable () rather than __builtin_trap () here which has security implications. But the load doesn't need to be there. <bb 2> [local count: 1073741825]: _3 = *a_2(D); if (_3 == 0) goto <bb 3>; [100.00%] else goto <bb 4>; [0.00%] <bb 3> [local count: 598933193]: return _3; <bb 4> [count: 0]: _7 ={v} MEM[(const int *)0B]; __builtin_trap ();