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 :/

Reply via email to