mirror of
https://github.com/intel/llvm.git
synced 2026-01-25 10:55:58 +08:00
ELF ICF: Merge only functions.
Previously, LLD merged all read-only sections. So the following
program prints out "true" if -icf=all is specified.
static const int foo = 1;
static const int bar = 1;
int main() { printf("%s\n", &foo == &bar ? "true" : "false"); }
This is somewhat counter-intuitive, and it actually caused nasty issues.
One example is https://bugs.chromium.org/p/chromium/issues/detail?id=682773#c24.
This patch changes the way how it works. Now ICF merges only functions
(i.e. executable sections).
Differential Revision: https://reviews.llvm.org/D30365
llvm-svn: 296534
This commit is contained in:
@@ -162,8 +162,8 @@ static bool isEligible(InputSection *S) {
|
||||
// .init and .fini contains instructions that must be executed to
|
||||
// initialize and finalize the process. They cannot and should not
|
||||
// be merged.
|
||||
return S->Live && (S->Flags & SHF_ALLOC) && !(S->Flags & SHF_WRITE) &&
|
||||
S->Name != ".init" && S->Name != ".fini";
|
||||
return S->Live && (S->Flags & SHF_ALLOC) && (S->Flags & SHF_EXECINSTR) &&
|
||||
!(S->Flags & SHF_WRITE) && S->Name != ".init" && S->Name != ".fini";
|
||||
}
|
||||
|
||||
// Split an equivalence class into smaller classes.
|
||||
|
||||
20
lld/test/ELF/icf9.s
Normal file
20
lld/test/ELF/icf9.s
Normal file
@@ -0,0 +1,20 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
### Make sure that we do not merge data.
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||
# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
|
||||
|
||||
# CHECK-NOT: selected .data.d1
|
||||
# CHECK-NOT: selected .data.d2
|
||||
|
||||
.globl _start, d1, d2
|
||||
_start:
|
||||
ret
|
||||
|
||||
.section .data.f1, "a"
|
||||
d1:
|
||||
.byte 1
|
||||
|
||||
.section .data.f2, "a"
|
||||
d2:
|
||||
.byte 1
|
||||
Reference in New Issue
Block a user