Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / tls-loads-control3.ll
blob82daac5a9bae344742e290d75c49d1feb129f244
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic --tls-load-hoist=true -o - %s | FileCheck %s --check-prefix=HOIST0
3 ; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic -o - %s | FileCheck %s --check-prefix=HOIST2
5 ; This test has no module flag {"tls-load-hoist", i32 0}, so use --tls-load-hoist=x
6 ; to choose the way of loading thread_local address.
8 ; This test come from compiling clang/test/CodeGen/intel/tls_loads.cpp with:
9 ; (clang tls_loads.cpp -fPIC -ftls-model=global-dynamic -O2 -S -emit-llvm)
11 $_ZTW5thl_x = comdat any
13 $_ZTW6thl_x2 = comdat any
15 @thl_x = thread_local global i32 0, align 4
16 @thl_x2 = thread_local global i32 0, align 4
17 @_ZZ2f2iE2st.0 = internal thread_local unnamed_addr global i8 0, align 4
18 @_ZZ2f2iE2st.1 = internal thread_local unnamed_addr global i32 0, align 4
20 ; For HOIST0, check call __tls_get_addr@PLT only one time for each thread_local variable.
21 ; For HOIST2, Check the default way: usually call __tls_get_addr@PLT every time when use thread_local variable.
23 ; Function Attrs: mustprogress uwtable
24 define i32 @_Z2f1i(i32 %c) local_unnamed_addr #0 {
25 ; HOIST0-LABEL: _Z2f1i:
26 ; HOIST0:       # %bb.0: # %entry
27 ; HOIST0-NEXT:    pushq %r15
28 ; HOIST0-NEXT:    .cfi_def_cfa_offset 16
29 ; HOIST0-NEXT:    pushq %r14
30 ; HOIST0-NEXT:    .cfi_def_cfa_offset 24
31 ; HOIST0-NEXT:    pushq %rbx
32 ; HOIST0-NEXT:    .cfi_def_cfa_offset 32
33 ; HOIST0-NEXT:    .cfi_offset %rbx, -32
34 ; HOIST0-NEXT:    .cfi_offset %r14, -24
35 ; HOIST0-NEXT:    .cfi_offset %r15, -16
36 ; HOIST0-NEXT:    movl %edi, %ebx
37 ; HOIST0-NEXT:    data16
38 ; HOIST0-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
39 ; HOIST0-NEXT:    data16
40 ; HOIST0-NEXT:    data16
41 ; HOIST0-NEXT:    rex64
42 ; HOIST0-NEXT:    callq __tls_get_addr@PLT
43 ; HOIST0-NEXT:    movq %rax, %r14
44 ; HOIST0-NEXT:    testl %ebx, %ebx
45 ; HOIST0-NEXT:    je .LBB0_4
46 ; HOIST0-NEXT:  # %bb.1: # %while.body.preheader
47 ; HOIST0-NEXT:    data16
48 ; HOIST0-NEXT:    leaq thl_x2@TLSGD(%rip), %rdi
49 ; HOIST0-NEXT:    data16
50 ; HOIST0-NEXT:    data16
51 ; HOIST0-NEXT:    rex64
52 ; HOIST0-NEXT:    callq __tls_get_addr@PLT
53 ; HOIST0-NEXT:    movq %rax, %r15
54 ; HOIST0-NEXT:    .p2align 4, 0x90
55 ; HOIST0-NEXT:  .LBB0_2: # %while.body
56 ; HOIST0-NEXT:    # =>This Inner Loop Header: Depth=1
57 ; HOIST0-NEXT:    movl (%r15), %edi
58 ; HOIST0-NEXT:    callq _Z6gfunc2i@PLT
59 ; HOIST0-NEXT:    addl (%r14), %eax
60 ; HOIST0-NEXT:    movl %eax, (%r14)
61 ; HOIST0-NEXT:    decl %ebx
62 ; HOIST0-NEXT:    jne .LBB0_2
63 ; HOIST0-NEXT:    jmp .LBB0_3
64 ; HOIST0-NEXT:  .LBB0_4: # %entry.while.end_crit_edge
65 ; HOIST0-NEXT:    movl (%r14), %eax
66 ; HOIST0-NEXT:  .LBB0_3: # %while.end
67 ; HOIST0-NEXT:    popq %rbx
68 ; HOIST0-NEXT:    .cfi_def_cfa_offset 24
69 ; HOIST0-NEXT:    popq %r14
70 ; HOIST0-NEXT:    .cfi_def_cfa_offset 16
71 ; HOIST0-NEXT:    popq %r15
72 ; HOIST0-NEXT:    .cfi_def_cfa_offset 8
73 ; HOIST0-NEXT:    retq
75 ; HOIST2-LABEL: _Z2f1i:
76 ; HOIST2:       # %bb.0: # %entry
77 ; HOIST2-NEXT:    pushq %rbp
78 ; HOIST2-NEXT:    .cfi_def_cfa_offset 16
79 ; HOIST2-NEXT:    pushq %rbx
80 ; HOIST2-NEXT:    .cfi_def_cfa_offset 24
81 ; HOIST2-NEXT:    pushq %rax
82 ; HOIST2-NEXT:    .cfi_def_cfa_offset 32
83 ; HOIST2-NEXT:    .cfi_offset %rbx, -24
84 ; HOIST2-NEXT:    .cfi_offset %rbp, -16
85 ; HOIST2-NEXT:    testl %edi, %edi
86 ; HOIST2-NEXT:    je .LBB0_4
87 ; HOIST2-NEXT:  # %bb.1:
88 ; HOIST2-NEXT:    movl %edi, %ebx
89 ; HOIST2-NEXT:    .p2align 4, 0x90
90 ; HOIST2-NEXT:  .LBB0_2: # %while.body
91 ; HOIST2-NEXT:    # =>This Inner Loop Header: Depth=1
92 ; HOIST2-NEXT:    data16
93 ; HOIST2-NEXT:    leaq thl_x2@TLSGD(%rip), %rdi
94 ; HOIST2-NEXT:    data16
95 ; HOIST2-NEXT:    data16
96 ; HOIST2-NEXT:    rex64
97 ; HOIST2-NEXT:    callq __tls_get_addr@PLT
98 ; HOIST2-NEXT:    movl (%rax), %edi
99 ; HOIST2-NEXT:    callq _Z6gfunc2i@PLT
100 ; HOIST2-NEXT:    movl %eax, %ebp
101 ; HOIST2-NEXT:    data16
102 ; HOIST2-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
103 ; HOIST2-NEXT:    data16
104 ; HOIST2-NEXT:    data16
105 ; HOIST2-NEXT:    rex64
106 ; HOIST2-NEXT:    callq __tls_get_addr@PLT
107 ; HOIST2-NEXT:    addl (%rax), %ebp
108 ; HOIST2-NEXT:    movl %ebp, (%rax)
109 ; HOIST2-NEXT:    decl %ebx
110 ; HOIST2-NEXT:    jne .LBB0_2
111 ; HOIST2-NEXT:    jmp .LBB0_3
112 ; HOIST2-NEXT:  .LBB0_4: # %entry.while.end_crit_edge
113 ; HOIST2-NEXT:    data16
114 ; HOIST2-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
115 ; HOIST2-NEXT:    data16
116 ; HOIST2-NEXT:    data16
117 ; HOIST2-NEXT:    rex64
118 ; HOIST2-NEXT:    callq __tls_get_addr@PLT
119 ; HOIST2-NEXT:    movl (%rax), %ebp
120 ; HOIST2-NEXT:  .LBB0_3: # %while.end
121 ; HOIST2-NEXT:    movl %ebp, %eax
122 ; HOIST2-NEXT:    addq $8, %rsp
123 ; HOIST2-NEXT:    .cfi_def_cfa_offset 24
124 ; HOIST2-NEXT:    popq %rbx
125 ; HOIST2-NEXT:    .cfi_def_cfa_offset 16
126 ; HOIST2-NEXT:    popq %rbp
127 ; HOIST2-NEXT:    .cfi_def_cfa_offset 8
128 ; HOIST2-NEXT:    retq
129 entry:
130   %tobool.not3 = icmp eq i32 %c, 0
131   br i1 %tobool.not3, label %entry.while.end_crit_edge, label %while.body
133 entry.while.end_crit_edge:                        ; preds = %entry
134   %.pre = load i32, ptr @thl_x, align 4
135   br label %while.end
137 while.body:                                       ; preds = %entry, %while.body
138   %c.addr.04 = phi i32 [ %dec, %while.body ], [ %c, %entry ]
139   %dec = add nsw i32 %c.addr.04, -1
140   %0 = load i32, ptr @thl_x2, align 4
141   %call = tail call i32 @_Z6gfunc2i(i32 %0)
142   %1 = load i32, ptr @thl_x, align 4
143   %add = add nsw i32 %1, %call
144   store i32 %add, ptr @thl_x, align 4
145   %tobool.not = icmp eq i32 %dec, 0
146   br i1 %tobool.not, label %while.end, label %while.body
148 while.end:                                        ; preds = %while.body, %entry.while.end_crit_edge
149   %2 = phi i32 [ %.pre, %entry.while.end_crit_edge ], [ %add, %while.body ]
150   ret i32 %2
153 declare i32 @_Z6gfunc2i(i32) local_unnamed_addr #1
155 ; Function Attrs: mustprogress uwtable
156 define i32 @_Z2f2i(i32 %c) local_unnamed_addr #0 {
157 ; HOIST0-LABEL: _Z2f2i:
158 ; HOIST0:       # %bb.0: # %entry
159 ; HOIST0-NEXT:    pushq %r15
160 ; HOIST0-NEXT:    .cfi_def_cfa_offset 16
161 ; HOIST0-NEXT:    pushq %r14
162 ; HOIST0-NEXT:    .cfi_def_cfa_offset 24
163 ; HOIST0-NEXT:    pushq %r12
164 ; HOIST0-NEXT:    .cfi_def_cfa_offset 32
165 ; HOIST0-NEXT:    pushq %rbx
166 ; HOIST0-NEXT:    .cfi_def_cfa_offset 40
167 ; HOIST0-NEXT:    pushq %rax
168 ; HOIST0-NEXT:    .cfi_def_cfa_offset 48
169 ; HOIST0-NEXT:    .cfi_offset %rbx, -40
170 ; HOIST0-NEXT:    .cfi_offset %r12, -32
171 ; HOIST0-NEXT:    .cfi_offset %r14, -24
172 ; HOIST0-NEXT:    .cfi_offset %r15, -16
173 ; HOIST0-NEXT:    movl %edi, %ebx
174 ; HOIST0-NEXT:    data16
175 ; HOIST0-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
176 ; HOIST0-NEXT:    data16
177 ; HOIST0-NEXT:    data16
178 ; HOIST0-NEXT:    rex64
179 ; HOIST0-NEXT:    callq __tls_get_addr@PLT
180 ; HOIST0-NEXT:    movq %rax, %r14
181 ; HOIST0-NEXT:    testl %ebx, %ebx
182 ; HOIST0-NEXT:    je .LBB1_3
183 ; HOIST0-NEXT:  # %bb.1: # %while.body.preheader
184 ; HOIST0-NEXT:    leaq _ZZ2f2iE2st.0@TLSLD(%rip), %rdi
185 ; HOIST0-NEXT:    callq __tls_get_addr@PLT
186 ; HOIST0-NEXT:    movq %rax, %rcx
187 ; HOIST0-NEXT:    leaq _ZZ2f2iE2st.0@DTPOFF(%rax), %r15
188 ; HOIST0-NEXT:    leaq _ZZ2f2iE2st.1@DTPOFF(%rax), %r12
189 ; HOIST0-NEXT:    .p2align 4, 0x90
190 ; HOIST0-NEXT:  .LBB1_2: # %while.body
191 ; HOIST0-NEXT:    # =>This Inner Loop Header: Depth=1
192 ; HOIST0-NEXT:    callq _Z5gfuncv@PLT
193 ; HOIST0-NEXT:    addl %eax, (%r14)
194 ; HOIST0-NEXT:    callq _Z5gfuncv@PLT
195 ; HOIST0-NEXT:    addb %al, (%r15)
196 ; HOIST0-NEXT:    callq _Z5gfuncv@PLT
197 ; HOIST0-NEXT:    addl %eax, (%r12)
198 ; HOIST0-NEXT:    decl %ebx
199 ; HOIST0-NEXT:    jne .LBB1_2
200 ; HOIST0-NEXT:  .LBB1_3: # %while.end
201 ; HOIST0-NEXT:    movl (%r14), %eax
202 ; HOIST0-NEXT:    addq $8, %rsp
203 ; HOIST0-NEXT:    .cfi_def_cfa_offset 40
204 ; HOIST0-NEXT:    popq %rbx
205 ; HOIST0-NEXT:    .cfi_def_cfa_offset 32
206 ; HOIST0-NEXT:    popq %r12
207 ; HOIST0-NEXT:    .cfi_def_cfa_offset 24
208 ; HOIST0-NEXT:    popq %r14
209 ; HOIST0-NEXT:    .cfi_def_cfa_offset 16
210 ; HOIST0-NEXT:    popq %r15
211 ; HOIST0-NEXT:    .cfi_def_cfa_offset 8
212 ; HOIST0-NEXT:    retq
214 ; HOIST2-LABEL: _Z2f2i:
215 ; HOIST2:       # %bb.0: # %entry
216 ; HOIST2-NEXT:    pushq %rbp
217 ; HOIST2-NEXT:    .cfi_def_cfa_offset 16
218 ; HOIST2-NEXT:    pushq %r14
219 ; HOIST2-NEXT:    .cfi_def_cfa_offset 24
220 ; HOIST2-NEXT:    pushq %rbx
221 ; HOIST2-NEXT:    .cfi_def_cfa_offset 32
222 ; HOIST2-NEXT:    .cfi_offset %rbx, -32
223 ; HOIST2-NEXT:    .cfi_offset %r14, -24
224 ; HOIST2-NEXT:    .cfi_offset %rbp, -16
225 ; HOIST2-NEXT:    testl %edi, %edi
226 ; HOIST2-NEXT:    je .LBB1_3
227 ; HOIST2-NEXT:  # %bb.1: # %while.body.preheader
228 ; HOIST2-NEXT:    movl %edi, %ebx
229 ; HOIST2-NEXT:    .p2align 4, 0x90
230 ; HOIST2-NEXT:  .LBB1_2: # %while.body
231 ; HOIST2-NEXT:    # =>This Inner Loop Header: Depth=1
232 ; HOIST2-NEXT:    callq _Z5gfuncv@PLT
233 ; HOIST2-NEXT:    movl %eax, %ebp
234 ; HOIST2-NEXT:    data16
235 ; HOIST2-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
236 ; HOIST2-NEXT:    data16
237 ; HOIST2-NEXT:    data16
238 ; HOIST2-NEXT:    rex64
239 ; HOIST2-NEXT:    callq __tls_get_addr@PLT
240 ; HOIST2-NEXT:    addl %ebp, (%rax)
241 ; HOIST2-NEXT:    callq _Z5gfuncv@PLT
242 ; HOIST2-NEXT:    movl %eax, %ebp
243 ; HOIST2-NEXT:    leaq _ZZ2f2iE2st.0@TLSLD(%rip), %rdi
244 ; HOIST2-NEXT:    callq __tls_get_addr@PLT
245 ; HOIST2-NEXT:    movq %rax, %r14
246 ; HOIST2-NEXT:    addb %bpl, _ZZ2f2iE2st.0@DTPOFF(%rax)
247 ; HOIST2-NEXT:    callq _Z5gfuncv@PLT
248 ; HOIST2-NEXT:    movl %eax, %ecx
249 ; HOIST2-NEXT:    movq %r14, %rax
250 ; HOIST2-NEXT:    addl %ecx, _ZZ2f2iE2st.1@DTPOFF(%r14)
251 ; HOIST2-NEXT:    decl %ebx
252 ; HOIST2-NEXT:    jne .LBB1_2
253 ; HOIST2-NEXT:  .LBB1_3: # %while.end
254 ; HOIST2-NEXT:    data16
255 ; HOIST2-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
256 ; HOIST2-NEXT:    data16
257 ; HOIST2-NEXT:    data16
258 ; HOIST2-NEXT:    rex64
259 ; HOIST2-NEXT:    callq __tls_get_addr@PLT
260 ; HOIST2-NEXT:    movl (%rax), %eax
261 ; HOIST2-NEXT:    popq %rbx
262 ; HOIST2-NEXT:    .cfi_def_cfa_offset 24
263 ; HOIST2-NEXT:    popq %r14
264 ; HOIST2-NEXT:    .cfi_def_cfa_offset 16
265 ; HOIST2-NEXT:    popq %rbp
266 ; HOIST2-NEXT:    .cfi_def_cfa_offset 8
267 ; HOIST2-NEXT:    retq
268 entry:
269   %tobool.not9 = icmp eq i32 %c, 0
270   br i1 %tobool.not9, label %while.end, label %while.body
272 while.body:                                       ; preds = %entry, %while.body
273   %c.addr.010 = phi i32 [ %dec, %while.body ], [ %c, %entry ]
274   %dec = add nsw i32 %c.addr.010, -1
275   %call = tail call i32 @_Z5gfuncv()
276   %0 = load i32, ptr @thl_x, align 4
277   %add = add nsw i32 %0, %call
278   store i32 %add, ptr @thl_x, align 4
279   %call1 = tail call i32 @_Z5gfuncv()
280   %1 = load i8, ptr @_ZZ2f2iE2st.0, align 4
281   %2 = trunc i32 %call1 to i8
282   %conv5 = add i8 %1, %2
283   store i8 %conv5, ptr @_ZZ2f2iE2st.0, align 4
284   %call6 = tail call i32 @_Z5gfuncv()
285   %3 = load i32, ptr @_ZZ2f2iE2st.1, align 4
286   %add7 = add nsw i32 %3, %call6
287   store i32 %add7, ptr @_ZZ2f2iE2st.1, align 4
288   %tobool.not = icmp eq i32 %dec, 0
289   br i1 %tobool.not, label %while.end, label %while.body
291 while.end:                                        ; preds = %while.body, %entry
292   %4 = load i32, ptr @thl_x, align 4
293   ret i32 %4
296 declare i32 @_Z5gfuncv() local_unnamed_addr #1
298 ; Function Attrs: mustprogress uwtable
299 define i32 @_Z2f3i(i32 %c) local_unnamed_addr #0 {
300 ; HOIST0-LABEL: _Z2f3i:
301 ; HOIST0:       # %bb.0: # %entry
302 ; HOIST0-NEXT:    pushq %rbx
303 ; HOIST0-NEXT:    .cfi_def_cfa_offset 16
304 ; HOIST0-NEXT:    .cfi_offset %rbx, -16
305 ; HOIST0-NEXT:    data16
306 ; HOIST0-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
307 ; HOIST0-NEXT:    data16
308 ; HOIST0-NEXT:    data16
309 ; HOIST0-NEXT:    rex64
310 ; HOIST0-NEXT:    callq __tls_get_addr@PLT
311 ; HOIST0-NEXT:    movq %rax, %rbx
312 ; HOIST0-NEXT:    movl (%rax), %edi
313 ; HOIST0-NEXT:    callq _Z6gfunc2i@PLT
314 ; HOIST0-NEXT:    movl (%rbx), %edi
315 ; HOIST0-NEXT:    callq _Z6gfunc2i@PLT
316 ; HOIST0-NEXT:    movl $1, %eax
317 ; HOIST0-NEXT:    popq %rbx
318 ; HOIST0-NEXT:    .cfi_def_cfa_offset 8
319 ; HOIST0-NEXT:    retq
321 ; HOIST2-LABEL: _Z2f3i:
322 ; HOIST2:       # %bb.0: # %entry
323 ; HOIST2-NEXT:    pushq %rbx
324 ; HOIST2-NEXT:    .cfi_def_cfa_offset 16
325 ; HOIST2-NEXT:    .cfi_offset %rbx, -16
326 ; HOIST2-NEXT:    data16
327 ; HOIST2-NEXT:    leaq thl_x@TLSGD(%rip), %rdi
328 ; HOIST2-NEXT:    data16
329 ; HOIST2-NEXT:    data16
330 ; HOIST2-NEXT:    rex64
331 ; HOIST2-NEXT:    callq __tls_get_addr@PLT
332 ; HOIST2-NEXT:    movq %rax, %rbx
333 ; HOIST2-NEXT:    movl (%rax), %edi
334 ; HOIST2-NEXT:    callq _Z6gfunc2i@PLT
335 ; HOIST2-NEXT:    movl (%rbx), %edi
336 ; HOIST2-NEXT:    callq _Z6gfunc2i@PLT
337 ; HOIST2-NEXT:    movl $1, %eax
338 ; HOIST2-NEXT:    popq %rbx
339 ; HOIST2-NEXT:    .cfi_def_cfa_offset 8
340 ; HOIST2-NEXT:    retq
341 entry:
342   %0 = load i32, ptr @thl_x, align 4
343   %call = tail call i32 @_Z6gfunc2i(i32 %0)
344   %1 = load i32, ptr @thl_x, align 4
345   %call1 = tail call i32 @_Z6gfunc2i(i32 %1)
346   ret i32 1
349 attributes #0 = { nounwind mustprogress uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
350 attributes #1 = { "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
351 attributes #2 = { uwtable "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
353 !llvm.module.flags = !{!0, !1, !2}
355 !0 = !{i32 1, !"wchar_size", i32 4}
356 !1 = !{i32 7, !"PIC Level", i32 2}
357 !2 = !{i32 7, !"uwtable", i32 1}