https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101674
--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> --- uninit analysis has the guarding condition r_14(D) <= 18 but the guard of the PHI is computed in non-optimal way since this is a PHI use of a PHI with an uninitialized val on an edge but the paths we construct in predicate::use_cannot_happen only consider the second PHI uninit edge. bb 12: # v_31 = PHI <v_30(D)(10), v_13(D)(11)> ... bb 14: # v_32 = PHI <v_31(23), r_14(D)(19)> .. = blah (v_32); when we visit v_31 we determine an uninit use in v_32 on the 23->14 edge and queue that PHI for analysis where we then find the blah (v_32) use. But this queueing forgets that the paths that guard this uninit use PHI def need all go through 12 -> 11. The code in tree-ssa-uninit.cc does this, so the gimple-predicate-analysis.cc code doesn't know anything about this. That's a weakness in the API, predicate::is_use_guarded (the API is somewhat awkward generally). It might be we want the path from BB 12 through BB 14 to the use in the 'use_preds' or like suggested above in the def preds instead. When the put it into the 'use_preds' we get r_14(D) <= 18 && _7 != 0 && l_18(D) > 100 where we fail to open-code _7 (defined as _1 & _6). At least we then get the proper PHI def chain into the uninit use edge so such change alone would be a correctness improvement here. Now, we do pick up the definition of _1 & _6 but only after normalization which we apply to the predicate of the PHI def but not to the predicate of the use until after the use_cannot_happen test is complete. But one issue is that normalization does nothing to !((_1 & _2) != 0) which would be !(_1 != 0) | !(_2 != _0) but we don't do anything to that in the chain normalization case (we'd need to duplicate here). The single pred case would also not do this because of the is_neq_zero_form_p guard. Not to say that the use_preds.use_cannot_happen case looks awfully similar to the superset_of. The main difference seems to be that init_from_phi_def picks up a PHI def predicate starting only from the immediate dominator while use_cannot_happen tries to build "fancy" predicates starting from function entry. And some use m_eval to compute 'opnds' while others use the mask passed in to is_use_guarded. The code is somewhat of a mess here. It's all mightly complicated but limited at the same time :/