[llvm-dev] how to simplify FP ops with an undef operand?
Simon Pilgrim via llvm-dev
llvm-dev at lists.llvm.org
Wed Feb 28 14:55:10 PST 2018
It'd be great if we can get all of this properly documented in the
LangRef - we often seem to be relying on comments next to the individual
combines to guide us in many of these cases.
If we're going to be using isKnownNeverNaN to support this - the
SelectionDAG version needs a bit of improvement for better vector
handling etc. to match the ValueTracking version.
On 28/02/2018 22:45, Sanjay Patel via llvm-dev wrote:
> Ah, thanks for explaining. So given that any of these ops will return
> NaN with a NaN operand, let's choose the undef operand value to be
> NaN. That means we can fold all of these to a NaN constant in the
> general case.
>
> But if we have 'nnan' FMF, then we can fold harder to undef?
> nnan - Allow optimizations to assume the arguments and result are not
> NaN. Such optimizations are required to retain defined behavior over
> NaNs, but the value of the result is undefined.
>
> On Wed, Feb 28, 2018 at 3:25 PM, Kaylor, Andrew
> <andrew.kaylor at intel.com <mailto:andrew.kaylor at intel.com>> wrote:
>
> What I’m saying is that if we have one operand that is not an
> undef value then that operand might be NaN and if it is then the
> result must be NaN. So while it may be true that we don’t have a
> NaN, it is not true that we definitely do not have a NaN in the
> example. This is analogous to the example in the language
> reference where it says “%A = or %X, undef” -> “%A = undef” is
> unsafe because any bits that are set in %A must be set in the
> result. If any floating point operand is NaN dynamically, then the
> result must be NaN.
>
> I don’t believe it’s accurate to say that NaN is “morally
> equivalent” to undef. There are some similarities, but the
> important difference is that NaN always has well defined behavior
> with a specific correct result. There is, perhaps, a sense in
> which it is analogous to a poison value, but for the purposes of
> reasoning about the correctness of floating point operations I
> think it’s best to be pedantic about treating it as the specific
> value that it is.
>
> Finally, I was pretty sure you knew that fdiv by zero wasn’t
> undefined. I just wanted to clarify that the “?” in your comment
> was indicating that the assertion in the language reference was
> questionable as opposed to this point being in any way actually
> uncertain.
>
> *From:*Sanjay Patel [mailto:spatel at rotateright.com
> <mailto:spatel at rotateright.com>]
> *Sent:* Wednesday, February 28, 2018 1:05 PM
> *To:* Kaylor, Andrew <andrew.kaylor at intel.com
> <mailto:andrew.kaylor at intel.com>>
> *Cc:* llvm-dev <llvm-dev at lists.llvm.org
> <mailto:llvm-dev at lists.llvm.org>>; Nuno Lopes <nunoplopes at sapo.pt
> <mailto:nunoplopes at sapo.pt>>; Stephen Canon <scanon at apple.com
> <mailto:scanon at apple.com>>; David Majnemer
> <david.majnemer at gmail.com <mailto:david.majnemer at gmail.com>>; John
> Regehr <regehr at cs.utah.edu <mailto:regehr at cs.utah.edu>>; Sanjoy
> Das <sanjoy at playingwithpointers.com
> <mailto:sanjoy at playingwithpointers.com>>; Friedman, Eli
> <efriedma at codeaurora.org <mailto:efriedma at codeaurora.org>>; Matt
> Arsenault <arsenm2 at gmail.com <mailto:arsenm2 at gmail.com>>;
> Kreitzer, David L <david.l.kreitzer at intel.com
> <mailto:david.l.kreitzer at intel.com>>
>
>
> *Subject:* Re: how to simplify FP ops with an undef operand?
>
> Correct - NaN is not undef in IR. But we don't have a NaN in this
> example. We have its moral equivalent in LLVM - an uninitialized
> value, undef.
>
> So we're not introducing any extra uncertainty by propagating the
> undef. The backend can choose whatever encoding of undef makes
> sense when lowering?
>
> And yes, I don't know why FP-div-by-zero would ever be UB. I think
> that text in the LangRef should be removed regardless of any other
> outcome here.
>
> On Wed, Feb 28, 2018 at 1:18 PM, Kaylor, Andrew
> <andrew.kaylor at intel.com <mailto:andrew.kaylor at intel.com>> wrote:
>
> Why is NaN “just ‘undef’ in IR”? NaN is a specific value with
> well-defined behavior. I would think that unless the no-NaNs
> flag is used we need to preserve the behavior of NaNs.
>
> *From:*Sanjay Patel [mailto:spatel at rotateright.com
> <mailto:spatel at rotateright.com>]
> *Sent:* Wednesday, February 28, 2018 12:08 PM
> *To:* Kaylor, Andrew <andrew.kaylor at intel.com
> <mailto:andrew.kaylor at intel.com>>
> *Cc:* llvm-dev <llvm-dev at lists.llvm.org
> <mailto:llvm-dev at lists.llvm.org>>; Nuno Lopes
> <nunoplopes at sapo.pt <mailto:nunoplopes at sapo.pt>>; Stephen
> Canon <scanon at apple.com <mailto:scanon at apple.com>>; David
> Majnemer <david.majnemer at gmail.com
> <mailto:david.majnemer at gmail.com>>; John Regehr
> <regehr at cs.utah.edu <mailto:regehr at cs.utah.edu>>; Sanjoy Das
> <sanjoy at playingwithpointers.com
> <mailto:sanjoy at playingwithpointers.com>>; Friedman, Eli
> <efriedma at codeaurora.org <mailto:efriedma at codeaurora.org>>;
> Matt Arsenault <arsenm2 at gmail.com <mailto:arsenm2 at gmail.com>>
> *Subject:* Re: how to simplify FP ops with an undef operand?
>
> Yes, if %x is a NaN, we should expect that NaN is propagated.
>
> I'm still not sure what to do here. We can take comfort in
> knowing that whatever we do is likely an improvement over the
> current situation though. :)
>
> That's because the code in InstSimplify is inconsistent with
> the LangRef:
> http://llvm.org/docs/LangRef.html#undefined-values
> <http://llvm.org/docs/LangRef.html#undefined-values> (UB for
> fdiv by 0?)
>
> ...and both of those are inconsistent with undef handling in SDAG.
>
> Let me propose an alternate interpretation:
>
> 1. The meaning of snan as written in IEEE754-2008 is:
> "Signaling NaNs afford representations for uninitialized
> variables..."
> 2. That matches our intent with 'undef' here in IR as written
> in the LangRef: "unspecified bit-pattern".
> 3. The current fdiv transform is actually correct (any SNaN
> UB/trapping commentary is irrelevant because we assume
> exceptions are off by default).
>
> The undef operand represents an uninitialized variable, and
> the result of any FP op with that uninitialized variable is
> well-defined: it's another NaN which is just 'undef' in IR.
>
> On Wed, Feb 28, 2018 at 11:43 AM, Kaylor, Andrew
> <andrew.kaylor at intel.com <mailto:andrew.kaylor at intel.com>> wrote:
>
> I’m not sure the transformation happening with fdiv is
> correct. If we have “%y = fdiv float %x, undef” and %x is
> a NaN then the result will be NaN for any value of the
> undef, right? So if I understand the undef rules correctly
> (never a certainty) then we can’t safely replace the
> expression with undef. We could, I think, replace it with
> “%y = %x” though. I think the same is true for fadd, fsub,
> fmul, and frem.
>
> -Andy
>
> %y = fadd float %x, undef
>
> Can we simplify this?
>
> Currently in IR, we do nothing for fadd/fsub/fmul. For
> fdiv/frem, we propagate undef. The code comment for
> fdiv/frem says:
> "the undef could be a snan"
>
> If that's correct, then shouldn't it be the same for
> fadd/fsub/fmul? But this can't be correct because we
> support targets that don't raise exceptions...and even
> targets that raise exceptions do not trap by default on snan?
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180228/e269df9b/attachment.html>
More information about the llvm-dev
mailing list