Skip to content

Commit 780054d

Browse files
authored
CodeGen: Add ISD::AssertNoFPClass (#138839)
It is used to mark a value that we are sure that it is not some fcType. The examples include: * An arguments of a function is marked with nofpclass * Output value of an intrinsic can be sure to not be some type So that the following operation can make some assumptions.
1 parent c15539c commit 780054d

File tree

13 files changed

+546
-5
lines changed

13 files changed

+546
-5
lines changed

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ 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+
/// This node takes two operands. The first is the node that is known
73+
/// never to be some float types; the second is a constant value with
74+
/// the value of FPClassTest (casted to uint32_t).
75+
/// NOTE: In case of the source value (or any vector element value) is
76+
/// poisoned the assertion will not be true for that value.
77+
AssertNoFPClass,
78+
7079
/// Various leaf nodes.
7180
BasicBlock,
7281
VALUETYPE,

llvm/include/llvm/Target/TargetSelectionDAG.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@ def SDT_assert : SDTypeProfile<1, 1,
875875
[SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
876876
def assertsext : SDNode<"ISD::AssertSext", SDT_assert>;
877877
def assertzext : SDNode<"ISD::AssertZext", SDT_assert>;
878+
def assertnofpclass : SDNode<"ISD::AssertNoFPClass", SDTFPUnaryOp>;
878879
def assertalign : SDNode<"ISD::AssertAlign", SDT_assert>;
879880

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

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 25 additions & 1 deletion
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:
@@ -2582,6 +2583,7 @@ bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
25822583
case ISD::LLROUND:
25832584
case ISD::LRINT:
25842585
case ISD::LLRINT: R = PromoteFloatOp_UnaryOp(N, OpNo); break;
2586+
case ISD::AssertNoFPClass: R = PromoteFloatOp_AssertNoFPClass(N, OpNo); break;
25852587
case ISD::FP_TO_SINT_SAT:
25862588
case ISD::FP_TO_UINT_SAT:
25872589
R = PromoteFloatOp_FP_TO_XINT_SAT(N, OpNo); break;
@@ -2640,6 +2642,12 @@ SDValue DAGTypeLegalizer::PromoteFloatOp_UnaryOp(SDNode *N, unsigned OpNo) {
26402642
return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op);
26412643
}
26422644

2645+
// Convert the promoted float value to the desired integer type
2646+
SDValue DAGTypeLegalizer::PromoteFloatOp_AssertNoFPClass(SDNode *N,
2647+
unsigned OpNo) {
2648+
return GetPromotedFloat(N->getOperand(0));
2649+
}
2650+
26432651
SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N,
26442652
unsigned OpNo) {
26452653
SDValue Op = GetPromotedFloat(N->getOperand(0));
@@ -2804,6 +2812,9 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
28042812
case ISD::FTAN:
28052813
case ISD::FTANH:
28062814
case ISD::FCANONICALIZE: R = PromoteFloatRes_UnaryOp(N); break;
2815+
case ISD::AssertNoFPClass:
2816+
R = PromoteFloatRes_AssertNoFPClass(N);
2817+
break;
28072818

28082819
// Binary FP Operations
28092820
case ISD::FADD:
@@ -2996,10 +3007,16 @@ SDValue DAGTypeLegalizer::PromoteFloatRes_UnaryOp(SDNode *N) {
29963007
EVT VT = N->getValueType(0);
29973008
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
29983009
SDValue Op = GetPromotedFloat(N->getOperand(0));
2999-
30003010
return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op);
30013011
}
30023012

3013+
// Unary operation with a more non-float operand where the result and the
3014+
// operand have PromoteFloat type action. Construct a new SDNode with the
3015+
// promoted float value of the old operand.
3016+
SDValue DAGTypeLegalizer::PromoteFloatRes_AssertNoFPClass(SDNode *N) {
3017+
return GetPromotedFloat(N->getOperand(0));
3018+
}
3019+
30033020
// Binary operations where the result and both operands have PromoteFloat type
30043021
// action. Construct a new SDNode with the promoted float values of the old
30053022
// operands.
@@ -3281,6 +3298,9 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
32813298
case ISD::FTAN:
32823299
case ISD::FTANH:
32833300
case ISD::FCANONICALIZE: R = SoftPromoteHalfRes_UnaryOp(N); break;
3301+
case ISD::AssertNoFPClass:
3302+
R = SoftPromoteHalfRes_AssertNoFPClass(N);
3303+
break;
32843304

