Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / x86-win64-shrink-wrapping.ll
blob6ed23b0d770cd444f9782a2951d75e4b943723f5
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
9 ; shouldn't change.
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
22 ; ENABLE-NEXT:    #APP
23 ; ENABLE-NEXT:    nop
24 ; ENABLE-NEXT:    #NO_APP
25 ; ENABLE-NEXT:    xorl %eax, %eax
26 ; ENABLE-NEXT:    movl $10, %ecx
27 ; ENABLE-NEXT:    #APP
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
37 ; ENABLE-NEXT:    #APP
38 ; ENABLE-NEXT:    nop
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
47 ; ENABLE-NEXT:    retq
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
58 ; DISABLE-NEXT:    #APP
59 ; DISABLE-NEXT:    nop
60 ; DISABLE-NEXT:    #NO_APP
61 ; DISABLE-NEXT:    xorl %eax, %eax
62 ; DISABLE-NEXT:    movl $10, %ecx
63 ; DISABLE-NEXT:    #APP
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
73 ; DISABLE-NEXT:    #APP
74 ; DISABLE-NEXT:    nop
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
83 ; DISABLE-NEXT:    retq
84 ; DISABLE-NEXT:    .seh_endproc
85 entry:
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", ""()
91   br label %for.body
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
105   br label %if.end
107 if.else:                                          ; preds = %entry
108   %mul = shl nsw i32 %N, 1
109   br label %if.end
111 if.end:                                           ; preds = %if.else, %for.end
112   %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
113   ret i32 %sum.1
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
127 ; ENABLE-NEXT:    #APP
128 ; ENABLE-NEXT:    nop
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
135 ; ENABLE-NEXT:    #APP
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
142 ; ENABLE-NEXT:    #APP
143 ; ENABLE-NEXT:    nop
144 ; ENABLE-NEXT:    #NO_APP
145 ; ENABLE-NEXT:    shll $3, %eax
146 ; ENABLE-NEXT:    popq %rbx
147 ; ENABLE-NEXT:    retq
148 ; ENABLE-NEXT:  .LBB1_4: # %if.else
149 ; ENABLE-NEXT:    addl %edx, %edx
150 ; ENABLE-NEXT:    movl %edx, %eax
151 ; ENABLE-NEXT:    retq
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
162 ; DISABLE-NEXT:    #APP
163 ; DISABLE-NEXT:    nop
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
170 ; DISABLE-NEXT:    #APP
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
177 ; DISABLE-NEXT:    #APP
178 ; DISABLE-NEXT:    nop
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
187 ; DISABLE-NEXT:    retq
188 ; DISABLE-NEXT:    .seh_endproc
189 entry:
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", ""()
195   br label %for.body
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
209   ret i32 %shl
211 if.else:                                          ; preds = %entry
212   %mul = shl nsw i32 %N, 1
213   br label %if.end
215 if.end:                                           ; preds = %if.else, %for.end
216   ret i32 %mul
219 attributes #0 = { uwtable }