-
Notifications
You must be signed in to change notification settings - Fork 14.1k
[llvm][GISel] Use computeKnownFPClass #141484
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
base: main
Are you sure you want to change the base?
Conversation
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- llvm/include/llvm/CodeGen/GlobalISel/Utils.h llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp llvm/lib/CodeGen/GlobalISel/Utils.cpp llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp View the diff from clang-format here.diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index 5f79bc3d8..fc0f4f8f8 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -346,7 +346,8 @@ 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,
- GISelValueTracking *ValueTracking, bool SNaN = false);
+ GISelValueTracking *ValueTracking,
+ 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,
|
3749625
to
b075896
Compare
@arsenm how do you think we should go about handling SNaNs here? The previous code basically assumed that SNaNs can never occur. |
@llvm/pr-subscribers-llvm-globalisel Author: Tim Gymnich (tgymnich) Changes
cc @arsenm Patch is 47.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/141484.diff 13 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index 684a9bf554fb1..cd27a3d5cdbac 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -337,11 +337,12 @@ bool 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.
bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
- bool SNaN = false);
+ GISelValueTracking *ValueTracking, 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 *ValueTracking) {
+ return isKnownNeverNaN(Val, MRI, ValueTracking, true);
}
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO);
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b1e851183de0d..8952226ae7f1e 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -6519,8 +6519,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 67b1a449f8483..e98c49bbcc9dd 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -693,6 +693,9 @@ static bool outputDenormalIsIEEEOrPosZero(const MachineFunction &MF, LLT Ty) {
void GISelValueTracking::computeKnownFPClass(Register R, KnownFPClass &Known,
FPClassTest InterestedClasses,
unsigned Depth) {
+ if (!R.isVirtual())
+ return;
+
LLT Ty = MRI.getType(R);
APInt DemandedElts =
Ty.isFixedVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1);
@@ -736,6 +739,9 @@ void GISelValueTracking::computeKnownFPClass(Register R,
assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ if (!R.isVirtual())
+ return;
+
MachineInstr &MI = *MRI.getVRegDef(R);
unsigned Opcode = MI.getOpcode();
LLT DstTy = MRI.getType(R);
@@ -915,8 +921,6 @@ void GISelValueTracking::computeKnownFPClass(Register R,
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())
@@ -939,6 +943,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
}
case TargetOpcode::G_FSIN:
case TargetOpcode::G_FCOS:
+ case TargetOpcode::G_FTAN:
case TargetOpcode::G_FSINCOS: {
// Return NaN on infinite inputs.
Register Val = MI.getOperand(1).getReg();
@@ -946,18 +951,19 @@ void GISelValueTracking::computeKnownFPClass(Register R,
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
Depth + 1);
+
Known.knownNot(fcInf);
if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
Known.knownNot(fcNan);
break;
}
+ case TargetOpcode::G_FMAXNUM_IEEE:
+ case TargetOpcode::G_FMINNUM_IEEE:
case TargetOpcode::G_FMAXNUM:
case TargetOpcode::G_FMINNUM:
- case TargetOpcode::G_FMINNUM_IEEE:
case TargetOpcode::G_FMAXIMUM:
case TargetOpcode::G_FMINIMUM:
- case TargetOpcode::G_FMAXNUM_IEEE:
case TargetOpcode::G_FMAXIMUMNUM:
case TargetOpcode::G_FMINIMUMNUM: {
Register LHS = MI.getOperand(1).getReg();
@@ -972,6 +978,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
Known = KnownLHS | KnownRHS;
+ if (Opcode == TargetOpcode::G_FMAXNUM_IEEE ||
+ Opcode == TargetOpcode::G_FMINNUM_IEEE)
+ Known.knownNot(fcSNan);
+
// If either operand is not NaN, the result is not NaN.
if (NeverNaN && (Opcode == TargetOpcode::G_FMINNUM ||
Opcode == TargetOpcode::G_FMAXNUM ||
@@ -979,6 +989,12 @@ void GISelValueTracking::computeKnownFPClass(Register R,
Opcode == TargetOpcode::G_FMAXIMUMNUM))
Known.knownNot(fcNan);
+ if ((Opcode == TargetOpcode::G_FMAXNUM_IEEE ||
+ Opcode == TargetOpcode::G_FMINNUM_IEEE) &&
+ ((KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNever(fcSNan)) ||
+ (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNeverNaN())))
+ Known.knownNot(fcNan);
+
if (Opcode == TargetOpcode::G_FMAXNUM ||
Opcode == TargetOpcode::G_FMAXIMUMNUM ||
Opcode == TargetOpcode::G_FMAXNUM_IEEE) {
@@ -1024,7 +1040,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
//
if ((Known.KnownFPClasses & fcZero) != fcNone &&
!Known.isKnownNeverSubnormal()) {
- DenormalMode Mode = MF->getDenormalMode(getFltSemanticForLLT(DstTy));
+ DenormalMode Mode =
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
if (Mode != DenormalMode::getIEEE())
Known.KnownFPClasses |= fcZero;
}
@@ -1066,6 +1083,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
case TargetOpcode::G_FCANONICALIZE: {
Register Val = MI.getOperand(1).getReg();
KnownFPClass KnownSrc;
+
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
Depth + 1);
@@ -1086,8 +1104,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
// If the parent function flushes denormals, the canonical output cannot
// be a denormal.
- LLT Ty = MRI.getType(Val);
- const fltSemantics &FPType = getFltSemanticForLLT(Ty.getScalarType());
+ LLT Ty = MRI.getType(Val).getScalarType();
+ const fltSemantics &FPType = getFltSemanticForLLT(Ty);
DenormalMode DenormMode = MF->getDenormalMode(FPType);
if (DenormMode == DenormalMode::getIEEE()) {
if (KnownSrc.isKnownNever(fcPosZero))
@@ -1167,6 +1185,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if (KnownSrc.isKnownNeverNaN()) {
Known.knownNot(fcNan);
Known.signBitMustBeZero();
+ } else {
+ Known.knownNot(fcSNan);
}
break;
@@ -1197,8 +1217,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
Known.knownNot(fcNan);
- LLT Ty = MRI.getType(Val);
- const fltSemantics &FltSem = getFltSemanticForLLT(Ty.getScalarType());
+ LLT Ty = MRI.getType(Val).getScalarType();
+ const fltSemantics &FltSem = getFltSemanticForLLT(Ty);
DenormalMode Mode = MF->getDenormalMode(FltSem);
if (KnownSrc.isKnownNeverLogicalZero(Mode))
@@ -1277,6 +1297,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
Register LHS = MI.getOperand(1).getReg();
Register RHS = MI.getOperand(2).getReg();
KnownFPClass KnownLHS, KnownRHS;
+
bool WantNegative =
(Opcode == TargetOpcode::G_FADD ||
Opcode == TargetOpcode::G_STRICT_FADD) &&
@@ -1316,19 +1337,19 @@ void GISelValueTracking::computeKnownFPClass(Register R,
Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
// (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
- if ((KnownLHS.isKnownNeverLogicalNegZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy))) ||
- KnownRHS.isKnownNeverLogicalNegZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
+ if ((KnownLHS.isKnownNeverLogicalNegZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType()))) ||
+ KnownRHS.isKnownNeverLogicalNegZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) &&
// Make sure output negative denormal can't flush to -0
outputDenormalIsIEEEOrPosZero(*MF, DstTy))
Known.knownNot(fcNegZero);
} else {
// Only fsub -0, +0 can return -0
- if ((KnownLHS.isKnownNeverLogicalNegZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy))) ||
- KnownRHS.isKnownNeverLogicalPosZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
+ if ((KnownLHS.isKnownNeverLogicalNegZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType()))) ||
+ KnownRHS.isKnownNeverLogicalPosZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) &&
// Make sure output negative denormal can't flush to -0
outputDenormalIsIEEEOrPosZero(*MF, DstTy))
Known.knownNot(fcNegZero);
@@ -1341,6 +1362,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
case TargetOpcode::G_STRICT_FMUL: {
Register LHS = MI.getOperand(1).getReg();
Register RHS = MI.getOperand(2).getReg();
+
// X * X is always non-negative or a NaN.
if (LHS == RHS)
Known.knownNot(fcNegative);
@@ -1374,11 +1396,11 @@ void GISelValueTracking::computeKnownFPClass(Register R,
}
if ((KnownRHS.isKnownNeverInfinity() ||
- KnownLHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
+ KnownLHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) &&
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))))
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))))
Known.knownNot(fcNan);
break;
@@ -1430,10 +1452,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverInfinity()) &&
- ((KnownLHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) ||
- (KnownRHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))))) {
+ ((KnownLHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) ||
+ (KnownRHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))))) {
Known.knownNot(fcNan);
}
@@ -1446,8 +1468,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
// Inf REM x and x REM 0 produce NaN.
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
KnownLHS.isKnownNeverInfinity() &&
- KnownRHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) {
+ KnownRHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) {
Known.knownNot(fcNan);
}
@@ -1471,11 +1493,12 @@ void GISelValueTracking::computeKnownFPClass(Register R,
Register Src = MI.getOperand(1).getReg();
// Infinity, nan and zero propagate from source.
computeKnownFPClass(R, DemandedElts, InterestedClasses, Known, Depth + 1);
+ Known.knownNot(fcSNan);
- LLT DstTy = MRI.getType(Dst);
- const fltSemantics &DstSem = getFltSemanticForLLT(DstTy.getScalarType());
- LLT SrcTy = MRI.getType(Src);
- const fltSemantics &SrcSem = getFltSemanticForLLT(SrcTy.getScalarType());
+ LLT DstTy = MRI.getType(Dst).getScalarType();
+ const fltSemantics &DstSem = getFltSemanticForLLT(DstTy);
+ LLT SrcTy = MRI.getType(Src).getScalarType();
+ const fltSemantics &SrcSem = getFltSemanticForLLT(SrcTy);
// All subnormal inputs should be in the normal range in the result type.
if (APFloat::isRepresentableAsNormalIn(SrcSem, DstSem)) {
@@ -1494,6 +1517,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
case TargetOpcode::G_FPTRUNC: {
computeKnownFPClassForFPTrunc(MI, DemandedElts, InterestedClasses, Known,
Depth);
+ Known.knownNot(fcSNan);
break;
}
case TargetOpcode::G_SITOFP:
@@ -1671,6 +1695,126 @@ void GISelValueTracking::computeKnownFPClass(Register R,
computeKnownFPClass(Src, DemandedElts, InterestedClasses, Known, Depth + 1);
break;
}
+ case TargetOpcode::G_FATAN: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+
+ if (KnownSrc.isKnownAlways(fcInf))
+ Known.KnownFPClasses = fcNan;
+
+ break;
+ }
+ case TargetOpcode::G_FATAN2: {
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ KnownFPClass KnownLHS;
+ KnownFPClass KnownRHS;
+
+ computeKnownFPClass(LHS, DemandedElts, InterestedClasses, KnownLHS,
+ Depth + 1);
+
+ computeKnownFPClass(RHS, DemandedElts, InterestedClasses, KnownRHS,
+ Depth + 1);
+
+ if (!KnownRHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
+ break;
+
+ if (KnownLHS.isKnownAlways(fcZero)) {
+ // atan2(+-0, −0) -> +-pi
+ // atan2(+-0, x) -> +-pi for x < 0
+ if (KnownRHS.isKnownAlways(fcNegFinite)) {
+ Known.KnownFPClasses = fcFinite;
+ break;
+ }
+
+ // atan2(+-0, +0) -> +-0
+ // atan2(+-0, x) -> +-0 for x > 0
+ if (KnownRHS.isKnownAlways(fcPosFinite)) {
+ Known.KnownFPClasses = fcZero;
+ break;
+ }
+ }
+
+ if (KnownRHS.isKnownAlways(fcZero)) {
+ // atan2(y, +-0) -> -pi/2 for y < 0
+ if (KnownLHS.isKnownNeverZero() && KnownLHS.isKnownAlways(fcNegFinite)) {
+ Known.KnownFPClasses = fcNegFinite;
+ break;
+ }
+
+ // atan2(y, +-0) -> +pi/2 for y > 0
+ if (KnownLHS.isKnownNeverZero() && KnownLHS.isKnownAlways(fcPosFinite)) {
+ Known.KnownFPClasses = fcPosFinite;
+ break;
+ }
+ }
+
+ if (KnownLHS.isKnownAlways(fcPosFinite) && KnownLHS.isKnownNeverZero()) {
+ // atan2(+-y, -inf) -> +-pi for finite y > 0
+ if (KnownRHS.isKnownAlways(fcNegInf)) {
+ Known.KnownFPClasses = fcFinite;
+ break;
+ }
+
+ // atan2(+-y, +inf) -> +-0 for finite y > 0
+ if (KnownRHS.isKnownAlways(fcPosInf)) {
+ Known.KnownFPClasses = fcZero;
+ break;
+ }
+ }
+
+ if (KnownLHS.isKnownAlways(fcInf)) {
+ // atan2(+-inf, x) -> +-pi/2 for finite x
+ // atan2(+-inf, -inf) -> +-3pi/4
+ // atan2(+-inf, +inf) -> +-pi/4
+ Known.KnownFPClasses = fcFinite;
+ break;
+ }
+
+ break;
+ }
+ case TargetOpcode::G_FCOSH: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+
+ // cosh(+-inf) -> +inf
+ if (KnownSrc.isKnownAlways(fcInf))
+ Known.KnownFPClasses = fcPosInf;
+
+ break;
+ }
+ case TargetOpcode::G_FSINH: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+
+ // sinh(±∞) is ±∞
+ if (KnownSrc.isKnownAlways(fcInf))
+ Known.KnownFPClasses = fcInf;
+
+ break;
+ }
+ case TargetOpcode::G_FTANH: {
+ Register Val = MI.getOperand(1).getReg();
+ KnownFPClass KnownSrc;
+
+ computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
+ Depth + 1);
+
+ // tanh(+-inf) is +-1
+ if (KnownSrc.isKnownAlways(fcInf))
+ Known.KnownFPClasses = fcFinite;
+
+ break;
+ }
}
}
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 7b18a98d7f3ca..e242df04a5d80 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -8179,10 +8179,10 @@ LegalizerHelper::lowerFMinNumMaxNum(MachineInstr &MI) {
// Note this must be done here, and not as an optimization combine in the
// absence of a dedicate quiet-snan instruction as we're using an
// omni-purpose G_FCANONICALIZE.
- if (!isKnownNeverSNaN(Src0, MRI))
+ if (!isKnownNeverSNaN(Src0, MRI, VT))
Src0 = MIRBuilder.buildFCanonicalize(Ty, Src0, MI.getFlags()).getReg(0);
- if (!isKnownNeverSNaN(Src1, MRI))
+ if (!isKnownNeverSNaN(Src1, MRI, VT))
Src1 = MIRBuilder.buildFCanonicalize(Ty, Src1, MI.getFlags()).getReg(0);
}
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 64af7a57e8d12..cf8ded67ac679 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -12,6 +12,7 @@
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/CodeGenCommonISel.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
@@ -807,7 +808,7 @@ llvm::ConstantFoldVectorBinop(unsigned Opcode, const Register Op1,
}
bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
- bool SNaN) {
+ GISelValueTracking *VT, bool SNaN) {
const MachineInstr *DefMI = MRI.getVRegDef(Val);
if (!DefMI)
return false;
@@ -816,78 +817,11 @@ bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
if (DefMI->getFlag(MachineInstr::FmNoNans) || TM.Options.NoNaNsFPMath)
return true;
- // If the value is a constant, we can obviously see if it is a NaN or not.
- if (const ConstantFP *FPVal = getConstantFPVRegVal(Val, MRI)) {
- return !FPVal->getValueAPF().isNaN() ||
- (SNaN && !FPVal->getValueAPF().isSignaling());
- }
-
- if (DefMI->getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
- for (const auto &Op : DefMI->uses())
- if (!isKnownNeverNaN(Op.getReg(), MRI, SNaN))
- return false;
- return true;
- }
+ KnownFPClass FPClass = VT->computeKnownFPClass(Val, fcNan);
+ if (SNaN)
+ return FPClass.isKnownNever(fcSNan);
- switch (DefMI->getOpcode()) {
- default:
- break;
- case TargetOpcode::G_FADD:
- case TargetOpcode::G_FSUB:
- case TargetOpcode::G_FMUL:
- case TargetOpcode::G_FDIV:
- case TargetOpcode::G_FREM:
- case TargetOpcode::G_FSIN:
- case TargetOpcode::G_FCOS:
- case TargetOpcode::G_FTAN:
- case TargetOpcode::G_FACOS:
- case TargetOpcode::G_FASIN:
- case TargetOpcode::G_FATAN:
- case TargetOpcode::G_FATAN2:
- case TargetOpcode::G_FCOSH:
- case TargetOpcode::G_FSINH:
- case TargetOpcode::G_FTANH:
- case TargetOpcode::G_FMA:
- case TargetOpcode::G_FMAD:
- if (SNaN)
- return true;
-
- // TODO: Need isKnownNeverInfinity
- return false;
- case TargetOpcode::G_FMINNUM_IEEE:
- case TargetOpcode::G_FMAXNUM_IEEE: {
- if (SNaN)
- return true;
- // This can return a NaN if either operand is an sNaN, or if both operands
- // are NaN.
- return (isKnownNeverNaN(DefMI->getOperand(1).getReg(), MRI) &&
- isKnownNeverSNaN(DefMI->getOperand(2).getReg(), MRI)) ||
- (isKnownNeverSNaN(DefMI->getOperand(1).getReg(), MRI) &&
- isKnownNeverNaN(DefMI->getOperand(2).getReg(), MRI));
- }
- case TargetOpcode::G_FMINNUM:
- case TargetOpcode::G_FMAXNUM: {
- // Only one needs to be known ...
[truncated]
|
; GFX10-NEXT: v_mul_f32_e32 v0, 2.0, v0 | ||
; GFX10-NEXT: v_med3_f32 v0, v0, 1.0, 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All regressions stem from the difference in handling SNaNs. Not sure how to proceed.
; GFX12-NEXT: v_mul_f32_e32 v0, 2.0, v0 | ||
; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | ||
; GFX12-NEXT: v_med3_num_f32 v0, v0, 1.0, 0 | ||
; GFX12-NEXT: s_setpc_b64 s[30:31] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regression
@@ -337,11 +337,12 @@ bool 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. | |||
bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI, | |||
bool SNaN = false); | |||
GISelValueTracking *ValueTracking, bool SNaN = false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is optional it should be default initialized to null. If it's required it should be a reference. It should probably be required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not right now. But we could make it.
b075896
to
8571023
Compare
8571023
to
afcba08
Compare
computeKnownFPClass
inGISelValueTracking
cc @arsenm