[LLVMdev] Proposal for Poison Semantics
David Majnemer
david.majnemer at gmail.com
Wed Feb 4 18:07:05 PST 2015
On Wed, Feb 4, 2015 at 5:47 PM, Sanjoy Das <sanjoy at playingwithpointers.com>
wrote:
> > Turns out that undef + fast math flags is enough to cause LLVM to become
> > inconsistent:
> > define i1 @f(i1 %a.is_nan, float %a, float %b) {
> > %add = fadd nnan float %a, %b
> > %sel = select i1 %a.is_nan, float undef, float %add
> > %cmp = fcmp ord float %b, %sel
> > ret i1 %cmp
> > }
> >
> > When 'b' is NaN, the following occurs:
> > %add = float undef
> > %sel = float undef
> > %cmp = i1 false
> >
> > However, the 'select i1 %A, %B, undef' -> 'undef' optimization permits
> us to
>
> How can you transform 'select X, Y, undef' to undef? What if X is
> true? Did you mean 'select X, undef, undef' -> undef?
>
Sorry, I meant 'select X, Y, undef' to 'Y'
>
> > transform @f to:
> > define i1 @f(i1 %a.is_nan, float %a, float %b) {
> > %add = fadd nnan float %a, %b
> > %cmp = fcmp ord float %add, 0.000000e+00
>
> I don't see how you got here -- %cmp was "fcmp ord float %b, %sel".
> Now %b is NaN so %add is undef, making %cmp = "fcmp ord NaN, undef"
> which is false for any value of undef.
>
Just to be clear, I agree. This is why I said that %cmp = i1 false in the
untransformed @f.
>
> Maybe I'm being thick, but I think it will help if you break down the
> second half of your argument into smaller steps. :)
>
We start with:
define i1 @f(i1 %a.is_nan, float %a, float %b) {
%add = fadd nnan float %a, %b
%sel = select i1 %a.is_nan, float undef, float %add
%cmp = fcmp ord float %b, %sel
ret i1 %cmp
}
LLVM (currently) permits 'select i1 %a.is_nan, float undef, float %add' to
turn into '%add', this leaves us with:
define i1 @f(i1 %a.is_nan, float %a, float %b) {
%add = fadd nnan float %a, %b
%cmp = fcmp ord float %b, %add
ret i1 %cmp
}
'fadd nnan' claims that it is allowed to assume that its operands can't be
NaN and that those which value depend on the value will not get NaN. I
believe this would let 'fcmp' assume that it only needs to look at the
result of '%add':
define i1 @f(i1 %a.is_nan, float %a, float %b) {
%add = fadd nnan float %a, %b
%cmp = fcmp ord float 0., %add
ret i1 %cmp
}
> Having said that I won't be surprised if fast-math flags suffer from
> issues similar to poison -- "Allow algebraically equivalent
> transformations that may dramatically change results in floating
> point" sounds somewhat vague to me.
>
> -- Sanjoy
>
> > ret i1 %cmp
> > }
> >
> > Now we will have:
> > %add = float undef
> > %cmp = i1 undef
> >
> >
> >>
> >>
> >>
> >> John
> >
> >
> >
> > _______________________________________________
> > LLVM Developers mailing list
> > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150204/bca71788/attachment.html>
More information about the llvm-dev
mailing list