Skip to content

Commit 0228b77

Browse files
authored
[SDAG] Add missing SoftenFloatRes legalization for FMODF (#129264)
This is needed on some ARM platforms.
1 parent 0ae1f0a commit 0228b77

File tree

3 files changed

+539
-13
lines changed

3 files changed

+539
-13
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
132132
case ISD::STRICT_FLDEXP: R = SoftenFloatRes_ExpOp(N); break;
133133
case ISD::FFREXP: R = SoftenFloatRes_FFREXP(N); break;
134134
case ISD::FSINCOS: R = SoftenFloatRes_FSINCOS(N); break;
135+
case ISD::FMODF: R = SoftenFloatRes_FMODF(N); break;
135136
case ISD::STRICT_FREM:
136137
case ISD::FREM: R = SoftenFloatRes_FREM(N); break;
137138
case ISD::STRICT_FRINT:
@@ -791,27 +792,35 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
791792
return ReturnVal;
792793
}
793794

794-
SDValue
795-
DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(SDNode *N,
796-
RTLIB::Libcall LC) {
795+
SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
796+
SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
797797
assert(!N->isStrictFPOpcode() && "strictfp not implemented");
798798
EVT VT = N->getValueType(0);
799799

800+
assert(VT == N->getValueType(1) &&
801+
"expected both return values to have the same type");
802+
800803
if (!TLI.getLibcallName(LC))
801804
return SDValue();
802805

803806
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
804-
SDValue FirstResultSlot = DAG.CreateStackTemporary(NVT);
805-
SDValue SecondResultSlot = DAG.CreateStackTemporary(NVT);
806807

807808
SDLoc DL(N);
808809

809-
TargetLowering::MakeLibCallOptions CallOptions;
810-
std::array Ops{GetSoftenedFloat(N->getOperand(0)), FirstResultSlot,
811-
SecondResultSlot};
812-
std::array OpsVT{VT, FirstResultSlot.getValueType(),
813-
SecondResultSlot.getValueType()};
810+
SmallVector<SDValue, 3> Ops = {GetSoftenedFloat(N->getOperand(0))};
811+
SmallVector<EVT, 3> OpsVT = {VT};
812+
813+
std::array<SDValue, 2> StackSlots;
814+
for (unsigned ResNum = 0; ResNum < N->getNumValues(); ++ResNum) {
815+
if (ResNum == CallRetResNo)
816+
continue;
817+
SDValue StackSlot = DAG.CreateStackTemporary(NVT);
818+
Ops.push_back(StackSlot);
819+
OpsVT.push_back(StackSlot.getValueType());
820+
StackSlots[ResNum] = StackSlot;
821+
}
814822

823+
TargetLowering::MakeLibCallOptions CallOptions;
815824
// TODO: setTypeListBeforeSoften can't properly express multiple return types,
816825
// but since both returns have the same type it should be okay.
817826
CallOptions.setTypeListBeforeSoften({OpsVT}, VT, true);
@@ -825,8 +834,14 @@ DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(SDNode *N,
825834
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx);
826835
return DAG.getLoad(NVT, DL, Chain, StackSlot, PtrInfo);
827836
};
828-
SetSoftenedFloat(SDValue(N, 0), CreateStackLoad(FirstResultSlot));
829-
SetSoftenedFloat(SDValue(N, 1), CreateStackLoad(SecondResultSlot));
837+
838+
for (auto [ResNum, SlackSlot] : enumerate(StackSlots)) {
839+
if (CallRetResNo == ResNum) {
840+
SetSoftenedFloat(SDValue(N, ResNum), ReturnVal);
841+
continue;
842+
}
843+
SetSoftenedFloat(SDValue(N, ResNum), CreateStackLoad(SlackSlot));
844+
}
830845

831846
return SDValue();
832847
}
@@ -836,6 +851,11 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS(SDNode *N) {
836851
N, RTLIB::getSINCOS(N->getValueType(0)));
837852
}
838853

854+
SDValue DAGTypeLegalizer::SoftenFloatRes_FMODF(SDNode *N) {
855+
return SoftenFloatRes_UnaryWithTwoFPResults(
856+
N, RTLIB::getMODF(N->getValueType(0)), /*CallRetResNo=*/0);
857+
}
858+
839859
SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {
840860
return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
841861
RTLIB::REM_F32,

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
562562
// Convert Float Results to Integer.
563563
void SoftenFloatResult(SDNode *N, unsigned ResNo);
564564
SDValue SoftenFloatRes_Unary(SDNode *N, RTLIB::Libcall LC);
565-
SDValue SoftenFloatRes_UnaryWithTwoFPResults(SDNode *N, RTLIB::Libcall LC);
565+
SDValue SoftenFloatRes_UnaryWithTwoFPResults(
566+
SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo = {});
566567
SDValue SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC);
567568
SDValue SoftenFloatRes_MERGE_VALUES(SDNode *N, unsigned ResNo);
568569
SDValue SoftenFloatRes_ARITH_FENCE(SDNode *N);
@@ -608,6 +609,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
608609
SDValue SoftenFloatRes_ExpOp(SDNode *N);
609610
SDValue SoftenFloatRes_FFREXP(SDNode *N);
610611
SDValue SoftenFloatRes_FSINCOS(SDNode *N);
612+
SDValue SoftenFloatRes_FMODF(SDNode *N);
611613
SDValue SoftenFloatRes_FREEZE(SDNode *N);
612614
SDValue SoftenFloatRes_FREM(SDNode *N);
613615
SDValue SoftenFloatRes_FRINT(SDNode *N);

0 commit comments

Comments
 (0)