xref: /llvm-project/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll (revision 2b63077cfa13095b3e64f79fe825cc85ca9da7be)
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
5;
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.
12target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
13target triple = "x86_64-apple-macosx"
14
15
16; Initial motivating example: Simple diamond with a call just on one side.
17define 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
33;
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
52
53true:
54  store i32 %a, ptr %tmp, align 4
55  %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
56  br label %false
57
58false:
59  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
60  ret i32 %tmp.0
61}
62
63; Function Attrs: optsize
64declare i32 @doSomething(i32, ptr)
65
66
67; Check that we do not perform the restore inside the loop whereas the save
68; is outside.
69define 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
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
100;
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
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
132entry:
133  %tobool = icmp eq i32 %cond, 0
134  br i1 %tobool, label %if.else, label %for.preheader
135
136for.preheader:
137  tail call void asm "nop", ""()
138  br label %for.body
139
140for.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
148
149for.end:                                          ; preds = %for.body
150  %shl = shl i32 %add, 3
151  br label %if.end
152
153if.else:                                          ; preds = %entry
154  %mul = shl nsw i32 %N, 1
155  br label %if.end
156
157if.end:                                           ; preds = %if.else, %for.end
158  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
159  ret i32 %sum.1
160}
161
162declare i32 @something(...)
163
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.
166define 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
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
192;
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
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
218entry:
219  br label %for.preheader
220
221for.preheader:
222  tail call void asm "nop", ""()
223  br label %for.body
224
225for.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
233
234for.exit:
235  tail call void asm "nop", ""()
236  br label %for.end
237
238for.end:                                          ; preds = %for.body
239  ret i32 %add
240}
241
242; Check with a more complex case that we do not have save within the loop and
243; restore outside.
244define 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
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
278;
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
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
313entry:
314  %tobool = icmp eq i32 %cond, 0
315  br i1 %tobool, label %if.else, label %for.preheader
316
317for.preheader:
318  tail call void asm "nop", ""()
319  br label %for.body
320
321for.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
329
330for.end:                                          ; preds = %for.body
331  tail call void asm "nop", "~{ebx}"()
332  %shl = shl i32 %add, 3
333  br label %if.end
334
335if.else:                                          ; preds = %entry
336  %mul = shl nsw i32 %N, 1
337  br label %if.end
338
339if.end:                                           ; preds = %if.else, %for.end
340  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
341  ret i32 %sum.1
342}
343
344; Check with a more complex case that we do not have restore within the loop and
345; save outside.
346define 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
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
375;
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
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
405entry:
406  %tobool = icmp eq i32 %cond, 0
407  br i1 %tobool, label %if.else, label %if.then
408
409if.then:                                          ; preds = %entry
410  tail call void asm "nop", "~{ebx}"()
411  br label %for.body
412
413for.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
421
422for.end:                                          ; preds = %for.body
423  %shl = shl i32 %add, 3
424  br label %if.end
425
426if.else:                                          ; preds = %entry
427  %mul = shl nsw i32 %N, 1
428  br label %if.end
429
430if.end:                                           ; preds = %if.else, %for.end
431  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
432  ret i32 %sum.1
433}
434
435; Check that we handle function with no frame information correctly.
436define i32 @emptyFrame() {
437; ENABLE-LABEL: emptyFrame:
438; ENABLE:       ## %bb.0: ## %entry
439; ENABLE-NEXT:    xorl %eax, %eax
440; ENABLE-NEXT:    retq
441;
442; DISABLE-LABEL: emptyFrame:
443; DISABLE:       ## %bb.0: ## %entry
444; DISABLE-NEXT:    xorl %eax, %eax
445; DISABLE-NEXT:    retq
446entry:
447  ret i32 0
448}
449
450; Check that we handle inline asm correctly.
451define 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
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
483;
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
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
516entry:
517  %tobool = icmp eq i32 %cond, 0
518  br i1 %tobool, label %if.else, label %for.preheader
519
520for.preheader:
521  tail call void asm "nop", ""()
522  br label %for.body
523
524for.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
530
531for.exit:
532  tail call void asm "nop", ""()
533  br label %if.end
534
535if.else:                                          ; preds = %entry
536  %mul = shl nsw i32 %N, 1
537  br label %if.end
538
539if.end:                                           ; preds = %for.body, %if.else
540  %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ]
541  ret i32 %sum.0
542}
543
544; Check that we handle calls to variadic functions correctly.
545define 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
569;
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
594entry:
595  %tobool = icmp eq i32 %cond, 0
596  br i1 %tobool, label %if.else, label %if.then
597
598if.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
602
603if.else:                                          ; preds = %entry
604  %mul = shl nsw i32 %N, 1
605  br label %if.end
606
607if.end:                                           ; preds = %if.else, %if.then
608  %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
609  ret i32 %sum.0
610}
611
612declare i32 @someVariadicFunc(i32, ...)
613
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 }
636
637declare hidden fastcc ptr @find_temp_slot_from_address(ptr readonly)
638
639define 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
676;
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
713entry:
714  %cmp = icmp eq ptr %x, null
715  br i1 %cmp, label %cleanup, label %if.end
716
717if.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
722
723lor.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  ]
738
739if.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
743
744if.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
748
749cleanup:                                          ; 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
751}
752
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.
756define 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
768;
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
781entry:
782  %tobool = icmp eq i8 %bad_thing, 0
783  br i1 %tobool, label %if.end, label %if.abort
784
785if.abort:
786  tail call void @abort() #0
787  unreachable
788
789if.end:
790  ret i32 42
791}
792
793declare void @abort() #0
794
795attributes #0 = { noreturn nounwind }
796
797
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.
805;
806define 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
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
838;
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
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
870entry:
871  br i1 poison, label %if.then, label %if.end
872
873if.then:
874  %ptr = alloca i32, i32 4
875  br label %for.body
876
877for.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
883
884if.end:
885  ret void
886}
887
888; Another infinite loop test this time with a body bigger than just one block.
889define 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
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
937;
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
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
985entry:
986  br i1 poison, label %if.then, label %if.end
987
988if.then:
989  %ptr = alloca i32, i32 4
990  br label %for.body
991
992for.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 poison, label %body1, label %body2
998
999body1:
1000  tail call void asm sideeffect "nop", "~{ebx}"()
1001  br label %for.body
1002
1003body2:
1004  tail call void asm sideeffect "nop", "~{ebx}"()
1005  br label %for.body
1006
1007if.end:
1008  ret void
1009}
1010
1011; Another infinite loop test this time with two nested infinite loop.
1012define 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
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
1044;
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
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
1076entry:
1077  br i1 poison, label %loop2a, label %body
1078
1079body:                                             ; preds = %entry
1080  br i1 poison, label %loop2a, label %end
1081
1082loop1:                                            ; 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
1088
1089loop2a:                                           ; 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
1093
1094loop2b:                                           ; preds = %loop1
1095  store ptr %next.phi, ptr %var.phi
1096  br label %loop1
1097
1098end:
1099  ret void
1100}
1101
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!
1104define 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
1125;
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
1149
1150true:
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
1156
1157false:
1158  %tmp5 = tail call i32 @doSomething(i32 6, ptr %addr)
1159  br label %end
1160
1161end:
1162  %tmp.0 = phi i32 [ %tmp4, %true ], [ %tmp5, %false ]
1163  ret i32 %tmp.0
1164}
1165
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
1169
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.
1176define 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
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
1211;
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
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
1246entry:
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
1252
1253for.body.lr.ph:                                   ; preds = %entry
1254  tail call void asm sideeffect "nop", "~{ebx}"()
1255  br label %for.body
1256
1257for.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
1265
1266for.cond.for.end_crit_edge:                       ; preds = %for.body
1267  store i32 %conv3, ptr @a, align 4
1268  br label %for.end
1269
1270for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
1271  %call = tail call i32 (ptr) @varfunc(ptr null)
1272  ret i32 0
1273}
1274
1275declare i32 @varfunc(ptr nocapture readonly)
1276
1277@sum1 = external hidden thread_local global i32, align 4
1278
1279
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.
1286define 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
1307;
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
1328entry:
1329  br i1 %bool1, label %main, label %else
1330
1331main:
1332  %tmp1 = load i32, ptr %sum1, align 4
1333  store i32 %tmp1, ptr @sum1, align 4
1334  br label %exit
1335
1336else:
1337  %call = call i32 @doSomething(i32 0, ptr null)
1338  br label %exit
1339
1340exit:
1341  %res = phi i32 [ %arg, %main], [ %call, %else ]
1342  ret i32 %res
1343}
1344
1345attributes #3 = { nounwind }
1346
1347@irreducibleCFGa = common global i32 0, align 4
1348@irreducibleCFGf = common global i8 0, align 1
1349@irreducibleCFGb = common global i32 0, align 4
1350
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
1363
1364define 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
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
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
1407;
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
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
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
1450entry:
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
1455
1456preheader:
1457  br label %preheader
1458
1459split:
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
1463
1464for.body4.i:
1465  %call.i = tail call i32 (...) @something(i32 %i0)
1466  br label %for.cond8
1467
1468for.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
1472
1473for.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
1477
1478fn1.exit:
1479  ret i32 0
1480
1481for.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
1485}
1486
1487attributes #4 = { "frame-pointer"="all" }
1488
1489@x = external global i32, align 4
1490@y = external global i32, align 4
1491
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.
1495
1496define 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
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
1523;
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
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
1553
1554; <label>:3:
1555  store i32 0, ptr @x, align 4
1556  br label %4
1557
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
1563
1564; <label>:7:
1565  %8 = call i32 (...) @something()
1566  br label %9
1567
1568; <label>:9:
1569  call void (...) @somethingElse()
1570  br label %9
1571
1572; <label>:10:
1573  ret void
1574}
1575
1576declare void @somethingElse(...)
1577
1578attributes #5 = { nounwind "frame-pointer"="non-leaf" }
1579