@@ -129,6 +129,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
129
129
case ISD::FLDEXP:
130
130
case ISD::STRICT_FLDEXP: R = SoftenFloatRes_ExpOp (N); break ;
131
131
case ISD::FFREXP: R = SoftenFloatRes_FFREXP (N); break ;
132
+ case ISD::FSINCOS: R = SoftenFloatRes_FSINCOS (N); break ;
132
133
case ISD::STRICT_FREM:
133
134
case ISD::FREM: R = SoftenFloatRes_FREM (N); break ;
134
135
case ISD::STRICT_FRINT:
@@ -774,6 +775,45 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
774
775
return ReturnVal;
775
776
}
776
777
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
+
777
817
SDValue DAGTypeLegalizer::SoftenFloatRes_FREM (SDNode *N) {
778
818
return SoftenFloatRes_Binary (N, GetFPLibCall (N->getValueType (0 ),
779
819
RTLIB::REM_F32,
@@ -2704,6 +2744,10 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
2704
2744
case ISD::FLDEXP: R = PromoteFloatRes_ExpOp (N); break ;
2705
2745
case ISD::FFREXP: R = PromoteFloatRes_FFREXP (N); break ;
2706
2746
2747
+ case ISD::FSINCOS:
2748
+ R = PromoteFloatRes_FSINCOS (N);
2749
+ break ;
2750
+
2707
2751
case ISD::FP_ROUND: R = PromoteFloatRes_FP_ROUND (N); break ;
2708
2752
case ISD::STRICT_FP_ROUND:
2709
2753
R = PromoteFloatRes_STRICT_FP_ROUND (N);
@@ -2899,6 +2943,20 @@ SDValue DAGTypeLegalizer::PromoteFloatRes_FFREXP(SDNode *N) {
2899
2943
return Res;
2900
2944
}
2901
2945
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
+
2902
2960
// Explicit operation to reduce precision. Reduce the value to half precision
2903
2961
// and promote it back to the legal type.
2904
2962
SDValue DAGTypeLegalizer::PromoteFloatRes_FP_ROUND (SDNode *N) {
@@ -3148,6 +3206,10 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
3148
3206
3149
3207
case ISD::FFREXP: R = SoftPromoteHalfRes_FFREXP (N); break ;
3150
3208
3209
+ case ISD::FSINCOS:
3210
+ R = SoftPromoteHalfRes_FSINCOS (N);
3211
+ break ;
3212
+
3151
3213
case ISD::LOAD: R = SoftPromoteHalfRes_LOAD (N); break ;
3152
3214
case ISD::ATOMIC_LOAD:
3153
3215
R = SoftPromoteHalfRes_ATOMIC_LOAD (N);
@@ -3304,6 +3366,27 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FFREXP(SDNode *N) {
3304
3366
return DAG.getNode (GetPromotionOpcode (NVT, OVT), dl, MVT::i16, Res);
3305
3367
}
3306
3368
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
+
3307
3390
SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND (SDNode *N) {
3308
3391
EVT RVT = N->getValueType (0 );
3309
3392
bool IsStrict = N->isStrictFPOpcode ();
0 commit comments