[llvm-dev] SCCP is not always correct in presence of undef (+ proposed fix)

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Fri Dec 30 23:55:16 PST 2016


Hi Daniel,

On Fri, Dec 30, 2016 at 10:55 PM, Daniel Berlin <dberlin at dberlin.org> wrote:
>> Right, but we are talking about "when, in the intermediate state, can i
>> transform an undef to a different value".
>>
>> Remember you can only go down the lattice. So you can't make undef
>> constant, and then discover it's wrong, and go back up :)
>> IE  can't change phi undef, undef to constant value 50, , discover 50
>> doesn't work, and say, well actually, let's make it undef again for an
>> iteration :)

If the kind of simplification (I think) you've mentioned is allowed,
then I think even Davide's lattice is problematic.  Say we have:

loop:
  X = phi(entry: undef, loop: T)
  ...
  T = undef
  if C then br loop else br outside

When we first visit X then we'll compute its state as (Undef MEET
Unknown) = Undef.  My guess is that you're implying that the Undef
lattice state (or some other computation hanging off of it) can be
folded immediately to, say, 50, but once we mark the backedge as
executable we'll set it to undef (or mark it as 49)?  And both of
these are bad because you're making a non-monotonic transition?  Given
this, I'm not sure what prevents the bad transform from happening even
if we have separate Unknown and Undef states.

If the solution is to not fold X into undef (which, by assumption, can
"spontaneously decay" into any value) until you're sure every incoming
value is also undef then I suppose we'll need some special handling
for undef values to prevent breaking cases like (as shown earlier):

loop:
  X = phi(entry: 10, loop: T)
  if X == 10 then br outside else br loop

=>

loop:
  X = phi(entry: 10, loop: T)
  br outside

(i.e. to keep the algorithm properly optimistic)?

And if we do have a way of keeping undefs as undefs (i.e. prevent X
from decaying into 50 when we first visit the first loop) then why
can't we re-use the same mechanism to avoid spuriously decaying "phi
undef undef-but-actually-unknown" to "50"?

Another way of stating my suggestion is that, if you agree that this
is a correct lattice (different from Davide's proposal) and pretend
the "spontaneous undef decay" problem does not exist, then:

digraph G {
  Unknown -> Undef
  Undef -> Constant1
  Undef -> Constant2
  Undef -> Constant3
  Constant1 -> Bottom
  Constant2 -> Bottom
  Constant3-> Bottom
}

then it should be legal / correct to first drop every lattice element
from "Unknown" to "Undef" before running the algorithm.  The only
cases where this would give us a conservative result is a place where
we'd have otherwise gotten "Unknown" for a used value; and the
algorithm should never have terminated in such a state.

-- Sanjoy


More information about the llvm-dev mailing list