1; RUN: llc < %s -mtriple=aarch64-apple-ios | FileCheck %s
2; RUN: llc < %s -mtriple=aarch64-apple-ios -enable-shrink-wrap=true | FileCheck %s
3; Shrink wrapping currently does not kick in because we have a TLS CALL
4; in the entry block and it will clobber the link register.
5
6; RUN: llc < %s -mtriple=aarch64-apple-ios -O0 -fast-isel | FileCheck --check-prefix=CHECK-O0 %s
7
8%struct.S = type { i8 }
9
10@sg = internal thread_local global %struct.S zeroinitializer, align 1
11@__dso_handle = external global i8
12@__tls_guard = internal thread_local unnamed_addr global i1 false
13@sum1 = internal thread_local global i32 0, align 4
14
15declare %struct.S* @_ZN1SC1Ev(%struct.S* returned)
16declare %struct.S* @_ZN1SD1Ev(%struct.S* returned)
17declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*)
18
19define cxx_fast_tlscc nonnull %struct.S* @_ZTW2sg() nounwind {
20  %.b.i = load i1, i1* @__tls_guard, align 1
21  br i1 %.b.i, label %__tls_init.exit, label %init.i
22
23init.i:
24  store i1 true, i1* @__tls_guard, align 1
25  %call.i.i = tail call %struct.S* @_ZN1SC1Ev(%struct.S* nonnull @sg)
26  %1 = tail call i32 @_tlv_atexit(void (i8*)* nonnull bitcast (%struct.S* (%struct.S*)* @_ZN1SD1Ev to void (i8*)*), i8* nonnull getelementptr inbounds (%struct.S, %struct.S* @sg, i64 0, i32 0), i8* nonnull @__dso_handle)
27  br label %__tls_init.exit
28
29__tls_init.exit:
30  ret %struct.S* @sg
31}
32
33; CHECK-LABEL: _ZTW2sg
34; CHECK-NOT: stp d31, d30
35; CHECK-NOT: stp d29, d28
36; CHECK-NOT: stp d27, d26
37; CHECK-NOT: stp d25, d24
38; CHECK-NOT: stp d23, d22
39; CHECK-NOT: stp d21, d20
40; CHECK-NOT: stp d19, d18
41; CHECK-NOT: stp d17, d16
42; CHECK-NOT: stp d7, d6
43; CHECK-NOT: stp d5, d4
44; CHECK-NOT: stp d3, d2
45; CHECK-NOT: stp d1, d0
46; CHECK-NOT: stp x20, x19
47; FIXME: The splitting logic in the register allocator fails to split along
48;        control flow here, we used to get this right by accident before...
49; CHECK-NOTXX: stp x14, x13
50; CHECK-NOT: stp x12, x11
51; CHECK-NOT: stp x10, x9
52; CHECK-NOT: stp x8, x7
53; CHECK-NOT: stp x6, x5
54; CHECK-NOT: stp x4, x3
55; CHECK-NOT: stp x2, x1
56; CHECK: blr
57; CHECK: tbnz w{{.*}}, #0, [[BB_end:.?LBB0_[0-9]+]]
58; CHECK: blr
59; CHECK: tlv_atexit
60; CHECK: [[BB_end]]:
61; CHECK: blr
62; CHECK-NOT: ldp x2, x1
63; CHECK-NOT: ldp x4, x3
64; CHECK-NOT: ldp x6, x5
65; CHECK-NOT: ldp x8, x7
66; CHECK-NOT: ldp x10, x9
67; CHECK-NOT: ldp x12, x11
68; CHECK-NOTXX: ldp x14, x13
69; CHECK-NOT: ldp x20, x19
70; CHECK-NOT: ldp d1, d0
71; CHECK-NOT: ldp d3, d2
72; CHECK-NOT: ldp d5, d4
73; CHECK-NOT: ldp d7, d6
74; CHECK-NOT: ldp d17, d16
75; CHECK-NOT: ldp d19, d18
76; CHECK-NOT: ldp d21, d20
77; CHECK-NOT: ldp d23, d22
78; CHECK-NOT: ldp d25, d24
79; CHECK-NOT: ldp d27, d26
80; CHECK-NOT: ldp d29, d28
81; CHECK-NOT: ldp d31, d30
82
83; CHECK-O0-LABEL: _ZTW2sg
84; CHECK-O0: stp d31, d30
85; CHECK-O0: stp d29, d28
86; CHECK-O0: stp d27, d26
87; CHECK-O0: stp d25, d24
88; CHECK-O0: stp d23, d22
89; CHECK-O0: stp d21, d20
90; CHECK-O0: stp d19, d18
91; CHECK-O0: stp d17, d16
92; CHECK-O0: stp d7, d6
93; CHECK-O0: stp d5, d4
94; CHECK-O0: stp d3, d2
95; CHECK-O0: stp d1, d0
96; CHECK-O0: stp x14, x13
97; CHECK-O0: stp x12, x11
98; CHECK-O0: stp x10, x9
99; CHECK-O0: stp x8, x7
100; CHECK-O0: stp x6, x5
101; CHECK-O0: stp x4, x3
102; CHECK-O0: stp x2, x1
103; CHECK-O0: blr
104; CHECK-O0: tbnz w{{.*}}, #0, [[BB_end:.?LBB0_[0-9]+]]
105; CHECK-O0: blr
106; CHECK-O0: tlv_atexit
107; CHECK-O0: [[BB_end]]:
108; CHECK-O0: blr
109; CHECK-O0: ldp x2, x1
110; CHECK-O0: ldp x4, x3
111; CHECK-O0: ldp x6, x5
112; CHECK-O0: ldp x8, x7
113; CHECK-O0: ldp x10, x9
114; CHECK-O0: ldp x12, x11
115; CHECK-O0: ldp x14, x13
116; CHECK-O0: ldp d1, d0
117; CHECK-O0: ldp d3, d2
118; CHECK-O0: ldp d5, d4
119; CHECK-O0: ldp d7, d6
120; CHECK-O0: ldp d17, d16
121; CHECK-O0: ldp d19, d18
122; CHECK-O0: ldp d21, d20
123; CHECK-O0: ldp d23, d22
124; CHECK-O0: ldp d25, d24
125; CHECK-O0: ldp d27, d26
126; CHECK-O0: ldp d29, d28
127; CHECK-O0: ldp d31, d30
128
129; CHECK-LABEL: _ZTW4sum1
130; CHECK-NOT: stp d31, d30
131; CHECK-NOT: stp d29, d28
132; CHECK-NOT: stp d27, d26
133; CHECK-NOT: stp d25, d24
134; CHECK-NOT: stp d23, d22
135; CHECK-NOT: stp d21, d20
136; CHECK-NOT: stp d19, d18
137; CHECK-NOT: stp d17, d16
138; CHECK-NOT: stp d7, d6
139; CHECK-NOT: stp d5, d4
140; CHECK-NOT: stp d3, d2
141; CHECK-NOT: stp d1, d0
142; CHECK-NOT: stp x20, x19
143; CHECK-NOT: stp x14, x13
144; CHECK-NOT: stp x12, x11
145; CHECK-NOT: stp x10, x9
146; CHECK-NOT: stp x8, x7
147; CHECK-NOT: stp x6, x5
148; CHECK-NOT: stp x4, x3
149; CHECK-NOT: stp x2, x1
150; CHECK: blr
151
152; CHECK-O0-LABEL: _ZTW4sum1
153; CHECK-O0-NOT: vstr
154; CHECK-O0-NOT: vldr
155define cxx_fast_tlscc nonnull i32* @_ZTW4sum1() nounwind {
156  ret i32* @sum1
157}
158
159; Make sure at O0, we don't generate spilling/reloading of the CSRs.
160; CHECK-O0-LABEL: tls_test2
161; CHECK-O0-NOT: stp d31, d30
162; CHECK-O0-NOT: stp d29, d28
163; CHECK-O0-NOT: stp d27, d26
164; CHECK-O0-NOT: stp d25, d24
165; CHECK-O0-NOT: stp d23, d22
166; CHECK-O0-NOT: stp d21, d20
167; CHECK-O0-NOT: stp d19, d18
168; CHECK-O0-NOT: stp d17, d16
169; CHECK-O0-NOT: stp d7, d6
170; CHECK-O0-NOT: stp d5, d4
171; CHECK-O0-NOT: stp d3, d2
172; CHECK-O0-NOT: stp d1, d0
173; CHECK-O0-NOT: stp x20, x19
174; CHECK-O0-NOT: stp x14, x13
175; CHECK-O0-NOT: stp x12, x11
176; CHECK-O0-NOT: stp x10, x9
177; CHECK-O0-NOT: stp x8, x7
178; CHECK-O0-NOT: stp x6, x5
179; CHECK-O0-NOT: stp x4, x3
180; CHECK-O0-NOT: stp x2, x1
181; CHECK-O0: bl {{.*}}tls_helper
182; CHECK-O0-NOT: ldp x2, x1
183; CHECK-O0-NOT: ldp x4, x3
184; CHECK-O0-NOT: ldp x6, x5
185; CHECK-O0-NOT: ldp x8, x7
186; CHECK-O0-NOT: ldp x10, x9
187; CHECK-O0-NOT: ldp x12, x11
188; CHECK-O0-NOT: ldp x14, x13
189; CHECK-O0-NOT: ldp x20, x19
190; CHECK-O0-NOT: ldp d1, d0
191; CHECK-O0-NOT: ldp d3, d2
192; CHECK-O0-NOT: ldp d5, d4
193; CHECK-O0-NOT: ldp d7, d6
194; CHECK-O0-NOT: ldp d17, d16
195; CHECK-O0-NOT: ldp d19, d18
196; CHECK-O0-NOT: ldp d21, d20
197; CHECK-O0-NOT: ldp d23, d22
198; CHECK-O0-NOT: ldp d25, d24
199; CHECK-O0-NOT: ldp d27, d26
200; CHECK-O0-NOT: ldp d29, d28
201; CHECK-O0-NOT: ldp d31, d30
202; CHECK-O0: ret
203%class.C = type { i32 }
204@tC = internal thread_local global %class.C zeroinitializer, align 4
205declare cxx_fast_tlscc void @tls_helper()
206define cxx_fast_tlscc %class.C* @tls_test2() #1 {
207  call cxx_fast_tlscc void @tls_helper()
208  ret %class.C* @tC
209}
210
211; Make sure we do not allow tail call when caller and callee have different
212; calling conventions.
213declare %class.C* @_ZN1CD1Ev(%class.C* readnone returned %this)
214; CHECK-LABEL: tls_test
215; CHECK: bl __tlv_atexit
216define cxx_fast_tlscc void @__tls_test() {
217entry:
218  store i32 0, i32* getelementptr inbounds (%class.C, %class.C* @tC, i64 0, i32 0), align 4
219  %0 = tail call i32 @_tlv_atexit(void (i8*)* bitcast (%class.C* (%class.C*)* @_ZN1CD1Ev to void (i8*)*), i8* bitcast (%class.C* @tC to i8*), i8* nonnull @__dso_handle) #1
220  ret void
221}
222
223attributes #0 = { nounwind "frame-pointer"="all" }
224attributes #1 = { nounwind }
225