Skip to content

Commit ebfff46

Browse files
committed
[LegalizeTypes][FPEnv][X86] Add initial support for softening strict fp nodes
This is based on what's required for softening fp128 operations on 32-bit X86 assuming f32/f64/f80 are legal. So there could be some things missing. Differential Revision: https://reviews.llvm.org/D70654
1 parent b19ec1e commit ebfff46

File tree

2 files changed

+932
-46
lines changed

2 files changed

+932
-46
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 146 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -65,35 +65,60 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
6565
case ISD::EXTRACT_VECTOR_ELT:
6666
R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N, ResNo); break;
6767
case ISD::FABS: R = SoftenFloatRes_FABS(N); break;
68+
case ISD::STRICT_FMINNUM:
6869
case ISD::FMINNUM: R = SoftenFloatRes_FMINNUM(N); break;
70+
case ISD::STRICT_FMAXNUM:
6971
case ISD::FMAXNUM: R = SoftenFloatRes_FMAXNUM(N); break;
72+
case ISD::STRICT_FADD:
7073
case ISD::FADD: R = SoftenFloatRes_FADD(N); break;
7174
case ISD::FCBRT: R = SoftenFloatRes_FCBRT(N); break;
75+
case ISD::STRICT_FCEIL:
7276
case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break;
7377
case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break;
78+
case ISD::STRICT_FCOS:
7479
case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break;
80+
case ISD::STRICT_FDIV:
7581
case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break;
82+
case ISD::STRICT_FEXP:
7683
case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break;
84+
case ISD::STRICT_FEXP2:
7785
case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break;
86+
case ISD::STRICT_FFLOOR:
7887
case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break;
88+
case ISD::STRICT_FLOG:
7989
case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break;
90+
case ISD::STRICT_FLOG2:
8091
case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break;
92+
case ISD::STRICT_FLOG10:
8193
case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break;
94+
case ISD::STRICT_FMA:
8295
case ISD::FMA: R = SoftenFloatRes_FMA(N); break;
96+
case ISD::STRICT_FMUL:
8397
case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break;
98+
case ISD::STRICT_FNEARBYINT:
8499
case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break;
85100
case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break;
101+
case ISD::STRICT_FP_EXTEND:
86102
case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break;
87103
case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break;
88104
case ISD::FP16_TO_FP: R = SoftenFloatRes_FP16_TO_FP(N); break;
105+
case ISD::STRICT_FPOW:
89106
case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break;
107+
case ISD::STRICT_FPOWI:
90108
case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break;
109+
case ISD::STRICT_FREM:
91110
case ISD::FREM: R = SoftenFloatRes_FREM(N); break;
111+
case ISD::STRICT_FRINT:
92112
case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break;
113+
case ISD::STRICT_FROUND:
93114
case ISD::FROUND: R = SoftenFloatRes_FROUND(N); break;
115+
case ISD::STRICT_FSIN:
94116
case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break;
117+
case ISD::STRICT_FSQRT:
95118
case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break;
119+
case ISD::STRICT_FSUB:
96120
case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break;
121+
case ISD::STRICT_FTRUNC:
97122
case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break;
98123
case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break;
99124
case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
@@ -113,25 +138,43 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
113138
}
114139

115140
SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(SDNode *N, RTLIB::Libcall LC) {
141+
bool IsStrict = N->isStrictFPOpcode();
116142
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
117-
assert(N->getNumOperands() == 1 && "Unexpected number of operands!");
118-
SDValue Op = GetSoftenedFloat(N->getOperand(0));
143+
unsigned Offset = IsStrict ? 1 : 0;
144+
assert(N->getNumOperands() == (1 + Offset) &&
145+
"Unexpected number of operands!");
146+
SDValue Op = GetSoftenedFloat(N->getOperand(0 + Offset));
147+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
119148
TargetLowering::MakeLibCallOptions CallOptions;
120-
EVT OpVT = N->getOperand(0).getValueType();
149+
EVT OpVT = N->getOperand(0 + Offset).getValueType();
121150
CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
122-
return TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, SDLoc(N)).first;
151+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
152+
CallOptions, SDLoc(N),
153+
Chain);
154+
if (IsStrict)
155+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
156+
return Tmp.first;
123157
}
124158

