[llvm] [GISel] Use GISelValueTracking in isKnownNeverNaN (PR #190542)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 5 11:00:29 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
@llvm/pr-subscribers-backend-aarch64
Author: Tim Gymnich (tgymnich)
<details>
<summary>Changes</summary>
Pass GISelValueTracking* through isKnownNeverNaN and isKnownNeverSNaN so
that the implementation can call computeKnownFPClass to derive NaN
information from value tracking, rather than only looking at flags and
direct constant definitions. Update all callers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@<!-- -->anthropic.com>
---
Patch is 92.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/190542.diff
16 Files Affected:
- (modified) llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h (+6)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/Utils.h (+3-3)
- (modified) llvm/include/llvm/Support/KnownFPClass.h (+25)
- (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+2-2)
- (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+390-382)
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+3-3)
- (modified) llvm/lib/CodeGen/GlobalISel/Utils.cpp (+5-72)
- (modified) llvm/lib/Support/KnownFPClass.cpp (+111)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUInstructions.td (+1-1)
- (modified) llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp (+5-5)
- (modified) llvm/test/CodeGen/AArch64/known-never-nan.ll (+24-15)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/clamp-minmax-const-combine.ll (+8-23)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/fmed3-min-max-const-combine.ll (+10-16)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/regbankcombiner-clamp-minmax-const.mir (+8-27)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/regbankcombiner-fmed3-minmax-const.mir (+6-9)
- (modified) llvm/unittests/CodeGen/GlobalISel/KnownFPClassTest.cpp (+369-28)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index 8db99ba4ed883..db1f4a89d3469 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -761,6 +761,12 @@ inline UnaryOp_match<SrcTy, TargetOpcode::G_FSQRT> m_GFSqrt(const SrcTy &Src) {
return UnaryOp_match<SrcTy, TargetOpcode::G_FSQRT>(Src);
}
+template <typename SrcTy>
+inline UnaryOp_match<SrcTy, TargetOpcode::G_FFLOOR>
+m_GFFloor(const SrcTy &Src) {
+ return UnaryOp_match<SrcTy, TargetOpcode::G_FFLOOR>(Src);
+}
+
// General helper for generic MI compares, i.e. G_ICMP and G_FCMP
// TODO: Allow checking a specific predicate.
template <typename Pred_P, typename LHS_P, typename RHS_P, unsigned Opcode,
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index de6606e7ed14a..0ffec025b7e36 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -340,12 +340,12 @@ isKnownToBeAPowerOfTwo(Register Val, const MachineRegisterInfo &MRI,
/// Returns true if \p Val can be assumed to never be a NaN. If \p SNaN is true,
/// this returns if \p Val can be assumed to never be a signaling NaN.
-LLVM_ABI bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
+LLVM_ABI bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI, GISelValueTracking *VT,
bool SNaN = false);
/// Returns true if \p Val can be assumed to never be a signaling NaN.
-inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI) {
- return isKnownNeverNaN(Val, MRI, true);
+inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI, GISelValueTracking *VT) {
+ return isKnownNeverNaN(Val, MRI, VT, true);
}
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF,
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index c48e0f8b7b65b..b18bfb55eacd1 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -299,6 +299,31 @@ struct KnownFPClass {
/// Report known values for cos
LLVM_ABI static KnownFPClass cos(const KnownFPClass &Src);
+ /// Report known values for tan
+ LLVM_ABI static KnownFPClass tan(const KnownFPClass &Src);
+
+ /// Report known values for sinh
+ LLVM_ABI static KnownFPClass sinh(const KnownFPClass &Src);
+
+ /// Report known values for cosh
+ LLVM_ABI static KnownFPClass cosh(const KnownFPClass &Src);
+
+ /// Report known values for tanh
+ LLVM_ABI static KnownFPClass tanh(const KnownFPClass &Src);
+
+ /// Report known values for asin
+ LLVM_ABI static KnownFPClass asin(const KnownFPClass &Src);
+
+ /// Report known values for acos
+ LLVM_ABI static KnownFPClass acos(const KnownFPClass &Src);
+
+ /// Report known values for atan
+ LLVM_ABI static KnownFPClass atan(const KnownFPClass &Src);
+
+ /// Report known values for atan2
+ LLVM_ABI static KnownFPClass atan2(const KnownFPClass &LHS,
+ const KnownFPClass &RHS);
+
/// Return true if the sign bit must be 0, ignoring the sign of nans.
bool signBitIsZeroOrNaN() const { return isKnownNever(fcNegative); }
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 177170575fe07..cfeefdb906f71 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7093,8 +7093,8 @@ unsigned CombinerHelper::getFPMinMaxOpcForSelect(
CombinerHelper::SelectPatternNaNBehaviour
CombinerHelper::computeRetValAgainstNaN(Register LHS, Register RHS,
bool IsOrderedComparison) const {
- bool LHSSafe = isKnownNeverNaN(LHS, MRI);
- bool RHSSafe = isKnownNeverNaN(RHS, MRI);
+ bool LHSSafe = isKnownNeverNaN(LHS, MRI, VT);
+ bool RHSSafe = isKnownNeverNaN(RHS, MRI, VT);
// Completely unsafe.
if (!LHSSafe && !RHSSafe)
return SelectPatternNaNBehaviour::NOT_APPLICABLE;
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index f0b455fbdc7d0..073bae76f6da3 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -868,13 +868,6 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
LLVM_DEBUG(dumpResult(MI, Known, Depth));
}
-static bool outputDenormalIsIEEEOrPosZero(const MachineFunction &MF, LLT Ty) {
- Ty = Ty.getScalarType();
- DenormalMode Mode = MF.getDenormalMode(getFltSemanticForLLT(Ty));
- return Mode.Output == DenormalMode::IEEE ||
- Mode.Output == DenormalMode::PositiveZero;
-}
-
void GISelValueTracking::computeKnownFPClass(Register R, KnownFPClass &Known,
FPClassTest InterestedClasses,
unsigned Depth) {
@@ -884,6 +877,16 @@ void GISelValueTracking::computeKnownFPClass(Register R, KnownFPClass &Known,
computeKnownFPClass(R, DemandedElts, InterestedClasses, Known, Depth);
}
+/// Return true if this value is known to be the fractional part x - floor(x),
+/// which lies in [0, 1). This implies the value cannot introduce overflow in a
+/// fmul when the other operand is known finite.
+static bool isAbsoluteValueULEOne(Register R, const MachineRegisterInfo &MRI) {
+ using namespace MIPatternMatch;
+ Register SubX;
+ return mi_match(R, MRI,
+ m_GFSub(m_Reg(SubX), m_GFFloor(m_DeferredReg(SubX))));
+}
+
void GISelValueTracking::computeKnownFPClassForFPTrunc(
const MachineInstr &MI, const APInt &DemandedElts,
FPClassTest InterestedClasses, KnownFPClass &Known, unsigned Depth) {
@@ -895,15 +898,7 @@ void GISelValueTracking::computeKnownFPClassForFPTrunc(
KnownFPClass KnownSrc;
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
Depth + 1);
-
- // Sign should be preserved
- // TODO: Handle cannot be ordered greater than zero
- if (KnownSrc.cannotBeOrderedLessThanZero())
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
-
- Known.propagateNaN(KnownSrc, true);
-
- // Infinity needs a range check.
+ Known = KnownFPClass::fptrunc(KnownSrc);
}
void GISelValueTracking::computeKnownFPClass(Register R,
@@ -1065,6 +1060,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
case TargetOpcode::G_FMA:
case TargetOpcode::G_STRICT_FMA:
case TargetOpcode::G_FMAD: {
+ Known.knownNot(fcSNan);
if ((InterestedClasses & fcNegative) == fcNone)
break;
@@ -1072,19 +1068,43 @@ void GISelValueTracking::computeKnownFPClass(Register R,
Register B = MI.getOperand(2).getReg();
Register C = MI.getOperand(3).getReg();
- if (A != B)
- break;
-
- // The multiply cannot be -0 and therefore the add can't be -0
- Known.knownNot(fcNegZero);
-
- // x * x + y is non-negative if y is non-negative.
- KnownFPClass KnownAddend;
- computeKnownFPClass(C, DemandedElts, InterestedClasses, KnownAddend,
- Depth + 1);
+ DenormalMode Mode =
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
- if (KnownAddend.cannotBeOrderedLessThanZero())
- Known.knownNot(fcNegative);
+ if (A == B && isGuaranteedNotToBeUndef(A, MRI, Depth + 1)) {
+ // x * x + y
+ KnownFPClass KnownSrc, KnownAddend;
+ computeKnownFPClass(C, DemandedElts, InterestedClasses, KnownAddend,
+ Depth + 1);
+ computeKnownFPClass(A, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ if (KnownNotFromFlags) {
+ KnownSrc.knownNot(KnownNotFromFlags);
+ KnownAddend.knownNot(KnownNotFromFlags);
+ }
+ Known = KnownFPClass::fma_square(KnownSrc, KnownAddend, Mode);
+ } else {
+ KnownFPClass KnownSrc[3];
+ computeKnownFPClass(A, DemandedElts, InterestedClasses, KnownSrc[0],
+ Depth + 1);
+ if (KnownSrc[0].isUnknown())
+ break;
+ computeKnownFPClass(B, DemandedElts, InterestedClasses, KnownSrc[1],
+ Depth + 1);
+ if (KnownSrc[1].isUnknown())
+ break;
+ computeKnownFPClass(C, DemandedElts, InterestedClasses, KnownSrc[2],
+ Depth + 1);
+ if (KnownSrc[2].isUnknown())
+ break;
+ if (KnownNotFromFlags) {
+ KnownSrc[0].knownNot(KnownNotFromFlags);
+ KnownSrc[1].knownNot(KnownNotFromFlags);
+ KnownSrc[2].knownNot(KnownNotFromFlags);
+ }
+ Known = KnownFPClass::fma(KnownSrc[0], KnownSrc[1], KnownSrc[2], Mode);
+ }
+ Known.knownNot(fcSNan);
break;
}
case TargetOpcode::G_FSQRT:
@@ -1095,20 +1115,14 @@ void GISelValueTracking::computeKnownFPClass(Register R,
InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask;
Register Val = MI.getOperand(1).getReg();
-
computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc, Depth + 1);
- if (KnownSrc.isKnownNeverPosInfinity())
- Known.knownNot(fcPosInf);
- if (KnownSrc.isKnownNever(fcSNan))
- Known.knownNot(fcSNan);
-
- // Any negative value besides -0 returns a nan.
- if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
- Known.knownNot(fcNan);
-
- // The only negative value that can be returned is -0 for -0 inputs.
- Known.knownNot(fcNegInf | fcNegSubnormal | fcNegNormal);
+ DenormalMode Mode =
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
+ Known = KnownFPClass::sqrt(KnownSrc, Mode);
+ if (MI.getFlag(MachineInstr::MIFlag::FmNsz))
+ Known.knownNot(fcNegZero);
+ Known.knownNot(fcSNan);
break;
}
case TargetOpcode::G_FABS: {
@@ -1122,19 +1136,102 @@ void GISelValueTracking::computeKnownFPClass(Register R,
Known.fabs();
break;
}
+ case TargetOpcode::G_FATAN2: {
+ Register Y = MI.getOperand(1).getReg();
+ Register X = MI.getOperand(2).getReg();
+ KnownFPClass KnownY, KnownX;
+ computeKnownFPClass(Y, DemandedElts, InterestedClasses, KnownY, Depth + 1);
+ computeKnownFPClass(X, DemandedElts, InterestedClasses, KnownX, Depth + 1);
+ Known = KnownFPClass::atan2(KnownY, KnownX);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FSINH: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::sinh(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FCOSH: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::cosh(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FTANH: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::tanh(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FASIN: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::asin(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FACOS: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::acos(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FATAN: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::atan(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FTAN: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::tan(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
case TargetOpcode::G_FSIN:
- case TargetOpcode::G_FCOS:
- case TargetOpcode::G_FSINCOS: {
+ case TargetOpcode::G_FCOS: {
// Return NaN on infinite inputs.
Register Val = MI.getOperand(1).getReg();
KnownFPClass KnownSrc;
-
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
Depth + 1);
- Known.knownNot(fcInf);
-
- if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
- Known.knownNot(fcNan);
+ Known = Opcode == TargetOpcode::G_FCOS ? KnownFPClass::cos(KnownSrc)
+ : KnownFPClass::sin(KnownSrc);
+ Known.knownNot(fcSNan);
+ break;
+ }
+ case TargetOpcode::G_FSINCOS: {
+ // Operand layout: (sin_dst, cos_dst, src)
+ Register Src = MI.getOperand(2).getReg();
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Src, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+ if (R == MI.getOperand(0).getReg())
+ Known = KnownFPClass::sin(KnownSrc);
+ else
+ Known = KnownFPClass::cos(KnownSrc);
+ Known.knownNot(fcSNan);
break;
}
case TargetOpcode::G_FMAXNUM:
@@ -1154,99 +1251,35 @@ void GISelValueTracking::computeKnownFPClass(Register R,
computeKnownFPClass(RHS, DemandedElts, InterestedClasses, KnownRHS,
Depth + 1);
- bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
- Known = KnownLHS | KnownRHS;
-
- // If either operand is not NaN, the result is not NaN.
- if (NeverNaN && (Opcode == TargetOpcode::G_FMINNUM ||
- Opcode == TargetOpcode::G_FMAXNUM ||
- Opcode == TargetOpcode::G_FMINIMUMNUM ||
- Opcode == TargetOpcode::G_FMAXIMUMNUM))
- Known.knownNot(fcNan);
-
- if (Opcode == TargetOpcode::G_FMAXNUM ||
- Opcode == TargetOpcode::G_FMAXIMUMNUM ||
- Opcode == TargetOpcode::G_FMAXNUM_IEEE) {
- // If at least one operand is known to be positive, the result must be
- // positive.
- if ((KnownLHS.cannotBeOrderedLessThanZero() &&
- KnownLHS.isKnownNeverNaN()) ||
- (KnownRHS.cannotBeOrderedLessThanZero() &&
- KnownRHS.isKnownNeverNaN()))
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- } else if (Opcode == TargetOpcode::G_FMAXIMUM) {
- // If at least one operand is known to be positive, the result must be
- // positive.
- if (KnownLHS.cannotBeOrderedLessThanZero() ||
- KnownRHS.cannotBeOrderedLessThanZero())
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- } else if (Opcode == TargetOpcode::G_FMINNUM ||
- Opcode == TargetOpcode::G_FMINIMUMNUM ||
- Opcode == TargetOpcode::G_FMINNUM_IEEE) {
- // If at least one operand is known to be negative, the result must be
- // negative.
- if ((KnownLHS.cannotBeOrderedGreaterThanZero() &&
- KnownLHS.isKnownNeverNaN()) ||
- (KnownRHS.cannotBeOrderedGreaterThanZero() &&
- KnownRHS.isKnownNeverNaN()))
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
- } else if (Opcode == TargetOpcode::G_FMINIMUM) {
- // If at least one operand is known to be negative, the result must be
- // negative.
- if (KnownLHS.cannotBeOrderedGreaterThanZero() ||
- KnownRHS.cannotBeOrderedGreaterThanZero())
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
- } else {
- llvm_unreachable("unhandled intrinsic");
- }
-
- // Fixup zero handling if denormals could be returned as a zero.
- //
- // As there's no spec for denormal flushing, be conservative with the
- // treatment of denormals that could be flushed to zero. For older
- // subtargets on AMDGPU the min/max instructions would not flush the
- // output and return the original value.
- //
- if ((Known.KnownFPClasses & fcZero) != fcNone &&
- !Known.isKnownNeverSubnormal()) {
- DenormalMode Mode =
- MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
- if (Mode != DenormalMode::getIEEE())
- Known.KnownFPClasses |= fcZero;
+ KnownFPClass::MinMaxKind Kind;
+ switch (Opcode) {
+ case TargetOpcode::G_FMINIMUM:
+ Kind = KnownFPClass::MinMaxKind::minimum;
+ break;
+ case TargetOpcode::G_FMAXIMUM:
+ Kind = KnownFPClass::MinMaxKind::maximum;
+ break;
+ case TargetOpcode::G_FMINIMUMNUM:
+ Kind = KnownFPClass::MinMaxKind::minimumnum;
+ break;
+ case TargetOpcode::G_FMAXIMUMNUM:
+ Kind = KnownFPClass::MinMaxKind::maximumnum;
+ break;
+ case TargetOpcode::G_FMINNUM:
+ case TargetOpcode::G_FMINNUM_IEEE:
+ Kind = KnownFPClass::MinMaxKind::minnum;
+ break;
+ case TargetOpcode::G_FMAXNUM:
+ case TargetOpcode::G_FMAXNUM_IEEE:
+ Kind = KnownFPClass::MinMaxKind::maxnum;
+ break;
+ default:
+ llvm_unreachable("unhandled min/max opcode");
}
- if (Known.isKnownNeverNaN()) {
- if (KnownLHS.SignBit && KnownRHS.SignBit &&
- *KnownLHS.SignBit == *KnownRHS.SignBit) {
- if (*KnownLHS.SignBit)
- Known.signBitMustBeOne();
- else
- Known.signBitMustBeZero();
- } else if ((Opcode == TargetOpcode::G_FMAXIMUM ||
- Opcode == TargetOpcode::G_FMINIMUM) ||
- Opcode == TargetOpcode::G_FMAXIMUMNUM ||
- Opcode == TargetOpcode::G_FMINIMUMNUM ||
- Opcode == TargetOpcode::G_FMAXNUM_IEEE ||
- Opcode == TargetOpcode::G_FMINNUM_IEEE ||
- // FIXME: Should be using logical zero versions
- ((KnownLHS.isKnownNeverNegZero() ||
- KnownRHS.isKnownNeverPosZero()) &&
- (KnownLHS.isKnownNeverPosZero() ||
- KnownRHS.isKnownNeverNegZero()))) {
- if ((Opcode == TargetOpcode::G_FMAXIMUM ||
- Opcode == TargetOpcode::G_FMAXNUM ||
- Opcode == TargetOpcode::G_FMAXIMUMNUM ||
- Opcode == TargetOpcode::G_FMAXNUM_IEEE) &&
- (KnownLHS.SignBit == false || KnownRHS.SignBit == false))
- Known.signBitMustBeZero();
- else if ((Opcode == TargetOpcode::G_FMINIMUM ||
- Opcode == TargetOpcode::G_FMINNUM ||
- Opcode == TargetOpcode::G_FMINIMUMNUM ||
- Opcode == TargetOpcode::G_FMINNUM_IEEE) &&
- (KnownLHS.SignBit == true || KnownRHS.SignBit == true))
- Known.signBitMustBeOne();
- }
- }
+ DenormalMode Mode =
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
+ Known = KnownFPClass::minMaxLike(KnownLHS, KnownRHS, Kind, Mode);
break;
}
case TargetOpcode::G_FCANONICALIZE: {
@@ -1255,42 +1288,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
Depth + 1);
- // This is essentially a stronger form of
- // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
- // actually have an IR canonicalization guarantee.
-
- // Canonicalize may flush denormals to zero, so we have to consider the
- // denormal mode to preserve known-not-0 knowledge.
- Known.KnownFPClasses = KnownSrc.KnownFPClasses | fcZero | fcQNan;
-
- // Stronger version of propagateNaN
- // Canonicalize is guaranteed to quiet signaling nans.
- if (KnownSrc.isKnownNeverNaN())
- Known.knownNot(fcNan);
- else
- Known.knownNot(fcSNan);
-
- // If the parent function flushes denormals, the canonical output cannot
- // be a denormal.
LLT Ty = MRI.getType(Val).getScalarType();
const fltSemantics &FPType = getFltSemanticForLLT(Ty);
...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/190542
More information about the llvm-commits
mailing list