https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/215993
>From 75a8471d4b18bf9d67a92c580fc3f9cd41401e78 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Sat, 8 Aug 2026 17:51:04 +0200 Subject: [PATCH] RuntimeLibcalls: Fix AArch64 wrongly typed long-double libcalls 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) <[email protected]> --- llvm/include/llvm/IR/RuntimeLibcalls.td | 14 ++++++++++++-- llvm/test/CodeGen/AArch64/exp10-f128.ll | 19 +++++++++++++++++++ llvm/test/CodeGen/AArch64/frexp-f128.ll | 24 ++++++++++++++++++++++++ llvm/test/CodeGen/AArch64/ldexp-f128.ll | 19 +++++++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/exp10-f128.ll create mode 100644 llvm/test/CodeGen/AArch64/frexp-f128.ll create mode 100644 llvm/test/CodeGen/AArch64/ldexp-f128.ll 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 +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
