Skip to content

Commit d9e047f

Browse files
committed
SelectionDAG: Support nofpclass(nan/qnan/snan)
SelectionDAGISel::LowerArguments: Pass NoNaN Flags to InVals. `nofpclass` support values nan, snan, qnan, where nan=snan|qnan. So let's use NoSNaNs and NoQNaNs in SDNodeFlags. Thus, we can use it in isKnownNeverNaN. support ISD::AssertFPNoClass Fix AssertFPNoClass
1 parent 1cf9f76 commit d9e047f

12 files changed

+1277
-12
lines changed

Diff for: llvm/include/llvm/CodeGen/ISDOpcodes.h

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ enum NodeType {
6767
/// poisoned the assertion will not be true for that value.
6868
AssertAlign,
6969

70+
/// AssertNoFPClass - These nodes record if a register contains a float
71+
/// value that is known to be not some type.
72+
/// NOTE: In case of the source value (or any vector element value) is
73+
/// poisoned the assertion will not be true for that value.
74+
AssertNoFPClass,
75+
7076
/// Various leaf nodes.
7177
BasicBlock,
7278
VALUETYPE,

Diff for: llvm/include/llvm/CodeGen/SelectionDAGNodes.h

+19-7
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ struct SDNodeFlags {
397397
Exact = 1 << 2,
398398
Disjoint = 1 << 3,
399399
NonNeg = 1 << 4,
400-
NoNaNs = 1 << 5,
400+
// 1 << 5 was used as NoNaNs
401401
NoInfs = 1 << 6,
402402
NoSignedZeros = 1 << 7,
403403
AllowReciprocal = 1 << 8,
@@ -416,21 +416,26 @@ struct SDNodeFlags {
416416
// Compare instructions which may carry the samesign flag.
417417
SameSign = 1 << 14,
418418

419+
NoSNaNs = 1 << 15,
420+
NoQNaNs = 1 << 16,
421+
419422
// NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
420423
// the class definition when adding new flags.
421424

422425
PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
423-
NonNeg | NoNaNs | NoInfs | SameSign,
424-
FastMathFlags = NoNaNs | NoInfs | NoSignedZeros | AllowReciprocal |
425-
AllowContract | ApproximateFuncs | AllowReassociation,
426+
NonNeg | NoSNaNs | NoQNaNs | NoInfs | SameSign,
427+
FastMathFlags = NoSNaNs | NoQNaNs | NoInfs | NoSignedZeros |
428+
AllowReciprocal | AllowContract | ApproximateFuncs |
429+
AllowReassociation,
426430
};
427431

428432
/// Default constructor turns off all optimization flags.
429433
SDNodeFlags(unsigned Flags = SDNodeFlags::None) : Flags(Flags) {}
430434

431435
/// Propagate the fast-math-flags from an IR FPMathOperator.
432436
void copyFMF(const FPMathOperator &FPMO) {
433-
setNoNaNs(FPMO.hasNoNaNs());
437+
setNoSNaNs(FPMO.hasNoNaNs());
438+
setNoQNaNs(FPMO.hasNoNaNs());
434439
setNoInfs(FPMO.hasNoInfs());
435440
setNoSignedZeros(FPMO.hasNoSignedZeros());
436441
setAllowReciprocal(FPMO.hasAllowReciprocal());
@@ -446,7 +451,12 @@ struct SDNodeFlags {
446451
void setDisjoint(bool b) { setFlag<Disjoint>(b); }
447452
void setSameSign(bool b) { setFlag<SameSign>(b); }
448453
void setNonNeg(bool b) { setFlag<NonNeg>(b); }
449-
void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
454+
void setNoNaNs(bool b) {
455+
setFlag<NoSNaNs>(b);
456+
setFlag<NoQNaNs>(b);
457+
}
458+
void setNoSNaNs(bool b) { setFlag<NoSNaNs>(b); }
459+
void setNoQNaNs(bool b) { setFlag<NoQNaNs>(b); }
450460
void setNoInfs(bool b) { setFlag<NoInfs>(b); }
451461
void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
452462
void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
@@ -463,7 +473,9 @@ struct SDNodeFlags {
463473
bool hasDisjoint() const { return Flags & Disjoint; }
464474
bool hasSameSign() const { return Flags & SameSign; }
465475
bool hasNonNeg() const { return Flags & NonNeg; }
466-
bool hasNoNaNs() const { return Flags & NoNaNs; }
476+
bool hasNoNaNs() const { return (Flags & NoSNaNs) && (Flags & NoQNaNs); }
477+
bool hasNoSNaNs() const { return Flags & NoSNaNs; }
478+
bool hasNoQNaNs() const { return Flags & NoQNaNs; }
467479
bool hasNoInfs() const { return Flags & NoInfs; }
468480
bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
469481
bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }

Diff for: llvm/include/llvm/Target/TargetSelectionDAG.td

+1
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,7 @@ def SDT_assert : SDTypeProfile<1, 1,
859859
[SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
860860
def assertsext : SDNode<"ISD::AssertSext", SDT_assert>;
861861
def assertzext : SDNode<"ISD::AssertZext", SDT_assert>;
862+
def assernofpclass : SDNode<"ISD::AssertNoFPClass", SDTFPUnaryOp>;
862863
def assertalign : SDNode<"ISD::AssertAlign", SDT_assert>;
863864

864865
def convergencectrl_anchor : SDNode<"ISD::CONVERGENCECTRL_ANCHOR",

Diff for: llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
168168
case ISD::POISON:
169169
case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break;
170170
case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break;
171+
case ISD::AssertNoFPClass: R = GetSoftenedFloat(N->getOperand(0)); break;
171172
case ISD::VECREDUCE_FADD:
172173
case ISD::VECREDUCE_FMUL:
173174
case ISD::VECREDUCE_FMIN:
@@ -2576,6 +2577,7 @@ bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
25762577
R = PromoteFloatOp_FAKE_USE(N, OpNo);
25772578
break;
25782579
case ISD::FCOPYSIGN: R = PromoteFloatOp_FCOPYSIGN(N, OpNo); break;
2580+
case ISD::AssertNoFPClass:
25792581
case ISD::FP_TO_SINT:
25802582
case ISD::FP_TO_UINT:
25812583
case ISD::LROUND:
@@ -2803,6 +2805,7 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
28032805
case ISD::FTRUNC:
28042806
case ISD::FTAN:
28052807
case ISD::FTANH:
2808+
case ISD::AssertNoFPClass:
28062809
case ISD::FCANONICALIZE: R = PromoteFloatRes_UnaryOp(N); break;
28072810

28082811
// Binary FP Operations

Diff for: llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
129129
case ISD::UINT_TO_FP:
130130
case ISD::ZERO_EXTEND:
131131
case ISD::FCANONICALIZE:
132+
case ISD::AssertNoFPClass:
132133
R = ScalarizeVecRes_UnaryOp(N);
133134
break;
134135
case ISD::ADDRSPACECAST:
@@ -1278,6 +1279,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
12781279
case ISD::UINT_TO_FP:
12791280
case ISD::VP_UINT_TO_FP:
12801281
case ISD::FCANONICALIZE:
1282+
case ISD::AssertNoFPClass:
12811283
SplitVecRes_UnaryOp(N, Lo, Hi);
12821284
break;
12831285
case ISD::ADDRSPACECAST:
@@ -4846,6 +4848,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
48464848
case ISD::FREEZE:
48474849
case ISD::ARITH_FENCE:
48484850
case ISD::FCANONICALIZE:
4851+
case ISD::AssertNoFPClass:
48494852
Res = WidenVecRes_Unary(N);
48504853
break;
48514854
case ISD::FMA: case ISD::VP_FMA:

Diff for: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -5598,7 +5598,12 @@ bool SelectionDAG::isBaseWithConstantOffset(SDValue Op) const {
55985598

55995599
bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const {
56005600
// If we're told that NaNs won't happen, assume they won't.
5601-
if (getTarget().Options.NoNaNsFPMath || Op->getFlags().hasNoNaNs())
5601+
if (getTarget().Options.NoNaNsFPMath)
5602+
return true;
5603+
SDNodeFlags OpFlags = Op->getFlags();
5604+
if (SNaN && OpFlags.hasNoSNaNs())
5605+
return true;
5606+
if (OpFlags.hasNoSNaNs() && OpFlags.hasNoQNaNs())
56025607
return true;
56035608

56045609
if (Depth >= MaxRecursionDepth)
@@ -7365,6 +7370,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
73657370
N2.getOpcode() == ISD::TargetConstant && "Invalid FP_ROUND!");
73667371
if (N1.getValueType() == VT) return N1; // noop conversion.
73677372
break;
7373+
case ISD::AssertNoFPClass:
7374+
assert(N1.getValueType().isFloatingPoint() &&
7375+
"AssertNoFPClass is used for a non-floating type");
7376+
return N1;
73687377
case ISD::AssertSext:
73697378
case ISD::AssertZext: {
73707379
EVT EVT = cast<VTSDNode>(N2)->getVT();

Diff for: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -11827,10 +11827,25 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
1182711827
AssertOp = ISD::AssertSext;
1182811828
else if (Arg.hasAttribute(Attribute::ZExt))
1182911829
AssertOp = ISD::AssertZext;
11830-
11831-
ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i], NumParts,
11832-
PartVT, VT, nullptr, NewRoot,
11833-
F.getCallingConv(), AssertOp));
11830+
SDValue OutVal =
11831+
getCopyFromParts(DAG, dl, &InVals[i], NumParts, PartVT, VT, nullptr,
11832+
NewRoot, F.getCallingConv(), AssertOp);
11833+
if (Arg.hasAttribute(Attribute::NoFPClass) &&
11834+
OutVal.getValueType().isFloatingPoint()) {
11835+
SDNodeFlags OutValFlags = OutVal->getFlags();
11836+
bool NoSNaN = ((Arg.getNoFPClass() & llvm::fcSNan) == llvm::fcSNan);
11837+
bool NoQNaN = ((Arg.getNoFPClass() & llvm::fcQNan) == llvm::fcQNan);
11838+
bool NoInf = ((Arg.getNoFPClass() & llvm::fcInf) == llvm::fcInf);
11839+
bool NoNegZero =
11840+
((Arg.getNoFPClass() & llvm::fcInf) == llvm::fcNegZero);
11841+
OutValFlags.setNoSNaNs(NoSNaN);
11842+
OutValFlags.setNoQNaNs(NoQNaN);
11843+
OutValFlags.setNoInfs(NoInf);
11844+
OutValFlags.setNoSignedZeros(NoNegZero);
11845+
OutVal =
11846+
DAG.getNode(ISD::AssertNoFPClass, dl, VT, OutVal, OutValFlags);
11847+
}
11848+
ArgValues.push_back(OutVal);
1183411849
}
1183511850

1183611851
i += NumParts;

Diff for: llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
122122
case ISD::TokenFactor: return "TokenFactor";
123123
case ISD::AssertSext: return "AssertSext";
124124
case ISD::AssertZext: return "AssertZext";
125+
case ISD::AssertNoFPClass: return "AssertNoFPClass";
125126
case ISD::AssertAlign: return "AssertAlign";
126127

127128
case ISD::BasicBlock: return "BasicBlock";

Diff for: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -3265,6 +3265,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
32653265
return;
32663266
case ISD::AssertSext:
32673267
case ISD::AssertZext:
3268+
case ISD::AssertNoFPClass:
32683269
case ISD::AssertAlign:
32693270
ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0));
32703271
CurDAG->RemoveDeadNode(NodeToMatch);

0 commit comments

Comments
 (0)