32853305
// Binary FP Operations
32863306
case ISD::FADD:
@@ -3607,6 +3627,10 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryOp(SDNode *N) {
36073627
return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
36083628
}
36093629

3630+
SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(SDNode *N) {
3631+
return GetSoftPromotedHalf(N->getOperand(0));
3632+
}
3633+
36103634
SDValue DAGTypeLegalizer::SoftPromoteHalfRes_BinOp(SDNode *N) {
36113635
EVT OVT = N->getValueType(0);
36123636
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
772772
SDValue PromoteFloatRes_SELECT(SDNode *N);
773773
SDValue PromoteFloatRes_SELECT_CC(SDNode *N);
774774
SDValue PromoteFloatRes_UnaryOp(SDNode *N);
775+
SDValue PromoteFloatRes_AssertNoFPClass(SDNode *N);
775776
SDValue PromoteFloatRes_UNDEF(SDNode *N);
776777
SDValue BitcastToInt_ATOMIC_SWAP(SDNode *N);
777778
SDValue PromoteFloatRes_XINT_TO_FP(SDNode *N);
@@ -785,6 +786,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
785786
SDValue PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo);
786787
SDValue PromoteFloatOp_STRICT_FP_EXTEND(SDNode *N, unsigned OpNo);
787788
SDValue PromoteFloatOp_UnaryOp(SDNode *N, unsigned OpNo);
789+
SDValue PromoteFloatOp_AssertNoFPClass(SDNode *N, unsigned OpNo);
788790
SDValue PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N, unsigned OpNo);
789791
SDValue PromoteFloatOp_STORE(SDNode *N, unsigned OpNo);
790792
SDValue PromoteFloatOp_ATOMIC_STORE(SDNode *N, unsigned OpNo);
@@ -820,6 +822,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
820822
SDValue SoftPromoteHalfRes_SELECT(SDNode *N);
821823
SDValue SoftPromoteHalfRes_SELECT_CC(SDNode *N);
822824
SDValue SoftPromoteHalfRes_UnaryOp(SDNode *N);
825+
SDValue SoftPromoteHalfRes_AssertNoFPClass(SDNode *N);
823826
SDValue SoftPromoteHalfRes_XINT_TO_FP(SDNode *N);
824827
SDValue SoftPromoteHalfRes_UNDEF(SDNode *N);
825828
SDValue SoftPromoteHalfRes_VECREDUCE(SDNode *N);

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
6161
case ISD::AssertZext:
6262
case ISD::AssertSext:
6363
case ISD::FPOWI:
64+
case ISD::AssertNoFPClass:
6465
R = ScalarizeVecRes_UnaryOpWithExtraInput(N);
6566
break;
6667
case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
@@ -1276,6 +1277,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
12761277
case ISD::UINT_TO_FP:
12771278
case ISD::VP_UINT_TO_FP:
12781279
case ISD::FCANONICALIZE:
1280+
case ISD::AssertNoFPClass:
12791281
SplitVecRes_UnaryOp(N, Lo, Hi);
12801282
break;
12811283
case ISD::ADDRSPACECAST:
@@ -2614,7 +2616,7 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
26142616
const SDNodeFlags Flags = N->getFlags();
26152617
unsigned Opcode = N->getOpcode();
26162618
if (N->getNumOperands() <= 2) {
2617-
if (Opcode == ISD::FP_ROUND) {
2619+
if (Opcode == ISD::FP_ROUND || Opcode == ISD::AssertNoFPClass) {
26182620
Lo = DAG.getNode(Opcode, dl, LoVT, Lo, N->getOperand(1), Flags);
26192621
Hi = DAG.getNode(Opcode, dl, HiVT, Hi, N->getOperand(1), Flags);
26202622
} else {
@@ -4872,6 +4874,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
48724874
case ISD::FREEZE:
48734875
case ISD::ARITH_FENCE:
48744876
case ISD::FCANONICALIZE:
4877+
case ISD::AssertNoFPClass:
48754878
Res = WidenVecRes_Unary(N);
48764879
break;
48774880
case ISD::FMA: case ISD::VP_FMA:
@@ -5616,6 +5619,9 @@ SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) {
56165619
SDValue InOp = GetWidenedVector(N->getOperand(0));
56175620
if (N->getNumOperands() == 1)
56185621
return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, N->getFlags());
5622+
if (N->getOpcode() == ISD::AssertNoFPClass)
5623+
return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp,
5624+
N->getOperand(1), N->getFlags());
56195625

56205626
assert(N->getNumOperands() == 3 && "Unexpected number of operands!");
56215627
assert(N->isVPOpcode() && "Expected VP opcode");

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5831,6 +5831,15 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
58315831
return false;
58325832
return true;
58335833
}
5834+
case ISD::AssertNoFPClass: {
5835+
FPClassTest NoFPClass =
5836+
static_cast<FPClassTest>(Op.getConstantOperandVal(1));
5837+
if ((NoFPClass & fcNan) == fcNan)
5838+
return true;
5839+
if (SNaN && (NoFPClass & fcSNan) == fcSNan)
5840+
return true;
5841+
return isKnownNeverNaN(Op.getOperand(0), DemandedElts, SNaN, Depth + 1);
5842+
}
58345843
default:
58355844
if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
58365845
Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID) {
@@ -7490,6 +7499,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
74907499
N2.getOpcode() == ISD::TargetConstant && "Invalid FP_ROUND!");
74917500
if (N1.getValueType() == VT) return N1; // noop conversion.
74927501
break;
7502+
case ISD::AssertNoFPClass: {
7503+
assert(N1.getValueType().isFloatingPoint() &&
7504+
"AssertNoFPClass is used for a non-floating type");
7505+
assert(isa<ConstantSDNode>(N2) && "NoFPClass is not Constant");
7506+
FPClassTest NoFPClass = static_cast<FPClassTest>(N2->getAsZExtVal());
7507+
assert(llvm::to_underlying(NoFPClass) <=
7508+
BitmaskEnumDetail::Mask<FPClassTest>() &&
7509+
"FPClassTest value too large");
7510+
break;
7511+
}
74937512
case ISD::AssertSext:
74947513
case ISD::AssertZext: {
74957514
EVT EVT = cast<VTSDNode>(N2)->getVT();

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11803,9 +11803,18 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
1180311803
else if (Arg.hasAttribute(Attribute::ZExt))
1180411804
AssertOp = ISD::AssertZext;
1180511805

11806-
ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i], NumParts,
11807-
PartVT, VT, nullptr, NewRoot,
11808-
F.getCallingConv(), AssertOp));
11806+
SDValue OutVal =
11807+
getCopyFromParts(DAG, dl, &InVals[i], NumParts, PartVT, VT, nullptr,
11808+
NewRoot, F.getCallingConv(), AssertOp);
11809+
11810+
FPClassTest NoFPClass = Arg.getNoFPClass();
11811+
if (NoFPClass != fcNone) {
11812+
SDValue SDNoFPClass = DAG.getTargetConstant(
11813+
static_cast<uint64_t>(NoFPClass), dl, MVT::i32);
11814+
OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(),
11815+
OutVal, SDNoFPClass);
11816+
}
11817+
ArgValues.push_back(OutVal);
1180911818
}
1181011819

1181111820
i += NumParts;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
124124
case ISD::TokenFactor: return "TokenFactor";
125125
case ISD::AssertSext: return "AssertSext";
126126
case ISD::AssertZext: return "AssertZext";
127+
case ISD::AssertNoFPClass: return "AssertNoFPClass";
127128
case ISD::AssertAlign: return "AssertAlign";
128129

129130
case ISD::BasicBlock: return "BasicBlock";

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3264,6 +3264,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
32643264
return;
32653265
case ISD::AssertSext:
32663266
case ISD::AssertZext:
3267+
case ISD::AssertNoFPClass:
32673268
case ISD::AssertAlign:
32683269
ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0));
32693270
CurDAG->RemoveDeadNode(NodeToMatch);

0 commit comments

Comments
 (0)