Add support for emitting libcalls for x86_fp80 -> fp128 and vice-versa

compiler_rt doesn't provide them (yet), but libgcc does. PR34076.

llvm-svn: 322772
This commit is contained in:
Benjamin Kramer 2018-01-17 22:29:16 +00:00
parent e5b8de2f1f
commit 8b1986b5cb
4 changed files with 39 additions and 0 deletions

View File

@ -251,6 +251,7 @@ HANDLE_LIBCALL(FMAX_PPCF128, "fmaxl")
// Conversion
HANDLE_LIBCALL(FPEXT_F32_PPCF128, "__gcc_stoq")
HANDLE_LIBCALL(FPEXT_F64_PPCF128, "__gcc_dtoq")
HANDLE_LIBCALL(FPEXT_F80_F128, "__extendxftf2")
HANDLE_LIBCALL(FPEXT_F64_F128, "__extenddftf2")
HANDLE_LIBCALL(FPEXT_F32_F128, "__extendsftf2")
HANDLE_LIBCALL(FPEXT_F32_F64, "__extendsfdf2")
@ -267,6 +268,7 @@ HANDLE_LIBCALL(FPROUND_PPCF128_F32, "__gcc_qtos")
HANDLE_LIBCALL(FPROUND_F80_F64, "__truncxfdf2")
HANDLE_LIBCALL(FPROUND_F128_F64, "__trunctfdf2")
HANDLE_LIBCALL(FPROUND_PPCF128_F64, "__gcc_qtod")
HANDLE_LIBCALL(FPROUND_F128_F80, "__trunctfxf2")
HANDLE_LIBCALL(FPTOSINT_F32_I32, "__fixsfsi")
HANDLE_LIBCALL(FPTOSINT_F32_I64, "__fixsfdi")
HANDLE_LIBCALL(FPTOSINT_F32_I128, "__fixsfti")

View File

@ -192,6 +192,9 @@ RTLIB::Libcall RTLIB::getFPEXT(EVT OpVT, EVT RetVT) {
return FPEXT_F64_F128;
else if (RetVT == MVT::ppcf128)
return FPEXT_F64_PPCF128;
} else if (OpVT == MVT::f80) {
if (RetVT == MVT::f128)
return FPEXT_F80_F128;
}
return UNKNOWN_LIBCALL;
@ -227,6 +230,9 @@ RTLIB::Libcall RTLIB::getFPROUND(EVT OpVT, EVT RetVT) {
return FPROUND_F128_F64;
if (OpVT == MVT::ppcf128)
return FPROUND_PPCF128_F64;
} else if (RetVT == MVT::f80) {
if (OpVT == MVT::f128)
return FPROUND_F128_F80;
}
return UNKNOWN_LIBCALL;

View File

@ -309,6 +309,7 @@ RuntimeLibcallSignatures[RTLIB::UNKNOWN_LIBCALL] = {
// CONVERSION
/* FPEXT_F32_PPCF128 */ unsupported,
/* FPEXT_F64_PPCF128 */ unsupported,
/* FPEXT_F80_F128 */ unsupported,
/* FPEXT_F64_F128 */ func_iPTR_f64,
/* FPEXT_F32_F128 */ func_iPTR_f32,
/* FPEXT_F32_F64 */ f64_func_f32,
@ -325,6 +326,7 @@ RuntimeLibcallSignatures[RTLIB::UNKNOWN_LIBCALL] = {
/* FPROUND_F80_F64 */ unsupported,
/* FPROUND_F128_F64 */ f64_func_i64_i64,
/* FPROUND_PPCF128_F64 */ unsupported,
/* FPROUND_F128_F80 */ unsupported,
/* FPTOSINT_F32_I32 */ i32_func_f32,
/* FPTOSINT_F32_I64 */ i64_func_f32,
/* FPTOSINT_F32_I128 */ i64_i64_func_f32,
@ -804,6 +806,7 @@ RuntimeLibcallNames[RTLIB::UNKNOWN_LIBCALL] = {
/* FMAX_PPCF128 */ nullptr,
/* FPEXT_F32_PPCF128 */ nullptr,
/* FPEXT_F64_PPCF128 */ nullptr,
/* FPEXT_F80_F128 */ nullptr,
/* FPEXT_F64_F128 */ "__extenddftf2",
/* FPEXT_F32_F128 */ "__extendsftf2",
/* FPEXT_F32_F64 */ "__extendsfdf2",
@ -820,6 +823,7 @@ RuntimeLibcallNames[RTLIB::UNKNOWN_LIBCALL] = {
/* FPROUND_F80_F64 */ "__truncxfdf2",
/* FPROUND_F128_F64 */ "__trunctfdf2",
/* FPROUND_PPCF128_F64 */ nullptr,
/* FPROUND_F128_F80 */ nullptr,
/* FPTOSINT_F32_I32 */ "__fixsfsi",
/* FPTOSINT_F32_I64 */ "__fixsfdi",
/* FPTOSINT_F32_I128 */ "__fixsfti",

View File

@ -12,6 +12,7 @@
@vu64 = common global i64 0, align 8
@vf32 = common global float 0.000000e+00, align 4
@vf64 = common global double 0.000000e+00, align 8
@vf80 = common global x86_fp80 0xK00000000000000000000, align 8
@vf128 = common global fp128 0xL00000000000000000000000000000000, align 16
define void @TestFPExtF32_F128() {
@ -52,6 +53,19 @@ entry:
; X64: ret
}
define void @TestFPExtF80_F128() {
entry:
%0 = load x86_fp80, x86_fp80* @vf80, align 8
%conv = fpext x86_fp80 %0 to fp128
store fp128 %conv, fp128* @vf128, align 16
ret void
; X32-LABEL: TestFPExtF80_F128:
; X32: calll __extendxftf2
;
; X64-LABEL: TestFPExtF80_F128:
; X64: callq __extendxftf2
}
define void @TestFPToSIF128_I32() {
entry:
%0 = load fp128, fp128* @vf128, align 16
@ -160,6 +174,19 @@ entry:
; X64: retq
}
define void @TestFPTruncF128_F80() {
entry:
%0 = load fp128, fp128* @vf128, align 16
%conv = fptrunc fp128 %0 to x86_fp80
store x86_fp80 %conv, x86_fp80* @vf80, align 8
ret void
; X32-LABEL: TestFPTruncF128_F80:
; X32: calll __trunctfxf2
;
; X64-LABEL: TestFPTruncF128_F80:
; X64: callq __trunctfxf2
}
define void @TestSIToFPI32_F128() {
entry:
%0 = load i32, i32* @vi32, align 4