[llvm] [SelectionDAG] Use `KnownBits` to determine if an operand may be NaN. (PR #188606)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 26 07:45:58 PDT 2026
https://github.com/zGoldthorpe updated https://github.com/llvm/llvm-project/pull/188606
>From f0fb561bb4e75fa1b5733359923f28d6fad08483 Mon Sep 17 00:00:00 2001
From: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
Date: Wed, 25 Mar 2026 15:37:09 -0500
Subject: [PATCH 1/4] [SelectionDAG] Use `KnownBits` to determine if an operand
may be NaN.
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 23 +++++++++++++++++++
.../CodeGen/AMDGPU/fneg-modifier-casting.ll | 4 ++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 028c9955a6bb1..eaf24fa8bdf06 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6193,6 +6193,29 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
Depth);
}
+ // Try to infer NaN from known bits, but only for detecting signaling or
+ // nonsignaling NaNs
+ if (!SNaN) {
+ EVT VT = Op.getValueType().getScalarType();
+ const unsigned Mantissa = VT == MVT::f16 ? 10
+ : VT == MVT::f32 ? 23
+ : VT == MVT::f64 ? 52
+ : VT == MVT::f128 ? 112
+ : 0;
+ const unsigned Exponent = VT == MVT::f16 ? 5
+ : VT == MVT::f32 ? 8
+ : VT == MVT::f64 ? 11
+ : VT == MVT::f128 ? 15
+ : 0;
+
+ if (Mantissa) {
+ KnownBits Known = computeKnownBits(Op, DemandedElts);
+ KnownBits KnownMan = Known.extractBits(Mantissa, 0);
+ KnownBits KnownExp = Known.extractBits(Exponent, Mantissa);
+ if (!KnownExp.getMaxValue().isAllOnes() || KnownMan.isZero())
+ return true;
+ }
+ }
return false;
}
}
diff --git a/llvm/test/CodeGen/AMDGPU/fneg-modifier-casting.ll b/llvm/test/CodeGen/AMDGPU/fneg-modifier-casting.ll
index 9b44acd5c0716..64431cb31ea6e 100644
--- a/llvm/test/CodeGen/AMDGPU/fneg-modifier-casting.ll
+++ b/llvm/test/CodeGen/AMDGPU/fneg-modifier-casting.ll
@@ -1680,7 +1680,7 @@ define amdgpu_kernel void @fnge_select_f32_multi_use_regression(float %.i2369) {
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: v_cmp_nlt_f32_e64 s[0:1], s0, 0
; GCN-NEXT: v_cndmask_b32_e64 v0, 0, 1, s[0:1]
-; GCN-NEXT: v_cmp_nge_f32_e32 vcc, 0, v0
+; GCN-NEXT: v_cmp_lt_f32_e32 vcc, 0, v0
; GCN-NEXT: v_cndmask_b32_e32 v1, 0, v0, vcc
; GCN-NEXT: v_mul_f32_e64 v0, -v0, v1
; GCN-NEXT: v_cmp_le_f32_e32 vcc, 0, v0
@@ -1694,7 +1694,7 @@ define amdgpu_kernel void @fnge_select_f32_multi_use_regression(float %.i2369) {
; GFX11-NEXT: v_cmp_nlt_f32_e64 s0, s0, 0
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_cndmask_b32_e64 v0, 0, 1, s0
-; GFX11-NEXT: v_cmp_nge_f32_e32 vcc_lo, 0, v0
+; GFX11-NEXT: v_cmp_lt_f32_e32 vcc_lo, 0, v0
; GFX11-NEXT: v_cndmask_b32_e32 v1, 0, v0, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_mul_f32_e64 v0, -v0, v1
>From fcfd5a757ab1f3e64c4a68d92e99642b3c242107 Mon Sep 17 00:00:00 2001
From: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
Date: Wed, 25 Mar 2026 16:43:52 -0500
Subject: [PATCH 2/4] Use `fltSemantics`
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 40 +++++++++++--------
1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index eaf24fa8bdf06..bb76e08894e20 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6196,24 +6196,32 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
// Try to infer NaN from known bits, but only for detecting signaling or
// nonsignaling NaNs
if (!SNaN) {
- EVT VT = Op.getValueType().getScalarType();
- const unsigned Mantissa = VT == MVT::f16 ? 10
- : VT == MVT::f32 ? 23
- : VT == MVT::f64 ? 52
- : VT == MVT::f128 ? 112
- : 0;
- const unsigned Exponent = VT == MVT::f16 ? 5
- : VT == MVT::f32 ? 8
- : VT == MVT::f64 ? 11
- : VT == MVT::f128 ? 15
- : 0;
-
- if (Mantissa) {
- KnownBits Known = computeKnownBits(Op, DemandedElts);
- KnownBits KnownMan = Known.extractBits(Mantissa, 0);
- KnownBits KnownExp = Known.extractBits(Exponent, Mantissa);
+ const fltSemantics &FltSem = Op.getValueType().getFltSemantics();
+ const KnownBits Known = computeKnownBits(Op, DemandedElts);
+ const unsigned Mantissa = FltSem.precision - 1;
+ const unsigned Exponent = FltSem.sizeInBits - FltSem.precision;
+ const KnownBits KnownMan = Known.extractBits(Mantissa, 0);
+ const KnownBits KnownExp = Known.extractBits(Exponent, Mantissa);
+
+ switch (FltSem.nanEncoding) {
+ default:
+ break;
+ case fltNanEncoding::IEEE: {
if (!KnownExp.getMaxValue().isAllOnes() || KnownMan.isZero())
return true;
+ break;
+ }
+ case fltNanEncoding::AllOnes: {
+ if (!KnownExp.getMaxValue().isAllOnes() ||
+ !KnownMan.getMaxValue().isAllOnes())
+ return true;
+ break;
+ }
+ case fltNanEncoding::NegativeZero:
+ if (Known.Zero.isSignBitSet() || !KnownExp.isZero() ||
+ !KnownMan.isZero())
+ return true;
+ break;
}
}
return false;
>From e427b07c5e1422108478cbf57dc84a61715861ad Mon Sep 17 00:00:00 2001
From: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
Date: Wed, 25 Mar 2026 17:34:12 -0500
Subject: [PATCH 3/4] Remove unnecessary `default` block.
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index bb76e08894e20..872efa20c3587 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6204,8 +6204,6 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
const KnownBits KnownExp = Known.extractBits(Exponent, Mantissa);
switch (FltSem.nanEncoding) {
- default:
- break;
case fltNanEncoding::IEEE: {
if (!KnownExp.getMaxValue().isAllOnes() || KnownMan.isZero())
return true;
>From f45aaee4ecf5b8323d1370290f32fce601b24980 Mon Sep 17 00:00:00 2001
From: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
Date: Thu, 26 Mar 2026 09:45:23 -0500
Subject: [PATCH 4/4] Added guards and removed consts.
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 53 ++++++++++---------
1 file changed, 28 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 872efa20c3587..53cee1970f739 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6195,31 +6195,34 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
// Try to infer NaN from known bits, but only for detecting signaling or
// nonsignaling NaNs
- if (!SNaN) {
- const fltSemantics &FltSem = Op.getValueType().getFltSemantics();
- const KnownBits Known = computeKnownBits(Op, DemandedElts);
- const unsigned Mantissa = FltSem.precision - 1;
- const unsigned Exponent = FltSem.sizeInBits - FltSem.precision;
- const KnownBits KnownMan = Known.extractBits(Mantissa, 0);
- const KnownBits KnownExp = Known.extractBits(Exponent, Mantissa);
-
- switch (FltSem.nanEncoding) {
- case fltNanEncoding::IEEE: {
- if (!KnownExp.getMaxValue().isAllOnes() || KnownMan.isZero())
- return true;
- break;
- }
- case fltNanEncoding::AllOnes: {
- if (!KnownExp.getMaxValue().isAllOnes() ||
- !KnownMan.getMaxValue().isAllOnes())
- return true;
- break;
- }
- case fltNanEncoding::NegativeZero:
- if (Known.Zero.isSignBitSet() || !KnownExp.isZero() ||
- !KnownMan.isZero())
- return true;
- break;
+ EVT VT = Op.getValueType();
+ if (!SNaN && VT.isFloatingPoint()) {
+ const fltSemantics &FltSem = VT.getFltSemantics();
+ if (FltSem.precision > 0) {
+ KnownBits Known = computeKnownBits(Op, DemandedElts);
+ unsigned Mantissa = FltSem.precision - 1;
+ unsigned Exponent = FltSem.sizeInBits - FltSem.precision;
+ KnownBits KnownMan = Known.extractBits(Mantissa, 0);
+ KnownBits KnownExp = Known.extractBits(Exponent, Mantissa);
+
+ switch (FltSem.nanEncoding) {
+ case fltNanEncoding::IEEE: {
+ if (!KnownExp.getMaxValue().isAllOnes() || KnownMan.isZero())
+ return true;
+ break;
+ }
+ case fltNanEncoding::AllOnes: {
+ if (!KnownExp.getMaxValue().isAllOnes() ||
+ !KnownMan.getMaxValue().isAllOnes())
+ return true;
+ break;
+ }
+ case fltNanEncoding::NegativeZero:
+ if (Known.Zero.isSignBitSet() || !KnownExp.isZero() ||
+ !KnownMan.isZero())
+ return true;
+ break;
+ }
}
}
return false;
More information about the llvm-commits
mailing list