Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / x86-shrink-wrapping.ll
blobfab3847b3a2c51256f0e28e896b0b0d41e886f46
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc %s -o - -enable-shrink-wrap=true -pass-remarks-output=%t -disable-cgp-delete-phis | FileCheck %s --check-prefix=ENABLE
3 ; RUN: cat %t | FileCheck %s --check-prefix=REMARKS
4 ; RUN: llc %s -o - -enable-shrink-wrap=false -disable-cgp-delete-phis | FileCheck %s --check-prefix=DISABLE
6 ; Note: Lots of tests use inline asm instead of regular calls.
7 ; This allows to have a better control on what the allocation will do.
8 ; Otherwise, we may have spill right in the entry block, defeating
9 ; shrink-wrapping. Moreover, some of the inline asm statement (nop)
10 ; are here to ensure that the related paths do not end up as critical
11 ; edges.
12 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
13 target triple = "x86_64-apple-macosx"
16 ; Initial motivating example: Simple diamond with a call just on one side.
17 define i32 @foo(i32 %a, i32 %b) {
18 ; ENABLE-LABEL: foo:
19 ; ENABLE:       ## %bb.0:
20 ; ENABLE-NEXT:    movl %edi, %eax
21 ; ENABLE-NEXT:    cmpl %esi, %edi
22 ; ENABLE-NEXT:    jge LBB0_2
23 ; ENABLE-NEXT:  ## %bb.1: ## %true
24 ; ENABLE-NEXT:    pushq %rax
25 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
26 ; ENABLE-NEXT:    movl %eax, {{[0-9]+}}(%rsp)
27 ; ENABLE-NEXT:    leaq {{[0-9]+}}(%rsp), %rsi
28 ; ENABLE-NEXT:    xorl %edi, %edi
29 ; ENABLE-NEXT:    callq _doSomething
30 ; ENABLE-NEXT:    addq $8, %rsp
31 ; ENABLE-NEXT:  LBB0_2: ## %false
32 ; ENABLE-NEXT:    retq
34 ; DISABLE-LABEL: foo:
35 ; DISABLE:       ## %bb.0:
36 ; DISABLE-NEXT:    pushq %rax
37 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
38 ; DISABLE-NEXT:    movl %edi, %eax
39 ; DISABLE-NEXT:    cmpl %esi, %edi
40 ; DISABLE-NEXT:    jge LBB0_2
41 ; DISABLE-NEXT:  ## %bb.1: ## %true
42 ; DISABLE-NEXT:    movl %eax, {{[0-9]+}}(%rsp)
43 ; DISABLE-NEXT:    leaq {{[0-9]+}}(%rsp), %rsi
44 ; DISABLE-NEXT:    xorl %edi, %edi
45 ; DISABLE-NEXT:    callq _doSomething
46 ; DISABLE-NEXT:  LBB0_2: ## %false
47 ; DISABLE-NEXT:    popq %rcx
48 ; DISABLE-NEXT:    retq
49   %tmp = alloca i32, align 4
50   %tmp2 = icmp slt i32 %a, %b
51   br i1 %tmp2, label %true, label %false
53 true:
54   store i32 %a, ptr %tmp, align 4
55   %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
56   br label %false
58 false:
59   %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
60   ret i32 %tmp.0
63 ; Function Attrs: optsize
64 declare i32 @doSomething(i32, ptr)
67 ; Check that we do not perform the restore inside the loop whereas the save
68 ; is outside.
69 define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) {
70 ; ENABLE-LABEL: freqSaveAndRestoreOutsideLoop:
71 ; ENABLE:       ## %bb.0: ## %entry
72 ; ENABLE-NEXT:    testl %edi, %edi
73 ; ENABLE-NEXT:    je LBB1_4
74 ; ENABLE-NEXT:  ## %bb.1: ## %for.preheader
75 ; ENABLE-NEXT:    pushq %rbx
76 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
77 ; ENABLE-NEXT:    .cfi_offset %rbx, -16
78 ; ENABLE-NEXT:    ## InlineAsm Start
79 ; ENABLE-NEXT:    nop
80 ; ENABLE-NEXT:    ## InlineAsm End
81 ; ENABLE-NEXT:    xorl %eax, %eax
82 ; ENABLE-NEXT:    movl $10, %ecx
83 ; ENABLE-NEXT:    .p2align 4, 0x90
84 ; ENABLE-NEXT:  LBB1_2: ## %for.body
85 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
86 ; ENABLE-NEXT:    ## InlineAsm Start
87 ; ENABLE-NEXT:    movl $1, %edx
88 ; ENABLE-NEXT:    ## InlineAsm End
89 ; ENABLE-NEXT:    addl %edx, %eax
90 ; ENABLE-NEXT:    decl %ecx
91 ; ENABLE-NEXT:    jne LBB1_2
92 ; ENABLE-NEXT:  ## %bb.3: ## %for.end
93 ; ENABLE-NEXT:    shll $3, %eax
94 ; ENABLE-NEXT:    popq %rbx
95 ; ENABLE-NEXT:    retq
96 ; ENABLE-NEXT:  LBB1_4: ## %if.else
97 ; ENABLE-NEXT:    movl %esi, %eax
98 ; ENABLE-NEXT:    addl %esi, %eax
99 ; ENABLE-NEXT:    retq
101 ; DISABLE-LABEL: freqSaveAndRestoreOutsideLoop:
102 ; DISABLE:       ## %bb.0: ## %entry
103 ; DISABLE-NEXT:    pushq %rbx
104 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
105 ; DISABLE-NEXT:    .cfi_offset %rbx, -16
106 ; DISABLE-NEXT:    testl %edi, %edi
107 ; DISABLE-NEXT:    je LBB1_4
108 ; DISABLE-NEXT:  ## %bb.1: ## %for.preheader
109 ; DISABLE-NEXT:    ## InlineAsm Start
110 ; DISABLE-NEXT:    nop
111 ; DISABLE-NEXT:    ## InlineAsm End
112 ; DISABLE-NEXT:    xorl %eax, %eax
113 ; DISABLE-NEXT:    movl $10, %ecx
114 ; DISABLE-NEXT:    .p2align 4, 0x90
115 ; DISABLE-NEXT:  LBB1_2: ## %for.body
116 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
117 ; DISABLE-NEXT:    ## InlineAsm Start
118 ; DISABLE-NEXT:    movl $1, %edx
119 ; DISABLE-NEXT:    ## InlineAsm End
120 ; DISABLE-NEXT:    addl %edx, %eax
121 ; DISABLE-NEXT:    decl %ecx
122 ; DISABLE-NEXT:    jne LBB1_2
123 ; DISABLE-NEXT:  ## %bb.3: ## %for.end
124 ; DISABLE-NEXT:    shll $3, %eax
125 ; DISABLE-NEXT:    popq %rbx
126 ; DISABLE-NEXT:    retq
127 ; DISABLE-NEXT:  LBB1_4: ## %if.else
128 ; DISABLE-NEXT:    movl %esi, %eax
129 ; DISABLE-NEXT:    addl %esi, %eax
130 ; DISABLE-NEXT:    popq %rbx
131 ; DISABLE-NEXT:    retq
132 entry:
133   %tobool = icmp eq i32 %cond, 0
134   br i1 %tobool, label %if.else, label %for.preheader
136 for.preheader:
137   tail call void asm "nop", ""()
138   br label %for.body
140 for.body:                                         ; preds = %entry, %for.body
141   %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
142   %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
143   %call = tail call i32 asm sideeffect "movl $$1, $0", "=r,~{ebx}"()
144   %add = add nsw i32 %call, %sum.04
145   %inc = add nuw nsw i32 %i.05, 1
146   %exitcond = icmp eq i32 %inc, 10
147   br i1 %exitcond, label %for.end, label %for.body
149 for.end:                                          ; preds = %for.body
150   %shl = shl i32 %add, 3
151   br label %if.end
153 if.else:                                          ; preds = %entry
154   %mul = shl nsw i32 %N, 1
155   br label %if.end
157 if.end:                                           ; preds = %if.else, %for.end
158   %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
159   ret i32 %sum.1
162 declare i32 @something(...)
164 ; Check that we do not perform the shrink-wrapping inside the loop even
165 ; though that would be legal. The cost model must prevent that.
166 define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) {
167 ; ENABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
168 ; ENABLE:       ## %bb.0: ## %entry
169 ; ENABLE-NEXT:    pushq %rbx
170 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
171 ; ENABLE-NEXT:    .cfi_offset %rbx, -16
172 ; ENABLE-NEXT:    ## InlineAsm Start
173 ; ENABLE-NEXT:    nop
174 ; ENABLE-NEXT:    ## InlineAsm End
175 ; ENABLE-NEXT:    xorl %eax, %eax
176 ; ENABLE-NEXT:    movl $10, %ecx
177 ; ENABLE-NEXT:    .p2align 4, 0x90
178 ; ENABLE-NEXT:  LBB2_1: ## %for.body
179 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
180 ; ENABLE-NEXT:    ## InlineAsm Start
181 ; ENABLE-NEXT:    movl $1, %edx
182 ; ENABLE-NEXT:    ## InlineAsm End
183 ; ENABLE-NEXT:    addl %edx, %eax
184 ; ENABLE-NEXT:    decl %ecx
185 ; ENABLE-NEXT:    jne LBB2_1
186 ; ENABLE-NEXT:  ## %bb.2: ## %for.exit
187 ; ENABLE-NEXT:    ## InlineAsm Start
188 ; ENABLE-NEXT:    nop
189 ; ENABLE-NEXT:    ## InlineAsm End
190 ; ENABLE-NEXT:    popq %rbx
191 ; ENABLE-NEXT:    retq
193 ; DISABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
194 ; DISABLE:       ## %bb.0: ## %entry
195 ; DISABLE-NEXT:    pushq %rbx
196 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
197 ; DISABLE-NEXT:    .cfi_offset %rbx, -16
198 ; DISABLE-NEXT:    ## InlineAsm Start
199 ; DISABLE-NEXT:    nop
200 ; DISABLE-NEXT:    ## InlineAsm End
201 ; DISABLE-NEXT:    xorl %eax, %eax
202 ; DISABLE-NEXT:    movl $10, %ecx
203 ; DISABLE-NEXT:    .p2align 4, 0x90
204 ; DISABLE-NEXT:  LBB2_1: ## %for.body
205 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
206 ; DISABLE-NEXT:    ## InlineAsm Start
207 ; DISABLE-NEXT:    movl $1, %edx
208 ; DISABLE-NEXT:    ## InlineAsm End
209 ; DISABLE-NEXT:    addl %edx, %eax
210 ; DISABLE-NEXT:    decl %ecx
211 ; DISABLE-NEXT:    jne LBB2_1
212 ; DISABLE-NEXT:  ## %bb.2: ## %for.exit
213 ; DISABLE-NEXT:    ## InlineAsm Start
214 ; DISABLE-NEXT:    nop
215 ; DISABLE-NEXT:    ## InlineAsm End
216 ; DISABLE-NEXT:    popq %rbx
217 ; DISABLE-NEXT:    retq
218 entry:
219   br label %for.preheader
221 for.preheader:
222   tail call void asm "nop", ""()
223   br label %for.body
225 for.body:                                         ; preds = %for.body, %entry
226   %i.04 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]
227   %sum.03 = phi i32 [ 0, %for.preheader ], [ %add, %for.body ]
228   %call = tail call i32 asm sideeffect "movl $$1, $0", "=r,~{ebx}"()
229   %add = add nsw i32 %call, %sum.03
230   %inc = add nuw nsw i32 %i.04, 1
231   %exitcond = icmp eq i32 %inc, 10
232   br i1 %exitcond, label %for.exit, label %for.body
234 for.exit:
235   tail call void asm "nop", ""()
236   br label %for.end
238 for.end:                                          ; preds = %for.body
239   ret i32 %add
242 ; Check with a more complex case that we do not have save within the loop and
243 ; restore outside.
244 define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) {
245 ; ENABLE-LABEL: loopInfoSaveOutsideLoop:
246 ; ENABLE:       ## %bb.0: ## %entry
247 ; ENABLE-NEXT:    testl %edi, %edi
248 ; ENABLE-NEXT:    je LBB3_4
249 ; ENABLE-NEXT:  ## %bb.1: ## %for.preheader
250 ; ENABLE-NEXT:    pushq %rbx
251 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
252 ; ENABLE-NEXT:    .cfi_offset %rbx, -16
253 ; ENABLE-NEXT:    ## InlineAsm Start
254 ; ENABLE-NEXT:    nop
255 ; ENABLE-NEXT:    ## InlineAsm End
256 ; ENABLE-NEXT:    xorl %eax, %eax
257 ; ENABLE-NEXT:    movl $10, %ecx
258 ; ENABLE-NEXT:    .p2align 4, 0x90
259 ; ENABLE-NEXT:  LBB3_2: ## %for.body
260 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
261 ; ENABLE-NEXT:    ## InlineAsm Start
262 ; ENABLE-NEXT:    movl $1, %edx
263 ; ENABLE-NEXT:    ## InlineAsm End
264 ; ENABLE-NEXT:    addl %edx, %eax
265 ; ENABLE-NEXT:    decl %ecx
266 ; ENABLE-NEXT:    jne LBB3_2
267 ; ENABLE-NEXT:  ## %bb.3: ## %for.end
268 ; ENABLE-NEXT:    ## InlineAsm Start
269 ; ENABLE-NEXT:    nop
270 ; ENABLE-NEXT:    ## InlineAsm End
271 ; ENABLE-NEXT:    shll $3, %eax
272 ; ENABLE-NEXT:    popq %rbx
273 ; ENABLE-NEXT:    retq
274 ; ENABLE-NEXT:  LBB3_4: ## %if.else
275 ; ENABLE-NEXT:    movl %esi, %eax
276 ; ENABLE-NEXT:    addl %esi, %eax
277 ; ENABLE-NEXT:    retq
279 ; DISABLE-LABEL: loopInfoSaveOutsideLoop:
280 ; DISABLE:       ## %bb.0: ## %entry
281 ; DISABLE-NEXT:    pushq %rbx
282 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
283 ; DISABLE-NEXT:    .cfi_offset %rbx, -16
284 ; DISABLE-NEXT:    testl %edi, %edi
285 ; DISABLE-NEXT:    je LBB3_4
286 ; DISABLE-NEXT:  ## %bb.1: ## %for.preheader
287 ; DISABLE-NEXT:    ## InlineAsm Start
288 ; DISABLE-NEXT:    nop
289 ; DISABLE-NEXT:    ## InlineAsm End
290 ; DISABLE-NEXT:    xorl %eax, %eax
291 ; DISABLE-NEXT:    movl $10, %ecx
292 ; DISABLE-NEXT:    .p2align 4, 0x90
293 ; DISABLE-NEXT:  LBB3_2: ## %for.body
294 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
295 ; DISABLE-NEXT:    ## InlineAsm Start
296 ; DISABLE-NEXT:    movl $1, %edx
297 ; DISABLE-NEXT:    ## InlineAsm End
298 ; DISABLE-NEXT:    addl %edx, %eax
299 ; DISABLE-NEXT:    decl %ecx
300 ; DISABLE-NEXT:    jne LBB3_2
301 ; DISABLE-NEXT:  ## %bb.3: ## %for.end
302 ; DISABLE-NEXT:    ## InlineAsm Start
303 ; DISABLE-NEXT:    nop
304 ; DISABLE-NEXT:    ## InlineAsm End
305 ; DISABLE-NEXT:    shll $3, %eax
306 ; DISABLE-NEXT:    popq %rbx
307 ; DISABLE-NEXT:    retq
308 ; DISABLE-NEXT:  LBB3_4: ## %if.else
309 ; DISABLE-NEXT:    movl %esi, %eax
310 ; DISABLE-NEXT:    addl %esi, %eax
311 ; DISABLE-NEXT:    popq %rbx
312 ; DISABLE-NEXT:    retq
313 entry:
314   %tobool = icmp eq i32 %cond, 0
315   br i1 %tobool, label %if.else, label %for.preheader
317 for.preheader:
318   tail call void asm "nop", ""()
319   br label %for.body
321 for.body:                                         ; preds = %entry, %for.body
322   %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
323   %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
324   %call = tail call i32 asm sideeffect "movl $$1, $0", "=r,~{ebx}"()
325   %add = add nsw i32 %call, %sum.04
326   %inc = add nuw nsw i32 %i.05, 1
327   %exitcond = icmp eq i32 %inc, 10
328   br i1 %exitcond, label %for.end, label %for.body
330 for.end:                                          ; preds = %for.body
331   tail call void asm "nop", "~{ebx}"()
332   %shl = shl i32 %add, 3
333   br label %if.end
335 if.else:                                          ; preds = %entry
336   %mul = shl nsw i32 %N, 1
337   br label %if.end
339 if.end:                                           ; preds = %if.else, %for.end
340   %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
341   ret i32 %sum.1
344 ; Check with a more complex case that we do not have restore within the loop and
345 ; save outside.
346 define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind {
347 ; ENABLE-LABEL: loopInfoRestoreOutsideLoop:
348 ; ENABLE:       ## %bb.0: ## %entry
349 ; ENABLE-NEXT:    testl %edi, %edi
350 ; ENABLE-NEXT:    je LBB4_4
351 ; ENABLE-NEXT:  ## %bb.1: ## %if.then
352 ; ENABLE-NEXT:    pushq %rbx
353 ; ENABLE-NEXT:    ## InlineAsm Start
354 ; ENABLE-NEXT:    nop
355 ; ENABLE-NEXT:    ## InlineAsm End
356 ; ENABLE-NEXT:    xorl %eax, %eax
357 ; ENABLE-NEXT:    movl $10, %ecx
358 ; ENABLE-NEXT:    .p2align 4, 0x90
359 ; ENABLE-NEXT:  LBB4_2: ## %for.body
360 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
361 ; ENABLE-NEXT:    ## InlineAsm Start
362 ; ENABLE-NEXT:    movl $1, %edx
363 ; ENABLE-NEXT:    ## InlineAsm End
364 ; ENABLE-NEXT:    addl %edx, %eax
365 ; ENABLE-NEXT:    decl %ecx
366 ; ENABLE-NEXT:    jne LBB4_2
367 ; ENABLE-NEXT:  ## %bb.3: ## %for.end
368 ; ENABLE-NEXT:    shll $3, %eax
369 ; ENABLE-NEXT:    popq %rbx
370 ; ENABLE-NEXT:    retq
371 ; ENABLE-NEXT:  LBB4_4: ## %if.else
372 ; ENABLE-NEXT:    movl %esi, %eax
373 ; ENABLE-NEXT:    addl %esi, %eax
374 ; ENABLE-NEXT:    retq
376 ; DISABLE-LABEL: loopInfoRestoreOutsideLoop:
377 ; DISABLE:       ## %bb.0: ## %entry
378 ; DISABLE-NEXT:    pushq %rbx
379 ; DISABLE-NEXT:    testl %edi, %edi
380 ; DISABLE-NEXT:    je LBB4_4
381 ; DISABLE-NEXT:  ## %bb.1: ## %if.then
382 ; DISABLE-NEXT:    ## InlineAsm Start
383 ; DISABLE-NEXT:    nop
384 ; DISABLE-NEXT:    ## InlineAsm End
385 ; DISABLE-NEXT:    xorl %eax, %eax
386 ; DISABLE-NEXT:    movl $10, %ecx
387 ; DISABLE-NEXT:    .p2align 4, 0x90
388 ; DISABLE-NEXT:  LBB4_2: ## %for.body
389 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
390 ; DISABLE-NEXT:    ## InlineAsm Start
391 ; DISABLE-NEXT:    movl $1, %edx
392 ; DISABLE-NEXT:    ## InlineAsm End
393 ; DISABLE-NEXT:    addl %edx, %eax
394 ; DISABLE-NEXT:    decl %ecx
395 ; DISABLE-NEXT:    jne LBB4_2
396 ; DISABLE-NEXT:  ## %bb.3: ## %for.end
397 ; DISABLE-NEXT:    shll $3, %eax
398 ; DISABLE-NEXT:    popq %rbx
399 ; DISABLE-NEXT:    retq
400 ; DISABLE-NEXT:  LBB4_4: ## %if.else
401 ; DISABLE-NEXT:    movl %esi, %eax
402 ; DISABLE-NEXT:    addl %esi, %eax
403 ; DISABLE-NEXT:    popq %rbx
404 ; DISABLE-NEXT:    retq
405 entry:
406   %tobool = icmp eq i32 %cond, 0
407   br i1 %tobool, label %if.else, label %if.then
409 if.then:                                          ; preds = %entry
410   tail call void asm "nop", "~{ebx}"()
411   br label %for.body
413 for.body:                                         ; preds = %for.body, %if.then
414   %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ]
415   %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
416   %call = tail call i32 asm sideeffect "movl $$1, $0", "=r,~{ebx}"()
417   %add = add nsw i32 %call, %sum.04
418   %inc = add nuw nsw i32 %i.05, 1
419   %exitcond = icmp eq i32 %inc, 10
420   br i1 %exitcond, label %for.end, label %for.body
422 for.end:                                          ; preds = %for.body
423   %shl = shl i32 %add, 3
424   br label %if.end
426 if.else:                                          ; preds = %entry
427   %mul = shl nsw i32 %N, 1
428   br label %if.end
430 if.end:                                           ; preds = %if.else, %for.end
431   %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
432   ret i32 %sum.1
435 ; Check that we handle function with no frame information correctly.
436 define i32 @emptyFrame() {
437 ; ENABLE-LABEL: emptyFrame:
438 ; ENABLE:       ## %bb.0: ## %entry
439 ; ENABLE-NEXT:    xorl %eax, %eax
440 ; ENABLE-NEXT:    retq
442 ; DISABLE-LABEL: emptyFrame:
443 ; DISABLE:       ## %bb.0: ## %entry
444 ; DISABLE-NEXT:    xorl %eax, %eax
445 ; DISABLE-NEXT:    retq
446 entry:
447   ret i32 0
450 ; Check that we handle inline asm correctly.
451 define i32 @inlineAsm(i32 %cond, i32 %N) {
452 ; ENABLE-LABEL: inlineAsm:
453 ; ENABLE:       ## %bb.0: ## %entry
454 ; ENABLE-NEXT:    testl %edi, %edi
455 ; ENABLE-NEXT:    je LBB6_4
456 ; ENABLE-NEXT:  ## %bb.1: ## %for.preheader
457 ; ENABLE-NEXT:    pushq %rbx
458 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
459 ; ENABLE-NEXT:    .cfi_offset %rbx, -16
460 ; ENABLE-NEXT:    ## InlineAsm Start
461 ; ENABLE-NEXT:    nop
462 ; ENABLE-NEXT:    ## InlineAsm End
463 ; ENABLE-NEXT:    movl $10, %eax
464 ; ENABLE-NEXT:    .p2align 4, 0x90
465 ; ENABLE-NEXT:  LBB6_2: ## %for.body
466 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
467 ; ENABLE-NEXT:    ## InlineAsm Start
468 ; ENABLE-NEXT:    addl $1, %ebx
469 ; ENABLE-NEXT:    ## InlineAsm End
470 ; ENABLE-NEXT:    decl %eax
471 ; ENABLE-NEXT:    jne LBB6_2
472 ; ENABLE-NEXT:  ## %bb.3: ## %for.exit
473 ; ENABLE-NEXT:    ## InlineAsm Start
474 ; ENABLE-NEXT:    nop
475 ; ENABLE-NEXT:    ## InlineAsm End
476 ; ENABLE-NEXT:    xorl %eax, %eax
477 ; ENABLE-NEXT:    popq %rbx
478 ; ENABLE-NEXT:    retq
479 ; ENABLE-NEXT:  LBB6_4: ## %if.else
480 ; ENABLE-NEXT:    movl %esi, %eax
481 ; ENABLE-NEXT:    addl %esi, %eax
482 ; ENABLE-NEXT:    retq
484 ; DISABLE-LABEL: inlineAsm:
485 ; DISABLE:       ## %bb.0: ## %entry
486 ; DISABLE-NEXT:    pushq %rbx
487 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
488 ; DISABLE-NEXT:    .cfi_offset %rbx, -16
489 ; DISABLE-NEXT:    testl %edi, %edi
490 ; DISABLE-NEXT:    je LBB6_4
491 ; DISABLE-NEXT:  ## %bb.1: ## %for.preheader
492 ; DISABLE-NEXT:    ## InlineAsm Start
493 ; DISABLE-NEXT:    nop
494 ; DISABLE-NEXT:    ## InlineAsm End
495 ; DISABLE-NEXT:    movl $10, %eax
496 ; DISABLE-NEXT:    .p2align 4, 0x90
497 ; DISABLE-NEXT:  LBB6_2: ## %for.body
498 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
499 ; DISABLE-NEXT:    ## InlineAsm Start
500 ; DISABLE-NEXT:    addl $1, %ebx
501 ; DISABLE-NEXT:    ## InlineAsm End
502 ; DISABLE-NEXT:    decl %eax
503 ; DISABLE-NEXT:    jne LBB6_2
504 ; DISABLE-NEXT:  ## %bb.3: ## %for.exit
505 ; DISABLE-NEXT:    ## InlineAsm Start
506 ; DISABLE-NEXT:    nop
507 ; DISABLE-NEXT:    ## InlineAsm End
508 ; DISABLE-NEXT:    xorl %eax, %eax
509 ; DISABLE-NEXT:    popq %rbx
510 ; DISABLE-NEXT:    retq
511 ; DISABLE-NEXT:  LBB6_4: ## %if.else
512 ; DISABLE-NEXT:    movl %esi, %eax
513 ; DISABLE-NEXT:    addl %esi, %eax
514 ; DISABLE-NEXT:    popq %rbx
515 ; DISABLE-NEXT:    retq
516 entry:
517   %tobool = icmp eq i32 %cond, 0
518   br i1 %tobool, label %if.else, label %for.preheader
520 for.preheader:
521   tail call void asm "nop", ""()
522   br label %for.body
524 for.body:                                         ; preds = %entry, %for.body
525   %i.03 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
526   tail call void asm "addl $$1, %ebx", "~{ebx}"()
527   %inc = add nuw nsw i32 %i.03, 1
528   %exitcond = icmp eq i32 %inc, 10
529   br i1 %exitcond, label %for.exit, label %for.body
531 for.exit:
532   tail call void asm "nop", ""()
533   br label %if.end
535 if.else:                                          ; preds = %entry
536   %mul = shl nsw i32 %N, 1
537   br label %if.end
539 if.end:                                           ; preds = %for.body, %if.else
540   %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ]
541   ret i32 %sum.0
544 ; Check that we handle calls to variadic functions correctly.
545 define i32 @callVariadicFunc(i32 %cond, i32 %N) {
546 ; ENABLE-LABEL: callVariadicFunc:
547 ; ENABLE:       ## %bb.0: ## %entry
548 ; ENABLE-NEXT:    movl %esi, %eax
549 ; ENABLE-NEXT:    testl %edi, %edi
550 ; ENABLE-NEXT:    je LBB7_2
551 ; ENABLE-NEXT:  ## %bb.1: ## %if.then
552 ; ENABLE-NEXT:    pushq %rax
553 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
554 ; ENABLE-NEXT:    movl %eax, (%rsp)
555 ; ENABLE-NEXT:    movl %eax, %edi
556 ; ENABLE-NEXT:    movl %eax, %esi
557 ; ENABLE-NEXT:    movl %eax, %edx
558 ; ENABLE-NEXT:    movl %eax, %ecx
559 ; ENABLE-NEXT:    movl %eax, %r8d
560 ; ENABLE-NEXT:    movl %eax, %r9d
561 ; ENABLE-NEXT:    xorl %eax, %eax
562 ; ENABLE-NEXT:    callq _someVariadicFunc
563 ; ENABLE-NEXT:    shll $3, %eax
564 ; ENABLE-NEXT:    addq $8, %rsp
565 ; ENABLE-NEXT:    retq
566 ; ENABLE-NEXT:  LBB7_2: ## %if.else
567 ; ENABLE-NEXT:    addl %eax, %eax
568 ; ENABLE-NEXT:    retq
570 ; DISABLE-LABEL: callVariadicFunc:
571 ; DISABLE:       ## %bb.0: ## %entry
572 ; DISABLE-NEXT:    pushq %rax
573 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
574 ; DISABLE-NEXT:    movl %esi, %eax
575 ; DISABLE-NEXT:    testl %edi, %edi
576 ; DISABLE-NEXT:    je LBB7_2
577 ; DISABLE-NEXT:  ## %bb.1: ## %if.then
578 ; DISABLE-NEXT:    movl %eax, (%rsp)
579 ; DISABLE-NEXT:    movl %eax, %edi
580 ; DISABLE-NEXT:    movl %eax, %esi
581 ; DISABLE-NEXT:    movl %eax, %edx
582 ; DISABLE-NEXT:    movl %eax, %ecx
583 ; DISABLE-NEXT:    movl %eax, %r8d
584 ; DISABLE-NEXT:    movl %eax, %r9d
585 ; DISABLE-NEXT:    xorl %eax, %eax
586 ; DISABLE-NEXT:    callq _someVariadicFunc
587 ; DISABLE-NEXT:    shll $3, %eax
588 ; DISABLE-NEXT:    popq %rcx
589 ; DISABLE-NEXT:    retq
590 ; DISABLE-NEXT:  LBB7_2: ## %if.else
591 ; DISABLE-NEXT:    addl %eax, %eax
592 ; DISABLE-NEXT:    popq %rcx
593 ; DISABLE-NEXT:    retq
594 entry:
595   %tobool = icmp eq i32 %cond, 0
596   br i1 %tobool, label %if.else, label %if.then
598 if.then:                                          ; preds = %entry
599   %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N)
600   %shl = shl i32 %call, 3
601   br label %if.end
603 if.else:                                          ; preds = %entry
604   %mul = shl nsw i32 %N, 1
605   br label %if.end
607 if.end:                                           ; preds = %if.else, %if.then
608   %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
609   ret i32 %sum.0
612 declare i32 @someVariadicFunc(i32, ...)
614 ; Check that we use LEA not to clobber EFLAGS.
615 %struct.temp_slot = type { ptr, ptr, ptr, i32, i64, ptr, ptr, i8, i8, i32, i32, i64, i64 }
616 %union.tree_node = type { %struct.tree_decl }
617 %struct.tree_decl = type { %struct.tree_common, ptr, i32, i32, ptr, i48, %union.anon, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, %union.anon.1, ptr, ptr, ptr, i64, ptr }
618 %struct.tree_common = type { ptr, ptr, i32 }
619 %union.anon = type { i64 }
620 %union.anon.1 = type { ptr }
621 %struct.function = type { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, i32, i32, i32, i32, ptr, %struct.ix86_args, ptr, ptr, ptr, ptr, i32, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, i64, ptr, ptr, ptr, ptr, i32, ptr, ptr, i32, i32, i32, ptr, i32, i32, ptr, ptr, ptr, i32, i32, ptr, i32, i32, ptr, ptr, i24 }
622 %struct.eh_status = type opaque
623 %struct.stmt_status = type opaque
624 %struct.expr_status = type { i32, i32, i32, ptr, ptr, ptr, ptr }
625 %struct.emit_status = type { i32, i32, ptr, ptr, ptr, ptr, i32, i32, ptr, i32, ptr, ptr, ptr }
626 %struct.sequence_stack = type { ptr, ptr, ptr, ptr }
627 %struct.varasm_status = type opaque
628 %struct.ix86_args = type { i32, i32, i32, i32, i32, i32, i32 }
629 %struct.initial_value_struct = type opaque
630 %struct.var_refs_queue = type { ptr, i32, i32, ptr }
631 %struct.machine_function = type opaque
632 %struct.language_function = type opaque
633 %struct.lang_decl = type opaque
634 %struct.rtx_def = type { i32, [1 x %union.rtunion_def] }
635 %union.rtunion_def = type { i64 }
637 declare hidden fastcc ptr @find_temp_slot_from_address(ptr readonly)
639 define void @useLEA(ptr readonly %x) {
640 ; ENABLE-LABEL: useLEA:
641 ; ENABLE:       ## %bb.0: ## %entry
642 ; ENABLE-NEXT:    testq %rdi, %rdi
643 ; ENABLE-NEXT:    je LBB8_9
644 ; ENABLE-NEXT:  ## %bb.1: ## %if.end
645 ; ENABLE-NEXT:    cmpw $66, (%rdi)
646 ; ENABLE-NEXT:    jne LBB8_9
647 ; ENABLE-NEXT:  ## %bb.2: ## %lor.lhs.false
648 ; ENABLE-NEXT:    pushq %rax
649 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
650 ; ENABLE-NEXT:    movq 8(%rdi), %rdi
651 ; ENABLE-NEXT:    movzwl (%rdi), %eax
652 ; ENABLE-NEXT:    leal -54(%rax), %ecx
653 ; ENABLE-NEXT:    cmpl $14, %ecx
654 ; ENABLE-NEXT:    ja LBB8_3
655 ; ENABLE-NEXT:  ## %bb.7: ## %lor.lhs.false
656 ; ENABLE-NEXT:    movl $24599, %edx ## imm = 0x6017
657 ; ENABLE-NEXT:    btl %ecx, %edx
658 ; ENABLE-NEXT:    jae LBB8_3
659 ; ENABLE-NEXT:  LBB8_8:
660 ; ENABLE-NEXT:    addq $8, %rsp
661 ; ENABLE-NEXT:  LBB8_9: ## %cleanup
662 ; ENABLE-NEXT:    retq
663 ; ENABLE-NEXT:  LBB8_3: ## %lor.lhs.false
664 ; ENABLE-NEXT:    cmpl $134, %eax
665 ; ENABLE-NEXT:    je LBB8_8
666 ; ENABLE-NEXT:  ## %bb.4: ## %lor.lhs.false
667 ; ENABLE-NEXT:    cmpl $140, %eax
668 ; ENABLE-NEXT:    je LBB8_8
669 ; ENABLE-NEXT:  ## %bb.5: ## %if.end.55
670 ; ENABLE-NEXT:    callq _find_temp_slot_from_address
671 ; ENABLE-NEXT:    testq %rax, %rax
672 ; ENABLE-NEXT:    je LBB8_8
673 ; ENABLE-NEXT:  ## %bb.6: ## %if.then.60
674 ; ENABLE-NEXT:    movb $1, 57(%rax)
675 ; ENABLE-NEXT:    jmp LBB8_8
677 ; DISABLE-LABEL: useLEA:
678 ; DISABLE:       ## %bb.0: ## %entry
679 ; DISABLE-NEXT:    pushq %rax
680 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
681 ; DISABLE-NEXT:    testq %rdi, %rdi
682 ; DISABLE-NEXT:    je LBB8_7
683 ; DISABLE-NEXT:  ## %bb.1: ## %if.end
684 ; DISABLE-NEXT:    cmpw $66, (%rdi)
685 ; DISABLE-NEXT:    jne LBB8_7
686 ; DISABLE-NEXT:  ## %bb.2: ## %lor.lhs.false
687 ; DISABLE-NEXT:    movq 8(%rdi), %rdi
688 ; DISABLE-NEXT:    movzwl (%rdi), %eax
689 ; DISABLE-NEXT:    leal -54(%rax), %ecx
690 ; DISABLE-NEXT:    cmpl $14, %ecx
691 ; DISABLE-NEXT:    ja LBB8_3
692 ; DISABLE-NEXT:  ## %bb.8: ## %lor.lhs.false
693 ; DISABLE-NEXT:    movl $24599, %edx ## imm = 0x6017
694 ; DISABLE-NEXT:    btl %ecx, %edx
695 ; DISABLE-NEXT:    jae LBB8_3
696 ; DISABLE-NEXT:  LBB8_7: ## %cleanup
697 ; DISABLE-NEXT:    popq %rax
698 ; DISABLE-NEXT:    retq
699 ; DISABLE-NEXT:  LBB8_3: ## %lor.lhs.false
700 ; DISABLE-NEXT:    cmpl $134, %eax
701 ; DISABLE-NEXT:    je LBB8_7
702 ; DISABLE-NEXT:  ## %bb.4: ## %lor.lhs.false
703 ; DISABLE-NEXT:    cmpl $140, %eax
704 ; DISABLE-NEXT:    je LBB8_7
705 ; DISABLE-NEXT:  ## %bb.5: ## %if.end.55
706 ; DISABLE-NEXT:    callq _find_temp_slot_from_address
707 ; DISABLE-NEXT:    testq %rax, %rax
708 ; DISABLE-NEXT:    je LBB8_7
709 ; DISABLE-NEXT:  ## %bb.6: ## %if.then.60
710 ; DISABLE-NEXT:    movb $1, 57(%rax)
711 ; DISABLE-NEXT:    popq %rax
712 ; DISABLE-NEXT:    retq
713 entry:
714   %cmp = icmp eq ptr %x, null
715   br i1 %cmp, label %cleanup, label %if.end
717 if.end:                                           ; preds = %entry
718   %bf.load = load i32, ptr %x, align 8
719   %bf.clear = and i32 %bf.load, 65535
720   %cmp1 = icmp eq i32 %bf.clear, 66
721   br i1 %cmp1, label %lor.lhs.false, label %cleanup
723 lor.lhs.false:                                    ; preds = %if.end
724   %arrayidx = getelementptr inbounds %struct.rtx_def, ptr %x, i64 0, i32 1, i64 0
725   %tmp1 = load ptr, ptr %arrayidx, align 8
726   %bf.load2 = load i32, ptr %tmp1, align 8
727   %bf.clear3 = and i32 %bf.load2, 65535
728   switch i32 %bf.clear3, label %if.end.55 [
729     i32 67, label %cleanup
730     i32 68, label %cleanup
731     i32 54, label %cleanup
732     i32 55, label %cleanup
733     i32 58, label %cleanup
734     i32 134, label %cleanup
735     i32 56, label %cleanup
736     i32 140, label %cleanup
737   ]
739 if.end.55:                                        ; preds = %lor.lhs.false
740   %call = tail call fastcc ptr @find_temp_slot_from_address(ptr %tmp1) #2
741   %cmp59 = icmp eq ptr %call, null
742   br i1 %cmp59, label %cleanup, label %if.then.60
744 if.then.60:                                       ; preds = %if.end.55
745   %addr_taken = getelementptr inbounds %struct.temp_slot, ptr %call, i64 0, i32 8
746   store i8 1, ptr %addr_taken, align 1
747   br label %cleanup
749 cleanup:                                          ; preds = %if.then.60, %if.end.55, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %if.end, %entry
750   ret void
753 ; Make sure we do not insert unreachable code after noreturn function.
754 ; Although this is not incorrect to insert such code, it is useless
755 ; and it hurts the binary size.
756 define i32 @noreturn(i8 signext %bad_thing) {
757 ; ENABLE-LABEL: noreturn:
758 ; ENABLE:       ## %bb.0: ## %entry
759 ; ENABLE-NEXT:    testb %dil, %dil
760 ; ENABLE-NEXT:    jne LBB9_2
761 ; ENABLE-NEXT:  ## %bb.1: ## %if.end
762 ; ENABLE-NEXT:    movl $42, %eax
763 ; ENABLE-NEXT:    retq
764 ; ENABLE-NEXT:  LBB9_2: ## %if.abort
765 ; ENABLE-NEXT:    pushq %rax
766 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
767 ; ENABLE-NEXT:    callq _abort
769 ; DISABLE-LABEL: noreturn:
770 ; DISABLE:       ## %bb.0: ## %entry
771 ; DISABLE-NEXT:    pushq %rax
772 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
773 ; DISABLE-NEXT:    testb %dil, %dil
774 ; DISABLE-NEXT:    jne LBB9_2
775 ; DISABLE-NEXT:  ## %bb.1: ## %if.end
776 ; DISABLE-NEXT:    movl $42, %eax
777 ; DISABLE-NEXT:    popq %rcx
778 ; DISABLE-NEXT:    retq
779 ; DISABLE-NEXT:  LBB9_2: ## %if.abort
780 ; DISABLE-NEXT:    callq _abort
781 entry:
782   %tobool = icmp eq i8 %bad_thing, 0
783   br i1 %tobool, label %if.end, label %if.abort
785 if.abort:
786   tail call void @abort() #0
787   unreachable
789 if.end:
790   ret i32 42
793 declare void @abort() #0
795 attributes #0 = { noreturn nounwind }
798 ; Make sure that we handle infinite loops properly When checking that the Save
799 ; and Restore blocks are control flow equivalent, the loop searches for the
800 ; immediate (post) dominator for the (restore) save blocks. When either the Save
801 ; or Restore block is located in an infinite loop the only immediate (post)
802 ; dominator is itself. In this case, we cannot perform shrink wrapping, but we
803 ; should return gracefully and continue compilation.
804 ; The only condition for this test is the compilation finishes correctly.
806 define void @infiniteloop() {
807 ; ENABLE-LABEL: infiniteloop:
808 ; ENABLE:       ## %bb.0: ## %entry
809 ; ENABLE-NEXT:    pushq %rbp
810 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
811 ; ENABLE-NEXT:    .cfi_offset %rbp, -16
812 ; ENABLE-NEXT:    movq %rsp, %rbp
813 ; ENABLE-NEXT:    .cfi_def_cfa_register %rbp
814 ; ENABLE-NEXT:    pushq %rbx
815 ; ENABLE-NEXT:    pushq %rax
816 ; ENABLE-NEXT:    .cfi_offset %rbx, -24
817 ; ENABLE-NEXT:    xorl %eax, %eax
818 ; ENABLE-NEXT:    testb %al, %al
819 ; ENABLE-NEXT:    jne LBB10_3
820 ; ENABLE-NEXT:  ## %bb.1: ## %if.then
821 ; ENABLE-NEXT:    movq %rsp, %rcx
822 ; ENABLE-NEXT:    addq $-16, %rcx
823 ; ENABLE-NEXT:    movq %rcx, %rsp
824 ; ENABLE-NEXT:    ## InlineAsm Start
825 ; ENABLE-NEXT:    movl $1, %edx
826 ; ENABLE-NEXT:    ## InlineAsm End
827 ; ENABLE-NEXT:    .p2align 4, 0x90
828 ; ENABLE-NEXT:  LBB10_2: ## %for.body
829 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
830 ; ENABLE-NEXT:    addl %edx, %eax
831 ; ENABLE-NEXT:    movl %eax, (%rcx)
832 ; ENABLE-NEXT:    jmp LBB10_2
833 ; ENABLE-NEXT:  LBB10_3: ## %if.end
834 ; ENABLE-NEXT:    leaq -8(%rbp), %rsp
835 ; ENABLE-NEXT:    popq %rbx
836 ; ENABLE-NEXT:    popq %rbp
837 ; ENABLE-NEXT:    retq
839 ; DISABLE-LABEL: infiniteloop:
840 ; DISABLE:       ## %bb.0: ## %entry
841 ; DISABLE-NEXT:    pushq %rbp
842 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
843 ; DISABLE-NEXT:    .cfi_offset %rbp, -16
844 ; DISABLE-NEXT:    movq %rsp, %rbp
845 ; DISABLE-NEXT:    .cfi_def_cfa_register %rbp
846 ; DISABLE-NEXT:    pushq %rbx
847 ; DISABLE-NEXT:    pushq %rax
848 ; DISABLE-NEXT:    .cfi_offset %rbx, -24
849 ; DISABLE-NEXT:    xorl %eax, %eax
850 ; DISABLE-NEXT:    testb %al, %al
851 ; DISABLE-NEXT:    jne LBB10_3
852 ; DISABLE-NEXT:  ## %bb.1: ## %if.then
853 ; DISABLE-NEXT:    movq %rsp, %rcx
854 ; DISABLE-NEXT:    addq $-16, %rcx
855 ; DISABLE-NEXT:    movq %rcx, %rsp
856 ; DISABLE-NEXT:    ## InlineAsm Start
857 ; DISABLE-NEXT:    movl $1, %edx
858 ; DISABLE-NEXT:    ## InlineAsm End
859 ; DISABLE-NEXT:    .p2align 4, 0x90
860 ; DISABLE-NEXT:  LBB10_2: ## %for.body
861 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
862 ; DISABLE-NEXT:    addl %edx, %eax
863 ; DISABLE-NEXT:    movl %eax, (%rcx)
864 ; DISABLE-NEXT:    jmp LBB10_2
865 ; DISABLE-NEXT:  LBB10_3: ## %if.end
866 ; DISABLE-NEXT:    leaq -8(%rbp), %rsp
867 ; DISABLE-NEXT:    popq %rbx
868 ; DISABLE-NEXT:    popq %rbp
869 ; DISABLE-NEXT:    retq
870 entry:
871   br i1 undef, label %if.then, label %if.end
873 if.then:
874   %ptr = alloca i32, i32 4
875   br label %for.body
877 for.body:                                         ; preds = %for.body, %entry
878   %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
879   %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"()
880   %add = add nsw i32 %call, %sum.03
881   store i32 %add, ptr %ptr
882   br label %for.body
884 if.end:
885   ret void
888 ; Another infinite loop test this time with a body bigger than just one block.
889 define void @infiniteloop2() {
890 ; ENABLE-LABEL: infiniteloop2:
891 ; ENABLE:       ## %bb.0: ## %entry
892 ; ENABLE-NEXT:    pushq %rbp
893 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
894 ; ENABLE-NEXT:    .cfi_offset %rbp, -16
895 ; ENABLE-NEXT:    movq %rsp, %rbp
896 ; ENABLE-NEXT:    .cfi_def_cfa_register %rbp
897 ; ENABLE-NEXT:    pushq %rbx
898 ; ENABLE-NEXT:    pushq %rax
899 ; ENABLE-NEXT:    .cfi_offset %rbx, -24
900 ; ENABLE-NEXT:    xorl %eax, %eax
901 ; ENABLE-NEXT:    testb %al, %al
902 ; ENABLE-NEXT:    jne LBB11_5
903 ; ENABLE-NEXT:  ## %bb.1: ## %if.then
904 ; ENABLE-NEXT:    movq %rsp, %rcx
905 ; ENABLE-NEXT:    addq $-16, %rcx
906 ; ENABLE-NEXT:    movq %rcx, %rsp
907 ; ENABLE-NEXT:    xorl %edx, %edx
908 ; ENABLE-NEXT:    jmp LBB11_2
909 ; ENABLE-NEXT:    .p2align 4, 0x90
910 ; ENABLE-NEXT:  LBB11_4: ## %body2
911 ; ENABLE-NEXT:    ## in Loop: Header=BB11_2 Depth=1
912 ; ENABLE-NEXT:    ## InlineAsm Start
913 ; ENABLE-NEXT:    nop
914 ; ENABLE-NEXT:    ## InlineAsm End
915 ; ENABLE-NEXT:    movl $1, %edx
916 ; ENABLE-NEXT:  LBB11_2: ## %for.body
917 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
918 ; ENABLE-NEXT:    movl %edx, %esi
919 ; ENABLE-NEXT:    ## InlineAsm Start
920 ; ENABLE-NEXT:    movl $1, %edx
921 ; ENABLE-NEXT:    ## InlineAsm End
922 ; ENABLE-NEXT:    addl %esi, %edx
923 ; ENABLE-NEXT:    movl %edx, (%rcx)
924 ; ENABLE-NEXT:    testb %al, %al
925 ; ENABLE-NEXT:    jne LBB11_4
926 ; ENABLE-NEXT:  ## %bb.3: ## %body1
927 ; ENABLE-NEXT:    ## in Loop: Header=BB11_2 Depth=1
928 ; ENABLE-NEXT:    ## InlineAsm Start
929 ; ENABLE-NEXT:    nop
930 ; ENABLE-NEXT:    ## InlineAsm End
931 ; ENABLE-NEXT:    jmp LBB11_2
932 ; ENABLE-NEXT:  LBB11_5: ## %if.end
933 ; ENABLE-NEXT:    leaq -8(%rbp), %rsp
934 ; ENABLE-NEXT:    popq %rbx
935 ; ENABLE-NEXT:    popq %rbp
936 ; ENABLE-NEXT:    retq
938 ; DISABLE-LABEL: infiniteloop2:
939 ; DISABLE:       ## %bb.0: ## %entry
940 ; DISABLE-NEXT:    pushq %rbp
941 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
942 ; DISABLE-NEXT:    .cfi_offset %rbp, -16
943 ; DISABLE-NEXT:    movq %rsp, %rbp
944 ; DISABLE-NEXT:    .cfi_def_cfa_register %rbp
945 ; DISABLE-NEXT:    pushq %rbx
946 ; DISABLE-NEXT:    pushq %rax
947 ; DISABLE-NEXT:    .cfi_offset %rbx, -24
948 ; DISABLE-NEXT:    xorl %eax, %eax
949 ; DISABLE-NEXT:    testb %al, %al
950 ; DISABLE-NEXT:    jne LBB11_5
951 ; DISABLE-NEXT:  ## %bb.1: ## %if.then
952 ; DISABLE-NEXT:    movq %rsp, %rcx
953 ; DISABLE-NEXT:    addq $-16, %rcx
954 ; DISABLE-NEXT:    movq %rcx, %rsp
955 ; DISABLE-NEXT:    xorl %edx, %edx
956 ; DISABLE-NEXT:    jmp LBB11_2
957 ; DISABLE-NEXT:    .p2align 4, 0x90
958 ; DISABLE-NEXT:  LBB11_4: ## %body2
959 ; DISABLE-NEXT:    ## in Loop: Header=BB11_2 Depth=1
960 ; DISABLE-NEXT:    ## InlineAsm Start
961 ; DISABLE-NEXT:    nop
962 ; DISABLE-NEXT:    ## InlineAsm End
963 ; DISABLE-NEXT:    movl $1, %edx
964 ; DISABLE-NEXT:  LBB11_2: ## %for.body
965 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
966 ; DISABLE-NEXT:    movl %edx, %esi
967 ; DISABLE-NEXT:    ## InlineAsm Start
968 ; DISABLE-NEXT:    movl $1, %edx
969 ; DISABLE-NEXT:    ## InlineAsm End
970 ; DISABLE-NEXT:    addl %esi, %edx
971 ; DISABLE-NEXT:    movl %edx, (%rcx)
972 ; DISABLE-NEXT:    testb %al, %al
973 ; DISABLE-NEXT:    jne LBB11_4
974 ; DISABLE-NEXT:  ## %bb.3: ## %body1
975 ; DISABLE-NEXT:    ## in Loop: Header=BB11_2 Depth=1
976 ; DISABLE-NEXT:    ## InlineAsm Start
977 ; DISABLE-NEXT:    nop
978 ; DISABLE-NEXT:    ## InlineAsm End
979 ; DISABLE-NEXT:    jmp LBB11_2
980 ; DISABLE-NEXT:  LBB11_5: ## %if.end
981 ; DISABLE-NEXT:    leaq -8(%rbp), %rsp
982 ; DISABLE-NEXT:    popq %rbx
983 ; DISABLE-NEXT:    popq %rbp
984 ; DISABLE-NEXT:    retq
985 entry:
986   br i1 undef, label %if.then, label %if.end
988 if.then:
989   %ptr = alloca i32, i32 4
990   br label %for.body
992 for.body:                                         ; preds = %for.body, %entry
993   %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2]
994   %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"()
995   %add = add nsw i32 %call, %sum.03
996   store i32 %add, ptr %ptr
997   br i1 undef, label %body1, label %body2
999 body1:
1000   tail call void asm sideeffect "nop", "~{ebx}"()
1001   br label %for.body
1003 body2:
1004   tail call void asm sideeffect "nop", "~{ebx}"()
1005   br label %for.body
1007 if.end:
1008   ret void
1011 ; Another infinite loop test this time with two nested infinite loop.
1012 define void @infiniteloop3() {
1013 ; ENABLE-LABEL: infiniteloop3:
1014 ; ENABLE:       ## %bb.0: ## %entry
1015 ; ENABLE-NEXT:    xorl %eax, %eax
1016 ; ENABLE-NEXT:    testb %al, %al
1017 ; ENABLE-NEXT:    jne LBB12_2
1018 ; ENABLE-NEXT:  ## %bb.1: ## %body
1019 ; ENABLE-NEXT:    xorl %eax, %eax
1020 ; ENABLE-NEXT:    testb %al, %al
1021 ; ENABLE-NEXT:    jne LBB12_7
1022 ; ENABLE-NEXT:  LBB12_2: ## %loop2a.preheader
1023 ; ENABLE-NEXT:    xorl %eax, %eax
1024 ; ENABLE-NEXT:    xorl %ecx, %ecx
1025 ; ENABLE-NEXT:    movq %rax, %rsi
1026 ; ENABLE-NEXT:    jmp LBB12_4
1027 ; ENABLE-NEXT:    .p2align 4, 0x90
1028 ; ENABLE-NEXT:  LBB12_3: ## %loop2b
1029 ; ENABLE-NEXT:    ## in Loop: Header=BB12_4 Depth=1
1030 ; ENABLE-NEXT:    movq %rdx, (%rsi)
1031 ; ENABLE-NEXT:    movq %rdx, %rsi
1032 ; ENABLE-NEXT:  LBB12_4: ## %loop1
1033 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1034 ; ENABLE-NEXT:    movq %rcx, %rdx
1035 ; ENABLE-NEXT:    testq %rax, %rax
1036 ; ENABLE-NEXT:    movq (%rax), %rcx
1037 ; ENABLE-NEXT:    jne LBB12_3
1038 ; ENABLE-NEXT:  ## %bb.5: ## in Loop: Header=BB12_4 Depth=1
1039 ; ENABLE-NEXT:    movq %rdx, %rax
1040 ; ENABLE-NEXT:    movq %rdx, %rsi
1041 ; ENABLE-NEXT:    jmp LBB12_4
1042 ; ENABLE-NEXT:  LBB12_7: ## %end
1043 ; ENABLE-NEXT:    retq
1045 ; DISABLE-LABEL: infiniteloop3:
1046 ; DISABLE:       ## %bb.0: ## %entry
1047 ; DISABLE-NEXT:    xorl %eax, %eax
1048 ; DISABLE-NEXT:    testb %al, %al
1049 ; DISABLE-NEXT:    jne LBB12_2
1050 ; DISABLE-NEXT:  ## %bb.1: ## %body
1051 ; DISABLE-NEXT:    xorl %eax, %eax
1052 ; DISABLE-NEXT:    testb %al, %al
1053 ; DISABLE-NEXT:    jne LBB12_7
1054 ; DISABLE-NEXT:  LBB12_2: ## %loop2a.preheader
1055 ; DISABLE-NEXT:    xorl %eax, %eax
1056 ; DISABLE-NEXT:    xorl %ecx, %ecx
1057 ; DISABLE-NEXT:    movq %rax, %rsi
1058 ; DISABLE-NEXT:    jmp LBB12_4
1059 ; DISABLE-NEXT:    .p2align 4, 0x90
1060 ; DISABLE-NEXT:  LBB12_3: ## %loop2b
1061 ; DISABLE-NEXT:    ## in Loop: Header=BB12_4 Depth=1
1062 ; DISABLE-NEXT:    movq %rdx, (%rsi)
1063 ; DISABLE-NEXT:    movq %rdx, %rsi
1064 ; DISABLE-NEXT:  LBB12_4: ## %loop1
1065 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1066 ; DISABLE-NEXT:    movq %rcx, %rdx
1067 ; DISABLE-NEXT:    testq %rax, %rax
1068 ; DISABLE-NEXT:    movq (%rax), %rcx
1069 ; DISABLE-NEXT:    jne LBB12_3
1070 ; DISABLE-NEXT:  ## %bb.5: ## in Loop: Header=BB12_4 Depth=1
1071 ; DISABLE-NEXT:    movq %rdx, %rax
1072 ; DISABLE-NEXT:    movq %rdx, %rsi
1073 ; DISABLE-NEXT:    jmp LBB12_4
1074 ; DISABLE-NEXT:  LBB12_7: ## %end
1075 ; DISABLE-NEXT:    retq
1076 entry:
1077   br i1 undef, label %loop2a, label %body
1079 body:                                             ; preds = %entry
1080   br i1 undef, label %loop2a, label %end
1082 loop1:                                            ; preds = %loop2a, %loop2b
1083   %var.phi = phi ptr [ %next.phi, %loop2b ], [ %var, %loop2a ]
1084   %next.phi = phi ptr [ %next.load, %loop2b ], [ %next.var, %loop2a ]
1085   %0 = icmp eq ptr %var, null
1086   %next.load = load ptr, ptr undef
1087   br i1 %0, label %loop2a, label %loop2b
1089 loop2a:                                           ; preds = %loop1, %body, %entry
1090   %var = phi ptr [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ]
1091   %next.var = phi ptr [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ]
1092   br label %loop1
1094 loop2b:                                           ; preds = %loop1
1095   store ptr %next.phi, ptr %var.phi
1096   br label %loop1
1098 end:
1099   ret void
1102 ; Check that we just don't bail out on RegMask.
1103 ; In this case, the RegMask does not touch a CSR so we are good to go!
1104 define i32 @regmask(i32 %a, i32 %b, ptr %addr) {
1105 ; ENABLE-LABEL: regmask:
1106 ; ENABLE:       ## %bb.0:
1107 ; ENABLE-NEXT:    cmpl %esi, %edi
1108 ; ENABLE-NEXT:    jge LBB13_2
1109 ; ENABLE-NEXT:  ## %bb.1: ## %true
1110 ; ENABLE-NEXT:    pushq %rbx
1111 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
1112 ; ENABLE-NEXT:    .cfi_offset %rbx, -16
1113 ; ENABLE-NEXT:    ## InlineAsm Start
1114 ; ENABLE-NEXT:    nop
1115 ; ENABLE-NEXT:    ## InlineAsm End
1116 ; ENABLE-NEXT:    xorl %edi, %edi
1117 ; ENABLE-NEXT:    movq %rdx, %rsi
1118 ; ENABLE-NEXT:    callq _doSomething
1119 ; ENABLE-NEXT:    popq %rbx
1120 ; ENABLE-NEXT:    retq
1121 ; ENABLE-NEXT:  LBB13_2: ## %false
1122 ; ENABLE-NEXT:    movl $6, %edi
1123 ; ENABLE-NEXT:    movq %rdx, %rsi
1124 ; ENABLE-NEXT:    jmp _doSomething ## TAILCALL
1126 ; DISABLE-LABEL: regmask:
1127 ; DISABLE:       ## %bb.0:
1128 ; DISABLE-NEXT:    pushq %rbx
1129 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
1130 ; DISABLE-NEXT:    .cfi_offset %rbx, -16
1131 ; DISABLE-NEXT:    cmpl %esi, %edi
1132 ; DISABLE-NEXT:    jge LBB13_2
1133 ; DISABLE-NEXT:  ## %bb.1: ## %true
1134 ; DISABLE-NEXT:    ## InlineAsm Start
1135 ; DISABLE-NEXT:    nop
1136 ; DISABLE-NEXT:    ## InlineAsm End
1137 ; DISABLE-NEXT:    xorl %edi, %edi
1138 ; DISABLE-NEXT:    movq %rdx, %rsi
1139 ; DISABLE-NEXT:    callq _doSomething
1140 ; DISABLE-NEXT:    popq %rbx
1141 ; DISABLE-NEXT:    retq
1142 ; DISABLE-NEXT:  LBB13_2: ## %false
1143 ; DISABLE-NEXT:    movl $6, %edi
1144 ; DISABLE-NEXT:    movq %rdx, %rsi
1145 ; DISABLE-NEXT:    popq %rbx
1146 ; DISABLE-NEXT:    jmp _doSomething ## TAILCALL
1147   %tmp2 = icmp slt i32 %a, %b
1148   br i1 %tmp2, label %true, label %false
1150 true:
1151   ; Clobber a CSR so that we check something on the regmask
1152   ; of the tail call.
1153   tail call void asm sideeffect "nop", "~{ebx}"()
1154   %tmp4 = call i32 @doSomething(i32 0, ptr %addr)
1155   br label %end
1157 false:
1158   %tmp5 = tail call i32 @doSomething(i32 6, ptr %addr)
1159   br label %end
1161 end:
1162   %tmp.0 = phi i32 [ %tmp4, %true ], [ %tmp5, %false ]
1163   ret i32 %tmp.0
1166 @b = internal unnamed_addr global i1 false
1167 @c = internal unnamed_addr global i8 0, align 1
1168 @a = common global i32 0, align 4
1170 ; Make sure the prologue does not clobber the EFLAGS when
1171 ; it is live accross.
1172 ; PR25629.
1173 ; Note: The registers may change in the following patterns, but
1174 ; because they imply register hierarchy (e.g., eax, al) this is
1175 ; tricky to write robust patterns.
1176 define i32 @useLEAForPrologue(i32 %d, i32 %a, i8 %c) #3 {
1177 ; ENABLE-LABEL: useLEAForPrologue:
1178 ; ENABLE:       ## %bb.0: ## %entry
1179 ; ENABLE-NEXT:    pushq %rbx
1180 ; ENABLE-NEXT:    subq $16, %rsp
1181 ; ENABLE-NEXT:    xorl %eax, %eax
1182 ; ENABLE-NEXT:    cmpb $0, _b(%rip)
1183 ; ENABLE-NEXT:    movl $48, %ecx
1184 ; ENABLE-NEXT:    cmovnel %eax, %ecx
1185 ; ENABLE-NEXT:    movb %cl, _c(%rip)
1186 ; ENABLE-NEXT:    je LBB14_4
1187 ; ENABLE-NEXT:  ## %bb.1: ## %for.body.lr.ph
1188 ; ENABLE-NEXT:    ## InlineAsm Start
1189 ; ENABLE-NEXT:    nop
1190 ; ENABLE-NEXT:    ## InlineAsm End
1191 ; ENABLE-NEXT:    .p2align 4, 0x90
1192 ; ENABLE-NEXT:  LBB14_2: ## %for.body
1193 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1194 ; ENABLE-NEXT:    cmpl %esi, %edi
1195 ; ENABLE-NEXT:    setl %al
1196 ; ENABLE-NEXT:    xorl %esi, %esi
1197 ; ENABLE-NEXT:    movb %al, %sil
1198 ; ENABLE-NEXT:    incb %dl
1199 ; ENABLE-NEXT:    cmpb $45, %dl
1200 ; ENABLE-NEXT:    jl LBB14_2
1201 ; ENABLE-NEXT:  ## %bb.3: ## %for.cond.for.end_crit_edge
1202 ; ENABLE-NEXT:    movq _a@GOTPCREL(%rip), %rax
1203 ; ENABLE-NEXT:    movl %esi, (%rax)
1204 ; ENABLE-NEXT:  LBB14_4: ## %for.end
1205 ; ENABLE-NEXT:    xorl %edi, %edi
1206 ; ENABLE-NEXT:    callq _varfunc
1207 ; ENABLE-NEXT:    xorl %eax, %eax
1208 ; ENABLE-NEXT:    addq $16, %rsp
1209 ; ENABLE-NEXT:    popq %rbx
1210 ; ENABLE-NEXT:    retq
1212 ; DISABLE-LABEL: useLEAForPrologue:
1213 ; DISABLE:       ## %bb.0: ## %entry
1214 ; DISABLE-NEXT:    pushq %rbx
1215 ; DISABLE-NEXT:    subq $16, %rsp
1216 ; DISABLE-NEXT:    xorl %eax, %eax
1217 ; DISABLE-NEXT:    cmpb $0, _b(%rip)
1218 ; DISABLE-NEXT:    movl $48, %ecx
1219 ; DISABLE-NEXT:    cmovnel %eax, %ecx
1220 ; DISABLE-NEXT:    movb %cl, _c(%rip)
1221 ; DISABLE-NEXT:    je LBB14_4
1222 ; DISABLE-NEXT:  ## %bb.1: ## %for.body.lr.ph
1223 ; DISABLE-NEXT:    ## InlineAsm Start
1224 ; DISABLE-NEXT:    nop
1225 ; DISABLE-NEXT:    ## InlineAsm End
1226 ; DISABLE-NEXT:    .p2align 4, 0x90
1227 ; DISABLE-NEXT:  LBB14_2: ## %for.body
1228 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1229 ; DISABLE-NEXT:    cmpl %esi, %edi
1230 ; DISABLE-NEXT:    setl %al
1231 ; DISABLE-NEXT:    xorl %esi, %esi
1232 ; DISABLE-NEXT:    movb %al, %sil
1233 ; DISABLE-NEXT:    incb %dl
1234 ; DISABLE-NEXT:    cmpb $45, %dl
1235 ; DISABLE-NEXT:    jl LBB14_2
1236 ; DISABLE-NEXT:  ## %bb.3: ## %for.cond.for.end_crit_edge
1237 ; DISABLE-NEXT:    movq _a@GOTPCREL(%rip), %rax
1238 ; DISABLE-NEXT:    movl %esi, (%rax)
1239 ; DISABLE-NEXT:  LBB14_4: ## %for.end
1240 ; DISABLE-NEXT:    xorl %edi, %edi
1241 ; DISABLE-NEXT:    callq _varfunc
1242 ; DISABLE-NEXT:    xorl %eax, %eax
1243 ; DISABLE-NEXT:    addq $16, %rsp
1244 ; DISABLE-NEXT:    popq %rbx
1245 ; DISABLE-NEXT:    retq
1246 entry:
1247   %tmp = alloca i3
1248   %.b = load i1, ptr @b, align 1
1249   %bool = select i1 %.b, i8 0, i8 48
1250   store i8 %bool, ptr @c, align 1
1251   br i1 %.b, label %for.body.lr.ph, label %for.end
1253 for.body.lr.ph:                                   ; preds = %entry
1254   tail call void asm sideeffect "nop", "~{ebx}"()
1255   br label %for.body
1257 for.body:                                         ; preds = %for.body.lr.ph, %for.body
1258   %inc6 = phi i8 [ %c, %for.body.lr.ph ], [ %inc, %for.body ]
1259   %cond5 = phi i32 [ %a, %for.body.lr.ph ], [ %conv3, %for.body ]
1260   %cmp2 = icmp slt i32 %d, %cond5
1261   %conv3 = zext i1 %cmp2 to i32
1262   %inc = add i8 %inc6, 1
1263   %cmp = icmp slt i8 %inc, 45
1264   br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
1266 for.cond.for.end_crit_edge:                       ; preds = %for.body
1267   store i32 %conv3, ptr @a, align 4
1268   br label %for.end
1270 for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
1271   %call = tail call i32 (ptr) @varfunc(ptr null)
1272   ret i32 0
1275 declare i32 @varfunc(ptr nocapture readonly)
1277 @sum1 = external hidden thread_local global i32, align 4
1280 ; Function Attrs: nounwind
1281 ; Make sure the TLS call used to access @sum1 happens after the prologue
1282 ; and before the epilogue.
1283 ; TLS calls used to be wrongly model and shrink-wrapping would have inserted
1284 ; the prologue and epilogue just around the call to doSomething.
1285 ; PR25820.
1286 define i32 @tlsCall(i1 %bool1, i32 %arg, ptr readonly dereferenceable(4) %sum1) #3 {
1287 ; ENABLE-LABEL: tlsCall:
1288 ; ENABLE:       ## %bb.0: ## %entry
1289 ; ENABLE-NEXT:    pushq %rax
1290 ; ENABLE-NEXT:    testb $1, %dil
1291 ; ENABLE-NEXT:    je LBB15_2
1292 ; ENABLE-NEXT:  ## %bb.1: ## %main
1293 ; ENABLE-NEXT:    movl (%rdx), %ecx
1294 ; ENABLE-NEXT:    movq _sum1@TLVP(%rip), %rdi
1295 ; ENABLE-NEXT:    callq *(%rdi)
1296 ; ENABLE-NEXT:    movl %ecx, (%rax)
1297 ; ENABLE-NEXT:    jmp LBB15_3
1298 ; ENABLE-NEXT:  LBB15_2: ## %else
1299 ; ENABLE-NEXT:    xorl %edi, %edi
1300 ; ENABLE-NEXT:    xorl %esi, %esi
1301 ; ENABLE-NEXT:    callq _doSomething
1302 ; ENABLE-NEXT:    movl %eax, %esi
1303 ; ENABLE-NEXT:  LBB15_3: ## %exit
1304 ; ENABLE-NEXT:    movl %esi, %eax
1305 ; ENABLE-NEXT:    popq %rcx
1306 ; ENABLE-NEXT:    retq
1308 ; DISABLE-LABEL: tlsCall:
1309 ; DISABLE:       ## %bb.0: ## %entry
1310 ; DISABLE-NEXT:    pushq %rax
1311 ; DISABLE-NEXT:    testb $1, %dil
1312 ; DISABLE-NEXT:    je LBB15_2
1313 ; DISABLE-NEXT:  ## %bb.1: ## %main
1314 ; DISABLE-NEXT:    movl (%rdx), %ecx
1315 ; DISABLE-NEXT:    movq _sum1@TLVP(%rip), %rdi
1316 ; DISABLE-NEXT:    callq *(%rdi)
1317 ; DISABLE-NEXT:    movl %ecx, (%rax)
1318 ; DISABLE-NEXT:    jmp LBB15_3
1319 ; DISABLE-NEXT:  LBB15_2: ## %else
1320 ; DISABLE-NEXT:    xorl %edi, %edi
1321 ; DISABLE-NEXT:    xorl %esi, %esi
1322 ; DISABLE-NEXT:    callq _doSomething
1323 ; DISABLE-NEXT:    movl %eax, %esi
1324 ; DISABLE-NEXT:  LBB15_3: ## %exit
1325 ; DISABLE-NEXT:    movl %esi, %eax
1326 ; DISABLE-NEXT:    popq %rcx
1327 ; DISABLE-NEXT:    retq
1328 entry:
1329   br i1 %bool1, label %main, label %else
1331 main:
1332   %tmp1 = load i32, ptr %sum1, align 4
1333   store i32 %tmp1, ptr @sum1, align 4
1334   br label %exit
1336 else:
1337   %call = call i32 @doSomething(i32 0, ptr null)
1338   br label %exit
1340 exit:
1341   %res = phi i32 [ %arg, %main], [ %call, %else ]
1342   ret i32 %res
1345 attributes #3 = { nounwind }
1347 @irreducibleCFGa = common global i32 0, align 4
1348 @irreducibleCFGf = common global i8 0, align 1
1349 @irreducibleCFGb = common global i32 0, align 4
1351 ; Check that we do not run shrink-wrapping on irreducible CFGs until
1352 ; it is actually supported.
1353 ; At the moment, on those CFGs the loop information may be incorrect
1354 ; and since we use that information to do the placement, we may end up
1355 ; inserting the prologue/epilogue at incorrect places.
1356 ; PR25988.
1357 ; Make sure we emit missed optimization remarks for this.
1358 ; REMARKS: Pass:            shrink-wrap
1359 ; REMARKS-NEXT: Name:            UnsupportedIrreducibleCFG
1360 ; REMARKS-NEXT: Function:        irreducibleCFG
1361 ; REMARKS-NEXT: Args:
1362 ; REMARKS-NEXT:   - String:          Irreducible CFGs are not supported yet
1364 define i32 @irreducibleCFG() #4 {
1365 ; ENABLE-LABEL: irreducibleCFG:
1366 ; ENABLE:       ## %bb.0: ## %entry
1367 ; ENABLE-NEXT:    pushq %rbp
1368 ; ENABLE-NEXT:    .cfi_def_cfa_offset 16
1369 ; ENABLE-NEXT:    .cfi_offset %rbp, -16
1370 ; ENABLE-NEXT:    movq %rsp, %rbp
1371 ; ENABLE-NEXT:    .cfi_def_cfa_register %rbp
1372 ; ENABLE-NEXT:    pushq %rbx
1373 ; ENABLE-NEXT:    pushq %rax
1374 ; ENABLE-NEXT:    .cfi_offset %rbx, -24
1375 ; ENABLE-NEXT:    movq _irreducibleCFGf@GOTPCREL(%rip), %rax
1376 ; ENABLE-NEXT:    cmpb $0, (%rax)
1377 ; ENABLE-NEXT:    je LBB16_2
1378 ; ENABLE-NEXT:    .p2align 4, 0x90
1379 ; ENABLE-NEXT:  LBB16_1: ## %preheader
1380 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1381 ; ENABLE-NEXT:    jmp LBB16_1
1382 ; ENABLE-NEXT:  LBB16_2: ## %split
1383 ; ENABLE-NEXT:    movq _irreducibleCFGb@GOTPCREL(%rip), %rax
1384 ; ENABLE-NEXT:    cmpl $0, (%rax)
1385 ; ENABLE-NEXT:    je LBB16_3
1386 ; ENABLE-NEXT:  ## %bb.4: ## %for.body4.i
1387 ; ENABLE-NEXT:    movq _irreducibleCFGa@GOTPCREL(%rip), %rax
1388 ; ENABLE-NEXT:    movl (%rax), %edi
1389 ; ENABLE-NEXT:    xorl %ebx, %ebx
1390 ; ENABLE-NEXT:    xorl %eax, %eax
1391 ; ENABLE-NEXT:    callq _something
1392 ; ENABLE-NEXT:    jmp LBB16_5
1393 ; ENABLE-NEXT:  LBB16_3:
1394 ; ENABLE-NEXT:    xorl %ebx, %ebx
1395 ; ENABLE-NEXT:    .p2align 4, 0x90
1396 ; ENABLE-NEXT:  LBB16_5: ## %for.inc
1397 ; ENABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1398 ; ENABLE-NEXT:    incl %ebx
1399 ; ENABLE-NEXT:    cmpl $7, %ebx
1400 ; ENABLE-NEXT:    jl LBB16_5
1401 ; ENABLE-NEXT:  ## %bb.6: ## %fn1.exit
1402 ; ENABLE-NEXT:    xorl %eax, %eax
1403 ; ENABLE-NEXT:    addq $8, %rsp
1404 ; ENABLE-NEXT:    popq %rbx
1405 ; ENABLE-NEXT:    popq %rbp
1406 ; ENABLE-NEXT:    retq
1408 ; DISABLE-LABEL: irreducibleCFG:
1409 ; DISABLE:       ## %bb.0: ## %entry
1410 ; DISABLE-NEXT:    pushq %rbp
1411 ; DISABLE-NEXT:    .cfi_def_cfa_offset 16
1412 ; DISABLE-NEXT:    .cfi_offset %rbp, -16
1413 ; DISABLE-NEXT:    movq %rsp, %rbp
1414 ; DISABLE-NEXT:    .cfi_def_cfa_register %rbp
1415 ; DISABLE-NEXT:    pushq %rbx
1416 ; DISABLE-NEXT:    pushq %rax
1417 ; DISABLE-NEXT:    .cfi_offset %rbx, -24
1418 ; DISABLE-NEXT:    movq _irreducibleCFGf@GOTPCREL(%rip), %rax
1419 ; DISABLE-NEXT:    cmpb $0, (%rax)
1420 ; DISABLE-NEXT:    je LBB16_2
1421 ; DISABLE-NEXT:    .p2align 4, 0x90
1422 ; DISABLE-NEXT:  LBB16_1: ## %preheader
1423 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1424 ; DISABLE-NEXT:    jmp LBB16_1
1425 ; DISABLE-NEXT:  LBB16_2: ## %split
1426 ; DISABLE-NEXT:    movq _irreducibleCFGb@GOTPCREL(%rip), %rax
1427 ; DISABLE-NEXT:    cmpl $0, (%rax)
1428 ; DISABLE-NEXT:    je LBB16_3
1429 ; DISABLE-NEXT:  ## %bb.4: ## %for.body4.i
1430 ; DISABLE-NEXT:    movq _irreducibleCFGa@GOTPCREL(%rip), %rax
1431 ; DISABLE-NEXT:    movl (%rax), %edi
1432 ; DISABLE-NEXT:    xorl %ebx, %ebx
1433 ; DISABLE-NEXT:    xorl %eax, %eax
1434 ; DISABLE-NEXT:    callq _something
1435 ; DISABLE-NEXT:    jmp LBB16_5
1436 ; DISABLE-NEXT:  LBB16_3:
1437 ; DISABLE-NEXT:    xorl %ebx, %ebx
1438 ; DISABLE-NEXT:    .p2align 4, 0x90
1439 ; DISABLE-NEXT:  LBB16_5: ## %for.inc
1440 ; DISABLE-NEXT:    ## =>This Inner Loop Header: Depth=1
1441 ; DISABLE-NEXT:    incl %ebx
1442 ; DISABLE-NEXT:    cmpl $7, %ebx
1443 ; DISABLE-NEXT:    jl LBB16_5
1444 ; DISABLE-NEXT:  ## %bb.6: ## %fn1.exit
1445 ; DISABLE-NEXT:    xorl %eax, %eax
1446 ; DISABLE-NEXT:    addq $8, %rsp
1447 ; DISABLE-NEXT:    popq %rbx
1448 ; DISABLE-NEXT:    popq %rbp
1449 ; DISABLE-NEXT:    retq
1450 entry:
1451   %i0 = load i32, ptr @irreducibleCFGa, align 4
1452   %.pr = load i8, ptr @irreducibleCFGf, align 1
1453   %bool = icmp eq i8 %.pr, 0
1454   br i1 %bool, label %split, label %preheader
1456 preheader:
1457   br label %preheader
1459 split:
1460   %i1 = load i32, ptr @irreducibleCFGb, align 4
1461   %tobool1.i = icmp ne i32 %i1, 0
1462   br i1 %tobool1.i, label %for.body4.i, label %for.cond8.i.preheader
1464 for.body4.i:
1465   %call.i = tail call i32 (...) @something(i32 %i0)
1466   br label %for.cond8
1468 for.cond8:
1469   %p1 = phi i32 [ %inc18.i, %for.inc ], [ 0, %for.body4.i ]
1470   %.pr1.pr = load i32, ptr @irreducibleCFGb, align 4
1471   br label %for.cond8.i.preheader
1473 for.cond8.i.preheader:
1474   %.pr1 = phi i32 [ %.pr1.pr, %for.cond8 ], [ %i1, %split ]
1475   %p13 = phi i32 [ %p1, %for.cond8 ], [ 0, %split ]
1476   br label %for.inc
1478 fn1.exit:
1479   ret i32 0
1481 for.inc:
1482   %inc18.i = add nuw nsw i32 %p13, 1
1483   %cmp = icmp slt i32 %inc18.i, 7
1484   br i1 %cmp, label %for.cond8, label %fn1.exit
1487 attributes #4 = { "frame-pointer"="all" }
1489 @x = external global i32, align 4
1490 @y = external global i32, align 4
1492 ; The post-dominator tree does not include the branch containing the infinite
1493 ; loop, which can occur into a misplacement of the restore block, if we're
1494 ; looking for the nearest common post-dominator of an "unreachable" block.
1496 define void @infiniteLoopNoSuccessor() #5 {
1497 ; ENABLE-LABEL: infiniteLoopNoSuccessor:
1498 ; ENABLE:       ## %bb.0:
1499 ; ENABLE-NEXT:    pushq %rbp
1500 ; ENABLE-NEXT:    movq %rsp, %rbp
1501 ; ENABLE-NEXT:    movq _x@GOTPCREL(%rip), %rax
1502 ; ENABLE-NEXT:    cmpl $0, (%rax)
1503 ; ENABLE-NEXT:    je LBB17_2
1504 ; ENABLE-NEXT:  ## %bb.1:
1505 ; ENABLE-NEXT:    movl $0, (%rax)
1506 ; ENABLE-NEXT:  LBB17_2:
1507 ; ENABLE-NEXT:    xorl %eax, %eax
1508 ; ENABLE-NEXT:    callq _somethingElse
1509 ; ENABLE-NEXT:    movq _y@GOTPCREL(%rip), %rax
1510 ; ENABLE-NEXT:    cmpl $0, (%rax)
1511 ; ENABLE-NEXT:    je LBB17_3
1512 ; ENABLE-NEXT:  ## %bb.5:
1513 ; ENABLE-NEXT:    popq %rbp
1514 ; ENABLE-NEXT:    retq
1515 ; ENABLE-NEXT:  LBB17_3:
1516 ; ENABLE-NEXT:    xorl %eax, %eax
1517 ; ENABLE-NEXT:    callq _something
1518 ; ENABLE-NEXT:    .p2align 4, 0x90
1519 ; ENABLE-NEXT:  LBB17_4: ## =>This Inner Loop Header: Depth=1
1520 ; ENABLE-NEXT:    xorl %eax, %eax
1521 ; ENABLE-NEXT:    callq _somethingElse
1522 ; ENABLE-NEXT:    jmp LBB17_4
1524 ; DISABLE-LABEL: infiniteLoopNoSuccessor:
1525 ; DISABLE:       ## %bb.0:
1526 ; DISABLE-NEXT:    pushq %rbp
1527 ; DISABLE-NEXT:    movq %rsp, %rbp
1528 ; DISABLE-NEXT:    movq _x@GOTPCREL(%rip), %rax
1529 ; DISABLE-NEXT:    cmpl $0, (%rax)
1530 ; DISABLE-NEXT:    je LBB17_2
1531 ; DISABLE-NEXT:  ## %bb.1:
1532 ; DISABLE-NEXT:    movl $0, (%rax)
1533 ; DISABLE-NEXT:  LBB17_2:
1534 ; DISABLE-NEXT:    xorl %eax, %eax
1535 ; DISABLE-NEXT:    callq _somethingElse
1536 ; DISABLE-NEXT:    movq _y@GOTPCREL(%rip), %rax
1537 ; DISABLE-NEXT:    cmpl $0, (%rax)
1538 ; DISABLE-NEXT:    je LBB17_3
1539 ; DISABLE-NEXT:  ## %bb.5:
1540 ; DISABLE-NEXT:    popq %rbp
1541 ; DISABLE-NEXT:    retq
1542 ; DISABLE-NEXT:  LBB17_3:
1543 ; DISABLE-NEXT:    xorl %eax, %eax
1544 ; DISABLE-NEXT:    callq _something
1545 ; DISABLE-NEXT:    .p2align 4, 0x90
1546 ; DISABLE-NEXT:  LBB17_4: ## =>This Inner Loop Header: Depth=1
1547 ; DISABLE-NEXT:    xorl %eax, %eax
1548 ; DISABLE-NEXT:    callq _somethingElse
1549 ; DISABLE-NEXT:    jmp LBB17_4
1550   %1 = load i32, ptr @x, align 4
1551   %2 = icmp ne i32 %1, 0
1552   br i1 %2, label %3, label %4
1554 ; <label>:3:
1555   store i32 0, ptr @x, align 4
1556   br label %4
1558 ; <label>:4:
1559   call void (...) @somethingElse()
1560   %5 = load i32, ptr @y, align 4
1561   %6 = icmp ne i32 %5, 0
1562   br i1 %6, label %10, label %7
1564 ; <label>:7:
1565   %8 = call i32 (...) @something()
1566   br label %9
1568 ; <label>:9:
1569   call void (...) @somethingElse()
1570   br label %9
1572 ; <label>:10:
1573   ret void
1576 declare void @somethingElse(...)
1578 attributes #5 = { nounwind "frame-pointer"="non-leaf" }