[llvm-dev] Floating point semantic modes

Kaylor, Andrew via llvm-dev
Wed, 12 Feb 2020 01:18:01 -0000

> supporting exceptions and snan should be separate as exception support is
required by iso c annex f, while snan is not (gcc has separate option for snan)
> the assumption of the exception support should be that all nan values are
qnan unless snan support is turned on.

I'm not sure I see the point of this. There are a few cases where we need to
do something extra to correctly support signaling NaNs, but I'm not clear
what users would gain by being able to turn this off separately from strict
exception semantics.


> the FLT_ROUNDS value can be inlined if fenv access is off or changing the
rounding mode is not supported, otherwise it should expand to a runtime check
which can be a libc call (which is what glibc does nowadays).

I think I've been confused about what you mean when you refer to libc. I was
thinking you were referring to what happened inside the math library functions.
From this e-mail I think you're more concerned about what's in the
header files. This is starting to make a little more sense to me now. I've
been thinking about something I thought of as "what clang does" that
was actually a product of the compiler and the clang header files.

With the clang-compiler+clang-headers combination the current result of
FLT_ROUNDS is an intrinsic that gets the actual rounding mode. It sounds like
that's in agreement with your expectations, but I understand now why you
were saying that's a properly of the runtime library.

If glibc does what you say, someone might want to update this:
https://gcc.gnu.org/bugzilla//show_bug.cgi?id=30569


> FLT_EVAL_METHOD is trickier because of ts-18661, a libc (or platform) may
decide e.g. not to support _Float16 independently of what the compiler is doing
and that affects the value of FLT_EVAL_METHOD.
> in any case i think it's better if the compiler had predefined
__FLT_EVAL_METHOD etc macros that a libc may use in float.h if it decides to.
(in hosted mode the compiler float.h may not be used at all)

That's what happens today in clang. Currently it will only ever be set to 0,
1, or 2. I'm suggesting it should be -1 in cases where we're allowing
unsafe math because any value changing optimization renders the intermediate
precision meaningless.

Thanks for the continued input!

-Andy


-----Original Message-----
From: Szabolcs Nagy <nsz at port70.net>
Sent: Tuesday, February 11, 2020 3:03 AM
To: Kaylor, Andrew <andrew.kaylor at intel.com>
Cc: cfe-dev at lists.llvm.org; LLVM Developers Mailing List <llvm-dev at
lists.llvm.org>; Ristow, Warren <warren.ristow at sony.com>; Ulrich
Weigand (Ulrich.Weigand at de.ibm.com) <Ulrich.Weigand at de.ibm.com>;
Cameron McInally <cameron.mcinally at nyu.edu>; Kevin Neal <Kevin.Neal
at sas.com>; Blower, Melanie I <melanie.blower at intel.com>; sepavloff
at gmail.com; hfinkel at anl.gov; Sanjay Patel <spatel at
rotateright.com>; Wang, Pengfei <pengfei.wang at intel.com>
Subject: Re: [llvm-dev] Floating point semantic modes

* Kaylor, Andrew <andrew.kaylor at intel.com> [2020-01-29 23:54:46
+0000]:
> > ideally there would be a way to support snan too. (e.g. isnan(x)
> > cannot be turned into x!=x then)
>
> The except_behavior mode is supposed to handle this. The LLVM support for
constrained intrinsics is considering all manner of FP exceptions that could be
raised, including the distinction between QNaN and SNaN. The default LLVM IR
definition does not support this distinction.
>
> We seem to have an issue with isnan() in clang though. If you call isnan()
you get a call to __isnan() which should be fine (assuming the library does the
right thing), but we're translating __builtin_isnan() to x!=x. That's
not what we should be doing if except_behavior isn't "ignore".

supporting exceptions and snan should be separate as exception support is
required by iso c annex f, while snan is not (gcc has separate option for snan)

the assumption of the exception support should be that all nan values are qnan
unless snan support is turned on.

> > FLT_ROUNDS, FLT_EVAL_METHOD and math_errhandling are controlled by
> > the c runtime, so a compiler has no business changing them, the
> > compiler can define its own __FLT_ROUNDS, etc macros and the libc
> > may or may not use those, but e.g. in case of FLT_ROUNDS it makes no
> > sense for the compiler to try to do anything: the mode changes at
> > runtime, the libc macro will expand to a function call that
> > determines the current rounding mode. (same problem arises if you
> > can change the other modes on a per function or code block
> > granularity.)
>
> I don't think I understand what you're saying here. FLT_ROUNDS, in
> particular, I thought was supposed to be implemented without reference
> to the runtime library. In clang we're mapping this to an intrinsic
> that gets a target-specific inline expansion. For example:
> https://godbolt.org/z/uQD-AF
>
> And FLT_EVAL_METHOD I take to be an indicator of how the compiler is
handling intermediate results.

the FLT_ROUNDS value can be inlined if fenv access is off or changing the
rounding mode is not supported, otherwise it should expand to a runtime check
which can be a libc call (which is what glibc does nowadays).

FLT_EVAL_METHOD is trickier because of ts-18661, a libc (or platform) may decide
e.g. not to support _Float16 independently of what the compiler is doing and
that affects the value of FLT_EVAL_METHOD.

in any case i think it's better if the compiler had predefined
__FLT_EVAL_METHOD etc macros that a libc may use in float.h if it decides to.
(in hosted mode the compiler float.h may not be used at all)