[llvm-dev] Floating point semantic modes

Szabolcs Nagy via llvm-dev
Tue, 11 Feb 2020 11:02:37 -0000

* 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)