Skip to content

[NVPTX] Don't propagate ninf and nnan in lowerFREM #147125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

paperchalice
Copy link
Contributor

0/0 and 1/0 can produce nan and inf.

0/0 and 1/0 can produce nan and inf.
@llvmbot
Copy link
Member

llvmbot commented Jul 5, 2025

@llvm/pr-subscribers-backend-nvptx

Author: None (paperchalice)

Changes

0/0 and 1/0 can produce nan and inf.


Full diff: https://github.com/llvm/llvm-project/pull/147125.diff

2 Files Affected:

  • (modified) llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp (+7-3)
  • (added) llvm/test/CodeGen/NVPTX/frem-ninf-nnan.ll (+11)
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
index bb0aeb493ed48..9418ca3bf446c 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -2793,12 +2793,16 @@ static SDValue lowerFREM(SDValue Op, SelectionDAG &DAG,
   EVT Ty = Op.getValueType();
   SDNodeFlags Flags = Op->getFlags();
 
+  // fdiv can still generate inf and nan when nnan and ninf are set.
+  SDNodeFlags NewFlags = Flags;
+  NewFlags.setNoNaNs(false);
+  NewFlags.setNoInfs(false);
   SDValue Div = DAG.getNode(ISD::FDIV, DL, Ty, X, Y, Flags);
-  SDValue Trunc = DAG.getNode(ISD::FTRUNC, DL, Ty, Div, Flags);
+  SDValue Trunc = DAG.getNode(ISD::FTRUNC, DL, Ty, Div, NewFlags);
   SDValue Mul = DAG.getNode(ISD::FMUL, DL, Ty, Trunc, Y,
-                            Flags | SDNodeFlags::AllowContract);
+                            NewFlags | SDNodeFlags::AllowContract);
   SDValue Sub = DAG.getNode(ISD::FSUB, DL, Ty, X, Mul,
-                            Flags | SDNodeFlags::AllowContract);
+                            NewFlags | SDNodeFlags::AllowContract);
 
   if (AllowUnsafeFPMath || Flags.hasNoInfs())
     return Sub;
diff --git a/llvm/test/CodeGen/NVPTX/frem-ninf-nnan.ll b/llvm/test/CodeGen/NVPTX/frem-ninf-nnan.ll
new file mode 100644
index 0000000000000..639f9ab201ad0
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/frem-ninf-nnan.ll
@@ -0,0 +1,11 @@
+; RUN: llc %s --stop-after=nvptx-isel -mcpu=sm_60 -o - | FileCheck %s
+
+target triple = "nvptx64-unknown-cuda"
+
+define float @frem_ninf_nnan(float %a, float %b) {
+  ; CHECK:     nnan ninf FDIV32rr_prec
+  ; CHECK-NOT: nnan ninf contract FNEGf32
+  ; CHECK:     contract FNEGf32
+  %r = frem ninf nnan float %a, %b
+  ret float %r
+}

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI this lowering is also just wrong and should be an approximation requiring afn. We have essentially the same expansion in AMDGPU to be replaced by #130988

@@ -0,0 +1,11 @@
; RUN: llc %s --stop-after=nvptx-isel -mcpu=sm_60 -o - | FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend using -stop-after=finalize-isel instead if you want to check mir


if (AllowUnsafeFPMath || Flags.hasNoInfs())
if (AllowUnsafeFPMath || (Flags.hasNoInfs() && Flags.hasApproximateFuncs()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't touch the afn thing here. I also did not mean this tail section of the function is wrong, I meant the entire implementation of this function is wrong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants