[llvm] 2239699 - RuntimeLibcalls: Fix AArch64 wrongly typed long-double libcalls (#215993)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 15 13:19:47 PDT 2026


Author: Matt Arsenault
Date: 2026-08-15T22:19:42+02:00
New Revision: 22396993a985b1a86a1ddb241b5cdd0843c5d306

URL: https://github.com/llvm/llvm-project/commit/22396993a985b1a86a1ddb241b5cdd0843c5d306
DIFF: https://github.com/llvm/llvm-project/commit/22396993a985b1a86a1ddb241b5cdd0843c5d306.diff

LOG: RuntimeLibcalls: Fix AArch64 wrongly typed long-double libcalls (#215993)

Respect the triple's LongDoubleFormat.

AArch64SystemLibrary added the fp128-typed frexpl/ldexpl and exp10l
without a long-double-format guard, so triples where long double is IEEE double
(Darwin, Windows, Android) were emitting l suffixed calls with the wrong
type.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>

Added: 
    llvm/test/CodeGen/AArch64/exp10-f128.ll
    llvm/test/CodeGen/AArch64/frexp-f128.ll
    llvm/test/CodeGen/AArch64/ldexp-f128.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 2146ba42a3eb8..79bc7418f4027 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -2201,12 +2201,20 @@ defvar AArch64LongDoubleF128Body =
     !listremove(DefaultRuntimeLibcallImpls_longdouble_f128,
                 [frexpl_f128, ldexpl_f128, exp10l_f128]);
 
+// fp128 long double, excluding the Windows math runtime (which lacks frexpl/
+// ldexpl) and Darwin (which lacks exp10l).
+def isLongDoubleF128NotWinMath : RuntimeLibcallAvailability<
+  (all_of IsLongDoubleF128, (any_of (not IsOSWindows), IsOSCygMing))>;
+def isLongDoubleF128NotDarwin : RuntimeLibcallAvailability<
+  (all_of IsLongDoubleF128, (not IsOSDarwin))>;
+
 def AArch64SystemLibrary : SystemRuntimeLibrary<
   isAArch64_ExceptArm64EC,
   (add WinDefaultLibcallImpls,
        LibcallImpls<(add __powisf2, __powidf2), isNotOSMSVCRT>,
        LibmHasFrexpF32, LibmHasLdexpF32,
-       LibmHasFrexpF128, LibmHasLdexpF128,
+       // The l-suffixed libm functions are fp128 only when long double is.
+       LibcallImpls<(add frexpl_f128, ldexpl_f128), isLongDoubleF128NotWinMath>,
        LibcallImpls<(add AArch64LongDoubleF128Body), isLongDoubleF128>,
        AArch64LibcallImpls,
        LibcallImpls<(add Int128RTLibcalls), isAArch64_ILP64>,
@@ -2214,7 +2222,9 @@ def AArch64SystemLibrary : SystemRuntimeLibrary<
        DarwinExp10, DarwinSinCosStret, DarwinMemsetPattern,
        MacOSUnlockedIO,
        LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
-       DefaultLibmExp10,
+       LibmHasExp10F32, LibmHasExp10F64,
+       // exp10l is fp128 only when long double is.
+       LibcallImpls<(add exp10l_f128), isLongDoubleF128NotDarwin>,
        DefaultStackProtector,
        SecurityCheckCookieIfWinMSVC,
        LibcallImpls<(add __chkstk), isOSWindows>,

diff  --git a/llvm/test/CodeGen/AArch64/exp10-f128.ll b/llvm/test/CodeGen/AArch64/exp10-f128.ll
new file mode 100644
index 0000000000000..e551c52b7def1
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/exp10-f128.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck -check-prefix=HAS-FP128 %s
+; RUN: llc -mtriple=aarch64-linux-android < %s | FileCheck -check-prefix=HAS-FP128 %s
+
+; fp128 exp10 lowers to exp10l where long double is fp128 (Linux,
+; including Android), and diagnoses a missing libcall where it is not.
+
+; RUN: not llc -mtriple=aarch64-apple-macosx -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=aarch64-windows-msvc -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; ERR: error: no libcall available for fexp10
+
+define fp128 @test_exp10_f128(fp128 %x) {
+; HAS-FP128-LABEL: test_exp10_f128:
+; HAS-FP128:       // %bb.0:
+; HAS-FP128-NEXT:    b exp10l
+  %r = call fp128 @llvm.exp10.f128(fp128 %x)
+  ret fp128 %r
+}

diff  --git a/llvm/test/CodeGen/AArch64/frexp-f128.ll b/llvm/test/CodeGen/AArch64/frexp-f128.ll
new file mode 100644
index 0000000000000..5276f501821e8
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/frexp-f128.ll
@@ -0,0 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck -check-prefix=HAS-FP128 %s
+; RUN: llc -mtriple=aarch64-linux-android < %s | FileCheck -check-prefix=HAS-FP128 %s
+
+; fp128 frexp lowers to frexpl where long double is fp128 (Linux, including
+; Android), and diagnoses a missing libcall when it is not.
+
+; RUN: not llc -mtriple=aarch64-apple-macosx -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=aarch64-windows-msvc -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; ERR: error: no libcall available for ffrexp
+
+define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) nounwind {
+; HAS-FP128-LABEL: test_frexp_f128_i32:
+; HAS-FP128:       // %bb.0:
+; HAS-FP128-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; HAS-FP128-NEXT:    add x0, sp, #12
+; HAS-FP128-NEXT:    bl frexpl
+; HAS-FP128-NEXT:    ldr w0, [sp, #12]
+; HAS-FP128-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
+; HAS-FP128-NEXT:    ret
+  %call = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
+  ret { fp128, i32 } %call
+}

diff  --git a/llvm/test/CodeGen/AArch64/ldexp-f128.ll b/llvm/test/CodeGen/AArch64/ldexp-f128.ll
new file mode 100644
index 0000000000000..62b34afb0e179
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ldexp-f128.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck -check-prefix=HAS-FP128 %s
+; RUN: llc -mtriple=aarch64-linux-android < %s | FileCheck -check-prefix=HAS-FP128 %s
+
+; fp128 ldexp lowers to ldexpl where long double is fp128 (Linux, including
+; Android), and diagnoses a missing libcall where it is not.
+
+; RUN: not llc -mtriple=aarch64-apple-macosx -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=aarch64-windows-msvc -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; ERR: error: no libcall available for fldexp
+
+define fp128 @test_ldexp_f128_i32(fp128 %val, i32 %a) {
+; HAS-FP128-LABEL: test_ldexp_f128_i32:
+; HAS-FP128:       // %bb.0:
+; HAS-FP128-NEXT:    b ldexpl
+  %call = tail call fp128 @llvm.ldexp.f128.i32(fp128 %val, i32 %a)
+  ret fp128 %call
+}


        


More information about the llvm-commits mailing list