@@ -127,6 +127,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
127127 case ISD::FLDEXP:
128128 case ISD::STRICT_FLDEXP: R = SoftenFloatRes_ExpOp (N); break ;
129129 case ISD::FFREXP: R = SoftenFloatRes_FFREXP (N); break ;
130+ case ISD::FSINCOS: R = SoftenFloatRes_FSINCOS (N); break ;
130131 case ISD::STRICT_FREM:
131132 case ISD::FREM: R = SoftenFloatRes_FREM (N); break ;
132133 case ISD::STRICT_FRINT:
@@ -765,6 +766,45 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
765766 return ReturnVal;
766767}
767768
769+ SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS (SDNode *N) {
770+ assert (!N->isStrictFPOpcode () && " strictfp not implemented for fsincos" );
771+ EVT VT = N->getValueType (0 );
772+ RTLIB::Libcall LC = RTLIB::getFSINCOS (VT);
773+
774+ if (!TLI.getLibcallName (LC))
775+ return SDValue ();
776+
777+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), VT);
778+ SDValue StackSlotSin = DAG.CreateStackTemporary (NVT);
779+ SDValue StackSlotCos = DAG.CreateStackTemporary (NVT);
780+
781+ SDLoc DL (N);
782+
783+ TargetLowering::MakeLibCallOptions CallOptions;
784+ std::array Ops{GetSoftenedFloat (N->getOperand (0 )), StackSlotSin,
785+ StackSlotCos};
786+ std::array OpsVT{VT, StackSlotSin.getValueType (),
787+ StackSlotCos.getValueType ()};
788+
789+ // TODO: setTypeListBeforeSoften can't properly express multiple return types,
790+ // but since both returns have the same type for sincos it should be okay.
791+ CallOptions.setTypeListBeforeSoften ({OpsVT}, VT, true );
792+
793+ auto [ReturnVal, Chain] = TLI.makeLibCall (DAG, LC, NVT, Ops, CallOptions, DL,
794+ /* Chain=*/ SDValue ());
795+ unsigned ResNo = 0 ;
796+ for (SDValue OutPtr : {StackSlotSin, StackSlotCos}) {
797+ int FrameIdx = cast<FrameIndexSDNode>(OutPtr)->getIndex ();
798+ auto PtrInfo =
799+ MachinePointerInfo::getFixedStack (DAG.getMachineFunction (), FrameIdx);
800+
801+ SDValue LoadExp = DAG.getLoad (NVT, DL, Chain, OutPtr, PtrInfo);
802+ SetSoftenedFloat (SDValue (N, ResNo++), LoadExp);
803+ }
804+
805+ return SDValue ();
806+ }
807+
768808SDValue DAGTypeLegalizer::SoftenFloatRes_FREM (SDNode *N) {
769809 return SoftenFloatRes_Binary (N, GetFPLibCall (N->getValueType (0 ),
770810 RTLIB::REM_F32,
@@ -2683,6 +2723,10 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
26832723 case ISD::FLDEXP: R = PromoteFloatRes_ExpOp (N); break ;
26842724 case ISD::FFREXP: R = PromoteFloatRes_FFREXP (N); break ;
26852725
2726+ case ISD::FSINCOS:
2727+ R = PromoteFloatRes_FSINCOS (N);
2728+ break ;
2729+
26862730 case ISD::FP_ROUND: R = PromoteFloatRes_FP_ROUND (N); break ;
26872731 case ISD::STRICT_FP_ROUND:
26882732 R = PromoteFloatRes_STRICT_FP_ROUND (N);
@@ -2878,6 +2922,18 @@ SDValue DAGTypeLegalizer::PromoteFloatRes_FFREXP(SDNode *N) {
28782922 return Res;
28792923}
28802924
2925+ SDValue DAGTypeLegalizer::PromoteFloatRes_FSINCOS (SDNode *N) {
2926+ EVT VT = N->getValueType (0 );
2927+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), VT);
2928+ SDValue Op = GetPromotedFloat (N->getOperand (0 ));
2929+ SDValue Res = DAG.getNode (N->getOpcode (), SDLoc (N), {NVT, NVT}, Op);
2930+
2931+ for (unsigned ResNum = 0 ; ResNum < N->getNumValues (); ResNum++)
2932+ SetPromotedFloat (SDValue (N, ResNum), Res.getValue (ResNum));
2933+
2934+ return SDValue ();
2935+ }
2936+
28812937// Explicit operation to reduce precision. Reduce the value to half precision
28822938// and promote it back to the legal type.
28832939SDValue DAGTypeLegalizer::PromoteFloatRes_FP_ROUND (SDNode *N) {
@@ -3126,6 +3182,10 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
31263182
31273183 case ISD::FFREXP: R = SoftPromoteHalfRes_FFREXP (N); break ;
31283184
3185+ case ISD::FSINCOS:
3186+ R = SoftPromoteHalfRes_FSINCOS (N);
3187+ break ;
3188+
31293189 case ISD::LOAD: R = SoftPromoteHalfRes_LOAD (N); break ;
31303190 case ISD::ATOMIC_LOAD:
31313191 R = SoftPromoteHalfRes_ATOMIC_LOAD (N);
@@ -3282,6 +3342,26 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FFREXP(SDNode *N) {
32823342 return DAG.getNode (GetPromotionOpcode (NVT, OVT), dl, MVT::i16 , Res);
32833343}
32843344
3345+ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FSINCOS (SDNode *N) {
3346+ EVT OVT = N->getValueType (0 );
3347+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), OVT);
3348+ SDValue Op = GetSoftPromotedHalf (N->getOperand (0 ));
3349+ SDLoc dl (N);
3350+
3351+ // Promote to the larger FP type.
3352+ Op = DAG.getNode (GetPromotionOpcode (OVT, NVT), dl, NVT, Op);
3353+ SDValue Res = DAG.getNode (N->getOpcode (), dl, DAG.getVTList (NVT, NVT), Op);
3354+
3355+ // Convert back to FP16 as an integer.
3356+ ISD::NodeType Truncate = GetPromotionOpcode (NVT, OVT);
3357+ for (unsigned ResNum = 0 ; ResNum < N->getNumValues (); ResNum++) {
3358+ SDValue Trunc = DAG.getNode (Truncate, dl, MVT::i16 , Res.getValue (ResNum));
3359+ SetSoftPromotedHalf (SDValue (N, ResNum), Trunc);
3360+ }
3361+
3362+ return SDValue ();
3363+ }
3364+
32853365SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND (SDNode *N) {
32863366 EVT RVT = N->getValueType (0 );
32873367 bool IsStrict = N->isStrictFPOpcode ();
0 commit comments