From c73eb21dd089e309a51dc680e32e32e6b0566882 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 14 Feb 2025 16:44:28 -0800 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6-beta.1 --- lld/test/ELF/lto/arm-rtlibcall.ll | 122 ++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 lld/test/ELF/lto/arm-rtlibcall.ll diff --git a/lld/test/ELF/lto/arm-rtlibcall.ll b/lld/test/ELF/lto/arm-rtlibcall.ll new file mode 100644 index 0000000000000..89b0a1eb0e90e --- /dev/null +++ b/lld/test/ELF/lto/arm-rtlibcall.ll @@ -0,0 +1,122 @@ +; REQUIRES: arm +;; https://github.com/llvm/llvm-project/issues/127284 +;; Test for LTO optimizing out references to symbols that are pulled in by +;; compiler-generated libcalls (post LTO). +;; The problem here is that the call to __aeabi_ldivmod is generated post-LTO, +;; during ISel, so aeabi_ldivmod.o is only marked as required afterwards but by +;; that time we have decided that all the callees of __aeabi_ldivmod are not +;; needed and have been marked as ABS zero symbols. +; RUN: rm -rf %t && split-file %s %t && cd %t +; RUN: llvm-as divmoddi4.ll -o divmoddi4.bc +; RUN: llvm-mc -filetype=obj -triple=armv7-none-unknown-eabi aeabi_ldivmod.s -o aeabi_ldivmod.o +;; With an explicit __aebi_ldivmod call in the input IR this works as expected: +; RUN: llvm-as main-explicit.ll -o main-explicit-ldivmod.bc +; RUN: ld.lld main-explicit-ldivmod.bc --start-lib aeabi_ldivmod.o divmoddi4.bc --end-lib -o test.exe -Bstatic +; RUN: llvm-objdump -d -r -t test.exe | FileCheck %s --check-prefix=GOOD-DUMP +; GOOD-DUMP-LABEL: SYMBOL TABLE: +; GOOD-DUMP: [[#]] g F .text [[#]] _start +; GOOD-DUMP: [[#]] g F .text 00000024 __aeabi_ldivmod +; GOOD-DUMP: [[#]] g F .text [[#]] __divmoddi4 +; GOOD-DUMP-LABEL: <__aeabi_ldivmod>: +; GOOD-DUMP: bl 0x20140 <__divmoddi4> @ imm = #0x28 + +; But if the call is generated by ISel, we end up with an invalid reference: +; RUN: llvm-as main-implicit.ll -o main-implicit-ldivmod.bc +; RUN: ld.lld main-implicit-ldivmod.bc --start-lib aeabi_ldivmod.o divmoddi4.bc --end-lib -o test.exe -Bstatic +; RUN: llvm-objdump -d -r -t test.exe | FileCheck %s --check-prefix=BAD-DUMP +;; We jump to address zero here and __divmoddi4 ends up being an absolute symbol: +; BAD-DUMP-LABEL: SYMBOL TABLE: +; BAD-DUMP: [[#]] g F .text [[#]] _start +; BAD-DUMP: [[#]] g F .text 00000024 __aeabi_ldivmod +; BAD-DUMP: [[#]] g *ABS* 00000000 __divmoddi4 +; BAD-DUMP-LABEL: <__aeabi_ldivmod>: +; BAD-DUMP: bl 0x0 <__divmoddi4> @ imm = #-0x200fc +;; Linking with -pie complains about the invalid relocation (and even points back to the source files) +; RUN: not ld.lld main-implicit-ldivmod.bc --start-lib aeabi_ldivmod.o divmoddi4.bc --end-lib -o test.exe --no-undefined -pie --no-dynamic-linker 2>&1 | FileCheck %s --check-prefix=PIE-ERROR +PIE-ERROR: ld.lld: error: relocation R_ARM_CALL cannot refer to absolute symbol: __divmoddi4 +PIE-ERROR-NEXT: >>> defined in divmoddi4.bc +PIE-ERROR-NEXT: >>> referenced by aeabi_ldivmod.o:(__aeabi_ldivmod) + +;; Interestingly, just declaring __aeabi_ldivmod is sufficient to not run into this issue. +; RUN: llvm-as main-declared.ll -o main-declared-ldivmod.bc +; RUN: ld.lld main-declared-ldivmod.bc --start-lib aeabi_ldivmod.o divmoddi4.bc --end-lib -o test.exe -Bstatic +; RUN: llvm-objdump -d -r -t test.exe | FileCheck %s --check-prefix=GOOD-DUMP + +;--- divmoddi4.ll +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7-none-unknown-eabi" + +; Adding it to llvm.used does not appears to have any effect! +; @llvm.used = appending global [1 x ptr] [ptr @__divmoddi4], section "llvm.metadata" + +; Stub version of the real __divmoddi4 +define i64 @__divmoddi4(i64 %a, i64 %b, ptr writeonly %rem) #0 align 32 { +entry: + %sub = sub i64 %a, %b + store i64 0, ptr %rem, align 8 + ret i64 %sub +} + +attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a15" } + +;--- aeabi_ldivmod.s +.syntax unified +.p2align 2 +.arm +.globl __aeabi_ldivmod +.type __aeabi_ldivmod,%function +__aeabi_ldivmod: + push {r6, lr} + sub sp, sp, #16 + add r6, sp, #8 + str r6, [sp] + bl __divmoddi4 + ldr r2, [sp, #8] + ldr r3, [sp, #12] + add sp, sp, #16 + pop {r6, pc} +.size __aeabi_ldivmod, . - __aeabi_ldivmod + +;--- main-implicit.ll +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7-none-unknown-eabi" + +define dso_local i64 @_start(i64 %num, i64 %denom) local_unnamed_addr #0 { +entry: + %div = sdiv i64 %num, %denom + %ret = add i64 %div, 2 + ret i64 %ret +} + +attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a15" } + +;--- main-explicit.ll +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7-none-unknown-eabi" + +declare { i64, i64 } @__aeabi_ldivmod(i64, i64) + +define dso_local noundef i64 @_start(i64 noundef %num, i64 noundef %denom) local_unnamed_addr #0 { +entry: + %quotrem = call { i64, i64 } @__aeabi_ldivmod(i64 %num, i64 %denom) + %div = extractvalue { i64, i64 } %quotrem, 0 + %ret = add i64 %div, 2 + ret i64 %ret +} + +attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a15" } + +;--- main-declared.ll +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7-none-unknown-eabi" + +declare { i64, i64 } @__aeabi_ldivmod(i64, i64) + +define dso_local i64 @_start(i64 %num, i64 %denom) local_unnamed_addr #0 { +entry: + %div = sdiv i64 %num, %denom + %ret = add i64 %div, 2 + ret i64 %ret +} + +attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a15" } \ No newline at end of file From f08327202fa55d7885b4330a23873c5594711b26 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 14 Feb 2025 16:54:27 -0800 Subject: [PATCH 2/2] add test without --start-lib/--end-lib Created using spr 1.3.6-beta.1 --- lld/test/ELF/lto/arm-rtlibcall.ll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lld/test/ELF/lto/arm-rtlibcall.ll b/lld/test/ELF/lto/arm-rtlibcall.ll index 89b0a1eb0e90e..81a0e60402fe0 100644 --- a/lld/test/ELF/lto/arm-rtlibcall.ll +++ b/lld/test/ELF/lto/arm-rtlibcall.ll @@ -36,6 +36,9 @@ PIE-ERROR: ld.lld: error: relocation R_ARM_CALL cannot refer to absolute symbol: __divmoddi4 PIE-ERROR-NEXT: >>> defined in divmoddi4.bc PIE-ERROR-NEXT: >>> referenced by aeabi_ldivmod.o:(__aeabi_ldivmod) +;; Removing --start-lib/--end-lib also ensures that the reference is retained +; RUN: ld.lld main-implicit-ldivmod.bc aeabi_ldivmod.o divmoddi4.bc -o test.exe -Bstatic +; RUN: llvm-objdump -d -r -t test.exe | FileCheck %s --check-prefix=GOOD-DUMP ;; Interestingly, just declaring __aeabi_ldivmod is sufficient to not run into this issue. ; RUN: llvm-as main-declared.ll -o main-declared-ldivmod.bc