xref: /llvm-project/lld/test/MachO/icf-safe-thunks.ll (revision ed5072ee28809abf0f140ca15df549a418bb5c69)
1; NOTE: Code has been autogenerated by utils/update_test_body.py
2; REQUIRES: aarch64
3
4; RUN: rm -rf %t && split-file %s %t
5
6; RUN: llc -filetype=obj %t/a.ll -O3 -o %t/a.o -enable-machine-outliner=never -mtriple arm64-apple-macos -addrsig
7; RUN: %lld -arch arm64 -lSystem --icf=safe_thunks -dylib -o %t/a.dylib -map %t/a.map %t/a.o
8; RUN: llvm-objdump %t/a.dylib -d --macho | FileCheck %s --check-prefixes=CHECK-ARM64
9; RUN: cat %t/a.map | FileCheck %s --check-prefixes=CHECK-ARM64-MAP
10
11; CHECK-ARM64:        (__TEXT,__text) section
12; CHECK-ARM64-NEXT:   _func_unique_1:
13; CHECK-ARM64-NEXT:        mov {{.*}}, #0x1
14;
15; CHECK-ARM64:        _func_unique_2_canmerge:
16; CHECK-ARM64-NEXT:   _func_2identical_v1:
17; CHECK-ARM64-NEXT:        mov {{.*}}, #0x2
18;
19; CHECK-ARM64:        _func_3identical_v1:
20; CHECK-ARM64-NEXT:        mov {{.*}}, #0x3
21;
22; CHECK-ARM64:        _func_3identical_v1_canmerge:
23; CHECK-ARM64-NEXT:   _func_3identical_v2_canmerge:
24; CHECK-ARM64-NEXT:   _func_3identical_v3_canmerge:
25; CHECK-ARM64-NEXT:        mov {{.*}}, #0x21
26;
27; CHECK-ARM64:        _func_call_thunked_1_nomerge:
28; CHECK-ARM64-NEXT:        stp	x29
29;
30; CHECK-ARM64:        _func_call_thunked_2_nomerge:
31; CHECK-ARM64-NEXT:   _func_call_thunked_2_merge:
32; CHECK-ARM64-NEXT:        stp	x29
33;
34; CHECK-ARM64:        _call_all_funcs:
35; CHECK-ARM64-NEXT:        stp  x29
36;
37; CHECK-ARM64:        _take_func_addr:
38; CHECK-ARM64-NEXT:        adr
39;
40; CHECK-ARM64:        _func_2identical_v2:
41; CHECK-ARM64-NEXT:        b  _func_2identical_v1
42; CHECK-ARM64-NEXT:   _func_3identical_v2:
43; CHECK-ARM64-NEXT:        b  _func_3identical_v1
44; CHECK-ARM64-NEXT:   _func_3identical_v3:
45; CHECK-ARM64-NEXT:        b  _func_3identical_v1
46
47
48; CHECK-ARM64-MAP:      0x00000010 [  2] _func_unique_1
49; CHECK-ARM64-MAP-NEXT: 0x00000010 [  2] _func_2identical_v1
50; CHECK-ARM64-MAP-NEXT: 0x00000000 [  2] _func_unique_2_canmerge
51; CHECK-ARM64-MAP-NEXT: 0x00000010 [  2] _func_3identical_v1
52; CHECK-ARM64-MAP-NEXT: 0x00000010 [  2] _func_3identical_v1_canmerge
53; CHECK-ARM64-MAP-NEXT: 0x00000000 [  2] _func_3identical_v2_canmerge
54; CHECK-ARM64-MAP-NEXT: 0x00000000 [  2] _func_3identical_v3_canmerge
55; CHECK-ARM64-MAP-NEXT: 0x00000020 [  2] _func_call_thunked_1_nomerge
56; CHECK-ARM64-MAP-NEXT: 0x00000020 [  2] _func_call_thunked_2_nomerge
57; CHECK-ARM64-MAP-NEXT: 0x00000000 [  2] _func_call_thunked_2_merge
58; CHECK-ARM64-MAP-NEXT: 0x00000034 [  2] _call_all_funcs
59; CHECK-ARM64-MAP-NEXT: 0x00000050 [  2] _take_func_addr
60; CHECK-ARM64-MAP-NEXT: 0x00000004 [  2] _func_2identical_v2
61; CHECK-ARM64-MAP-NEXT: 0x00000004 [  2] _func_3identical_v2
62; CHECK-ARM64-MAP-NEXT: 0x00000004 [  2] _func_3identical_v3
63
64;--- a.cpp
65#define ATTR __attribute__((noinline)) extern "C"
66typedef unsigned long long ULL;
67
68volatile char g_val = 0;
69void *volatile g_ptr = 0;
70
71ATTR void func_unique_1() { g_val = 1; }
72
73ATTR void func_unique_2_canmerge() { g_val = 2; }
74
75ATTR void func_2identical_v1() { g_val = 2; }
76
77ATTR void func_2identical_v2() { g_val = 2; }
78
79ATTR void func_3identical_v1() { g_val = 3; }
80
81ATTR void func_3identical_v2() { g_val = 3; }
82
83ATTR void func_3identical_v3() { g_val = 3; }
84
85ATTR void func_3identical_v1_canmerge() { g_val = 33; }
86
87ATTR void func_3identical_v2_canmerge() { g_val = 33; }
88
89ATTR void func_3identical_v3_canmerge() { g_val = 33; }
90
91ATTR void func_call_thunked_1_nomerge() {
92    func_2identical_v1();
93    g_val = 77;
94}
95
96ATTR void func_call_thunked_2_nomerge() {
97    func_2identical_v2();
98    g_val = 77;
99}
100
101ATTR void func_call_thunked_2_merge() {
102    func_2identical_v2();
103    g_val = 77;
104}
105
106ATTR void call_all_funcs() {
107    func_unique_1();
108    func_unique_2_canmerge();
109    func_2identical_v1();
110    func_2identical_v2();
111    func_3identical_v1();
112    func_3identical_v2();
113    func_3identical_v3();
114    func_3identical_v1_canmerge();
115    func_3identical_v2_canmerge();
116    func_3identical_v3_canmerge();
117}
118
119ATTR void take_func_addr() {
120    g_ptr = (void*)func_unique_1;
121    g_ptr = (void*)func_2identical_v1;
122    g_ptr = (void*)func_2identical_v2;
123    g_ptr = (void*)func_3identical_v1;
124    g_ptr = (void*)func_3identical_v2;
125    g_ptr = (void*)func_3identical_v3;
126}
127
128;--- gen
129clang -target arm64-apple-macos11.0 -S -emit-llvm a.cpp -O3 -o -
130
131;--- a.ll
132; ModuleID = 'a.cpp'
133source_filename = "a.cpp"
134target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
135target triple = "arm64-apple-macosx11.0.0"
136
137@g_val = global i8 0, align 1
138@g_ptr = global ptr null, align 8
139
140; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
141define void @func_unique_1() #0 {
142  store volatile i8 1, ptr @g_val, align 1, !tbaa !4
143  ret void
144}
145
146; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
147define void @func_unique_2_canmerge() local_unnamed_addr #0 {
148  store volatile i8 2, ptr @g_val, align 1, !tbaa !4
149  ret void
150}
151
152; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
153define void @func_2identical_v1() #0 {
154  store volatile i8 2, ptr @g_val, align 1, !tbaa !4
155  ret void
156}
157
158; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
159define void @func_2identical_v2() #0 {
160  store volatile i8 2, ptr @g_val, align 1, !tbaa !4
161  ret void
162}
163
164; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
165define void @func_3identical_v1() #0 {
166  store volatile i8 3, ptr @g_val, align 1, !tbaa !4
167  ret void
168}
169
170; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
171define void @func_3identical_v2() #0 {
172  store volatile i8 3, ptr @g_val, align 1, !tbaa !4
173  ret void
174}
175
176; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
177define void @func_3identical_v3() #0 {
178  store volatile i8 3, ptr @g_val, align 1, !tbaa !4
179  ret void
180}
181
182; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
183define void @func_3identical_v1_canmerge() local_unnamed_addr #0 {
184  store volatile i8 33, ptr @g_val, align 1, !tbaa !4
185  ret void
186}
187
188; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
189define void @func_3identical_v2_canmerge() local_unnamed_addr #0 {
190  store volatile i8 33, ptr @g_val, align 1, !tbaa !4
191  ret void
192}
193
194; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
195define void @func_3identical_v3_canmerge() local_unnamed_addr #0 {
196  store volatile i8 33, ptr @g_val, align 1, !tbaa !4
197  ret void
198}
199
200; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync)
201define void @func_call_thunked_1_nomerge() local_unnamed_addr #1 {
202  tail call void @func_2identical_v1()
203  store volatile i8 77, ptr @g_val, align 1, !tbaa !4
204  ret void
205}
206
207; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync)
208define void @func_call_thunked_2_nomerge() local_unnamed_addr #1 {
209  tail call void @func_2identical_v2()
210  store volatile i8 77, ptr @g_val, align 1, !tbaa !4
211  ret void
212}
213
214; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync)
215define void @func_call_thunked_2_merge() local_unnamed_addr #1 {
216  tail call void @func_2identical_v2()
217  store volatile i8 77, ptr @g_val, align 1, !tbaa !4
218  ret void
219}
220
221; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync)
222define void @call_all_funcs() local_unnamed_addr #1 {
223  tail call void @func_unique_1()
224  tail call void @func_unique_2_canmerge()
225  tail call void @func_2identical_v1()
226  tail call void @func_2identical_v2()
227  tail call void @func_3identical_v1()
228  tail call void @func_3identical_v2()
229  tail call void @func_3identical_v3()
230  tail call void @func_3identical_v1_canmerge()
231  tail call void @func_3identical_v2_canmerge()
232  tail call void @func_3identical_v3_canmerge()
233  ret void
234}
235
236; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
237define void @take_func_addr() local_unnamed_addr #0 {
238  store volatile ptr @func_unique_1, ptr @g_ptr, align 8, !tbaa !7
239  store volatile ptr @func_2identical_v1, ptr @g_ptr, align 8, !tbaa !7
240  store volatile ptr @func_2identical_v2, ptr @g_ptr, align 8, !tbaa !7
241  store volatile ptr @func_3identical_v1, ptr @g_ptr, align 8, !tbaa !7
242  store volatile ptr @func_3identical_v2, ptr @g_ptr, align 8, !tbaa !7
243  store volatile ptr @func_3identical_v3, ptr @g_ptr, align 8, !tbaa !7
244  ret void
245}
246
247attributes #0 = { mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" }
248attributes #1 = { mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" }
249
250!llvm.module.flags = !{!0, !1, !2, !3}
251
252!0 = !{i32 1, !"wchar_size", i32 4}
253!1 = !{i32 8, !"PIC Level", i32 2}
254!2 = !{i32 7, !"uwtable", i32 1}
255!3 = !{i32 7, !"frame-pointer", i32 1}
256!4 = !{!5, !5, i64 0}
257!5 = !{!"omnipotent char", !6, i64 0}
258!6 = !{!"Simple C++ TBAA"}
259!7 = !{!8, !8, i64 0}
260!8 = !{!"any pointer", !5, i64 0}
261