To implement these we call the LLVM intrinsic is.fpclass indicating that
we are checking for either a quiet or signalling NaN.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Is converting to f32 correct? I see that the f64 case is supported (https://github.com/llvm/llvm-project/blob/bb588519c5b5a6555e418259bb5d4a37d35f5837/llvm/test/CodeGen/X86/is_fpclass.ll#L649).
Can you add the following to the summary?
-> The isnan extension is already captured in the Extensions documentation (https://github.com/llvm/llvm-project/blob/main/flang/docs/Extensions.md).
-> Add Fixes #6082 ( https://github.com/llvm/llvm-project/issues/60882).
Could you add tests for kind=10 and 16 as well?
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | ||
---|---|---|
3708 | I think we can just use mlir::LLVM::IsFPClass unconditionally? It will always lower directly to this function call but is cleaner code anyway. | |
flang/test/Lower/Intrinsics/isnan.f90 | ||
39 | I didn't add this conversion here, it appears to be happening before the IntrinsicCall class gets hold of it, so I guess somewhere prior we're defining isnan to have that conversion. I didn't really consider it as this will be correct (converting a f64 to f32 will preserve the isnan) but on second thought we should try and avoid the conversion to remove the extra instruction. I'll see if I can find out where it is coming from. |
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | ||
---|---|---|
3697 | Can you check whether args are f32 or f64? |
flang/test/Lower/Intrinsics/isnan.f90 | ||
---|---|---|
39 | It is indeed inserted before lowering, probably when resolving the intrinsic call (it appears in the -fdebug-unparse). |
flang/lib/Evaluate/fold-logical.cpp | ||
---|---|---|
160 | I've tried to add a check that we only replace the type of the function when we are actually able to fold, i.e. when the argument can be treated as a constant real of kind 4. This seems to pass both my own tests and the existing fold tests for isnan, but I'm not 100% confident it's correct so wanted to highlight this to get a review from someone more familiar with the folding code. |
flang/test/Lower/Intrinsics/isnan.f90 | ||
---|---|---|
39 | This is now slightly confusingly pointing at a different conversion (the one to fir.logical<4>), which I don't think can be removed. Just for reference to anyone coming along to review in future. |
flang/lib/Evaluate/fold-logical.cpp | ||
---|---|---|
160 | I think this will prevent folding of isnan with constant arguments that are not of default real type. It is probably best to only use args[0] && args[0]->UnwrapExpr() && IsActuallyConstant(*args[0]->UnwrapExpr()) that will let let isnan be folded for any real type constant argument. Otherwise, bypassing the folding that cannot succeed seems OK to me. |
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | ||
---|---|---|
3708 |
I think it may be okay to always generate the intrinsic operation. Thanks! |
FYI I see couple of gfortran tests related to isnan are failing
maxlocval_2
maxlocval_4
minlocval_1
minlocval_4
namelist_42
namelist_43
nan_6
nearest_3
An initial investigation by @SBallantyne revealed that these failures are not related to the implementation of the isnan intrinsic. See details in https://github.com/llvm/llvm-project/issues/61286#issuecomment-1462224026. Will need input before we can make progress.
I've tried to add a check that we only replace the type of the function when we are actually able to fold, i.e. when the argument can be treated as a constant real of kind 4. This seems to pass both my own tests and the existing fold tests for isnan, but I'm not 100% confident it's correct so wanted to highlight this to get a review from someone more familiar with the folding code.