125159
SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC) {
160+
bool IsStrict = N->isStrictFPOpcode();
126161
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
127-
assert(N->getNumOperands() == 2 && "Unexpected number of operands!");
128-
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
129-
GetSoftenedFloat(N->getOperand(1)) };
162+
unsigned Offset = IsStrict ? 1 : 0;
163+
assert(N->getNumOperands() == (2 + Offset) &&
164+
"Unexpected number of operands!");
165+
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0 + Offset)),
166+
GetSoftenedFloat(N->getOperand(1 + Offset)) };
167+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
130168
TargetLowering::MakeLibCallOptions CallOptions;
131-
EVT OpsVT[2] = { N->getOperand(0).getValueType(),
132-
N->getOperand(1).getValueType() };
169+
EVT OpsVT[2] = { N->getOperand(0 + Offset).getValueType(),
170+
N->getOperand(1 + Offset).getValueType() };
133171
CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
134-
return TLI.makeLibCall(DAG, LC, NVT, Ops, CallOptions, SDLoc(N)).first;
172+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Ops,
173+
CallOptions, SDLoc(N),
174+
Chain);
175+
if (IsStrict)
176+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
177+
return Tmp.first;
135178
}
136179

137180
SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode *N) {
@@ -368,22 +411,29 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
368411
}
369412

370413
SDValue DAGTypeLegalizer::SoftenFloatRes_FMA(SDNode *N) {
414+
bool IsStrict = N->isStrictFPOpcode();
371415
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
372-
SDValue Ops[3] = { GetSoftenedFloat(N->getOperand(0)),
373-
GetSoftenedFloat(N->getOperand(1)),
374-
GetSoftenedFloat(N->getOperand(2)) };
416+
unsigned Offset = IsStrict ? 1 : 0;
417+
SDValue Ops[3] = { GetSoftenedFloat(N->getOperand(0 + Offset)),
418+
GetSoftenedFloat(N->getOperand(1 + Offset)),
419+
GetSoftenedFloat(N->getOperand(2 + Offset)) };
420+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
375421
TargetLowering::MakeLibCallOptions CallOptions;
376-
EVT OpsVT[3] = { N->getOperand(0).getValueType(),
377-
N->getOperand(1).getValueType(),
378-
N->getOperand(2).getValueType() };
422+
EVT OpsVT[3] = { N->getOperand(0 + Offset).getValueType(),
423+
N->getOperand(1 + Offset).getValueType(),
424+
N->getOperand(2 + Offset).getValueType() };
379425
CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
380-
return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0),
381-
RTLIB::FMA_F32,
382-
RTLIB::FMA_F64,
383-
RTLIB::FMA_F80,
384-
RTLIB::FMA_F128,
385-
RTLIB::FMA_PPCF128),
386-
NVT, Ops, CallOptions, SDLoc(N)).first;
426+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
427+
GetFPLibCall(N->getValueType(0),
428+
RTLIB::FMA_F32,
429+
RTLIB::FMA_F64,
430+
RTLIB::FMA_F80,
431+
RTLIB::FMA_F128,
432+
RTLIB::FMA_PPCF128),
433+
NVT, Ops, CallOptions, SDLoc(N), Chain);
434+
if (IsStrict)
435+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
436+
return Tmp.first;
387437
}
388438

389439
SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
@@ -430,14 +480,24 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
430480
}
431481

432482
SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
483+
bool IsStrict = N->isStrictFPOpcode();
433484
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
434-
SDValue Op = N->getOperand(0);
485+
SDValue Op = N->getOperand(IsStrict ? 1 : 0);
486+
487+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
435488

