[llvm-dev] RFC: Killing undef and spreading poison

Nuno Lopes via llvm-dev llvm-dev at lists.llvm.org
Sun Oct 23 08:47:59 PDT 2016


> Nuno Lopes wrote:
> > Right, that's a very good point. We already have this problem today as well, though.
> > We can translate this into a select by using freeze, as you say (that's exactly for these cases why we are proposing to introduce freeze).
> > What we need to settle on, and we didn't touch this on our proposal, is how LLVM's analyses API will look like. Most (if not all) LLVM analyses today report a result that doesn't exclude that the value might be poison.  That's because if you report %v to be non-null and it's actually poison it's fine since poison can be restricted to be non-null. 
> >  We will need to introduce a isNotPoison() analysis and a
ensureIsNonPoison() utility (that needs to be used by all transformations doing speculation).
> > I would freeze %y. What's the argument against?
> 
> frozen %y can be zero if %x (and thus %y) is poison.
> 
> ensureIsNonPoison will have to work in concert with whatever inferred %y to be non-zero.

Ah, you're very right. Freeze(%y) is not sufficient.

I think the problem is not as bad as it may sound at first sight.  There are two important properties: 1) instructions return poison if given poison as input and 2) br poison is UB.  Therefore an analysis is allowed to say "%x | 1" is non-zero. If %x is poison, the result is poison and any transformed expression can be poison or return any non-poison value. If the expression is used later as a condition for branching, it would be UB to branch on poison, so it doesn't matter either.
So it seems to me that the cases that matter is when we hoist stuff past control-flow (e.g., loop unswitching, LICM, etc).  If we hoist a division out of a loop because some IsNonZero(divisor) analysis said it is fine, then I agree we need utils to ensure the value will indeed be non-zero.
Currently we don't hoist most divisions out of loops, so we are not making things worse. Going forward we would the utility functions just mentioned.  Not sure what the design of that would look like in general, if we develop separate IsNonZero + EnsureNonZero functions, or one combined function.
Another idea that popped my mind several times, but I've been trying to avoid is to attach metadata/constraints to freeze instructions.  If we do an optimization that requires the frozen value to be non-zero, leave a constraint there.  The problem (besides the added complexity) is that metadata and assume constraints right now can be discarded at will by optimizers, so correctness guarantees could be voided.

Nuno



More information about the llvm-dev mailing list