@@ -602,10 +602,20 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
602602 setOperationAction(ISD::FP_TO_SINT_SAT, MVT::i64, Custom);
603603 setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
604604
605- if (!Subtarget->hasVFP2Base())
605+ if (!Subtarget->hasVFP2Base()) {
606606 setAllExpand(MVT::f32);
607- if (!Subtarget->hasFP64())
607+ } else {
608+ for (auto Op : {ISD::STRICT_FADD, ISD::STRICT_FSUB, ISD::STRICT_FMUL,
609+ ISD::STRICT_FDIV, ISD::STRICT_FMA, ISD::STRICT_FSQRT})
610+ setOperationAction(Op, MVT::f32, Legal);
611+ }
612+ if (!Subtarget->hasFP64()) {
608613 setAllExpand(MVT::f64);
614+ } else {
615+ for (auto Op : {ISD::STRICT_FADD, ISD::STRICT_FSUB, ISD::STRICT_FMUL,
616+ ISD::STRICT_FDIV, ISD::STRICT_FMA, ISD::STRICT_FSQRT})
617+ setOperationAction(Op, MVT::f64, Legal);
618+ }
609619 }
610620
611621 if (Subtarget->hasFullFP16()) {
@@ -1338,29 +1348,42 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
13381348 }
13391349
13401350 // FP16 often need to be promoted to call lib functions
1351+ // clang-format off
13411352 if (Subtarget->hasFullFP16()) {
1342- setOperationAction(ISD::FREM, MVT::f16, Promote);
1353+ for (auto Op : {ISD::FREM, ISD::FPOW, ISD::FPOWI,
1354+ ISD::FCOS, ISD::FSIN, ISD::FSINCOS,
1355+ ISD::FSINCOSPI, ISD::FMODF, ISD::FACOS,
1356+ ISD::FASIN, ISD::FATAN, ISD::FATAN2,
1357+ ISD::FCOSH, ISD::FSINH, ISD::FTANH,
1358+ ISD::FTAN, ISD::FEXP, ISD::FEXP2,
1359+ ISD::FEXP10, ISD::FLOG, ISD::FLOG2,
1360+ ISD::FLOG10, ISD::STRICT_FREM, ISD::STRICT_FPOW,
1361+ ISD::STRICT_FPOWI, ISD::STRICT_FCOS, ISD::STRICT_FSIN,
1362+ ISD::STRICT_FACOS, ISD::STRICT_FASIN, ISD::STRICT_FATAN,
1363+ ISD::STRICT_FATAN2, ISD::STRICT_FCOSH, ISD::STRICT_FSINH,
1364+ ISD::STRICT_FTANH, ISD::STRICT_FEXP, ISD::STRICT_FEXP2,
1365+ ISD::STRICT_FLOG, ISD::STRICT_FLOG2, ISD::STRICT_FLOG10,
1366+ ISD::STRICT_FTAN}) {
1367+ setOperationAction(Op, MVT::f16, Promote);
1368+ }
1369+
1370+ // Round-to-integer need custom lowering for fp16, as Promote doesn't work
1371+ // because the result type is integer.
1372+ for (auto Op : {ISD::LROUND, ISD::LLROUND, ISD::LRINT, ISD::LLRINT,
1373+ ISD::STRICT_LROUND, ISD::STRICT_LLROUND, ISD::STRICT_LRINT,
1374+ ISD::STRICT_LLRINT})
1375+ setOperationAction(Op, MVT::f16, Custom);
1376+
1377+ for (auto Op : {ISD::FROUND, ISD::FROUNDEVEN, ISD::FTRUNC,
1378+ ISD::FNEARBYINT, ISD::FRINT, ISD::FFLOOR,
1379+ ISD::FCEIL, ISD::STRICT_FROUND, ISD::STRICT_FROUNDEVEN,
1380+ ISD::STRICT_FTRUNC, ISD::STRICT_FNEARBYINT, ISD::STRICT_FRINT,
1381+ ISD::STRICT_FFLOOR, ISD::STRICT_FCEIL}) {
1382+ setOperationAction(Op, MVT::f16, Legal);
1383+ }
1384+ // clang-format on
1385+
13431386 setOperationAction(ISD::FCOPYSIGN, MVT::f16, Expand);
1344- setOperationAction(ISD::FSIN, MVT::f16, Promote);
1345- setOperationAction(ISD::FCOS, MVT::f16, Promote);
1346- setOperationAction(ISD::FTAN, MVT::f16, Promote);
1347- setOperationAction(ISD::FSINCOS, MVT::f16, Promote);
1348- setOperationAction(ISD::FPOWI, MVT::f16, Promote);
1349- setOperationAction(ISD::FPOW, MVT::f16, Promote);
1350- setOperationAction(ISD::FEXP, MVT::f16, Promote);
1351- setOperationAction(ISD::FEXP2, MVT::f16, Promote);
1352- setOperationAction(ISD::FEXP10, MVT::f16, Promote);
1353- setOperationAction(ISD::FLOG, MVT::f16, Promote);
1354- setOperationAction(ISD::FLOG10, MVT::f16, Promote);
1355- setOperationAction(ISD::FLOG2, MVT::f16, Promote);
1356-
1357- setOperationAction(ISD::FROUND, MVT::f16, Legal);
1358- setOperationAction(ISD::FROUNDEVEN, MVT::f16, Legal);
1359- setOperationAction(ISD::FTRUNC, MVT::f16, Legal);
1360- setOperationAction(ISD::FNEARBYINT, MVT::f16, Legal);
1361- setOperationAction(ISD::FRINT, MVT::f16, Legal);
1362- setOperationAction(ISD::FFLOOR, MVT::f16, Legal);
1363- setOperationAction(ISD::FCEIL, MVT::f16, Legal);
13641387 }
13651388
13661389 if (Subtarget->hasNEON()) {
@@ -10721,6 +10744,30 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1072110744 return LowerCMP(Op, DAG);
1072210745 case ISD::ABS:
1072310746 return LowerABS(Op, DAG);
10747+ case ISD::LRINT:
10748+ case ISD::LLRINT:
10749+ case ISD::LROUND:
10750+ case ISD::LLROUND: {
10751+ assert((Op.getOperand(0).getValueType() == MVT::f16 ||
10752+ Op.getOperand(1).getValueType() == MVT::bf16) &&
10753+ "Expected custom lowering of rounding operations only for f16");
10754+ SDLoc DL(Op);
10755+ SDValue Ext = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Op.getOperand(0));
10756+ return DAG.getNode(Op.getOpcode(), DL, Op.getValueType(), Ext);
10757+ }
10758+ case ISD::STRICT_LROUND:
10759+ case ISD::STRICT_LLROUND:
10760+ case ISD::STRICT_LRINT:
10761+ case ISD::STRICT_LLRINT: {
10762+ assert((Op.getOperand(1).getValueType() == MVT::f16 ||
10763+ Op.getOperand(1).getValueType() == MVT::bf16) &&
10764+ "Expected custom lowering of rounding operations only for f16");
10765+ SDLoc DL(Op);
10766+ SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
10767+ {Op.getOperand(0), Op.getOperand(1)});
10768+ return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
10769+ {Ext.getValue(1), Ext.getValue(0)});
10770+ }
1072410771 }
1072510772}
1072610773
0 commit comments