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 | FileCheck %s --check-prefix=ENABLE
3 ; RUN: cat %t | FileCheck %s --check-prefix=REMARKS
4 ; RUN: llc %s -o - -enable-shrink-wrap=false | 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
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) {
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
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
49 %tmp = alloca i32, align 4
50 %tmp2 = icmp slt i32 %a, %b
51 br i1 %tmp2, label %true, label %false
54 store i32 %a, i32* %tmp, align 4
55 %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
59 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
63 ; Function Attrs: optsize
64 declare i32 @doSomething(i32, i32*)
67 ; Check that we do not perform the restore inside the loop whereas the save
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
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
96 ; ENABLE-NEXT: LBB1_4: ## %if.else
97 ; ENABLE-NEXT: movl %esi, %eax
98 ; ENABLE-NEXT: addl %esi, %eax
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
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
127 ; DISABLE-NEXT: LBB1_4: ## %if.else
128 ; DISABLE-NEXT: movl %esi, %eax
129 ; DISABLE-NEXT: addl %esi, %eax
130 ; DISABLE-NEXT: popq %rbx
133 %tobool = icmp eq i32 %cond, 0
134 br i1 %tobool, label %if.else, label %for.preheader
137 tail call void asm "nop", ""()
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
153 if.else: ; preds = %entry
154 %mul = shl nsw i32 %N, 1
157 if.end: ; preds = %if.else, %for.end
158 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
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
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
189 ; ENABLE-NEXT: ## InlineAsm End
190 ; ENABLE-NEXT: popq %rbx
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
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
215 ; DISABLE-NEXT: ## InlineAsm End
216 ; DISABLE-NEXT: popq %rbx
219 br label %for.preheader
222 tail call void asm "nop", ""()
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
235 tail call void asm "nop", ""()
238 for.end: ; preds = %for.body
242 ; Check with a more complex case that we do not have save within the loop and
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
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
270 ; ENABLE-NEXT: ## InlineAsm End
271 ; ENABLE-NEXT: shll $3, %eax
272 ; ENABLE-NEXT: popq %rbx
274 ; ENABLE-NEXT: LBB3_4: ## %if.else
275 ; ENABLE-NEXT: movl %esi, %eax
276 ; ENABLE-NEXT: addl %esi, %eax
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
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
304 ; DISABLE-NEXT: ## InlineAsm End
305 ; DISABLE-NEXT: shll $3, %eax
306 ; DISABLE-NEXT: popq %rbx
308 ; DISABLE-NEXT: LBB3_4: ## %if.else
309 ; DISABLE-NEXT: movl %esi, %eax
310 ; DISABLE-NEXT: addl %esi, %eax
311 ; DISABLE-NEXT: popq %rbx
314 %tobool = icmp eq i32 %cond, 0
315 br i1 %tobool, label %if.else, label %for.preheader
318 tail call void asm "nop", ""()
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
335 if.else: ; preds = %entry
336 %mul = shl nsw i32 %N, 1
339 if.end: ; preds = %if.else, %for.end
340 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
344 ; Check with a more complex case that we do not have restore within the loop and
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
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
371 ; ENABLE-NEXT: LBB4_4: ## %if.else
372 ; ENABLE-NEXT: movl %esi, %eax
373 ; ENABLE-NEXT: addl %esi, %eax
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
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
400 ; DISABLE-NEXT: LBB4_4: ## %if.else
401 ; DISABLE-NEXT: movl %esi, %eax
402 ; DISABLE-NEXT: addl %esi, %eax
403 ; DISABLE-NEXT: popq %rbx
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}"()
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
426 if.else: ; preds = %entry
427 %mul = shl nsw i32 %N, 1
430 if.end: ; preds = %if.else, %for.end
431 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
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
442 ; DISABLE-LABEL: emptyFrame:
443 ; DISABLE: ## %bb.0: ## %entry
444 ; DISABLE-NEXT: xorl %eax, %eax
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
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
475 ; ENABLE-NEXT: ## InlineAsm End
476 ; ENABLE-NEXT: xorl %eax, %eax
477 ; ENABLE-NEXT: popq %rbx
479 ; ENABLE-NEXT: LBB6_4: ## %if.else
480 ; ENABLE-NEXT: movl %esi, %eax
481 ; ENABLE-NEXT: addl %esi, %eax
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
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
507 ; DISABLE-NEXT: ## InlineAsm End
508 ; DISABLE-NEXT: xorl %eax, %eax
509 ; DISABLE-NEXT: popq %rbx
511 ; DISABLE-NEXT: LBB6_4: ## %if.else
512 ; DISABLE-NEXT: movl %esi, %eax
513 ; DISABLE-NEXT: addl %esi, %eax
514 ; DISABLE-NEXT: popq %rbx
517 %tobool = icmp eq i32 %cond, 0
518 br i1 %tobool, label %if.else, label %for.preheader
521 tail call void asm "nop", ""()
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
532 tail call void asm "nop", ""()
535 if.else: ; preds = %entry
536 %mul = shl nsw i32 %N, 1
539 if.end: ; preds = %for.body, %if.else
540 %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ]
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
566 ; ENABLE-NEXT: LBB7_2: ## %if.else
567 ; ENABLE-NEXT: addl %eax, %eax
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
590 ; DISABLE-NEXT: LBB7_2: ## %if.else
591 ; DISABLE-NEXT: addl %eax, %eax
592 ; DISABLE-NEXT: popq %rcx
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
603 if.else: ; preds = %entry
604 %mul = shl nsw i32 %N, 1
607 if.end: ; preds = %if.else, %if.then
608 %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
612 declare i32 @someVariadicFunc(i32, ...)
614 ; Check that we use LEA not to clobber EFLAGS.
615 %struct.temp_slot = type { %struct.temp_slot*, %struct.rtx_def*, %struct.rtx_def*, i32, i64, %union.tree_node*, %union.tree_node*, i8, i8, i32, i32, i64, i64 }
616 %union.tree_node = type { %struct.tree_decl }
617 %struct.tree_decl = type { %struct.tree_common, i8*, i32, i32, %union.tree_node*, i48, %union.anon, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %struct.rtx_def*, %struct.rtx_def*, %union.anon.1, %union.tree_node*, %union.tree_node*, %union.tree_node*, i64, %struct.lang_decl* }
618 %struct.tree_common = type { %union.tree_node*, %union.tree_node*, i32 }
619 %union.anon = type { i64 }
620 %union.anon.1 = type { %struct.function* }
621 %struct.function = type { %struct.eh_status*, %struct.stmt_status*, %struct.expr_status*, %struct.emit_status*, %struct.varasm_status*, i8*, %union.tree_node*, %struct.function*, i32, i32, i32, i32, %struct.rtx_def*, %struct.ix86_args, %struct.rtx_def*, %struct.rtx_def*, i8*, %struct.initial_value_struct*, i32, %union.tree_node*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %union.tree_node*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, i64, %union.tree_node*, %union.tree_node*, %struct.rtx_def*, %struct.rtx_def*, i32, %struct.rtx_def**, %struct.temp_slot*, i32, i32, i32, %struct.var_refs_queue*, i32, i32, i8*, %union.tree_node*, %struct.rtx_def*, i32, i32, %struct.machine_function*, i32, i32, %struct.language_function*, %struct.rtx_def*, i24 }
622 %struct.eh_status = type opaque
623 %struct.stmt_status = type opaque
624 %struct.expr_status = type { i32, i32, i32, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def* }
625 %struct.emit_status = type { i32, i32, %struct.rtx_def*, %struct.rtx_def*, %union.tree_node*, %struct.sequence_stack*, i32, i32, i8*, i32, i8*, %union.tree_node**, %struct.rtx_def** }
626 %struct.sequence_stack = type { %struct.rtx_def*, %struct.rtx_def*, %union.tree_node*, %struct.sequence_stack* }
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 { %struct.rtx_def*, i32, i32, %struct.var_refs_queue* }
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 %struct.temp_slot* @find_temp_slot_from_address(%struct.rtx_def* readonly)
639 define void @useLEA(%struct.rtx_def* readonly %x) {
640 ; ENABLE-LABEL: useLEA:
641 ; ENABLE: ## %bb.0: ## %entry
642 ; ENABLE-NEXT: pushq %rax
643 ; ENABLE-NEXT: .cfi_def_cfa_offset 16
644 ; ENABLE-NEXT: testq %rdi, %rdi
645 ; ENABLE-NEXT: je LBB8_7
646 ; ENABLE-NEXT: ## %bb.1: ## %if.end
647 ; ENABLE-NEXT: cmpw $66, (%rdi)
648 ; ENABLE-NEXT: jne LBB8_7
649 ; ENABLE-NEXT: ## %bb.2: ## %lor.lhs.false
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.8: ## %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_7: ## %cleanup
660 ; ENABLE-NEXT: popq %rax
662 ; ENABLE-NEXT: LBB8_3: ## %lor.lhs.false
663 ; ENABLE-NEXT: cmpl $134, %eax
664 ; ENABLE-NEXT: je LBB8_7
665 ; ENABLE-NEXT: ## %bb.4: ## %lor.lhs.false
666 ; ENABLE-NEXT: cmpl $140, %eax
667 ; ENABLE-NEXT: je LBB8_7
668 ; ENABLE-NEXT: ## %bb.5: ## %if.end.55
669 ; ENABLE-NEXT: callq _find_temp_slot_from_address
670 ; ENABLE-NEXT: testq %rax, %rax
671 ; ENABLE-NEXT: je LBB8_7
672 ; ENABLE-NEXT: ## %bb.6: ## %if.then.60
673 ; ENABLE-NEXT: movb $1, 57(%rax)
674 ; ENABLE-NEXT: popq %rax
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
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
714 %cmp = icmp eq %struct.rtx_def* %x, null
715 br i1 %cmp, label %cleanup, label %if.end
717 if.end: ; preds = %entry
718 %tmp = getelementptr inbounds %struct.rtx_def, %struct.rtx_def* %x, i64 0, i32 0
719 %bf.load = load i32, i32* %tmp, align 8
720 %bf.clear = and i32 %bf.load, 65535
721 %cmp1 = icmp eq i32 %bf.clear, 66
722 br i1 %cmp1, label %lor.lhs.false, label %cleanup
724 lor.lhs.false: ; preds = %if.end
725 %arrayidx = getelementptr inbounds %struct.rtx_def, %struct.rtx_def* %x, i64 0, i32 1, i64 0
726 %rtx = bitcast %union.rtunion_def* %arrayidx to %struct.rtx_def**
727 %tmp1 = load %struct.rtx_def*, %struct.rtx_def** %rtx, align 8
728 %tmp2 = getelementptr inbounds %struct.rtx_def, %struct.rtx_def* %tmp1, i64 0, i32 0
729 %bf.load2 = load i32, i32* %tmp2, align 8
730 %bf.clear3 = and i32 %bf.load2, 65535
731 switch i32 %bf.clear3, label %if.end.55 [
732 i32 67, label %cleanup
733 i32 68, label %cleanup
734 i32 54, label %cleanup
735 i32 55, label %cleanup
736 i32 58, label %cleanup
737 i32 134, label %cleanup
738 i32 56, label %cleanup
739 i32 140, label %cleanup
742 if.end.55: ; preds = %lor.lhs.false
743 %call = tail call fastcc %struct.temp_slot* @find_temp_slot_from_address(%struct.rtx_def* %tmp1) #2
744 %cmp59 = icmp eq %struct.temp_slot* %call, null
745 br i1 %cmp59, label %cleanup, label %if.then.60
747 if.then.60: ; preds = %if.end.55
748 %addr_taken = getelementptr inbounds %struct.temp_slot, %struct.temp_slot* %call, i64 0, i32 8
749 store i8 1, i8* %addr_taken, align 1
752 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
756 ; Make sure we do not insert unreachable code after noreturn function.
757 ; Although this is not incorrect to insert such code, it is useless
758 ; and it hurts the binary size.
759 define i32 @noreturn(i8 signext %bad_thing) {
760 ; ENABLE-LABEL: noreturn:
761 ; ENABLE: ## %bb.0: ## %entry
762 ; ENABLE-NEXT: testb %dil, %dil
763 ; ENABLE-NEXT: jne LBB9_2
764 ; ENABLE-NEXT: ## %bb.1: ## %if.end
765 ; ENABLE-NEXT: movl $42, %eax
767 ; ENABLE-NEXT: LBB9_2: ## %if.abort
768 ; ENABLE-NEXT: pushq %rax
769 ; ENABLE-NEXT: .cfi_def_cfa_offset 16
770 ; ENABLE-NEXT: callq _abort
772 ; DISABLE-LABEL: noreturn:
773 ; DISABLE: ## %bb.0: ## %entry
774 ; DISABLE-NEXT: pushq %rax
775 ; DISABLE-NEXT: .cfi_def_cfa_offset 16
776 ; DISABLE-NEXT: testb %dil, %dil
777 ; DISABLE-NEXT: jne LBB9_2
778 ; DISABLE-NEXT: ## %bb.1: ## %if.end
779 ; DISABLE-NEXT: movl $42, %eax
780 ; DISABLE-NEXT: popq %rcx
782 ; DISABLE-NEXT: LBB9_2: ## %if.abort
783 ; DISABLE-NEXT: callq _abort
785 %tobool = icmp eq i8 %bad_thing, 0
786 br i1 %tobool, label %if.end, label %if.abort
789 tail call void @abort() #0
796 declare void @abort() #0
798 attributes #0 = { noreturn nounwind }
801 ; Make sure that we handle infinite loops properly When checking that the Save
802 ; and Restore blocks are control flow equivalent, the loop searches for the
803 ; immediate (post) dominator for the (restore) save blocks. When either the Save
804 ; or Restore block is located in an infinite loop the only immediate (post)
805 ; dominator is itself. In this case, we cannot perform shrink wrapping, but we
806 ; should return gracefully and continue compilation.
807 ; The only condition for this test is the compilation finishes correctly.
809 define void @infiniteloop() {
810 ; ENABLE-LABEL: infiniteloop:
811 ; ENABLE: ## %bb.0: ## %entry
812 ; ENABLE-NEXT: pushq %rbp
813 ; ENABLE-NEXT: .cfi_def_cfa_offset 16
814 ; ENABLE-NEXT: .cfi_offset %rbp, -16
815 ; ENABLE-NEXT: movq %rsp, %rbp
816 ; ENABLE-NEXT: .cfi_def_cfa_register %rbp
817 ; ENABLE-NEXT: pushq %rbx
818 ; ENABLE-NEXT: pushq %rax
819 ; ENABLE-NEXT: .cfi_offset %rbx, -24
820 ; ENABLE-NEXT: xorl %eax, %eax
821 ; ENABLE-NEXT: testb %al, %al
822 ; ENABLE-NEXT: jne LBB10_3
823 ; ENABLE-NEXT: ## %bb.1: ## %if.then
824 ; ENABLE-NEXT: movq %rsp, %rcx
825 ; ENABLE-NEXT: addq $-16, %rcx
826 ; ENABLE-NEXT: movq %rcx, %rsp
827 ; ENABLE-NEXT: ## InlineAsm Start
828 ; ENABLE-NEXT: movl $1, %edx
829 ; ENABLE-NEXT: ## InlineAsm End
830 ; ENABLE-NEXT: .p2align 4, 0x90
831 ; ENABLE-NEXT: LBB10_2: ## %for.body
832 ; ENABLE-NEXT: ## =>This Inner Loop Header: Depth=1
833 ; ENABLE-NEXT: addl %edx, %eax
834 ; ENABLE-NEXT: movl %eax, (%rcx)
835 ; ENABLE-NEXT: jmp LBB10_2
836 ; ENABLE-NEXT: LBB10_3: ## %if.end
837 ; ENABLE-NEXT: leaq -8(%rbp), %rsp
838 ; ENABLE-NEXT: popq %rbx
839 ; ENABLE-NEXT: popq %rbp
842 ; DISABLE-LABEL: infiniteloop:
843 ; DISABLE: ## %bb.0: ## %entry
844 ; DISABLE-NEXT: pushq %rbp
845 ; DISABLE-NEXT: .cfi_def_cfa_offset 16
846 ; DISABLE-NEXT: .cfi_offset %rbp, -16
847 ; DISABLE-NEXT: movq %rsp, %rbp
848 ; DISABLE-NEXT: .cfi_def_cfa_register %rbp
849 ; DISABLE-NEXT: pushq %rbx
850 ; DISABLE-NEXT: pushq %rax
851 ; DISABLE-NEXT: .cfi_offset %rbx, -24
852 ; DISABLE-NEXT: xorl %eax, %eax
853 ; DISABLE-NEXT: testb %al, %al
854 ; DISABLE-NEXT: jne LBB10_3
855 ; DISABLE-NEXT: ## %bb.1: ## %if.then
856 ; DISABLE-NEXT: movq %rsp, %rcx
857 ; DISABLE-NEXT: addq $-16, %rcx
858 ; DISABLE-NEXT: movq %rcx, %rsp
859 ; DISABLE-NEXT: ## InlineAsm Start
860 ; DISABLE-NEXT: movl $1, %edx
861 ; DISABLE-NEXT: ## InlineAsm End
862 ; DISABLE-NEXT: .p2align 4, 0x90
863 ; DISABLE-NEXT: LBB10_2: ## %for.body
864 ; DISABLE-NEXT: ## =>This Inner Loop Header: Depth=1
865 ; DISABLE-NEXT: addl %edx, %eax
866 ; DISABLE-NEXT: movl %eax, (%rcx)
867 ; DISABLE-NEXT: jmp LBB10_2
868 ; DISABLE-NEXT: LBB10_3: ## %if.end
869 ; DISABLE-NEXT: leaq -8(%rbp), %rsp
870 ; DISABLE-NEXT: popq %rbx
871 ; DISABLE-NEXT: popq %rbp
874 br i1 undef, label %if.then, label %if.end
877 %ptr = alloca i32, i32 4
880 for.body: ; preds = %for.body, %entry
881 %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
882 %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"()
883 %add = add nsw i32 %call, %sum.03
884 store i32 %add, i32* %ptr
891 ; Another infinite loop test this time with a body bigger than just one block.
892 define void @infiniteloop2() {
893 ; ENABLE-LABEL: infiniteloop2:
894 ; ENABLE: ## %bb.0: ## %entry
895 ; ENABLE-NEXT: pushq %rbp
896 ; ENABLE-NEXT: .cfi_def_cfa_offset 16
897 ; ENABLE-NEXT: .cfi_offset %rbp, -16
898 ; ENABLE-NEXT: movq %rsp, %rbp
899 ; ENABLE-NEXT: .cfi_def_cfa_register %rbp
900 ; ENABLE-NEXT: pushq %rbx
901 ; ENABLE-NEXT: pushq %rax
902 ; ENABLE-NEXT: .cfi_offset %rbx, -24
903 ; ENABLE-NEXT: xorl %eax, %eax
904 ; ENABLE-NEXT: testb %al, %al
905 ; ENABLE-NEXT: jne LBB11_5
906 ; ENABLE-NEXT: ## %bb.1: ## %if.then
907 ; ENABLE-NEXT: movq %rsp, %rcx
908 ; ENABLE-NEXT: addq $-16, %rcx
909 ; ENABLE-NEXT: movq %rcx, %rsp
910 ; ENABLE-NEXT: xorl %edx, %edx
911 ; ENABLE-NEXT: jmp LBB11_2
912 ; ENABLE-NEXT: .p2align 4, 0x90
913 ; ENABLE-NEXT: LBB11_4: ## %body2
914 ; ENABLE-NEXT: ## in Loop: Header=BB11_2 Depth=1
915 ; ENABLE-NEXT: ## InlineAsm Start
917 ; ENABLE-NEXT: ## InlineAsm End
918 ; ENABLE-NEXT: movl $1, %edx
919 ; ENABLE-NEXT: LBB11_2: ## %for.body
920 ; ENABLE-NEXT: ## =>This Inner Loop Header: Depth=1
921 ; ENABLE-NEXT: movl %edx, %esi
922 ; ENABLE-NEXT: ## InlineAsm Start
923 ; ENABLE-NEXT: movl $1, %edx
924 ; ENABLE-NEXT: ## InlineAsm End
925 ; ENABLE-NEXT: addl %esi, %edx
926 ; ENABLE-NEXT: movl %edx, (%rcx)
927 ; ENABLE-NEXT: testb %al, %al
928 ; ENABLE-NEXT: jne LBB11_4
929 ; ENABLE-NEXT: ## %bb.3: ## %body1
930 ; ENABLE-NEXT: ## in Loop: Header=BB11_2 Depth=1
931 ; ENABLE-NEXT: ## InlineAsm Start
933 ; ENABLE-NEXT: ## InlineAsm End
934 ; ENABLE-NEXT: jmp LBB11_2
935 ; ENABLE-NEXT: LBB11_5: ## %if.end
936 ; ENABLE-NEXT: leaq -8(%rbp), %rsp
937 ; ENABLE-NEXT: popq %rbx
938 ; ENABLE-NEXT: popq %rbp
941 ; DISABLE-LABEL: infiniteloop2:
942 ; DISABLE: ## %bb.0: ## %entry
943 ; DISABLE-NEXT: pushq %rbp
944 ; DISABLE-NEXT: .cfi_def_cfa_offset 16
945 ; DISABLE-NEXT: .cfi_offset %rbp, -16
946 ; DISABLE-NEXT: movq %rsp, %rbp
947 ; DISABLE-NEXT: .cfi_def_cfa_register %rbp
948 ; DISABLE-NEXT: pushq %rbx
949 ; DISABLE-NEXT: pushq %rax
950 ; DISABLE-NEXT: .cfi_offset %rbx, -24
951 ; DISABLE-NEXT: xorl %eax, %eax
952 ; DISABLE-NEXT: testb %al, %al
953 ; DISABLE-NEXT: jne LBB11_5
954 ; DISABLE-NEXT: ## %bb.1: ## %if.then
955 ; DISABLE-NEXT: movq %rsp, %rcx
956 ; DISABLE-NEXT: addq $-16, %rcx
957 ; DISABLE-NEXT: movq %rcx, %rsp
958 ; DISABLE-NEXT: xorl %edx, %edx
959 ; DISABLE-NEXT: jmp LBB11_2
960 ; DISABLE-NEXT: .p2align 4, 0x90
961 ; DISABLE-NEXT: LBB11_4: ## %body2
962 ; DISABLE-NEXT: ## in Loop: Header=BB11_2 Depth=1
963 ; DISABLE-NEXT: ## InlineAsm Start
965 ; DISABLE-NEXT: ## InlineAsm End
966 ; DISABLE-NEXT: movl $1, %edx
967 ; DISABLE-NEXT: LBB11_2: ## %for.body
968 ; DISABLE-NEXT: ## =>This Inner Loop Header: Depth=1
969 ; DISABLE-NEXT: movl %edx, %esi
970 ; DISABLE-NEXT: ## InlineAsm Start
971 ; DISABLE-NEXT: movl $1, %edx
972 ; DISABLE-NEXT: ## InlineAsm End
973 ; DISABLE-NEXT: addl %esi, %edx
974 ; DISABLE-NEXT: movl %edx, (%rcx)
975 ; DISABLE-NEXT: testb %al, %al
976 ; DISABLE-NEXT: jne LBB11_4
977 ; DISABLE-NEXT: ## %bb.3: ## %body1
978 ; DISABLE-NEXT: ## in Loop: Header=BB11_2 Depth=1
979 ; DISABLE-NEXT: ## InlineAsm Start
981 ; DISABLE-NEXT: ## InlineAsm End
982 ; DISABLE-NEXT: jmp LBB11_2
983 ; DISABLE-NEXT: LBB11_5: ## %if.end
984 ; DISABLE-NEXT: leaq -8(%rbp), %rsp
985 ; DISABLE-NEXT: popq %rbx
986 ; DISABLE-NEXT: popq %rbp
989 br i1 undef, label %if.then, label %if.end
992 %ptr = alloca i32, i32 4
995 for.body: ; preds = %for.body, %entry
996 %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2]
997 %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"()
998 %add = add nsw i32 %call, %sum.03
999 store i32 %add, i32* %ptr
1000 br i1 undef, label %body1, label %body2
1003 tail call void asm sideeffect "nop", "~{ebx}"()
1007 tail call void asm sideeffect "nop", "~{ebx}"()
1014 ; Another infinite loop test this time with two nested infinite loop.
1015 define void @infiniteloop3() {
1016 ; ENABLE-LABEL: infiniteloop3:
1017 ; ENABLE: ## %bb.0: ## %entry
1018 ; ENABLE-NEXT: xorl %eax, %eax
1019 ; ENABLE-NEXT: testb %al, %al
1020 ; ENABLE-NEXT: jne LBB12_2
1021 ; ENABLE-NEXT: ## %bb.1: ## %body
1022 ; ENABLE-NEXT: xorl %eax, %eax
1023 ; ENABLE-NEXT: testb %al, %al
1024 ; ENABLE-NEXT: jne LBB12_7
1025 ; ENABLE-NEXT: LBB12_2: ## %loop2a.preheader
1026 ; ENABLE-NEXT: xorl %eax, %eax
1027 ; ENABLE-NEXT: xorl %ecx, %ecx
1028 ; ENABLE-NEXT: movq %rax, %rsi
1029 ; ENABLE-NEXT: jmp LBB12_4
1030 ; ENABLE-NEXT: .p2align 4, 0x90
1031 ; ENABLE-NEXT: LBB12_3: ## %loop2b
1032 ; ENABLE-NEXT: ## in Loop: Header=BB12_4 Depth=1
1033 ; ENABLE-NEXT: movq %rdx, (%rsi)
1034 ; ENABLE-NEXT: movq %rdx, %rsi
1035 ; ENABLE-NEXT: LBB12_4: ## %loop1
1036 ; ENABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1037 ; ENABLE-NEXT: movq %rcx, %rdx
1038 ; ENABLE-NEXT: testq %rax, %rax
1039 ; ENABLE-NEXT: movq (%rax), %rcx
1040 ; ENABLE-NEXT: jne LBB12_3
1041 ; ENABLE-NEXT: ## %bb.5: ## in Loop: Header=BB12_4 Depth=1
1042 ; ENABLE-NEXT: movq %rdx, %rax
1043 ; ENABLE-NEXT: movq %rdx, %rsi
1044 ; ENABLE-NEXT: jmp LBB12_4
1045 ; ENABLE-NEXT: LBB12_7: ## %end
1048 ; DISABLE-LABEL: infiniteloop3:
1049 ; DISABLE: ## %bb.0: ## %entry
1050 ; DISABLE-NEXT: xorl %eax, %eax
1051 ; DISABLE-NEXT: testb %al, %al
1052 ; DISABLE-NEXT: jne LBB12_2
1053 ; DISABLE-NEXT: ## %bb.1: ## %body
1054 ; DISABLE-NEXT: xorl %eax, %eax
1055 ; DISABLE-NEXT: testb %al, %al
1056 ; DISABLE-NEXT: jne LBB12_7
1057 ; DISABLE-NEXT: LBB12_2: ## %loop2a.preheader
1058 ; DISABLE-NEXT: xorl %eax, %eax
1059 ; DISABLE-NEXT: xorl %ecx, %ecx
1060 ; DISABLE-NEXT: movq %rax, %rsi
1061 ; DISABLE-NEXT: jmp LBB12_4
1062 ; DISABLE-NEXT: .p2align 4, 0x90
1063 ; DISABLE-NEXT: LBB12_3: ## %loop2b
1064 ; DISABLE-NEXT: ## in Loop: Header=BB12_4 Depth=1
1065 ; DISABLE-NEXT: movq %rdx, (%rsi)
1066 ; DISABLE-NEXT: movq %rdx, %rsi
1067 ; DISABLE-NEXT: LBB12_4: ## %loop1
1068 ; DISABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1069 ; DISABLE-NEXT: movq %rcx, %rdx
1070 ; DISABLE-NEXT: testq %rax, %rax
1071 ; DISABLE-NEXT: movq (%rax), %rcx
1072 ; DISABLE-NEXT: jne LBB12_3
1073 ; DISABLE-NEXT: ## %bb.5: ## in Loop: Header=BB12_4 Depth=1
1074 ; DISABLE-NEXT: movq %rdx, %rax
1075 ; DISABLE-NEXT: movq %rdx, %rsi
1076 ; DISABLE-NEXT: jmp LBB12_4
1077 ; DISABLE-NEXT: LBB12_7: ## %end
1078 ; DISABLE-NEXT: retq
1080 br i1 undef, label %loop2a, label %body
1082 body: ; preds = %entry
1083 br i1 undef, label %loop2a, label %end
1085 loop1: ; preds = %loop2a, %loop2b
1086 %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ]
1087 %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ]
1088 %0 = icmp eq i32* %var, null
1089 %next.load = load i32*, i32** undef
1090 br i1 %0, label %loop2a, label %loop2b
1092 loop2a: ; preds = %loop1, %body, %entry
1093 %var = phi i32* [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ]
1094 %next.var = phi i32* [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ]
1097 loop2b: ; preds = %loop1
1098 %gep1 = bitcast i32* %var.phi to i32*
1099 %next.ptr = bitcast i32* %gep1 to i32**
1100 store i32* %next.phi, i32** %next.ptr
1107 ; Check that we just don't bail out on RegMask.
1108 ; In this case, the RegMask does not touch a CSR so we are good to go!
1109 define i32 @regmask(i32 %a, i32 %b, i32* %addr) {
1110 ; ENABLE-LABEL: regmask:
1112 ; ENABLE-NEXT: cmpl %esi, %edi
1113 ; ENABLE-NEXT: jge LBB13_2
1114 ; ENABLE-NEXT: ## %bb.1: ## %true
1115 ; ENABLE-NEXT: pushq %rbx
1116 ; ENABLE-NEXT: .cfi_def_cfa_offset 16
1117 ; ENABLE-NEXT: .cfi_offset %rbx, -16
1118 ; ENABLE-NEXT: ## InlineAsm Start
1120 ; ENABLE-NEXT: ## InlineAsm End
1121 ; ENABLE-NEXT: xorl %edi, %edi
1122 ; ENABLE-NEXT: movq %rdx, %rsi
1123 ; ENABLE-NEXT: callq _doSomething
1124 ; ENABLE-NEXT: popq %rbx
1126 ; ENABLE-NEXT: LBB13_2: ## %false
1127 ; ENABLE-NEXT: movl $6, %edi
1128 ; ENABLE-NEXT: movq %rdx, %rsi
1129 ; ENABLE-NEXT: jmp _doSomething ## TAILCALL
1131 ; DISABLE-LABEL: regmask:
1132 ; DISABLE: ## %bb.0:
1133 ; DISABLE-NEXT: pushq %rbx
1134 ; DISABLE-NEXT: .cfi_def_cfa_offset 16
1135 ; DISABLE-NEXT: .cfi_offset %rbx, -16
1136 ; DISABLE-NEXT: cmpl %esi, %edi
1137 ; DISABLE-NEXT: jge LBB13_2
1138 ; DISABLE-NEXT: ## %bb.1: ## %true
1139 ; DISABLE-NEXT: ## InlineAsm Start
1141 ; DISABLE-NEXT: ## InlineAsm End
1142 ; DISABLE-NEXT: xorl %edi, %edi
1143 ; DISABLE-NEXT: movq %rdx, %rsi
1144 ; DISABLE-NEXT: callq _doSomething
1145 ; DISABLE-NEXT: popq %rbx
1146 ; DISABLE-NEXT: retq
1147 ; DISABLE-NEXT: LBB13_2: ## %false
1148 ; DISABLE-NEXT: movl $6, %edi
1149 ; DISABLE-NEXT: movq %rdx, %rsi
1150 ; DISABLE-NEXT: popq %rbx
1151 ; DISABLE-NEXT: jmp _doSomething ## TAILCALL
1152 %tmp2 = icmp slt i32 %a, %b
1153 br i1 %tmp2, label %true, label %false
1156 ; Clobber a CSR so that we check something on the regmask
1158 tail call void asm sideeffect "nop", "~{ebx}"()
1159 %tmp4 = call i32 @doSomething(i32 0, i32* %addr)
1163 %tmp5 = tail call i32 @doSomething(i32 6, i32* %addr)
1167 %tmp.0 = phi i32 [ %tmp4, %true ], [ %tmp5, %false ]
1171 @b = internal unnamed_addr global i1 false
1172 @c = internal unnamed_addr global i8 0, align 1
1173 @a = common global i32 0, align 4
1175 ; Make sure the prologue does not clobber the EFLAGS when
1176 ; it is live accross.
1178 ; Note: The registers may change in the following patterns, but
1179 ; because they imply register hierarchy (e.g., eax, al) this is
1180 ; tricky to write robust patterns.
1181 define i32 @useLEAForPrologue(i32 %d, i32 %a, i8 %c) #3 {
1182 ; ENABLE-LABEL: useLEAForPrologue:
1183 ; ENABLE: ## %bb.0: ## %entry
1184 ; ENABLE-NEXT: pushq %rbx
1185 ; ENABLE-NEXT: subq $16, %rsp
1186 ; ENABLE-NEXT: xorl %eax, %eax
1187 ; ENABLE-NEXT: cmpb $0, {{.*}}(%rip)
1188 ; ENABLE-NEXT: movl $48, %ecx
1189 ; ENABLE-NEXT: cmovnel %eax, %ecx
1190 ; ENABLE-NEXT: movb %cl, {{.*}}(%rip)
1191 ; ENABLE-NEXT: je LBB14_4
1192 ; ENABLE-NEXT: ## %bb.1: ## %for.body.lr.ph
1193 ; ENABLE-NEXT: ## InlineAsm Start
1195 ; ENABLE-NEXT: ## InlineAsm End
1196 ; ENABLE-NEXT: .p2align 4, 0x90
1197 ; ENABLE-NEXT: LBB14_2: ## %for.body
1198 ; ENABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1199 ; ENABLE-NEXT: cmpl %esi, %edi
1200 ; ENABLE-NEXT: setl %al
1201 ; ENABLE-NEXT: xorl %esi, %esi
1202 ; ENABLE-NEXT: movb %al, %sil
1203 ; ENABLE-NEXT: incb %dl
1204 ; ENABLE-NEXT: cmpb $45, %dl
1205 ; ENABLE-NEXT: jl LBB14_2
1206 ; ENABLE-NEXT: ## %bb.3: ## %for.cond.for.end_crit_edge
1207 ; ENABLE-NEXT: movq _a@{{.*}}(%rip), %rax
1208 ; ENABLE-NEXT: movl %esi, (%rax)
1209 ; ENABLE-NEXT: LBB14_4: ## %for.end
1210 ; ENABLE-NEXT: xorl %edi, %edi
1211 ; ENABLE-NEXT: callq _varfunc
1212 ; ENABLE-NEXT: xorl %eax, %eax
1213 ; ENABLE-NEXT: addq $16, %rsp
1214 ; ENABLE-NEXT: popq %rbx
1217 ; DISABLE-LABEL: useLEAForPrologue:
1218 ; DISABLE: ## %bb.0: ## %entry
1219 ; DISABLE-NEXT: pushq %rbx
1220 ; DISABLE-NEXT: subq $16, %rsp
1221 ; DISABLE-NEXT: xorl %eax, %eax
1222 ; DISABLE-NEXT: cmpb $0, {{.*}}(%rip)
1223 ; DISABLE-NEXT: movl $48, %ecx
1224 ; DISABLE-NEXT: cmovnel %eax, %ecx
1225 ; DISABLE-NEXT: movb %cl, {{.*}}(%rip)
1226 ; DISABLE-NEXT: je LBB14_4
1227 ; DISABLE-NEXT: ## %bb.1: ## %for.body.lr.ph
1228 ; DISABLE-NEXT: ## InlineAsm Start
1230 ; DISABLE-NEXT: ## InlineAsm End
1231 ; DISABLE-NEXT: .p2align 4, 0x90
1232 ; DISABLE-NEXT: LBB14_2: ## %for.body
1233 ; DISABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1234 ; DISABLE-NEXT: cmpl %esi, %edi
1235 ; DISABLE-NEXT: setl %al
1236 ; DISABLE-NEXT: xorl %esi, %esi
1237 ; DISABLE-NEXT: movb %al, %sil
1238 ; DISABLE-NEXT: incb %dl
1239 ; DISABLE-NEXT: cmpb $45, %dl
1240 ; DISABLE-NEXT: jl LBB14_2
1241 ; DISABLE-NEXT: ## %bb.3: ## %for.cond.for.end_crit_edge
1242 ; DISABLE-NEXT: movq _a@{{.*}}(%rip), %rax
1243 ; DISABLE-NEXT: movl %esi, (%rax)
1244 ; DISABLE-NEXT: LBB14_4: ## %for.end
1245 ; DISABLE-NEXT: xorl %edi, %edi
1246 ; DISABLE-NEXT: callq _varfunc
1247 ; DISABLE-NEXT: xorl %eax, %eax
1248 ; DISABLE-NEXT: addq $16, %rsp
1249 ; DISABLE-NEXT: popq %rbx
1250 ; DISABLE-NEXT: retq
1253 %.b = load i1, i1* @b, align 1
1254 %bool = select i1 %.b, i8 0, i8 48
1255 store i8 %bool, i8* @c, align 1
1256 br i1 %.b, label %for.body.lr.ph, label %for.end
1258 for.body.lr.ph: ; preds = %entry
1259 tail call void asm sideeffect "nop", "~{ebx}"()
1262 for.body: ; preds = %for.body.lr.ph, %for.body
1263 %inc6 = phi i8 [ %c, %for.body.lr.ph ], [ %inc, %for.body ]
1264 %cond5 = phi i32 [ %a, %for.body.lr.ph ], [ %conv3, %for.body ]
1265 %cmp2 = icmp slt i32 %d, %cond5
1266 %conv3 = zext i1 %cmp2 to i32
1267 %inc = add i8 %inc6, 1
1268 %cmp = icmp slt i8 %inc, 45
1269 br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
1271 for.cond.for.end_crit_edge: ; preds = %for.body
1272 store i32 %conv3, i32* @a, align 4
1275 for.end: ; preds = %for.cond.for.end_crit_edge, %entry
1276 %call = tail call i32 (i8*) @varfunc(i8* null)
1280 declare i32 @varfunc(i8* nocapture readonly)
1282 @sum1 = external hidden thread_local global i32, align 4
1285 ; Function Attrs: nounwind
1286 ; Make sure the TLS call used to access @sum1 happens after the prologue
1287 ; and before the epilogue.
1288 ; TLS calls used to be wrongly model and shrink-wrapping would have inserted
1289 ; the prologue and epilogue just around the call to doSomething.
1291 define i32 @tlsCall(i1 %bool1, i32 %arg, i32* readonly dereferenceable(4) %sum1) #3 {
1292 ; ENABLE-LABEL: tlsCall:
1293 ; ENABLE: ## %bb.0: ## %entry
1294 ; ENABLE-NEXT: pushq %rax
1295 ; ENABLE-NEXT: testb $1, %dil
1296 ; ENABLE-NEXT: je LBB15_2
1297 ; ENABLE-NEXT: ## %bb.1: ## %master
1298 ; ENABLE-NEXT: movl (%rdx), %ecx
1299 ; ENABLE-NEXT: movq _sum1@{{.*}}(%rip), %rdi
1300 ; ENABLE-NEXT: callq *(%rdi)
1301 ; ENABLE-NEXT: movl %ecx, (%rax)
1302 ; ENABLE-NEXT: jmp LBB15_3
1303 ; ENABLE-NEXT: LBB15_2: ## %else
1304 ; ENABLE-NEXT: xorl %edi, %edi
1305 ; ENABLE-NEXT: xorl %esi, %esi
1306 ; ENABLE-NEXT: callq _doSomething
1307 ; ENABLE-NEXT: movl %eax, %esi
1308 ; ENABLE-NEXT: LBB15_3: ## %exit
1309 ; ENABLE-NEXT: movl %esi, %eax
1310 ; ENABLE-NEXT: popq %rcx
1313 ; DISABLE-LABEL: tlsCall:
1314 ; DISABLE: ## %bb.0: ## %entry
1315 ; DISABLE-NEXT: pushq %rax
1316 ; DISABLE-NEXT: testb $1, %dil
1317 ; DISABLE-NEXT: je LBB15_2
1318 ; DISABLE-NEXT: ## %bb.1: ## %master
1319 ; DISABLE-NEXT: movl (%rdx), %ecx
1320 ; DISABLE-NEXT: movq _sum1@{{.*}}(%rip), %rdi
1321 ; DISABLE-NEXT: callq *(%rdi)
1322 ; DISABLE-NEXT: movl %ecx, (%rax)
1323 ; DISABLE-NEXT: jmp LBB15_3
1324 ; DISABLE-NEXT: LBB15_2: ## %else
1325 ; DISABLE-NEXT: xorl %edi, %edi
1326 ; DISABLE-NEXT: xorl %esi, %esi
1327 ; DISABLE-NEXT: callq _doSomething
1328 ; DISABLE-NEXT: movl %eax, %esi
1329 ; DISABLE-NEXT: LBB15_3: ## %exit
1330 ; DISABLE-NEXT: movl %esi, %eax
1331 ; DISABLE-NEXT: popq %rcx
1332 ; DISABLE-NEXT: retq
1334 br i1 %bool1, label %master, label %else
1337 %tmp1 = load i32, i32* %sum1, align 4
1338 store i32 %tmp1, i32* @sum1, align 4
1342 %call = call i32 @doSomething(i32 0, i32* null)
1346 %res = phi i32 [ %arg, %master], [ %call, %else ]
1350 attributes #3 = { nounwind }
1352 @irreducibleCFGa = common global i32 0, align 4
1353 @irreducibleCFGf = common global i8 0, align 1
1354 @irreducibleCFGb = common global i32 0, align 4
1356 ; Check that we do not run shrink-wrapping on irreducible CFGs until
1357 ; it is actually supported.
1358 ; At the moment, on those CFGs the loop information may be incorrect
1359 ; and since we use that information to do the placement, we may end up
1360 ; inserting the prologue/epilogue at incorrect places.
1362 ; Make sure we emit missed optimization remarks for this.
1363 ; REMARKS: Pass: shrink-wrap
1364 ; REMARKS-NEXT: Name: UnsupportedIrreducibleCFG
1365 ; REMARKS-NEXT: Function: irreducibleCFG
1366 ; REMARKS-NEXT: Args:
1367 ; REMARKS-NEXT: - String: Irreducible CFGs are not supported yet
1369 define i32 @irreducibleCFG() #4 {
1370 ; ENABLE-LABEL: irreducibleCFG:
1371 ; ENABLE: ## %bb.0: ## %entry
1372 ; ENABLE-NEXT: pushq %rbp
1373 ; ENABLE-NEXT: .cfi_def_cfa_offset 16
1374 ; ENABLE-NEXT: .cfi_offset %rbp, -16
1375 ; ENABLE-NEXT: movq %rsp, %rbp
1376 ; ENABLE-NEXT: .cfi_def_cfa_register %rbp
1377 ; ENABLE-NEXT: pushq %rbx
1378 ; ENABLE-NEXT: pushq %rax
1379 ; ENABLE-NEXT: .cfi_offset %rbx, -24
1380 ; ENABLE-NEXT: movq _irreducibleCFGf@{{.*}}(%rip), %rax
1381 ; ENABLE-NEXT: cmpb $0, (%rax)
1382 ; ENABLE-NEXT: je LBB16_2
1383 ; ENABLE-NEXT: .p2align 4, 0x90
1384 ; ENABLE-NEXT: LBB16_1: ## %preheader
1385 ; ENABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1386 ; ENABLE-NEXT: jmp LBB16_1
1387 ; ENABLE-NEXT: LBB16_2: ## %split
1388 ; ENABLE-NEXT: movq _irreducibleCFGb@{{.*}}(%rip), %rax
1389 ; ENABLE-NEXT: cmpl $0, (%rax)
1390 ; ENABLE-NEXT: je LBB16_3
1391 ; ENABLE-NEXT: ## %bb.4: ## %for.body4.i
1392 ; ENABLE-NEXT: movq _irreducibleCFGa@{{.*}}(%rip), %rax
1393 ; ENABLE-NEXT: movl (%rax), %edi
1394 ; ENABLE-NEXT: xorl %ebx, %ebx
1395 ; ENABLE-NEXT: xorl %eax, %eax
1396 ; ENABLE-NEXT: callq _something
1397 ; ENABLE-NEXT: jmp LBB16_5
1398 ; ENABLE-NEXT: LBB16_3:
1399 ; ENABLE-NEXT: xorl %ebx, %ebx
1400 ; ENABLE-NEXT: .p2align 4, 0x90
1401 ; ENABLE-NEXT: LBB16_5: ## %for.inc
1402 ; ENABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1403 ; ENABLE-NEXT: incl %ebx
1404 ; ENABLE-NEXT: cmpl $7, %ebx
1405 ; ENABLE-NEXT: jl LBB16_5
1406 ; ENABLE-NEXT: ## %bb.6: ## %fn1.exit
1407 ; ENABLE-NEXT: xorl %eax, %eax
1408 ; ENABLE-NEXT: addq $8, %rsp
1409 ; ENABLE-NEXT: popq %rbx
1410 ; ENABLE-NEXT: popq %rbp
1413 ; DISABLE-LABEL: irreducibleCFG:
1414 ; DISABLE: ## %bb.0: ## %entry
1415 ; DISABLE-NEXT: pushq %rbp
1416 ; DISABLE-NEXT: .cfi_def_cfa_offset 16
1417 ; DISABLE-NEXT: .cfi_offset %rbp, -16
1418 ; DISABLE-NEXT: movq %rsp, %rbp
1419 ; DISABLE-NEXT: .cfi_def_cfa_register %rbp
1420 ; DISABLE-NEXT: pushq %rbx
1421 ; DISABLE-NEXT: pushq %rax
1422 ; DISABLE-NEXT: .cfi_offset %rbx, -24
1423 ; DISABLE-NEXT: movq _irreducibleCFGf@{{.*}}(%rip), %rax
1424 ; DISABLE-NEXT: cmpb $0, (%rax)
1425 ; DISABLE-NEXT: je LBB16_2
1426 ; DISABLE-NEXT: .p2align 4, 0x90
1427 ; DISABLE-NEXT: LBB16_1: ## %preheader
1428 ; DISABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1429 ; DISABLE-NEXT: jmp LBB16_1
1430 ; DISABLE-NEXT: LBB16_2: ## %split
1431 ; DISABLE-NEXT: movq _irreducibleCFGb@{{.*}}(%rip), %rax
1432 ; DISABLE-NEXT: cmpl $0, (%rax)
1433 ; DISABLE-NEXT: je LBB16_3
1434 ; DISABLE-NEXT: ## %bb.4: ## %for.body4.i
1435 ; DISABLE-NEXT: movq _irreducibleCFGa@{{.*}}(%rip), %rax
1436 ; DISABLE-NEXT: movl (%rax), %edi
1437 ; DISABLE-NEXT: xorl %ebx, %ebx
1438 ; DISABLE-NEXT: xorl %eax, %eax
1439 ; DISABLE-NEXT: callq _something
1440 ; DISABLE-NEXT: jmp LBB16_5
1441 ; DISABLE-NEXT: LBB16_3:
1442 ; DISABLE-NEXT: xorl %ebx, %ebx
1443 ; DISABLE-NEXT: .p2align 4, 0x90
1444 ; DISABLE-NEXT: LBB16_5: ## %for.inc
1445 ; DISABLE-NEXT: ## =>This Inner Loop Header: Depth=1
1446 ; DISABLE-NEXT: incl %ebx
1447 ; DISABLE-NEXT: cmpl $7, %ebx
1448 ; DISABLE-NEXT: jl LBB16_5
1449 ; DISABLE-NEXT: ## %bb.6: ## %fn1.exit
1450 ; DISABLE-NEXT: xorl %eax, %eax
1451 ; DISABLE-NEXT: addq $8, %rsp
1452 ; DISABLE-NEXT: popq %rbx
1453 ; DISABLE-NEXT: popq %rbp
1454 ; DISABLE-NEXT: retq
1456 %i0 = load i32, i32* @irreducibleCFGa, align 4
1457 %.pr = load i8, i8* @irreducibleCFGf, align 1
1458 %bool = icmp eq i8 %.pr, 0
1459 br i1 %bool, label %split, label %preheader
1465 %i1 = load i32, i32* @irreducibleCFGb, align 4
1466 %tobool1.i = icmp ne i32 %i1, 0
1467 br i1 %tobool1.i, label %for.body4.i, label %for.cond8.i.preheader
1470 %call.i = tail call i32 (...) @something(i32 %i0)
1474 %p1 = phi i32 [ %inc18.i, %for.inc ], [ 0, %for.body4.i ]
1475 %.pr1.pr = load i32, i32* @irreducibleCFGb, align 4
1476 br label %for.cond8.i.preheader
1478 for.cond8.i.preheader:
1479 %.pr1 = phi i32 [ %.pr1.pr, %for.cond8 ], [ %i1, %split ]
1480 %p13 = phi i32 [ %p1, %for.cond8 ], [ 0, %split ]
1487 %inc18.i = add nuw nsw i32 %p13, 1
1488 %cmp = icmp slt i32 %inc18.i, 7
1489 br i1 %cmp, label %for.cond8, label %fn1.exit
1492 attributes #4 = { "no-frame-pointer-elim"="true" }
1494 @x = external global i32, align 4
1495 @y = external global i32, align 4
1497 ; The post-dominator tree does not include the branch containing the infinite
1498 ; loop, which can occur into a misplacement of the restore block, if we're
1499 ; looking for the nearest common post-dominator of an "unreachable" block.
1501 define void @infiniteLoopNoSuccessor() #5 {
1502 ; ENABLE-LABEL: infiniteLoopNoSuccessor:
1504 ; ENABLE-NEXT: pushq %rbp
1505 ; ENABLE-NEXT: movq %rsp, %rbp
1506 ; ENABLE-NEXT: movq _x@{{.*}}(%rip), %rax
1507 ; ENABLE-NEXT: cmpl $0, (%rax)
1508 ; ENABLE-NEXT: je LBB17_2
1509 ; ENABLE-NEXT: ## %bb.1:
1510 ; ENABLE-NEXT: movl $0, (%rax)
1511 ; ENABLE-NEXT: LBB17_2:
1512 ; ENABLE-NEXT: xorl %eax, %eax
1513 ; ENABLE-NEXT: callq _somethingElse
1514 ; ENABLE-NEXT: movq _y@{{.*}}(%rip), %rax
1515 ; ENABLE-NEXT: cmpl $0, (%rax)
1516 ; ENABLE-NEXT: je LBB17_3
1517 ; ENABLE-NEXT: ## %bb.5:
1518 ; ENABLE-NEXT: popq %rbp
1520 ; ENABLE-NEXT: LBB17_3:
1521 ; ENABLE-NEXT: xorl %eax, %eax
1522 ; ENABLE-NEXT: callq _something
1523 ; ENABLE-NEXT: .p2align 4, 0x90
1524 ; ENABLE-NEXT: LBB17_4: ## =>This Inner Loop Header: Depth=1
1525 ; ENABLE-NEXT: xorl %eax, %eax
1526 ; ENABLE-NEXT: callq _somethingElse
1527 ; ENABLE-NEXT: jmp LBB17_4
1529 ; DISABLE-LABEL: infiniteLoopNoSuccessor:
1530 ; DISABLE: ## %bb.0:
1531 ; DISABLE-NEXT: pushq %rbp
1532 ; DISABLE-NEXT: movq %rsp, %rbp
1533 ; DISABLE-NEXT: movq _x@{{.*}}(%rip), %rax
1534 ; DISABLE-NEXT: cmpl $0, (%rax)
1535 ; DISABLE-NEXT: je LBB17_2
1536 ; DISABLE-NEXT: ## %bb.1:
1537 ; DISABLE-NEXT: movl $0, (%rax)
1538 ; DISABLE-NEXT: LBB17_2:
1539 ; DISABLE-NEXT: xorl %eax, %eax
1540 ; DISABLE-NEXT: callq _somethingElse
1541 ; DISABLE-NEXT: movq _y@{{.*}}(%rip), %rax
1542 ; DISABLE-NEXT: cmpl $0, (%rax)
1543 ; DISABLE-NEXT: je LBB17_3
1544 ; DISABLE-NEXT: ## %bb.5:
1545 ; DISABLE-NEXT: popq %rbp
1546 ; DISABLE-NEXT: retq
1547 ; DISABLE-NEXT: LBB17_3:
1548 ; DISABLE-NEXT: xorl %eax, %eax
1549 ; DISABLE-NEXT: callq _something
1550 ; DISABLE-NEXT: .p2align 4, 0x90
1551 ; DISABLE-NEXT: LBB17_4: ## =>This Inner Loop Header: Depth=1
1552 ; DISABLE-NEXT: xorl %eax, %eax
1553 ; DISABLE-NEXT: callq _somethingElse
1554 ; DISABLE-NEXT: jmp LBB17_4
1555 %1 = load i32, i32* @x, align 4
1556 %2 = icmp ne i32 %1, 0
1557 br i1 %2, label %3, label %4
1560 store i32 0, i32* @x, align 4
1564 call void (...) @somethingElse()
1565 %5 = load i32, i32* @y, align 4
1566 %6 = icmp ne i32 %5, 0
1567 br i1 %6, label %10, label %7
1570 %8 = call i32 (...) @something()
1574 call void (...) @somethingElse()
1581 declare void @somethingElse(...)
1583 attributes #5 = { nounwind "no-frame-pointer-elim-non-leaf" }