https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102703
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- There is a missed optimization at the gimple level for sure. if (d_11 > 1) goto <bb 5>; [59.00%] else goto <bb 4>; [41.00%] <bb 4> [local count: 391808389]: <bb 5> [local count: 955630225]: # iftmp.1_6 = PHI <0(3), 2(4)> c = iftmp.1_6; The store to c is removed by the time we get to fixup_cfg3 but the phi is around still: In .mergephi2: d_11 = (short unsigned int) a.4_5; if (d_11 > 1) goto <bb 5>; [59.00%] else goto <bb 4>; [41.00%] <bb 4> [local count: 391808389]: <bb 5> [local count: 955630225]: # iftmp.1_6 = PHI <0(3), 2(4)> _10 = a.4_5 & 65535; if (_10 == 0) goto <bb 6>; [50.00%] else goto <bb 8>; [50.00%] Then thread1 decides to thread based on the if statement for some unknown reason .... even if the first if statement was dead as the phi is dead. Maybe we need a quick DCE sometime right after forwprop2? But maybe jump threading should NOT happen here. Yes there is a missing jump threading at the gimple level with older versions too (but it is related to the problem here because of the added jump threading which was bogus). This is missed optimization for previous versions: d_11 = (short unsigned int) a.4_2; _10 = a.4_2 & 65535; _6 = d_11 != 0; _15 = _10 == 0; _1 = _6 & _15; The above is always false as we have (a&65535) == 0 && (a&65535) != .0