Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lld / test / MachO / icf.s
blob68ed369188e91428de9de919afd14b0fadc7ad28
1 # REQUIRES: x86
2 # RUN: rm -rf %t; split-file %s %t
4 ## Check that we fold identical function bodies correctly. Note: This test
5 ## has many different functions; each group of similarly-named functions aim
6 ## to test one aspect of ICF's logic. To prevent accidental folding across
7 ## groups, we use `mov` instructions with a variety of immediates, with
8 ## different immediate values for each group.
10 # RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/main.s -o %t/main.o
11 # RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/abs.s -o %t/abs.o
12 # RUN: %lld -lSystem --icf=all -o %t/main %t/main.o %t/abs.o
13 # RUN: llvm-objdump -d --syms --dwarf=frames %t/main | FileCheck %s
15 # CHECK-LABEL: SYMBOL TABLE:
16 # CHECK: [[#%x,ABS1B_REF:]] l F __TEXT,__text _abs1a_ref
17 # CHECK: [[#%x,ABS1B_REF]] l F __TEXT,__text _abs1b_ref
18 # CHECK: [[#%x,ABS1B_REF_WITH_ADDEND:]] l F __TEXT,__text _abs1a_ref_with_addend
19 # CHECK: [[#%x,ABS1B_REF_WITH_ADDEND]] l F __TEXT,__text _abs1b_ref_with_addend
20 # CHECK: [[#%x,ABS2_REF:]] l F __TEXT,__text _abs2_ref
21 # CHECK: [[#%x,NOT_ABS_REF:]] l F __TEXT,__text _not_abs_ref
22 # CHECK: [[#%x,DYLIB_REF_2:]] l F __TEXT,__text _dylib_ref_1
23 # CHECK: [[#%x,DYLIB_REF_2]] l F __TEXT,__text _dylib_ref_2
24 # CHECK: [[#%x,DYLIB_REF_3:]] l F __TEXT,__text _dylib_ref_3
25 # CHECK: [[#%x,DYLIB_REF_4:]] l F __TEXT,__text _dylib_ref_4
26 # CHECK: [[#%x,ALT:]] l F __TEXT,__text _alt
27 # CHECK: [[#%x,WITH_ALT_ENTRY:]] l F __TEXT,__text _with_alt_entry
28 # CHECK: [[#%x,NO_ALT_ENTRY:]] l F __TEXT,__text _no_alt_entry
29 # CHECK: [[#%x,DEFINED_REF_WITH_ADDEND_2:]] l F __TEXT,__text _defined_ref_with_addend_1
30 # CHECK: [[#%x,DEFINED_REF_WITH_ADDEND_2]] l F __TEXT,__text _defined_ref_with_addend_2
31 # CHECK: [[#%x,DEFINED_REF_WITH_ADDEND_3:]] l F __TEXT,__text _defined_ref_with_addend_3
32 # CHECK: [[#%x,RECURSIVE:]] l F __TEXT,__text _recursive
33 # CHECK: [[#%x,CALL_RECURSIVE_2:]] l F __TEXT,__text _call_recursive_1
34 # CHECK: [[#%x,CALL_RECURSIVE_2]] l F __TEXT,__text _call_recursive_2
35 # CHECK: [[#%x,CHECK_LENGTH_1:]] l F __TEXT,__text _check_length_1
36 # CHECK: [[#%x,CHECK_LENGTH_2:]] l F __TEXT,__text _check_length_2
37 # CHECK: [[#%x,HAS_UNWIND_2:]] l F __TEXT,__text _has_unwind_1
38 # CHECK: [[#%x,HAS_UNWIND_2]] l F __TEXT,__text _has_unwind_2
39 # CHECK: [[#%x,HAS_UNWIND_3:]] l F __TEXT,__text _has_unwind_3
40 # CHECK: [[#%x,HAS_UNWIND_4:]] l F __TEXT,__text _has_unwind_4
41 # CHECK: [[#%x,HAS_ABS_PERSONALITY_1:]] l F __TEXT,__text _has_abs_personality_1
42 # CHECK: [[#%x,HAS_ABS_PERSONALITY_2:]] l F __TEXT,__text _has_abs_personality_2
43 # CHECK: [[#%x,HAS_EH_FRAME_1:]] l F __TEXT,__text _has_eh_frame_1
44 # CHECK: [[#%x,HAS_EH_FRAME_2:]] l F __TEXT,__text _has_eh_frame_2
45 # CHECK: [[#%x,HAS_EH_FRAME_3:]] l F __TEXT,__text _has_eh_frame_3
46 # CHECK: [[#%x,MUTALLY_RECURSIVE_2:]] l F __TEXT,__text _mutually_recursive_1
47 # CHECK: [[#%x,MUTALLY_RECURSIVE_2]] l F __TEXT,__text _mutually_recursive_2
48 # CHECK: [[#%x,INIT_2:]] l F __TEXT,__text _init_1
49 # CHECK: [[#%x,INIT_2]] l F __TEXT,__text _init_2
50 # CHECK: [[#%x,INIT_3:]] l O __TEXT,__foo _init_3
51 ### FIXME: Mutually-recursive functions with identical bodies (see below)
52 # COM: [[#%x,ASYMMETRIC_RECURSIVE_2:]] l F __TEXT,__text _asymmetric_recursive_1
53 # COM: [[#%x,ASYMMETRIC_RECURSIVE_2]] l F __TEXT,__text _asymmetric_recursive_2
54 # CHECK: [[#%x,GCC_EXCEPT_0:]] l O __TEXT,__gcc_except_tab GCC_except_table0
55 # CHECK: [[#%x,GCC_EXCEPT_0]] l O __TEXT,__gcc_except_tab GCC_except_table1
56 # CHECK: [[#%x,GCC_EXCEPT_2:]] l O __TEXT,__gcc_except_tab GCC_except_table2
58 ## Check that we don't accidentally dedup distinct EH frames.
59 # CHECK: FDE {{.*}} pc=[[#%x,HAS_EH_FRAME_1]]
60 # CHECK: FDE {{.*}} pc=[[#%x,HAS_EH_FRAME_2]]
61 # CHECK: FDE {{.*}} pc=[[#%x,HAS_EH_FRAME_3]]
63 # CHECK-LABEL: Disassembly of section __TEXT,__text:
64 # CHECK: <_main>:
65 # CHECK: callq 0x[[#%x,ABS1B_REF]] <_abs1b_ref>
66 # CHECK: callq 0x[[#%x,ABS1B_REF]] <_abs1b_ref>
67 # CHECK: callq 0x[[#%x,ABS1B_REF_WITH_ADDEND]] <_abs1b_ref_with_addend>
68 # CHECK: callq 0x[[#%x,ABS1B_REF_WITH_ADDEND]] <_abs1b_ref_with_addend>
69 # CHECK: callq 0x[[#%x,ABS2_REF]] <_abs2_ref>
70 # CHECK: callq 0x[[#%x,NOT_ABS_REF]] <_not_abs_ref>
71 # CHECK: callq 0x[[#%x,DYLIB_REF_2]] <_dylib_ref_2>
72 # CHECK: callq 0x[[#%x,DYLIB_REF_2]] <_dylib_ref_2>
73 # CHECK: callq 0x[[#%x,DYLIB_REF_3]] <_dylib_ref_3>
74 # CHECK: callq 0x[[#%x,DYLIB_REF_4]] <_dylib_ref_4>
75 # CHECK: callq 0x[[#%x,ALT]] <_alt>
76 # CHECK: callq 0x[[#%x,WITH_ALT_ENTRY]] <_with_alt_entry>
77 # CHECK: callq 0x[[#%x,NO_ALT_ENTRY]] <_no_alt_entry>
78 # CHECK: callq 0x[[#%x,DEFINED_REF_WITH_ADDEND_2]] <_defined_ref_with_addend_2>
79 # CHECK: callq 0x[[#%x,DEFINED_REF_WITH_ADDEND_2]] <_defined_ref_with_addend_2>
80 # CHECK: callq 0x[[#%x,DEFINED_REF_WITH_ADDEND_3]] <_defined_ref_with_addend_3>
81 # CHECK: callq 0x[[#%x,RECURSIVE]] <_recursive>
82 # CHECK: callq 0x[[#%x,CALL_RECURSIVE_2]] <_call_recursive_2>
83 # CHECK: callq 0x[[#%x,CALL_RECURSIVE_2]] <_call_recursive_2>
84 # CHECK: callq 0x[[#%x,CHECK_LENGTH_1]] <_check_length_1>
85 # CHECK: callq 0x[[#%x,CHECK_LENGTH_2]] <_check_length_2>
86 # CHECK: callq 0x[[#%x,HAS_UNWIND_2]] <_has_unwind_2>
87 # CHECK: callq 0x[[#%x,HAS_UNWIND_2]] <_has_unwind_2>
88 # CHECK: callq 0x[[#%x,HAS_UNWIND_3]] <_has_unwind_3>
89 # CHECK: callq 0x[[#%x,HAS_UNWIND_4]] <_has_unwind_4>
90 # CHECK: callq 0x[[#%x,HAS_ABS_PERSONALITY_1]] <_has_abs_personality_1>
91 # CHECK: callq 0x[[#%x,HAS_ABS_PERSONALITY_2]] <_has_abs_personality_2>
92 # CHECK: callq 0x[[#%x,HAS_EH_FRAME_1]] <_has_eh_frame_1>
93 # CHECK: callq 0x[[#%x,HAS_EH_FRAME_2]] <_has_eh_frame_2>
94 # CHECK: callq 0x[[#%x,HAS_EH_FRAME_3]] <_has_eh_frame_3>
95 # CHECK: callq 0x[[#%x,MUTALLY_RECURSIVE_2]] <_mutually_recursive_2>
96 # CHECK: callq 0x[[#%x,MUTALLY_RECURSIVE_2]] <_mutually_recursive_2>
97 ## FIXME Mutually-recursive functions with identical bodies (see below)
98 # COM: callq 0x[[#%x,ASYMMETRIC_RECURSIVE_2]] <_asymmetric_recursive_2>
99 # COM: callq 0x[[#%x,ASYMMETRIC_RECURSIVE_2]] <_asymmetric_recursive_2>
100 # CHECK: callq 0x[[#%x,INIT_2]] <_init_2>
101 # CHECK: callq 0x[[#%x,INIT_2]] <_init_2>
102 # CHECK: callq 0x[[#%x,INIT_3]] <_init_3>
104 ### TODO:
105 ### * Fold: funcs only differ in alignment
106 ### * No fold: func is weak? preemptible?
107 ### * Test that we hash things appropriately w/ minimal collisions
109 #--- abs.s
110 .subsections_via_symbols
112 .globl _abs1a, _abs1b, _abs2, _not_abs
113 _abs1a = 0xfac3
114 _abs1b = 0xfac3
115 _abs2 = 0xf00d
117 .data
118 .space 0xfac3
119 ## _not_abs has the same Defined::value as _abs1{a,b}
120 _not_abs:
122 #--- main.s
123 .subsections_via_symbols
124 .text
126 _abs1a_ref:
127 movabs $_abs1a, %rdx
129 _abs1b_ref:
130 movabs $_abs1b, %rdx
132 _abs1a_ref_with_addend:
133 movabs $_abs1a + 3, %rdx
135 _abs1b_ref_with_addend:
136 movabs $_abs1b + 3, %rdx
138 ## No fold: the absolute symbol value differs
139 _abs2_ref:
140 movabs $_abs2, %rdx
142 ## No fold: _not_abs has the same value as _abs1{a,b}, but is not absolute.
143 _not_abs_ref:
144 movabs $_not_abs, %rdx
146 _dylib_ref_1:
147 mov ___nan@GOTPCREL(%rip), %rax
148 callq ___isnan
150 _dylib_ref_2:
151 mov ___nan@GOTPCREL(%rip), %rax
152 callq ___isnan
154 ## No fold: referent dylib symbol differs
155 _dylib_ref_3:
156 mov ___inf@GOTPCREL(%rip), %rax
157 callq ___inf
159 ## No fold: referent dylib addend differs
160 _dylib_ref_4:
161 mov ___nan + 1@GOTPCREL(%rip), %rax
162 callq ___inf + 1
164 ## Sections with alt entries cannot be merged.
165 .alt_entry _alt
166 _with_alt_entry:
167 movq $3132, %rax
168 _alt:
171 _no_alt_entry:
172 movq $3132, %rax
175 _defined_ref_with_addend_1:
176 callq _with_alt_entry + 4
178 _defined_ref_with_addend_2:
179 callq _with_alt_entry + 4
181 # No fold: addend differs
182 _defined_ref_with_addend_3:
183 callq _with_alt_entry + 8
185 ## _recursive has the same body as its next two callers, but cannot be folded
186 ## with them.
187 _recursive:
188 callq _recursive
190 _call_recursive_1:
191 callq _recursive
193 _call_recursive_2:
194 callq _recursive
196 ## Functions of different lengths should not be folded
197 _check_length_1:
198 movq $97, %rax
200 _check_length_2:
201 movq $97, %rax
202 .space 1
204 _my_personality:
205 mov $1345, %rax
207 ## Functions with identical unwind info should be folded.
208 _has_unwind_1:
209 .cfi_startproc
210 .cfi_personality 155, _my_personality
211 .cfi_lsda 16, Lexception0
212 .cfi_def_cfa_offset 16
214 .cfi_endproc
216 _has_unwind_2:
217 .cfi_startproc
218 .cfi_personality 155, _my_personality
219 .cfi_lsda 16, Lexception1
220 .cfi_def_cfa_offset 16
222 .cfi_endproc
224 ## This function has a different cfa_offset from the first two, and therefore
225 ## should not be folded.
226 _has_unwind_3:
227 .cfi_startproc
228 .cfi_personality 155, _my_personality
229 .cfi_lsda 16, Lexception1
230 .cfi_def_cfa_offset 8
232 .cfi_endproc
234 ## This function has a different LSDA from the first two, and therefore should
235 ## not be folded.
236 _has_unwind_4:
237 .cfi_startproc
238 .cfi_personality 155, _my_personality
239 .cfi_lsda 16, Lexception2
240 .cfi_def_cfa_offset 16
242 .cfi_endproc
244 ## The next two functions should not be folded as they refer to personalities
245 ## at different absolute addresses. This verifies that we are doing the right
246 ## thing in our "data slicing hack" for compact unwind.
247 _has_abs_personality_1:
248 .cfi_startproc
249 .cfi_personality 155, _abs_personality_1
250 .cfi_def_cfa_offset 16
252 .cfi_endproc
254 _has_abs_personality_2:
255 .cfi_startproc
256 .cfi_personality 155, _abs_personality_2
257 .cfi_def_cfa_offset 16
259 .cfi_endproc
261 _abs_personality_1 = 0x1
262 _abs_personality_2 = 0x2
264 ## In theory _has_eh_frame_{1, 2} can be dedup'ed, but we don't support this
265 ## yet.
266 _has_eh_frame_1:
267 .cfi_startproc
268 .cfi_def_cfa_offset 8
269 ## cfi_escape cannot be encoded in compact unwind
270 .cfi_escape 0x2e, 0x10
272 .cfi_endproc
274 _has_eh_frame_2:
275 .cfi_startproc
276 .cfi_def_cfa_offset 8
277 ## cfi_escape cannot be encoded in compact unwind
278 .cfi_escape 0x2e, 0x10
280 .cfi_endproc
282 ## The nop in this function body means that it cannot be folded with the
283 ## previous two, even though the unwind info is otherwise identical.
284 _has_eh_frame_3:
285 .cfi_startproc
286 .cfi_def_cfa_offset 8
287 ## cfi_escape cannot be encoded in compact unwind
288 .cfi_escape 0x2e, 0x10
291 .cfi_endproc
293 ## Fold: Mutually-recursive functions with symmetric bodies
294 _mutually_recursive_1:
295 callq _mutually_recursive_1 # call myself
296 callq _mutually_recursive_2 # call my twin
298 _mutually_recursive_2:
299 callq _mutually_recursive_2 # call myself
300 callq _mutually_recursive_1 # call my twin
302 ## Fold: Mutually-recursive functions with identical bodies
304 ## FIXME: This test is currently broken. Recursive call sites have no relocs
305 ## and the non-zero displacement field is already written to the section
306 ## data, while non-recursive call sites use symbol relocs and section data
307 ## contains zeros in the displacement field. Thus, ICF's equalsConstant()
308 ## finds that the section data doesn't match.
310 ## ELF folds this case properly because it emits symbol relocs for all calls,
311 ## even recursive ones.
313 _asymmetric_recursive_1:
314 callq _asymmetric_recursive_1 # call myself
315 callq _asymmetric_recursive_2 # call my twin
316 movl $3, %eax
318 _asymmetric_recursive_2:
319 callq _asymmetric_recursive_1 # call my twin
320 callq _asymmetric_recursive_2 # call myself
321 movl $3, %eax
323 _init_1:
324 movq $12938, %rax
326 ## Fold: _init_2 is in a section that gets renamed and output as __text
327 .section __TEXT,__StaticInit
328 _init_2:
329 movq $12938, %rax
331 ## No fold: _init_3 is in a different output section from _init_{1,2}
332 .section __TEXT,__foo
333 _init_3:
334 movq $12938, %rax
336 .text
337 .globl _main
338 _main:
339 callq _abs1a_ref
340 callq _abs1b_ref
341 callq _abs1a_ref_with_addend
342 callq _abs1b_ref_with_addend
343 callq _abs2_ref
344 callq _not_abs_ref
345 callq _dylib_ref_1
346 callq _dylib_ref_2
347 callq _dylib_ref_3
348 callq _dylib_ref_4
349 callq _alt
350 callq _with_alt_entry
351 callq _no_alt_entry
352 callq _defined_ref_with_addend_1
353 callq _defined_ref_with_addend_2
354 callq _defined_ref_with_addend_3
355 callq _recursive
356 callq _call_recursive_1
357 callq _call_recursive_2
358 callq _check_length_1
359 callq _check_length_2
360 callq _has_unwind_1
361 callq _has_unwind_2
362 callq _has_unwind_3
363 callq _has_unwind_4
364 callq _has_abs_personality_1
365 callq _has_abs_personality_2
366 callq _has_eh_frame_1
367 callq _has_eh_frame_2
368 callq _has_eh_frame_3
369 callq _mutually_recursive_1
370 callq _mutually_recursive_2
371 callq _asymmetric_recursive_1
372 callq _asymmetric_recursive_2
373 callq _init_1
374 callq _init_2
375 callq _init_3
377 .section __TEXT,__gcc_except_tab
378 GCC_except_table0:
379 Lexception0:
380 .byte 255
382 GCC_except_table1:
383 Lexception1:
384 .byte 255
386 GCC_except_table2:
387 Lexception2:
388 .byte 254