[llvm-branch-commits] [llvm] RuntimeLibcalls: Stop improperly reporting fp128 long double calls on ARM (PR #215917)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Aug 12 15:56:45 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
32-bit ARM's long double is IEEE double, so l suffixed calls do not have fp128
type. Additionally, the f128 typed / suffixed functions are not built in glibc as
__HAVE_FLOAT128 is defined to 0 in the arch config. Remove the testcases
which emitted nonexistent or wrongly typed calls and replace with error
tests.
Related: #<!-- -->44744
Co-authored-by: Claude (Claude-Opus-4.8) <noreply@<!-- -->anthropic.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/215917.diff
6 Files Affected:
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+6-3)
- (modified) llvm/test/CodeGen/ARM/ldexp-fp128.ll (+5-49)
- (modified) llvm/test/CodeGen/ARM/ldexp.ll (-10)
- (modified) llvm/test/CodeGen/ARM/llvm.frexp.ll (+1-52)
- (modified) llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll (+2-2)
- (modified) llvm/test/CodeGen/RISCV/fp128.ll (+45)
``````````diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 16cd8c538a91a..ffbe89a6d1b8c 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -2717,15 +2717,18 @@ def ARMSystemLibrary
AEABIOverrides),
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, sincosl_f128,
+ exp10l_f128),
+ isLongDoubleF128>,
WindowARMDivRemCalls,
WindowARMFPIntCasts,
SecurityCheckCookieIfWinMSVC,
LibcallImpls<(add __chkstk), isOSWindows>,
AEABIDivRemCalls,
DarwinSinCosStret, DarwinExp10, DarwinMemsetPattern,
- LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
- DefaultLibmExp10,
+ LibmHasSinCosF32, LibmHasSinCosF64,
+ LibmHasExp10F32, LibmHasExp10F64,
LibcSafestackPointerAddress,
AEABICalls,
diff --git a/llvm/test/CodeGen/ARM/ldexp-fp128.ll b/llvm/test/CodeGen/ARM/ldexp-fp128.ll
index 93fcd39e824fb..1e2d6cc59b066 100644
--- a/llvm/test/CodeGen/ARM/ldexp-fp128.ll
+++ b/llvm/test/CodeGen/ARM/ldexp-fp128.ll
@@ -1,16 +1,10 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
-; RUN: llc -mtriple=armv7-unknown-linux < %s | FileCheck -check-prefix=LINUX %s
+; RUN: not llc -mtriple=armv7-unknown-linux -filetype=null %s 2>&1 | FileCheck %s
+; ARM long double is IEEE double, so there is no fp128 ldexpl libcall.
+; CHECK: error: no libcall available for fldexp
+
+; This is an improperly typed call, long double is not fp128.
define fp128 @testExpl(fp128 %val, i32 %a) {
-; LINUX-LABEL: testExpl:
-; LINUX: @ %bb.0:
-; LINUX-NEXT: push {r11, lr}
-; LINUX-NEXT: sub sp, sp, #8
-; LINUX-NEXT: ldr r12, [sp, #16]
-; LINUX-NEXT: str r12, [sp]
-; LINUX-NEXT: bl ldexpl
-; LINUX-NEXT: add sp, sp, #8
-; LINUX-NEXT: pop {r11, pc}
%call = tail call fp128 @ldexpl(fp128 %val, i32 %a)
ret fp128 %call
}
@@ -18,49 +12,11 @@ define fp128 @testExpl(fp128 %val, i32 %a) {
declare fp128 @ldexpl(fp128, i32) memory(none)
define fp128 @test_ldexp_f128_i32(fp128 %val, i32 %a) {
-; LINUX-LABEL: test_ldexp_f128_i32:
-; LINUX: @ %bb.0:
-; LINUX-NEXT: push {r11, lr}
-; LINUX-NEXT: sub sp, sp, #8
-; LINUX-NEXT: ldr r12, [sp, #16]
-; LINUX-NEXT: str r12, [sp]
-; LINUX-NEXT: bl ldexpl
-; LINUX-NEXT: add sp, sp, #8
-; LINUX-NEXT: pop {r11, pc}
%call = tail call fp128 @llvm.ldexp.f128.i32(fp128 %val, i32 %a)
ret fp128 %call
}
define <2 x fp128> @test_ldexp_v2f128_v2i32(<2 x fp128> %val, <2 x i32> %a) {
-; LINUX-LABEL: test_ldexp_v2f128_v2i32:
-; LINUX: @ %bb.0:
-; LINUX-NEXT: push {r4, r5, r6, lr}
-; LINUX-NEXT: vpush {d8}
-; LINUX-NEXT: sub sp, sp, #8
-; LINUX-NEXT: mov r5, r3
-; LINUX-NEXT: add r3, sp, #40
-; LINUX-NEXT: mov r6, r2
-; LINUX-NEXT: mov r4, r0
-; LINUX-NEXT: ldm r3, {r0, r1, r2, r3}
-; LINUX-NEXT: vldr d8, [sp, #56]
-; LINUX-NEXT: vst1.32 {d8[1]}, [sp:32]
-; LINUX-NEXT: bl ldexpl
-; LINUX-NEXT: ldr r12, [sp, #32]
-; LINUX-NEXT: vst1.32 {d8[0]}, [sp:32]
-; LINUX-NEXT: ldr lr, [sp, #36]
-; LINUX-NEXT: str r0, [r4, #16]
-; LINUX-NEXT: mov r0, r6
-; LINUX-NEXT: str r1, [r4, #20]
-; LINUX-NEXT: mov r1, r5
-; LINUX-NEXT: str r2, [r4, #24]
-; LINUX-NEXT: mov r2, r12
-; LINUX-NEXT: str r3, [r4, #28]
-; LINUX-NEXT: mov r3, lr
-; LINUX-NEXT: bl ldexpl
-; LINUX-NEXT: stm r4, {r0, r1, r2, r3}
-; LINUX-NEXT: add sp, sp, #8
-; LINUX-NEXT: vpop {d8}
-; LINUX-NEXT: pop {r4, r5, r6, pc}
%call = tail call <2 x fp128> @llvm.ldexp.v2f128.v2i32(<2 x fp128> %val, <2 x i32> %a)
ret <2 x fp128> %call
}
diff --git a/llvm/test/CodeGen/ARM/ldexp.ll b/llvm/test/CodeGen/ARM/ldexp.ll
index cdf91eb902e05..83ca530ba6c88 100644
--- a/llvm/test/CodeGen/ARM/ldexp.ll
+++ b/llvm/test/CodeGen/ARM/ldexp.ll
@@ -37,16 +37,6 @@ entry:
declare float @ldexpf(float, i32) memory(none)
-define fp128 @testExpl(fp128 %val, i32 %a) {
-; LINUX: bl ldexpl
-; WINDOWS: b.w ldexpl
-entry:
- %call = tail call fp128 @ldexpl(fp128 %val, i32 %a)
- ret fp128 %call
-}
-
-declare fp128 @ldexpl(fp128, i32) memory(none)
-
define half @testExpf16(half %val, i32 %a) {
; LINUX: bl ldexpf
; WINDOWS: bl ldexp{{$}}
diff --git a/llvm/test/CodeGen/ARM/llvm.frexp.ll b/llvm/test/CodeGen/ARM/llvm.frexp.ll
index cd2516e1b1acc..f3ba7f730c866 100644
--- a/llvm/test/CodeGen/ARM/llvm.frexp.ll
+++ b/llvm/test/CodeGen/ARM/llvm.frexp.ll
@@ -542,58 +542,7 @@ define <2 x i32> @test_frexp_v2f64_v2i32_only_use_exp(<2 x double> %a) {
ret <2 x i32> %result.1
}
-define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) nounwind {
-; CHECK-LABEL: test_frexp_f128_i32:
-; CHECK: @ %bb.0:
-; CHECK-NEXT: push {r4, lr}
-; CHECK-NEXT: sub sp, #8
-; CHECK-NEXT: mov r12, r3
-; CHECK-NEXT: ldr r3, [sp, #16]
-; CHECK-NEXT: mov r4, r0
-; CHECK-NEXT: add r0, sp, #4
-; CHECK-NEXT: str r0, [sp]
-; CHECK-NEXT: mov r0, r1
-; CHECK-NEXT: mov r1, r2
-; CHECK-NEXT: mov r2, r12
-; CHECK-NEXT: bl frexpl
-; CHECK-NEXT: ldr.w r12, [sp, #4]
-; CHECK-NEXT: stm.w r4, {r0, r1, r2, r3, r12}
-; CHECK-NEXT: add sp, #8
-; CHECK-NEXT: pop {r4, pc}
- %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
- ret { fp128, i32 } %result
-}
-
-define fp128 @test_frexp_f128_i32_only_use_fract(fp128 %a) nounwind {
-; CHECK-LABEL: test_frexp_f128_i32_only_use_fract:
-; CHECK: @ %bb.0:
-; CHECK-NEXT: push {r7, lr}
-; CHECK-NEXT: sub sp, #8
-; CHECK-NEXT: add.w r12, sp, #4
-; CHECK-NEXT: str.w r12, [sp]
-; CHECK-NEXT: bl frexpl
-; CHECK-NEXT: add sp, #8
-; CHECK-NEXT: pop {r7, pc}
- %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
- %result.0 = extractvalue { fp128, i32 } %result, 0
- ret fp128 %result.0
-}
-
-define i32 @test_frexp_f128_i32_only_use_exp(fp128 %a) nounwind {
-; CHECK-LABEL: test_frexp_f128_i32_only_use_exp:
-; CHECK: @ %bb.0:
-; CHECK-NEXT: push {r7, lr}
-; CHECK-NEXT: sub sp, #8
-; CHECK-NEXT: add.w r12, sp, #4
-; CHECK-NEXT: str.w r12, [sp]
-; CHECK-NEXT: bl frexpl
-; CHECK-NEXT: ldr r0, [sp, #4]
-; CHECK-NEXT: add sp, #8
-; CHECK-NEXT: pop {r7, pc}
- %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
- %result.0 = extractvalue { fp128, i32 } %result, 1
- ret i32 %result.0
-}
+; ARM long double is IEEE double, so there is no fp128 frexpl libcall.
declare { float, i32 } @llvm.frexp.f32.i32(float) #0
declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0
diff --git a/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll b/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll
index 50956b5e93f38..54ac792da1374 100644
--- a/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll
+++ b/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll
@@ -2,8 +2,8 @@
; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %}
; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-none | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %}
; RUN: %if aarch64-registered-target %{ not llc -mtriple=arm64-apple-macosx -filetype=null %s 2>&1 | FileCheck --check-prefix=ERR %s %}
-; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-none-eabi | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %}
-; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-unknown-linux-gnueabi | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %}
+; RUN: %if arm-registered-target %{ not llc -mtriple=arm-none-eabi -filetype=null %s 2>&1 | FileCheck --check-prefix=ERR %s %}
+; RUN: %if arm-registered-target %{ not llc -mtriple=arm-unknown-linux-gnueabi -filetype=null %s 2>&1 | FileCheck --check-prefix=ERR %s %}
; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %}
; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %}
; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %}
diff --git a/llvm/test/CodeGen/RISCV/fp128.ll b/llvm/test/CodeGen/RISCV/fp128.ll
index 9beecf0c025c8..19a4a50723513 100644
--- a/llvm/test/CodeGen/RISCV/fp128.ll
+++ b/llvm/test/CodeGen/RISCV/fp128.ll
@@ -573,3 +573,48 @@ define i32 @lround_f128() nounwind {
%r = call i32 @llvm.lround.f128(fp128 %1)
ret i32 %r
}
+
+; fp128 ldexp lowers to ldexpl (long double is fp128).
+define fp128 @ldexp_f128(fp128 %x, i32 %y) nounwind {
+; RV32I-LABEL: ldexp_f128:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -48
+; RV32I-NEXT: sw ra, 44(sp) # 4-byte Folded Spill
+; RV32I-NEXT: sw s0, 40(sp) # 4-byte Folded Spill
+; RV32I-NEXT: lw a3, 0(a1)
+; RV32I-NEXT: lw a4, 4(a1)
+; RV32I-NEXT: lw a5, 8(a1)
+; RV32I-NEXT: lw a6, 12(a1)
+; RV32I-NEXT: mv s0, a0
+; RV32I-NEXT: sw a3, 8(sp)
+; RV32I-NEXT: sw a4, 12(sp)
+; RV32I-NEXT: addi a0, sp, 24
+; RV32I-NEXT: addi a1, sp, 8
+; RV32I-NEXT: sw a5, 16(sp)
+; RV32I-NEXT: sw a6, 20(sp)
+; RV32I-NEXT: call ldexpl
+; RV32I-NEXT: lw a0, 24(sp)
+; RV32I-NEXT: lw a1, 28(sp)
+; RV32I-NEXT: lw a2, 32(sp)
+; RV32I-NEXT: lw a3, 36(sp)
+; RV32I-NEXT: sw a0, 0(s0)
+; RV32I-NEXT: sw a1, 4(s0)
+; RV32I-NEXT: sw a2, 8(s0)
+; RV32I-NEXT: sw a3, 12(s0)
+; RV32I-NEXT: lw ra, 44(sp) # 4-byte Folded Reload
+; RV32I-NEXT: lw s0, 40(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 48
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: ldexp_f128:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: sext.w a2, a2
+; RV64I-NEXT: call ldexpl
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %z = call fp128 @llvm.ldexp.f128.i32(fp128 %x, i32 %y)
+ ret fp128 %z
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/215917
More information about the llvm-branch-commits
mailing list