@@ -115,7 +115,6 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
115115 case ISD::FMA: R = SoftenFloatRes_FMA (N); break ;
116116 case ISD::STRICT_FMUL:
117117 case ISD::FMUL: R = SoftenFloatRes_FMUL (N); break ;
118- case ISD::STRICT_FNEARBYINT:
119118 case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT (N); break ;
120119 case ISD::FNEG: R = SoftenFloatRes_FNEG (N); break ;
121120 case ISD::STRICT_FP_EXTEND:
@@ -227,6 +226,32 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC) {
227226 return Tmp.first ;
228227}
229228
229+ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOperation (SDNode *N,
230+ RTLIB::Libcall LC) {
231+ bool HasChain = N->hasChain ();
232+ assert (N->getNumValues () == 1 + HasChain &&
233+ " multiple result is not supported yet" );
234+ SDValue Chain = HasChain ? N->getOperand (0 ) : SDValue ();
235+ SmallVector<SDValue, 4 > Ops;
236+ SmallVector<EVT, 4 > OpsVT;
237+
238+ for (unsigned i = HasChain, e = N->getNumOperands (); i != e; ++i) {
239+ SDValue Op = N->getOperand (i);
240+ OpsVT.push_back (Op.getValueType ());
241+ Op = GetSoftenedFloat (Op);
242+ Ops.push_back (Op);
243+ }
244+
245+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), N->getValueType (0 ));
246+ TargetLowering::MakeLibCallOptions CallOptions;
247+ CallOptions.setTypeListBeforeSoften (OpsVT, N->getValueType (0 ));
248+ std::pair<SDValue, SDValue> Tmp =
249+ TLI.makeLibCall (DAG, LC, NVT, Ops, CallOptions, SDLoc (N), Chain);
250+ if (HasChain)
251+ ReplaceValueWith (SDValue (N, 1 ), Tmp.second );
252+ return Tmp.first ;
253+ }
254+
230255SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST (SDNode *N) {
231256 return BitConvertToInteger (N->getOperand (0 ));
232257}
@@ -582,7 +607,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
582607}
583608
584609SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT (SDNode *N) {
585- return SoftenFloatRes_Unary (N, GetFPLibCall (N->getValueType (0 ),
610+ return SoftenFloatRes_FPOperation (N, GetFPLibCall (N->getValueType (0 ),
586611 RTLIB::NEARBYINT_F32,
587612 RTLIB::NEARBYINT_F64,
588613 RTLIB::NEARBYINT_F80,
@@ -1596,7 +1621,6 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
15961621 case ISD::FMA: ExpandFloatRes_FMA (N, Lo, Hi); break ;
15971622 case ISD::STRICT_FMUL:
15981623 case ISD::FMUL: ExpandFloatRes_FMUL (N, Lo, Hi); break ;
1599- case ISD::STRICT_FNEARBYINT:
16001624 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT (N, Lo, Hi); break ;
16011625 case ISD::FNEG: ExpandFloatRes_FNEG (N, Lo, Hi); break ;
16021626 case ISD::STRICT_FP_EXTEND:
@@ -1688,6 +1712,21 @@ void DAGTypeLegalizer::ExpandFloatRes_Binary(SDNode *N, RTLIB::Libcall LC,
16881712 GetPairElements (Tmp.first , Lo, Hi);
16891713}
16901714
1715+ void DAGTypeLegalizer::ExpandFloatRes_FPOperation (SDNode *N, RTLIB::Libcall LC,
1716+ SDValue &Lo, SDValue &Hi) {
1717+ bool HasChain = N->hasChain ();
1718+ SDValue Chain = HasChain ? N->getOperand (0 ) : SDValue ();
1719+ assert (N->getNumValues () == 1 + HasChain &&
1720+ " multiple result is not supported yet" );
1721+ SmallVector<SDValue, 4 > Ops (HasChain ? llvm::drop_begin (N->ops ()) : N->ops ());
1722+ TargetLowering::MakeLibCallOptions CallOptions;
1723+ std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall (
1724+ DAG, LC, N->getValueType (0 ), Ops, CallOptions, SDLoc (N), Chain);
1725+ if (HasChain)
1726+ ReplaceValueWith (SDValue (N, 1 ), Tmp.second );
1727+ GetPairElements (Tmp.first , Lo, Hi);
1728+ }
1729+
16911730void DAGTypeLegalizer::ExpandFloatRes_FMODF (SDNode *N) {
16921731 ExpandFloatRes_UnaryWithTwoFPResults (N, RTLIB::getMODF (N->getValueType (0 )),
16931732 /* CallRetResNo=*/ 0 );
@@ -1951,7 +1990,7 @@ void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
19511990
19521991void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT (SDNode *N,
19531992 SDValue &Lo, SDValue &Hi) {
1954- ExpandFloatRes_Unary (N, GetFPLibCall (N->getValueType (0 ),
1993+ ExpandFloatRes_FPOperation (N, GetFPLibCall (N->getValueType (0 ),
19551994 RTLIB::NEARBYINT_F32,
19561995 RTLIB::NEARBYINT_F64,
19571996 RTLIB::NEARBYINT_F80,
@@ -2827,6 +2866,11 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
28272866 R = PromoteFloatRes_EXTRACT_VECTOR_ELT (N); break ;
28282867 case ISD::FCOPYSIGN: R = PromoteFloatRes_FCOPYSIGN (N); break ;
28292868
2869+ // Floating-point operations with optional chain.
2870+ case ISD::FNEARBYINT:
2871+ R = PromoteFloatRes_FPOperation (N);
2872+ break ;
2873+
28302874 // Unary FP Operations
28312875 case ISD::FABS:
28322876 case ISD::FACOS:
@@ -2843,7 +2887,6 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
28432887 case ISD::FLOG:
28442888 case ISD::FLOG2:
28452889 case ISD::FLOG10:
2846- case ISD::FNEARBYINT:
28472890 case ISD::FNEG:
28482891 case ISD::FRINT:
28492892 case ISD::FROUND:
@@ -3071,6 +3114,29 @@ SDValue DAGTypeLegalizer::PromoteFloatRes_BinOp(SDNode *N) {
30713114 return DAG.getNode (N->getOpcode (), SDLoc (N), NVT, Op0, Op1, N->getFlags ());
30723115}
30733116
3117+ SDValue DAGTypeLegalizer::PromoteFloatRes_FPOperation (SDNode *N) {
3118+ bool HasChain = N->hasChain ();
3119+ SDValue Chain = HasChain ? N->getOperand (0 ) : SDValue ();
3120+ assert (N->getNumValues () == 1 + HasChain &&
3121+ " multiple result is not supported yet" );
3122+ SmallVector<SDValue, 4 > Ops;
3123+
3124+ if (HasChain)
3125+ Ops.push_back (Chain);
3126+ for (unsigned i = HasChain, e = N->getNumOperands (); i != e; ++i) {
3127+ SDValue Op = N->getOperand (i);
3128+ // FIXME Use strict conversions for strict operations.
3129+ Op = GetPromotedFloat (Op);
3130+ Ops.push_back (Op);
3131+ }
3132+
3133+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), N->getValueType (0 ));
3134+ SDValue Res = DAG.getNode (N->getOpcode (), SDLoc (N), NVT, Ops);
3135+ if (HasChain)
3136+ ReplaceValueWith (SDValue (N, 1 ), Res.getValue (1 ));
3137+ return Res;
3138+ }
3139+
30743140SDValue DAGTypeLegalizer::PromoteFloatRes_FMAD (SDNode *N) {
30753141 EVT VT = N->getValueType (0 );
30763142 EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), VT);
@@ -3312,6 +3378,11 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
33123378 case ISD::STRICT_FP_ROUND:
33133379 case ISD::FP_ROUND: R = SoftPromoteHalfRes_FP_ROUND (N); break ;
33143380
3381+ // Floating-point operations with optional chain.
3382+ case ISD::FNEARBYINT:
3383+ R = SoftPromoteHalfRes_FPOperation (N);
3384+ break ;
3385+
33153386 // Unary FP Operations
33163387 case ISD::FACOS:
33173388 case ISD::FASIN:
@@ -3327,7 +3398,6 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
33273398 case ISD::FLOG:
33283399 case ISD::FLOG2:
33293400 case ISD::FLOG10:
3330- case ISD::FNEARBYINT:
33313401 case ISD::FREEZE:
33323402 case ISD::FRINT:
33333403 case ISD::FROUND:
@@ -3714,6 +3784,38 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_BinOp(SDNode *N) {
37143784 return DAG.getNode (GetPromotionOpcode (NVT, OVT), dl, MVT::i16 , Res);
37153785}
37163786
3787+ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FPOperation (SDNode *N) {
3788+ SDLoc dl (N);
3789+ bool HasChain = N->hasChain ();
3790+ assert (N->getNumValues () == 1 + HasChain &&
3791+ " multiple result is not supported yet" );
3792+ SDValue Chain = HasChain ? N->getOperand (0 ) : SDValue ();
3793+ EVT OVT = N->getValueType (0 );
3794+ EVT NVT = TLI.getTypeToTransformTo (*DAG.getContext (), OVT);
3795+ auto PromotionOpcode = GetPromotionOpcode (OVT, NVT);
3796+
3797+ SmallVector<SDValue, 4 > Ops;
3798+ if (HasChain)
3799+ Ops.push_back (Chain);
3800+ for (unsigned i = HasChain, e = N->getNumOperands (); i != e; ++i) {
3801+ SDValue Op = GetSoftPromotedHalf (N->getOperand (i));
3802+ // FIXME Use strict conversions for strict operations.
3803+ Op = DAG.getNode (PromotionOpcode, dl, NVT, Op);
3804+ Ops.push_back (Op);
3805+ }
3806+
3807+ SDValue Res = DAG.getNode (N->getOpcode (), SDLoc (N), NVT, Ops);
3808+ if (HasChain)
3809+ Chain = Res.getValue (1 );
3810+
3811+ // Convert back to FP16 as an integer.
3812+ Res = DAG.getNode (GetPromotionOpcode (NVT, OVT), dl, MVT::i16 , Res);
3813+
3814+ if (HasChain)
3815+ ReplaceValueWith (SDValue (N, 1 ), Chain);
3816+ return Res;
3817+ }
3818+
37173819SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE (SDNode *N) {
37183820 // Expand and soften recursively.
37193821 ReplaceValueWith (SDValue (N, 0 ), TLI.expandVecReduce (N, DAG));
0 commit comments