sepavloff added a comment.

In D104854#2886328 <https://reviews.llvm.org/D104854#2886328>, @efriedma wrote:

>> The options '-ffast-math' and '-fno-honor-nans' imply that FP operation
>> operands are never NaNs. This assumption however should not be applied
>> to the functions that check FP number properties, including 'isnan'. If
>> such function returns expected result instead of actually making
>> checks, it becomes useless in many cases.
>
> This doesn't work the way you want it to, at least given the way nnan/ninf 
> are currently defined in LangRef.  It's possible to end up in a situation 
> where `isnan(x) == isnan(x)` evaluates to false at runtime.  It doesn't 
> matter how you compute isnan; the problem is that the input is poisoned.
>
> I think the right solution to this sort of issue is to insert a "freeze" in 
> the LLVM IR, or something like that.  Not sure how we'd expect users to write 
> this in C.  Suggestions welcome.

According to the documentation, nnan/ninf may be applied to `fneg`, `fadd`, 
`fsub`, `fmul`, `fdiv`, `frem`, `fcmp`, `phi`, `select` and `call`. We can 
ignore this flag for calls of isnan and similar functions. Of course, if 
conditions of using `-ffast-math` are broken, we have undefined behavior and 
`isnan(x) != isnan(x)` becomes possible, like in this code:

  %c = fadd %a, nan
  %r = call llvm.isnan.f32(%c) 

Similarly, it is legitimate to optimize `isnan` in the code:

  %c = fadd %a, %b
  %r = call llvm.isnan.f32(%c)

In this case the result of `fadd` cannot be NaN, otherwise contract of 
`-ffast-math` is broken. So `isnan` in this case may be optimized to `false`.



================
Comment at: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:6964
+    return DAG.getSetCC(DL, ResultVT, Op, DAG.getConstantFP(0.0, DL, 
OperandVT),
+                        ISD::SETUO);
+
----------------
efriedma wrote:
> Maybe we want to consider falling back to the integer path if SETCC isn't 
> legal for the given operand type?  We could do that as a followup, though.
It makes sense, it could be beneficial for targets that have limited set of 
floating point comparisons. However straightforward check like:

    if (Flags.hasNoFPExcept() && isOperationLegalOrCustom(ISD::SETCC, 
OperandVT))

results in worse code, mainly for vector types. It should be more complex check.
 


================
Comment at: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:6984
+  return DAG.getSetCC(DL, ResultVT, Sub, DAG.getConstant(0, DL, IntVT),
+                      ISD::SETNE);
+}
----------------
efriedma wrote:
> Instead of emitting `ExpMaskV - AbsV != 0`, can we just emit `ExpMaskV != 
> AbsV`?
> Instead of emitting ExpMaskV - AbsV != 0, can we just emit ExpMaskV != AbsV?

Implemented.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D104854

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to