@@ -129,6 +129,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
129129 case ISD::FLDEXP:
130130 case ISD::STRICT_FLDEXP: R = SoftenFloatRes_ExpOp (N); break ;
131131 case ISD::FFREXP: R = SoftenFloatRes_FFREXP (N); break ;
132+ case ISD::FSINCOS: R = SoftenFloatRes_FSINCOS (N); break ;
132133 case ISD::STRICT_FREM:
133134 case ISD::FREM: R = SoftenFloatRes_FREM (N); break ;
134135 case ISD::STRICT_FRINT:
@@ -774,6 +775,45 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
774775 return ReturnVal;
775776}
776777
778+ SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS (SDNode *N) {
779+ assert (!N->isStrictFPOpcode () && " strictfp not implemented for fsincos" );
780+ EVT VT = N->getValueType (0 );
781+ RTLIB::Libcall LC = RTLIB::getFSINCOS (VT);
782+
783+ if (!TLI.getLibcallName (LC))
784+ return SDValue ();
785+
786+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), VT);
787+ SDValue StackSlotSin = DAG.CreateStackTemporary (NVT);
788+ SDValue StackSlotCos = DAG.CreateStackTemporary (NVT);
789+
790+ SDLoc DL (N);
791+
792+ TargetLowering::MakeLibCallOptions CallOptions;
793+ std::array Ops{GetSoftenedFloat (N->getOperand (0 )), StackSlotSin,
794+ StackSlotCos};
795+ std::array OpsVT{VT, StackSlotSin.getValueType (),
796+ StackSlotCos.getValueType ()};
797+
798+ // TODO: setTypeListBeforeSoften can't properly express multiple return types,
799+ // but since both returns have the same type for sincos it should be okay.
800+ CallOptions.setTypeListBeforeSoften ({OpsVT}, VT, true );
801+
802+ auto [ReturnVal, Chain] = TLI.makeLibCall (DAG, LC, NVT, Ops, CallOptions, DL,
803+ /* Chain=*/ SDValue ());
804+
805+ auto CreateStackLoad = [&, Chain = Chain](SDValue StackSlot) {
806+ int FrameIdx = cast<FrameIndexSDNode>(StackSlot)->getIndex ();
807+ auto PtrInfo =
808+ MachinePointerInfo::getFixedStack (DAG.getMachineFunction (), FrameIdx);
809+ return DAG.getLoad (NVT, DL, Chain, StackSlot, PtrInfo);
810+ };
811+ SetSoftenedFloat (SDValue (N, 0 ), CreateStackLoad (StackSlotSin));
812+ SetSoftenedFloat (SDValue (N, 1 ), CreateStackLoad (StackSlotCos));
813+
814+ return SDValue ();
815+ }
816+
777817SDValue DAGTypeLegalizer::SoftenFloatRes_FREM (SDNode *N) {
778818 return SoftenFloatRes_Binary (N, GetFPLibCall (N->getValueType (0 ),
779819 RTLIB::REM_F32,
@@ -2704,6 +2744,10 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
27042744 case ISD::FLDEXP: R = PromoteFloatRes_ExpOp (N); break ;
27052745 case ISD::FFREXP: R = PromoteFloatRes_FFREXP (N); break ;
27062746
2747+ case ISD::FSINCOS:
2748+ R = PromoteFloatRes_FSINCOS (N);
2749+ break ;
2750+
27072751 case ISD::FP_ROUND: R = PromoteFloatRes_FP_ROUND (N); break ;
27082752 case ISD::STRICT_FP_ROUND:
27092753 R = PromoteFloatRes_STRICT_FP_ROUND (N);
@@ -2899,6 +2943,20 @@ SDValue DAGTypeLegalizer::PromoteFloatRes_FFREXP(SDNode *N) {
28992943 return Res;
29002944}
29012945
2946+ SDValue DAGTypeLegalizer::PromoteFloatRes_FSINCOS (SDNode *N) {
2947+ EVT VT = N->getValueType (0 );
2948+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), VT);
2949+ SDValue Op = GetPromotedFloat (N->getOperand (0 ));
2950+ SDValue Res = DAG.getNode (N->getOpcode (), SDLoc (N), {NVT, NVT}, Op);
2951+
2952+ for (unsigned ResNum = 0 , NumValues = N->getNumValues (); ResNum < NumValues;
2953+ ++ResNum) {
2954+ SetPromotedFloat (SDValue (N, ResNum), Res.getValue (ResNum));
2955+ }
2956+
2957+ return SDValue ();
2958+ }
2959+
29022960// Explicit operation to reduce precision. Reduce the value to half precision
29032961// and promote it back to the legal type.
29042962SDValue DAGTypeLegalizer::PromoteFloatRes_FP_ROUND (SDNode *N) {
@@ -3148,6 +3206,10 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
31483206
31493207 case ISD::FFREXP: R = SoftPromoteHalfRes_FFREXP (N); break ;
31503208
3209+ case ISD::FSINCOS:
3210+ R = SoftPromoteHalfRes_FSINCOS (N);
3211+ break ;
3212+
31513213 case ISD::LOAD: R = SoftPromoteHalfRes_LOAD (N); break ;
31523214 case ISD::ATOMIC_LOAD:
31533215 R = SoftPromoteHalfRes_ATOMIC_LOAD (N);
@@ -3304,6 +3366,27 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FFREXP(SDNode *N) {
33043366 return DAG.getNode (GetPromotionOpcode (NVT, OVT), dl, MVT::i16 , Res);
33053367}
33063368
3369+ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FSINCOS (SDNode *N) {
3370+ EVT OVT = N->getValueType (0 );
3371+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), OVT);
3372+ SDValue Op = GetSoftPromotedHalf (N->getOperand (0 ));
3373+ SDLoc dl (N);
3374+
3375+ // Promote to the larger FP type.
3376+ Op = DAG.getNode (GetPromotionOpcode (OVT, NVT), dl, NVT, Op);
3377+ SDValue Res = DAG.getNode (N->getOpcode (), dl, DAG.getVTList (NVT, NVT), Op);
3378+
3379+ // Convert back to FP16 as an integer.
3380+ ISD::NodeType Truncate = GetPromotionOpcode (NVT, OVT);
3381+ for (unsigned ResNum = 0 , NumValues = N->getNumValues (); ResNum < NumValues;
3382+ ++ResNum) {
3383+ SDValue Trunc = DAG.getNode (Truncate, dl, MVT::i16 , Res.getValue (ResNum));
3384+ SetSoftPromotedHalf (SDValue (N, ResNum), Trunc);
3385+ }
3386+
3387+ return SDValue ();
3388+ }
3389+
33073390SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND (SDNode *N) {
33083391 EVT RVT = N->getValueType (0 );
33093392 bool IsStrict = N->isStrictFPOpcode ();
0 commit comments