436489
// There's only a libcall for f16 -> f32, so proceed in two stages. Also, it's
437490
// entirely possible for both f16 and f32 to be legal, so use the fully
438491
// hard-float FP_EXTEND rather than FP16_TO_FP.
439492
if (Op.getValueType() == MVT::f16 && N->getValueType(0) != MVT::f32) {
440-
Op = DAG.getNode(ISD::FP_EXTEND, SDLoc(N), MVT::f32, Op);
493+
if (IsStrict) {
494+
Op = DAG.getNode(ISD::STRICT_FP_EXTEND, SDLoc(N),
495+
{ MVT::f32, MVT::Other }, { Chain, Op });
496+
Chain = Op.getValue(1);
497+
} else {
498+
Op = DAG.getNode(ISD::FP_EXTEND, SDLoc(N), MVT::f32, Op);
499+
}
500+
441501
if (getTypeAction(MVT::f32) == TargetLowering::TypeSoftenFloat)
442502
AddToWorklist(Op.getNode());
443503
}
@@ -456,7 +516,12 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
456516
TargetLowering::MakeLibCallOptions CallOptions;
457517
EVT OpsVT[1] = { N->getOperand(0).getValueType() };
458518
CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
459-
return TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, SDLoc(N)).first;
519+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
520+
CallOptions, SDLoc(N),
521+
Chain);
522+
if (IsStrict)
523+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
524+
return Tmp.first;
460525
}
461526

462527
// FIXME: Should we just use 'normal' FP_EXTEND / FP_TRUNC instead of special
@@ -505,7 +570,9 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
505570
}
506571

507572
SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
508-
assert(N->getOperand(1).getValueType() == MVT::i32 &&
573+
bool IsStrict = N->isStrictFPOpcode();
574+
unsigned Offset = IsStrict ? 1 : 0;
575+
assert(N->getOperand(1 + Offset).getValueType() == MVT::i32 &&
509576
"Unsupported power type!");
510577
RTLIB::Libcall LC = GetFPLibCall(N->getValueType(0),
511578
RTLIB::POWI_F32,
@@ -521,12 +588,19 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
521588
}
522589

523590
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
524-
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) };
591+
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0 + Offset)),
592+
N->getOperand(1 + Offset) };
593+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
525594
TargetLowering::MakeLibCallOptions CallOptions;
526-
EVT OpsVT[2] = { N->getOperand(0).getValueType(),
527-
N->getOperand(1).getValueType() };
595+
EVT OpsVT[2] = { N->getOperand(0 + Offset).getValueType(),
596+
N->getOperand(1 + Offset).getValueType() };
528597
CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
529-
return TLI.makeLibCall(DAG, LC, NVT, Ops, CallOptions, SDLoc(N)).first;
598+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Ops,
599+
CallOptions, SDLoc(N),
600+
Chain);
601+
if (IsStrict)
602+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
603+
return Tmp.first;
530604
}
531605

532606
SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {
@@ -718,12 +792,17 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
718792
case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break;
719793
case ISD::FP_EXTEND: Res = SoftenFloatOp_FP_EXTEND(N); break;
720794
case ISD::FP_TO_FP16: // Same as FP_ROUND for softening purposes
795+
case ISD::STRICT_FP_ROUND:
721796
case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
722797
case ISD::FP_TO_SINT:
723798
case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_XINT(N); break;
799+
case ISD::STRICT_LROUND:
724800
case ISD::LROUND: Res = SoftenFloatOp_LROUND(N); break;
801+
case ISD::STRICT_LLROUND:
725802
case ISD::LLROUND: Res = SoftenFloatOp_LLROUND(N); break;
803+
case ISD::STRICT_LRINT:
726804
case ISD::LRINT: Res = SoftenFloatOp_LRINT(N); break;
805+
case ISD::STRICT_LLRINT:
727806
case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(N); break;
728807
case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
729808
case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
@@ -774,20 +853,31 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_EXTEND(SDNode *N) {
774853
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
775854
// We actually deal with the partially-softened FP_TO_FP16 node too, which
776855
// returns an i16 so doesn't meet the constraints necessary for FP_ROUND.
777-
assert(N->getOpcode() == ISD::FP_ROUND || N->getOpcode() == ISD::FP_TO_FP16);
856+
assert(N->getOpcode() == ISD::FP_ROUND || N->getOpcode() == ISD::FP_TO_FP16 ||
857+
N->getOpcode() == ISD::STRICT_FP_ROUND);
778858

779-
EVT SVT = N->getOperand(0).getValueType();
859+
bool IsStrict = N->isStrictFPOpcode();
860+
SDValue Op = N->getOperand(IsStrict ? 1 : 0);
861+
EVT SVT = Op.getValueType();
780862
EVT RVT = N->getValueType(0);
781863
EVT FloatRVT = N->getOpcode() == ISD::FP_TO_FP16 ? MVT::f16 : RVT;
782864

783865
RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, FloatRVT);
784866
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
785867

786-
SDValue Op = GetSoftenedFloat(N->getOperand(0));
868+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
869+
Op = GetSoftenedFloat(Op);
787870
TargetLowering::MakeLibCallOptions CallOptions;
788-
EVT OpsVT[1] = { N->getOperand(0).getValueType() };
789-
CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
790-
return TLI.makeLibCall(DAG, LC, RVT, Op, CallOptions, SDLoc(N)).first;
871+
CallOptions.setTypeListBeforeSoften(SVT, RVT, true);
872+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RVT, Op,
873+
CallOptions, SDLoc(N),
874+
Chain);
875+
if (IsStrict) {
876+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
877+
ReplaceValueWith(SDValue(N, 0), Tmp.first);
878+
return SDValue();
879+
}
880+
return Tmp.first;
791881
}
792882

