diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 9a0a50ee7003f..c8595b97b337d 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -194,6 +194,7 @@ set(BF16_SOURCES truncdfbf2.c truncxfbf2.c truncsfbf2.c + trunctfbf2.c ) set(GENERIC_TF_SOURCES diff --git a/compiler-rt/lib/builtins/trunctfbf2.c b/compiler-rt/lib/builtins/trunctfbf2.c new file mode 100644 index 0000000000000..3d47b13bdf5c2 --- /dev/null +++ b/compiler-rt/lib/builtins/trunctfbf2.c @@ -0,0 +1,18 @@ +//===--------- lib/trunctfbf2.c - quad -> bfloat conversion -------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#define QUAD_PRECISION +#include "fp_lib.h" + +#if defined(CRT_HAS_TF_MODE) && defined(__x86_64__) +#define SRC_QUAD +#define DST_BFLOAT +#include "fp_trunc_impl.inc" + +COMPILER_RT_ABI dst_t __trunctfbf2(src_t a) { return __truncXfYf2__(a); } + +#endif \ No newline at end of file diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def index 9c56cf098ff77..13a27b58b9cd7 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -383,6 +383,7 @@ HANDLE_LIBCALL(FPROUND_PPCF128_F16, "__trunctfhf2") HANDLE_LIBCALL(FPROUND_F32_BF16, "__truncsfbf2") HANDLE_LIBCALL(FPROUND_F64_BF16, "__truncdfbf2") HANDLE_LIBCALL(FPROUND_F80_BF16, "__truncxfbf2") +HANDLE_LIBCALL(FPROUND_F128_BF16, "__trunctfbf2") HANDLE_LIBCALL(FPROUND_F64_F32, "__truncdfsf2") HANDLE_LIBCALL(FPROUND_F80_F32, "__truncxfsf2") HANDLE_LIBCALL(FPROUND_F128_F32, "__trunctfsf2") diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 231de6bba5e5b..392cfbdd21273 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -171,6 +171,8 @@ RTLIB::Libcall RTLIB::getFPROUND(EVT OpVT, EVT RetVT) { return FPROUND_F64_BF16; if (OpVT == MVT::f80) return FPROUND_F80_BF16; + if (OpVT == MVT::f128) + return FPROUND_F128_BF16; } else if (RetVT == MVT::f32) { if (OpVT == MVT::f64) return FPROUND_F64_F32; diff --git a/llvm/test/CodeGen/X86/bfloat.ll b/llvm/test/CodeGen/X86/bfloat.ll index 3144fd56d9ccf..27348dd31958f 100644 --- a/llvm/test/CodeGen/X86/bfloat.ll +++ b/llvm/test/CodeGen/X86/bfloat.ll @@ -1975,3 +1975,25 @@ define bfloat @PR108936(x86_fp80 %0) nounwind { %2 = fptrunc x86_fp80 %0 to bfloat ret bfloat %2 } + +define bfloat @PR115710(fp128 %0) nounwind { +; X86-LABEL: PR115710: +; X86: # %bb.0: +; X86-NEXT: subl $28, %esp +; X86-NEXT: vmovaps {{[0-9]+}}(%esp), %xmm0 +; X86-NEXT: vmovups %xmm0, (%esp) +; X86-NEXT: calll __trunctfbf2 +; X86-NEXT: # kill: def $ax killed $ax def $eax +; X86-NEXT: vmovw %eax, %xmm0 +; X86-NEXT: addl $28, %esp +; X86-NEXT: retl +; +; CHECK-LABEL: PR115710: +; CHECK: # %bb.0: +; CHECK-NEXT: pushq %rax +; CHECK-NEXT: callq __trunctfbf2@PLT +; CHECK-NEXT: popq %rax +; CHECK-NEXT: retq + %2 = fptrunc fp128 %0 to bfloat + ret bfloat %2 +}