[llvm] 4487de6 - RuntimeLibcalls: Provide fp128 long double libcalls on X86 (#216622)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 17 03:14:44 PDT 2026
Author: Matt Arsenault
Date: 2026-08-17T12:14:38+02:00
New Revision: 4487de6d50f331b31cde0eb747ae54b496f3755e
URL: https://github.com/llvm/llvm-project/commit/4487de6d50f331b31cde0eb747ae54b496f3755e
DIFF: https://github.com/llvm/llvm-project/commit/4487de6d50f331b31cde0eb747ae54b496f3755e.diff
LOG: RuntimeLibcalls: Provide fp128 long double libcalls on X86 (#216622)
16a8d8d038a3 removed the l-suffixed long double math functions
from the default set and re-added them per-target gated on
isLongDoubleF128, but X86 was not given the re-add. On targets
whose long double is fp128 (e.g. x86_64 Android/OHOS) this dropped
the fp128 l-suffixed libcalls.
Fixes the regression reported on #214944.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
Added:
llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll
Modified:
llvm/include/llvm/IR/RuntimeLibcalls.td
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 79bc7418f4027..1176b9b5d1a5a 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -3421,6 +3421,11 @@ defvar SinCosF32F64Libcalls = LibcallImpls<(add sincosf, sincos), hasSinCos_f32_
defvar MemChkLibcalls = [__memcpy_chk, __memset_chk, __memmove_chk];
+// frexpl/ldexpl/exp10l are added separately below with their own guards.
+defvar X86LongDoubleF128Body =
+ !listremove(DefaultRuntimeLibcallImpls_longdouble_f128,
+ [frexpl_f128, ldexpl_f128, exp10l_f128]);
+
defvar X86CommonLibcalls =
(add (sub WinDefaultLibcallImpls, WindowsDivRemMulLibcallOverrides, MemChkLibcalls),
DarwinSinCosStret, DarwinExp10, DarwinMemsetPattern, MacOSUnlockedIO,
@@ -3431,6 +3436,9 @@ defvar X86CommonLibcalls =
LibmHasFrexpF32, LibmHasLdexpF32,
LibmHasFrexpF80, LibmHasLdexpF80,
LibcallImpls<(add frexpl_f128, ldexpl_f128, exp10l_f128), hasExpFrexplLdexplF128>,
+ // The l-suffixed long double math is fp128 only when long double is fp128
+ // (e.g. x86_64 Android/OHOS). frexpl/ldexpl/exp10l are added above.
+ LibcallImpls<(add X86LongDoubleF128Body), isLongDoubleF128>,
DefaultRuntimeLibcallImpls_f80,
LibmHasExp10F32, LibmHasExp10F64, LibmHasExp10F80,
LibcallImpls<(add MostPowI), isNotOSMSVCRT>,
diff --git a/llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll b/llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll
new file mode 100644
index 0000000000000..d3020bcbcd961
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll
@@ -0,0 +1,98 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=x86_64-linux-android -enable-legalize-types-checking < %s | FileCheck %s --check-prefix=ANDROID
+
+; On targets whose long double is IEEE-quad (fp128), such as x86_64 Android/OHOS,
+; fp128 math intrinsics lower to the l-suffixed long double libcalls (fmaxl,
+; sqrtl, ...) which the C library provides for long double. This
diff ers from the
+; f128-suffixed _Float128 functions (sqrtf128, ...) used on glibc targets whose
+; long double is x87 (covered by fp128-libcalls-gnu.ll).
+;
+; This is a regression test for #214944, where X86 stopped providing the fp128
+; long double libcalls, producing "no libcall available" errors on android.
+
+ at vf128 = common dso_local global fp128 0xL00000000000000000000000000000000, align 16
+
+define dso_local void @Test128Max(fp128 %d1, fp128 %d2) nounwind {
+; ANDROID-LABEL: Test128Max:
+; ANDROID: # %bb.0:
+; ANDROID-NEXT: pushq %rax
+; ANDROID-NEXT: callq fmaxl at PLT
+; ANDROID-NEXT: movaps %xmm0, vf128(%rip)
+; ANDROID-NEXT: popq %rax
+; ANDROID-NEXT: retq
+ %max = call fp128 @llvm.maxnum.f128(fp128 %d1, fp128 %d2)
+ store fp128 %max, ptr @vf128, align 16
+ ret void
+}
+
+define dso_local void @Test128Min(fp128 %d1, fp128 %d2) nounwind {
+; ANDROID-LABEL: Test128Min:
+; ANDROID: # %bb.0:
+; ANDROID-NEXT: pushq %rax
+; ANDROID-NEXT: callq fminl at PLT
+; ANDROID-NEXT: movaps %xmm0, vf128(%rip)
+; ANDROID-NEXT: popq %rax
+; ANDROID-NEXT: retq
+ %min = call fp128 @llvm.minnum.f128(fp128 %d1, fp128 %d2)
+ store fp128 %min, ptr @vf128, align 16
+ ret void
+}
+
+define dso_local void @Test128Sqrt(fp128 %d1) nounwind {
+; ANDROID-LABEL: Test128Sqrt:
+; ANDROID: # %bb.0:
+; ANDROID-NEXT: pushq %rax
+; ANDROID-NEXT: callq sqrtl at PLT
+; ANDROID-NEXT: movaps %xmm0, vf128(%rip)
+; ANDROID-NEXT: popq %rax
+; ANDROID-NEXT: retq
+ %sqrt = call fp128 @llvm.sqrt.f128(fp128 %d1)
+ store fp128 %sqrt, ptr @vf128, align 16
+ ret void
+}
+
+define dso_local void @Test128Sin(fp128 %d1) nounwind {
+; ANDROID-LABEL: Test128Sin:
+; ANDROID: # %bb.0:
+; ANDROID-NEXT: pushq %rax
+; ANDROID-NEXT: callq sinl at PLT
+; ANDROID-NEXT: movaps %xmm0, vf128(%rip)
+; ANDROID-NEXT: popq %rax
+; ANDROID-NEXT: retq
+ %sin = call fp128 @llvm.sin.f128(fp128 %d1)
+ store fp128 %sin, ptr @vf128, align 16
+ ret void
+}
+
+define dso_local void @Test128Pow(fp128 %d1, fp128 %d2) nounwind {
+; ANDROID-LABEL: Test128Pow:
+; ANDROID: # %bb.0:
+; ANDROID-NEXT: pushq %rax
+; ANDROID-NEXT: callq powl at PLT
+; ANDROID-NEXT: movaps %xmm0, vf128(%rip)
+; ANDROID-NEXT: popq %rax
+; ANDROID-NEXT: retq
+ %pow = call fp128 @llvm.pow.f128(fp128 %d1, fp128 %d2)
+ store fp128 %pow, ptr @vf128, align 16
+ ret void
+}
+
+define dso_local void @Test128Rint(fp128 %d1) nounwind {
+; ANDROID-LABEL: Test128Rint:
+; ANDROID: # %bb.0:
+; ANDROID-NEXT: pushq %rax
+; ANDROID-NEXT: callq rintl at PLT
+; ANDROID-NEXT: movaps %xmm0, vf128(%rip)
+; ANDROID-NEXT: popq %rax
+; ANDROID-NEXT: retq
+ %rint = call fp128 @llvm.rint.f128(fp128 %d1)
+ store fp128 %rint, ptr @vf128, align 16
+ ret void
+}
+
+declare fp128 @llvm.maxnum.f128(fp128, fp128)
+declare fp128 @llvm.minnum.f128(fp128, fp128)
+declare fp128 @llvm.sqrt.f128(fp128)
+declare fp128 @llvm.sin.f128(fp128)
+declare fp128 @llvm.pow.f128(fp128, fp128)
+declare fp128 @llvm.rint.f128(fp128)
More information about the llvm-commits
mailing list