xref: /llvm-project/lld/test/COFF/start-lib.ll (revision d9b8120259a546ce7aa9f047566fef29479f59e8)
1; REQUIRES: x86
2
3; RUN: rm -rf %t.dir
4; RUN: split-file %s %t.dir
5
6; RUN: llc -filetype=obj %t.dir/main.ll -o %t.obj
7; RUN: llc -filetype=obj %t.dir/start-lib1.ll -o %t1.obj
8; RUN: llc -filetype=obj %t.dir/start-lib2.ll -o %t2.obj
9; RUN: llc -filetype=obj %t.dir/eager.ll -o %t-eager.obj
10; RUN: opt -thinlto-bc %t.dir/main.ll -o %t.bc
11; RUN: opt -thinlto-bc %t.dir/start-lib1.ll -o %t1.bc
12; RUN: opt -thinlto-bc %t.dir/start-lib2.ll -o %t2.bc
13; RUN: opt -thinlto-bc %t.dir/eager.ll -o %t-eager.bc
14;
15; RUN: lld-link -out:%t1.exe -entry:main -opt:noref -lldmap:%t1.map \
16; RUN:     %t.obj %t1.obj %t2.obj %t-eager.obj
17; RUN: FileCheck --check-prefix=TEST1 %s < %t1.map
18; RUN: lld-link -out:%t1.exe -entry:main -opt:noref -lldmap:%t1.thinlto.map \
19; RUN:     %t.bc %t1.bc %t2.bc %t-eager.bc
20; RUN: FileCheck --check-prefix=TEST1 %s < %t1.thinlto.map
21; TEST1: foo
22; TEST1: bar
23;
24; RUN: lld-link -out:%t2.exe -entry:main -opt:noref -lldmap:%t2.map \
25; RUN:     %t.obj -start-lib %t1.obj %t-eager.obj -end-lib %t2.obj
26; RUN: FileCheck --check-prefix=TEST2 %s < %t2.map
27; RUN: lld-link -out:%t2.exe -entry:main -opt:noref -lldmap:%t2.thinlto.map \
28; RUN:     %t.bc -start-lib %t1.bc %t-eager.bc -end-lib %t2.bc
29; RUN: FileCheck --check-prefix=TEST2 %s < %t2.thinlto.map
30; TEST2:     Address Size Align Out In Symbol
31; TEST2-NOT:                           {{ }}foo{{$}}
32; TEST2:                               {{ }}bar{{$}}
33; TEST2-NOT:                           {{ }}foo{{$}}
34;
35; RUN: lld-link -out:%t3.exe -entry:main -opt:noref -lldmap:%t3.map \
36; RUN:     %t.obj -start-lib %t1.obj %t2.obj %t-eager.obj
37; RUN: FileCheck --check-prefix=TEST3 %s < %t3.map
38; RUN: lld-link -out:%t3.exe -entry:main -opt:noref -lldmap:%t3.thinlto.map \
39; RUN:     %t.bc -start-lib %t1.bc %t2.bc %t-eager.bc
40; RUN: FileCheck --check-prefix=TEST3 %s < %t3.thinlto.map
41; TEST3:     Address Size Align Out In Symbol
42; TEST3-NOT: {{ }}foo{{$}}
43; TEST3-NOT: {{ }}bar{{$}}
44
45
46#--- main.ll
47
48target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
49target triple = "x86_64-pc-windows-msvc"
50
51declare void @eager()
52
53define void @main() {
54  call void @eager()
55  ret void
56}
57
58
59#--- start-lib1.ll
60
61target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
62target triple = "x86_64-pc-windows-msvc"
63
64declare i32 @bar()
65
66define i32 @foo() {
67  %1 = call i32 () @bar()
68  %2 = add i32 %1, 1
69  ret i32 %2
70}
71
72!llvm.linker.options = !{!0}
73!0 = !{!"/INCLUDE:foo"}
74
75
76#--- start-lib2.ll
77
78target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
79target triple = "x86_64-pc-windows-msvc"
80
81define i32 @bar() {
82  ret i32 1
83}
84
85!llvm.linker.options = !{!0}
86!0 = !{!"/INCLUDE:bar"}
87
88#--- eager.ll
89
90target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
91target triple = "x86_64-pc-windows-msvc"
92
93define void @eager() {
94  ret void
95}
96
97define i32 @ogre() {
98  ret i32 1
99}
100
101
102; Check that lazy object files trigger loads correctly.
103; If the links succeed, that's enough, no additional tests needed.
104
105; RUN: llc -filetype=obj %t.dir/main2.ll -o %t-main2.obj
106; RUN: llc -filetype=obj %t.dir/foo.ll -o %t-foo.obj
107; RUN: llc -filetype=obj %t.dir/bar.ll -o %t-bar.obj
108; RUN: llc -filetype=obj %t.dir/baz.ll -o %t-baz.obj
109; RUN: opt -thinlto-bc %t.dir/main2.ll -o %t-main2.bc
110; RUN: opt -thinlto-bc %t.dir/foo.ll -o %t-foo.bc
111; RUN: opt -thinlto-bc %t.dir/bar.ll -o %t-bar.bc
112; RUN: opt -thinlto-bc %t.dir/baz.ll -o %t-baz.bc
113
114; RUN: lld-link -out:%t2.exe -entry:main \
115; RUN:     %t-main2.obj %t-foo.obj %t-bar.obj %t-baz.obj
116; RUN: lld-link -out:%t2.exe -entry:main \
117; RUN:     %t-main2.obj /start-lib %t-foo.obj %t-bar.obj %t-baz.obj /end-lib
118; RUN: lld-link -out:%t2.exe -entry:main \
119; RUN:     /start-lib %t-foo.obj %t-bar.obj %t-baz.obj /end-lib %t-main2.obj
120
121; RUN: lld-link -out:%t2.exe -entry:main \
122; RUN:     %t-main2.bc %t-foo.bc %t-bar.bc %t-baz.bc
123; RUN: lld-link -out:%t2.exe -entry:main \
124; RUN:     %t-main2.bc /start-lib %t-foo.bc %t-bar.bc %t-baz.bc /end-lib
125; RUN: lld-link -out:%t2.exe -entry:main \
126; RUN:     /start-lib %t-foo.bc %t-bar.bc %t-baz.bc /end-lib %t-main2.bc
127
128#--- main2.ll
129
130target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
131target triple = "x86_64-pc-windows-msvc"
132
133declare void @bar()
134
135define void @main() {
136  call void () @bar()
137  ret void
138}
139
140
141#--- foo.ll
142
143target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
144target triple = "x86_64-pc-windows-msvc"
145
146define void @foo() {
147  ret void
148}
149
150
151#--- bar.ll
152
153target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
154target triple = "x86_64-pc-windows-msvc"
155
156; One undefined symbol from the lazy obj file before it,
157; one from the one after it.
158declare void @foo()
159declare void @baz()
160
161define void @bar() {
162  call void () @foo()
163  call void () @baz()
164  ret void
165}
166
167
168#--- baz.ll
169
170target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
171target triple = "x86_64-pc-windows-msvc"
172
173define void @baz() {
174  ret void
175}
176
177
178; Check cycles between symbols in two /start-lib files.
179; If the links succeed and does not emit duplicate symbol diagnostics,
180; that's enough.
181
182; RUN: llc -filetype=obj %t.dir/main3.ll -o %t-main3.obj
183; RUN: llc -filetype=obj %t.dir/cycle1.ll -o %t-cycle1.obj
184; RUN: llc -filetype=obj %t.dir/cycle2.ll -o %t-cycle2.obj
185; RUN: opt -thinlto-bc %t.dir/main3.ll -o %t-main3.bc
186; RUN: opt -thinlto-bc %t.dir/cycle1.ll -o %t-cycle1.bc
187; RUN: opt -thinlto-bc %t.dir/cycle2.ll -o %t-cycle2.bc
188
189; RUN: lld-link -out:%t3.exe -entry:main \
190; RUN:     %t-main3.obj %t-cycle1.obj %t-cycle2.obj
191; RUN: lld-link -out:%t3.exe -entry:main \
192; RUN:     %t-main3.obj /start-lib %t-cycle1.obj %t-cycle2.obj /end-lib
193; RUN: lld-link -out:%t3.exe -entry:main \
194; RUN:     /start-lib %t-cycle1.obj %t-cycle2.obj /end-lib %t-main3.obj
195
196; RUN: lld-link -out:%t3.exe -entry:main \
197; RUN:     %t-main3.bc %t-cycle1.bc %t-cycle2.bc
198; RUN: lld-link -out:%t3.exe -entry:main \
199; RUN:     %t-main3.bc /start-lib %t-cycle1.bc %t-cycle2.bc /end-lib
200; RUN: lld-link -out:%t3.exe -entry:main \
201; RUN:     /start-lib %t-cycle1.bc %t-cycle2.bc /end-lib %t-main3.bc
202
203#--- main3.ll
204
205target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
206target triple = "x86_64-pc-windows-msvc"
207
208declare void @foo1()
209
210define void @main() {
211  call void () @foo1()
212  ret void
213}
214
215#--- cycle1.ll
216
217target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
218target triple = "x86_64-pc-windows-msvc"
219
220declare void @bar()
221
222define void @foo1() {
223  ; cycle1.ll pulls in cycle2.ll for bar(), and cycle2.ll then pulls in
224  ; cycle1.ll again for foo2().
225  call void () @bar()
226  ret void
227}
228
229define void @foo2() {
230  ret void
231}
232
233
234#--- cycle2.ll
235
236target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
237target triple = "x86_64-pc-windows-msvc"
238
239declare void @foo2()
240
241define void @bar() {
242  call void () @foo2()
243  ret void
244}
245