[llvm-dev] how to simplify FP ops with an undef operand?

Robin Kruppe via llvm-dev llvm-dev at lists.llvm.org
Fri Mar 2 05:59:43 PST 2018


On 2 March 2018 at 06:32, Chris Lattner via llvm-dev <
llvm-dev at lists.llvm.org> wrote:
> Potentially controversial points:
>
>  - Because LLVM reorders and speculates the instruction forms, and because
> IEEE defines the corresponding IEEE operations as trapping on SNaNs, it is
> clear that SNaNs are outside of the domain of these LLVM operations.
Either
> speculation is ok or trapping on SNaN is ok, pick one…  (and we already
did
> :)

Whether operations on sNaNs trap in the "default execution environment", or
otherwise interrupt normal control flow or have side effects, seems to be
the key point of disagreement here. I don't believe they do, at least as
far as my amateur reading of IEEE 754-2008 can tell:

1) (most) operations on sNaN signal an _invalid operation_ exception
(§7.2), and so do many other operations on other values (also §7.2), such
as: 0 * inf, inf / inf, fma(0, inf, x), sqrt on negative inputs, converting
a float to an integer when the source is NaN/is infinity/does not fit in
the destination type, etc.
2) IEEE specifies a default way of handling exceptions (§7.1), which for
_invalid operation_ is returning a quiet NaN (§7.2).
3) Language standards should offer a way to override the default exception
handling (§8.1).
4) _Immediate_ alternate exception handling (§8.3) can be implemented via
traps (§8.3, NOTE 2).

As I said I'm not an expert on this standard, but it seems very clear-cut
to me that IEEE specifies operations like divide(x, sNaN) should return a
quiet NaN, nothing else, unless the program uses language-provided
facilities to install some other behavior. In this respect sNaN operations
are not any different from other invalid, inexact, overflowing, etc.
operations (as Steve already said).

If this is the case, there is no reason to treat e.g. "fdiv %x, snan" as
having side effects or some sort of UB: fdiv and friends already assume a
"default" fenv where nobody looks at flags, changes rounding modes,
installs alternative exception handling, etc. so the invalid operation
exception from sNaN operands is just as irrelevant as all the other
exceptions are. LLVM can simply assume the default exception handling (as
it already does in many cases) and fold calculations on signaling NaNs to
quiet NaNs if it so wishes.

I have not surveyed the numerous hardware implementations (and everything
else that goes into the "default execution environment", e.g., what the OS
does), so it might be that some of those default to trapping on sNaNs. I've
never heard of such a thing, and just verified that it does not happen on
my x86_64 machine, but there's a lot of weirdness out there. If you know of
any targets that trap on sNaN by default, please tell us. Otherwise, going
only by IEEE (as you yourself did), I don't see how traps could be a
possibility without the program opting into fenv access (in which case the
frontend has to emit constrained intrinsics anyway).

Cheers,
Robin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180302/f36c1f17/attachment.html>


More information about the llvm-dev mailing list