[llvm] 28ad007 - [ThinLTO] Don't mark calloc function dead (#72673)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 30 10:02:31 PST 2023


Author: eleviant
Date: 2023-11-30T19:02:25+01:00
New Revision: 28ad007927a4126e12b7aec7daa7f10bc1e29ae1

URL: https://github.com/llvm/llvm-project/commit/28ad007927a4126e12b7aec7daa7f10bc1e29ae1
DIFF: https://github.com/llvm/llvm-project/commit/28ad007927a4126e12b7aec7daa7f10bc1e29ae1.diff

LOG: [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.

Added: 
    

Modified: 
    lld/test/ELF/lto/libcall-archive-calloc.ll
    llvm/include/llvm/IR/RuntimeLibcalls.def
    llvm/test/ThinLTO/X86/builtin-nostrip.ll

Removed: 
    


################################################################################
diff  --git a/lld/test/ELF/lto/libcall-archive-calloc.ll b/lld/test/ELF/lto/libcall-archive-calloc.ll
index 12d5d4ae572d99b..f082a6ce68abcc7 100644
--- a/lld/test/ELF/lto/libcall-archive-calloc.ll
+++ b/lld/test/ELF/lto/libcall-archive-calloc.ll
@@ -11,12 +11,12 @@
 ; RUN: llvm-dis < t.0.4.opt.bc | FileCheck %s
 ; RUN: llvm-nm t | FileCheck %s --check-prefix=NM
 
-; CHECK: declare noalias noundef ptr @calloc(i64 noundef, i64 noundef)
+; CHECK: define dso_local void @calloc
 
 ; NM-NOT:  {{.}}
 ; NM:      {{.*}} T _start
 ;; TODO: Currently the symbol is lazy, which lowers to a SHN_ABS symbol at address 0.
-; NM-NEXT: {{.*}} A calloc
+; NM-NEXT: {{.*}} T calloc
 ; NM-NEXT: {{.*}} T foo
 ; NM-NEXT: {{.*}} T malloc
 ; NM-NEXT: {{.*}} T memset

diff  --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index 6ec98e278988428..19dea60bebf9be5 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -438,6 +438,8 @@ HANDLE_LIBCALL(UO_PPCF128, "__gcc_qunord")
 HANDLE_LIBCALL(MEMCPY, "memcpy")
 HANDLE_LIBCALL(MEMMOVE, "memmove")
 HANDLE_LIBCALL(MEMSET, "memset")
+// DSEPass can emit calloc if it finds a pair of malloc/memset
+HANDLE_LIBCALL(CALLOC, "calloc")
 HANDLE_LIBCALL(BZERO, nullptr)
 
 // Element-wise unordered-atomic memory of 
diff erent sizes

diff  --git a/llvm/test/ThinLTO/X86/builtin-nostrip.ll b/llvm/test/ThinLTO/X86/builtin-nostrip.ll
index 1b6a4ef879254e4..9ac58cf824d2f74 100644
--- a/llvm/test/ThinLTO/X86/builtin-nostrip.ll
+++ b/llvm/test/ThinLTO/X86/builtin-nostrip.ll
@@ -10,7 +10,8 @@
 ; RUN: llvm-lto2 run %t1.bc -o %t.out -save-temps \
 ; RUN:   -r %t1.bc,bar,pl \
 ; RUN:   -r %t1.bc,__stack_chk_guard,pl \
-; RUN:   -r %t1.bc,__stack_chk_fail,pl
+; RUN:   -r %t1.bc,__stack_chk_fail,pl \
+; RUN:   -r %t1.bc,calloc,pl
 ; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK-NM
 
 ; Re-compile, this time without the thinlto indices.
@@ -20,7 +21,8 @@
 ; RUN: llvm-lto2 run %t4.bc -o %t5.out -save-temps \
 ; RUN:   -r %t4.bc,bar,pl \
 ; RUN:   -r %t4.bc,__stack_chk_guard,pl \
-; RUN:   -r %t4.bc,__stack_chk_fail,pl
+; RUN:   -r %t4.bc,__stack_chk_fail,pl \
+; RUN:   -r %t4.bc,calloc,pl
 ; RUN: llvm-nm %t5.out.0 | FileCheck %s --check-prefix=CHECK-NM
 
 ; Test the old lto interface without thinlto.
@@ -30,6 +32,9 @@
 ; CHECK-NM-NOT: bar
 ; CHECK-NM: T __stack_chk_fail
 ; CHECK-NM: D __stack_chk_guard
+; Allow calloc to be internalized so --gc-sections can
+; still eliminate it if it's not really used anywhere.
+; CHECK-NM: {{[Tt]}} calloc
 ; CHECK-NM-NOT: bar
 
 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() {
 define void @__stack_chk_fail() {
     ret void
 }
+
+define ptr @calloc(i64, i64) {
+    ret ptr null
+}


        


More information about the llvm-commits mailing list