1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc %s -o - -enable-shrink-wrap=true | FileCheck %s --check-prefix=ENABLE
3 ; RUN: llc %s -o - -enable-shrink-wrap=false | FileCheck %s --check-prefix=DISABLE
5 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
6 target triple = "x86_64--windows-gnu"
8 ; The output of this function with or without shrink-wrapping
10 ; Indeed, the epilogue block would have been if.else, meaning
11 ; after the pops, we will have additional instruction (jump, mov,
12 ; etc.) prior to the return and this is forbidden for Win64.
13 define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) #0 {
14 ; ENABLE-LABEL: loopInfoSaveOutsideLoop:
15 ; ENABLE: # %bb.0: # %entry
16 ; ENABLE-NEXT: pushq %rbx
17 ; ENABLE-NEXT: .seh_pushreg %rbx
18 ; ENABLE-NEXT: .seh_endprologue
19 ; ENABLE-NEXT: testl %ecx, %ecx
20 ; ENABLE-NEXT: je .LBB0_4
21 ; ENABLE-NEXT: # %bb.1: # %for.preheader
24 ; ENABLE-NEXT: #NO_APP
25 ; ENABLE-NEXT: xorl %eax, %eax
26 ; ENABLE-NEXT: movl $10, %ecx
28 ; ENABLE-NEXT: movl $1, %edx
29 ; ENABLE-NEXT: #NO_APP
30 ; ENABLE-NEXT: .p2align 4, 0x90
31 ; ENABLE-NEXT: .LBB0_2: # %for.body
32 ; ENABLE-NEXT: # =>This Inner Loop Header: Depth=1
33 ; ENABLE-NEXT: addl %edx, %eax
34 ; ENABLE-NEXT: decl %ecx
35 ; ENABLE-NEXT: jne .LBB0_2
36 ; ENABLE-NEXT: # %bb.3: # %for.end
39 ; ENABLE-NEXT: #NO_APP
40 ; ENABLE-NEXT: shll $3, %eax
41 ; ENABLE-NEXT: jmp .LBB0_5
42 ; ENABLE-NEXT: .LBB0_4: # %if.else
43 ; ENABLE-NEXT: movl %edx, %eax
44 ; ENABLE-NEXT: addl %edx, %eax
45 ; ENABLE-NEXT: .LBB0_5: # %if.end
46 ; ENABLE-NEXT: popq %rbx
48 ; ENABLE-NEXT: .seh_endproc
50 ; DISABLE-LABEL: loopInfoSaveOutsideLoop:
51 ; DISABLE: # %bb.0: # %entry
52 ; DISABLE-NEXT: pushq %rbx
53 ; DISABLE-NEXT: .seh_pushreg %rbx
54 ; DISABLE-NEXT: .seh_endprologue
55 ; DISABLE-NEXT: testl %ecx, %ecx
56 ; DISABLE-NEXT: je .LBB0_4
57 ; DISABLE-NEXT: # %bb.1: # %for.preheader
60 ; DISABLE-NEXT: #NO_APP
61 ; DISABLE-NEXT: xorl %eax, %eax
62 ; DISABLE-NEXT: movl $10, %ecx
64 ; DISABLE-NEXT: movl $1, %edx
65 ; DISABLE-NEXT: #NO_APP
66 ; DISABLE-NEXT: .p2align 4, 0x90
67 ; DISABLE-NEXT: .LBB0_2: # %for.body
68 ; DISABLE-NEXT: # =>This Inner Loop Header: Depth=1
69 ; DISABLE-NEXT: addl %edx, %eax
70 ; DISABLE-NEXT: decl %ecx
71 ; DISABLE-NEXT: jne .LBB0_2
72 ; DISABLE-NEXT: # %bb.3: # %for.end
75 ; DISABLE-NEXT: #NO_APP
76 ; DISABLE-NEXT: shll $3, %eax
77 ; DISABLE-NEXT: jmp .LBB0_5
78 ; DISABLE-NEXT: .LBB0_4: # %if.else
79 ; DISABLE-NEXT: movl %edx, %eax
80 ; DISABLE-NEXT: addl %edx, %eax
81 ; DISABLE-NEXT: .LBB0_5: # %if.end
82 ; DISABLE-NEXT: popq %rbx
84 ; DISABLE-NEXT: .seh_endproc
86 %tobool = icmp eq i32 %cond, 0
87 br i1 %tobool, label %if.else, label %for.preheader
89 for.preheader: ; preds = %entry
90 tail call void asm "nop", ""()
93 for.body: ; preds = %for.body, %for.preheader
94 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
95 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
96 %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"()
97 %add = add nsw i32 %call, %sum.04
98 %inc = add nuw nsw i32 %i.05, 1
99 %exitcond = icmp eq i32 %inc, 10
100 br i1 %exitcond, label %for.end, label %for.body
102 for.end: ; preds = %for.body
103 tail call void asm "nop", "~{ebx}"()
104 %shl = shl i32 %add, 3
107 if.else: ; preds = %entry
108 %mul = shl nsw i32 %N, 1
111 if.end: ; preds = %if.else, %for.end
112 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
116 ; When we can sink the epilogue of the function into an existing exit block,
117 ; this is Ok for shrink-wrapping to kicks in.
118 define i32 @loopInfoSaveOutsideLoop2(i32 %cond, i32 %N) #0 {
119 ; ENABLE-LABEL: loopInfoSaveOutsideLoop2:
120 ; ENABLE: # %bb.0: # %entry
121 ; ENABLE-NEXT: testl %ecx, %ecx
122 ; ENABLE-NEXT: je .LBB1_4
123 ; ENABLE-NEXT: # %bb.1: # %for.preheader
124 ; ENABLE-NEXT: pushq %rbx
125 ; ENABLE-NEXT: .seh_pushreg %rbx
126 ; ENABLE-NEXT: .seh_endprologue
129 ; ENABLE-NEXT: #NO_APP
130 ; ENABLE-NEXT: xorl %eax, %eax
131 ; ENABLE-NEXT: movl $10, %ecx
132 ; ENABLE-NEXT: .p2align 4, 0x90
133 ; ENABLE-NEXT: .LBB1_2: # %for.body
134 ; ENABLE-NEXT: # =>This Inner Loop Header: Depth=1
136 ; ENABLE-NEXT: movl $1, %edx
137 ; ENABLE-NEXT: #NO_APP
138 ; ENABLE-NEXT: addl %edx, %eax
139 ; ENABLE-NEXT: decl %ecx
140 ; ENABLE-NEXT: jne .LBB1_2
141 ; ENABLE-NEXT: # %bb.3: # %for.end
144 ; ENABLE-NEXT: #NO_APP
145 ; ENABLE-NEXT: shll $3, %eax
146 ; ENABLE-NEXT: popq %rbx
148 ; ENABLE-NEXT: .LBB1_4: # %if.else
149 ; ENABLE-NEXT: addl %edx, %edx
150 ; ENABLE-NEXT: movl %edx, %eax
152 ; ENABLE-NEXT: .seh_endproc
154 ; DISABLE-LABEL: loopInfoSaveOutsideLoop2:
155 ; DISABLE: # %bb.0: # %entry
156 ; DISABLE-NEXT: pushq %rbx
157 ; DISABLE-NEXT: .seh_pushreg %rbx
158 ; DISABLE-NEXT: .seh_endprologue
159 ; DISABLE-NEXT: testl %ecx, %ecx
160 ; DISABLE-NEXT: je .LBB1_4
161 ; DISABLE-NEXT: # %bb.1: # %for.preheader
164 ; DISABLE-NEXT: #NO_APP
165 ; DISABLE-NEXT: xorl %eax, %eax
166 ; DISABLE-NEXT: movl $10, %ecx
167 ; DISABLE-NEXT: .p2align 4, 0x90
168 ; DISABLE-NEXT: .LBB1_2: # %for.body
169 ; DISABLE-NEXT: # =>This Inner Loop Header: Depth=1
171 ; DISABLE-NEXT: movl $1, %edx
172 ; DISABLE-NEXT: #NO_APP
173 ; DISABLE-NEXT: addl %edx, %eax
174 ; DISABLE-NEXT: decl %ecx
175 ; DISABLE-NEXT: jne .LBB1_2
176 ; DISABLE-NEXT: # %bb.3: # %for.end
179 ; DISABLE-NEXT: #NO_APP
180 ; DISABLE-NEXT: shll $3, %eax
181 ; DISABLE-NEXT: jmp .LBB1_5
182 ; DISABLE-NEXT: .LBB1_4: # %if.else
183 ; DISABLE-NEXT: addl %edx, %edx
184 ; DISABLE-NEXT: movl %edx, %eax
185 ; DISABLE-NEXT: .LBB1_5: # %if.end
186 ; DISABLE-NEXT: popq %rbx
188 ; DISABLE-NEXT: .seh_endproc
190 %tobool = icmp eq i32 %cond, 0
191 br i1 %tobool, label %if.else, label %for.preheader
193 for.preheader: ; preds = %entry
194 tail call void asm "nop", ""()
197 for.body: ; preds = %for.body, %for.preheader
198 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
199 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
200 %call = tail call i32 asm sideeffect "movl $$1, $0", "=r,~{ebx}"()
201 %add = add nsw i32 %call, %sum.04
202 %inc = add nuw nsw i32 %i.05, 1
203 %exitcond = icmp eq i32 %inc, 10
204 br i1 %exitcond, label %for.end, label %for.body
206 for.end: ; preds = %for.body
207 tail call void asm "nop", "~{ebx}"()
208 %shl = shl i32 %add, 3
211 if.else: ; preds = %entry
212 %mul = shl nsw i32 %N, 1
215 if.end: ; preds = %if.else, %for.end
219 attributes #0 = { uwtable }