https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81897
--- Comment #8 from Jeffrey A. Law <law at redhat dot com> --- This really looks like something tree-ssa-uninit.c ought to be handling too. [ Just to be clear we should fix both tree-ssa-uninit.c the cfgcleanup. ] We have a PHI with a default definition on the RHS: <bb 4> [local count: 182536114]: # dst_32 = PHI <dst_7(D)(18), dst_9(20)> __warned = 1; if (fibmatch_6 != 0) goto <bb 13>; [0.00%] else goto <bb 14>; [100.00%] So if you dump the CFG and analyze the path you'll find that the only way to traverse the edge 18->4 has a series of predicates, *all* of which must be true to ever reach 18->4. Yet the predicate analysis bits only analyze the last predicate in the path: [WORKLIST]: add to initial list: dst_32 = PHI <dst_7(D)(18), dst_9(20)> [CHECK]: examining phi: dst_32 = PHI <dst_7(D)(18), dst_9(20)> [BEFORE SIMPLICATION -- [DEF]: is guarded by : _19 == 0 [BEFORE NORMALIZATION --[DEF]: is guarded by : _19 == 0 [AFTER NORMALIZATION -- [DEF]: is guarded by : _19 == 0 I think that's because our choice for where to start the predicate analysis for the def of a PHI arg is terrible. We look at the domiantor of e->src: /* Build the control dependency chain for uninit operand `i'... */ uninit_preds = vNULL; if (!compute_control_dep_chain (find_dom (e->src), e->src, dep_chains, &num_chains, &cur_chain, &num_calls)) I'm not sure why it's done that way. THere's no reason we can't go all the way back to the entry block here (note there's some lameness in compute_control_dep_chain that needs to be worked around -- you can't just slam ENTRY_BLOCK_PTR in there). But fixing that still doesn't resolve the problem, but gives us a shot at actually seeing a full predicate chain -- which would include the predicate from bb2: <bb 2> [local count: 1073741825]: fibmatch_6 = f (); if (fibmatch_6 == 0) goto <bb 3>; [33.00%] else goto <bb 7>; [67.00%] We care about the 2-->7 edge here. ie, the *only* way to traverse the 18->4 edge is to first have traversed the 2->7 edge which occurs when fibmatch_6 != 0. That's the def side. Now looking at the use side. <bb 4> [local count: 182536114]: # dst_32 = PHI <dst_7(D)(18), dst_9(20)> __warned = 1; if (fibmatch_6 != 0) goto <bb 13>; [0.00%] else goto <bb 14>; [100.00%] <bb 14> [local count: 182536114]: goto <bb 6>; [100.00%] <bb 13> [local count: 0]: <bb 5> [local count: 536870912]: <bb 6> [local count: 1073741825]: # dst_2 = PHI <dst_9(16), 0(5), dst_9(12), dst_32(14), dst_9(21)> return dst_2; So given that the only way we ever traverse 18->4 is when fibmatch_6 != 0 which implies that we always traverse 4->13->5->6 and on that path we never use dst_32.