793883
SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
@@ -947,15 +1037,27 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FCOPYSIGN(SDNode *N) {
9471037

9481038
SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(SDNode *N, RTLIB::Libcall LC) {
9491039
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
950-
SDValue Op = GetSoftenedFloat(N->getOperand(0));
1040+
bool IsStrict = N->isStrictFPOpcode();
1041+
unsigned Offset = IsStrict ? 1 : 0;
1042+
SDValue Op = GetSoftenedFloat(N->getOperand(0 + Offset));
1043+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
9511044
TargetLowering::MakeLibCallOptions CallOptions;
952-
EVT OpVT = N->getOperand(0).getValueType();
1045+
EVT OpVT = N->getOperand(0 + Offset).getValueType();
9531046
CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
954-
return TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, SDLoc(N)).first;
1047+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
1048+
CallOptions, SDLoc(N),
1049+
Chain);
1050+
if (IsStrict) {
1051+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
1052+
ReplaceValueWith(SDValue(N, 0), Tmp.first);
1053+
return SDValue();
1054+
}
1055+
1056+
return Tmp.first;
9551057
}
9561058

9571059
SDValue DAGTypeLegalizer::SoftenFloatOp_LROUND(SDNode *N) {
958-
EVT OpVT = N->getOperand(0).getValueType();
1060+
EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
9591061
return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
9601062
RTLIB::LROUND_F32,
9611063
RTLIB::LROUND_F64,
@@ -965,7 +1067,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_LROUND(SDNode *N) {
9651067
}
9661068

9671069
SDValue DAGTypeLegalizer::SoftenFloatOp_LLROUND(SDNode *N) {
968-
EVT OpVT = N->getOperand(0).getValueType();
1070+
EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
9691071
return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
9701072
RTLIB::LLROUND_F32,
9711073
RTLIB::LLROUND_F64,
@@ -975,7 +1077,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_LLROUND(SDNode *N) {
9751077
}
9761078

9771079
SDValue DAGTypeLegalizer::SoftenFloatOp_LRINT(SDNode *N) {
978-
EVT OpVT = N->getOperand(0).getValueType();
1080+
EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
9791081
return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
9801082
RTLIB::LRINT_F32,
9811083
RTLIB::LRINT_F64,
@@ -985,7 +1087,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_LRINT(SDNode *N) {
9851087
}
9861088

9871089
SDValue DAGTypeLegalizer::SoftenFloatOp_LLRINT(SDNode *N) {
988-
EVT OpVT = N->getOperand(0).getValueType();
1090+
EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
9891091
return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
9901092
RTLIB::LLRINT_F32,
9911093
RTLIB::LLRINT_F64,

0 commit comments

Comments
 (0)