[PATCH] D137811: InstCombine: Perform basic isnan combines on llvm.is.fpclass

Serge Pavlov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 31 22:56:38 PST 2023


sepavloff added a comment.

In D137811#4095037 <https://reviews.llvm.org/D137811#4095037>, @jyknight wrote:

> In D137811#4090256 <https://reviews.llvm.org/D137811#4090256>, @sepavloff wrote:
>
>>   The C classification macros fpclassify, iscanonical, isfinite, isinf, isnan, isnormal,
>>   issignaling, issubnormal, iszero, and signbit provide the IEC 60559 operations indicated
>>   in the table above provided their arguments are in the format of their semantic type. Then these
>>   macros raise no floating-point exceptions, even if an argument is a signaling NaN.
>>
>> and this property must be kept no matter if exceptions are ignored or not.
>
> No, the property does not need to be maintained if the exception flag state cannot be observed by correct code. And that's exactly the case at hand in FENV_ACCESS OFF code (and, correspondingly, non-strictfp in LLVM IR). In such code, you are not allowed to have trap-on-exception enabled, nor are you allowed to access the floating-point exception status flags, and, the state of the status flags is unspecified upon transitioning back to FENV_ACCESS ON code. Thus, within such code, we may set the status flags to any arbitrary value we wish -- nobody can (correctly) tell the difference.

What about the original case, when `isnan` is used in inline function?

  inline int get_code(float x) {
    return isnan(x) ? 1 : 2;
  }
  #pragma STDC FENV_ACCESS ON
  void func2(float x) {
    int code1 = get_code(x);
    ...
  }

Can this function, defined as non-strictfp, raise `Invalid` exception when inlined into strictfp function?

>> In a broader context, it looks natural that a non-strictfp function may lose some exceptions that strictfp function would raise. But it would be counterintuitive if it raised new exceptions, which cannot be observed in strictfp function.
>
> That's not a problem. It is definitely permissible for a non-strictfp function to raise an FP-exceptions that "should not" be raised. That this is permissible is one of the most important properties of the non-strict operations -- it allows code motion which is impermissible if the status-flag side effects must be taken into account. (e.g. speculating an "fadd" above a conditional).

There is a use case, when a computation is made with traps allowed for errors (Invalid, Overflow, DivideByZero). If an error occurs, computation is stopped. It saves from checks in multiple places during computation. The computation runs in default mode, because rounding mode is standard and precise exception flag behavior is unimportant. If non-strictfp functions are allowed to throw spurious exceptions, such solution won't work. Running computations in strictfp mode is not an option because of poor performance.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137811/new/

https://reviews.llvm.org/D137811



More information about the llvm-commits mailing list