[lld] [llvm] [ThinLTO] Don't mark calloc function dead (PR #72673)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 09:08:44 PST 2023
https://github.com/eleviant updated https://github.com/llvm/llvm-project/pull/72673
>From b5badb959f286289fd299a1c3b3605e278dcfe94 Mon Sep 17 00:00:00 2001
From: Evgeny Leviant <eleviant at accesssoftek.com>
Date: Fri, 17 Nov 2023 15:32:24 +0300
Subject: [PATCH] [ThinLTO] Don't mark calloc function dead
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 directly it can be marked dead during thin link and result
in link error.
---
lld/test/ELF/lto/libcall-archive-calloc.ll | 4 ++--
llvm/include/llvm/IR/RuntimeLibcalls.def | 2 ++
llvm/test/ThinLTO/X86/builtin-nostrip.ll | 13 +++++++++++--
3 files changed, 15 insertions(+), 4 deletions(-)
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 different 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