diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 91a2db163f2..611cc48a31f 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -301,6 +301,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, setOperationAction(ISD::FTRUNC, MVT::f16, Promote); setOperationAction(ISD::FMINNUM, MVT::f16, Promote); setOperationAction(ISD::FMAXNUM, MVT::f16, Promote); + setOperationAction(ISD::FMINNAN, MVT::f16, Promote); + setOperationAction(ISD::FMAXNAN, MVT::f16, Promote); // v4f16 is also a storage-only type, so promote it to v4f32 when that is // known to be safe. @@ -681,8 +683,8 @@ void AArch64TargetLowering::addTypeForNEON(EVT VT, EVT PromotedBitwiseVT) { ISD::SABSDIFF, ISD::UABSDIFF}) setOperationAction(Opcode, VT.getSimpleVT(), Legal); - // F[MIN|MAX][NUM|NAN] are available for all FP NEON types. - if (VT.isFloatingPoint()) + // F[MIN|MAX][NUM|NAN] are available for all FP NEON types (not f16 though!). + if (VT.isFloatingPoint() && VT.getVectorElementType() != MVT::f16) for (unsigned Opcode : {ISD::FMINNAN, ISD::FMAXNAN, ISD::FMINNUM, ISD::FMAXNUM}) setOperationAction(Opcode, VT.getSimpleVT(), Legal); diff --git a/test/CodeGen/AArch64/arm64-fmax.ll b/test/CodeGen/AArch64/arm64-fmax.ll index 470be6aa5df..40cc36ea52f 100644 --- a/test/CodeGen/AArch64/arm64-fmax.ll +++ b/test/CodeGen/AArch64/arm64-fmax.ll @@ -51,3 +51,14 @@ define i64 @test_integer(i64 %in) { %val = select i1 %cmp, i64 0, i64 %in ret i64 %val } + +define float @test_f16(half %in) { +; CHECK-LABEL: test_f16: + %cmp = fcmp nnan ult half %in, 0.000000e+00 + %val = select i1 %cmp, half %in, half 0.000000e+00 + %longer = fpext half %val to float + ret float %longer +; FIXME: It'd be nice for this to create an fmin instruction! +; CHECK: fcvt +; CHECK: fcsel +}