Skip to content

Commit 28ad007

Browse files
authored
[ThinLTO] Don't mark calloc function dead (#72673)
Dead store elimination pass may fold malloc + memset calls into a single call to calloc. If calloc is not preserved and is not being called it can be marked dead which results in link error.
1 parent 306e13e commit 28ad007

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

lld/test/ELF/lto/libcall-archive-calloc.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
; RUN: llvm-dis < t.0.4.opt.bc | FileCheck %s
1212
; RUN: llvm-nm t | FileCheck %s --check-prefix=NM
1313

14-
; CHECK: declare noalias noundef ptr @calloc(i64 noundef, i64 noundef)
14+
; CHECK: define dso_local void @calloc
1515

1616
; NM-NOT: {{.}}
1717
; NM: {{.*}} T _start
1818
;; TODO: Currently the symbol is lazy, which lowers to a SHN_ABS symbol at address 0.
19-
; NM-NEXT: {{.*}} A calloc
19+
; NM-NEXT: {{.*}} T calloc
2020
; NM-NEXT: {{.*}} T foo
2121
; NM-NEXT: {{.*}} T malloc
2222
; NM-NEXT: {{.*}} T memset

llvm/include/llvm/IR/RuntimeLibcalls.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@ HANDLE_LIBCALL(UO_PPCF128, "__gcc_qunord")
438438
HANDLE_LIBCALL(MEMCPY, "memcpy")
439439
HANDLE_LIBCALL(MEMMOVE, "memmove")
440440
HANDLE_LIBCALL(MEMSET, "memset")
441+
// DSEPass can emit calloc if it finds a pair of malloc/memset
442+
HANDLE_LIBCALL(CALLOC, "calloc")
441443
HANDLE_LIBCALL(BZERO, nullptr)
442444

443445
// Element-wise unordered-atomic memory of different sizes

llvm/test/ThinLTO/X86/builtin-nostrip.ll

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
; RUN: llvm-lto2 run %t1.bc -o %t.out -save-temps \
1111
; RUN: -r %t1.bc,bar,pl \
1212
; RUN: -r %t1.bc,__stack_chk_guard,pl \
13-
; RUN: -r %t1.bc,__stack_chk_fail,pl
13+
; RUN: -r %t1.bc,__stack_chk_fail,pl \
14+
; RUN: -r %t1.bc,calloc,pl
1415
; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK-NM
1516

1617
; Re-compile, this time without the thinlto indices.
@@ -20,7 +21,8 @@
2021
; RUN: llvm-lto2 run %t4.bc -o %t5.out -save-temps \
2122
; RUN: -r %t4.bc,bar,pl \
2223
; RUN: -r %t4.bc,__stack_chk_guard,pl \
23-
; RUN: -r %t4.bc,__stack_chk_fail,pl
24+
; RUN: -r %t4.bc,__stack_chk_fail,pl \
25+
; RUN: -r %t4.bc,calloc,pl
2426
; RUN: llvm-nm %t5.out.0 | FileCheck %s --check-prefix=CHECK-NM
2527

2628
; Test the old lto interface without thinlto.
@@ -30,6 +32,9 @@
3032
; CHECK-NM-NOT: bar
3133
; CHECK-NM: T __stack_chk_fail
3234
; CHECK-NM: D __stack_chk_guard
35+
; Allow calloc to be internalized so --gc-sections can
36+
; still eliminate it if it's not really used anywhere.
37+
; CHECK-NM: {{[Tt]}} calloc
3338
; CHECK-NM-NOT: bar
3439

3540
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
@@ -44,3 +49,7 @@ define void @bar() {
4449
define void @__stack_chk_fail() {
4550
ret void
4651
}
52+
53+
define ptr @calloc(i64, i64) {
54+
ret ptr null
55+
}

0 commit comments

Comments
 (0)