@@ -601,10 +601,20 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
601601 setOperationAction(ISD::FP_TO_SINT_SAT, MVT::i64, Custom);
602602 setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
603603
604- if (!Subtarget->hasVFP2Base())
604+ if (!Subtarget->hasVFP2Base()) {
605605 setAllExpand(MVT::f32);
606- if (!Subtarget->hasFP64())
606+ } else {
607+ for (auto Op : {ISD::STRICT_FADD, ISD::STRICT_FSUB, ISD::STRICT_FMUL,
608+ ISD::STRICT_FDIV, ISD::STRICT_FMA, ISD::STRICT_FSQRT})
609+ setOperationAction(Op, MVT::f32, Legal);
610+ }
611+ if (!Subtarget->hasFP64()) {
607612 setAllExpand(MVT::f64);
613+ } else {
614+ for (auto Op : {ISD::STRICT_FADD, ISD::STRICT_FSUB, ISD::STRICT_FMUL,
615+ ISD::STRICT_FDIV, ISD::STRICT_FMA, ISD::STRICT_FSQRT})
616+ setOperationAction(Op, MVT::f64, Legal);
617+ }
608618 }
609619
610620 if (Subtarget->hasFullFP16()) {
@@ -1281,12 +1291,16 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
12811291 if (!Subtarget->hasFPARMv8Base() || !Subtarget->hasFP64()) {
12821292 setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
12831293 setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);
1294+ setOperationAction(ISD::STRICT_FP16_TO_FP, MVT::f64, LibCall);
1295+ setOperationAction(ISD::STRICT_FP_TO_FP16, MVT::f64, LibCall);
12841296 }
12851297
12861298 // fp16 is a special v7 extension that adds f16 <-> f32 conversions.
12871299 if (!Subtarget->hasFP16()) {
12881300 setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
12891301 setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
1302+ setOperationAction(ISD::STRICT_FP16_TO_FP, MVT::f32, LibCall);
1303+ setOperationAction(ISD::STRICT_FP_TO_FP16, MVT::f32, LibCall);
12901304 }
12911305
12921306 // Strict floating-point comparisons need custom lowering.
@@ -1333,31 +1347,42 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
13331347 }
13341348
13351349 // FP16 often need to be promoted to call lib functions
1350+ // clang-format off
13361351 if (Subtarget->hasFullFP16()) {
1337- setOperationAction(ISD::FREM, MVT::f16, Promote);
1338- setOperationAction(ISD::FCOPYSIGN, MVT::f16, Expand);
1339- setOperationAction(ISD::FSIN, MVT::f16, Promote);
1340- setOperationAction(ISD::FCOS, MVT::f16, Promote);
1341- setOperationAction(ISD::FTAN, MVT::f16, Promote);
1342- setOperationAction(ISD::FSINCOS, MVT::f16, Promote);
1343- setOperationAction(ISD::FPOWI, MVT::f16, Promote);
1344- setOperationAction(ISD::FPOW, MVT::f16, Promote);
1345- setOperationAction(ISD::FEXP, MVT::f16, Promote);
1346- setOperationAction(ISD::FEXP2, MVT::f16, Promote);
1347- setOperationAction(ISD::FEXP10, MVT::f16, Promote);
1348- setOperationAction(ISD::FLOG, MVT::f16, Promote);
1349- setOperationAction(ISD::FLOG10, MVT::f16, Promote);
1350- setOperationAction(ISD::FLOG2, MVT::f16, Promote);
13511352 setOperationAction(ISD::LRINT, MVT::f16, Expand);
13521353 setOperationAction(ISD::LROUND, MVT::f16, Expand);
1353-
1354- setOperationAction(ISD::FROUND, MVT::f16, Legal);
1355- setOperationAction(ISD::FROUNDEVEN, MVT::f16, Legal);
1356- setOperationAction(ISD::FTRUNC, MVT::f16, Legal);
1357- setOperationAction(ISD::FNEARBYINT, MVT::f16, Legal);
1358- setOperationAction(ISD::FRINT, MVT::f16, Legal);
1359- setOperationAction(ISD::FFLOOR, MVT::f16, Legal);
1360- setOperationAction(ISD::FCEIL, MVT::f16, Legal);
1354+ setOperationAction(ISD::FCOPYSIGN, MVT::f16, Expand);
1355+
1356+ for (auto Op : {ISD::FREM, ISD::FPOW, ISD::FPOWI,
1357+ ISD::FCOS, ISD::FSIN, ISD::FSINCOS,
1358+ ISD::FSINCOSPI, ISD::FMODF, ISD::FACOS,
1359+ ISD::FASIN, ISD::FATAN, ISD::FATAN2,
1360+ ISD::FCOSH, ISD::FSINH, ISD::FTANH,
1361+ ISD::FTAN, ISD::FEXP, ISD::FEXP2,
1362+ ISD::FEXP10, ISD::FLOG, ISD::FLOG2,
1363+ ISD::FLOG10, ISD::STRICT_FREM, ISD::STRICT_FPOW,
1364+ ISD::STRICT_FPOWI, ISD::STRICT_FCOS, ISD::STRICT_FSIN,
1365+ ISD::STRICT_FACOS, ISD::STRICT_FASIN, ISD::STRICT_FATAN,
1366+ ISD::STRICT_FATAN2, ISD::STRICT_FCOSH, ISD::STRICT_FSINH,
1367+ ISD::STRICT_FTANH, ISD::STRICT_FEXP, ISD::STRICT_FEXP2,
1368+ ISD::STRICT_FLOG, ISD::STRICT_FLOG2, ISD::STRICT_FLOG10,
1369+ ISD::STRICT_FTAN}) {
1370+ setOperationAction(Op, MVT::f16, Promote);
1371+ }
1372+
1373+ // Round-to-integer need custom lowering for fp16, as Promote doesn't work
1374+ // because the result type is integer.
1375+ for (auto Op : {ISD::STRICT_LROUND, ISD::STRICT_LLROUND, ISD::STRICT_LRINT, ISD::STRICT_LLRINT})
1376+ setOperationAction(Op, MVT::f16, Custom);
1377+
1378+ for (auto Op : {ISD::FROUND, ISD::FROUNDEVEN, ISD::FTRUNC,
1379+ ISD::FNEARBYINT, ISD::FRINT, ISD::FFLOOR,
1380+ ISD::FCEIL, ISD::STRICT_FROUND, ISD::STRICT_FROUNDEVEN,
1381+ ISD::STRICT_FTRUNC, ISD::STRICT_FNEARBYINT, ISD::STRICT_FRINT,
1382+ ISD::STRICT_FFLOOR, ISD::STRICT_FCEIL}) {
1383+ setOperationAction(Op, MVT::f16, Legal);
1384+ }
1385+ // clang-format on
13611386 }
13621387
13631388 if (Subtarget->hasNEON()) {
@@ -10725,6 +10750,19 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1072510750 return LowerCMP(Op, DAG);
1072610751 case ISD::ABS:
1072710752 return LowerABS(Op, DAG);
10753+ case ISD::STRICT_LROUND:
10754+ case ISD::STRICT_LLROUND:
10755+ case ISD::STRICT_LRINT:
10756+ case ISD::STRICT_LLRINT: {
10757+ assert((Op.getOperand(1).getValueType() == MVT::f16 ||
10758+ Op.getOperand(1).getValueType() == MVT::bf16) &&
10759+ "Expected custom lowering of rounding operations only for f16");
10760+ SDLoc DL(Op);
10761+ SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
10762+ {Op.getOperand(0), Op.getOperand(1)});
10763+ return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
10764+ {Ext.getValue(1), Ext.getValue(0)});
10765+ }
1072810766 }
1072910767}
1073010768
0 commit comments