[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