@@ -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+
839859SDValue DAGTypeLegalizer::SoftenFloatRes_FREM (SDNode *N) {
840860 return SoftenFloatRes_Binary (N, GetFPLibCall (N->getValueType (0 ),
841861 RTLIB::REM_F32,
0 commit comments