Skip to content

Commit 3b299a1

Browse files
committed
replace isKnownNeverNaN impl
1 parent 4cfe0d7 commit 3b299a1

File tree

7 files changed

+163
-89
lines changed

7 files changed

+163
-89
lines changed

llvm/include/llvm/CodeGen/GlobalISel/Utils.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,12 @@ isKnownToBeAPowerOfTwo(Register Val, const MachineRegisterInfo &MRI,
346346
/// Returns true if \p Val can be assumed to never be a NaN. If \p SNaN is true,
347347
/// this returns if \p Val can be assumed to never be a signaling NaN.
348348
LLVM_ABI bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
349-
bool SNaN = false);
349+
GISelValueTracking *ValueTracking, bool SNaN = false);
350350

351351
/// Returns true if \p Val can be assumed to never be a signaling NaN.
352-
inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI) {
353-
return isKnownNeverNaN(Val, MRI, true);
352+
inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI,
353+
GISelValueTracking *ValueTracking) {
354+
return isKnownNeverNaN(Val, MRI, ValueTracking, true);
354355
}
355356

356357
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF,

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6519,8 +6519,8 @@ unsigned CombinerHelper::getFPMinMaxOpcForSelect(
65196519
CombinerHelper::SelectPatternNaNBehaviour
65206520
CombinerHelper::computeRetValAgainstNaN(Register LHS, Register RHS,
65216521
bool IsOrderedComparison) const {
6522-
bool LHSSafe = isKnownNeverNaN(LHS, MRI);
6523-
bool RHSSafe = isKnownNeverNaN(RHS, MRI);
6522+
bool LHSSafe = isKnownNeverNaN(LHS, MRI, VT);
6523+
bool RHSSafe = isKnownNeverNaN(RHS, MRI, VT);
65246524
// Completely unsafe.
65256525
if (!LHSSafe && !RHSSafe)
65266526
return SelectPatternNaNBehaviour::NOT_APPLICABLE;

llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -937,8 +937,6 @@ void GISelValueTracking::computeKnownFPClass(Register R,
937937

938938
if (KnownSrc.isKnownNeverPosInfinity())
939939
Known.knownNot(fcPosInf);
940-
if (KnownSrc.isKnownNever(fcSNan))
941-
Known.knownNot(fcSNan);
942940

943941
// Any negative value besides -0 returns a nan.
944942
if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
@@ -961,25 +959,27 @@ void GISelValueTracking::computeKnownFPClass(Register R,
961959
}
962960
case TargetOpcode::G_FSIN:
963961
case TargetOpcode::G_FCOS:
962+
case TargetOpcode::G_FTAN:
964963
case TargetOpcode::G_FSINCOS: {
965964
// Return NaN on infinite inputs.
966965
Register Val = MI.getOperand(1).getReg();
967966
KnownFPClass KnownSrc;
968967

969968
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
970969
Depth + 1);
970+
971971
Known.knownNot(fcInf);
972972

973973
if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
974974
Known.knownNot(fcNan);
975975
break;
976976
}
977+
case TargetOpcode::G_FMAXNUM_IEEE:
978+
case TargetOpcode::G_FMINNUM_IEEE:
977979
case TargetOpcode::G_FMAXNUM:
978980
case TargetOpcode::G_FMINNUM:
979-
case TargetOpcode::G_FMINNUM_IEEE:
980981
case TargetOpcode::G_FMAXIMUM:
981982
case TargetOpcode::G_FMINIMUM:
982-
case TargetOpcode::G_FMAXNUM_IEEE:
983983
case TargetOpcode::G_FMAXIMUMNUM:
984984
case TargetOpcode::G_FMINIMUMNUM: {
985985
Register LHS = MI.getOperand(1).getReg();
@@ -994,13 +994,23 @@ void GISelValueTracking::computeKnownFPClass(Register R,
994994
bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
995995
Known = KnownLHS | KnownRHS;
996996

997+
if (Opcode == TargetOpcode::G_FMAXNUM_IEEE ||
998+
Opcode == TargetOpcode::G_FMINNUM_IEEE)
999+
Known.knownNot(fcSNan);
1000+
9971001
// If either operand is not NaN, the result is not NaN.
9981002
if (NeverNaN && (Opcode == TargetOpcode::G_FMINNUM ||
9991003
Opcode == TargetOpcode::G_FMAXNUM ||
10001004
Opcode == TargetOpcode::G_FMINIMUMNUM ||
10011005
Opcode == TargetOpcode::G_FMAXIMUMNUM))
10021006
Known.knownNot(fcNan);
10031007

1008+
if ((Opcode == TargetOpcode::G_FMAXNUM_IEEE ||
1009+
Opcode == TargetOpcode::G_FMINNUM_IEEE) &&
1010+
((KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNever(fcSNan)) ||
1011+
(KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNeverNaN())))
1012+
Known.knownNot(fcNan);
1013+
10041014
if (Opcode == TargetOpcode::G_FMAXNUM ||
10051015
Opcode == TargetOpcode::G_FMAXIMUMNUM ||
10061016
Opcode == TargetOpcode::G_FMAXNUM_IEEE) {
@@ -1089,6 +1099,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
10891099
case TargetOpcode::G_FCANONICALIZE: {
10901100
Register Val = MI.getOperand(1).getReg();
10911101
KnownFPClass KnownSrc;
1102+
10921103
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
10931104
Depth + 1);
10941105

@@ -1190,6 +1201,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
11901201
if (KnownSrc.isKnownNeverNaN()) {
11911202
Known.knownNot(fcNan);
11921203
Known.signBitMustBeZero();
1204+
} else {
1205+
Known.knownNot(fcSNan);
11931206
}
11941207

11951208
break;
@@ -1300,6 +1313,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
13001313
Register LHS = MI.getOperand(1).getReg();
13011314
Register RHS = MI.getOperand(2).getReg();
13021315
KnownFPClass KnownLHS, KnownRHS;
1316+
13031317
bool WantNegative =
13041318
(Opcode == TargetOpcode::G_FADD ||
13051319
Opcode == TargetOpcode::G_STRICT_FADD) &&
@@ -1364,6 +1378,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
13641378
case TargetOpcode::G_STRICT_FMUL: {
13651379
Register LHS = MI.getOperand(1).getReg();
13661380
Register RHS = MI.getOperand(2).getReg();
1381+
13671382
// X * X is always non-negative or a NaN.
13681383
if (LHS == RHS)
13691384
Known.knownNot(fcNegative);
@@ -1494,6 +1509,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
14941509
Register Src = MI.getOperand(1).getReg();
14951510
// Infinity, nan and zero propagate from source.
14961511
computeKnownFPClass(R, DemandedElts, InterestedClasses, Known, Depth + 1);
1512+
Known.knownNot(fcSNan);
14971513

14981514
LLT DstTy = MRI.getType(Dst).getScalarType();
14991515
const fltSemantics &DstSem = getFltSemanticForLLT(DstTy);
@@ -1517,6 +1533,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
15171533
case TargetOpcode::G_FPTRUNC: {
15181534
computeKnownFPClassForFPTrunc(MI, DemandedElts, InterestedClasses, Known,
15191535
Depth);
1536+
Known.knownNot(fcSNan);
15201537
break;
15211538
}
15221539
case TargetOpcode::G_SITOFP:
@@ -1698,6 +1715,126 @@ void GISelValueTracking::computeKnownFPClass(Register R,
16981715
computeKnownFPClass(Src, DemandedElts, InterestedClasses, Known, Depth + 1);
16991716
break;
17001717
}
1718+
case TargetOpcode::G_FATAN: {
1719+
Register Val = MI.getOperand(1).getReg();
1720+
KnownFPClass KnownSrc;
1721+
1722+
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1723+
Depth + 1);
1724+
1725+
if (KnownSrc.isKnownAlways(fcInf))
1726+
Known.KnownFPClasses = fcNan;
1727+
1728+
break;
1729+
}
1730+
case TargetOpcode::G_FATAN2: {
1731+
Register LHS = MI.getOperand(1).getReg();
1732+
Register RHS = MI.getOperand(2).getReg();
1733+
KnownFPClass KnownLHS;
1734+
KnownFPClass KnownRHS;
1735+
1736+
computeKnownFPClass(LHS, DemandedElts, InterestedClasses, KnownLHS,
1737+
Depth + 1);
1738+
1739+
computeKnownFPClass(RHS, DemandedElts, InterestedClasses, KnownRHS,
1740+
Depth + 1);
1741+
1742+
if (!KnownRHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
1743+
break;
1744+
1745+
if (KnownLHS.isKnownAlways(fcZero)) {
1746+
// atan2(+-0, −0) -> +-pi
1747+
// atan2(+-0, x) -> +-pi for x < 0
1748+
if (KnownRHS.isKnownAlways(fcNegFinite)) {
1749+
Known.KnownFPClasses = fcFinite;
1750+
break;
1751+
}
1752+
1753+
// atan2(+-0, +0) -> +-0
1754+
// atan2(+-0, x) -> +-0 for x > 0
1755+
if (KnownRHS.isKnownAlways(fcPosFinite)) {
1756+
Known.KnownFPClasses = fcZero;
1757+
break;
1758+
}
1759+
}
1760+
1761+
if (KnownRHS.isKnownAlways(fcZero)) {
1762+
// atan2(y, +-0) -> -pi/2 for y < 0
1763+
if (KnownLHS.isKnownNeverZero() && KnownLHS.isKnownAlways(fcNegFinite)) {
1764+
Known.KnownFPClasses = fcNegFinite;
1765+
break;
1766+
}
1767+
1768+
// atan2(y, +-0) -> +pi/2 for y > 0
1769+
if (KnownLHS.isKnownNeverZero() && KnownLHS.isKnownAlways(fcPosFinite)) {
1770+
Known.KnownFPClasses = fcPosFinite;
1771+
break;
1772+
}
1773+
}
1774+
1775+
if (KnownLHS.isKnownAlways(fcPosFinite) && KnownLHS.isKnownNeverZero()) {
1776+
// atan2(+-y, -inf) -> +-pi for finite y > 0
1777+
if (KnownRHS.isKnownAlways(fcNegInf)) {
1778+
Known.KnownFPClasses = fcFinite;
1779+
break;
1780+
}
1781+
1782+
// atan2(+-y, +inf) -> +-0 for finite y > 0
1783+
if (KnownRHS.isKnownAlways(fcPosInf)) {
1784+
Known.KnownFPClasses = fcZero;
1785+
break;
1786+
}
1787+
}
1788+
1789+
if (KnownLHS.isKnownAlways(fcInf)) {
1790+
// atan2(+-inf, x) -> +-pi/2 for finite x
1791+
// atan2(+-inf, -inf) -> +-3pi/4
1792+
// atan2(+-inf, +inf) -> +-pi/4
1793+
Known.KnownFPClasses = fcFinite;
1794+
break;
1795+
}
1796+
1797+
break;
1798+
}
1799+
case TargetOpcode::G_FCOSH: {
1800+
Register Val = MI.getOperand(1).getReg();
1801+
KnownFPClass KnownSrc;
1802+
1803+
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1804+
Depth + 1);
1805+
1806+
// cosh(+-inf) -> +inf
1807+
if (KnownSrc.isKnownAlways(fcInf))
1808+
Known.KnownFPClasses = fcPosInf;
1809+
1810+
break;
1811+
}
1812+
case TargetOpcode::G_FSINH: {
1813+
Register Val = MI.getOperand(1).getReg();
1814+
KnownFPClass KnownSrc;
1815+
1816+
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1817+
Depth + 1);
1818+
1819+
// sinh(±∞) is ±∞
1820+
if (KnownSrc.isKnownAlways(fcInf))
1821+
Known.KnownFPClasses = fcInf;
1822+
1823+
break;
1824+
}
1825+
case TargetOpcode::G_FTANH: {
1826+
Register Val = MI.getOperand(1).getReg();
1827+
KnownFPClass KnownSrc;
1828+
1829+
computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1830+
Depth + 1);
1831+
1832+
// tanh(+-inf) is +-1
1833+
if (KnownSrc.isKnownAlways(fcInf))
1834+
Known.KnownFPClasses = fcFinite;
1835+
1836+
break;
1837+
}
17011838
}
17021839
}
17031840

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8179,10 +8179,10 @@ LegalizerHelper::lowerFMinNumMaxNum(MachineInstr &MI) {
81798179
// Note this must be done here, and not as an optimization combine in the
81808180
// absence of a dedicate quiet-snan instruction as we're using an
81818181
// omni-purpose G_FCANONICALIZE.
8182-
if (!isKnownNeverSNaN(Src0, MRI))
8182+
if (!isKnownNeverSNaN(Src0, MRI, VT))
81838183
Src0 = MIRBuilder.buildFCanonicalize(Ty, Src0, MI.getFlags()).getReg(0);
81848184

8185-
if (!isKnownNeverSNaN(Src1, MRI))
8185+
if (!isKnownNeverSNaN(Src1, MRI, VT))
81868186
Src1 = MIRBuilder.buildFCanonicalize(Ty, Src1, MI.getFlags()).getReg(0);
81878187
}
81888188

llvm/lib/CodeGen/GlobalISel/Utils.cpp

Lines changed: 6 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "llvm/CodeGen/GlobalISel/Utils.h"
1313
#include "llvm/ADT/APFloat.h"
1414
#include "llvm/ADT/APInt.h"
15+
#include "llvm/ADT/FloatingPointMode.h"
1516
#include "llvm/Analysis/ValueTracking.h"
1617
#include "llvm/CodeGen/CodeGenCommonISel.h"
1718
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
@@ -807,7 +808,7 @@ llvm::ConstantFoldVectorBinop(unsigned Opcode, const Register Op1,
807808
}
808809

809810
bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
810-
bool SNaN) {
811+
GISelValueTracking *VT, bool SNaN) {
811812
const MachineInstr *DefMI = MRI.getVRegDef(Val);
812813
if (!DefMI)
813814
return false;
@@ -816,78 +817,11 @@ bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
816817
if (DefMI->getFlag(MachineInstr::FmNoNans) || TM.Options.NoNaNsFPMath)
817818
return true;
818819

819-
// If the value is a constant, we can obviously see if it is a NaN or not.
820-
if (const ConstantFP *FPVal = getConstantFPVRegVal(Val, MRI)) {
821-
return !FPVal->getValueAPF().isNaN() ||
822-
(SNaN && !FPVal->getValueAPF().isSignaling());
823-
}
824-
825-
if (DefMI->getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
826-
for (const auto &Op : DefMI->uses())
827-
if (!isKnownNeverNaN(Op.getReg(), MRI, SNaN))
828-
return false;
829-
return true;
830-
}
820+
KnownFPClass FPClass = VT->computeKnownFPClass(Val, fcNan);
821+
if (SNaN)
822+
return FPClass.isKnownNever(fcSNan);
831823

832-
switch (DefMI->getOpcode()) {
833-
default:
834-
break;
835-
case TargetOpcode::G_FADD:
836-
case TargetOpcode::G_FSUB:
837-
case TargetOpcode::G_FMUL:
838-
case TargetOpcode::G_FDIV:
839-
case TargetOpcode::G_FREM:
840-
case TargetOpcode::G_FSIN:
841-
case TargetOpcode::G_FCOS:
842-
case TargetOpcode::G_FTAN:
843-
case TargetOpcode::G_FACOS:
844-
case TargetOpcode::G_FASIN:
845-
case TargetOpcode::G_FATAN:
846-
case TargetOpcode::G_FATAN2:
847-
case TargetOpcode::G_FCOSH:
848-
case TargetOpcode::G_FSINH:
849-
case TargetOpcode::G_FTANH:
850-
case TargetOpcode::G_FMA:
851-
case TargetOpcode::G_FMAD:
852-
if (SNaN)
853-
return true;
854-
855-
// TODO: Need isKnownNeverInfinity
856-
return false;
857-
case TargetOpcode::G_FMINNUM_IEEE:
858-
case TargetOpcode::G_FMAXNUM_IEEE: {
859-
if (SNaN)
860-
return true;
861-
// This can return a NaN if either operand is an sNaN, or if both operands
862-
// are NaN.
863-
return (isKnownNeverNaN(DefMI->getOperand(1).getReg(), MRI) &&
864-
isKnownNeverSNaN(DefMI->getOperand(2).getReg(), MRI)) ||
865-
(isKnownNeverSNaN(DefMI->getOperand(1).getReg(), MRI) &&
866-
isKnownNeverNaN(DefMI->getOperand(2).getReg(), MRI));
867-
}
868-
case TargetOpcode::G_FMINNUM:
869-
case TargetOpcode::G_FMAXNUM: {
870-
// Only one needs to be known not-nan, since it will be returned if the
871-
// other ends up being one.
872-
return isKnownNeverNaN(DefMI->getOperand(1).getReg(), MRI, SNaN) ||
873-
isKnownNeverNaN(DefMI->getOperand(2).getReg(), MRI, SNaN);
874-
}
875-
}
876-
877-
if (SNaN) {
878-
// FP operations quiet. For now, just handle the ones inserted during
879-
// legalization.
880-
switch (DefMI->getOpcode()) {
881-
case TargetOpcode::G_FPEXT:
882-
case TargetOpcode::G_FPTRUNC:
883-
case TargetOpcode::G_FCANONICALIZE:
884-
return true;
885-
default:
886-
return false;
887-
}
888-
}
889-
890-
return false;
824+
return FPClass.isKnownNeverNaN();
891825
}
892826

893827
Align llvm::inferAlignFromPtrInfo(MachineFunction &MF,

llvm/lib/Target/AMDGPU/AMDGPUInstructions.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ class NeverNaNPats<dag ops, list<dag> frags> : PatFrags<ops, frags> {
859859
return CurDAG->isKnownNeverNaN(SDValue(N,0));
860860
}];
861861
let GISelPredicateCode = [{
862-
return isKnownNeverNaN(MI.getOperand(0).getReg(), MRI);
862+
return isKnownNeverNaN(MI.getOperand(0).getReg(), MRI, VT);
863863
}];
864864
}
865865

0 commit comments

Comments
 (0)