diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -286,6 +286,7 @@ HANDLE_LIBCALL(FPEXT_F80_F128, "__extendxftf2") HANDLE_LIBCALL(FPEXT_F64_F128, "__extenddftf2") HANDLE_LIBCALL(FPEXT_F32_F128, "__extendsftf2") +HANDLE_LIBCALL(FPEXT_F16_F128, "__extendhftf2") HANDLE_LIBCALL(FPEXT_F32_F64, "__extendsfdf2") HANDLE_LIBCALL(FPEXT_F16_F32, "__gnu_h2f_ieee") HANDLE_LIBCALL(FPROUND_F32_F16, "__gnu_f2h_ieee") diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -224,6 +224,8 @@ if (OpVT == MVT::f16) { if (RetVT == MVT::f32) return FPEXT_F16_F32; + if (RetVT == MVT::f128) + return FPEXT_F16_F128; } else if (OpVT == MVT::f32) { if (RetVT == MVT::f64) return FPEXT_F32_F64; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -417,8 +417,10 @@ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Custom); setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Custom); setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i128, Custom); + setOperationAction(ISD::FP_ROUND, MVT::f16, Custom); setOperationAction(ISD::FP_ROUND, MVT::f32, Custom); setOperationAction(ISD::FP_ROUND, MVT::f64, Custom); + setOperationAction(ISD::STRICT_FP_ROUND, MVT::f16, Custom); setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Custom); setOperationAction(ISD::STRICT_FP_ROUND, MVT::f64, Custom); diff --git a/llvm/test/CodeGen/AArch64/arm64-fp128.ll b/llvm/test/CodeGen/AArch64/arm64-fp128.ll --- a/llvm/test/CodeGen/AArch64/arm64-fp128.ll +++ b/llvm/test/CodeGen/AArch64/arm64-fp128.ll @@ -219,6 +219,7 @@ ; CHECK: ret } +@varhalf = global half 0.0, align 2 @varfloat = global float 0.0, align 4 @vardouble = global double 0.0, align 8 @@ -227,6 +228,12 @@ %val = load fp128, fp128* @lhs, align 16 + %half = fptrunc fp128 %val to half + store half %half, half* @varhalf, align 2 +; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs] +; CHECK: bl __trunctfhf2 +; CHECK: str h0, [{{x[0-9]+}}, :lo12:varhalf] + %float = fptrunc fp128 %val to float store float %float, float* @varfloat, align 4 ; CHECK: bl __trunctfsf2 @@ -245,6 +252,13 @@ %val = load fp128, fp128* @lhs, align 16 + %half = load half, half* @varhalf + %fromhalf = fpext half %half to fp128 + store volatile fp128 %fromhalf, fp128* @lhs, align 16 +; CHECK: ldr h0, [{{x[0-9]+}}, :lo12:varhalf] +; CHECK: bl __extendhftf2 +; CHECK: str q0, [{{x[0-9]+}}, :lo12:lhs] + %float = load float, float* @varfloat %fromfloat = fpext float %float to fp128 store volatile fp128 %fromfloat, fp128* @lhs, align 16