Summary: Removing the dropped symbols will prevent indirect call promotion in the ThinLTO Backend from adding a new reference to a symbol, which can result in linker unsats. This can happen when we compile with a sample profile collected from one binary by used for another, which may have profiled targets that aren't used in the new binary. Note that until dropDeadSymbols handles variables and aliases (in progress), we may not be able to remove the declaration and can still have an issue. Reviewers: grimar, davidxl Subscribers: mehdi_amini, inglorion, llvm-commits, eraman Differential Revision: https://reviews.llvm.org/D42816 llvm-svn: 324299
85 lines
3.9 KiB
LLVM
85 lines
3.9 KiB
LLVM
; Test to ensure we don't internalize or treat as dead a global value
|
|
; with a valid C identifier section name. Otherwise, ELF linker generation of
|
|
; __start_"sectionname" and __stop_"sectionname" symbols would not occur and
|
|
; we can end up with undefined references at link time.
|
|
|
|
; First try RegularLTO
|
|
; RUN: opt %s -o %t.o
|
|
; RUN: llvm-lto2 dump-symtab %t.o | FileCheck %s --check-prefix=SYMTAB
|
|
; RUN: opt %p/Inputs/global_with_section.ll -o %t2.o
|
|
; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \
|
|
; RUN: --plugin-opt=save-temps \
|
|
; RUN: -o %t3.o %t.o %t2.o
|
|
; Check results of internalization
|
|
; RUN: llvm-dis %t3.o.0.2.internalize.bc -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2-REGULARLTO
|
|
|
|
; Next try ThinLTO
|
|
; RUN: opt -module-summary %s -o %t.o
|
|
; RUN: llvm-lto2 dump-symtab %t.o | FileCheck %s --check-prefix=SYMTAB
|
|
; RUN: opt -module-summary %p/Inputs/global_with_section.ll -o %t2.o
|
|
; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \
|
|
; RUN: --plugin-opt=thinlto \
|
|
; RUN: --plugin-opt=save-temps \
|
|
; RUN: -o %t3.o %t.o %t2.o
|
|
; Check results of internalization
|
|
; RUN: llvm-dis %t.o.2.internalize.bc -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-THINLTO
|
|
; RUN: llvm-dis %t2.o.2.internalize.bc -o - | FileCheck %s --check-prefix=CHECK2-THINLTO
|
|
|
|
; SYMTAB: deadfunc_with_section
|
|
; SYMTAB-NEXT: section some_other_section
|
|
; SYMTAB-NEXT: deadfunc_with_nonC_section
|
|
; SYMTAB-NEXT: section .nonCsection
|
|
; SYMTAB-NEXT: deadfunc2_called_from_section
|
|
; SYMTAB-NEXT: deadfunc2_called_from_nonC_section
|
|
; SYMTAB-NEXT: var_with_section
|
|
; SYMTAB-NEXT: section some_section
|
|
; SYMTAB-NEXT: var_with_nonC_section
|
|
; SYMTAB-NEXT: section .nonCsection
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
; We should not internalize @var_with_section due to section
|
|
; CHECK-DAG: @var_with_section = dso_local global i32 0, section "some_section"
|
|
@var_with_section = global i32 0, section "some_section"
|
|
|
|
; Confirm via a variable with a non-C identifier section that we are getting
|
|
; the expected internalization.
|
|
; CHECK-REGULARLTO-DAG: @var_with_nonC_section = internal global i32 0, section ".nonCsection"
|
|
; Check we dropped definition of dead variable.
|
|
; CHECK-THINLTO-NOT: @var_with_nonC_section
|
|
@var_with_nonC_section = global i32 0, section ".nonCsection"
|
|
|
|
; We should not internalize @deadfunc_with_section due to section
|
|
; CHECK-DAG: define dso_local void @deadfunc_with_section() section "some_other_section"
|
|
define void @deadfunc_with_section() section "some_other_section" {
|
|
call void @deadfunc2_called_from_section()
|
|
ret void
|
|
}
|
|
|
|
; Confirm via a function with a non-C identifier section that we are getting
|
|
; the expected internalization.
|
|
; CHECK2-REGULARLTO-DAG: define internal void @deadfunc_with_nonC_section() section ".nonCsection"
|
|
; Check dead function converted to declaration.
|
|
; CHECK-THINLTO-NOT: @deadfunc_with_nonC_section()
|
|
define void @deadfunc_with_nonC_section() section ".nonCsection" {
|
|
call void @deadfunc2_called_from_nonC_section()
|
|
ret void
|
|
}
|
|
|
|
; In RegularLTO mode, where we have combined all the IR,
|
|
; @deadfunc2_called_from_section can be internalized.
|
|
; CHECK2-REGULARLTO: define internal void @deadfunc2_called_from_section
|
|
; In ThinLTO mode, we can't internalize it as it needs to be preserved
|
|
; (due to the access from @deadfunc_with_section which must be preserved), and
|
|
; can't be internalized since the reference is from a different module.
|
|
; CHECK2-THINLTO: define dso_local void @deadfunc2_called_from_section
|
|
declare void @deadfunc2_called_from_section()
|
|
|
|
; Confirm when called from a function with a non-C identifier section that we
|
|
; are getting the expected internalization.
|
|
; CHECK2-REGULARLTO: define internal void @deadfunc2_called_from_nonC_section
|
|
; Check dead function converted to declaration.
|
|
; CHECK2-THINLTO-NOT: @deadfunc2_called_from_nonC_section
|
|
declare void @deadfunc2_called_from_nonC_section()
|