Index: llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -68,6 +68,7 @@ case ISD::FMINNUM: R = SoftenFloatRes_FMINNUM(N); break; case ISD::FMAXNUM: R = SoftenFloatRes_FMAXNUM(N); break; case ISD::FADD: R = SoftenFloatRes_FADD(N); break; + case ISD::FCBRT: R = SoftenFloatRes_FCBRT(N); break; case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; @@ -224,6 +225,21 @@ NVT, Ops, CallOptions, SDLoc(N)).first; } +SDValue DAGTypeLegalizer::SoftenFloatRes_FCBRT(SDNode *N) { + EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + TargetLowering::MakeLibCallOptions CallOptions; + EVT OpsVT[1] = { N->getOperand(0).getValueType() }; + CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true); + return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), + RTLIB::CBRT_F32, + RTLIB::CBRT_F64, + RTLIB::CBRT_F80, + RTLIB::CBRT_F128, + RTLIB::CBRT_PPCF128), + NVT, Op, CallOptions, SDLoc(N)).first; +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); SDValue Op = GetSoftenedFloat(N->getOperand(0)); @@ -1125,6 +1141,7 @@ case ISD::FMINNUM: ExpandFloatRes_FMINNUM(N, Lo, Hi); break; case ISD::FMAXNUM: ExpandFloatRes_FMAXNUM(N, Lo, Hi); break; case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; + case ISD::FCBRT: ExpandFloatRes_FCBRT(N, Lo, Hi); break; case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; case ISD::FCOPYSIGN: ExpandFloatRes_FCOPYSIGN(N, Lo, Hi); break; case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; @@ -1218,6 +1235,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_FCBRT(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), RTLIB::CBRT_F32, + RTLIB::CBRT_F64, RTLIB::CBRT_F80, + RTLIB::CBRT_F128, RTLIB::CBRT_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -2026,6 +2052,7 @@ // Unary FP Operations case ISD::FABS: + case ISD::FCBRT: case ISD::FCEIL: case ISD::FCOS: case ISD::FEXP: Index: llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h =================================================================== --- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -495,6 +495,7 @@ SDValue SoftenFloatRes_FMINNUM(SDNode *N); SDValue SoftenFloatRes_FMAXNUM(SDNode *N); SDValue SoftenFloatRes_FADD(SDNode *N); + SDValue SoftenFloatRes_FCBRT(SDNode *N); SDValue SoftenFloatRes_FCEIL(SDNode *N); SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N); SDValue SoftenFloatRes_FCOS(SDNode *N); @@ -563,6 +564,7 @@ void ExpandFloatRes_FMINNUM (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandFloatRes_FMAXNUM (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandFloatRes_FADD (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FCBRT (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandFloatRes_FCEIL (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandFloatRes_FCOPYSIGN (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandFloatRes_FCOS (SDNode *N, SDValue &Lo, SDValue &Hi); Index: llvm/test/CodeGen/ARM/fp16-promote.ll =================================================================== --- llvm/test/CodeGen/ARM/fp16-promote.ll +++ llvm/test/CodeGen/ARM/fp16-promote.ll @@ -497,6 +497,21 @@ ret void } +; CHECK-FP16-LABEL: test_cbrt: +; CHECK-FP16: vcvtb.f32.f16 +; CHECK-FP16: bl powf +; CHECK-FP16: vcvtb.f16.f32 +; CHECK-LIBCALL-LABEL: test_cbrt: +; CHECK-LIBCALL: bl __aeabi_h2f +; CHECK-LIBCALL: bl powf +; CHECK-LIBCALL: bl __aeabi_f2h +define void @test_cbrt(half* %p) #0 { + %a = load half, half* %p, align 2 + %r = call half @llvm.pow.f16(half %a, half 0x3FD5540000000000) + store half %r, half* %p + ret void +} + ; CHECK-FP16-LABEL: test_exp: ; CHECK-FP16: vcvtb.f32.f16 ; CHECK-FP16: bl expf Index: llvm/test/CodeGen/ARM/pow.ll =================================================================== --- llvm/test/CodeGen/ARM/pow.ll +++ llvm/test/CodeGen/ARM/pow.ll @@ -26,6 +26,22 @@ ret double %r } +define float @pow_f32_one_third_fmf(float %x) nounwind { +; ANY-LABEL: pow_f32_one_third_fmf: +; SOFTFLOAT: bl cbrtf +; HARDFLOAT: b cbrtf + %r = call fast float @llvm.pow.f32(float %x, float 0x3FD5555560000000) + ret float %r +} + +define double @pow_f64_one_third_fmf(double %x) nounwind { +; ANY-LABEL: pow_f64_one_third_fmf: +; SOFTFLOAT: bl cbrt +; HARDFLOAT: b cbrt + %r = call fast double @llvm.pow.f64(double %x, double 0x3FD5555555555555) + ret double %r +} + define <4 x float> @pow_v4f32_one_fourth_fmf(<4 x float> %x) nounwind { ; ANY-LABEL: pow_v4f32_one_fourth_fmf: ; SOFTFLOAT: bl powf