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_5
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
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: .seh_startepilogue
42 ; ENABLE-NEXT: popq %rbx
43 ; ENABLE-NEXT: .seh_endepilogue
45 ; ENABLE-NEXT: .LBB0_5: # %if.else
46 ; ENABLE-NEXT: movl %edx, %eax
47 ; ENABLE-NEXT: addl %edx, %eax
48 ; ENABLE-NEXT: .seh_startepilogue
49 ; ENABLE-NEXT: popq %rbx
50 ; ENABLE-NEXT: .seh_endepilogue
52 ; ENABLE-NEXT: .seh_endproc
54 ; DISABLE-LABEL: loopInfoSaveOutsideLoop:
55 ; DISABLE: # %bb.0: # %entry
56 ; DISABLE-NEXT: pushq %rbx
57 ; DISABLE-NEXT: .seh_pushreg %rbx
58 ; DISABLE-NEXT: .seh_endprologue
59 ; DISABLE-NEXT: testl %ecx, %ecx
60 ; DISABLE-NEXT: je .LBB0_5
61 ; DISABLE-NEXT: # %bb.1: # %for.preheader
64 ; DISABLE-NEXT: #NO_APP
65 ; DISABLE-NEXT: xorl %eax, %eax
66 ; DISABLE-NEXT: movl $10, %ecx
68 ; DISABLE-NEXT: movl $1, %edx
69 ; DISABLE-NEXT: #NO_APP
70 ; DISABLE-NEXT: .p2align 4
71 ; DISABLE-NEXT: .LBB0_2: # %for.body
72 ; DISABLE-NEXT: # =>This Inner Loop Header: Depth=1
73 ; DISABLE-NEXT: addl %edx, %eax
74 ; DISABLE-NEXT: decl %ecx
75 ; DISABLE-NEXT: jne .LBB0_2
76 ; DISABLE-NEXT: # %bb.3: # %for.end
79 ; DISABLE-NEXT: #NO_APP
80 ; DISABLE-NEXT: shll $3, %eax
81 ; DISABLE-NEXT: .seh_startepilogue
82 ; DISABLE-NEXT: popq %rbx
83 ; DISABLE-NEXT: .seh_endepilogue
85 ; DISABLE-NEXT: .LBB0_5: # %if.else
86 ; DISABLE-NEXT: movl %edx, %eax
87 ; DISABLE-NEXT: addl %edx, %eax
88 ; DISABLE-NEXT: .seh_startepilogue
89 ; DISABLE-NEXT: popq %rbx
90 ; DISABLE-NEXT: .seh_endepilogue
92 ; DISABLE-NEXT: .seh_endproc
94 %tobool = icmp eq i32 %cond, 0
95 br i1 %tobool, label %if.else, label %for.preheader
97 for.preheader: ; preds = %entry
98 tail call void asm "nop", ""()
101 for.body: ; preds = %for.body, %for.preheader
102 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
103 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
104 %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"()
105 %add = add nsw i32 %call, %sum.04
106 %inc = add nuw nsw i32 %i.05, 1
107 %exitcond = icmp eq i32 %inc, 10
108 br i1 %exitcond, label %for.end, label %for.body
110 for.end: ; preds = %for.body
111 tail call void asm "nop", "~{ebx}"()
112 %shl = shl i32 %add, 3
115 if.else: ; preds = %entry
116 %mul = shl nsw i32 %N, 1
119 if.end: ; preds = %if.else, %for.end
120 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
124 ; When we can sink the epilogue of the function into an existing exit block,
125 ; this is Ok for shrink-wrapping to kicks in.
126 define i32 @loopInfoSaveOutsideLoop2(i32 %cond, i32 %N) #0 {
127 ; ENABLE-LABEL: loopInfoSaveOutsideLoop2:
128 ; ENABLE: # %bb.0: # %entry
129 ; ENABLE-NEXT: testl %ecx, %ecx
130 ; ENABLE-NEXT: je .LBB1_4
131 ; ENABLE-NEXT: # %bb.1: # %for.preheader
132 ; ENABLE-NEXT: pushq %rbx
133 ; ENABLE-NEXT: .seh_pushreg %rbx
134 ; ENABLE-NEXT: .seh_endprologue
137 ; ENABLE-NEXT: #NO_APP
138 ; ENABLE-NEXT: xorl %eax, %eax
139 ; ENABLE-NEXT: movl $10, %ecx
140 ; ENABLE-NEXT: .p2align 4
141 ; ENABLE-NEXT: .LBB1_2: # %for.body
142 ; ENABLE-NEXT: # =>This Inner Loop Header: Depth=1
144 ; ENABLE-NEXT: movl $1, %edx
145 ; ENABLE-NEXT: #NO_APP
146 ; ENABLE-NEXT: addl %edx, %eax
147 ; ENABLE-NEXT: decl %ecx
148 ; ENABLE-NEXT: jne .LBB1_2
149 ; ENABLE-NEXT: # %bb.3: # %for.end
152 ; ENABLE-NEXT: #NO_APP
153 ; ENABLE-NEXT: shll $3, %eax
154 ; ENABLE-NEXT: .seh_startepilogue
155 ; ENABLE-NEXT: popq %rbx
156 ; ENABLE-NEXT: .seh_endepilogue
158 ; ENABLE-NEXT: .LBB1_4: # %if.else
159 ; ENABLE-NEXT: addl %edx, %edx
160 ; ENABLE-NEXT: movl %edx, %eax
162 ; ENABLE-NEXT: .seh_endproc
164 ; DISABLE-LABEL: loopInfoSaveOutsideLoop2:
165 ; DISABLE: # %bb.0: # %entry
166 ; DISABLE-NEXT: pushq %rbx
167 ; DISABLE-NEXT: .seh_pushreg %rbx
168 ; DISABLE-NEXT: .seh_endprologue
169 ; DISABLE-NEXT: testl %ecx, %ecx
170 ; DISABLE-NEXT: je .LBB1_5
171 ; DISABLE-NEXT: # %bb.1: # %for.preheader
174 ; DISABLE-NEXT: #NO_APP
175 ; DISABLE-NEXT: xorl %eax, %eax
176 ; DISABLE-NEXT: movl $10, %ecx
177 ; DISABLE-NEXT: .p2align 4
178 ; DISABLE-NEXT: .LBB1_2: # %for.body
179 ; DISABLE-NEXT: # =>This Inner Loop Header: Depth=1
181 ; DISABLE-NEXT: movl $1, %edx
182 ; DISABLE-NEXT: #NO_APP
183 ; DISABLE-NEXT: addl %edx, %eax
184 ; DISABLE-NEXT: decl %ecx
185 ; DISABLE-NEXT: jne .LBB1_2
186 ; DISABLE-NEXT: # %bb.3: # %for.end
189 ; DISABLE-NEXT: #NO_APP
190 ; DISABLE-NEXT: shll $3, %eax
191 ; DISABLE-NEXT: .seh_startepilogue
192 ; DISABLE-NEXT: popq %rbx
193 ; DISABLE-NEXT: .seh_endepilogue
195 ; DISABLE-NEXT: .LBB1_5: # %if.else
196 ; DISABLE-NEXT: addl %edx, %edx
197 ; DISABLE-NEXT: movl %edx, %eax
198 ; DISABLE-NEXT: .seh_startepilogue
199 ; DISABLE-NEXT: popq %rbx
200 ; DISABLE-NEXT: .seh_endepilogue
202 ; DISABLE-NEXT: .seh_endproc
204 %tobool = icmp eq i32 %cond, 0
205 br i1 %tobool, label %if.else, label %for.preheader
207 for.preheader: ; preds = %entry
208 tail call void asm "nop", ""()
211 for.body: ; preds = %for.body, %for.preheader
212 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
213 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
214 %call = tail call i32 asm sideeffect "movl $$1, $0", "=r,~{ebx}"()
215 %add = add nsw i32 %call, %sum.04
216 %inc = add nuw nsw i32 %i.05, 1
217 %exitcond = icmp eq i32 %inc, 10
218 br i1 %exitcond, label %for.end, label %for.body
220 for.end: ; preds = %for.body
221 tail call void asm "nop", "~{ebx}"()
222 %shl = shl i32 %add, 3
225 if.else: ; preds = %entry
226 %mul = shl nsw i32 %N, 1
229 if.end: ; preds = %if.else, %for.end
233 attributes #0 = { uwtable }