summaryrefslogtreecommitdiffstats
path: root/llvm/test/Linker
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-12-01 15:19:48 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-12-01 15:19:48 +0000
commitbaa3bf8f76568de6198613fb2ba7695a76c29109 (patch)
treeec15e39aac1505fc951253627c2ee9f094b4abdf /llvm/test/Linker
parent6c800eb3f02f2a57cceae862f9602318f9b7b9cc (diff)
downloadbcm5719-llvm-baa3bf8f76568de6198613fb2ba7695a76c29109.tar.gz
bcm5719-llvm-baa3bf8f76568de6198613fb2ba7695a76c29109.zip
Bring r254336 back:
The difference is that now we don't error on out-of-comdat access to internal global values. We copy them instead. This seems to match the expectation of COFF linkers (see pr25686). Original message: Start deciding earlier what to link. A traditional linker is roughly split in symbol resolution and "copying stuff". The two tasks are badly mixed in lib/Linker. This starts splitting them apart. With this patch there are no direct call to linkGlobalValueBody or linkGlobalValueProto. Everything is linked via WapValue. This also includes a few fixes: * A GV goes undefined if the comdat is dropped (comdat11.ll). * We error if an internal GV goes undefined (comdat13.ll). * We don't link an unused comdat. The first two match the behavior of an ELF linker. The second one is equivalent to running globaldce on the input. llvm-svn: 254418
Diffstat (limited to 'llvm/test/Linker')
-rw-r--r--llvm/test/Linker/Inputs/comdat11.ll9
-rw-r--r--llvm/test/Linker/Inputs/comdat13.ll9
-rw-r--r--llvm/test/Linker/comdat11.ll13
-rw-r--r--llvm/test/Linker/comdat12.ll8
-rw-r--r--llvm/test/Linker/comdat13.ll30
-rw-r--r--llvm/test/Linker/comdat9.ll3
6 files changed, 72 insertions, 0 deletions
diff --git a/llvm/test/Linker/Inputs/comdat11.ll b/llvm/test/Linker/Inputs/comdat11.ll
new file mode 100644
index 00000000000..5b7f74cf0b2
--- /dev/null
+++ b/llvm/test/Linker/Inputs/comdat11.ll
@@ -0,0 +1,9 @@
+$foo = comdat any
+@foo = global i8 1, comdat
+define void @zed() {
+ call void @bar()
+ ret void
+}
+define void @bar() comdat($foo) {
+ ret void
+}
diff --git a/llvm/test/Linker/Inputs/comdat13.ll b/llvm/test/Linker/Inputs/comdat13.ll
new file mode 100644
index 00000000000..85515210ed7
--- /dev/null
+++ b/llvm/test/Linker/Inputs/comdat13.ll
@@ -0,0 +1,9 @@
+$foo = comdat any
+@foo = internal global i8 1, comdat
+define i8* @zed() {
+ call void @bax()
+ ret i8* @foo
+}
+define internal void @bax() comdat($foo) {
+ ret void
+}
diff --git a/llvm/test/Linker/comdat11.ll b/llvm/test/Linker/comdat11.ll
new file mode 100644
index 00000000000..dbade4104fe
--- /dev/null
+++ b/llvm/test/Linker/comdat11.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-link -S %s %p/Inputs/comdat11.ll -o - | FileCheck %s
+
+$foo = comdat any
+@foo = global i8 0, comdat
+
+; CHECK: @foo = global i8 0, comdat
+
+; CHECK: define void @zed() {
+; CHECK: call void @bar()
+; CHECK: ret void
+; CHECK: }
+
+; CHECK: declare void @bar()
diff --git a/llvm/test/Linker/comdat12.ll b/llvm/test/Linker/comdat12.ll
new file mode 100644
index 00000000000..d06e222b63a
--- /dev/null
+++ b/llvm/test/Linker/comdat12.ll
@@ -0,0 +1,8 @@
+; RUN: llvm-link %s -S -o - | FileCheck %s
+
+$foo = comdat largest
+define internal void @foo() comdat($foo) {
+ ret void
+}
+
+; CHECK-NOT: foo
diff --git a/llvm/test/Linker/comdat13.ll b/llvm/test/Linker/comdat13.ll
new file mode 100644
index 00000000000..d1e382a2f27
--- /dev/null
+++ b/llvm/test/Linker/comdat13.ll
@@ -0,0 +1,30 @@
+; RUN: llvm-link -S %s %p/Inputs/comdat13.ll -o - | FileCheck %s
+
+; In Inputs/comdat13.ll a function not in the $foo comdat (zed) references an
+; internal function in the comdat $foo.
+; The IR would be ilegal on ELF ("relocation refers to discarded section"),
+; but COFF linkers seem to just duplicate the comdat.
+
+$foo = comdat any
+@foo = internal global i8 0, comdat
+define i8* @bar() {
+ ret i8* @foo
+}
+
+; CHECK: $foo = comdat any
+
+; CHECK: @foo = internal global i8 0, comdat
+; CHECK: @foo.1 = internal global i8 1, comdat($foo)
+
+; CHECK: define i8* @bar() {
+; CHECK-NEXT: ret i8* @foo
+; CHECK-NEXT: }
+
+; CHECK: define i8* @zed() {
+; CHECK-NEXT: call void @bax()
+; CHECK-NEXT: ret i8* @foo.1
+; CHECK-NEXT: }
+
+; CHECK: define internal void @bax() comdat($foo) {
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
diff --git a/llvm/test/Linker/comdat9.ll b/llvm/test/Linker/comdat9.ll
index 274957401aa..4f6f2cfb845 100644
--- a/llvm/test/Linker/comdat9.ll
+++ b/llvm/test/Linker/comdat9.ll
@@ -14,6 +14,9 @@ $f2 = comdat largest
define internal void @f2() comdat($f2) {
ret void
}
+define void @f3() comdat($f2) {
+ ret void
+}
; CHECK-DAG: $f2 = comdat largest
; CHECK-DAG: define internal void @f2() comdat {
OpenPOWER on IntegriCloud