Skip to content

Commit 7020dbc

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.
1 parent 136f257 commit 7020dbc

File tree

6 files changed

+1316
-6
lines changed

6 files changed

+1316
-6
lines changed

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

+13-5
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,19 +416,23 @@ 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,
426+
NonNeg | NoSNaNs | NoQNaNs | NoInfs | SameSign,
424427
};
425428

426429
/// Default constructor turns off all optimization flags.
427430
SDNodeFlags(unsigned Flags = SDNodeFlags::None) : Flags(Flags) {}
428431

429432
/// Propagate the fast-math-flags from an IR FPMathOperator.
430433
void copyFMF(const FPMathOperator &FPMO) {
431-
setNoNaNs(FPMO.hasNoNaNs());
434+
setNoSNaNs(FPMO.hasNoNaNs());
435+
setNoQNaNs(FPMO.hasNoNaNs());
432436
setNoInfs(FPMO.hasNoInfs());
433437
setNoSignedZeros(FPMO.hasNoSignedZeros());
434438
setAllowReciprocal(FPMO.hasAllowReciprocal());
@@ -444,7 +448,9 @@ struct SDNodeFlags {
444448
void setDisjoint(bool b) { setFlag<Disjoint>(b); }
445449
void setSameSign(bool b) { setFlag<SameSign>(b); }
446450
void setNonNeg(bool b) { setFlag<NonNeg>(b); }
447-
void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
451+
void setNoNaNs(bool b) { setFlag<NoSNaNs>(b); setFlag<NoQNaNs>(b); }
452+
void setNoSNaNs(bool b) { setFlag<NoSNaNs>(b); }
453+
void setNoQNaNs(bool b) { setFlag<NoQNaNs>(b); }
448454
void setNoInfs(bool b) { setFlag<NoInfs>(b); }
449455
void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
450456
void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
@@ -461,7 +467,9 @@ struct SDNodeFlags {
461467
bool hasDisjoint() const { return Flags & Disjoint; }
462468
bool hasSameSign() const { return Flags & SameSign; }
463469
bool hasNonNeg() const { return Flags & NonNeg; }
464-
bool hasNoNaNs() const { return Flags & NoNaNs; }
470+
bool hasNoNaNs() const { return (Flags & NoSNaNs) && (Flags & NoQNaNs); }
471+
bool hasNoSNaNs() const { return Flags & NoSNaNs; }
472+
bool hasNoQNaNs() const { return Flags & NoQNaNs; }
465473
bool hasNoInfs() const { return Flags & NoInfs; }
466474
bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
467475
bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -5613,7 +5613,12 @@ bool SelectionDAG::isBaseWithConstantOffset(SDValue Op) const {
56135613

56145614
bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const {
56155615
// If we're told that NaNs won't happen, assume they won't.
5616-
if (getTarget().Options.NoNaNsFPMath || Op->getFlags().hasNoNaNs())
5616+
if (getTarget().Options.NoNaNsFPMath)
5617+
return true;
5618+
SDNodeFlags OpFlags = Op->getFlags();
5619+
if (SNaN && OpFlags.hasNoSNaNs())
5620+
return true;
5621+
if (OpFlags.hasNoSNaNs() && OpFlags.hasNoQNaNs())
56175622
return true;
56185623

56195624
if (Depth >= MaxRecursionDepth)

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

+10
Original file line numberDiff line numberDiff line change
@@ -11885,6 +11885,16 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
1188511885
AssertOp = ISD::AssertSext;
1188611886
else if (Arg.hasAttribute(Attribute::ZExt))
1188711887
AssertOp = ISD::AssertZext;
11888+
if (Arg.hasAttribute(Attribute::NoFPClass)) {
11889+
SDNodeFlags InValFlags = InVals[i]->getFlags();
11890+
bool NoSNaN = ((Arg.getNoFPClass() & llvm::fcSNan) == llvm::fcSNan);
11891+
bool NoQNaN = ((Arg.getNoFPClass() & llvm::fcQNan) == llvm::fcQNan);
11892+
InValFlags.setNoSNaNs(NoSNaN);
11893+
InValFlags.setNoQNaNs(NoQNaN);
11894+
InValFlags.setNoInfs((Arg.getNoFPClass() & llvm::fcInf) ==
11895+
llvm::fcInf);
11896+
InVals[i]->setFlags(InValFlags);
11897+
}
1188811898

1188911899
ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i], NumParts,
1189011900
PartVT, VT, nullptr, NewRoot,

0 commit comments

Comments
 (0)