[llvm] [DAG] computeKnownFPClass - add ISD::SINT_TO_FP/UINT_TO_FP handling (PR #190539)
Pau Sum via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 7 18:17:40 PDT 2026
https://github.com/pau-sum updated https://github.com/llvm/llvm-project/pull/190539
>From 0e82bd5d812a9a581aaedc3d5b9667fa6f449966 Mon Sep 17 00:00:00 2001
From: Pau Sum <pau at sumpau.com>
Date: Sun, 5 Apr 2026 08:50:09 -0400
Subject: [PATCH 1/4] [DAG] computeKnownFPClass - add
ISD::SINT_TO_FP/UINT_TO_FP handling
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 55 ++++
llvm/test/CodeGen/RISCV/combine-is_fpclass.ll | 281 ++++++++++++++++++
2 files changed, 336 insertions(+)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 137922aa62557..aaec1d9eb0f4f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6082,6 +6082,61 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
Known = computeKnownFPClass(Op.getOperand(0), InterestedClasses, Depth + 1);
break;
}
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP: {
+ // Cannot produce nan
+ Known.knownNot(fcNan);
+
+ // Integers cannot be subnormal
+ Known.knownNot(fcSubnormal);
+
+ // sitofp and uitofp turn into +0.0 for zero.
+ Known.knownNot(fcNegZero);
+
+ // UIToFP is always non-negative regardless of known bits.
+ if (Opcode == ISD::UINT_TO_FP)
+ Known.signBitMustBeZero();
+
+ // Only compute known bits if we can learn something useful from them.
+ if (!(InterestedClasses & (fcPosZero | fcNormal | fcInf)))
+ break;
+
+ KnownBits IntKnown =
+ computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
+
+ // If the integer is non-zero, the result cannot be +0.0
+ if (IntKnown.isNonZero())
+ Known.knownNot(fcPosZero);
+
+ if (Opcode == ISD::SINT_TO_FP) {
+ // If the signed integer is known non-negative, the result is
+ // non-negative. If the signed integer is known negative, the result is
+ // negative.
+ if (IntKnown.isNonNegative())
+ Known.signBitMustBeZero();
+ else if (IntKnown.isNegative())
+ Known.signBitMustBeOne();
+ }
+
+ // Guard kept for ilogb()
+ if (InterestedClasses & fcInf) {
+ // Get width of largest magnitude integer known.
+ // This still works for a signed minimum value because the largest FP
+ // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
+ int IntSize = IntKnown.getBitWidth();
+ if (Opcode == ISD::UINT_TO_FP)
+ IntSize -= IntKnown.countMinLeadingZeros();
+ else if (Opcode == ISD::SINT_TO_FP)
+ IntSize -= IntKnown.countMinSignBits();
+
+ // If the exponent of the largest finite FP value can hold the largest
+ // integer, the result of the cast must be finite.
+ if (ilogb(APFloat::getLargest(VT.getScalarType().getFltSemantics())) >=
+ IntSize)
+ Known.knownNot(fcInf);
+ }
+ break;
+ }
case ISD::BITCAST: {
// FIXME: It should not be necessary to check for an elementwise bitcast.
// If a bitcast is not elementwise between vector / scalar types,
diff --git a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
index 5049775710628..beeacc1391653 100644
--- a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
+++ b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
@@ -22,6 +22,287 @@ define i8 @iszero_constant_v4f32() nounwind {
ret i8 %r
}
+define i1 @uitofp_isnan(i32 %x) {
+; CHECK-LABEL: uitofp_isnan:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = uitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 3) ; 3 = nan
+ ret i1 %res
+}
+
+define i1 @uitofp_issubnormal(i32 %x) {
+; CHECK-LABEL: uitofp_issubnormal:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = uitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 144) ; 144 = subnormal
+ ret i1 %res
+}
+
+define i1 @uitofp_isnegzero(i32 %x) {
+; CHECK-LABEL: uitofp_isnegzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = uitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 32) ; 32 = neg_zero
+ ret i1 %res
+}
+
+define i1 @uitofp_isneg(i32 %x) {
+; CHECK-LABEL: uitofp_isneg:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = uitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 60) ; 60 = negative
+ ret i1 %res
+}
+
+define i1 @uitofp_isposzero(i32 %x) {
+; CHECK-LABEL: uitofp_isposzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %nz = or i32 %x, 1 ; Ensure nonzero
+ %f = uitofp i32 %nz to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 64) ; 64 = pos_zero
+ ret i1 %res
+}
+
+define i1 @uitofp_isinf(i32 %x) {
+; CHECK-LABEL: uitofp_isinf:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = uitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 516) ; 516 = inf
+ ret i1 %res
+}
+
+define i1 @sitofp_isnan(i32 %x) {
+; CHECK-LABEL: sitofp_isnan:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = sitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 3) ; 3 = nan
+ ret i1 %res
+}
+
+define i1 @sitofp_issubnormal(i32 %x) {
+; CHECK-LABEL: sitofp_issubnormal:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = sitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 144) ; 144 = subnormal
+ ret i1 %res
+}
+
+define i1 @sitofp_isnegzero(i32 %x) {
+; CHECK-LABEL: sitofp_isnegzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = sitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 32) ; 32 = neg_zero
+ ret i1 %res
+}
+
+define i1 @sitofp_isposzero(i32 %x) {
+; CHECK-LABEL: sitofp_isposzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %npz = or i32 %x, -2147483648 ; | 0x80000000: Set sign bit
+ %f = sitofp i32 %npz to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 64) ; 64 = pos_zero
+ ret i1 %res
+}
+
+define i1 @sitofp_isneg(i32 %x) {
+; CHECK-LABEL: sitofp_isneg:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %nn = and i32 %x, 2147483647 ; & 0x7FFFFFFF: Clear sign bit
+ %f = sitofp i32 %nn to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 60) ; 60 = negative
+ ret i1 %res
+}
+
+define i1 @sitofp_isnonneg(i32 %x) {
+; CHECK-LABEL: sitofp_isnonneg:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %n = or i32 %x, -2147483648 ; | 0x80000000: Set sign bit
+ %f = sitofp i32 %n to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 960) ; 960 = positive
+ ret i1 %res
+}
+
+define i1 @sitofp_isinf(i32 %x) {
+; CHECK-LABEL: sitofp_isinf:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %f = sitofp i32 %x to float
+ %res = call i1 @llvm.is.fpclass.f32(float %f, i32 516) ; 516 = inf
+ ret i1 %res
+}
+
+define <4 x i1> @uitofp_v4_isnan(<4 x i32> %x) {
+; CHECK-LABEL: uitofp_v4_isnan:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = uitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 3) ; 3 = nan
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @uitofp_v4_issubnormal(<4 x i32> %x) {
+; CHECK-LABEL: uitofp_v4_issubnormal:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = uitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 144) ; 144 subnormal
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @uitofp_v4_isnegzero(<4 x i32> %x) {
+; CHECK-LABEL: uitofp_v4_isnegzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = uitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 32); 32 = neg_zero
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @uitofp_v4_isneg(<4 x i32> %x) {
+; CHECK-LABEL: uitofp_v4_isneg:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = uitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 60) ; 60 = negative
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @uitofp_v4_isposzero(<4 x i32> %x) {
+; CHECK-LABEL: uitofp_v4_isposzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %nz = or <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>
+ %f = uitofp <4 x i32> %nz to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 64) ; 64 = pos_zero
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @uitofp_v4_isinf(<4 x i32> %x) {
+; CHECK-LABEL: uitofp_v4_isinf:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = uitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 516) ; 516 = inf
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @sitofp_v4_isnan(<4 x i32> %x) {
+; CHECK-LABEL: sitofp_v4_isnan:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = sitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 3) ; 3 = nan
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @sitofp_v4_issubnormal(<4 x i32> %x) {
+; CHECK-LABEL: sitofp_v4_issubnormal:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = sitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 144) ; 144 = subnormal
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @sitofp_v4_isnegzero(<4 x i32> %x) {
+; CHECK-LABEL: sitofp_v4_isnegzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = sitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 32) ; 32 = neg_zero
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @sitofp_v4_isposzero(<4 x i32> %x) {
+; CHECK-LABEL: sitofp_v4_isposzero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %npz = or <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> ; | 0x80000000: Set sign bit
+ %f = sitofp <4 x i32> %npz to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 64) ; 64 = pos_zero
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @sitofp_v4_isneg(<4 x i32> %x) {
+; CHECK-LABEL: sitofp_v4_isneg:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %nn = and <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> ; & 0x7FFFFFFF: Clear sign bit
+ %f = sitofp <4 x i32> %nn to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 60) ; 60 = negative
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @sitofp_v4_isnonneg(<4 x i32> %x) {
+; CHECK-LABEL: sitofp_v4_isnonneg:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %n = or <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> ; | 0x80000000: Set sign bit
+ %f = sitofp <4 x i32> %n to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 960) ; 960 = positive
+ ret <4 x i1> %res
+}
+
+define <4 x i1> @sitofp_v4_isinf(<4 x i32> %x) {
+; CHECK-LABEL: sitofp_v4_isinf:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
+; CHECK-NEXT: ret
+ %f = sitofp <4 x i32> %x to <4 x float>
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f, i32 516) ; 516 = inf
+ ret <4 x i1> %res
+}
+
define <vscale x 4 x i1> @splat_constant_is_pos_normal() {
; CHECK-LABEL: splat_constant_is_pos_normal:
; CHECK: # %bb.0:
>From 9d9bd5d541de47e06440bfa032ca2dc2f266ce08 Mon Sep 17 00:00:00 2001
From: Pau Sum <pau at sumpau.com>
Date: Tue, 7 Apr 2026 20:57:34 -0400
Subject: [PATCH 2/4] Add itofp logic to Support/KnownFPClass
---
llvm/include/llvm/Support/KnownFPClass.h | 7 +++
llvm/lib/Support/KnownFPClass.cpp | 67 ++++++++++++++++++++++++
2 files changed, 74 insertions(+)
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index c48e0f8b7b65b..1c05ad416a20c 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -229,6 +229,13 @@ struct KnownFPClass {
LLVM_ABI static KnownFPClass bitcast(const fltSemantics &FltSemantics,
const KnownBits &Bits);
+ LLVM_ABI static KnownFPClass sitofp(const KnownBits &KnownSrc,
+ const fltSemantics &FltSem,
+ FPClassTest InterestedClasses);
+ LLVM_ABI static KnownFPClass uitofp(const KnownBits &KnownSrc,
+ const fltSemantics &FltSem,
+ FPClassTest InterestedClasses);
+
/// Report known values for fadd
LLVM_ABI static KnownFPClass
fadd(const KnownFPClass &LHS, const KnownFPClass &RHS,
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 4f704eabfc6ec..849f0081708b2 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -287,6 +287,73 @@ KnownFPClass KnownFPClass::bitcast(const fltSemantics &FltSemantics,
return Known;
}
+static KnownFPClass itofp_impl(const KnownBits &KnownSrc,
+ const fltSemantics &FltSem,
+ FPClassTest InterestedClasses, bool IsSigned) {
+ KnownFPClass Known;
+ // Cannot produce nan
+ Known.knownNot(fcNan);
+
+ // Integers cannot be subnormal
+ Known.knownNot(fcSubnormal);
+
+ // sitofp and uitofp turn into +0.0 for zero.
+ Known.knownNot(fcNegZero);
+
+ // UIToFP is always non-negative regardless of known bits.
+ if (!IsSigned)
+ Known.signBitMustBeZero();
+
+ // Only compute known bits if we can learn something useful from them.
+ if (!(InterestedClasses & (fcPosZero | fcNormal | fcInf)))
+ return Known;
+
+ // If the integer is non-zero, the result cannot be +0.0
+ if (KnownSrc.isNonZero())
+ Known.knownNot(fcPosZero);
+
+ if (IsSigned) {
+ // If the signed integer is known non-negative, the result is
+ // non-negative. If the signed integer is known negative, the result is
+ // negative.
+ if (KnownSrc.isNonNegative())
+ Known.signBitMustBeZero();
+ else if (KnownSrc.isNegative())
+ Known.signBitMustBeOne();
+ }
+
+ // Guard kept for ilogb()
+ if (InterestedClasses & fcInf) {
+ // Get width of largest magnitude integer known.
+ // This still works for a signed minimum value because the largest FP
+ // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
+ int IntSize = KnownSrc.getBitWidth();
+ if (!IsSigned)
+ IntSize -= KnownSrc.countMinLeadingZeros();
+ else
+ IntSize -= KnownSrc.countMinSignBits();
+
+ // If the exponent of the largest finite FP value can hold the largest
+ // integer, the result of the cast must be finite.
+ if (APFloat::semanticsMaxExponent(FltSem) >= IntSize)
+ Known.knownNot(fcInf);
+ }
+
+ return Known;
+}
+
+KnownFPClass KnownFPClass::sitofp(const KnownBits &SrcKnown,
+ const fltSemantics &FltSem,
+ FPClassTest InterestedClasses) {
+ return itofp_impl(SrcKnown, FltSem, InterestedClasses, /*IsSigned=*/true);
+}
+
+KnownFPClass KnownFPClass::uitofp(const KnownBits &SrcKnown,
+ const fltSemantics &FltSem,
+ FPClassTest InterestedClasses) {
+ return itofp_impl(SrcKnown, FltSem, InterestedClasses, /*IsSigned=*/false);
+}
+
// Handle known sign bit and nan cases for fadd.
static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
const KnownFPClass &KnownRHS, DenormalMode Mode) {
>From bede3ff20570c8de61249f528f985862675cbbdc Mon Sep 17 00:00:00 2001
From: Pau Sum <pau at sumpau.com>
Date: Tue, 7 Apr 2026 20:59:08 -0400
Subject: [PATCH 3/4] refactor: Use Support/KnownFPClass for itofp cases for
SelDAG
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 53 ++-----------------
1 file changed, 4 insertions(+), 49 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index aaec1d9eb0f4f..c17aa2e51b764 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6084,57 +6084,12 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
}
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP: {
- // Cannot produce nan
- Known.knownNot(fcNan);
-
- // Integers cannot be subnormal
- Known.knownNot(fcSubnormal);
-
- // sitofp and uitofp turn into +0.0 for zero.
- Known.knownNot(fcNegZero);
-
- // UIToFP is always non-negative regardless of known bits.
- if (Opcode == ISD::UINT_TO_FP)
- Known.signBitMustBeZero();
-
- // Only compute known bits if we can learn something useful from them.
- if (!(InterestedClasses & (fcPosZero | fcNormal | fcInf)))
- break;
-
KnownBits IntKnown =
computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
-
- // If the integer is non-zero, the result cannot be +0.0
- if (IntKnown.isNonZero())
- Known.knownNot(fcPosZero);
-
- if (Opcode == ISD::SINT_TO_FP) {
- // If the signed integer is known non-negative, the result is
- // non-negative. If the signed integer is known negative, the result is
- // negative.
- if (IntKnown.isNonNegative())
- Known.signBitMustBeZero();
- else if (IntKnown.isNegative())
- Known.signBitMustBeOne();
- }
-
- // Guard kept for ilogb()
- if (InterestedClasses & fcInf) {
- // Get width of largest magnitude integer known.
- // This still works for a signed minimum value because the largest FP
- // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
- int IntSize = IntKnown.getBitWidth();
- if (Opcode == ISD::UINT_TO_FP)
- IntSize -= IntKnown.countMinLeadingZeros();
- else if (Opcode == ISD::SINT_TO_FP)
- IntSize -= IntKnown.countMinSignBits();
-
- // If the exponent of the largest finite FP value can hold the largest
- // integer, the result of the cast must be finite.
- if (ilogb(APFloat::getLargest(VT.getScalarType().getFltSemantics())) >=
- IntSize)
- Known.knownNot(fcInf);
- }
+ const fltSemantics &FltSem = VT.getScalarType().getFltSemantics();
+ Known = Opcode == ISD::SINT_TO_FP
+ ? KnownFPClass::sitofp(IntKnown, FltSem, InterestedClasses)
+ : KnownFPClass::uitofp(IntKnown, FltSem, InterestedClasses);
break;
}
case ISD::BITCAST: {
>From ca5e49fc108a1ccdc5e008cd0a4ef41ae467e240 Mon Sep 17 00:00:00 2001
From: Pau Sum <pau at sumpau.com>
Date: Tue, 7 Apr 2026 21:01:59 -0400
Subject: [PATCH 4/4] refactor: Use Support/KnownFPClass for itofp cases in
ValueTracking
---
llvm/lib/Analysis/ValueTracking.cpp | 56 +++--------------------------
1 file changed, 5 insertions(+), 51 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index a0fb28612c534..529f42e821462 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5769,59 +5769,13 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
}
case Instruction::SIToFP:
case Instruction::UIToFP: {
- // Cannot produce nan
- Known.knownNot(fcNan);
-
- // Integers cannot be subnormal
- Known.knownNot(fcSubnormal);
-
- // sitofp and uitofp turn into +0.0 for zero.
- Known.knownNot(fcNegZero);
-
- // UIToFP is always non-negative regardless of known bits.
- if (Op->getOpcode() == Instruction::UIToFP)
- Known.signBitMustBeZero();
-
- // Only compute known bits if we can learn something useful from them.
- if (!(InterestedClasses & (fcPosZero | fcNormal | fcInf)))
- break;
-
KnownBits IntKnown =
computeKnownBits(Op->getOperand(0), DemandedElts, Q, Depth + 1);
-
- // If the integer is non-zero, the result cannot be +0.0
- if (IntKnown.isNonZero())
- Known.knownNot(fcPosZero);
-
- if (Op->getOpcode() == Instruction::SIToFP) {
- // If the signed integer is known non-negative, the result is
- // non-negative. If the signed integer is known negative, the result is
- // negative.
- if (IntKnown.isNonNegative()) {
- Known.signBitMustBeZero();
- } else if (IntKnown.isNegative()) {
- Known.signBitMustBeOne();
- }
- }
-
- // Guard kept for ilogb()
- if (InterestedClasses & fcInf) {
- // Get width of largest magnitude integer known.
- // This still works for a signed minimum value because the largest FP
- // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
- int IntSize = IntKnown.getBitWidth();
- if (Op->getOpcode() == Instruction::UIToFP)
- IntSize -= IntKnown.countMinLeadingZeros();
- else if (Op->getOpcode() == Instruction::SIToFP)
- IntSize -= IntKnown.countMinSignBits();
-
- // If the exponent of the largest finite FP value can hold the largest
- // integer, the result of the cast must be finite.
- Type *FPTy = Op->getType()->getScalarType();
- if (ilogb(APFloat::getLargest(FPTy->getFltSemantics())) >= IntSize)
- Known.knownNot(fcInf);
- }
-
+ const fltSemantics &FltSem =
+ Op->getType()->getScalarType()->getFltSemantics();
+ Known = Op->getOpcode() == Instruction::SIToFP
+ ? KnownFPClass::sitofp(IntKnown, FltSem, InterestedClasses)
+ : KnownFPClass::uitofp(IntKnown, FltSem, InterestedClasses);
break;
}
case Instruction::ExtractElement: {
More information about the llvm-commits
mailing list