https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/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) <[email protected]> >From 42fb82794f91a347763e2eb1549435143adcfabe 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 ffbe89a6d1b8c..eb908b1cef0d2 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -2202,12 +2202,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>, @@ -2215,7 +2223,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..901e838105088 --- /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=GNU %s + +; fp128 exp10 lowers to exp10l where long double is fp128, and diagnoses a +; missing libcall (instead of crashing) 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 +; RUN: not llc -mtriple=aarch64-linux-android -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s + +; ERR: error: no libcall available for fexp10 + +define fp128 @test_exp10_f128(fp128 %x) { +; GNU-LABEL: test_exp10_f128: +; GNU: // %bb.0: +; GNU-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..3eef6e7dda0ef --- /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=GNU %s + +; fp128 frexp lowers to frexpl where long double is fp128, 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 +; RUN: not llc -mtriple=aarch64-linux-android -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 { +; GNU-LABEL: test_frexp_f128_i32: +; GNU: // %bb.0: +; GNU-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; GNU-NEXT: add x0, sp, #12 +; GNU-NEXT: bl frexpl +; GNU-NEXT: ldr w0, [sp, #12] +; GNU-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; GNU-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..9b715591fa710 --- /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=GNU %s + +; fp128 ldexp lowers to ldexpl where long double is fp128, 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 +; RUN: not llc -mtriple=aarch64-linux-android -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) { +; GNU-LABEL: test_ldexp_f128_i32: +; GNU: // %bb.0: +; GNU-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
